commit
						4142413002
					
				@ -12,19 +12,26 @@
 | 
			
		||||
  "dashboard": {
 | 
			
		||||
    "widgets": [
 | 
			
		||||
      {
 | 
			
		||||
        "component": "fees"
 | 
			
		||||
        "component": "fees",
 | 
			
		||||
        "mobileOrder": 4
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "component": "balance",
 | 
			
		||||
        "mobileOrder": 1,
 | 
			
		||||
        "props": {
 | 
			
		||||
          "address": "32ixEdVJWo3kmvJGMTZq5jAQVZZeuwnqzo"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "component": "goggles"
 | 
			
		||||
        "component": "twitter",
 | 
			
		||||
        "mobileOrder": 5,
 | 
			
		||||
        "props": {
 | 
			
		||||
          "handle": "bitcoinofficesv"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "component": "address",
 | 
			
		||||
        "mobileOrder": 2,
 | 
			
		||||
        "props": {
 | 
			
		||||
          "address": "32ixEdVJWo3kmvJGMTZq5jAQVZZeuwnqzo",
 | 
			
		||||
          "period": "1m"
 | 
			
		||||
@ -35,6 +42,7 @@
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "component": "addressTransactions",
 | 
			
		||||
        "mobileOrder": 3,
 | 
			
		||||
        "props": {
 | 
			
		||||
          "address": "32ixEdVJWo3kmvJGMTZq5jAQVZZeuwnqzo"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
    @for (widget of widgets; track widget.component) {
 | 
			
		||||
      @switch (widget.component) {
 | 
			
		||||
        @case ('fees') {
 | 
			
		||||
          <div class="col card-wrapper">
 | 
			
		||||
          <div class="col card-wrapper" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="main-title" i18n="fees-box.transaction-fees">Transaction Fees</div>
 | 
			
		||||
            <div class="card">
 | 
			
		||||
              <div class="card-body less-padding">
 | 
			
		||||
@ -14,12 +14,12 @@
 | 
			
		||||
          </div>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('difficulty') {
 | 
			
		||||
          <div class="col">
 | 
			
		||||
          <div class="col" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <app-difficulty></app-difficulty>
 | 
			
		||||
          </div>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('goggles') {
 | 
			
		||||
          <div class="col">
 | 
			
		||||
          <div class="col" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="card graph-card">
 | 
			
		||||
              <div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2">
 | 
			
		||||
                <a class="title-link mb-0" style="margin-top: -2px" href="" [routerLink]="['/mempool-block/0' | relativeUrl]">
 | 
			
		||||
@ -48,7 +48,7 @@
 | 
			
		||||
          </div>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('incoming') {
 | 
			
		||||
          <div class="col">
 | 
			
		||||
          <div class="col" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="card graph-card">
 | 
			
		||||
              <div class="card-body">
 | 
			
		||||
                <ng-container *ngTemplateOutlet="mempoolTable; context: { $implicit: mempoolInfoData }"></ng-container>
 | 
			
		||||
@ -93,7 +93,7 @@
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('replacements') {
 | 
			
		||||
          <div class="col" style="max-height: 410px">
 | 
			
		||||
          <div class="col" style="max-height: 410px" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="card">
 | 
			
		||||
              <div class="card-body">
 | 
			
		||||
                <a class="title-link" href="" [routerLink]="['/rbf' | relativeUrl]">
 | 
			
		||||
@ -140,7 +140,7 @@
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('blocks') {
 | 
			
		||||
          <div class="col" style="max-height: 410px">
 | 
			
		||||
          <div class="col" style="max-height: 410px" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="card">
 | 
			
		||||
              <div class="card-body">
 | 
			
		||||
                <a class="title-link" href="" [routerLink]="['/blocks' | relativeUrl]">
 | 
			
		||||
@ -184,7 +184,7 @@
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('transactions') {
 | 
			
		||||
          <div class="col" style="max-height: 410px">
 | 
			
		||||
          <div class="col" style="max-height: 410px" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="card">
 | 
			
		||||
              <div class="card-body">
 | 
			
		||||
                <h5 class="card-title" i18n="dashboard.recent-transactions">Recent Transactions</h5>
 | 
			
		||||
@ -224,13 +224,13 @@
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('balance') {
 | 
			
		||||
          <div class="col card-wrapper">
 | 
			
		||||
          <div class="col card-wrapper" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="main-title" i18n="dashboard.treasury">Treasury</div>
 | 
			
		||||
            <app-balance-widget [address]="widget.props.address" [addressSummary$]="addressSummary$" [addressInfo]="address"></app-balance-widget>
 | 
			
		||||
          </div>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('address') {
 | 
			
		||||
          <div class="col" style="max-height: 410px">
 | 
			
		||||
          <div class="col" style="max-height: 410px" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="card graph-card">
 | 
			
		||||
              <div class="card-body">
 | 
			
		||||
                <a class="title-link" href="" [routerLink]="[('/address/' + widget.props.address) | relativeUrl]">
 | 
			
		||||
@ -244,7 +244,7 @@
 | 
			
		||||
          </div>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('addressTransactions') {
 | 
			
		||||
          <div class="col" style="max-height: 410px">
 | 
			
		||||
          <div class="col" style="max-height: 410px" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="card">
 | 
			
		||||
              <div class="card-body">
 | 
			
		||||
                <a class="title-link" href="" [routerLink]="[('/address/' + widget.props.address) | relativeUrl]">
 | 
			
		||||
@ -257,6 +257,22 @@
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        }
 | 
			
		||||
        @case ('twitter') {
 | 
			
		||||
          <div class="col" style="min-height:410px" [style.order]="isMobile && widget.mobileOrder || 8">
 | 
			
		||||
            <div class="card graph-card">
 | 
			
		||||
              <div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2 d-flex flex-column">
 | 
			
		||||
                <a class="title-link" [href]="'https://x.com/' + widget.props?.handle" target="_blank">
 | 
			
		||||
                  <h5 class="card-title d-inline" i18n="dashboard.x-timeline">X Timeline</h5>
 | 
			
		||||
                  <span> </span>
 | 
			
		||||
                  <fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: text-top; font-size: 13px; color: var(--title-fg)"></fa-icon>
 | 
			
		||||
                </a>
 | 
			
		||||
                @defer {
 | 
			
		||||
                  <app-twitter-widget [handle]="widget.props?.handle" style="flex-grow: 1"></app-twitter-widget>
 | 
			
		||||
                }
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,7 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni
 | 
			
		||||
  incomingGraphHeight: number = 300;
 | 
			
		||||
  graphHeight: number = 300;
 | 
			
		||||
  webGlEnabled = true;
 | 
			
		||||
  isMobile: boolean = window.innerWidth <= 767.98;
 | 
			
		||||
 | 
			
		||||
  widgets;
 | 
			
		||||
 | 
			
		||||
@ -370,5 +371,6 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni
 | 
			
		||||
      this.goggleResolution = 86;
 | 
			
		||||
      this.graphHeight = 310;
 | 
			
		||||
    }
 | 
			
		||||
    this.isMobile = window.innerWidth <= 767.98;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,16 @@
 | 
			
		||||
@if (loading) {
 | 
			
		||||
  <div class="spinner-wrapper">
 | 
			
		||||
    <div class="ml-2 spinner-border text-light" style="width: 25px; height: 25px"></div>
 | 
			
		||||
  </div>
 | 
			
		||||
} @else if (error) {
 | 
			
		||||
  <div class="error-wrapper">
 | 
			
		||||
    <span>failed to load X timeline</span>
 | 
			
		||||
  </div>
 | 
			
		||||
}
 | 
			
		||||
<iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true"
 | 
			
		||||
  title="Twitter Timeline"
 | 
			
		||||
  [src]="iframeSrc"
 | 
			
		||||
  style="position: static; visibility: visible; width: 100%; height: 100%; display: block; flex-grow: 1;"
 | 
			
		||||
  (load)="onReady()"
 | 
			
		||||
></iframe>
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,10 @@
 | 
			
		||||
.spinner-wrapper, .error-wrapper {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,65 @@
 | 
			
		||||
import { Component, Input, ChangeDetectionStrategy, SecurityContext } from '@angular/core';
 | 
			
		||||
import { LanguageService } from '../../services/language.service';
 | 
			
		||||
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-twitter-widget',
 | 
			
		||||
  templateUrl: './twitter-widget.component.html',
 | 
			
		||||
  styleUrls: ['./twitter-widget.component.scss'],
 | 
			
		||||
  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
			
		||||
})
 | 
			
		||||
export class TwitterWidgetComponent {
 | 
			
		||||
  @Input() handle: string;
 | 
			
		||||
  @Input() width = 300;
 | 
			
		||||
  @Input() height = 400;
 | 
			
		||||
 | 
			
		||||
  loading: boolean = true;
 | 
			
		||||
  error: boolean = false;
 | 
			
		||||
  lang: string = 'en';
 | 
			
		||||
 | 
			
		||||
  iframeSrc: SafeResourceUrl;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private languageService: LanguageService,
 | 
			
		||||
    public sanitizer: DomSanitizer,
 | 
			
		||||
  ) {
 | 
			
		||||
    this.lang = this.languageService.getLanguage();
 | 
			
		||||
    this.setIframeSrc();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setIframeSrc(): void {
 | 
			
		||||
    this.iframeSrc = this.sanitizer.bypassSecurityTrustResourceUrl(this.sanitizer.sanitize(SecurityContext.URL,
 | 
			
		||||
      'https://syndication.twitter.com/srv/timeline-profile/screen-name/bitcoinofficesv?creatorScreenName=mempool'
 | 
			
		||||
      + '&dnt=true'
 | 
			
		||||
      + '&embedId=twitter-widget-0'
 | 
			
		||||
      + '&features=eyJ0ZndfdGltZWxpbmVfbGlzdCI6eyJidWNrZXQiOltdLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X2ZvbGxvd2VyX2NvdW50X3N1bnNldCI6eyJidWNrZXQiOnRydWUsInZlcnNpb24iOm51bGx9LCJ0ZndfdHdlZXRfZWRpdF9iYWNrZW5kIjp7ImJ1Y2tldCI6Im9uIiwidmVyc2lvbiI6bnVsbH0sInRmd19yZWZzcmNfc2Vzc2lvbiI6eyJidWNrZXQiOiJvbiIsInZlcnNpb24iOm51bGx9LCJ0ZndfZm9zbnJfc29mdF9pbnRlcnZlbnRpb25zX2VuYWJsZWQiOnsiYnVja2V0Ijoib24iLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X21peGVkX21lZGlhXzE1ODk3Ijp7ImJ1Y2tldCI6InRyZWF0bWVudCIsInZlcnNpb24iOm51bGx9LCJ0ZndfZXhwZXJpbWVudHNfY29va2llX2V4cGlyYXRpb24iOnsiYnVja2V0IjoxMjA5NjAwLCJ2ZXJzaW9uIjpudWxsfSwidGZ3X3Nob3dfYmlyZHdhdGNoX3Bpdm90c19lbmFibGVkIjp7ImJ1Y2tldCI6Im9uIiwidmVyc2lvbiI6bnVsbH0sInRmd19kdXBsaWNhdGVfc2NyaWJlc190b19zZXR0aW5ncyI6eyJidWNrZXQiOiJvbiIsInZlcnNpb24iOm51bGx9LCJ0ZndfdXNlX3Byb2ZpbGVfaW1hZ2Vfc2hhcGVfZW5hYmxlZCI6eyJidWNrZXQiOiJvbiIsInZlcnNpb24iOm51bGx9LCJ0ZndfdmlkZW9faGxzX2R5bmFtaWNfbWFuaWZlc3RzXzE1MDgyIjp7ImJ1Y2tldCI6InRydWVfYml0cmF0ZSIsInZlcnNpb24iOm51bGx9LCJ0ZndfbGVnYWN5X3RpbWVsaW5lX3N1bnNldCI6eyJidWNrZXQiOnRydWUsInZlcnNpb24iOm51bGx9LCJ0ZndfdHdlZXRfZWRpdF9mcm9udGVuZCI6eyJidWNrZXQiOiJvbiIsInZlcnNpb24iOm51bGx9fQ%3D%3D'
 | 
			
		||||
      + '&frame=false'
 | 
			
		||||
      + '&hideBorder=true'
 | 
			
		||||
      + '&hideFooter=false'
 | 
			
		||||
      + '&hideHeader=true'
 | 
			
		||||
      + '&hideScrollBar=false'
 | 
			
		||||
      + `&lang=${this.lang}`
 | 
			
		||||
      + '&maxHeight=500px'
 | 
			
		||||
      + '&origin=https%3A%2F%2Fmempool.space%2F'
 | 
			
		||||
      // + '&sessionId=88f6d661d0dcca99c43c0a590f6a3e61c89226a9'
 | 
			
		||||
      + '&showHeader=false'
 | 
			
		||||
      + '&showReplies=false'
 | 
			
		||||
      + '&siteScreenName=mempool'
 | 
			
		||||
      + '&theme=dark'
 | 
			
		||||
      + '&transparent=true'
 | 
			
		||||
      + '&widgetsVersion=2615f7e52b7e0%3A1702314776716'
 | 
			
		||||
    ));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onReady(): void {
 | 
			
		||||
    console.log('ready!');
 | 
			
		||||
    this.loading = false;
 | 
			
		||||
    this.error = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onFailed(): void {
 | 
			
		||||
    console.log('failed!')
 | 
			
		||||
    this.loading = false;
 | 
			
		||||
    this.error = true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -35,6 +35,7 @@ export interface Customization {
 | 
			
		||||
  dashboard: {
 | 
			
		||||
    widgets: {
 | 
			
		||||
      component: string;
 | 
			
		||||
      mobileOrder?: number;
 | 
			
		||||
      props: { [key: string]: any };
 | 
			
		||||
    }[];
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@ -113,6 +113,7 @@ import { ClockComponent } from '../components/clock/clock.component';
 | 
			
		||||
import { CalculatorComponent } from '../components/calculator/calculator.component';
 | 
			
		||||
import { BitcoinsatoshisPipe } from '../shared/pipes/bitcoinsatoshis.pipe';
 | 
			
		||||
import { HttpErrorComponent } from '../shared/components/http-error/http-error.component';
 | 
			
		||||
import { TwitterWidgetComponent } from '../components/twitter-widget/twitter-widget.component';
 | 
			
		||||
 | 
			
		||||
import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-directives/weight-directives';
 | 
			
		||||
 | 
			
		||||
@ -226,6 +227,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
 | 
			
		||||
    AccelerateCheckout,
 | 
			
		||||
    PendingStatsComponent,
 | 
			
		||||
    HttpErrorComponent,
 | 
			
		||||
    TwitterWidgetComponent,
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    CommonModule,
 | 
			
		||||
@ -354,6 +356,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
 | 
			
		||||
    AccelerateCheckout,
 | 
			
		||||
    PendingStatsComponent,
 | 
			
		||||
    HttpErrorComponent,
 | 
			
		||||
    TwitterWidgetComponent,
 | 
			
		||||
 | 
			
		||||
    MempoolBlockOverviewComponent,
 | 
			
		||||
    ClockchainComponent,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user