misc unfurl preview fixes

This commit is contained in:
Mononaut 2025-02-10 03:47:05 +00:00
parent 1f4c56c19a
commit 27c28f939c
No known key found for this signature in database
GPG Key ID: A3F058E41374C04E
11 changed files with 111 additions and 83 deletions

View File

@ -36,6 +36,8 @@ export class AddressPreviewComponent implements OnInit, OnDestroy {
sent = 0; sent = 0;
totalUnspent = 0; totalUnspent = 0;
ogSession: number;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private electrsApiService: ElectrsApiService, private electrsApiService: ElectrsApiService,
@ -58,7 +60,7 @@ export class AddressPreviewComponent implements OnInit, OnDestroy {
.pipe( .pipe(
switchMap((params: ParamMap) => { switchMap((params: ParamMap) => {
this.rawAddress = params.get('id') || ''; this.rawAddress = params.get('id') || '';
this.openGraphService.waitFor('address-data-' + this.rawAddress); this.ogSession = this.openGraphService.waitFor('address-data-' + this.rawAddress);
this.error = undefined; this.error = undefined;
this.isLoadingAddress = true; this.isLoadingAddress = true;
this.loadedConfirmedTxCount = 0; this.loadedConfirmedTxCount = 0;
@ -79,7 +81,7 @@ export class AddressPreviewComponent implements OnInit, OnDestroy {
this.isLoadingAddress = false; this.isLoadingAddress = false;
this.error = err; this.error = err;
console.log(err); console.log(err);
this.openGraphService.fail('address-data-' + this.rawAddress); this.openGraphService.fail({ event: 'address-data-' + this.rawAddress, sessionId: this.ogSession });
return of(null); return of(null);
}) })
); );
@ -97,7 +99,7 @@ export class AddressPreviewComponent implements OnInit, OnDestroy {
this.address = address; this.address = address;
this.updateChainStats(); this.updateChainStats();
this.isLoadingAddress = false; this.isLoadingAddress = false;
this.openGraphService.waitOver('address-data-' + this.rawAddress); this.openGraphService.waitOver({ event: 'address-data-' + this.rawAddress, sessionId: this.ogSession });
}) })
) )
.subscribe(() => {}, .subscribe(() => {},
@ -105,7 +107,7 @@ export class AddressPreviewComponent implements OnInit, OnDestroy {
console.log(error); console.log(error);
this.error = error; this.error = error;
this.isLoadingAddress = false; this.isLoadingAddress = false;
this.openGraphService.fail('address-data-' + this.rawAddress); this.openGraphService.fail({ event: 'address-data-' + this.rawAddress, sessionId: this.ogSession });
} }
); );
} }

View File

@ -49,7 +49,7 @@
</ng-template> </ng-template>
</tr> </tr>
</ng-template> </ng-template>
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet'"> <tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet' && block?.extras?.pool">
<td i18n="block.miner">Miner</td> <td i18n="block.miner">Miner</td>
<td *ngIf="stateService.env.MINING_DASHBOARD"> <td *ngIf="stateService.env.MINING_DASHBOARD">
<a placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, block.extras.pool.slug]" class="badge" style="color: #FFF;padding:0;"> <a placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, block.extras.pool.slug]" class="badge" style="color: #FFF;padding:0;">

View File

@ -35,6 +35,8 @@ export class BlockPreviewComponent implements OnInit, OnDestroy {
overviewSubscription: Subscription; overviewSubscription: Subscription;
networkChangedSubscription: Subscription; networkChangedSubscription: Subscription;
ogSession: number;
@ViewChild('blockGraph') blockGraph: BlockOverviewGraphComponent; @ViewChild('blockGraph') blockGraph: BlockOverviewGraphComponent;
constructor( constructor(
@ -53,8 +55,8 @@ export class BlockPreviewComponent implements OnInit, OnDestroy {
const block$ = this.route.paramMap.pipe( const block$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => { switchMap((params: ParamMap) => {
this.rawId = params.get('id') || ''; this.rawId = params.get('id') || '';
this.openGraphService.waitFor('block-viz-' + this.rawId); this.ogSession = this.openGraphService.waitFor('block-viz-' + this.rawId);
this.openGraphService.waitFor('block-data-' + this.rawId); this.ogSession = this.openGraphService.waitFor('block-data-' + this.rawId);
const blockHash: string = params.get('id') || ''; const blockHash: string = params.get('id') || '';
this.block = undefined; this.block = undefined;
@ -86,8 +88,8 @@ export class BlockPreviewComponent implements OnInit, OnDestroy {
catchError((err) => { catchError((err) => {
this.error = err; this.error = err;
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('block-data-' + this.rawId); this.openGraphService.fail({ event: 'block-data-' + this.rawId, sessionId: this.ogSession });
this.openGraphService.fail('block-viz-' + this.rawId); this.openGraphService.fail({ event: 'block-viz-' + this.rawId, sessionId: this.ogSession });
return of(null); return of(null);
}), }),
); );
@ -114,7 +116,7 @@ export class BlockPreviewComponent implements OnInit, OnDestroy {
this.isLoadingOverview = true; this.isLoadingOverview = true;
this.overviewError = null; this.overviewError = null;
this.openGraphService.waitOver('block-data-' + this.rawId); this.openGraphService.waitOver({ event: 'block-data-' + this.rawId, sessionId: this.ogSession });
}), }),
throttleTime(50, asyncScheduler, { leading: true, trailing: true }), throttleTime(50, asyncScheduler, { leading: true, trailing: true }),
shareReplay({ bufferSize: 1, refCount: true }) shareReplay({ bufferSize: 1, refCount: true })
@ -129,7 +131,7 @@ export class BlockPreviewComponent implements OnInit, OnDestroy {
.pipe( .pipe(
catchError((err) => { catchError((err) => {
this.overviewError = err; this.overviewError = err;
this.openGraphService.fail('block-viz-' + this.rawId); this.openGraphService.fail({ event: 'block-viz-' + this.rawId, sessionId: this.ogSession });
return of([]); return of([]);
}), }),
switchMap((transactions) => { switchMap((transactions) => {
@ -138,7 +140,8 @@ export class BlockPreviewComponent implements OnInit, OnDestroy {
), ),
this.stateService.env.ACCELERATOR === true && block.height > 819500 this.stateService.env.ACCELERATOR === true && block.height > 819500
? this.servicesApiService.getAllAccelerationHistory$({ blockHeight: block.height }) ? this.servicesApiService.getAllAccelerationHistory$({ blockHeight: block.height })
.pipe(catchError(() => { .pipe(
catchError(() => {
return of([]); return of([]);
})) }))
: of([]) : of([])
@ -169,8 +172,8 @@ export class BlockPreviewComponent implements OnInit, OnDestroy {
this.error = error; this.error = error;
this.isLoadingOverview = false; this.isLoadingOverview = false;
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('block-viz-' + this.rawId); this.openGraphService.fail({ event: 'block-viz-' + this.rawId, sessionId: this.ogSession });
this.openGraphService.fail('block-data-' + this.rawId); this.openGraphService.fail({ event: 'block-data-' + this.rawId, sessionId: this.ogSession });
if (this.blockGraph) { if (this.blockGraph) {
this.blockGraph.destroy(); this.blockGraph.destroy();
} }
@ -196,6 +199,6 @@ export class BlockPreviewComponent implements OnInit, OnDestroy {
} }
onGraphReady(): void { onGraphReady(): void {
this.openGraphService.waitOver('block-viz-' + this.rawId); this.openGraphService.waitOver({ event: 'block-viz-' + this.rawId, sessionId: this.ogSession });
} }
} }

View File

@ -30,6 +30,8 @@ export class PoolPreviewComponent implements OnInit {
slug: string = undefined; slug: string = undefined;
ogSession: number;
constructor( constructor(
@Inject(LOCALE_ID) public locale: string, @Inject(LOCALE_ID) public locale: string,
private apiService: ApiService, private apiService: ApiService,
@ -47,22 +49,22 @@ export class PoolPreviewComponent implements OnInit {
this.isLoading = true; this.isLoading = true;
this.imageLoaded = false; this.imageLoaded = false;
this.slug = slug; this.slug = slug;
this.openGraphService.waitFor('pool-hash-' + this.slug); this.ogSession = this.openGraphService.waitFor('pool-hash-' + this.slug);
this.openGraphService.waitFor('pool-stats-' + this.slug); this.ogSession = this.openGraphService.waitFor('pool-stats-' + this.slug);
this.openGraphService.waitFor('pool-chart-' + this.slug); this.ogSession = this.openGraphService.waitFor('pool-chart-' + this.slug);
this.openGraphService.waitFor('pool-img-' + this.slug); this.ogSession = this.openGraphService.waitFor('pool-img-' + this.slug);
return this.apiService.getPoolHashrate$(this.slug) return this.apiService.getPoolHashrate$(this.slug)
.pipe( .pipe(
switchMap((data) => { switchMap((data) => {
this.isLoading = false; this.isLoading = false;
this.prepareChartOptions(data.map(val => [val.timestamp * 1000, val.avgHashrate])); this.prepareChartOptions(data.map(val => [val.timestamp * 1000, val.avgHashrate]));
this.openGraphService.waitOver('pool-hash-' + this.slug); this.openGraphService.waitOver({ event: 'pool-hash-' + this.slug, sessionId: this.ogSession });
return [slug]; return [slug];
}), }),
catchError(() => { catchError(() => {
this.isLoading = false; this.isLoading = false;
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('pool-hash-' + this.slug); this.openGraphService.fail({ event: 'pool-hash-' + this.slug, sessionId: this.ogSession });
return of([slug]); return of([slug]);
}) })
); );
@ -72,7 +74,7 @@ export class PoolPreviewComponent implements OnInit {
catchError(() => { catchError(() => {
this.isLoading = false; this.isLoading = false;
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('pool-stats-' + this.slug); this.openGraphService.fail({ event: 'pool-stats-' + this.slug, sessionId: this.ogSession });
return of(null); return of(null);
}) })
); );
@ -90,11 +92,11 @@ export class PoolPreviewComponent implements OnInit {
} }
poolStats.pool.regexes = regexes.slice(0, -3); poolStats.pool.regexes = regexes.slice(0, -3);
this.openGraphService.waitOver('pool-stats-' + this.slug); this.openGraphService.waitOver({ event: 'pool-stats-' + this.slug, sessionId: this.ogSession });
const logoSrc = `/resources/mining-pools/` + poolStats.pool.slug + '.svg'; const logoSrc = `/resources/mining-pools/` + poolStats.pool.slug + '.svg';
if (logoSrc === this.lastImgSrc) { if (logoSrc === this.lastImgSrc) {
this.openGraphService.waitOver('pool-img-' + this.slug); this.openGraphService.waitOver({ event: 'pool-img-' + this.slug, sessionId: this.ogSession });
} }
this.lastImgSrc = logoSrc; this.lastImgSrc = logoSrc;
return Object.assign({ return Object.assign({
@ -103,7 +105,7 @@ export class PoolPreviewComponent implements OnInit {
}), }),
catchError(() => { catchError(() => {
this.isLoading = false; this.isLoading = false;
this.openGraphService.fail('pool-stats-' + this.slug); this.openGraphService.fail({ event: 'pool-stats-' + this.slug, sessionId: this.ogSession });
return of(null); return of(null);
}) })
); );
@ -170,16 +172,16 @@ export class PoolPreviewComponent implements OnInit {
} }
onChartReady(): void { onChartReady(): void {
this.openGraphService.waitOver('pool-chart-' + this.slug); this.openGraphService.waitOver({ event: 'pool-chart-' + this.slug, sessionId: this.ogSession });
} }
onImageLoad(): void { onImageLoad(): void {
this.imageLoaded = true; this.imageLoaded = true;
this.openGraphService.waitOver('pool-img-' + this.slug); this.openGraphService.waitOver({ event: 'pool-img-' + this.slug, sessionId: this.ogSession });
} }
onImageFail(): void { onImageFail(): void {
this.imageLoaded = false; this.imageLoaded = false;
this.openGraphService.waitOver('pool-img-' + this.slug); this.openGraphService.waitOver({ event: 'pool-img-' + this.slug, sessionId: this.ogSession });
} }
} }

View File

@ -43,6 +43,8 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy {
opReturns: Vout[]; opReturns: Vout[];
extraData: 'none' | 'coinbase' | 'opreturn'; extraData: 'none' | 'coinbase' | 'opreturn';
ogSession: number;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private electrsApiService: ElectrsApiService, private electrsApiService: ElectrsApiService,
@ -75,7 +77,7 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy {
) )
.subscribe((cpfpInfo) => { .subscribe((cpfpInfo) => {
this.cpfpInfo = cpfpInfo; this.cpfpInfo = cpfpInfo;
this.openGraphService.waitOver('cpfp-data-' + this.txId); this.openGraphService.waitOver({ event: 'cpfp-data-' + this.txId, sessionId: this.ogSession });
}); });
this.subscription = this.route.paramMap this.subscription = this.route.paramMap
@ -83,8 +85,8 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy {
switchMap((params: ParamMap) => { switchMap((params: ParamMap) => {
const urlMatch = (params.get('id') || '').split(':'); const urlMatch = (params.get('id') || '').split(':');
this.txId = urlMatch[0]; this.txId = urlMatch[0];
this.openGraphService.waitFor('tx-data-' + this.txId); this.ogSession = this.openGraphService.waitFor('tx-data-' + this.txId);
this.openGraphService.waitFor('tx-time-' + this.txId); this.ogSession = this.openGraphService.waitFor('tx-time-' + this.txId);
this.seoService.setTitle( this.seoService.setTitle(
$localize`:@@bisq.transaction.browser-title:Transaction: ${this.txId}:INTERPOLATION:` $localize`:@@bisq.transaction.browser-title:Transaction: ${this.txId}:INTERPOLATION:`
); );
@ -138,7 +140,7 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy {
.subscribe((tx: Transaction) => { .subscribe((tx: Transaction) => {
if (!tx) { if (!tx) {
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('tx-data-' + this.txId); this.openGraphService.fail({ event: 'tx-data-' + this.txId, sessionId: this.ogSession });
return; return;
} }
@ -155,10 +157,10 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy {
if (tx.status.confirmed) { if (tx.status.confirmed) {
this.transactionTime = tx.status.block_time; this.transactionTime = tx.status.block_time;
this.openGraphService.waitOver('tx-time-' + this.txId); this.openGraphService.waitOver({ event: 'tx-time-' + this.txId, sessionId: this.ogSession });
} else if (!tx.status.confirmed && tx.firstSeen) { } else if (!tx.status.confirmed && tx.firstSeen) {
this.transactionTime = tx.firstSeen; this.transactionTime = tx.firstSeen;
this.openGraphService.waitOver('tx-time-' + this.txId); this.openGraphService.waitOver({ event: 'tx-time-' + this.txId, sessionId: this.ogSession });
} else { } else {
this.getTransactionTime(); this.getTransactionTime();
} }
@ -184,11 +186,11 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy {
} }
} }
this.openGraphService.waitOver('tx-data-' + this.txId); this.openGraphService.waitOver({ event: 'tx-data-' + this.txId, sessionId: this.ogSession });
}, },
(error) => { (error) => {
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('tx-data-' + this.txId); this.openGraphService.fail({ event: 'tx-data-' + this.txId, sessionId: this.ogSession });
this.error = error; this.error = error;
this.isLoadingTx = false; this.isLoadingTx = false;
} }
@ -205,7 +207,7 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy {
) )
.subscribe((transactionTimes) => { .subscribe((transactionTimes) => {
this.transactionTime = transactionTimes[0]; this.transactionTime = transactionTimes[0];
this.openGraphService.waitOver('tx-time-' + this.txId); this.openGraphService.waitOver({ event: 'tx-time-' + this.txId, sessionId: this.ogSession });
}); });
} }

View File

@ -125,6 +125,8 @@ export class WalletPreviewComponent implements OnInit, OnDestroy {
sent = 0; sent = 0;
chainBalance = 0; chainBalance = 0;
ogSession: number;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private stateService: StateService, private stateService: StateService,
@ -141,9 +143,9 @@ export class WalletPreviewComponent implements OnInit, OnDestroy {
map((params: ParamMap) => params.get('wallet') as string), map((params: ParamMap) => params.get('wallet') as string),
tap((walletName: string) => { tap((walletName: string) => {
this.walletName = walletName; this.walletName = walletName;
this.openGraphService.waitFor('wallet-addresses-' + this.walletName); this.ogSession = this.openGraphService.waitFor('wallet-addresses-' + this.walletName);
this.openGraphService.waitFor('wallet-data-' + this.walletName); this.ogSession = this.openGraphService.waitFor('wallet-data-' + this.walletName);
this.openGraphService.waitFor('wallet-txs-' + this.walletName); this.ogSession = this.openGraphService.waitFor('wallet-txs-' + this.walletName);
this.seoService.setTitle($localize`:@@wallet.component.browser-title:Wallet: ${walletName}:INTERPOLATION:`); this.seoService.setTitle($localize`:@@wallet.component.browser-title:Wallet: ${walletName}:INTERPOLATION:`);
this.seoService.setDescription($localize`:@@meta.description.bitcoin.wallet:See mempool transactions, confirmed transactions, balance, and more for ${this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'}${seoDescriptionNetwork(this.stateService.network)} wallet ${walletName}:INTERPOLATION:.`); this.seoService.setDescription($localize`:@@meta.description.bitcoin.wallet:See mempool transactions, confirmed transactions, balance, and more for ${this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'}${seoDescriptionNetwork(this.stateService.network)} wallet ${walletName}:INTERPOLATION:.`);
}), }),
@ -152,9 +154,9 @@ export class WalletPreviewComponent implements OnInit, OnDestroy {
this.error = err; this.error = err;
this.seoService.logSoft404(); this.seoService.logSoft404();
console.log(err); console.log(err);
this.openGraphService.fail('wallet-addresses-' + this.walletName); this.openGraphService.fail({ event: 'wallet-addresses-' + this.walletName, sessionId: this.ogSession });
this.openGraphService.fail('wallet-data-' + this.walletName); this.openGraphService.fail({ event: 'wallet-data-' + this.walletName, sessionId: this.ogSession });
this.openGraphService.fail('wallet-txs-' + this.walletName); this.openGraphService.fail({ event: 'wallet-txs-' + this.walletName, sessionId: this.ogSession });
return of({}); return of({});
}) })
)), )),
@ -185,13 +187,13 @@ export class WalletPreviewComponent implements OnInit, OnDestroy {
this.walletSubscription = this.walletAddresses$.subscribe(wallet => { this.walletSubscription = this.walletAddresses$.subscribe(wallet => {
this.addressStrings = Object.keys(wallet); this.addressStrings = Object.keys(wallet);
this.addresses = Object.values(wallet); this.addresses = Object.values(wallet);
this.openGraphService.waitOver('wallet-addresses-' + this.walletName); this.openGraphService.waitOver({ event: 'wallet-addresses-' + this.walletName, sessionId: this.ogSession });
}); });
this.walletSummary$ = this.wallet$.pipe( this.walletSummary$ = this.wallet$.pipe(
map(wallet => this.deduplicateWalletTransactions(Object.values(wallet).flatMap(address => address.transactions))), map(wallet => this.deduplicateWalletTransactions(Object.values(wallet).flatMap(address => address.transactions))),
tap(() => { tap(() => {
this.openGraphService.waitOver('wallet-txs-' + this.walletName); this.openGraphService.waitOver({ event: 'wallet-txs-' + this.walletName, sessionId: this.ogSession });
}) })
); );
@ -209,7 +211,7 @@ export class WalletPreviewComponent implements OnInit, OnDestroy {
); );
}), }),
tap(() => { tap(() => {
this.openGraphService.waitOver('wallet-data-' + this.walletName); this.openGraphService.waitOver({ event: 'wallet-data-' + this.walletName, sessionId: this.ogSession });
}) })
); );
} }

View File

@ -18,6 +18,8 @@ export class ChannelPreviewComponent implements OnInit {
channelGeo: number[] = []; channelGeo: number[] = [];
shortId: string; shortId: string;
ogSession: number;
constructor( constructor(
private lightningApiService: LightningApiService, private lightningApiService: LightningApiService,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
@ -30,8 +32,8 @@ export class ChannelPreviewComponent implements OnInit {
.pipe( .pipe(
switchMap((params: ParamMap) => { switchMap((params: ParamMap) => {
this.shortId = params.get('short_id') || ''; this.shortId = params.get('short_id') || '';
this.openGraphService.waitFor('channel-map-' + this.shortId); this.ogSession = this.openGraphService.waitFor('channel-map-' + this.shortId);
this.openGraphService.waitFor('channel-data-' + this.shortId); this.ogSession = this.openGraphService.waitFor('channel-data-' + this.shortId);
this.error = null; this.error = null;
this.seoService.setTitle(`Channel: ${params.get('short_id')}`); this.seoService.setTitle(`Channel: ${params.get('short_id')}`);
this.seoService.setDescription($localize`:@@meta.description.lightning.channel:Overview for Lightning channel ${params.get('short_id')}. See channel capacity, the Lightning nodes involved, related on-chain transactions, and more.`); this.seoService.setDescription($localize`:@@meta.description.lightning.channel:Overview for Lightning channel ${params.get('short_id')}. See channel capacity, the Lightning nodes involved, related on-chain transactions, and more.`);
@ -51,13 +53,13 @@ export class ChannelPreviewComponent implements OnInit {
data.node_right.longitude, data.node_right.latitude, data.node_right.longitude, data.node_right.latitude,
]; ];
} }
this.openGraphService.waitOver('channel-data-' + this.shortId); this.openGraphService.waitOver({ event: 'channel-data-' + this.shortId, sessionId: this.ogSession });
}), }),
catchError((err) => { catchError((err) => {
this.error = err; this.error = err;
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('channel-map-' + this.shortId); this.openGraphService.fail({ event: 'channel-map-' + this.shortId, sessionId: this.ogSession });
this.openGraphService.fail('channel-data-' + this.shortId); this.openGraphService.fail({ event: 'channel-data-' + this.shortId, sessionId: this.ogSession });
return of(null); return of(null);
}) })
); );
@ -66,6 +68,6 @@ export class ChannelPreviewComponent implements OnInit {
} }
onMapReady() { onMapReady() {
this.openGraphService.waitOver('channel-map-' + this.shortId); this.openGraphService.waitOver({ event: 'channel-map-' + this.shortId, sessionId: this.ogSession });
} }
} }

View File

@ -22,6 +22,8 @@ export class GroupPreviewComponent implements OnInit {
slug: string; slug: string;
groupId: string; groupId: string;
ogSession: number;
constructor( constructor(
private lightningApiService: LightningApiService, private lightningApiService: LightningApiService,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
@ -37,8 +39,8 @@ export class GroupPreviewComponent implements OnInit {
.pipe( .pipe(
switchMap((params: ParamMap) => { switchMap((params: ParamMap) => {
this.slug = params.get('slug'); this.slug = params.get('slug');
this.openGraphService.waitFor('ln-group-map-' + this.slug); this.ogSession = this.openGraphService.waitFor('ln-group-map-' + this.slug);
this.openGraphService.waitFor('ln-group-data-' + this.slug); this.ogSession = this.openGraphService.waitFor('ln-group-data-' + this.slug);
if (this.slug === 'the-mempool-open-source-project') { if (this.slug === 'the-mempool-open-source-project') {
this.groupId = 'mempool.space'; this.groupId = 'mempool.space';
@ -52,8 +54,8 @@ export class GroupPreviewComponent implements OnInit {
description: '', description: '',
}; };
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('ln-group-map-' + this.slug); this.openGraphService.fail({ event: 'ln-group-map-' + this.slug, sessionId: this.ogSession });
this.openGraphService.fail('ln-group-data-' + this.slug); this.openGraphService.fail({ event: 'ln-group-data-' + this.slug, sessionId: this.ogSession });
return of(null); return of(null);
} }
@ -99,7 +101,7 @@ export class GroupPreviewComponent implements OnInit {
const sumLiquidity = nodes.reduce((partialSum, a) => partialSum + parseInt(a.capacity, 10), 0); const sumLiquidity = nodes.reduce((partialSum, a) => partialSum + parseInt(a.capacity, 10), 0);
const sumChannels = nodes.reduce((partialSum, a) => partialSum + a.opened_channel_count, 0); const sumChannels = nodes.reduce((partialSum, a) => partialSum + a.opened_channel_count, 0);
this.openGraphService.waitOver('ln-group-data-' + this.slug); this.openGraphService.waitOver({ event: 'ln-group-data-' + this.slug, sessionId: this.ogSession });
return { return {
nodes: nodes, nodes: nodes,
@ -109,8 +111,8 @@ export class GroupPreviewComponent implements OnInit {
}), }),
catchError(() => { catchError(() => {
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('ln-group-map-' + this.slug); this.openGraphService.fail({ event: 'ln-group-map-' + this.slug, sessionId: this.ogSession });
this.openGraphService.fail('ln-group-data-' + this.slug); this.openGraphService.fail({ event: 'ln-group-data-' + this.slug, sessionId: this.ogSession });
return of({ return of({
nodes: [], nodes: [],
sumLiquidity: 0, sumLiquidity: 0,
@ -121,7 +123,7 @@ export class GroupPreviewComponent implements OnInit {
} }
onMapReady(): void { onMapReady(): void {
this.openGraphService.waitOver('ln-group-map-' + this.slug); this.openGraphService.waitOver({ event: 'ln-group-map-' + this.slug, sessionId: this.ogSession });
} }
} }

View File

@ -27,6 +27,8 @@ export class NodePreviewComponent implements OnInit {
publicKeySize = 99; publicKeySize = 99;
ogSession: number;
constructor( constructor(
private lightningApiService: LightningApiService, private lightningApiService: LightningApiService,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
@ -43,8 +45,8 @@ export class NodePreviewComponent implements OnInit {
.pipe( .pipe(
switchMap((params: ParamMap) => { switchMap((params: ParamMap) => {
this.publicKey = params.get('public_key'); this.publicKey = params.get('public_key');
this.openGraphService.waitFor('node-map-' + this.publicKey); this.ogSession = this.openGraphService.waitFor('node-map-' + this.publicKey);
this.openGraphService.waitFor('node-data-' + this.publicKey); this.ogSession = this.openGraphService.waitFor('node-data-' + this.publicKey);
return this.lightningApiService.getNode$(params.get('public_key')); return this.lightningApiService.getNode$(params.get('public_key'));
}), }),
map((node) => { map((node) => {
@ -76,15 +78,15 @@ export class NodePreviewComponent implements OnInit {
this.socketTypes = Object.keys(socketTypesMap); this.socketTypes = Object.keys(socketTypesMap);
node.avgCapacity = node.capacity / Math.max(1, node.active_channel_count); node.avgCapacity = node.capacity / Math.max(1, node.active_channel_count);
this.openGraphService.waitOver('node-data-' + this.publicKey); this.openGraphService.waitOver({ event: 'node-data-' + this.publicKey, sessionId: this.ogSession });
return node; return node;
}), }),
catchError(err => { catchError(err => {
this.error = err; this.error = err;
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('node-map-' + this.publicKey); this.openGraphService.fail({ event: 'node-map-' + this.publicKey, sessionId: this.ogSession });
this.openGraphService.fail('node-data-' + this.publicKey); this.openGraphService.fail({ event: 'node-data-' + this.publicKey, sessionId: this.ogSession });
return [{ return [{
alias: this.publicKey, alias: this.publicKey,
public_key: this.publicKey, public_key: this.publicKey,
@ -102,6 +104,6 @@ export class NodePreviewComponent implements OnInit {
} }
onMapReady() { onMapReady() {
this.openGraphService.waitOver('node-map-' + this.publicKey); this.openGraphService.waitOver({ event: 'node-map-' + this.publicKey, sessionId: this.ogSession });
} }
} }

View File

@ -19,6 +19,8 @@ export class NodesPerISPPreview implements OnInit {
id: string; id: string;
error: Error; error: Error;
ogSession: number;
constructor( constructor(
private apiService: ApiService, private apiService: ApiService,
private seoService: SeoService, private seoService: SeoService,
@ -32,8 +34,8 @@ export class NodesPerISPPreview implements OnInit {
switchMap((params: ParamMap) => { switchMap((params: ParamMap) => {
this.id = params.get('isp'); this.id = params.get('isp');
this.isp = null; this.isp = null;
this.openGraphService.waitFor('isp-map-' + this.id); this.ogSession = this.openGraphService.waitFor('isp-map-' + this.id);
this.openGraphService.waitFor('isp-data-' + this.id); this.ogSession = this.openGraphService.waitFor('isp-data-' + this.id);
return this.apiService.getNodeForISP$(params.get('isp')); return this.apiService.getNodeForISP$(params.get('isp'));
}), }),
map(response => { map(response => {
@ -75,7 +77,7 @@ export class NodesPerISPPreview implements OnInit {
} }
topCountry.flag = getFlagEmoji(topCountry.iso); topCountry.flag = getFlagEmoji(topCountry.iso);
this.openGraphService.waitOver('isp-data-' + this.id); this.openGraphService.waitOver({ event: 'isp-data-' + this.id, sessionId: this.ogSession });
return { return {
nodes: response.nodes, nodes: response.nodes,
@ -87,8 +89,8 @@ export class NodesPerISPPreview implements OnInit {
catchError(err => { catchError(err => {
this.error = err; this.error = err;
this.seoService.logSoft404(); this.seoService.logSoft404();
this.openGraphService.fail('isp-map-' + this.id); this.openGraphService.fail({ event: 'isp-map-' + this.id, sessionId: this.ogSession });
this.openGraphService.fail('isp-data-' + this.id); this.openGraphService.fail({ event: 'isp-data-' + this.id, sessionId: this.ogSession });
return of({ return of({
nodes: [], nodes: [],
sumLiquidity: 0, sumLiquidity: 0,
@ -100,6 +102,6 @@ export class NodesPerISPPreview implements OnInit {
} }
onMapReady() { onMapReady() {
this.openGraphService.waitOver('isp-map-' + this.id); this.openGraphService.waitOver({ event: 'isp-map-' + this.id, sessionId: this.ogSession });
} }
} }

View File

@ -12,8 +12,9 @@ import { LanguageService } from '@app/services/language.service';
export class OpenGraphService { export class OpenGraphService {
network = ''; network = '';
defaultImageUrl = ''; defaultImageUrl = '';
previewLoadingEvents = {}; previewLoadingEvents = {}; // pending count per event type
previewLoadingCount = 0; previewLoadingCount = 0; // number of unique events pending
sessionId = 1;
constructor( constructor(
private ngZone: NgZone, private ngZone: NgZone,
@ -45,7 +46,7 @@ export class OpenGraphService {
// expose routing method to global scope, so we can access it from the unfurler // expose routing method to global scope, so we can access it from the unfurler
window['ogService'] = { window['ogService'] = {
loadPage: (path) => { return this.loadPage(path) } loadPage: (path) => { return this.loadPage(path); }
}; };
} }
@ -77,7 +78,7 @@ export class OpenGraphService {
} }
/// register an event that needs to resolve before we can take a screenshot /// register an event that needs to resolve before we can take a screenshot
waitFor(event) { waitFor(event: string): number {
if (!this.previewLoadingEvents[event]) { if (!this.previewLoadingEvents[event]) {
this.previewLoadingEvents[event] = 1; this.previewLoadingEvents[event] = 1;
this.previewLoadingCount++; this.previewLoadingCount++;
@ -85,24 +86,31 @@ export class OpenGraphService {
this.previewLoadingEvents[event]++; this.previewLoadingEvents[event]++;
} }
this.metaService.updateTag({ property: 'og:preview:loading', content: 'loading'}); this.metaService.updateTag({ property: 'og:preview:loading', content: 'loading'});
return this.sessionId;
} }
// mark an event as resolved // mark an event as resolved
// if all registered events have resolved, signal we are ready for a screenshot // if all registered events have resolved, signal we are ready for a screenshot
waitOver(event) { waitOver({ event, sessionId }: { event: string, sessionId: number }) {
if (sessionId !== this.sessionId) {
return;
}
if (this.previewLoadingEvents[event]) { if (this.previewLoadingEvents[event]) {
this.previewLoadingEvents[event]--; this.previewLoadingEvents[event]--;
if (this.previewLoadingEvents[event] === 0 && this.previewLoadingCount > 0) { if (this.previewLoadingEvents[event] === 0 && this.previewLoadingCount > 0) {
delete this.previewLoadingEvents[event] delete this.previewLoadingEvents[event];
this.previewLoadingCount--; this.previewLoadingCount--;
} }
if (this.previewLoadingCount === 0) { }
this.metaService.updateTag({ property: 'og:preview:ready', content: 'ready'}); if (this.previewLoadingCount === 0) {
} this.metaService.updateTag({ property: 'og:preview:ready', content: 'ready'});
} }
} }
fail(event) { fail({ event, sessionId }: { event: string, sessionId: number }) {
if (sessionId !== this.sessionId) {
return;
}
if (this.previewLoadingEvents[event]) { if (this.previewLoadingEvents[event]) {
this.metaService.updateTag({ property: 'og:preview:fail', content: 'fail'}); this.metaService.updateTag({ property: 'og:preview:fail', content: 'fail'});
} }
@ -111,6 +119,7 @@ export class OpenGraphService {
resetLoading() { resetLoading() {
this.previewLoadingEvents = {}; this.previewLoadingEvents = {};
this.previewLoadingCount = 0; this.previewLoadingCount = 0;
this.sessionId++;
this.metaService.removeTag("property='og:preview:loading'"); this.metaService.removeTag("property='og:preview:loading'");
this.metaService.removeTag("property='og:preview:ready'"); this.metaService.removeTag("property='og:preview:ready'");
this.metaService.removeTag("property='og:preview:fail'"); this.metaService.removeTag("property='og:preview:fail'");
@ -122,7 +131,7 @@ export class OpenGraphService {
this.resetLoading(); this.resetLoading();
this.ngZone.run(() => { this.ngZone.run(() => {
this.router.navigateByUrl(path); this.router.navigateByUrl(path);
}) });
} }
} }
} }