Merge pull request #4759 from mempool/hunicus/add-preview-imgs
Add page-specific preview images
@ -1,6 +1,7 @@
 | 
				
			|||||||
import { ChangeDetectionStrategy, Component, ElementRef, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core';
 | 
					import { ChangeDetectionStrategy, Component, ElementRef, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core';
 | 
				
			||||||
import { WebsocketService } from '../../services/websocket.service';
 | 
					import { WebsocketService } from '../../services/websocket.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
import { StateService } from '../../services/state.service';
 | 
					import { StateService } from '../../services/state.service';
 | 
				
			||||||
import { Observable } from 'rxjs';
 | 
					import { Observable } from 'rxjs';
 | 
				
			||||||
import { ApiService } from '../../services/api.service';
 | 
					import { ApiService } from '../../services/api.service';
 | 
				
			||||||
@ -33,6 +34,7 @@ export class AboutComponent implements OnInit {
 | 
				
			|||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private websocketService: WebsocketService,
 | 
					    private websocketService: WebsocketService,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
    public stateService: StateService,
 | 
					    public stateService: StateService,
 | 
				
			||||||
    private enterpriseService: EnterpriseService,
 | 
					    private enterpriseService: EnterpriseService,
 | 
				
			||||||
    private apiService: ApiService,
 | 
					    private apiService: ApiService,
 | 
				
			||||||
@ -46,6 +48,7 @@ export class AboutComponent implements OnInit {
 | 
				
			|||||||
    this.backendInfo$ = this.stateService.backendInfo$;
 | 
					    this.backendInfo$ = this.stateService.backendInfo$;
 | 
				
			||||||
    this.seoService.setTitle($localize`:@@004b222ff9ef9dd4771b777950ca1d0e4cd4348a:About`);
 | 
					    this.seoService.setTitle($localize`:@@004b222ff9ef9dd4771b777950ca1d0e4cd4348a:About`);
 | 
				
			||||||
    this.seoService.setDescription($localize`:@@meta.description.about:Learn more about The Mempool Open Source Project®\: enterprise sponsors, individual sponsors, integrations, who contributes, FOSS licensing, and more.`);
 | 
					    this.seoService.setDescription($localize`:@@meta.description.about:Learn more about The Mempool Open Source Project®\: enterprise sponsors, individual sponsors, integrations, who contributes, FOSS licensing, and more.`);
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('about.jpg');
 | 
				
			||||||
    this.websocketService.want(['blocks']);
 | 
					    this.websocketService.want(['blocks']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.profiles$ = this.apiService.getAboutPageProfiles$().pipe(
 | 
					    this.profiles$ = this.apiService.getAboutPageProfiles$().pipe(
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
import { ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core';
 | 
					import { ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core';
 | 
				
			||||||
import { SeoService } from '../../../services/seo.service';
 | 
					import { SeoService } from '../../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../../services/opengraph.service';
 | 
				
			||||||
import { WebsocketService } from '../../../services/websocket.service';
 | 
					import { WebsocketService } from '../../../services/websocket.service';
 | 
				
			||||||
import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface';
 | 
					import { Acceleration, BlockExtended } from '../../../interfaces/node-api.interface';
 | 
				
			||||||
import { StateService } from '../../../services/state.service';
 | 
					import { StateService } from '../../../services/state.service';
 | 
				
			||||||
@ -34,11 +35,13 @@ export class AcceleratorDashboardComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
    private websocketService: WebsocketService,
 | 
					    private websocketService: WebsocketService,
 | 
				
			||||||
    private serviceApiServices: ServicesApiServices,
 | 
					    private serviceApiServices: ServicesApiServices,
 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    this.seoService.setTitle($localize`:@@a681a4e2011bb28157689dbaa387de0dd0aa0c11:Accelerator Dashboard`);
 | 
					    this.seoService.setTitle($localize`:@@a681a4e2011bb28157689dbaa387de0dd0aa0c11:Accelerator Dashboard`);
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('accelerator.jpg');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@ import { ApiService } from '../../services/api.service';
 | 
				
			|||||||
import { StateService } from '../../services/state.service';
 | 
					import { StateService } from '../../services/state.service';
 | 
				
			||||||
import { WebsocketService } from '../../services/websocket.service';
 | 
					import { WebsocketService } from '../../services/websocket.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
import { seoDescriptionNetwork } from '../../shared/common.utils';
 | 
					import { seoDescriptionNetwork } from '../../shared/common.utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
@ -39,6 +40,7 @@ export class BlocksList implements OnInit {
 | 
				
			|||||||
    public stateService: StateService,
 | 
					    public stateService: StateService,
 | 
				
			||||||
    private cd: ChangeDetectorRef,
 | 
					    private cd: ChangeDetectorRef,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    this.isMempoolModule = this.stateService.env.BASE_MODULE === 'mempool';
 | 
					    this.isMempoolModule = this.stateService.env.BASE_MODULE === 'mempool';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -57,6 +59,7 @@ export class BlocksList implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (!this.widget) {
 | 
					    if (!this.widget) {
 | 
				
			||||||
      this.seoService.setTitle($localize`:@@m8a7b4bd44c0ac71b2e72de0398b303257f7d2f54:Blocks`);
 | 
					      this.seoService.setTitle($localize`:@@m8a7b4bd44c0ac71b2e72de0398b303257f7d2f54:Blocks`);
 | 
				
			||||||
 | 
					      this.ogService.setManualOgImage('recent-blocks.jpg');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if( this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet' ) {
 | 
					    if( this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet' ) {
 | 
				
			||||||
      this.seoService.setDescription($localize`:@@meta.description.liquid.blocks:See the most recent Liquid${seoDescriptionNetwork(this.stateService.network)} blocks along with basic stats such as block height, block size, and more.`);
 | 
					      this.seoService.setDescription($localize`:@@meta.description.liquid.blocks:See the most recent Liquid${seoDescriptionNetwork(this.stateService.network)} blocks along with basic stats such as block height, block size, and more.`);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core';
 | 
					import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
import { WebsocketService } from '../../services/websocket.service';
 | 
					import { WebsocketService } from '../../services/websocket.service';
 | 
				
			||||||
import { StateService } from '../../services/state.service';
 | 
					import { StateService } from '../../services/state.service';
 | 
				
			||||||
import { EventType, NavigationStart, Router } from '@angular/router';
 | 
					import { EventType, NavigationStart, Router } from '@angular/router';
 | 
				
			||||||
@ -15,12 +16,14 @@ export class MiningDashboardComponent implements OnInit, AfterViewInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
    private websocketService: WebsocketService,
 | 
					    private websocketService: WebsocketService,
 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
    private router: Router
 | 
					    private router: Router
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    this.seoService.setTitle($localize`:@@a681a4e2011bb28157689dbaa387de0dd0aa0c11:Mining Dashboard`);
 | 
					    this.seoService.setTitle($localize`:@@a681a4e2011bb28157689dbaa387de0dd0aa0c11:Mining Dashboard`);
 | 
				
			||||||
    this.seoService.setDescription($localize`:@@meta.description.mining.dashboard:Get real-time Bitcoin mining stats like hashrate, difficulty adjustment, block rewards, pool dominance, and more.`);
 | 
					    this.seoService.setDescription($localize`:@@meta.description.mining.dashboard:Get real-time Bitcoin mining stats like hashrate, difficulty adjustment, block rewards, pool dominance, and more.`);
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('mining.jpg');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
import { Component } from '@angular/core';
 | 
					import { Component } from '@angular/core';
 | 
				
			||||||
import { Env, StateService } from '../../services/state.service';
 | 
					import { Env, StateService } from '../../services/state.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-privacy-policy',
 | 
					  selector: 'app-privacy-policy',
 | 
				
			||||||
@ -13,10 +14,12 @@ export class PrivacyPolicyComponent {
 | 
				
			|||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    this.seoService.setTitle('Privacy Policy');
 | 
					    this.seoService.setTitle('Privacy Policy');
 | 
				
			||||||
    this.seoService.setDescription('Trusted third parties are security holes, as are trusted first parties...you should only trust your own self-hosted instance of The Mempool Open Source Project®.');
 | 
					    this.seoService.setDescription('Trusted third parties are security holes, as are trusted first parties...you should only trust your own self-hosted instance of The Mempool Open Source Project®.');
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('privacy.jpg');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms
 | 
				
			|||||||
import { ApiService } from '../../services/api.service';
 | 
					import { ApiService } from '../../services/api.service';
 | 
				
			||||||
import { StateService } from '../../services/state.service';
 | 
					import { StateService } from '../../services/state.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
import { seoDescriptionNetwork } from '../../shared/common.utils';
 | 
					import { seoDescriptionNetwork } from '../../shared/common.utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
@ -21,6 +22,7 @@ export class PushTransactionComponent implements OnInit {
 | 
				
			|||||||
    private apiService: ApiService,
 | 
					    private apiService: ApiService,
 | 
				
			||||||
    public stateService: StateService,
 | 
					    public stateService: StateService,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
@ -30,6 +32,7 @@ export class PushTransactionComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    this.seoService.setTitle($localize`:@@meta.title.push-tx:Broadcast Transaction`);
 | 
					    this.seoService.setTitle($localize`:@@meta.title.push-tx:Broadcast Transaction`);
 | 
				
			||||||
    this.seoService.setDescription($localize`:@@meta.description.push-tx:Broadcast a transaction to the ${this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'}${seoDescriptionNetwork(this.stateService.network)} network using the transaction's hash.`);
 | 
					    this.seoService.setDescription($localize`:@@meta.description.push-tx:Broadcast a transaction to the ${this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'}${seoDescriptionNetwork(this.stateService.network)} network using the transaction's hash.`);
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('broadcast-tx.jpg');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  postTx() {
 | 
					  postTx() {
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@ import { RbfTree } from '../../interfaces/node-api.interface';
 | 
				
			|||||||
import { ApiService } from '../../services/api.service';
 | 
					import { ApiService } from '../../services/api.service';
 | 
				
			||||||
import { StateService } from '../../services/state.service';
 | 
					import { StateService } from '../../services/state.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
import { seoDescriptionNetwork } from '../../shared/common.utils';
 | 
					import { seoDescriptionNetwork } from '../../shared/common.utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
@ -29,6 +30,7 @@ export class RbfList implements OnInit, OnDestroy {
 | 
				
			|||||||
    public stateService: StateService,
 | 
					    public stateService: StateService,
 | 
				
			||||||
    private websocketService: WebsocketService,
 | 
					    private websocketService: WebsocketService,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
@ -57,6 +59,7 @@ export class RbfList implements OnInit, OnDestroy {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    this.seoService.setTitle($localize`:@@5e3d5a82750902f159122fcca487b07f1af3141f:RBF Replacements`);
 | 
					    this.seoService.setTitle($localize`:@@5e3d5a82750902f159122fcca487b07f1af3141f:RBF Replacements`);
 | 
				
			||||||
    this.seoService.setDescription($localize`:@@meta.description.rbf-list:See the most recent RBF replacements on the Bitcoin${seoDescriptionNetwork(this.stateService.network)} network, updated in real-time.`);
 | 
					    this.seoService.setDescription($localize`:@@meta.description.rbf-list:See the most recent RBF replacements on the Bitcoin${seoDescriptionNetwork(this.stateService.network)} network, updated in real-time.`);
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('rbf.jpg');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnDestroy(): void {
 | 
					  ngOnDestroy(): void {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
import { Component } from '@angular/core';
 | 
					import { Component } from '@angular/core';
 | 
				
			||||||
import { Env, StateService } from '../../services/state.service';
 | 
					import { Env, StateService } from '../../services/state.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-terms-of-service',
 | 
					  selector: 'app-terms-of-service',
 | 
				
			||||||
@ -12,10 +13,12 @@ export class TermsOfServiceComponent {
 | 
				
			|||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    this.seoService.setTitle('Terms of Service');
 | 
					    this.seoService.setTitle('Terms of Service');
 | 
				
			||||||
    this.seoService.setDescription('Out of respect for the Bitcoin community, the mempool.space website is Bitcoin Only and does not display any advertising.');
 | 
					    this.seoService.setDescription('Out of respect for the Bitcoin community, the mempool.space website is Bitcoin Only and does not display any advertising.');
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('tos.jpg');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
import { Component } from '@angular/core';
 | 
					import { Component } from '@angular/core';
 | 
				
			||||||
import { Env, StateService } from '../../services/state.service';
 | 
					import { Env, StateService } from '../../services/state.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-trademark-policy',
 | 
					  selector: 'app-trademark-policy',
 | 
				
			||||||
@ -13,10 +14,12 @@ export class TrademarkPolicyComponent {
 | 
				
			|||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    this.seoService.setTitle('Trademark Policy');
 | 
					    this.seoService.setTitle('Trademark Policy');
 | 
				
			||||||
    this.seoService.setDescription('An overview of the trademarks registered by Mempool Space K.K. and The Mempool Open Source Project® and what we consider to be lawful usage of those trademarks.');
 | 
					    this.seoService.setDescription('An overview of the trademarks registered by Mempool Space K.K. and The Mempool Open Source Project® and what we consider to be lawful usage of those trademarks.');
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('trademark-policy.jpg');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ import { ActivatedRoute } from '@angular/router';
 | 
				
			|||||||
import { Env, StateService } from '../../services/state.service';
 | 
					import { Env, StateService } from '../../services/state.service';
 | 
				
			||||||
import { WebsocketService } from '../../services/websocket.service';
 | 
					import { WebsocketService } from '../../services/websocket.service';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-docs',
 | 
					  selector: 'app-docs',
 | 
				
			||||||
@ -24,6 +25,7 @@ export class DocsComponent implements OnInit {
 | 
				
			|||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
    private websocket: WebsocketService,
 | 
					    private websocket: WebsocketService,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
@ -44,6 +46,7 @@ export class DocsComponent implements OnInit {
 | 
				
			|||||||
      this.activeTab = 0;
 | 
					      this.activeTab = 0;
 | 
				
			||||||
      this.seoService.setTitle($localize`:@@meta.title.docs.faq:FAQ`);
 | 
					      this.seoService.setTitle($localize`:@@meta.title.docs.faq:FAQ`);
 | 
				
			||||||
      this.seoService.setDescription($localize`:@@meta.description.docs.faq:Get answers to common questions like: What is a mempool? Why isn't my transaction confirming? How can I run my own instance of The Mempool Open Source Project? And more.`);
 | 
					      this.seoService.setDescription($localize`:@@meta.description.docs.faq:Get answers to common questions like: What is a mempool? Why isn't my transaction confirming? How can I run my own instance of The Mempool Open Source Project? And more.`);
 | 
				
			||||||
 | 
					      this.ogService.setManualOgImage('faq.jpg');
 | 
				
			||||||
    } else if( url[1].path === "rest" ) {
 | 
					    } else if( url[1].path === "rest" ) {
 | 
				
			||||||
      this.activeTab = 1;
 | 
					      this.activeTab = 1;
 | 
				
			||||||
      this.seoService.setTitle($localize`:@@meta.title.docs.rest:REST API`);
 | 
					      this.seoService.setTitle($localize`:@@meta.title.docs.rest:REST API`);
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ import { Observable } from 'rxjs';
 | 
				
			|||||||
import { share } from 'rxjs/operators';
 | 
					import { share } from 'rxjs/operators';
 | 
				
			||||||
import { INodesRanking, INodesStatistics } from '../../interfaces/node-api.interface';
 | 
					import { INodesRanking, INodesStatistics } from '../../interfaces/node-api.interface';
 | 
				
			||||||
import { SeoService } from '../../services/seo.service';
 | 
					import { SeoService } from '../../services/seo.service';
 | 
				
			||||||
 | 
					import { OpenGraphService } from '../../services/opengraph.service';
 | 
				
			||||||
import { StateService } from '../../services/state.service';
 | 
					import { StateService } from '../../services/state.service';
 | 
				
			||||||
import { LightningApiService } from '../lightning-api.service';
 | 
					import { LightningApiService } from '../lightning-api.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,14 +22,16 @@ export class LightningDashboardComponent implements OnInit, AfterViewInit {
 | 
				
			|||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private lightningApiService: LightningApiService,
 | 
					    private lightningApiService: LightningApiService,
 | 
				
			||||||
    private seoService: SeoService,
 | 
					    private seoService: SeoService,
 | 
				
			||||||
 | 
					    private ogService: OpenGraphService,
 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    this.onResize();
 | 
					    this.onResize();
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    this.seoService.setTitle($localize`:@@142e923d3b04186ac6ba23387265d22a2fa404e0:Lightning Explorer`);
 | 
					    this.seoService.setTitle($localize`:@@142e923d3b04186ac6ba23387265d22a2fa404e0:Lightning Explorer`);
 | 
				
			||||||
    this.seoService.setDescription($localize`:@@meta.description.lightning.dashboard:Get stats on the Lightning network (aggregate capacity, connectivity, etc), Lightning nodes (channels, liquidity, etc) and Lightning channels (status, fees, etc).`);
 | 
					    this.seoService.setDescription($localize`:@@meta.description.lightning.dashboard:Get stats on the Lightning network (aggregate capacity, connectivity, etc), Lightning nodes (channels, liquidity, etc) and Lightning channels (status, fees, etc).`);
 | 
				
			||||||
 | 
					    this.ogService.setManualOgImage('lightning.jpg');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.nodesRanking$ = this.lightningApiService.getNodesRanking$().pipe(share());
 | 
					    this.nodesRanking$ = this.lightningApiService.getNodesRanking$().pipe(share());
 | 
				
			||||||
    this.statistics$ = this.lightningApiService.getLatestStatistics$().pipe(share());
 | 
					    this.statistics$ = this.lightningApiService.getLatestStatistics$().pipe(share());
 | 
				
			||||||
 | 
				
			|||||||
@ -25,7 +25,7 @@ export class OpenGraphService {
 | 
				
			|||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    // save og:image tag from original template
 | 
					    // save og:image tag from original template
 | 
				
			||||||
    const initialOgImageTag = metaService.getTag("property='og:image'");
 | 
					    const initialOgImageTag = metaService.getTag("property='og:image'");
 | 
				
			||||||
    this.defaultImageUrl = initialOgImageTag?.content || 'https://mempool.space/resources/mempool-space-preview.png';
 | 
					    this.defaultImageUrl = initialOgImageTag?.content || 'https://mempool.space/resources/previews/mempool-space-preview.jpg';
 | 
				
			||||||
    this.router.events.pipe(
 | 
					    this.router.events.pipe(
 | 
				
			||||||
      filter(event => event instanceof NavigationEnd),
 | 
					      filter(event => event instanceof NavigationEnd),
 | 
				
			||||||
      map(() => this.activatedRoute),
 | 
					      map(() => this.activatedRoute),
 | 
				
			||||||
@ -53,7 +53,7 @@ export class OpenGraphService {
 | 
				
			|||||||
    const lang = this.LanguageService.getLanguage();
 | 
					    const lang = this.LanguageService.getLanguage();
 | 
				
			||||||
    const ogImageUrl = `${window.location.protocol}//${window.location.host}/render/${lang}/preview${this.router.url}`;
 | 
					    const ogImageUrl = `${window.location.protocol}//${window.location.host}/render/${lang}/preview${this.router.url}`;
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:image', content: ogImageUrl });
 | 
					    this.metaService.updateTag({ property: 'og:image', content: ogImageUrl });
 | 
				
			||||||
    this.metaService.updateTag({ property: 'twitter:image:src', content: ogImageUrl });
 | 
					    this.metaService.updateTag({ name: 'twitter:image', content: ogImageUrl });
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:image:type', content: 'image/png' });
 | 
					    this.metaService.updateTag({ property: 'og:image:type', content: 'image/png' });
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:image:width', content: '1200' });
 | 
					    this.metaService.updateTag({ property: 'og:image:width', content: '1200' });
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:image:height', content: '600' });
 | 
					    this.metaService.updateTag({ property: 'og:image:height', content: '600' });
 | 
				
			||||||
@ -61,12 +61,21 @@ export class OpenGraphService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  clearOgImage() {
 | 
					  clearOgImage() {
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:image', content: this.defaultImageUrl });
 | 
					    this.metaService.updateTag({ property: 'og:image', content: this.defaultImageUrl });
 | 
				
			||||||
    this.metaService.updateTag({ property: 'twitter:image:src', content: this.defaultImageUrl });
 | 
					    this.metaService.updateTag({ name: 'twitter:image', content: this.defaultImageUrl });
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:image:type', content: 'image/png' });
 | 
					    this.metaService.updateTag({ property: 'og:image:type', content: 'image/png' });
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:image:width', content: '1000' });
 | 
					    this.metaService.updateTag({ property: 'og:image:width', content: '1000' });
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:image:height', content: '500' });
 | 
					    this.metaService.updateTag({ property: 'og:image:height', content: '500' });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setManualOgImage(imageFilename) {
 | 
				
			||||||
 | 
					    const ogImage = `${window.location.protocol}//${window.location.host}/resources/previews/${imageFilename}`;
 | 
				
			||||||
 | 
					    this.metaService.updateTag({ property: 'og:image', content: ogImage });
 | 
				
			||||||
 | 
					    this.metaService.updateTag({ property: 'og:image:type', content: 'image/jpeg' });
 | 
				
			||||||
 | 
					    this.metaService.updateTag({ property: 'og:image:width', content: '2000' });
 | 
				
			||||||
 | 
					    this.metaService.updateTag({ property: 'og:image:height', content: '1000' });
 | 
				
			||||||
 | 
					    this.metaService.updateTag({ name: 'twitter:image', content: ogImage });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// 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) {
 | 
				
			||||||
    if (!this.previewLoadingEvents[event]) {
 | 
					    if (!this.previewLoadingEvents[event]) {
 | 
				
			||||||
 | 
				
			|||||||
@ -39,14 +39,14 @@ export class SeoService {
 | 
				
			|||||||
  setTitle(newTitle: string): void {
 | 
					  setTitle(newTitle: string): void {
 | 
				
			||||||
    this.titleService.setTitle(newTitle + ' - ' + this.getTitle());
 | 
					    this.titleService.setTitle(newTitle + ' - ' + this.getTitle());
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:title', content: newTitle});
 | 
					    this.metaService.updateTag({ property: 'og:title', content: newTitle});
 | 
				
			||||||
    this.metaService.updateTag({ property: 'twitter:title', content: newTitle});
 | 
					    this.metaService.updateTag({ name: 'twitter:title', content: newTitle});
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:meta:ready', content: 'ready'});
 | 
					    this.metaService.updateTag({ property: 'og:meta:ready', content: 'ready'});
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  resetTitle(): void {
 | 
					  resetTitle(): void {
 | 
				
			||||||
    this.titleService.setTitle(this.getTitle());
 | 
					    this.titleService.setTitle(this.getTitle());
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:title', content: this.getTitle()});
 | 
					    this.metaService.updateTag({ property: 'og:title', content: this.getTitle()});
 | 
				
			||||||
    this.metaService.updateTag({ property: 'twitter:title', content: this.getTitle()});
 | 
					    this.metaService.updateTag({ name: 'twitter:title', content: this.getTitle()});
 | 
				
			||||||
    this.metaService.updateTag({ property: 'og:meta:ready', content: 'ready'});
 | 
					    this.metaService.updateTag({ property: 'og:meta:ready', content: 'ready'});
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,17 +8,17 @@
 | 
				
			|||||||
  <base href="/">
 | 
					  <base href="/">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <meta name="description" content="Explore the full Bitcoin ecosystem with The Mempool Open Source Project®. See the real-time status of your transactions, get network info, and more." />
 | 
					  <meta name="description" content="Explore the full Bitcoin ecosystem with The Mempool Open Source Project®. See the real-time status of your transactions, get network info, and more." />
 | 
				
			||||||
  <meta property="og:image" content="https://mempool.space/resources/mempool-space-preview.png" />
 | 
					  <meta property="og:image" content="https://mempool.space/resources/previews/mempool-space-preview.jpg" />
 | 
				
			||||||
  <meta property="og:image:type" content="image/png" />
 | 
					  <meta property="og:image:type" content="image/jpeg" />
 | 
				
			||||||
  <meta property="og:image:width" content="1000" />
 | 
					  <meta property="og:image:width" content="2000" />
 | 
				
			||||||
  <meta property="og:image:height" content="500" />
 | 
					  <meta property="og:image:height" content="1000" />
 | 
				
			||||||
  <meta property="og:description" content="Explore the full Bitcoin ecosystem with The Mempool Open Source Project®. See the real-time status of your transactions, get network info, and more." />
 | 
					  <meta property="og:description" content="Explore the full Bitcoin ecosystem with The Mempool Open Source Project®. See the real-time status of your transactions, get network info, and more." />
 | 
				
			||||||
  <meta name="twitter:card" content="summary_large_image">
 | 
					  <meta name="twitter:card" content="summary_large_image">
 | 
				
			||||||
  <meta name="twitter:site" content="@mempool">
 | 
					  <meta name="twitter:site" content="@mempool">
 | 
				
			||||||
  <meta name="twitter:creator" content="@mempool">
 | 
					  <meta name="twitter:creator" content="@mempool">
 | 
				
			||||||
  <meta name="twitter:title" content="The Mempool Open Source Project®">
 | 
					  <meta name="twitter:title" content="The Mempool Open Source Project®">
 | 
				
			||||||
  <meta name="twitter:description" content="Explore the full Bitcoin ecosystem with The Mempool Open Source Project®. See the real-time status of your transactions, get network info, and more." />
 | 
					  <meta name="twitter:description" content="Explore the full Bitcoin ecosystem with The Mempool Open Source Project®. See the real-time status of your transactions, get network info, and more." />
 | 
				
			||||||
  <meta name="twitter:image:src" content="https://mempool.space/resources/mempool-space-preview.png" />
 | 
					  <meta name="twitter:image" content="https://mempool.space/resources/previews/mempool-space-preview.jpg" />
 | 
				
			||||||
  <meta name="twitter:domain" content="mempool.space">
 | 
					  <meta name="twitter:domain" content="mempool.space">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <link rel="apple-touch-icon" sizes="180x180" href="/resources/favicons/apple-touch-icon.png">
 | 
					  <link rel="apple-touch-icon" sizes="180x180" href="/resources/favicons/apple-touch-icon.png">
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/about.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 73 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/accelerator.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 60 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/broadcast-tx.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 43 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/faq.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 44 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/lightning.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 114 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/mempool-space-preview.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 34 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/mining.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 113 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/privacy.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 95 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/rbf.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 60 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/recent-blocks.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 72 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/tos.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 108 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/src/resources/previews/trademark-policy.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 78 KiB  | 
@ -30,7 +30,7 @@ const routes = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  lightning: {
 | 
					  lightning: {
 | 
				
			||||||
    title: "Lightning",
 | 
					    title: "Lightning",
 | 
				
			||||||
    fallbackImg: '/resources/previews/lightning.png',
 | 
					    fallbackImg: '/resources/previews/lightning.jpg',
 | 
				
			||||||
    routes: {
 | 
					    routes: {
 | 
				
			||||||
      node: {
 | 
					      node: {
 | 
				
			||||||
        render: true,
 | 
					        render: true,
 | 
				
			||||||
@ -68,7 +68,7 @@ const routes = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  mining: {
 | 
					  mining: {
 | 
				
			||||||
    title: "Mining",
 | 
					    title: "Mining",
 | 
				
			||||||
    fallbackImg: '/resources/previews/mining.png',
 | 
					    fallbackImg: '/resources/previews/mining.jpg',
 | 
				
			||||||
    routes: {
 | 
					    routes: {
 | 
				
			||||||
      pool: {
 | 
					      pool: {
 | 
				
			||||||
        render: true,
 | 
					        render: true,
 | 
				
			||||||
@ -83,7 +83,7 @@ const routes = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const networks = {
 | 
					const networks = {
 | 
				
			||||||
  bitcoin: {
 | 
					  bitcoin: {
 | 
				
			||||||
    fallbackImg: '/resources/previews/dashboard.png',
 | 
					    fallbackImg: '/resources/previews/mempool-space-preview.jpg',
 | 
				
			||||||
    routes: {
 | 
					    routes: {
 | 
				
			||||||
      ...routes // all routes supported
 | 
					      ...routes // all routes supported
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -147,4 +147,4 @@ export function matchRoute(network: string, path: string): Match {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return match;
 | 
					  return match;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||