mirror of
https://github.com/mempool/mempool.git
synced 2026-08-13 12:33:11 +02:00
Merge branch 'mempool:master' into getting-started-page
This commit is contained in:
commit
d909b88555
18 changed files with 28 additions and 146 deletions
|
|
@ -118,12 +118,11 @@ class Indexer {
|
|||
}
|
||||
}
|
||||
this.tasksScheduled[task] = setTimeout(async () => {
|
||||
delete this.tasksScheduled[task];
|
||||
try {
|
||||
await this.runSingleTask(task);
|
||||
} catch (e) {
|
||||
logger.err(`Unexpected error in scheduled task ${task}: ` + (e instanceof Error ? e.message : e));
|
||||
} finally {
|
||||
clearTimeout(this.tasksScheduled[task]);
|
||||
}
|
||||
}, timeout);
|
||||
}
|
||||
|
|
@ -149,7 +148,8 @@ class Indexer {
|
|||
latestPriceId = await PricesRepository.$getLatestPriceId();
|
||||
} catch (e) {
|
||||
logger.debug('failed to fetch latest price id from db: ' + (e instanceof Error ? e.message : e));
|
||||
} if (priceUpdater.historyInserted === false || latestPriceId === null) {
|
||||
}
|
||||
if (priceUpdater.historyInserted === false || latestPriceId === null) {
|
||||
logger.debug(`Blocks prices indexer is waiting for the price updater to complete`, logger.tags.mining);
|
||||
this.scheduleSingleTask(task, 10000);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -30,12 +30,13 @@ class NodesSocketsRepository {
|
|||
return 0;
|
||||
}
|
||||
try {
|
||||
const placeholders = addresses.map(() => '?').join(',');
|
||||
const query = `
|
||||
DELETE FROM nodes_sockets
|
||||
WHERE public_key = ?
|
||||
AND socket NOT IN (${addresses.map(id => `"${id}"`).join(',')})
|
||||
AND socket NOT IN (${placeholders})
|
||||
`;
|
||||
const [result] = await DB.query<ResultSetHeader>(query, [publicKey]);
|
||||
const [result] = await DB.query<ResultSetHeader>(query, [publicKey, ...addresses]);
|
||||
return result.affectedRows;
|
||||
} catch (e) {
|
||||
logger.err(`Cannot delete unused sockets for ${publicKey} from db. Reason: ` + (e instanceof Error ? e.message : e));
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<div id="become-sponsor-container" [ngClass]="context">
|
||||
<div class="become-sponsor community">
|
||||
<p style="font-weight: 700; font-size: 18px;">If you're an individual...</p>
|
||||
<a [href]="host + '/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" (click)="onSponsorClick($event)">Become a Community Sponsor</a>
|
||||
<a [href]="host + '/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">Become a Community Sponsor</a>
|
||||
<p class="sponsor-feature"><fa-icon [icon]="['fas', 'check']"></fa-icon> Exclusive swag</p>
|
||||
<p class="sponsor-feature"><fa-icon [icon]="['fas', 'check']"></fa-icon> Your avatar on the About page</p>
|
||||
<p class="sponsor-feature"><fa-icon [icon]="['fas', 'check']"></fa-icon> And more coming soon :)</p>
|
||||
</div>
|
||||
<div class="become-sponsor enterprise">
|
||||
<p style="font-weight: 700; font-size: 18px;">If you're a business...</p>
|
||||
<a [href]="host + '/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" (click)="onEnterpriseClick($event)">Become an Enterprise Sponsor</a>
|
||||
<a [href]="host + '/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">Become an Enterprise Sponsor</a>
|
||||
<p class="sponsor-feature"><fa-icon [icon]="['fas', 'check']"></fa-icon> Increased API limits</p>
|
||||
<p class="sponsor-feature"><fa-icon [icon]="['fas', 'check']"></fa-icon> Co-branded instance</p>
|
||||
<p class="sponsor-feature"><fa-icon [icon]="['fas', 'check']"></fa-icon> 99% service-level agreement</p>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { EnterpriseService } from '@app/services/enterprise.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-about-sponsors',
|
||||
|
|
@ -10,17 +9,4 @@ import { EnterpriseService } from '@app/services/enterprise.service';
|
|||
export class AboutSponsorsComponent {
|
||||
@Input() host = 'https://mempool.space';
|
||||
@Input() context = 'about';
|
||||
|
||||
constructor(private enterpriseService: EnterpriseService) {
|
||||
}
|
||||
|
||||
onSponsorClick(e): boolean {
|
||||
this.enterpriseService.goal(5);
|
||||
return true;
|
||||
}
|
||||
|
||||
onEnterpriseClick(e): boolean {
|
||||
this.enterpriseService.goal(6);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import { Router, ActivatedRoute } from '@angular/router';
|
|||
import { map, share, tap } from 'rxjs/operators';
|
||||
import { ITranslators } from '@interfaces/node-api.interface';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { EnterpriseService } from '@app/services/enterprise.service';
|
||||
import { ThemeService } from '../../services/theme.service';
|
||||
|
||||
@Component({
|
||||
|
|
@ -40,7 +39,6 @@ export class AboutComponent implements OnInit {
|
|||
private seoService: SeoService,
|
||||
private ogService: OpenGraphService,
|
||||
public stateService: StateService,
|
||||
private enterpriseService: EnterpriseService,
|
||||
private apiService: ApiService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
|
|
@ -141,16 +139,6 @@ export class AboutComponent implements OnInit {
|
|||
this.promoVideo.nativeElement.muted = false;
|
||||
}
|
||||
|
||||
onSponsorClick(e): boolean {
|
||||
this.enterpriseService.goal(5);
|
||||
return true;
|
||||
}
|
||||
|
||||
onEnterpriseClick(e): boolean {
|
||||
this.enterpriseService.goal(6);
|
||||
return true;
|
||||
}
|
||||
|
||||
get isLightMode(): boolean {
|
||||
return this.loadedTheme === 'nymkappa';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { ETA, EtaService } from '@app/services/eta.service';
|
|||
import { Transaction } from '@interfaces/electrs.interface';
|
||||
import { MiningStats } from '@app/services/mining.service';
|
||||
import { IAuth, AuthServiceMempool } from '@app/services/auth.service';
|
||||
import { EnterpriseService } from '@app/services/enterprise.service';
|
||||
import { PartnerCodeService } from '@app/services/partner-code.service';
|
||||
import { ApiService } from '@app/services/api.service';
|
||||
import { isDevMode } from '@angular/core';
|
||||
|
|
@ -147,7 +146,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
|||
private audioService: AudioService,
|
||||
private cd: ChangeDetectorRef,
|
||||
private authService: AuthServiceMempool,
|
||||
private enterpriseService: EnterpriseService,
|
||||
private partnerCodeService: PartnerCodeService,
|
||||
private themeService: ThemeService,
|
||||
) {
|
||||
|
|
@ -236,7 +234,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
|||
|
||||
if (this._step === 'checkout') {
|
||||
this.insertSquare();
|
||||
this.enterpriseService.goal(8);
|
||||
this.scrollToElementWithTimeout('acceleratePreviewAnchor', 'start', 100);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,10 @@ tr, td, th {
|
|||
}
|
||||
|
||||
.widget {
|
||||
.acceleration-list {
|
||||
overflow-anchor: none;
|
||||
}
|
||||
|
||||
.txid {
|
||||
width: 30%;
|
||||
overflow: hidden;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@
|
|||
<ng-container *ngTemplateOutlet="restOfTable"></ng-container>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="col-sm chart-container" *ngIf="webGlEnabled && !showComparison">
|
||||
<div class="col-sm chart-container block-graph-wrapper" *ngIf="webGlEnabled && !showComparison">
|
||||
<app-block-overview-graph
|
||||
#blockGraphActual
|
||||
[isLoading]="!stateService.isBrowser || isLoadingOverview"
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@
|
|||
}
|
||||
|
||||
.latest-transactions {
|
||||
overflow-anchor: none;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
table-layout:fixed;
|
||||
|
|
@ -223,6 +224,7 @@
|
|||
}
|
||||
|
||||
.lastest-replacements-table {
|
||||
overflow-anchor: none;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
table-layout:fixed;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.widget table {
|
||||
overflow-anchor: none;
|
||||
}
|
||||
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
margin-top: 13px;
|
||||
}
|
||||
|
||||
.widget table {
|
||||
overflow-anchor: none;
|
||||
}
|
||||
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
<br>
|
||||
|
||||
<li>We use a self-hosted statistics application (matomo) for analytics purposes, which collects your IP address along with the requests you make. Our matomo instance is configured to respect your privacy by redacting your IP address and other methods, and we do not share this data with any third-party. To conceal your activity from our analytics, we recommend that you use a privacy protecting browser extension that blocks matomo from being loaded.</li>
|
||||
<li>We use a self-hosted statistics application for analytics purposes, which collects your IP address along with the requests you make. Our instance is configured to respect your privacy by redacting your IP address and other methods, and we do not share this data with any third-party. To conceal your activity from our analytics, we recommend that you use a privacy protecting browser extension that blocks it from being loaded.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@
|
|||
}
|
||||
|
||||
.widget .latest-transactions {
|
||||
overflow-anchor: none;
|
||||
|
||||
.table-cell-satoshis {
|
||||
@media (min-width: 768px) {
|
||||
display: none;
|
||||
|
|
|
|||
|
|
@ -167,8 +167,6 @@ export class TrackerComponent implements OnInit, OnDestroy {
|
|||
this.miningStats = stats;
|
||||
});
|
||||
|
||||
this.enterpriseService.page();
|
||||
|
||||
this.enterpriseInfo$ = this.enterpriseService.info$.subscribe(info => {
|
||||
this.enterpriseInfo = info;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ import { RelativeUrlPipe } from '@app/shared/pipes/relative-url/relative-url.pip
|
|||
import { PriceService } from '@app/services/price.service';
|
||||
import { isFeatureActive } from '@app/bitcoin.utils';
|
||||
import { ServicesApiServices } from '@app/services/services-api.service';
|
||||
import { EnterpriseService } from '@app/services/enterprise.service';
|
||||
import { PartnerCodeService } from '@app/services/partner-code.service';
|
||||
import { ZONE_SERVICE } from '@app/injection-tokens';
|
||||
import { MiningService, MiningStats } from '@app/services/mining.service';
|
||||
|
|
@ -217,7 +216,6 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
private seoService: SeoService,
|
||||
private priceService: PriceService,
|
||||
private storageService: StorageService,
|
||||
private enterpriseService: EnterpriseService,
|
||||
private partnerCodeService: PartnerCodeService,
|
||||
private miningService: MiningService,
|
||||
private etaService: EtaService,
|
||||
|
|
@ -228,7 +226,6 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
ngOnInit() {
|
||||
this.setupPartnerCode();
|
||||
|
||||
this.enterpriseService.page();
|
||||
this.isDetailsOpen = this.route.snapshot.queryParams['showDetails'] === 'true';
|
||||
this.cpfpMode = this.route.snapshot.queryParams['cpfp'] === 'true';
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@
|
|||
}
|
||||
|
||||
.lastest-replacements-table {
|
||||
overflow-anchor: none;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
table-layout:fixed;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { Inject, Injectable } from '@angular/core';
|
|||
import { ApiService } from '@app/services/api.service';
|
||||
import { SeoService } from '@app/services/seo.service';
|
||||
import { StateService } from '@app/services/state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
|
|
@ -12,8 +11,6 @@ import { BehaviorSubject } from 'rxjs';
|
|||
export class EnterpriseService {
|
||||
exclusiveHostName = '.mempool.space';
|
||||
subdomain: string | null = null;
|
||||
statsUrl: string;
|
||||
siteId: number;
|
||||
info$: BehaviorSubject<object> = new BehaviorSubject(null);
|
||||
|
||||
constructor(
|
||||
|
|
@ -21,7 +18,6 @@ export class EnterpriseService {
|
|||
private apiService: ApiService,
|
||||
private seoService: SeoService,
|
||||
private stateService: StateService,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
) {
|
||||
const subdomain = this.stateService.env.customize?.enterprise || this.document.location.hostname.indexOf(this.exclusiveHostName) > -1
|
||||
&& this.document.location.hostname.split(this.exclusiveHostName)[0] || false;
|
||||
|
|
@ -30,8 +26,6 @@ export class EnterpriseService {
|
|||
this.fetchSubdomainInfo();
|
||||
this.disableSubnetworks();
|
||||
this.stateService.env.ACCELERATOR = false;
|
||||
} else {
|
||||
this.insertMatomo();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,12 +45,10 @@ export class EnterpriseService {
|
|||
fetchSubdomainInfo(): void {
|
||||
if (this.stateService.env.customize?.branding) {
|
||||
const info = this.stateService.env.customize?.branding;
|
||||
this.insertMatomo(info.site_id);
|
||||
this.seoService.setEnterpriseTitle(info.title, true);
|
||||
this.info$.next(this.processEnterpriseInfo(info));
|
||||
} else {
|
||||
this.apiService.getEnterpriseInfo$(this.subdomain).subscribe((info) => {
|
||||
this.insertMatomo(info.site_id);
|
||||
this.seoService.setEnterpriseTitle(info.title);
|
||||
this.info$.next(this.processEnterpriseInfo(info));
|
||||
},
|
||||
|
|
@ -78,98 +70,4 @@ export class EnterpriseService {
|
|||
logoUrl,
|
||||
};
|
||||
}
|
||||
|
||||
insertMatomo(siteId?: number): void {
|
||||
let statsUrl = '//stats.mempool.space/';
|
||||
|
||||
if (!siteId) {
|
||||
switch (this.document.location.hostname) {
|
||||
case 'mempool.space':
|
||||
statsUrl = '//stats.mempool.space/';
|
||||
siteId = 5;
|
||||
break;
|
||||
case 'mempool.ninja':
|
||||
statsUrl = '//stats.mempool.space/';
|
||||
siteId = 4;
|
||||
break;
|
||||
case 'liquid.network':
|
||||
siteId = 8;
|
||||
statsUrl = '//stats.liquid.network/';
|
||||
break;
|
||||
case 'liquid.place':
|
||||
siteId = 10;
|
||||
statsUrl = '//stats.liquid.network/';
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.statsUrl = statsUrl;
|
||||
this.siteId = siteId;
|
||||
|
||||
// @ts-ignore
|
||||
if (window._paq && window['Matomo']) {
|
||||
window['Matomo'].addTracker(statsUrl+'m.php', siteId.toString());
|
||||
const matomo = this.getMatomo();
|
||||
matomo.setDocumentTitle(this.seoService.getTitle());
|
||||
matomo.setCustomUrl(this.getCustomUrl());
|
||||
matomo.disableCookies();
|
||||
matomo.trackPageView();
|
||||
matomo.enableLinkTracking();
|
||||
} else {
|
||||
// @ts-ignore
|
||||
const alreadyInitialized = !!window._paq;
|
||||
// @ts-ignore
|
||||
const _paq = window._paq = window._paq || [];
|
||||
_paq.push(['setDocumentTitle', this.seoService.getTitle()]);
|
||||
_paq.push(['setCustomUrl', this.getCustomUrl()]);
|
||||
_paq.push(['disableCookies']);
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
if (alreadyInitialized) {
|
||||
_paq.push(['addTracker', statsUrl+'m.php', siteId.toString()]);
|
||||
} else {
|
||||
(function() {
|
||||
_paq.push(['setTrackerUrl', statsUrl+'m.php']);
|
||||
_paq.push(['setSiteId', siteId.toString()]);
|
||||
const d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
// @ts-ignore
|
||||
g.type='text/javascript'; g.async=true; g.src=statsUrl+'m.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getMatomo() {
|
||||
if (this.siteId != null) {
|
||||
return window['Matomo']?.getTracker(this.statsUrl+'m.php', this.siteId);
|
||||
}
|
||||
}
|
||||
|
||||
goal(id: number) {
|
||||
// @ts-ignore
|
||||
this.getMatomo()?.trackGoal(id);
|
||||
}
|
||||
|
||||
page() {
|
||||
const matomo = this.getMatomo();
|
||||
if (matomo) {
|
||||
matomo.setCustomUrl(this.getCustomUrl());
|
||||
matomo.trackPageView();
|
||||
}
|
||||
}
|
||||
|
||||
private getCustomUrl(): string {
|
||||
let url = window.location.origin + '/';
|
||||
let route = this.activatedRoute;
|
||||
while (route) {
|
||||
const segment = route?.routeConfig?.path;
|
||||
if (segment && segment.length) {
|
||||
url += segment + '/';
|
||||
}
|
||||
route = route.firstChild;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ const downloadMiningPoolLogos = async () => {
|
|||
const poolLogos = await fetchGitHubContents('/repos/mempool/mining-pool-logos/contents/', !!config.githubToken);
|
||||
|
||||
let downloadedCount = 0;
|
||||
const validFiles = poolLogos.filter(item => item.type === 'file' && item.download_url);
|
||||
const validFiles = poolLogos.filter(item => item.type === 'file' && item.download_url && item.name.toLowerCase().endsWith('.svg'));
|
||||
|
||||
for (const poolLogo of validFiles) {
|
||||
if (config.verbose) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue