Merge pull request #3795 from mempool/nymkappa/accelerator-soft-launch
[accelerator] prepare soft launch
This commit is contained in:
		
						commit
						0ffbdef561
					
				@ -107,6 +107,7 @@ class Mining {
 | 
			
		||||
        slug: poolInfo.slug,
 | 
			
		||||
        avgMatchRate: poolInfo.avgMatchRate !== null ? Math.round(100 * poolInfo.avgMatchRate) / 100 : null,
 | 
			
		||||
        avgFeeDelta: poolInfo.avgFeeDelta,
 | 
			
		||||
        poolUniqueId: poolInfo.poolUniqueId
 | 
			
		||||
      };
 | 
			
		||||
      poolsStats.push(poolStat);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ export interface PoolInfo {
 | 
			
		||||
  slug: string;
 | 
			
		||||
  avgMatchRate: number | null;
 | 
			
		||||
  avgFeeDelta: number | null;
 | 
			
		||||
  poolUniqueId: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface PoolStats extends PoolInfo {
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,8 @@ class PoolsRepository {
 | 
			
		||||
          pools.link AS link,
 | 
			
		||||
          slug,
 | 
			
		||||
          AVG(blocks_audits.match_rate) AS avgMatchRate,
 | 
			
		||||
          AVG((CAST(blocks.fees as SIGNED) - CAST(blocks_audits.expected_fees as SIGNED)) / NULLIF(CAST(blocks_audits.expected_fees as SIGNED), 0)) AS avgFeeDelta
 | 
			
		||||
          AVG((CAST(blocks.fees as SIGNED) - CAST(blocks_audits.expected_fees as SIGNED)) / NULLIF(CAST(blocks_audits.expected_fees as SIGNED), 0)) AS avgFeeDelta,
 | 
			
		||||
          unique_id as poolUniqueId
 | 
			
		||||
      FROM blocks
 | 
			
		||||
      JOIN pools on pools.id = pool_id
 | 
			
		||||
      LEFT JOIN blocks_audits ON blocks_audits.height = blocks.height
 | 
			
		||||
 | 
			
		||||
@ -22,5 +22,6 @@
 | 
			
		||||
  "TESTNET_BLOCK_AUDIT_START_HEIGHT": 0,
 | 
			
		||||
  "SIGNET_BLOCK_AUDIT_START_HEIGHT": 0,
 | 
			
		||||
  "LIGHTNING": false,
 | 
			
		||||
  "HISTORICAL_PRICE": true
 | 
			
		||||
  "HISTORICAL_PRICE": true,
 | 
			
		||||
  "ACCELERATOR": false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,14 @@
 | 
			
		||||
    <track label="Português" kind="captions" srclang="pt" src="/resources/promo-video/pt.vtt" [attr.default]="showSubtitles('pt') ? '' : null">
 | 
			
		||||
  </video>
 | 
			
		||||
 | 
			
		||||
  <ng-container *ngIf="false && officialMempoolSpace">
 | 
			
		||||
    <h3 class="mt-5">Sponsor the project</h3>
 | 
			
		||||
    <div class="d-flex justify-content-center" style="max-width: 90%; margin: 35px auto 75px auto; column-gap: 15px">
 | 
			
		||||
      <a href="/sponsor" class="btn" style="background-color: rgba(152, 88, 255, 0.75); box-shadow: 0px 0px 50px 5px rgba(152, 88, 255, 0.75)" i18n="about.community-sponsor-button">Community</a>
 | 
			
		||||
      <a href="/enterprise" class="btn" style="background-color: rgba(152, 88, 255, 0.75); box-shadow: 0px 0px 50px 5px rgba(152, 88, 255, 0.75)" i18n="about.enterprise-sponsor-button">Enterprise</a>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ng-container>
 | 
			
		||||
 | 
			
		||||
  <div class="enterprise-sponsor" id="enterprise-sponsors">
 | 
			
		||||
    <h3 i18n="about.sponsors.enterprise.withRocket">Enterprise Sponsors 🚀</h3>
 | 
			
		||||
    <div class="wrapper">
 | 
			
		||||
@ -191,16 +199,41 @@
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="community-sponsor" id="community-sponsors">
 | 
			
		||||
    <h3 i18n="about.sponsors.withHeart">Community Sponsors ❤️</h3>
 | 
			
		||||
  <ng-container *ngIf="officialMempoolSpace">
 | 
			
		||||
    <div *ngIf="profiles$ | async as profiles" id="community-sponsors">
 | 
			
		||||
      <div class="community-sponsor" style="margin-bottom: 68px" *ngIf="profiles.whales.length > 0">
 | 
			
		||||
        <h3 i18n="about.sponsors.withHeart">Whale Sponsors</h3>
 | 
			
		||||
        <div class="wrapper">
 | 
			
		||||
          <ng-container>
 | 
			
		||||
            <ng-template ngFor let-sponsor [ngForOf]="profiles.whales">
 | 
			
		||||
              <a [href]="'https://twitter.com/' + sponsor.username" target="_blank" rel="sponsored" [title]="sponsor.username">
 | 
			
		||||
                <img class="image" [src]="'data:' + sponsor.image_mime + ';base64,' + sponsor.image" onError="this.src = '/resources/profile/unknown.svg'; this.className = 'image unknown'"/>
 | 
			
		||||
              </a>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </ng-container>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="community-sponsor" style="margin-bottom: 68px" *ngIf="profiles.chads.length > 0">
 | 
			
		||||
        <h3 i18n="about.sponsors.withHeart">Chad Sponsors</h3>
 | 
			
		||||
        <div class="wrapper">
 | 
			
		||||
          <ng-template ngFor let-sponsor [ngForOf]="profiles.chads">
 | 
			
		||||
            <a [href]="'https://twitter.com/' + sponsor.username" target="_blank" rel="sponsored" [title]="sponsor.username">
 | 
			
		||||
              <img class="image" [src]="'data:' + sponsor.image_mime + ';base64,' + sponsor.image" onError="this.src = '/resources/profile/unknown.svg'; this.className = 'image unknown'"/>
 | 
			
		||||
            </a>
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ng-container>
 | 
			
		||||
 | 
			
		||||
  <div class="community-sponsor" style="margin-bottom: 68px">
 | 
			
		||||
    <h3 i18n="about.sponsors.withHeart">OG Sponsors ❤️</h3>
 | 
			
		||||
    <div class="wrapper">
 | 
			
		||||
      <ng-container *ngIf="sponsors$ | async as sponsors; else loadingSponsors">
 | 
			
		||||
        <ng-template ngFor let-sponsor [ngForOf]="sponsors">
 | 
			
		||||
          <a [href]="'https://twitter.com/' + sponsor.handle" target="_blank" rel="sponsored" [title]="sponsor.handle">
 | 
			
		||||
            <img class="image" [src]="'/api/v1/donations/images/' + sponsor.handle" />
 | 
			
		||||
          </a>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      <ng-container *ngIf="ogs$ | async as ogs; else loadingSponsors">
 | 
			
		||||
        <a *ngFor="let ogSponsor of ogs" [href]="'https://twitter.com/' + ogSponsor.handle" target="_blank" rel="sponsored" [title]="ogSponsor.handle">
 | 
			
		||||
          <img class="image" [src]="'/api/v1/donations/images/' + ogSponsor.handle" onError="this.src = '/resources/profile/unknown.svg'; this.className = 'image unknown'"/>
 | 
			
		||||
        </a>
 | 
			
		||||
      </ng-container>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
@ -340,7 +373,7 @@
 | 
			
		||||
      <div class="wrapper">
 | 
			
		||||
        <ng-template ngFor let-translator [ngForOf]="translators">
 | 
			
		||||
          <a [href]="'https://twitter.com/' + translator.value" target="_blank" [title]="translator.key">
 | 
			
		||||
            <img class="image" [src]="'/api/v1/translators/images/' + translator.value" />
 | 
			
		||||
            <img class="image" [src]="'/api/v1/translators/images/' + translator.value" onError="this.src = '/resources/profile/unknown.svg'; this.className = 'image unknown'"/>
 | 
			
		||||
          </a>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      </div>
 | 
			
		||||
@ -354,7 +387,7 @@
 | 
			
		||||
      <div class="wrapper">
 | 
			
		||||
        <ng-template ngFor let-contributor [ngForOf]="contributors.regular">
 | 
			
		||||
          <a [href]="'https://github.com/' + contributor.name" target="_blank" [title]="contributor.name">
 | 
			
		||||
            <img class="image" [src]="'/api/v1/contributors/images/' + contributor.id" />
 | 
			
		||||
            <img class="image" [src]="'/api/v1/contributors/images/' + contributor.id" onError="this.src = '/resources/profile/unknown.svg'; this.className = 'image unknown'"/>
 | 
			
		||||
            <span>{{ contributor.name }}</span>
 | 
			
		||||
          </a>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
@ -366,7 +399,7 @@
 | 
			
		||||
      <div class="wrapper">
 | 
			
		||||
        <ng-template ngFor let-contributor [ngForOf]="contributors.core">
 | 
			
		||||
          <a [href]="'https://github.com/' + contributor.name" target="_blank" [title]="contributor.name">
 | 
			
		||||
            <img class="image" [src]="'/api/v1/contributors/images/' + contributor.id" />
 | 
			
		||||
            <img class="image" [src]="'/api/v1/contributors/images/' + contributor.id" onError="this.src = '/resources/profile/unknown.svg'; this.className = 'image unknown'"/>
 | 
			
		||||
            <span>{{ contributor.name }}</span>
 | 
			
		||||
          </a>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@
 | 
			
		||||
    margin: 25px;
 | 
			
		||||
    line-height: 32px;
 | 
			
		||||
  }
 | 
			
		||||
  .unknown {
 | 
			
		||||
    border: 1px solid #b4b4b4;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .image.not-rounded {
 | 
			
		||||
    border-radius: 0;
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ import { Observable } from 'rxjs';
 | 
			
		||||
import { ApiService } from '../../services/api.service';
 | 
			
		||||
import { IBackendInfo } from '../../interfaces/websocket.interface';
 | 
			
		||||
import { Router, ActivatedRoute } from '@angular/router';
 | 
			
		||||
import { map, tap } from 'rxjs/operators';
 | 
			
		||||
import { map, share, tap } from 'rxjs/operators';
 | 
			
		||||
import { ITranslators } from '../../interfaces/node-api.interface';
 | 
			
		||||
import { DOCUMENT } from '@angular/common';
 | 
			
		||||
 | 
			
		||||
@ -19,14 +19,16 @@ import { DOCUMENT } from '@angular/common';
 | 
			
		||||
export class AboutComponent implements OnInit {
 | 
			
		||||
  @ViewChild('promoVideo') promoVideo: ElementRef;
 | 
			
		||||
  backendInfo$: Observable<IBackendInfo>;
 | 
			
		||||
  sponsors$: Observable<any>;
 | 
			
		||||
  translators$: Observable<ITranslators>;
 | 
			
		||||
  allContributors$: Observable<any>;
 | 
			
		||||
  frontendGitCommitHash = this.stateService.env.GIT_COMMIT_HASH;
 | 
			
		||||
  packetJsonVersion = this.stateService.env.PACKAGE_JSON_VERSION;
 | 
			
		||||
  officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE;
 | 
			
		||||
  showNavigateToSponsor = false;
 | 
			
		||||
 | 
			
		||||
  profiles$: Observable<any>;
 | 
			
		||||
  translators$: Observable<ITranslators>;
 | 
			
		||||
  allContributors$: Observable<any>;
 | 
			
		||||
  ogs$: Observable<any>;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private websocketService: WebsocketService,
 | 
			
		||||
    private seoService: SeoService,
 | 
			
		||||
@ -43,10 +45,13 @@ export class AboutComponent implements OnInit {
 | 
			
		||||
    this.seoService.setTitle($localize`:@@004b222ff9ef9dd4771b777950ca1d0e4cd4348a:About`);
 | 
			
		||||
    this.websocketService.want(['blocks']);
 | 
			
		||||
 | 
			
		||||
    this.sponsors$ = this.apiService.getDonation$()
 | 
			
		||||
      .pipe(
 | 
			
		||||
        tap(() => this.goToAnchor())
 | 
			
		||||
      );
 | 
			
		||||
    this.profiles$ = this.apiService.getAboutPageProfiles$().pipe(
 | 
			
		||||
      tap(() => {
 | 
			
		||||
        this.goToAnchor()
 | 
			
		||||
      }),
 | 
			
		||||
      share(),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    this.translators$ = this.apiService.getTranslators$()
 | 
			
		||||
      .pipe(
 | 
			
		||||
        map((translators) => {
 | 
			
		||||
@ -59,6 +64,9 @@ export class AboutComponent implements OnInit {
 | 
			
		||||
        }),
 | 
			
		||||
        tap(() => this.goToAnchor())
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
    this.ogs$ = this.apiService.getOgs$();
 | 
			
		||||
 | 
			
		||||
    this.allContributors$ = this.apiService.getContributor$().pipe(
 | 
			
		||||
      map((contributors) => {
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
<ng-container *ngIf="{ val: network$ | async } as network">
 | 
			
		||||
<header>
 | 
			
		||||
<header *ngIf="headerVisible">
 | 
			
		||||
  <nav class="navbar navbar-expand-md navbar-dark bg-dark">
 | 
			
		||||
  <a class="navbar-brand" [ngClass]="{'dual-logos': subdomain}" [routerLink]="['/' | relativeUrl]" (click)="brandClick($event)">
 | 
			
		||||
  <ng-template [ngIf]="subdomain">
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { Component, OnInit } from '@angular/core';
 | 
			
		||||
import { Component, OnInit, Input } from '@angular/core';
 | 
			
		||||
import { Env, StateService } from '../../services/state.service';
 | 
			
		||||
import { Observable, merge, of } from 'rxjs';
 | 
			
		||||
import { LanguageService } from '../../services/language.service';
 | 
			
		||||
@ -11,6 +11,9 @@ import { NavigationService } from '../../services/navigation.service';
 | 
			
		||||
  styleUrls: ['./master-page.component.scss'],
 | 
			
		||||
})
 | 
			
		||||
export class MasterPageComponent implements OnInit {
 | 
			
		||||
  @Input() headerVisible = true;
 | 
			
		||||
  @Input() footerVisibleOverride: boolean | null = null;
 | 
			
		||||
 | 
			
		||||
  env: Env;
 | 
			
		||||
  network$: Observable<string>;
 | 
			
		||||
  connectionState$: Observable<number>;
 | 
			
		||||
@ -38,10 +41,14 @@ export class MasterPageComponent implements OnInit {
 | 
			
		||||
    this.subdomain = this.enterpriseService.getSubdomain();
 | 
			
		||||
    this.navigationService.subnetPaths.subscribe((paths) => {
 | 
			
		||||
      this.networkPaths = paths;
 | 
			
		||||
      if (paths.mainnet.indexOf('docs') > -1) {
 | 
			
		||||
        this.footerVisible = false;
 | 
			
		||||
      if (this.footerVisibleOverride === null) {
 | 
			
		||||
        if (paths.mainnet.indexOf('docs') > -1) {
 | 
			
		||||
          this.footerVisible = false;
 | 
			
		||||
        } else {
 | 
			
		||||
          this.footerVisible = true;
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        this.footerVisible = true;
 | 
			
		||||
        this.footerVisible = this.footerVisibleOverride;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -99,14 +99,20 @@
 | 
			
		||||
                    </ng-template>
 | 
			
		||||
                    <ng-template #estimationTmpl>
 | 
			
		||||
                      <ng-template [ngIf]="this.mempoolPosition.block >= 7" [ngIfElse]="belowBlockLimit">
 | 
			
		||||
                        <span i18n="transaction.eta.in-several-hours|Transaction ETA in several hours or more">In several hours (or more)</span>
 | 
			
		||||
                        <span class="eta d-flex">
 | 
			
		||||
                          <span i18n="transaction.eta.in-several-hours|Transaction ETA in several hours or more">In several hours (or more)</span>
 | 
			
		||||
                          <span class="ml-2"></span><a *ngIf="stateService.env.OFFICIAL_MEMPOOL_SPACE && stateService.env.ACCELERATOR" [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn badge badge-primary accelerate ml-auto" i18n="transaction.accelerate|Accelerate button label">Accelerate</a>
 | 
			
		||||
                        </span>
 | 
			
		||||
                      </ng-template>
 | 
			
		||||
                      <ng-template #belowBlockLimit>
 | 
			
		||||
                        <ng-template [ngIf]="network === 'liquid' || network === 'liquidtestnet'" [ngIfElse]="timeEstimateDefault">
 | 
			
		||||
                          <app-time kind="until" [time]="(60 * 1000 * this.mempoolPosition.block) + now" [fastRender]="false" [fixedRender]="true"></app-time>
 | 
			
		||||
                        </ng-template>
 | 
			
		||||
                        <ng-template #timeEstimateDefault>
 | 
			
		||||
                          <app-time kind="until" *ngIf="(da$ | async) as da;" [time]="da.timeAvg * (this.mempoolPosition.block + 1) + now + da.timeOffset" [fastRender]="false" [fixedRender]="true"></app-time>
 | 
			
		||||
                          <span class="d-flex">
 | 
			
		||||
                            <app-time kind="until" *ngIf="(da$ | async) as da;" [time]="da.timeAvg * (this.mempoolPosition.block + 1) + now + da.timeOffset" [fastRender]="false" [fixedRender]="true"></app-time>
 | 
			
		||||
                            <span class="ml-2"></span><a *ngIf="stateService.env.OFFICIAL_MEMPOOL_SPACE && stateService.env.ACCELERATOR" [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn badge badge-primary accelerate ml-auto" i18n="transaction.accelerate|Accelerate button label">Accelerate</a>
 | 
			
		||||
                          </span>
 | 
			
		||||
                        </ng-template>
 | 
			
		||||
                      </ng-template>
 | 
			
		||||
                    </ng-template>
 | 
			
		||||
 | 
			
		||||
@ -216,4 +216,23 @@
 | 
			
		||||
  .alert-link {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.eta {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: end;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  align-content: center;
 | 
			
		||||
  @media (min-width: 850px) {
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.accelerate {
 | 
			
		||||
  align-self: auto;
 | 
			
		||||
  margin-top: 3px;
 | 
			
		||||
  @media (min-width: 850px) {
 | 
			
		||||
    justify-self: start;
 | 
			
		||||
    margin-left: 0px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -97,7 +97,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
 | 
			
		||||
    private router: Router,
 | 
			
		||||
    private relativeUrlPipe: RelativeUrlPipe,
 | 
			
		||||
    private electrsApiService: ElectrsApiService,
 | 
			
		||||
    private stateService: StateService,
 | 
			
		||||
    public stateService: StateService,
 | 
			
		||||
    private cacheService: CacheService,
 | 
			
		||||
    private websocketService: WebsocketService,
 | 
			
		||||
    private audioService: AudioService,
 | 
			
		||||
 | 
			
		||||
@ -112,6 +112,7 @@ export interface PoolInfo {
 | 
			
		||||
  addresses: string; // JSON array
 | 
			
		||||
  emptyBlocks: number;
 | 
			
		||||
  slug: string;
 | 
			
		||||
  poolUniqueId: number;
 | 
			
		||||
}
 | 
			
		||||
export interface PoolStat {
 | 
			
		||||
  pool: PoolInfo;
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,7 @@ import { OldestNodes } from '../lightning/nodes-ranking/oldest-nodes/oldest-node
 | 
			
		||||
import { NodesRankingsDashboard } from '../lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component';
 | 
			
		||||
import { NodeChannels } from '../lightning/nodes-channels/node-channels.component';
 | 
			
		||||
import { GroupComponent } from './group/group.component';
 | 
			
		||||
import { NodeOwnerComponent } from './node-owner/node-owner.component';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [
 | 
			
		||||
@ -66,6 +67,7 @@ import { GroupComponent } from './group/group.component';
 | 
			
		||||
    NodesRankingsDashboard,
 | 
			
		||||
    NodeChannels,
 | 
			
		||||
    GroupComponent,
 | 
			
		||||
    NodeOwnerComponent,
 | 
			
		||||
  ],
 | 
			
		||||
  imports: [
 | 
			
		||||
    CommonModule,
 | 
			
		||||
@ -103,6 +105,7 @@ import { GroupComponent } from './group/group.component';
 | 
			
		||||
    OldestNodes,
 | 
			
		||||
    NodesRankingsDashboard,
 | 
			
		||||
    NodeChannels,
 | 
			
		||||
    NodeOwnerComponent,
 | 
			
		||||
  ],
 | 
			
		||||
  providers: [
 | 
			
		||||
    LightningApiService,
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,17 @@
 | 
			
		||||
<div *ngIf="stateService.env.OFFICIAL_MEMPOOL_SPACE === true">
 | 
			
		||||
 | 
			
		||||
  <div *ngIf="{ value: (nodeOwner$ | async) } as nodeOwner">
 | 
			
		||||
 | 
			
		||||
    <div *ngIf="nodeOwner.value && nodeOwner.value.sns_id">
 | 
			
		||||
      <a target="_blank" [href]="'https://twitter.com/' + nodeOwner.value.username">
 | 
			
		||||
        <img class="profile-photo" [src]="'data:' + nodeOwner.value.image_mime + ';base64,' + nodeOwner.value.image">
 | 
			
		||||
      </a>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div *ngIf="nodeOwner.value === false">
 | 
			
		||||
      <a [href]="'/login/lnnode?type=signup&pubkey=' + publicKey + '&alias=' + alias" class="btn btn-primary btn-sm">Claim</a>
 | 
			
		||||
    <div>
 | 
			
		||||
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
</div>
 | 
			
		||||
@ -0,0 +1,4 @@
 | 
			
		||||
.profile-photo {
 | 
			
		||||
  width: 31px;
 | 
			
		||||
  height: 31px;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,20 @@
 | 
			
		||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
import { StateService } from '../../services/state.service';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-node-owner',
 | 
			
		||||
  templateUrl: './node-owner.component.html',
 | 
			
		||||
  styleUrls: ['./node-owner.component.scss'],
 | 
			
		||||
  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
			
		||||
})
 | 
			
		||||
export class NodeOwnerComponent{
 | 
			
		||||
  @Input() publicKey: string = '';
 | 
			
		||||
  @Input() alias: string = '';
 | 
			
		||||
  @Input() nodeOwner$: Observable<any>;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    public stateService: StateService
 | 
			
		||||
  ) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -3,13 +3,17 @@
 | 
			
		||||
  <ng-container *ngIf="!error">
 | 
			
		||||
    <h5 class="mb-0" style="color: #ffffff66" i18n="lightning.node">Lightning node</h5>
 | 
			
		||||
    <div class="title-container mb-2">
 | 
			
		||||
      <h1 class="mb-0 text-truncate">{{ node.alias }}</h1>
 | 
			
		||||
      <span class="tx-link">
 | 
			
		||||
      <div class="d-flex justify-content-between align-items-center">
 | 
			
		||||
        <h1 class="mb-0 text-truncate">{{ node.alias }}</h1>
 | 
			
		||||
        <!-- <app-node-owner [nodeOwner$]="nodeOwner$" [publicKey]="node.public_key" [alias]="node.alias" class="claim-btn"></app-node-owner> -->
 | 
			
		||||
      </div>
 | 
			
		||||
      <span class="tx-link justify-content-between align-items-center">
 | 
			
		||||
        <span class="node-id">
 | 
			
		||||
          <app-truncate [text]="node.public_key" [lastChars]="8" [link]="['/lightning/node' | relativeUrl, node.public_key]">
 | 
			
		||||
            <app-clipboard [text]="node.public_key"></app-clipboard>
 | 
			
		||||
          </app-truncate>
 | 
			
		||||
        </span>
 | 
			
		||||
        <!-- <app-node-owner [nodeOwner$]="nodeOwner$" [publicKey]="node.public_key" [alias]="node.alias" class="claim-btn-mobile"></app-node-owner> -->
 | 
			
		||||
      </span>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ng-container>
 | 
			
		||||
 | 
			
		||||
@ -111,3 +111,17 @@ app-fiat {
 | 
			
		||||
  margin: 0 0.25em;
 | 
			
		||||
  color: slategrey;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.claim-btn {
 | 
			
		||||
  max-height: 32px;
 | 
			
		||||
  @media (min-width: 850px) {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.claim-btn-mobile {
 | 
			
		||||
  max-height: 32px;
 | 
			
		||||
  @media (max-width: 850px) {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
 | 
			
		||||
import { ChangeDetectionStrategy, Component, OnInit, ChangeDetectorRef } from '@angular/core';
 | 
			
		||||
import { ActivatedRoute, ParamMap } from '@angular/router';
 | 
			
		||||
import { Observable } from 'rxjs';
 | 
			
		||||
import { catchError, map, switchMap, tap } from 'rxjs/operators';
 | 
			
		||||
import { Observable, of, EMPTY } from 'rxjs';
 | 
			
		||||
import { catchError, map, switchMap, tap, share } from 'rxjs/operators';
 | 
			
		||||
import { SeoService } from '../../services/seo.service';
 | 
			
		||||
import { ApiService } from '../../services/api.service';
 | 
			
		||||
import { LightningApiService } from '../lightning-api.service';
 | 
			
		||||
@ -38,6 +38,7 @@ export class NodeComponent implements OnInit {
 | 
			
		||||
  tlvRecords: CustomRecord[];
 | 
			
		||||
  avgChannelDistance$: Observable<number | null>;
 | 
			
		||||
  showFeatures = false;
 | 
			
		||||
  nodeOwner$: Observable<any>;
 | 
			
		||||
  kmToMiles = kmToMiles;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
@ -45,6 +46,7 @@ export class NodeComponent implements OnInit {
 | 
			
		||||
    private lightningApiService: LightningApiService,
 | 
			
		||||
    private activatedRoute: ActivatedRoute,
 | 
			
		||||
    private seoService: SeoService,
 | 
			
		||||
    private cd: ChangeDetectorRef,
 | 
			
		||||
  ) { }
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
@ -147,6 +149,24 @@ export class NodeComponent implements OnInit {
 | 
			
		||||
        return null;
 | 
			
		||||
      })
 | 
			
		||||
    ) as Observable<number | null>;
 | 
			
		||||
 | 
			
		||||
    this.nodeOwner$ = this.activatedRoute.paramMap
 | 
			
		||||
      .pipe(
 | 
			
		||||
        switchMap((params: ParamMap) => {
 | 
			
		||||
          return this.apiService.getNodeOwner$(params.get('public_key')).pipe(
 | 
			
		||||
            switchMap((response) =>  {
 | 
			
		||||
              if (response.status === 204) {
 | 
			
		||||
                return of(false);
 | 
			
		||||
              }
 | 
			
		||||
              return of(response.body);
 | 
			
		||||
            }),
 | 
			
		||||
            catchError(() => {
 | 
			
		||||
              return of(false);
 | 
			
		||||
            })
 | 
			
		||||
          )
 | 
			
		||||
        }),
 | 
			
		||||
        share(),
 | 
			
		||||
      );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  toggleShowDetails(): void {
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,8 @@ import { WebsocketResponse } from '../interfaces/websocket.interface';
 | 
			
		||||
import { Outspend, Transaction } from '../interfaces/electrs.interface';
 | 
			
		||||
import { Conversion } from './price.service';
 | 
			
		||||
 | 
			
		||||
const SERVICES_API_PREFIX = `/api/v1/services`;
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
  providedIn: 'root'
 | 
			
		||||
})
 | 
			
		||||
@ -92,15 +94,11 @@ export class ApiService {
 | 
			
		||||
    return this.httpClient.get<Outspend[][]>(this.apiBaseUrl + this.apiBasePath + '/api/v1/outspends', { params });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  requestDonation$(amount: number, orderId: string): Observable<any> {
 | 
			
		||||
    const params = {
 | 
			
		||||
      amount: amount,
 | 
			
		||||
      orderId: orderId,
 | 
			
		||||
    };
 | 
			
		||||
    return this.httpClient.post<any>(this.apiBaseUrl + '/api/v1/donations', params);
 | 
			
		||||
  getAboutPageProfiles$(): Observable<any[]> {
 | 
			
		||||
    return this.httpClient.get<any[]>(this.apiBaseUrl + '/api/v1/about-page');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getDonation$(): Observable<any[]> {
 | 
			
		||||
  getOgs$(): Observable<any> {
 | 
			
		||||
    return this.httpClient.get<any[]>(this.apiBaseUrl + '/api/v1/donations');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -112,10 +110,6 @@ export class ApiService {
 | 
			
		||||
    return this.httpClient.get<any[]>(this.apiBaseUrl + '/api/v1/contributors');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  checkDonation$(orderId: string): Observable<any[]> {
 | 
			
		||||
    return this.httpClient.get<any[]>(this.apiBaseUrl + '/api/v1/donations/check?order_id=' + orderId);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getInitData$(): Observable<WebsocketResponse> {
 | 
			
		||||
    return this.httpClient.get<WebsocketResponse>(this.apiBaseUrl + this.apiBasePath + '/api/v1/init-data');
 | 
			
		||||
  }
 | 
			
		||||
@ -323,4 +317,13 @@ export class ApiService {
 | 
			
		||||
        (timestamp ? `?timestamp=${timestamp}` : '')
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Services
 | 
			
		||||
   */
 | 
			
		||||
  getNodeOwner$(publicKey: string) {
 | 
			
		||||
    let params = new HttpParams()
 | 
			
		||||
      .set('node_public_key', publicKey);
 | 
			
		||||
    return this.httpClient.get<any>(`${SERVICES_API_PREFIX}/lightning/claim/current`, { params, observe: 'response' });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -47,6 +47,7 @@ export interface Env {
 | 
			
		||||
  TESTNET_BLOCK_AUDIT_START_HEIGHT: number;
 | 
			
		||||
  SIGNET_BLOCK_AUDIT_START_HEIGHT: number;
 | 
			
		||||
  HISTORICAL_PRICE: boolean;
 | 
			
		||||
  ACCELERATOR: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const defaultEnv: Env = {
 | 
			
		||||
@ -77,6 +78,7 @@ const defaultEnv: Env = {
 | 
			
		||||
  'TESTNET_BLOCK_AUDIT_START_HEIGHT': 0,
 | 
			
		||||
  'SIGNET_BLOCK_AUDIT_START_HEIGHT': 0,
 | 
			
		||||
  'HISTORICAL_PRICE': true,
 | 
			
		||||
  'ACCELERATOR': false,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<footer>
 | 
			
		||||
    <div class="container-fluid">
 | 
			
		||||
    <div class="row main">
 | 
			
		||||
      <div class="offset-lg-1 col-lg-4 col align-self-center branding">
 | 
			
		||||
      <div class="offset-lg-1 col-lg-4 col align-self-center branding mt-2">
 | 
			
		||||
        <div class="main-logo">
 | 
			
		||||
          <app-svg-images *ngIf="officialMempoolSpace" name="officialMempoolSpace" viewBox="0 0 500 126"></app-svg-images>
 | 
			
		||||
          <app-svg-images *ngIf="!officialMempoolSpace" name="mempoolSpace" viewBox="0 0 500 126"></app-svg-images>
 | 
			
		||||
@ -16,10 +16,12 @@
 | 
			
		||||
        <div class="selector">
 | 
			
		||||
          <app-rate-unit-selector></app-rate-unit-selector>
 | 
			
		||||
        </div>
 | 
			
		||||
        <ng-template #temporaryHidden>
 | 
			
		||||
          <a *ngIf="officialMempoolSpace" class="cta btn btn-purple sponsor" [routerLink]="['/signup' | relativeUrl]">Support the Project</a>
 | 
			
		||||
          <p *ngIf="officialMempoolSpace && env.BASE_MODULE === 'mempool'" class="cta-secondary"><a [routerLink]="['/signin' | relativeUrl]" i18n="shared.broadcast-transaction|Broadcast Transaction">Sign In</a></p>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
        <div *ngIf="officialMempoolSpace && stateService.env.ACCELERATOR" class="cta">
 | 
			
		||||
          <a class="btn btn-purple sponsor" [routerLink]="['/login' | relativeUrl]">
 | 
			
		||||
            <span *ngIf="loggedIn" i18n="shared.my-account">My Account</span>
 | 
			
		||||
            <span *ngIf="!loggedIn" i18n="shared.sign-in">Sign In / Sign Up</span>
 | 
			
		||||
          </a>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col-lg-6 col-md-10 offset-md-1 links outer">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ footer .row.main .branding {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
footer .row.main .branding > p {
 | 
			
		||||
  margin-bottom: 45px;
 | 
			
		||||
  margin-bottom: 25px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
footer .row.main .branding .btn {
 | 
			
		||||
@ -35,11 +35,7 @@ footer .row.main .branding button.account {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
footer .row.main .branding .cta {
 | 
			
		||||
  margin: 20px auto 25px auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
footer .row.main .branding .cta-secondary {
 | 
			
		||||
 | 
			
		||||
  margin: 25px auto 25px auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
footer .row.main .links.outer {
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,13 @@
 | 
			
		||||
import { ChangeDetectionStrategy, Component, OnInit, Inject, LOCALE_ID } from '@angular/core';
 | 
			
		||||
import { Observable, merge, of, Subject } from 'rxjs';
 | 
			
		||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, Inject, LOCALE_ID } from '@angular/core';
 | 
			
		||||
import { ActivatedRoute } from '@angular/router';
 | 
			
		||||
import { Observable, merge, of, Subject, Subscription } from 'rxjs';
 | 
			
		||||
import { tap, takeUntil } from 'rxjs/operators';
 | 
			
		||||
import { Env, StateService } from '../../../services/state.service';
 | 
			
		||||
import { IBackendInfo } from '../../../interfaces/websocket.interface';
 | 
			
		||||
import { LanguageService } from '../../../services/language.service';
 | 
			
		||||
import { NavigationService } from '../../../services/navigation.service';
 | 
			
		||||
import { StorageService } from '../../../services/storage.service';
 | 
			
		||||
import { WebsocketService } from '../../../services/websocket.service';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-global-footer',
 | 
			
		||||
@ -23,12 +26,19 @@ export class GlobalFooterComponent implements OnInit {
 | 
			
		||||
  network$: Observable<string>;
 | 
			
		||||
  networkPaths: { [network: string]: string };
 | 
			
		||||
  currentNetwork = '';
 | 
			
		||||
  loggedIn = false;
 | 
			
		||||
  username = null;
 | 
			
		||||
  urlSubscription: Subscription;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    public stateService: StateService,
 | 
			
		||||
    private languageService: LanguageService,
 | 
			
		||||
    private navigationService: NavigationService,
 | 
			
		||||
    @Inject(LOCALE_ID) public locale: string,
 | 
			
		||||
    private storageService: StorageService,
 | 
			
		||||
    private route: ActivatedRoute,
 | 
			
		||||
    private cd: ChangeDetectorRef,
 | 
			
		||||
    private websocketService: WebsocketService
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
@ -46,11 +56,23 @@ export class GlobalFooterComponent implements OnInit {
 | 
			
		||||
    this.network$.pipe(takeUntil(this.destroy$)).subscribe((network) => {
 | 
			
		||||
      this.currentNetwork = network;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    this.urlSubscription = this.route.url.subscribe((url) => {
 | 
			
		||||
      this.loggedIn = JSON.parse(this.storageService.getValue('auth')) !== null;
 | 
			
		||||
      const auth = JSON.parse(this.storageService.getValue('auth'));
 | 
			
		||||
      if (auth?.user?.username) {
 | 
			
		||||
        this.username = auth.user.username;
 | 
			
		||||
      } else {
 | 
			
		||||
        this.username = null;
 | 
			
		||||
      }
 | 
			
		||||
      this.cd.markForCheck();
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnDestroy(): void {
 | 
			
		||||
    this.destroy$.next(true);
 | 
			
		||||
    this.destroy$.complete();
 | 
			
		||||
    this.urlSubscription.unsubscribe();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  networkLink(network) {
 | 
			
		||||
 | 
			
		||||
@ -219,6 +219,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
 | 
			
		||||
    AmountShortenerPipe,
 | 
			
		||||
  ],
 | 
			
		||||
  exports: [
 | 
			
		||||
    MasterPageComponent,
 | 
			
		||||
    RouterModule,
 | 
			
		||||
    ReactiveFormsModule,
 | 
			
		||||
    NgbNavModule,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								frontend/src/resources/profile/unknown.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								frontend/src/resources/profile/unknown.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" data-v-4fa90e7f=""><path d="M14.33 7.17C13.588 7.058 12.807 7 12 7c-4.97 0-9 2.239-9 5 0 1.44 1.096 2.738 2.85 3.65l2.362-2.362a4 4 0 015.076-5.076l1.043-1.043zM11.23 15.926a4 4 0 004.695-4.695l2.648-2.647C20.078 9.478 21 10.68 21 12c0 2.761-4.03 5-9 5-.598 0-1.183-.032-1.749-.094l.98-.98zM17.793 5.207a1 1 0 111.414 1.414L6.48 19.35a1 1 0 11-1.414-1.414L17.793 5.207z"></path></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 464 B  | 
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user