diff --git a/backend/src/api/acceleration/acceleration.routes.ts b/backend/src/api/acceleration/acceleration.routes.ts index 69b320171..ae0c3f7a8 100644 --- a/backend/src/api/acceleration/acceleration.routes.ts +++ b/backend/src/api/acceleration/acceleration.routes.ts @@ -1,12 +1,14 @@ -import { Application, Request, Response } from "express"; -import config from "../../config"; -import axios from "axios"; -import logger from "../../logger"; +import { Application, Request, Response } from 'express'; +import config from '../../config'; +import axios from 'axios'; +import logger from '../../logger'; +import mempool from '../mempool'; +import AccelerationRepository from '../../repositories/AccelerationRepository'; class AccelerationRoutes { private tag = 'Accelerator'; - public initRoutes(app: Application) { + public initRoutes(app: Application): void { app .get(config.MEMPOOL.API_URL_PREFIX + 'services/accelerator/accelerations', this.$getAcceleratorAccelerations.bind(this)) .get(config.MEMPOOL.API_URL_PREFIX + 'services/accelerator/accelerations/history', this.$getAcceleratorAccelerationsHistory.bind(this)) @@ -15,41 +17,33 @@ class AccelerationRoutes { ; } - private async $getAcceleratorAccelerations(req: Request, res: Response) { - const url = `${config.MEMPOOL_SERVICES.API}/${req.originalUrl.replace('/api/v1/services/', '')}`; - try { - const response = await axios.get(url, { responseType: 'stream', timeout: 10000 }); - for (const key in response.headers) { - res.setHeader(key, response.headers[key]); - } - response.data.pipe(res); - } catch (e) { - logger.err(`Unable to get current accelerations from ${url} in $getAcceleratorAccelerations(), ${e}`, this.tag); - res.status(500).end(); - } + private async $getAcceleratorAccelerations(req: Request, res: Response): Promise { + const accelerations = mempool.getAccelerations(); + res.status(200).send(Object.values(accelerations)); } - private async $getAcceleratorAccelerationsHistory(req: Request, res: Response) { - const url = `${config.MEMPOOL_SERVICES.API}/${req.originalUrl.replace('/api/v1/services/', '')}`; - try { - const response = await axios.get(url, { responseType: 'stream', timeout: 10000 }); - for (const key in response.headers) { - res.setHeader(key, response.headers[key]); - } - response.data.pipe(res); - } catch (e) { - logger.err(`Unable to get acceleration history from ${url} in $getAcceleratorAccelerationsHistory(), ${e}`, this.tag); - res.status(500).end(); - } + private async $getAcceleratorAccelerationsHistory(req: Request, res: Response): Promise { + const history = await AccelerationRepository.$getAccelerationInfo(null, req.query.blockHeight ? parseInt(req.query.blockHeight as string, 10) : null); + res.status(200).send(history.map(accel => ({ + txid: accel.txid, + added: accel.added, + status: 'completed', + effectiveFee: accel.effective_fee, + effectiveVsize: accel.effective_vsize, + boostRate: accel.boost_rate, + boostCost: accel.boost_cost, + blockHeight: accel.height, + pools: [accel.pool], + }))); } - private async $getAcceleratorAccelerationsHistoryAggregated(req: Request, res: Response) { + private async $getAcceleratorAccelerationsHistoryAggregated(req: Request, res: Response): Promise { const url = `${config.MEMPOOL_SERVICES.API}/${req.originalUrl.replace('/api/v1/services/', '')}`; try { const response = await axios.get(url, { responseType: 'stream', timeout: 10000 }); for (const key in response.headers) { - res.setHeader(key, response.headers[key]); - } + res.setHeader(key, response.headers[key]); + } response.data.pipe(res); } catch (e) { logger.err(`Unable to get aggregated acceleration history from ${url} in $getAcceleratorAccelerationsHistoryAggregated(), ${e}`, this.tag); @@ -57,13 +51,13 @@ class AccelerationRoutes { } } - private async $getAcceleratorAccelerationsStats(req: Request, res: Response) { + private async $getAcceleratorAccelerationsStats(req: Request, res: Response): Promise { const url = `${config.MEMPOOL_SERVICES.API}/${req.originalUrl.replace('/api/v1/services/', '')}`; try { const response = await axios.get(url, { responseType: 'stream', timeout: 10000 }); for (const key in response.headers) { - res.setHeader(key, response.headers[key]); - } + res.setHeader(key, response.headers[key]); + } response.data.pipe(res); } catch (e) { logger.err(`Unable to get acceleration stats from ${url} in $getAcceleratorAccelerationsStats(), ${e}`, this.tag); diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 28ca38152..16ae94f66 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -29,6 +29,7 @@ import websocketHandler from './websocket-handler'; import redisCache from './redis-cache'; import rbfCache from './rbf-cache'; import { calcBitsDifference } from './difficulty-adjustment'; +import AccelerationRepository from '../repositories/AccelerationRepository'; class Blocks { private blocks: BlockExtended[] = []; @@ -872,6 +873,7 @@ class Blocks { await BlocksRepository.$deleteBlocksFrom(lastBlock.height - 10); await HashratesRepository.$deleteLastEntries(); await cpfpRepository.$deleteClustersFrom(lastBlock.height - 10); + await AccelerationRepository.$deleteAccelerationsFrom(lastBlock.height - 10); this.blocks = this.blocks.slice(0, -10); this.updateTimerProgress(timer, `rolled back chain divergence from ${this.currentBlockHeight}`); for (let i = 10; i >= 0; --i) { @@ -974,6 +976,9 @@ class Blocks { if (this.blocks.length > config.MEMPOOL.INITIAL_BLOCKS_AMOUNT * 4) { this.blocks = this.blocks.slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT * 4); } + blockSummary.transactions.forEach(tx => { + delete tx.acc; + }); this.blockSummaries.push(blockSummary); if (this.blockSummaries.length > config.MEMPOOL.INITIAL_BLOCKS_AMOUNT * 4) { this.blockSummaries = this.blockSummaries.slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT * 4); @@ -1117,6 +1122,7 @@ class Blocks { } return { txid: tx.txid, + time: tx.firstSeen, fee: tx.fee || 0, vsize: tx.vsize, value: Math.round(tx.vout.reduce((acc, vout) => acc + (vout.value ? vout.value : 0), 0)), diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index 81f2caa44..c8272674f 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository'; import { RowDataPacket } from 'mysql2'; class DatabaseMigration { - private static currentVersion = 76; + private static currentVersion = 77; private queryTimeout = 3600_000; private statisticsAddedIndexed = false; private uniqueLogs: string[] = []; @@ -664,6 +664,11 @@ class DatabaseMigration { await this.$executeQuery('ALTER TABLE `blocks_audits` ADD prioritized_txs JSON DEFAULT "[]"'); await this.updateToSchemaVersion(76); } + + if (databaseSchemaVersion < 77 && config.MEMPOOL.NETWORK === 'mainnet') { + await this.$executeQuery('ALTER TABLE `accelerations` ADD requested datetime DEFAULT NULL'); + await this.updateToSchemaVersion(77); + } } /** diff --git a/backend/src/api/services/acceleration.ts b/backend/src/api/services/acceleration.ts index f22959f3f..5dc5d5074 100644 --- a/backend/src/api/services/acceleration.ts +++ b/backend/src/api/services/acceleration.ts @@ -5,6 +5,9 @@ import axios from 'axios'; export interface Acceleration { txid: string, + added: number, + effectiveVsize: number, + effectiveFee: number, feeDelta: number, pools: number[], }; diff --git a/backend/src/repositories/AccelerationRepository.ts b/backend/src/repositories/AccelerationRepository.ts index 4969013c4..34df770f1 100644 --- a/backend/src/repositories/AccelerationRepository.ts +++ b/backend/src/repositories/AccelerationRepository.ts @@ -6,7 +6,7 @@ import { IEsploraApi } from '../api/bitcoin/esplora-api.interface'; import { Common } from '../api/common'; import config from '../config'; import blocks from '../api/blocks'; -import accelerationApi, { Acceleration } from '../api/services/acceleration'; +import accelerationApi, { Acceleration, AccelerationHistory } from '../api/services/acceleration'; import accelerationCosts from '../api/acceleration/acceleration'; import bitcoinApi from '../api/bitcoin/bitcoin-api-factory'; import transactionUtils from '../api/transaction-utils'; @@ -15,6 +15,7 @@ import { BlockExtended, MempoolTransactionExtended } from '../mempool.interfaces export interface PublicAcceleration { txid: string, height: number, + added: number, pool: { id: number, slug: string, @@ -29,15 +30,20 @@ export interface PublicAcceleration { class AccelerationRepository { private bidBoostV2Activated = 831580; - public async $saveAcceleration(acceleration: AccelerationInfo, block: IEsploraApi.Block, pool_id: number): Promise { + public async $saveAcceleration(acceleration: AccelerationInfo, block: IEsploraApi.Block, pool_id: number, accelerationData: Acceleration[]): Promise { + const accelerationMap: { [txid: string]: Acceleration } = {}; + for (const acc of accelerationData) { + accelerationMap[acc.txid] = acc; + } try { await DB.query(` - INSERT INTO accelerations(txid, added, height, pool, effective_vsize, effective_fee, boost_rate, boost_cost) - VALUE (?, FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?) + INSERT INTO accelerations(txid, requested, added, height, pool, effective_vsize, effective_fee, boost_rate, boost_cost) + VALUE (?, FROM_UNIXTIME(?), FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE height = ? `, [ acceleration.txSummary.txid, + accelerationMap[acceleration.txSummary.txid].added, block.timestamp, block.height, pool_id, @@ -64,7 +70,7 @@ class AccelerationRepository { } let query = ` - SELECT * FROM accelerations + SELECT *, UNIX_TIMESTAMP(requested) as requested_timestamp, UNIX_TIMESTAMP(added) as block_timestamp FROM accelerations JOIN pools on pools.unique_id = accelerations.pool `; let params: any[] = []; @@ -99,6 +105,7 @@ class AccelerationRepository { return rows.map(row => ({ txid: row.txid, height: row.height, + added: row.requested_timestamp || row.block_timestamp, pool: { id: row.id, slug: row.slug, @@ -202,7 +209,7 @@ class AccelerationRepository { const tx = blockTxs[acc.txid]; const accelerationInfo = accelerationCosts.getAccelerationInfo(tx, boostRate, transactions); accelerationInfo.cost = Math.max(0, Math.min(acc.feeDelta, accelerationInfo.cost)); - this.$saveAcceleration(accelerationInfo, block, block.extras.pool.id); + this.$saveAcceleration(accelerationInfo, block, block.extras.pool.id, successfulAccelerations); } } const lastSyncedHeight = await this.$getLastSyncedHeight(); @@ -230,7 +237,7 @@ class AccelerationRepository { logger.debug(`Fetching accelerations between block ${lastSyncedHeight} and ${currentHeight}`); // Fetch accelerations from mempool.space since the last synced block; - const accelerationsByBlock = {}; + const accelerationsByBlock: {[height: number]: AccelerationHistory[]} = {}; const blockHashes = {}; let done = false; let page = 1; @@ -297,12 +304,16 @@ class AccelerationRepository { const feeStats = Common.calcEffectiveFeeStatistics(template); boostRate = feeStats.medianFee; } + const accelerationSummaries = accelerations.map(acc => ({ + ...acc, + pools: acc.pools.map(pool => pool.pool_unique_id), + })) for (const acc of accelerations) { if (blockTxs[acc.txid]) { const tx = blockTxs[acc.txid]; const accelerationInfo = accelerationCosts.getAccelerationInfo(tx, boostRate, transactions); accelerationInfo.cost = Math.max(0, Math.min(acc.feeDelta, accelerationInfo.cost)); - await this.$saveAcceleration(accelerationInfo, block, block.extras.pool.id); + await this.$saveAcceleration(accelerationInfo, block, block.extras.pool.id, accelerationSummaries); } } await this.$setLastSyncedHeight(height); @@ -317,6 +328,26 @@ class AccelerationRepository { logger.debug(`Indexing accelerations completed`); } + + /** + * Delete accelerations from the database above blockHeight + */ + public async $deleteAccelerationsFrom(blockHeight: number): Promise { + logger.info(`Delete newer accelerations from height ${blockHeight} from the database`); + try { + const currentSyncedHeight = await this.$getLastSyncedHeight(); + if (currentSyncedHeight >= blockHeight) { + await DB.query(` + UPDATE state + SET number = ? + WHERE name = 'last_acceleration_block' + `, [blockHeight - 1]); + } + await DB.query(`DELETE FROM accelerations where height >= ${blockHeight}`); + } catch (e) { + logger.err('Cannot delete indexed accelerations. Reason: ' + (e instanceof Error ? e.message : e)); + } + } } export default new AccelerationRepository(); diff --git a/contributors/daweilv.txt b/contributors/daweilv.txt new file mode 100644 index 000000000..2abb9f73b --- /dev/null +++ b/contributors/daweilv.txt @@ -0,0 +1,3 @@ +I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of April 7, 2024. + +Signed: daweilv diff --git a/frontend/angular.json b/frontend/angular.json index f55c59ae9..f631cce4d 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -170,6 +170,11 @@ ], "styles": [ "src/styles.scss", + { + "input": "src/theme-contrast.scss", + "bundleName": "contrast", + "inject": false + }, "node_modules/@fortawesome/fontawesome-svg-core/styles.css" ], "vendorChunk": true, diff --git a/frontend/src/app/app.constants.ts b/frontend/src/app/app.constants.ts index 17105d97e..bd81d02c0 100644 --- a/frontend/src/app/app.constants.ts +++ b/frontend/src/app/app.constants.ts @@ -1,4 +1,4 @@ -export const mempoolFeeColors = [ +export const defaultMempoolFeeColors = [ '557d00', '5d7d01', '637d02', @@ -39,6 +39,47 @@ export const mempoolFeeColors = [ 'ae005b', ]; +export const contrastMempoolFeeColors = [ + '0082e6', + '0984df', + '1285d9', + '1a87d2', + '2388cb', + '2c8ac5', + '358bbe', + '3e8db7', + '468eb0', + '4f90aa', + '5892a3', + '61939c', + '6a9596', + '72968f', + '7b9888', + '849982', + '8d9b7b', + '959c74', + '9e9e6e', + 'a79f67', + 'b0a160', + 'b9a35a', + 'c1a453', + 'caa64c', + 'd3a745', + 'dca93f', + 'e5aa38', + 'edac31', + 'f6ad2b', + 'ffaf24', + 'ffb01e', + 'ffb118', + 'ffb212', + 'ffb30c', + 'ffb406', + 'ffb500', + 'ffb600', + 'ffb700', + ]; + export const chartColors = [ "#D81B60", "#8E24AA", diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index e3f585a25..65d484520 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -19,6 +19,7 @@ import { SharedModule } from './shared/shared.module'; import { StorageService } from './services/storage.service'; import { HttpCacheInterceptor } from './services/http-cache.interceptor'; import { LanguageService } from './services/language.service'; +import { ThemeService } from './services/theme.service'; import { FiatShortenerPipe } from './shared/pipes/fiat-shortener.pipe'; import { FiatCurrencyPipe } from './shared/pipes/fiat-currency.pipe'; import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe'; @@ -38,6 +39,7 @@ const providers = [ StorageService, EnterpriseService, LanguageService, + ThemeService, ShortenStringPipe, FiatShortenerPipe, FiatCurrencyPipe, diff --git a/frontend/src/app/components/about/about-sponsors.component.scss b/frontend/src/app/components/about/about-sponsors.component.scss index 7c01bb9a3..0ee27d1f5 100644 --- a/frontend/src/app/components/about/about-sponsors.component.scss +++ b/frontend/src/app/components/about/about-sponsors.component.scss @@ -14,7 +14,7 @@ } .become-sponsor { - background-color: #1d1f31; + background-color: var(--bg); border-radius: 16px; padding: 12px 20px; width: 400px; diff --git a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss index 8d36387f3..88d9f75ed 100644 --- a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss +++ b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss @@ -92,7 +92,7 @@ &.target { .fill { - background: #653b9c; + background: var(--tertiary); } .fee { position: absolute; @@ -114,7 +114,7 @@ } &.active, &:hover { .fill { - background: #105fb0; + background: var(--primary); } .line { .fee-rate .label { diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html index 3c8571dd4..d303858a5 100644 --- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html +++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html @@ -65,24 +65,26 @@
-
How much more are you willing to pay?
-
-
- Choose the maximum extra transaction fee you're willing to pay to get into the next block. -
-
-
- - - + @if (paymentType !== 'cashapp') { +
How much more are you willing to pay?
+
+
+ Choose the maximum extra transaction fee you're willing to pay to get into the next block. +
+
+
+ + + +
-
+ }
Acceleration summary
@@ -90,27 +92,51 @@ - - - - - - - - - - - - + @if (paymentType === 'cashapp') { + + + + + + + + + + + + + } @else { + + + + + + + + + + + + + } @@ -141,53 +167,76 @@ - - - - - - - - - - - + + @if (paymentType === 'cashapp') { + + + + + + + + + } @else { + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + } @@ -237,14 +286,17 @@ -
-
Accelerate with
-
-
- Loading -
+ @if (!hideCashApp && paymentType === 'cashapp') { +
+
+
Accelerate for with
+
+
+ Loading +
+
-
+ }
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss index 2e2b19ee8..1f73ea9b2 100644 --- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss +++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss @@ -1,6 +1,6 @@ .fee-card { padding: 15px; - background-color: #1d1f31; + background-color: var(--bg); .feerate { display: flex; @@ -23,7 +23,7 @@ } .feerate.active { - background-color: #105fb0 !important; + background-color: var(--primary) !important; opacity: 1; border: 1px solid #007fff !important; } @@ -109,4 +109,61 @@ .item { white-space: initial; +} + +.cashapp-cta { + width: 100%; + height: 54px; + background: #653b9c; + position: relative; + bottom: initial; + top: initial; + border-radius: 3px; + font-size: 14px; + line-height: 16px; + text-align: center; + padding: 4px 6px; + cursor: pointer; + box-shadow: 0px 0px 15px 0px #000; + + &.sticky-top { + position: fixed; + width: calc(100vw - 30px - 1.5rem); + margin: auto; + z-index: 50; + left: 0; + right: 0; + top: 102px; + @media (min-width: 573px) { + top: 62px; + } + } + &.sticky-bottom { + position: fixed; + width: calc(100vw - 30px - 1.5rem); + margin: auto; + z-index: 50; + left: 0; + right: 0; + bottom: 50px; + @media (min-width: 430px) { + bottom: 56px; + } + } + + @media (max-width: 400px) { + width: calc(100% + 1.5rem); + margin: 0 -0.75rem; + &.sticky-top, &.sticky-bottom { + width: calc(100vw - 30px); + } + } +} + +.cashapp-placeholder { + height: 54px; + + &.non-stick { + height: 0px; + } } \ No newline at end of file diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts index aee0189aa..19edf9b7e 100644 --- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts +++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges, HostListener, ChangeDetectorRef } from '@angular/core'; +import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges, HostListener, ChangeDetectorRef, ViewChild, ElementRef } from '@angular/core'; import { Subscription, catchError, of, tap } from 'rxjs'; import { StorageService } from '../../services/storage.service'; import { Transaction } from '../../interfaces/electrs.interface'; @@ -43,6 +43,9 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges @Input() tx: Transaction | undefined; @Input() scrollEvent: boolean; + @ViewChild('cashappCTA') + cashappCTA: ElementRef; + math = Math; error = ''; showSuccess = false; @@ -56,9 +59,11 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges defaultBid = 0; maxCost = 0; userBid = 0; + accelerationUUID: string; selectFeeRateIndex = 1; isMobile: boolean = window.innerWidth <= 767.98; user: any = undefined; + stickyCTA: string = 'non-stick'; maxRateOptions: RateOption[] = []; @@ -66,6 +71,7 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges paymentType: 'bitcoin' | 'cashapp' = 'bitcoin'; cashAppSubscription: Subscription; conversionsSubscription: Subscription; + cashappSubmit: any; payments: any; showSpinner = false; square: any; @@ -80,7 +86,10 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges private cd: ChangeDetectorRef ) { if (this.stateService.ref === 'https://cash.app/') { + this.paymentType = 'cashapp'; this.insertSquare(); + } else { + this.paymentType = 'bitcoin'; } } @@ -94,21 +103,23 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges } ngOnInit() { + this.accelerationUUID = window.crypto.randomUUID(); if (this.stateService.ref === 'https://cash.app/') { this.paymentType = 'cashapp'; - this.stateService.ref = ''; } else { this.paymentType = 'bitcoin'; } } ngOnChanges(changes: SimpleChanges): void { - if (changes.scrollEvent) { + if (changes.scrollEvent && this.paymentType !== 'cashapp' && this.stateService.ref !== 'https://cash.app/') { this.scrollToPreview('acceleratePreviewAnchor', 'start'); } } ngAfterViewInit() { + this.onScroll(); + if (this.paymentType === 'cashapp') { this.showSpinner = true; } @@ -173,10 +184,15 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges this.maxCost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee; if (!this.error) { - this.scrollToPreview('acceleratePreviewAnchor', 'start'); if (this.paymentType === 'cashapp') { this.setupSquare(); - } + } else { + this.scrollToPreview('acceleratePreviewAnchor', 'start'); + } + + setTimeout(() => { + this.onScroll(); + }, 100); } } }), @@ -231,7 +247,8 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges } this.accelerationSubscription = this.servicesApiService.accelerate$( this.tx.txid, - this.userBid + this.userBid, + this.accelerationUUID ).subscribe({ next: () => { this.audioService.playSound('ascend-chime-cartoon'); @@ -301,6 +318,10 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges this.conversionsSubscription = this.stateService.conversions$.subscribe( async (conversions) => { + if (this.cashAppPay) { + this.cashAppPay.destroy(); + } + const maxCostUsd = this.maxCost / 100_000_000 * conversions.USD; const paymentRequest = this.payments.paymentRequest({ countryCode: 'US', @@ -310,13 +331,15 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges label: 'Total', pending: true, productUrl: `https://mempool.space/tx/${this.tx.txid}`, - } + }, + button: { shape: 'semiround', size: 'small', theme: 'light'} }); this.cashAppPay = await this.payments.cashAppPay(paymentRequest, { redirectURL: `https://mempool.space/tx/${this.tx.txid}`, referenceId: `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`, + button: { shape: 'semiround', size: 'small', theme: 'light'} }); - await this.cashAppPay.attach('#cash-app-pay'); + const renderPromise = this.cashAppPay.CashAppPayInstance.render('#cash-app-pay', { button: { theme: 'light', size: 'small', shape: 'semiround' }, manage: false }); this.showSpinner = false; const that = this; @@ -332,7 +355,8 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges that.userBid, tokenResult.token, tokenResult.details.cashAppPay.cashtag, - tokenResult.details.cashAppPay.referenceId + tokenResult.details.cashAppPay.referenceId, + that.accelerationUUID ).subscribe({ next: () => { that.audioService.playSound('ascend-chime-cartoon'); @@ -351,13 +375,19 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges }); } }); + + this.cashappSubmit = await renderPromise; } ); } insertSquare(): void { let statsUrl = 'https://sandbox.web.squarecdn.com/v1/square.js'; - if (document.location.hostname === 'mempool-staging.tk7.mempool.space' || document.location.hostname === 'mempool.space') { + if (document.location.hostname === 'mempool-staging.fmt.mempool.space' || + document.location.hostname === 'mempool-staging.va1.mempool.space' || + document.location.hostname === 'mempool-staging.fra.mempool.space' || + document.location.hostname === 'mempool-staging.tk7.mempool.space' || + document.location.hostname === 'mempool.space') { statsUrl = 'https://web.squarecdn.com/v1/square.js'; } @@ -367,4 +397,34 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges g.type='text/javascript'; g.src=statsUrl; s.parentNode.insertBefore(g, s); })(); } + + submitCashappPay(): void { + if (this.cashappSubmit) { + this.cashappSubmit?.begin(); + } + } + + @HostListener('window:scroll', ['$event']) // for window scroll events + onScroll() { + if (this.estimate && !this.cashappCTA?.nativeElement) { + setTimeout(() => { + this.onScroll(); + }, 200); + return; + } + if (!this.cashappCTA?.nativeElement || this.paymentType !== 'cashapp' || !this.isMobile) { + return; + } + const cta = this.cashappCTA.nativeElement; + const rect = cta.getBoundingClientRect(); + const topOffset = window.innerWidth <= 572 ? 102 : 62; + const bottomOffset = window.innerWidth < 430 ? 50 : 56; + if (rect.top < topOffset) { + this.stickyCTA = 'sticky-top'; + } else if (rect.top > window.innerHeight - (bottomOffset + 54)) { + this.stickyCTA = 'sticky-bottom'; + } else { + this.stickyCTA = 'non-stick'; + } + } } diff --git a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.html b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.html index cbebb0f86..852e92ae0 100644 --- a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.html +++ b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.html @@ -45,7 +45,7 @@ -
diff --git a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.scss b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.scss index 11b468a24..96273dead 100644 --- a/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.scss +++ b/frontend/src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.scss @@ -62,7 +62,7 @@ h5 { .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .disabled { diff --git a/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.scss b/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.scss index fcc5564a8..e685d98af 100644 --- a/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.scss +++ b/frontend/src/app/components/acceleration/acceleration-stats/acceleration-stats.component.scss @@ -1,5 +1,5 @@ .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; diff --git a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.html b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.html index 74c8ed3d1..668f345f0 100644 --- a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.html +++ b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.html @@ -39,10 +39,10 @@ -
- + + + + } @else { - } @else { - } @@ -530,7 +537,7 @@ } @else if (this.mempoolPosition.block >= 7) { In several hours (or more) - @if (!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) { + @if (!(isMobile && paymentType === 'cashapp') && !tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) { Accelerate } @@ -539,7 +546,7 @@ } @else { - @if (!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) { + @if (!(isMobile && paymentType === 'cashapp') && !tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) { Accelerate } @@ -554,13 +561,13 @@ @if (!isLoadingTx) { - @if (((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration)) || filters.length) { + @if (isAcceleration || filters.length) { - @if (tx.acceleration || accelerationInfo) { + @if (isAcceleration) { } @else { }
Next block market rate - {{ estimate.targetFeeRate | number : '1.0-0' }} - sat/vB
- Estimated extra fee required - - {{ math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee) | number }} - - sats - -
Boost rate + {{ maxRateOptions[selectFeeRateIndex].rate | number : '1.0-0' }} + sat/vB
+ Boost fee + + {{ maxRateOptions[selectFeeRateIndex].fee | number }} + + sats + +
Next block market rate + {{ estimate.targetFeeRate | number : '1.0-0' }} + sat/vB
+ Estimated extra fee required + + {{ math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee) | number }} + + sats + +
- Estimated acceleration cost - - - {{ estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee | number }} - - - sats - -
- -
+ Total cost + + + {{ maxCost | number }} + + + sats + + + +
+ Estimated acceleration cost + + + {{ estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee | number }} + + + sats + +
+ +
- Maximum acceleration cost - - - {{ maxCost | number }} - - - sats - - - -
- -
+ Maximum acceleration cost + + + {{ maxCost | number }} + + + sats + + + +
+ +
- {{ (acceleration.boost) | number }} sat + + {{ acceleration.boost | number }} sat + ~ diff --git a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.scss b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.scss index 85e655b25..d4579bcf6 100644 --- a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.scss +++ b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.scss @@ -59,7 +59,7 @@ tr, td, th { } .progress { - background-color: #2d3348; + background-color: var(--secondary); } .txid { @@ -148,7 +148,7 @@ tr, td, th { .tooltip-custom .tooltiptext { visibility: hidden; - color: #fff; + color: var(--fg); text-align: center; padding: 5px 0; border-radius: 6px; diff --git a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts index 1a0aacbb6..5acd77d5d 100644 --- a/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts +++ b/frontend/src/app/components/acceleration/accelerations-list/accelerations-list.component.ts @@ -58,7 +58,7 @@ export class AccelerationsListComponent implements OnInit { } } for (const acc of accelerations) { - acc.boost = acc.feePaid - acc.baseFee - acc.vsizeFee; + acc.boost = acc.boostCost != null ? acc.boostCost : (acc.feePaid - acc.baseFee - acc.vsizeFee); } if (this.widget) { return of(accelerations.slice(0, 6)); diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html index 3488e1075..39abfa461 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html @@ -40,7 +40,7 @@
Mempool Goggles™ : Accelerations
  - +
diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.scss b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.scss index c8755c94e..e14f53dfb 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.scss +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.scss @@ -7,7 +7,7 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); } .graph-card { @@ -29,10 +29,10 @@ .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .card-title > a { - color: #4a68b9; + color: var(--title-fg); } .card-body.pool-ranking { diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts index 58bc43c42..acaff9170 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts @@ -8,13 +8,15 @@ import { Observable, catchError, combineLatest, distinctUntilChanged, interval, import { Color } from '../../block-overview-graph/sprite-types'; import { hexToColor } from '../../block-overview-graph/utils'; import TxView from '../../block-overview-graph/tx-view'; -import { feeLevels, mempoolFeeColors } from '../../../app.constants'; +import { feeLevels, defaultMempoolFeeColors, contrastMempoolFeeColors } from '../../../app.constants'; import { ServicesApiServices } from '../../../services/services-api.service'; import { detectWebGL } from '../../../shared/graphs.utils'; import { AudioService } from '../../../services/audio.service'; +import { ThemeService } from '../../../services/theme.service'; const acceleratedColor: Color = hexToColor('8F5FF6'); -const normalColors = mempoolFeeColors.map(hex => hexToColor(hex.slice(0,6) + '5F')); +const normalColors = defaultMempoolFeeColors.map(hex => hexToColor(hex + '5F')); +const contrastColors = contrastMempoolFeeColors.map(hex => hexToColor(hex.slice(0,6) + '5F')); interface AccelerationBlock extends BlockExtended { accelerationCount: number, @@ -37,6 +39,7 @@ export class AcceleratorDashboardComponent implements OnInit { firstLoad = true; graphHeight: number = 300; + theme: ThemeService; constructor( private seoService: SeoService, @@ -116,15 +119,15 @@ export class AcceleratorDashboardComponent implements OnInit { switchMap(([accelerations, blocks]) => { const blockMap = {}; for (const block of blocks) { - blockMap[block.id] = block; + blockMap[block.height] = block; } - const accelerationsByBlock: { [ hash: string ]: Acceleration[] } = {}; + const accelerationsByBlock: { [ height: number ]: Acceleration[] } = {}; for (const acceleration of accelerations) { - if (['completed_provisional', 'failed_provisional', 'completed'].includes(acceleration.status) && acceleration.pools.includes(blockMap[acceleration.blockHash]?.extras.pool.id)) { - if (!accelerationsByBlock[acceleration.blockHash]) { - accelerationsByBlock[acceleration.blockHash] = []; + if (['completed_provisional', 'failed_provisional', 'completed'].includes(acceleration.status) && acceleration.pools.includes(blockMap[acceleration.blockHeight]?.extras.pool.id)) { + if (!accelerationsByBlock[acceleration.blockHeight]) { + accelerationsByBlock[acceleration.blockHeight] = []; } - accelerationsByBlock[acceleration.blockHash].push(acceleration); + accelerationsByBlock[acceleration.blockHeight].push(acceleration); } } return of(blocks.slice(0, 6).map(block => { @@ -141,7 +144,7 @@ export class AcceleratorDashboardComponent implements OnInit { } else { const rate = tx.fee / tx.vsize; // color by simple single-tx fee rate const feeLevelIndex = feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1; - return normalColors[feeLevelIndex] || normalColors[mempoolFeeColors.length - 1]; + return this.theme.theme === 'contrast' ? contrastColors[feeLevelIndex] || contrastColors[contrastColors.length - 1] : normalColors[feeLevelIndex] || normalColors[normalColors.length - 1]; } } diff --git a/frontend/src/app/components/acceleration/pending-stats/pending-stats.component.scss b/frontend/src/app/components/acceleration/pending-stats/pending-stats.component.scss index fcc5564a8..e685d98af 100644 --- a/frontend/src/app/components/acceleration/pending-stats/pending-stats.component.scss +++ b/frontend/src/app/components/acceleration/pending-stats/pending-stats.component.scss @@ -1,5 +1,5 @@ .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; diff --git a/frontend/src/app/components/address-graph/address-graph.component.ts b/frontend/src/app/components/address-graph/address-graph.component.ts index a73229495..4e31e663f 100644 --- a/frontend/src/app/components/address-graph/address-graph.component.ts +++ b/frontend/src/app/components/address-graph/address-graph.component.ts @@ -6,6 +6,7 @@ import { ChainStats } from '../../interfaces/electrs.interface'; import { ElectrsApiService } from '../../services/electrs-api.service'; import { AmountShortenerPipe } from '../../shared/pipes/amount-shortener.pipe'; import { Router } from '@angular/router'; +import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; @Component({ selector: 'app-address-graph', @@ -46,6 +47,7 @@ export class AddressGraphComponent implements OnChanges { private router: Router, private amountShortenerPipe: AmountShortenerPipe, private cd: ChangeDetectorRef, + private relativeUrlPipe: RelativeUrlPipe, ) {} ngOnChanges(changes: SimpleChanges): void { @@ -122,7 +124,7 @@ export class AddressGraphComponent implements OnChanges { ${date} - `; + `; }.bind(this) }, xAxis: { @@ -159,7 +161,7 @@ export class AddressGraphComponent implements OnChanges { ], series: [ { - name: $localize`Balance:Balance`, + name: $localize`:@@7e69426bd97a606d8ae6026762858e6e7c86a1fd:Balance`, showSymbol: false, symbol: 'circle', symbolSize: 8, @@ -178,7 +180,7 @@ export class AddressGraphComponent implements OnChanges { onChartClick(e) { if (this.hoverData?.length && this.hoverData[0]?.[2]?.txid) { - this.router.navigate(['/tx/', this.hoverData[0][2].txid]); + this.router.navigate([this.relativeUrlPipe.transform('/tx/'), this.hoverData[0][2].txid]); } } diff --git a/frontend/src/app/components/address/address-preview.component.scss b/frontend/src/app/components/address/address-preview.component.scss index 21e7faab5..623d72db2 100644 --- a/frontend/src/app/components/address/address-preview.component.scss +++ b/frontend/src/app/components/address/address-preview.component.scss @@ -3,7 +3,7 @@ } .qr-wrapper { - background-color: #FFF; + background-color: var(--fg); padding: 10px; padding-bottom: 5px; display: inline-block; diff --git a/frontend/src/app/components/address/address.component.scss b/frontend/src/app/components/address/address.component.scss index fe0729b94..7107c73f2 100644 --- a/frontend/src/app/components/address/address.component.scss +++ b/frontend/src/app/components/address/address.component.scss @@ -1,5 +1,5 @@ .qr-wrapper { - background-color: #FFF; + background-color: var(--fg); padding: 10px; padding-bottom: 5px; display: inline-block; diff --git a/frontend/src/app/components/amount/amount.component.scss b/frontend/src/app/components/amount/amount.component.scss index b26429dcc..87f2fe6cd 100644 --- a/frontend/src/app/components/amount/amount.component.scss +++ b/frontend/src/app/components/amount/amount.component.scss @@ -1,3 +1,3 @@ .green-color { - color: #3bcc49; + color: var(--green); } \ No newline at end of file diff --git a/frontend/src/app/components/asset/asset.component.scss b/frontend/src/app/components/asset/asset.component.scss index 45e68042d..6f8bc0915 100644 --- a/frontend/src/app/components/asset/asset.component.scss +++ b/frontend/src/app/components/asset/asset.component.scss @@ -1,5 +1,5 @@ .qr-wrapper { - background-color: #FFF; + background-color: var(--fg); padding: 10px; padding-bottom: 5px; display: inline-block; diff --git a/frontend/src/app/components/assets/asset-group/asset-group.component.scss b/frontend/src/app/components/assets/asset-group/asset-group.component.scss index c0b31f273..d434c16ef 100644 --- a/frontend/src/app/components/assets/asset-group/asset-group.component.scss +++ b/frontend/src/app/components/assets/asset-group/asset-group.component.scss @@ -19,7 +19,7 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); width: 200px; height: 200px; align-items: center; diff --git a/frontend/src/app/components/assets/assets-featured/assets-featured.component.scss b/frontend/src/app/components/assets/assets-featured/assets-featured.component.scss index 32c560af4..c80c3689d 100644 --- a/frontend/src/app/components/assets/assets-featured/assets-featured.component.scss +++ b/frontend/src/app/components/assets/assets-featured/assets-featured.component.scss @@ -7,7 +7,7 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); width: 200px; height: 200px; align-items: center; diff --git a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.scss b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.scss index 21dd458b5..d38bb4843 100644 --- a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.scss +++ b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.scss @@ -95,7 +95,7 @@ } .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .card-text { font-size: 18px; diff --git a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts index 0abc55aa7..ba3489e17 100644 --- a/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts +++ b/frontend/src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts @@ -233,7 +233,7 @@ export class BlockFeeRatesGraphComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -309,7 +309,7 @@ export class BlockFeeRatesGraphComponent implements OnInit { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, @@ -376,7 +376,7 @@ export class BlockFeeRatesGraphComponent implements OnInit { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 40; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/block-fees-graph/block-fees-graph.component.ts b/frontend/src/app/components/block-fees-graph/block-fees-graph.component.ts index 895a6f33f..eb567c2a6 100644 --- a/frontend/src/app/components/block-fees-graph/block-fees-graph.component.ts +++ b/frontend/src/app/components/block-fees-graph/block-fees-graph.component.ts @@ -151,7 +151,7 @@ export class BlockFeesGraphComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -214,7 +214,7 @@ export class BlockFeesGraphComponent implements OnInit { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, @@ -305,7 +305,7 @@ export class BlockFeesGraphComponent implements OnInit { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 40; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/block-filters/block-filters.component.scss b/frontend/src/app/components/block-filters/block-filters.component.scss index b1c4bce17..e6da842c0 100644 --- a/frontend/src/app/components/block-filters/block-filters.component.scss +++ b/frontend/src/app/components/block-filters/block-filters.component.scss @@ -71,7 +71,7 @@ .filter-tag { font-size: 0.9em; background: #181b2daf; - border: solid 1px #105fb0; + border: solid 1px var(--primary); color: white; border-radius: 0.2rem; padding: 0.2em 0.5em; @@ -80,15 +80,15 @@ pointer-events: all; &.selected { - background-color: #105fb0; + background-color: var(--primary); } } &.any-mode { .filter-tag { - border: solid 1px #1a9436; + border: solid 1px var(--success); &.selected { - background-color: #1a9436; + background-color: var(--success); } } } @@ -114,15 +114,15 @@ } &.blue { - border: solid 1px #105fb0; + border: solid 1px var(--primary); &.active { - background: #105fb0; + background: var(--primary); } } &.green { - border: solid 1px #1a9436; + border: solid 1px var(--success); &.active { - background: #1a9436; + background: var(--success); } } &.yellow { diff --git a/frontend/src/app/components/block-health-graph/block-health-graph.component.ts b/frontend/src/app/components/block-health-graph/block-health-graph.component.ts index 8eef20d51..e48d5c091 100644 --- a/frontend/src/app/components/block-health-graph/block-health-graph.component.ts +++ b/frontend/src/app/components/block-health-graph/block-health-graph.component.ts @@ -131,7 +131,7 @@ export class BlockHealthGraphComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -178,7 +178,7 @@ export class BlockHealthGraphComponent implements OnInit { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, @@ -290,7 +290,7 @@ export class BlockHealthGraphComponent implements OnInit { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 40; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.scss b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.scss index c468cf792..af5135db7 100644 --- a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.scss +++ b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.scss @@ -2,7 +2,7 @@ position: relative; width: 100%; padding-bottom: 100%; - background: #181b2d; + background: var(--stat-box-bg); display: flex; justify-content: center; align-items: center; diff --git a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts index a67b5d981..3fee3f901 100644 --- a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts +++ b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts @@ -7,8 +7,9 @@ import TxView from './tx-view'; import { Color, Position } from './sprite-types'; import { Price } from '../../services/price.service'; import { StateService } from '../../services/state.service'; +import { ThemeService } from '../../services/theme.service'; import { Subscription } from 'rxjs'; -import { defaultColorFunction, setOpacity, defaultAuditColors, defaultColors, ageColorFunction } from './utils'; +import { defaultColorFunction, setOpacity, defaultAuditColors, defaultColors, ageColorFunction, contrastColorFunction, contrastAuditColors, contrastColors } from './utils'; import { ActiveFilter, FilterMode, toFlags } from '../../shared/filters.utils'; import { detectWebGL } from '../../shared/graphs.utils'; @@ -20,6 +21,13 @@ const unmatchedAuditColors = { prioritized: setOpacity(defaultAuditColors.prioritized, unmatchedOpacity), accelerated: setOpacity(defaultAuditColors.accelerated, unmatchedOpacity), }; +const unmatchedContrastAuditColors = { + censored: setOpacity(contrastAuditColors.censored, unmatchedOpacity), + missing: setOpacity(contrastAuditColors.missing, unmatchedOpacity), + added: setOpacity(contrastAuditColors.added, unmatchedOpacity), + prioritized: setOpacity(contrastAuditColors.prioritized, unmatchedOpacity), + accelerated: setOpacity(contrastAuditColors.accelerated, unmatchedOpacity), +}; @Component({ selector: 'app-block-overview-graph', @@ -53,6 +61,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On @ViewChild('blockCanvas') canvas: ElementRef; + themeChangedSubscription: Subscription; gl: WebGLRenderingContext; animationFrameRequest: number; @@ -84,6 +93,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On readonly ngZone: NgZone, readonly elRef: ElementRef, public stateService: StateService, + private themeService: ThemeService, ) { this.webGlEnabled = this.stateService.isBrowser && detectWebGL(); this.vertexArray = new FastVertexArray(512, TxSprite.dataSize); @@ -102,6 +112,9 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On if (this.gl) { this.initCanvas(); this.resizeCanvas(); + this.themeChangedSubscription = this.themeService.themeChanged$.subscribe(() => { + this.scene.setColorFunction(this.getColorFunction()); + }); } } } @@ -148,6 +161,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On if (this.canvas) { this.canvas.nativeElement.removeEventListener('webglcontextlost', this.handleContextLost); this.canvas.nativeElement.removeEventListener('webglcontextrestored', this.handleContextRestored); + this.themeChangedSubscription?.unsubscribe(); } } @@ -293,7 +307,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On this.start(); } else { this.scene = new BlockScene({ width: this.displayWidth, height: this.displayHeight, resolution: this.resolution, - blockLimit: this.blockLimit, orientation: this.orientation, flip: this.flip, vertexArray: this.vertexArray, + blockLimit: this.blockLimit, orientation: this.orientation, flip: this.flip, vertexArray: this.vertexArray, theme: this.themeService, highlighting: this.auditHighlighting, animationDuration: this.animationDuration, animationOffset: this.animationOffset, colorFunction: this.getColorFunction() }); this.start(); @@ -563,14 +577,27 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On getFilterColorFunction(flags: bigint, gradient: 'fee' | 'age'): ((tx: TxView) => Color) { return (tx: TxView) => { if ((this.filterMode === 'and' && (tx.bigintFlags & flags) === flags) || (this.filterMode === 'or' && (flags === 0n || (tx.bigintFlags & flags) > 0n))) { - return (gradient === 'age') ? ageColorFunction(tx, defaultColors.fee, defaultAuditColors, this.relativeTime || (Date.now() / 1000)) : defaultColorFunction(tx, defaultColors.fee, defaultAuditColors, this.relativeTime || (Date.now() / 1000)); + if (this.themeService.theme !== 'contrast') { + return (gradient === 'age') ? ageColorFunction(tx, defaultColors.fee, defaultAuditColors, this.relativeTime || (Date.now() / 1000)) : defaultColorFunction(tx, defaultColors.fee, defaultAuditColors, this.relativeTime || (Date.now() / 1000)); + } else { + return (gradient === 'age') ? ageColorFunction(tx, contrastColors.fee, contrastAuditColors, this.relativeTime || (Date.now() / 1000)) : contrastColorFunction(tx, contrastColors.fee, contrastAuditColors, this.relativeTime || (Date.now() / 1000)); + } } else { - return (gradient === 'age') ? { r: 1, g: 1, b: 1, a: 0.05 } : defaultColorFunction( - tx, - defaultColors.unmatchedfee, - unmatchedAuditColors, - this.relativeTime || (Date.now() / 1000) - ); + if (this.themeService.theme !== 'contrast') { + return (gradient === 'age') ? { r: 1, g: 1, b: 1, a: 0.05 } : defaultColorFunction( + tx, + defaultColors.unmatchedfee, + unmatchedAuditColors, + this.relativeTime || (Date.now() / 1000) + ); + } else { + return (gradient === 'age') ? { r: 1, g: 1, b: 1, a: 0.05 } : contrastColorFunction( + tx, + contrastColors.unmatchedfee, + unmatchedContrastAuditColors, + this.relativeTime || (Date.now() / 1000) + ); + } } }; } diff --git a/frontend/src/app/components/block-overview-graph/block-scene.ts b/frontend/src/app/components/block-overview-graph/block-scene.ts index fb45e492b..6f420a1da 100644 --- a/frontend/src/app/components/block-overview-graph/block-scene.ts +++ b/frontend/src/app/components/block-overview-graph/block-scene.ts @@ -2,13 +2,15 @@ import { FastVertexArray } from './fast-vertex-array'; import TxView from './tx-view'; import { TransactionStripped } from '../../interfaces/node-api.interface'; import { Color, Position, Square, ViewUpdateParams } from './sprite-types'; -import { defaultColorFunction } from './utils'; +import { defaultColorFunction, contrastColorFunction } from './utils'; +import { ThemeService } from '../../services/theme.service'; export default class BlockScene { scene: { count: number, offset: { x: number, y: number}}; vertexArray: FastVertexArray; txs: { [key: string]: TxView }; getColor: ((tx: TxView) => Color) = defaultColorFunction; + theme: ThemeService; orientation: string; flip: boolean; animationDuration: number = 900; @@ -29,11 +31,11 @@ export default class BlockScene { animateUntil = 0; dirty: boolean; - constructor({ width, height, resolution, blockLimit, animationDuration, animationOffset, orientation, flip, vertexArray, highlighting, colorFunction }: + constructor({ width, height, resolution, blockLimit, animationDuration, animationOffset, orientation, flip, vertexArray, theme, highlighting, colorFunction }: { width: number, height: number, resolution: number, blockLimit: number, animationDuration: number, animationOffset: number, - orientation: string, flip: boolean, vertexArray: FastVertexArray, highlighting: boolean, colorFunction: ((tx: TxView) => Color) | null } + orientation: string, flip: boolean, vertexArray: FastVertexArray, theme: ThemeService, highlighting: boolean, colorFunction: ((tx: TxView) => Color) | null } ) { - this.init({ width, height, resolution, blockLimit, animationDuration, animationOffset, orientation, flip, vertexArray, highlighting, colorFunction }); + this.init({ width, height, resolution, blockLimit, animationDuration, animationOffset, orientation, flip, vertexArray, theme, highlighting, colorFunction }); } resize({ width = this.width, height = this.height, animate = true }: { width?: number, height?: number, animate: boolean }): void { @@ -67,7 +69,7 @@ export default class BlockScene { } setColorFunction(colorFunction: ((tx: TxView) => Color) | null): void { - this.getColor = colorFunction || defaultColorFunction; + this.theme.theme !== 'default' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction; this.updateAllColors(); } @@ -197,6 +199,7 @@ export default class BlockScene { this.txs[tx.txid].feerate = tx.rate || (this.txs[tx.txid].fee / this.txs[tx.txid].vsize); this.txs[tx.txid].rate = tx.rate; this.txs[tx.txid].dirty = true; + this.updateColor(this.txs[tx.txid], startTime, 50, true); } }); @@ -232,9 +235,9 @@ export default class BlockScene { this.animateUntil = Math.max(this.animateUntil, tx.setHighlight(value)); } - private init({ width, height, resolution, blockLimit, animationDuration, animationOffset, orientation, flip, vertexArray, highlighting, colorFunction }: + private init({ width, height, resolution, blockLimit, animationDuration, animationOffset, orientation, flip, vertexArray, theme, highlighting, colorFunction }: { width: number, height: number, resolution: number, blockLimit: number, animationDuration: number, animationOffset: number, - orientation: string, flip: boolean, vertexArray: FastVertexArray, highlighting: boolean, colorFunction: ((tx: TxView) => Color) | null } + orientation: string, flip: boolean, vertexArray: FastVertexArray, theme: ThemeService, highlighting: boolean, colorFunction: ((tx: TxView) => Color) | null } ): void { this.animationDuration = animationDuration || 1000; this.configAnimationOffset = animationOffset; @@ -243,7 +246,8 @@ export default class BlockScene { this.flip = flip; this.vertexArray = vertexArray; this.highlightingEnabled = highlighting; - this.getColor = colorFunction || defaultColorFunction; + theme.theme !== 'default' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction; + this.theme = theme; this.scene = { count: 0, diff --git a/frontend/src/app/components/block-overview-graph/utils.ts b/frontend/src/app/components/block-overview-graph/utils.ts index d15e87534..ec6181853 100644 --- a/frontend/src/app/components/block-overview-graph/utils.ts +++ b/frontend/src/app/components/block-overview-graph/utils.ts @@ -1,4 +1,4 @@ -import { feeLevels, mempoolFeeColors } from '../../app.constants'; +import { feeLevels, defaultMempoolFeeColors, contrastMempoolFeeColors } from '../../app.constants'; import { Color } from './sprite-types'; import TxView from './tx-view'; @@ -47,7 +47,7 @@ interface ColorPalette { // precomputed colors const defaultColors: { [key: string]: ColorPalette } = { fee: { - base: mempoolFeeColors.map(hexToColor), + base: defaultMempoolFeeColors.map(hexToColor), audit: [], marginal: [], baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1 @@ -72,7 +72,37 @@ export const defaultAuditColors = { missing: darken(desaturate(hexToColor('f344df'), 0.3), 0.7), added: hexToColor('0099ff'), prioritized: darken(desaturate(hexToColor('0099ff'), 0.3), 0.7), - accelerated: hexToColor('8F5FF6'), + accelerated: hexToColor('8f5ff6'), +}; + +const contrastColors: { [key: string]: ColorPalette } = { + fee: { + base: contrastMempoolFeeColors.map(hexToColor), + audit: [], + marginal: [], + baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1 + }, +} +for (const key in contrastColors) { + const base = contrastColors[key].base; + contrastColors[key].audit = base.map((color) => darken(desaturate(color, 0.3), 0.9)); + contrastColors[key].marginal = base.map((color) => darken(desaturate(color, 0.8), 1.1)); + contrastColors['unmatched' + key] = { + base: contrastColors[key].base.map(c => setOpacity(c, 0.2)), + audit: contrastColors[key].audit.map(c => setOpacity(c, 0.2)), + marginal: contrastColors[key].marginal.map(c => setOpacity(c, 0.2)), + baseLevel: contrastColors[key].baseLevel, + }; +} + +export { contrastColors as contrastColors }; + +export const contrastAuditColors = { + censored: hexToColor('ffa8ff'), + missing: darken(desaturate(hexToColor('ffa8ff'), 0.3), 0.7), + added: hexToColor('00bb98'), + prioritized: darken(desaturate(hexToColor('00bb98'), 0.3), 0.7), + accelerated: hexToColor('8f5ff6'), }; export function defaultColorFunction( @@ -83,7 +113,7 @@ export function defaultColorFunction( ): Color { const rate = tx.fee / tx.vsize; // color by simple single-tx fee rate const levelIndex = colors.baseLevel(tx, rate, relativeTime || (Date.now() / 1000)); - const levelColor = colors.base[levelIndex] || colors.base[mempoolFeeColors.length - 1]; + const levelColor = colors.base[levelIndex] || colors.base[defaultMempoolFeeColors.length - 1]; // Normal mode if (!tx.scene?.highlightingEnabled) { if (tx.acc) { @@ -100,7 +130,7 @@ export function defaultColorFunction( case 'missing': case 'sigop': case 'rbf': - return colors.marginal[levelIndex] || colors.marginal[mempoolFeeColors.length - 1]; + return colors.marginal[levelIndex] || colors.marginal[defaultMempoolFeeColors.length - 1]; case 'fresh': case 'freshcpfp': return auditColors.missing; @@ -109,12 +139,12 @@ export function defaultColorFunction( case 'prioritized': return auditColors.prioritized; case 'selected': - return colors.marginal[levelIndex] || colors.marginal[mempoolFeeColors.length - 1]; + return colors.marginal[levelIndex] || colors.marginal[defaultMempoolFeeColors.length - 1]; case 'accelerated': return auditColors.accelerated; case 'found': if (tx.context === 'projected') { - return colors.audit[levelIndex] || colors.audit[mempoolFeeColors.length - 1]; + return colors.audit[levelIndex] || colors.audit[defaultMempoolFeeColors.length - 1]; } else { return levelColor; } @@ -127,17 +157,27 @@ export function defaultColorFunction( } } +export function contrastColorFunction( + tx: TxView, + colors: { base: Color[], audit: Color[], marginal: Color[], baseLevel: (tx: TxView, rate: number, time: number) => number } = contrastColors.fee, + auditColors: { [status: string]: Color } = contrastAuditColors, + relativeTime?: number, +): Color { + return defaultColorFunction(tx, colors, auditColors, relativeTime); +} + export function ageColorFunction( tx: TxView, colors: { base: Color[], audit: Color[], marginal: Color[], baseLevel: (tx: TxView, rate: number, time: number) => number } = defaultColors.fee, auditColors: { [status: string]: Color } = defaultAuditColors, relativeTime?: number, + theme?: string, ): Color { if (tx.acc || tx.status === 'accelerated') { return auditColors.accelerated; } - const color = defaultColorFunction(tx, colors, auditColors, relativeTime); + const color = theme !== 'contrast' ? defaultColorFunction(tx, colors, auditColors, relativeTime) : contrastColorFunction(tx, colors, auditColors, relativeTime); const ageLevel = (!tx.time ? 0 : (0.8 * Math.tanh((1 / 15) * Math.log2((Math.max(1, 0.6 * ((relativeTime - tx.time) - 60))))))); return { @@ -146,4 +186,4 @@ export function ageColorFunction( b: color.b, a: color.a * (1 - ageLevel) }; -} \ No newline at end of file +} diff --git a/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.scss b/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.scss index 51edee1e8..df34ce346 100644 --- a/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.scss +++ b/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.scss @@ -3,7 +3,7 @@ background: rgba(#11131f, 0.95); border-radius: 4px; box-shadow: 1px 1px 10px rgba(0,0,0,0.5); - color: #b1b1b1; + color: var(--tooltip-grey); display: flex; flex-direction: column; justify-content: space-between; @@ -30,7 +30,7 @@ th, td { } .badge.badge-accelerated { - background-color: #653b9c; + background-color: var(--tertiary); box-shadow: #ad7de57f 0px 0px 12px -2px; color: white; animation: acceleratePulse 1s infinite; @@ -51,27 +51,27 @@ th, td { .filter-tag { background: #181b2daf; - border: solid 1px #105fb0; + border: solid 1px var(--primary); color: white; transition: background-color 300ms; &.matching { - background-color: #105fb0; + background-color: var(--primary); } } &.any-mode { .filter-tag { - border: solid 1px #1a9436; + border: solid 1px var(--success); &.matching { - background-color: #1a9436; + background-color: var(--success); } } } } @keyframes acceleratePulse { - 0% { background-color: #653b9c; box-shadow: #ad7de57f 0px 0px 12px -2px; } + 0% { background-color: var(--tertiary); box-shadow: #ad7de57f 0px 0px 12px -2px; } 50% { background-color: #8457bb; box-shadow: #ad7de5 0px 0px 18px -2px;} - 100% { background-color: #653b9c; box-shadow: #ad7de57f 0px 0px 12px -2px; } + 100% { background-color: var(--tertiary); box-shadow: #ad7de57f 0px 0px 12px -2px; } } \ No newline at end of file diff --git a/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.ts b/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.ts index fe8efa9c7..d0c154420 100644 --- a/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.ts +++ b/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.ts @@ -150,7 +150,7 @@ export class BlockRewardsGraphComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -219,7 +219,7 @@ export class BlockRewardsGraphComponent implements OnInit { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, @@ -315,7 +315,7 @@ export class BlockRewardsGraphComponent implements OnInit { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 40; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts b/frontend/src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts index 76d6e8216..bf591ad70 100644 --- a/frontend/src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts +++ b/frontend/src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts @@ -146,7 +146,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -230,7 +230,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, @@ -252,7 +252,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit { symbol: 'none', lineStyle: { type: 'solid', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 1, width: 1, }, @@ -342,7 +342,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 40; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/block/block-preview.component.ts b/frontend/src/app/components/block/block-preview.component.ts index 3e1d9b409..91dfef8c2 100644 --- a/frontend/src/app/components/block/block-preview.component.ts +++ b/frontend/src/app/components/block/block-preview.component.ts @@ -136,7 +136,7 @@ export class BlockPreviewComponent implements OnInit, OnDestroy { return of(transactions); }) ), - this.stateService.env.ACCELERATOR === true && block.height > 819500 ? this.servicesApiService.getAccelerationHistory$({ blockHash: block.id }) : of([]) + this.stateService.env.ACCELERATOR === true && block.height > 819500 ? this.servicesApiService.getAccelerationHistory$({ blockHeight: block.height }) : of([]) ]); } ), diff --git a/frontend/src/app/components/block/block.component.scss b/frontend/src/app/components/block/block.component.scss index bad8fa52e..70f388e73 100644 --- a/frontend/src/app/components/block/block.component.scss +++ b/frontend/src/app/components/block/block.component.scss @@ -22,7 +22,7 @@ } .qr-wrapper { - background-color: #FFF; + background-color: var(--fg); padding: 10px; padding-bottom: 5px; display: inline-block; @@ -175,9 +175,7 @@ h1 { } a { - color: #1ad8f4; &:hover, &:focus { - color: #09a3ba; display: inline-block; } } @@ -254,7 +252,7 @@ h1 { cursor: pointer; &.active { - background: #24273e; + background: var(--box-bg); } &.active, &:hover { diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts index 13b0ecd76..50acb0632 100644 --- a/frontend/src/app/components/block/block.component.ts +++ b/frontend/src/app/components/block/block.component.ts @@ -345,7 +345,7 @@ export class BlockComponent implements OnInit, OnDestroy { return of(null); }) ), - this.stateService.env.ACCELERATOR === true && block.height > 819500 ? this.servicesApiService.getAccelerationHistory$({ blockHash: block.id }) : of([]) + this.stateService.env.ACCELERATOR === true && block.height > 819500 ? this.servicesApiService.getAccelerationHistory$({ blockHeight: block.height }) : of([]) ]); }) ) @@ -358,11 +358,15 @@ export class BlockComponent implements OnInit, OnDestroy { const acceleratedInBlock = {}; for (const acc of accelerations) { - acceleratedInBlock[acc.txid] = acc; + if (acc.pools?.some(pool => pool === this.block?.extras?.pool.id || pool?.['pool_unique_id'] === this.block?.extras?.pool.id)) { + acceleratedInBlock[acc.txid] = acc; + } } for (const tx of transactions) { if (acceleratedInBlock[tx.txid]) { tx.acc = true; + } else { + tx.acc = false; } } diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss index c1cc6809d..59082d5c5 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss @@ -117,7 +117,7 @@ } .black-background { - background-color: #11131f; + background-color: var(--active-bg); z-index: 100; position: relative; } @@ -144,7 +144,7 @@ } .loading .bitcoin-block.mined-block { - background: #2d3348; + background: var(--secondary); } @keyframes opacityPulse { diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts index 5141f4de9..ca79b68a6 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts @@ -63,11 +63,11 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { blockPadding: number = 30; gradientColors = { - '': ['#9339f4', '#105fb0'], - liquid: ['#116761', '#183550'], - 'liquidtestnet': ['#494a4a', '#272e46'], - testnet: ['#1d486f', '#183550'], - signet: ['#6f1d5d', '#471850'], + '': ['var(--mainnet-alt)', 'var(--primary)'], + liquid: ['var(--liquid)', 'var(--testnet-alt)'], + 'liquidtestnet': ['var(--liquidtestnet)', 'var(--liquidtestnet-alt)'], + testnet: ['var(--testnet)', 'var(--testnet-alt)'], + signet: ['var(--signet)', 'var(--signet-alt)'], }; constructor( @@ -330,7 +330,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { left: addLeft + this.blockOffset * index + 'px', background: `repeating-linear-gradient( #2d3348, - #2d3348 ${greenBackgroundHeight}%, + var(--secondary) ${greenBackgroundHeight}%, ${this.gradientColors[this.network][0]} ${Math.max(greenBackgroundHeight, 0)}%, ${this.gradientColors[this.network][1]} 100% )`, @@ -366,7 +366,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { return { left: addLeft + this.blockOffset * this.emptyBlocks.indexOf(block) + 'px', - background: "#2d3348", + background: "var(--secondary)", }; } diff --git a/frontend/src/app/components/blockchain/blockchain.component.scss b/frontend/src/app/components/blockchain/blockchain.component.scss index eacd16118..a8ecc6aba 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.scss +++ b/frontend/src/app/components/blockchain/blockchain.component.scss @@ -30,7 +30,7 @@ } .black-background { - background-color: #11131f; + background-color: var(--active-bg); z-index: 100; position: relative; } diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.scss b/frontend/src/app/components/blocks-list/blocks-list.component.scss index 3d3169a69..2315844ae 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.scss +++ b/frontend/src/app/components/blocks-list/blocks-list.component.scss @@ -46,7 +46,7 @@ tr, td, th { } .progress { - background-color: #2d3348; + background-color: var(--secondary); } .pool { @@ -266,7 +266,7 @@ tr, td, th { .tooltip-custom .tooltiptext { visibility: hidden; - color: #fff; + color: var(--fg); text-align: center; padding: 5px 0; border-radius: 6px; diff --git a/frontend/src/app/components/clock-face/clock-face.component.scss b/frontend/src/app/components/clock-face/clock-face.component.scss index 1ca2ce914..e2bb215d4 100644 --- a/frontend/src/app/components/clock-face/clock-face.component.scss +++ b/frontend/src/app/components/clock-face/clock-face.component.scss @@ -14,7 +14,7 @@ height: 100%; .face { - fill: #11131f; + fill: var(--active-bg); } } @@ -29,8 +29,8 @@ } &.hour { - fill: #105fb0; - stroke: #105fb0; + fill: var(--primary); + stroke: var(--primary); stroke-width: 6px; } } diff --git a/frontend/src/app/components/clock/clock.component.scss b/frontend/src/app/components/clock/clock.component.scss index 34aadcd74..7423c1d8f 100644 --- a/frontend/src/app/components/clock/clock.component.scss +++ b/frontend/src/app/components/clock/clock.component.scss @@ -161,7 +161,7 @@ } .side.bottom { - background: #105fb0; + background: var(--primary); transform: rotateX(-90deg); margin-top: var(--half-side); } diff --git a/frontend/src/app/components/difficulty-mining/difficulty-mining.component.html b/frontend/src/app/components/difficulty-mining/difficulty-mining.component.html index 0865708af..4d135dfbe 100644 --- a/frontend/src/app/components/difficulty-mining/difficulty-mining.component.html +++ b/frontend/src/app/components/difficulty-mining/difficulty-mining.component.html @@ -40,7 +40,7 @@
Current Period
{{ epochData.progress | number: '1.2-2' }} %
-
 
+
 
diff --git a/frontend/src/app/components/difficulty-mining/difficulty-mining.component.scss b/frontend/src/app/components/difficulty-mining/difficulty-mining.component.scss index 69e2892ee..7965ff5d6 100644 --- a/frontend/src/app/components/difficulty-mining/difficulty-mining.component.scss +++ b/frontend/src/app/components/difficulty-mining/difficulty-mining.component.scss @@ -79,12 +79,12 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); height: 100%; } .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 1rem; overflow: hidden; text-overflow: ellipsis; @@ -94,7 +94,7 @@ .progress { display: inline-flex; width: 100%; - background-color: #2d3348; + background-color: var(--secondary); height: 1.1rem; max-width: 180px; } diff --git a/frontend/src/app/components/difficulty/difficulty.component.scss b/frontend/src/app/components/difficulty/difficulty.component.scss index 3b591dc2d..697a6f534 100644 --- a/frontend/src/app/components/difficulty/difficulty.component.scss +++ b/frontend/src/app/components/difficulty/difficulty.component.scss @@ -10,7 +10,7 @@ justify-content: space-around; height: 50.5px; .shared-block { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } .item { @@ -91,19 +91,19 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); height: 100%; } .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 1rem; } .progress { display: inline-flex; width: 100%; - background-color: #2d3348; + background-color: var(--secondary); height: 1.1rem; max-width: 180px; } @@ -177,10 +177,10 @@ .epoch-blocks { display: block; width: 100%; - background: #2d3348; + background: var(--secondary); .rect { - fill: #2d3348; + fill: var(--secondary); &.behind { fill: #D81B60; @@ -189,7 +189,7 @@ fill: url(#diff-gradient); } &.ahead { - fill: #1a9436; + fill: var(--success); } &.hover { @@ -223,12 +223,12 @@ height: 100%; } .background { - background: linear-gradient(to right, #105fb0, #9339f4); + background: linear-gradient(to right, var(--primary), #9339f4); left: 0; right: 0; } .remaining { - background: #2d3348; + background: var(--secondary); right: 0; } .label { diff --git a/frontend/src/app/components/difficulty/difficulty.component.ts b/frontend/src/app/components/difficulty/difficulty.component.ts index a58250653..579b49fc3 100644 --- a/frontend/src/app/components/difficulty/difficulty.component.ts +++ b/frontend/src/app/components/difficulty/difficulty.component.ts @@ -82,24 +82,24 @@ export class DifficultyComponent implements OnInit { .pipe( map(([blocks, da]) => { const maxHeight = blocks.reduce((max, block) => Math.max(max, block.height), 0); - let colorAdjustments = '#ffffff66'; + let colorAdjustments = 'var(--transparent-fg)'; if (da.difficultyChange > 0) { - colorAdjustments = '#3bcc49'; + colorAdjustments = 'var(--green)'; } if (da.difficultyChange < 0) { - colorAdjustments = '#dc3545'; + colorAdjustments = 'var(--red)'; } - let colorPreviousAdjustments = '#dc3545'; + let colorPreviousAdjustments = 'var(--red)'; if (da.previousRetarget) { if (da.previousRetarget >= 0) { - colorPreviousAdjustments = '#3bcc49'; + colorPreviousAdjustments = 'var(--green)'; } if (da.previousRetarget === 0) { - colorPreviousAdjustments = '#ffffff66'; + colorPreviousAdjustments = 'var(--transparent-fg)'; } } else { - colorPreviousAdjustments = '#ffffff66'; + colorPreviousAdjustments = 'var(--transparent-fg)'; } const blocksUntilHalving = 210000 - (maxHeight % 210000); diff --git a/frontend/src/app/components/fee-distribution-graph/fee-distribution-graph.component.ts b/frontend/src/app/components/fee-distribution-graph/fee-distribution-graph.component.ts index ca5b3f452..c26aae31a 100644 --- a/frontend/src/app/components/fee-distribution-graph/fee-distribution-graph.component.ts +++ b/frontend/src/app/components/fee-distribution-graph/fee-distribution-graph.component.ts @@ -128,7 +128,7 @@ export class FeeDistributionGraphComponent implements OnInit, OnChanges, OnDestr splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, diff --git a/frontend/src/app/components/fees-box/fees-box.component.scss b/frontend/src/app/components/fees-box/fees-box.component.scss index ba68e2086..0272936ee 100644 --- a/frontend/src/app/components/fees-box/fees-box.component.scss +++ b/frontend/src/app/components/fees-box/fees-box.component.scss @@ -1,5 +1,5 @@ .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; @@ -36,7 +36,7 @@ margin-bottom: 0; } .card-text span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; top: 0px; } @@ -79,6 +79,7 @@ display: flex; flex-direction: row; transition: background-color 1s; + color: var(--color-fg); &.priority { @media (767px < width < 992px), (width < 576px) { width: 100%; diff --git a/frontend/src/app/components/fees-box/fees-box.component.ts b/frontend/src/app/components/fees-box/fees-box.component.ts index 4f9772b22..e923b26e9 100644 --- a/frontend/src/app/components/fees-box/fees-box.component.ts +++ b/frontend/src/app/components/fees-box/fees-box.component.ts @@ -1,9 +1,10 @@ -import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy, OnDestroy, ChangeDetectorRef } from '@angular/core'; import { StateService } from '../../services/state.service'; -import { Observable, combineLatest } from 'rxjs'; +import { Observable, combineLatest, Subscription } from 'rxjs'; import { Recommendedfees } from '../../interfaces/websocket.interface'; -import { feeLevels, mempoolFeeColors } from '../../app.constants'; +import { feeLevels } from '../../app.constants'; import { map, startWith, tap } from 'rxjs/operators'; +import { ThemeService } from '../../services/theme.service'; @Component({ selector: 'app-fees-box', @@ -11,14 +12,18 @@ import { map, startWith, tap } from 'rxjs/operators'; styleUrls: ['./fees-box.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class FeesBoxComponent implements OnInit { +export class FeesBoxComponent implements OnInit, OnDestroy { isLoading$: Observable; recommendedFees$: Observable; + themeSubscription: Subscription; gradient = 'linear-gradient(to right, #2e324e, #2e324e)'; noPriority = '#2e324e'; + fees: Recommendedfees; constructor( - private stateService: StateService + private stateService: StateService, + private themeService: ThemeService, + private cd: ChangeDetectorRef, ) { } ngOnInit(): void { @@ -31,18 +36,32 @@ export class FeesBoxComponent implements OnInit { this.recommendedFees$ = this.stateService.recommendedFees$ .pipe( tap((fees) => { - let feeLevelIndex = feeLevels.slice().reverse().findIndex((feeLvl) => fees.minimumFee >= feeLvl); - feeLevelIndex = feeLevelIndex >= 0 ? feeLevels.length - feeLevelIndex : feeLevelIndex; - const startColor = '#' + (mempoolFeeColors[feeLevelIndex - 1] || mempoolFeeColors[mempoolFeeColors.length - 1]); - - feeLevelIndex = feeLevels.slice().reverse().findIndex((feeLvl) => fees.fastestFee >= feeLvl); - feeLevelIndex = feeLevelIndex >= 0 ? feeLevels.length - feeLevelIndex : feeLevelIndex; - const endColor = '#' + (mempoolFeeColors[feeLevelIndex - 1] || mempoolFeeColors[mempoolFeeColors.length - 1]); - - this.gradient = `linear-gradient(to right, ${startColor}, ${endColor})`; - this.noPriority = startColor; + this.fees = fees; + this.setFeeGradient(); } ) ); + this.themeSubscription = this.themeService.themeChanged$.subscribe(() => { + this.setFeeGradient(); + }) + } + + setFeeGradient() { + let feeLevelIndex = feeLevels.slice().reverse().findIndex((feeLvl) => this.fees.minimumFee >= feeLvl); + feeLevelIndex = feeLevelIndex >= 0 ? feeLevels.length - feeLevelIndex : feeLevelIndex; + const startColor = '#' + (this.themeService.mempoolFeeColors[feeLevelIndex - 1] || this.themeService.mempoolFeeColors[this.themeService.mempoolFeeColors.length - 1]); + + feeLevelIndex = feeLevels.slice().reverse().findIndex((feeLvl) => this.fees.fastestFee >= feeLvl); + feeLevelIndex = feeLevelIndex >= 0 ? feeLevels.length - feeLevelIndex : feeLevelIndex; + const endColor = '#' + (this.themeService.mempoolFeeColors[feeLevelIndex - 1] || this.themeService.mempoolFeeColors[this.themeService.mempoolFeeColors.length - 1]); + + this.gradient = `linear-gradient(to right, ${startColor}, ${endColor})`; + this.noPriority = startColor; + + this.cd.markForCheck(); + } + + ngOnDestroy(): void { + this.themeSubscription.unsubscribe(); } } diff --git a/frontend/src/app/components/footer/footer.component.scss b/frontend/src/app/components/footer/footer.component.scss index cc0146345..b21f39676 100644 --- a/frontend/src/app/components/footer/footer.component.scss +++ b/frontend/src/app/components/footer/footer.component.scss @@ -3,7 +3,7 @@ bottom: 0; width: 100%; height: 60px; - background-color: #1d1f31; + background-color: var(--bg); box-shadow: 15px 15px 15px 15px #000; z-index: 10; @@ -40,16 +40,8 @@ } } -.txPerSecond { - color: #4a9ff4; -} - .mempoolSize { - color: #4a68b9; -} - -.unconfirmedTx { - color: #f14d80; + color: var(--title-fg); } .info-block { @@ -61,7 +53,7 @@ .progress { display: inline-flex; width: 160px; - background-color: #2d3348; + background-color: var(--secondary); height: 1.1rem; } diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.scss b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.scss index 32885d5de..dc19dc9d1 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.scss +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.scss @@ -94,12 +94,12 @@ } .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .card-text { font-size: 18px; span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } } diff --git a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts index f4924f255..b61f88521 100644 --- a/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts +++ b/frontend/src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -242,7 +242,7 @@ export class HashrateChartComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -354,7 +354,7 @@ export class HashrateChartComponent implements OnInit { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, @@ -472,7 +472,7 @@ export class HashrateChartComponent implements OnInit { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 30; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts index d938baf15..5ac2cc10d 100644 --- a/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts +++ b/frontend/src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts @@ -225,7 +225,7 @@ export class HashrateChartPoolsComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -308,7 +308,7 @@ export class HashrateChartPoolsComponent implements OnInit { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 30; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts b/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts index 5c102eadf..c456053ea 100644 --- a/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts +++ b/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts @@ -272,7 +272,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } } @@ -332,7 +332,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On const now = new Date(); // @ts-ignore this.mempoolStatsChartOption.grid.height = prevHeight + 20; - this.mempoolStatsChartOption.backgroundColor = '#11131f'; + this.mempoolStatsChartOption.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.mempoolStatsChartOption); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/liquid-master-page/liquid-master-page.component.scss b/frontend/src/app/components/liquid-master-page/liquid-master-page.component.scss index d6aaccff1..12d0930d4 100644 --- a/frontend/src/app/components/liquid-master-page/liquid-master-page.component.scss +++ b/frontend/src/app/components/liquid-master-page/liquid-master-page.component.scss @@ -7,7 +7,7 @@ } li.nav-item.active { - background-color: #653b9c; + background-color: var(--tertiary); } fa-icon { @@ -47,7 +47,7 @@ li.nav-item { } .navbar-nav { - background: #212121; + background: var(--navbar-bg); bottom: 0; box-shadow: 0px 0px 15px 0px #000; flex-direction: row; @@ -91,6 +91,10 @@ li.nav-item { } } +.dropdown-container { + margin-top: 5px; +} + nav { box-shadow: 0px 0px 15px 0px #000; } @@ -108,23 +112,23 @@ nav { } .mainnet.active { - background-color: #653b9c; + background-color: var(--tertiary); } .liquid.active { - background-color: #116761; + background-color: var(--liquid); } .liquidtestnet.active { - background-color: #494a4a; + background-color: var(--liquidtestnet); } .testnet.active { - background-color: #1d486f; + background-color: var(--testnet); } .signet.active { - background-color: #6f1d5d; + background-color: var(--signet); } .dropdown-divider { diff --git a/frontend/src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.html b/frontend/src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.html index 44dfedd26..fb68a530d 100644 --- a/frontend/src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.html +++ b/frontend/src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.html @@ -9,7 +9,7 @@
-
Total Expired 
+
Total Expired 
{{ (+expiredStats.all.total) / 100000000 | number: '1.5-5' }} BTC
diff --git a/frontend/src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.scss b/frontend/src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.scss index d2044f6de..1a2fd6864 100644 --- a/frontend/src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.scss +++ b/frontend/src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.scss @@ -14,7 +14,7 @@ } .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; diff --git a/frontend/src/app/components/liquid-reserves-audit/federation-addresses-list/federation-addresses-list.component.scss b/frontend/src/app/components/liquid-reserves-audit/federation-addresses-list/federation-addresses-list.component.scss index b711f659b..5fbab9cc5 100644 --- a/frontend/src/app/components/liquid-reserves-audit/federation-addresses-list/federation-addresses-list.component.scss +++ b/frontend/src/app/components/liquid-reserves-audit/federation-addresses-list/federation-addresses-list.component.scss @@ -33,7 +33,7 @@ tr, td, th { } .progress { - background-color: #2d3348; + background-color: var(--secondary); } .address { diff --git a/frontend/src/app/components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component.html b/frontend/src/app/components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component.html index 9240cf228..5017ad4b2 100644 --- a/frontend/src/app/components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component.html +++ b/frontend/src/app/components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component.html @@ -2,7 +2,7 @@
-
Liquid Federation Wallet 
+
Liquid Federation Wallet 
{{ federationWalletStats.address_count }} addresses
@@ -16,7 +16,7 @@
-
Liquid Federation Wallet 
+
Liquid Federation Wallet 
diff --git a/frontend/src/app/components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component.scss b/frontend/src/app/components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component.scss index 4ddce6501..aa345fbfd 100644 --- a/frontend/src/app/components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component.scss +++ b/frontend/src/app/components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component.scss @@ -15,7 +15,7 @@ .card-title { margin: 0; - color: #4a68b9; + color: var(--title-fg); font-size: 10px; font-size: 1rem; white-space: nowrap; diff --git a/frontend/src/app/components/liquid-reserves-audit/federation-utxos-list/federation-utxos-list.component.scss b/frontend/src/app/components/liquid-reserves-audit/federation-utxos-list/federation-utxos-list.component.scss index 6a2353f0c..cdd5a5ed9 100644 --- a/frontend/src/app/components/liquid-reserves-audit/federation-utxos-list/federation-utxos-list.component.scss +++ b/frontend/src/app/components/liquid-reserves-audit/federation-utxos-list/federation-utxos-list.component.scss @@ -24,7 +24,7 @@ tr, td, th { } .progress { - background-color: #2d3348; + background-color: var(--secondary); } .txid { diff --git a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.scss b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.scss index 7a3d9e49f..3af119fad 100644 --- a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.scss +++ b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.scss @@ -27,7 +27,7 @@ tr, td, th { } .progress { - background-color: #2d3348; + background-color: var(--secondary); } .transaction { diff --git a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component.html b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component.html index 6f012e84e..44b801a30 100644 --- a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component.html +++ b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component.html @@ -2,7 +2,7 @@ @@ -26,7 +26,7 @@ diff --git a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component.scss b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component.scss index 4cfef8e7a..9a7e6f0ea 100644 --- a/frontend/src/app/components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component.scss +++ b/frontend/src/app/components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component.scss @@ -15,7 +15,7 @@ .card-title { margin: 0; - color: #4a68b9; + color: var(--title-fg); font-size: 10px; font-size: 1rem; white-space: nowrap; diff --git a/frontend/src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.html b/frontend/src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.html index dede76b3f..49ba80d0c 100644 --- a/frontend/src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.html +++ b/frontend/src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.html @@ -23,7 +23,7 @@
Emergency Keys
diff --git a/frontend/src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.scss b/frontend/src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.scss index 13123431e..fd7197a88 100644 --- a/frontend/src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.scss +++ b/frontend/src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.scss @@ -22,7 +22,7 @@ .card-title { margin-bottom: 4px; - color: #4a68b9; + color: var(--title-fg); font-size: 10px; font-size: 1rem; white-space: nowrap; diff --git a/frontend/src/app/components/liquid-reserves-audit/reserves-ratio/reserves-ratio.component.ts b/frontend/src/app/components/liquid-reserves-audit/reserves-ratio/reserves-ratio.component.ts index 13f948fcd..04429d2ac 100644 --- a/frontend/src/app/components/liquid-reserves-audit/reserves-ratio/reserves-ratio.component.ts +++ b/frontend/src/app/components/liquid-reserves-audit/reserves-ratio/reserves-ratio.component.ts @@ -141,7 +141,7 @@ export class ReservesRatioComponent implements OnInit, OnChanges { show: true, offsetCenter: [0, '-127%'], fontSize: 18, - color: '#4a68b9', + color: 'var(--title-fg)', fontFamily: 'inherit', fontWeight: 500, }, diff --git a/frontend/src/app/components/liquid-reserves-audit/reserves-supply-stats/reserves-supply-stats.component.scss b/frontend/src/app/components/liquid-reserves-audit/reserves-supply-stats/reserves-supply-stats.component.scss index 6ffb900ed..47d29eb45 100644 --- a/frontend/src/app/components/liquid-reserves-audit/reserves-supply-stats/reserves-supply-stats.component.scss +++ b/frontend/src/app/components/liquid-reserves-audit/reserves-supply-stats/reserves-supply-stats.component.scss @@ -13,7 +13,7 @@ } .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; diff --git a/frontend/src/app/components/master-page-preview/master-page-preview.component.scss b/frontend/src/app/components/master-page-preview/master-page-preview.component.scss index f901f31a3..486922dfa 100644 --- a/frontend/src/app/components/master-page-preview/master-page-preview.component.scss +++ b/frontend/src/app/components/master-page-preview/master-page-preview.component.scss @@ -18,7 +18,7 @@ flex-direction: row; justify-content: space-between; align-items: center; - background: #11131f; + background: var(--active-bg); text-align: start; font-size: 1.8em; } diff --git a/frontend/src/app/components/master-page/master-page.component.scss b/frontend/src/app/components/master-page/master-page.component.scss index 9320e2b38..2f5bc536e 100644 --- a/frontend/src/app/components/master-page/master-page.component.scss +++ b/frontend/src/app/components/master-page/master-page.component.scss @@ -7,7 +7,7 @@ } li.nav-item.active { - background-color: #653b9c; + background-color: var(--tertiary); } fa-icon { @@ -58,7 +58,7 @@ li.nav-item { } .navbar-nav { - background: #212121; + background: var(--navbar-bg); bottom: 0; box-shadow: 0px 0px 15px 0px #000; flex-direction: row; @@ -139,23 +139,23 @@ nav { } .mainnet.active { - background-color: #653b9c; + background-color: var(--tertiary); } .liquid.active { - background-color: #116761; + background-color: var(--liquid); } .liquidtestnet.active { - background-color: #494a4a; + background-color: var(--liquidtestnet); } .testnet.active { - background-color: #1d486f; + background-color: var(--testnet); } .signet.active { - background-color: #6f1d5d; + background-color: var(--signet); } .dropdown-divider { diff --git a/frontend/src/app/components/mempool-block/mempool-block.component.scss b/frontend/src/app/components/mempool-block/mempool-block.component.scss index e74689a9a..b2f9419b8 100644 --- a/frontend/src/app/components/mempool-block/mempool-block.component.scss +++ b/frontend/src/app/components/mempool-block/mempool-block.component.scss @@ -1,5 +1,5 @@ .progress { - background-color: #2d3348; + background-color: var(--secondary); position: relative; top: 5px; } diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss index 606699d93..dada75603 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.scss @@ -106,7 +106,7 @@ } .black-background { - background-color: #11131f; + background-color: var(--active-bg); z-index: 100; position: relative; } diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts index ed5b61f2b..80d77427b 100644 --- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts +++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts @@ -4,12 +4,13 @@ import { MempoolBlock } from '../../interfaces/websocket.interface'; import { StateService } from '../../services/state.service'; import { Router } from '@angular/router'; import { map, switchMap, tap } from 'rxjs/operators'; -import { feeLevels, mempoolFeeColors } from '../../app.constants'; +import { feeLevels } from '../../app.constants'; import { specialBlocks } from '../../app.constants'; import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; import { Location } from '@angular/common'; import { DifficultyAdjustment, MempoolPosition } from '../../interfaces/node-api.interface'; import { animate, style, transition, trigger } from '@angular/animations'; +import { ThemeService } from '../../services/theme.service'; @Component({ selector: 'app-mempool-blocks', @@ -84,6 +85,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy { constructor( private router: Router, public stateService: StateService, + private themeService: ThemeService, private cd: ChangeDetectorRef, private relativeUrlPipe: RelativeUrlPipe, private location: Location, @@ -354,7 +356,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy { trimmedFeeRange.forEach((fee: number) => { let feeLevelIndex = feeLevels.slice().reverse().findIndex((feeLvl) => fee >= feeLvl); feeLevelIndex = feeLevelIndex >= 0 ? feeLevels.length - feeLevelIndex : feeLevelIndex; - gradientColors.push(mempoolFeeColors[feeLevelIndex - 1] || mempoolFeeColors[mempoolFeeColors.length - 1]); + gradientColors.push(this.themeService.mempoolFeeColors[feeLevelIndex - 1] || this.themeService.mempoolFeeColors[this.themeService.mempoolFeeColors.length - 1]); }); gradientColors.forEach((color, i, gc) => { diff --git a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts index 58d1764ab..4700332a3 100644 --- a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts +++ b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts @@ -432,7 +432,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } } @@ -500,7 +500,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges { const now = new Date(); // @ts-ignore this.mempoolVsizeFeesOptions.grid.height = prevHeight + 20; - this.mempoolVsizeFeesOptions.backgroundColor = '#11131f'; + this.mempoolVsizeFeesOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.mempoolVsizeFeesOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/menu/menu.component.scss b/frontend/src/app/components/menu/menu.component.scss index fe5e74ff9..3bec556fd 100644 --- a/frontend/src/app/components/menu/menu.component.scss +++ b/frontend/src/app/components/menu/menu.component.scss @@ -34,7 +34,7 @@ .sidenav.open { display: block; - background-color: #1d1f31; + background-color: var(--bg); } :host-context(.ltr-layout) .sidenav.open { @@ -56,7 +56,7 @@ .sidenav nav { width: 100%; height: calc(100vh - 65px); - background-color: #1d1f31; + background-color: var(--bg); padding-left: 20px; padding-right: 20px; padding-top: 20px; @@ -75,7 +75,7 @@ } .badge-og { - background-color: #4a68b9; + background-color: var(--title-fg); } .badge-pleb { @@ -87,7 +87,7 @@ } .badge-whale { - background-color: #653b9c; + background-color: var(--tertiary); } .badge-silver { @@ -99,5 +99,5 @@ } .badge-platinum { - background-color: #653b9c; + background-color: var(--tertiary); } \ No newline at end of file diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html index c4fca72eb..6b37d7dd9 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.html @@ -55,7 +55,7 @@
Recent Blocks
  - +
@@ -69,7 +69,7 @@
Adjustments
  - +
diff --git a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss index ce68c97ae..a7948b40e 100644 --- a/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss +++ b/frontend/src/app/components/mining-dashboard/mining-dashboard.component.scss @@ -7,7 +7,7 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); } .graph-card { @@ -32,10 +32,10 @@ .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .card-title > a { - color: #4a68b9; + color: var(--title-fg); } .card-body.pool-ranking { diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.scss b/frontend/src/app/components/pool-ranking/pool-ranking.component.scss index f5a49678b..65f4f1f5c 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.scss +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.scss @@ -99,7 +99,7 @@ } .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -107,7 +107,7 @@ .card-text { font-size: 18px; span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } } diff --git a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts index 299a95582..f7862d120 100644 --- a/frontend/src/app/components/pool-ranking/pool-ranking.component.ts +++ b/frontend/src/app/components/pool-ranking/pool-ranking.component.ts @@ -146,7 +146,7 @@ export class PoolRankingComponent implements OnInit { name: pool.name + ((isMobile() || this.widget) ? `` : ` (${pool.share}%)`), label: { overflow: 'none', - color: '#b1b1b1', + color: 'var(--tooltip-grey)', alignTo: 'edge', edgeDistance: edgeDistance, }, @@ -156,7 +156,7 @@ export class PoolRankingComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', }, borderColor: '#000', formatter: () => { @@ -186,7 +186,7 @@ export class PoolRankingComponent implements OnInit { name: $localize`Other (${percentage})`, label: { overflow: 'none', - color: '#b1b1b1', + color: 'var(--tooltip-grey)', alignTo: 'edge', edgeDistance: edgeDistance }, @@ -195,7 +195,7 @@ export class PoolRankingComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', }, borderColor: '#000', formatter: () => { @@ -306,7 +306,7 @@ export class PoolRankingComponent implements OnInit { onSaveChart() { const now = new Date(); - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/components/pool/pool-preview.component.scss b/frontend/src/app/components/pool/pool-preview.component.scss index bd0c19859..24a38c9c5 100644 --- a/frontend/src/app/components/pool/pool-preview.component.scss +++ b/frontend/src/app/components/pool/pool-preview.component.scss @@ -17,7 +17,7 @@ justify-content: space-between; width: 100%; margin-left: 15px; - background: #181b2d; + background: var(--stat-box-bg); padding: 0.75rem; width: 0; flex-grow: 1; @@ -43,7 +43,7 @@ .chart { width: 100%; height: 315px; - background: #181b2d; + background: var(--stat-box-bg); } .row { @@ -65,7 +65,7 @@ position: absolute; right: 0; top: 0; - background: #24273e; + background: var(--box-bg); &.noimg { opacity: 0; diff --git a/frontend/src/app/components/pool/pool.component.scss b/frontend/src/app/components/pool/pool.component.scss index 8bd6763e5..36bdc93e9 100644 --- a/frontend/src/app/components/pool/pool.component.scss +++ b/frontend/src/app/components/pool/pool.component.scss @@ -88,7 +88,7 @@ div.scrollable { } .progress { - background-color: #2d3348; + background-color: var(--secondary); } .coinbase { @@ -190,7 +190,7 @@ div.scrollable { } .data-title { - color: #4a68b9; + color: var(--title-fg); font-size: 14px; } diff --git a/frontend/src/app/components/pool/pool.component.ts b/frontend/src/app/components/pool/pool.component.ts index 7c6b5de38..3d2d0ac81 100644 --- a/frontend/src/app/components/pool/pool.component.ts +++ b/frontend/src/app/components/pool/pool.component.ts @@ -175,7 +175,7 @@ export class PoolComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', diff --git a/frontend/src/app/components/rbf-list/rbf-list.component.scss b/frontend/src/app/components/rbf-list/rbf-list.component.scss index 792bb8836..ff4dcf9b7 100644 --- a/frontend/src/app/components/rbf-list/rbf-list.component.scss +++ b/frontend/src/app/components/rbf-list/rbf-list.component.scss @@ -25,7 +25,7 @@ } .timeline-wrapper.mined { - border: solid 4px #1a9436; + border: solid 4px var(--success); } .no-replacements { diff --git a/frontend/src/app/components/rbf-timeline/rbf-timeline.component.scss b/frontend/src/app/components/rbf-timeline/rbf-timeline.component.scss index 8962be63c..6803e82ae 100644 --- a/frontend/src/app/components/rbf-timeline/rbf-timeline.component.scss +++ b/frontend/src/app/components/rbf-timeline/rbf-timeline.component.scss @@ -15,12 +15,12 @@ &::before { left: 0; - background: linear-gradient(to right, #24273e, #24273e, transparent); + background: linear-gradient(to right, var(--box-bg), var(--box-bg), transparent); } &::after { right: 0; - background: linear-gradient(to left, #24273e, #24273e, transparent); + background: linear-gradient(to left, var(--box-bg), var(--box-bg), transparent); } .timeline-wrapper { @@ -45,7 +45,7 @@ width: 100%; height: 70px; top: -70px; - background: linear-gradient(to bottom, rgba(36, 39, 62, 0) 0%, rgba(36, 39, 62, 1) 100%); + background: linear-gradient(to bottom, var(--fade-out-box-bg-start), var(--fade-out-box-bg-end)); z-index: 1; } } @@ -101,7 +101,7 @@ right: -5px; top: 0; transform: translateY(-50%); - background: #105fb0; + background: var(--primary); border-radius: 5px; &.left { @@ -112,7 +112,7 @@ } &.fullrbf { - background: #1bd8f4; + background: var(--info); } } &.first-node { @@ -165,20 +165,20 @@ &.mined { .shape-border { - background: #1a9436; + background: var(--success); } } .shape-border:hover { padding: 0px; .shape { - background: #1bd8f4; + background: var(--info); } } &.selected.mined { .shape-border { - background: #1a9436; + background: var(--success); height: calc(1em + 16px); width: calc(1em + 16px); @@ -190,7 +190,7 @@ padding: 4px; .shape { border-width: 1px; - border-color: #1bd8f4 + border-color: var(--info) } } } @@ -207,9 +207,9 @@ width: 20px; height: 108px; bottom: 50%; - border-right: solid 10px #105fb0; + border-right: solid 10px var(--primary); &.fullrbf { - border-right: solid 10px #1bd8f4; + border-right: solid 10px var(--info); } &.last-pipe { height: 150px; @@ -218,10 +218,10 @@ } .corner { - border-bottom: solid 10px #105fb0; + border-bottom: solid 10px var(--primary); border-bottom-right-radius: 10px; &.fullrbf { - border-bottom: solid 10px #1bd8f4; + border-bottom: solid 10px var(--info); } } } diff --git a/frontend/src/app/components/reward-stats/reward-stats.component.scss b/frontend/src/app/components/reward-stats/reward-stats.component.scss index e02b3a311..2237d8716 100644 --- a/frontend/src/app/components/reward-stats/reward-stats.component.scss +++ b/frontend/src/app/components/reward-stats/reward-stats.component.scss @@ -1,5 +1,5 @@ .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; @@ -50,7 +50,7 @@ margin-bottom: 0; } .card-text span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; top: 0px; } diff --git a/frontend/src/app/components/search-form/search-results/search-results.component.scss b/frontend/src/app/components/search-form/search-results/search-results.component.scss index 496e718d8..5540d7e7a 100644 --- a/frontend/src/app/components/search-form/search-results/search-results.component.scss +++ b/frontend/src/app/components/search-form/search-results/search-results.component.scss @@ -1,5 +1,5 @@ .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; diff --git a/frontend/src/app/components/start/start.component.scss b/frontend/src/app/components/start/start.component.scss index e321b8d6f..50e520cc5 100644 --- a/frontend/src/app/components/start/start.component.scss +++ b/frontend/src/app/components/start/start.component.scss @@ -32,7 +32,7 @@ cursor: pointer; opacity: 0.8; transition: opacity 500ms; - background: radial-gradient(#1d1f31 0%, transparent 50%); + background: radial-gradient(var(--bg) 0%, transparent 50%); &:hover { opacity: 1; diff --git a/frontend/src/app/components/statistics/statistics.component.scss b/frontend/src/app/components/statistics/statistics.component.scss index 3d4813fb5..835a170cc 100644 --- a/frontend/src/app/components/statistics/statistics.component.scss +++ b/frontend/src/app/components/statistics/statistics.component.scss @@ -117,7 +117,7 @@ } .inactive { .square { - background-color: #ffffff66 !important; + background-color: var(--transparent-fg) !important; } .fee-text { text-decoration: line-through; diff --git a/frontend/src/app/components/theme-selector/theme-selector.component.html b/frontend/src/app/components/theme-selector/theme-selector.component.html new file mode 100644 index 000000000..e32e3f61c --- /dev/null +++ b/frontend/src/app/components/theme-selector/theme-selector.component.html @@ -0,0 +1,6 @@ +
+ +
diff --git a/frontend/src/app/components/theme-selector/theme-selector.component.scss b/frontend/src/app/components/theme-selector/theme-selector.component.scss new file mode 100644 index 000000000..afdcf2980 --- /dev/null +++ b/frontend/src/app/components/theme-selector/theme-selector.component.scss @@ -0,0 +1,3 @@ +.custom-select { + width: 100px; +} diff --git a/frontend/src/app/components/theme-selector/theme-selector.component.ts b/frontend/src/app/components/theme-selector/theme-selector.component.ts new file mode 100644 index 000000000..7f38844bb --- /dev/null +++ b/frontend/src/app/components/theme-selector/theme-selector.component.ts @@ -0,0 +1,31 @@ +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { ThemeService } from '../../services/theme.service'; + +@Component({ + selector: 'app-theme-selector', + templateUrl: './theme-selector.component.html', + styleUrls: ['./theme-selector.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ThemeSelectorComponent implements OnInit { + themeForm: UntypedFormGroup; + themes = ['default', 'contrast']; + + constructor( + private formBuilder: UntypedFormBuilder, + private themeService: ThemeService, + ) { } + + ngOnInit() { + this.themeForm = this.formBuilder.group({ + theme: ['default'] + }); + this.themeForm.get('theme')?.setValue(this.themeService.theme); + } + + changeTheme() { + const newTheme = this.themeForm.get('theme')?.value; + this.themeService.apply(newTheme); + } +} diff --git a/frontend/src/app/components/transaction/transaction-preview.component.scss b/frontend/src/app/components/transaction/transaction-preview.component.scss index 4fa8b661a..986ee7d8e 100644 --- a/frontend/src/app/components/transaction/transaction-preview.component.scss +++ b/frontend/src/app/components/transaction/transaction-preview.component.scss @@ -54,7 +54,7 @@ } .label { - color: #ffffff66; + color: var(--transparent-fg); } &.pair > *:first-child { @@ -79,7 +79,7 @@ .graph-wrapper { position: relative; - background: #181b2d; + background: var(--stat-box-bg); padding: 10px 0; padding-bottom: 0; @@ -113,7 +113,7 @@ max-width: 100%; margin: auto; table-layout: auto; - background: #2d3348af; + background: var(--secondary)af; border-top-left-radius: 5px; border-top-right-radius: 5px; diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html index a42975016..55f7047e6 100644 --- a/frontend/src/app/components/transaction/transaction.component.html +++ b/frontend/src/app/components/transaction/transaction.component.html @@ -80,7 +80,9 @@

Accelerate

- + @if (!(isMobile && paymentType === 'cashapp')) { + + }
@@ -456,13 +458,18 @@ - @if (!isLoadingTx && transactionTime !== -1) { + @if (isLoadingTx) { + + } @else if (transactionTime === -1) { +
First seen
First seen
- @if ((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration)) { + @if (isAcceleration) { Accelerated } @@ -606,15 +613,15 @@ @if (!isLoadingTx) { @if ((cpfpInfo && hasEffectiveFeeRate) || accelerationInfo) {
Accelerated fee rateEffective fee rate
- @if (accelerationInfo) { - + @if (accelerationInfo?.acceleratedFeeRate && (!tx.effectiveFeePerVsize || accelerationInfo.acceleratedFeeRate >= tx.effectiveFeePerVsize)) { + } @else { } diff --git a/frontend/src/app/components/transaction/transaction.component.scss b/frontend/src/app/components/transaction/transaction.component.scss index bfdd4cc03..375b5c4e0 100644 --- a/frontend/src/app/components/transaction/transaction.component.scss +++ b/frontend/src/app/components/transaction/transaction.component.scss @@ -61,7 +61,7 @@ } .badge.badge-accelerated { - background-color: #653b9c; + background-color: var(--tertiary); color: white; } @@ -70,11 +70,11 @@ } .arrow-green { - color: #1a9436; + color: var(--success); } .arrow-red { - color: #dc3545; + color: var(--red); } .container-xl { @@ -100,7 +100,7 @@ .graph-container { position: relative; width: 100%; - background: #181b2d; + background: var(--stat-box-bg); padding: 10px 0; padding-bottom: 0; } @@ -256,7 +256,7 @@ } .blink-bg { - color: #fff; + color: var(--fg); background: repeating-linear-gradient(#daad0a 0%, #daad0a 5%, #987805 100%) !important; animation: shadowyBackground 1s infinite; box-shadow: 0px 0px 20px rgba(#eba814, 1); @@ -279,7 +279,7 @@ display: flex !important; align-self: auto; margin-left: auto; - background-color: #653b9c; + background-color: var(--tertiary); @media (max-width: 849px) { margin-left: 5px; } @@ -302,7 +302,7 @@ align-self: auto; margin-top: 3px; margin-left: auto; - background-color: #653b9c; + background-color: var(--tertiary); @media (max-width: 995px) { margin-left: 0px; } @@ -311,6 +311,13 @@ } } +.accelerateFullSize { + width: 100%; + height: 100%; + padding: 0.5rem 0.25rem; + background-color: #653b9c; +} + .goggles-icon { display: block; width: 2.2em; diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts index ab55d706a..029ee487b 100644 --- a/frontend/src/app/components/transaction/transaction.component.ts +++ b/frontend/src/app/components/transaction/transaction.component.ts @@ -9,7 +9,8 @@ import { delay, mergeMap, tap, - map + map, + retry } from 'rxjs/operators'; import { Transaction } from '../../interfaces/electrs.interface'; import { of, merge, Subscription, Observable, Subject, from, throwError, combineLatest } from 'rxjs'; @@ -93,12 +94,13 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { adjustedVsize: number | null; pool: Pool | null; auditStatus: AuditStatus | null; + isAcceleration: boolean = false; filters: Filter[] = []; showCpfpDetails = false; fetchCpfp$ = new Subject(); fetchRbfHistory$ = new Subject(); fetchCachedTx$ = new Subject(); - fetchAcceleration$ = new Subject(); + fetchAcceleration$ = new Subject(); fetchMiningInfo$ = new Subject<{ hash: string, height: number, txid: string }>(); isCached: boolean = false; now = Date.now(); @@ -117,6 +119,8 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { flowEnabled: boolean; tooltipPosition: { x: number, y: number }; isMobile: boolean; + paymentType: 'bitcoin' | 'cashapp' = 'bitcoin'; + firstLoad = true; featuresEnabled: boolean; segwitEnabled: boolean; @@ -154,6 +158,11 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { ngOnInit() { this.acceleratorAvailable = this.stateService.env.OFFICIAL_MEMPOOL_SPACE && this.stateService.env.ACCELERATOR && this.stateService.network === ''; + if (this.acceleratorAvailable && this.stateService.ref === 'https://cash.app/') { + this.showAccelerationSummary = true; + this.paymentType = 'cashapp'; + } + this.enterpriseService.page(); this.websocketService.want(['blocks', 'mempool-blocks']); @@ -280,9 +289,10 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { filter(() => this.stateService.env.ACCELERATOR === true), tap(() => { this.accelerationInfo = null; + this.setIsAccelerated(); }), - switchMap((blockHash: string) => { - return this.servicesApiService.getAccelerationHistory$({ blockHash }); + switchMap((blockHeight: number) => { + return this.servicesApiService.getAccelerationHistory$({ blockHeight }); }), catchError(() => { return of(null); @@ -290,8 +300,12 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { ).subscribe((accelerationHistory) => { for (const acceleration of accelerationHistory) { if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'completed_provisional')) { - acceleration.acceleratedFee = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + acceleration.feePaid - acceleration.baseFee - acceleration.vsizeFee); + const boostCost = acceleration.boostCost || (acceleration.feePaid - acceleration.baseFee - acceleration.vsizeFee); + acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize; + acceleration.boost = boostCost; + this.accelerationInfo = acceleration; + this.setIsAccelerated(); } } }); @@ -312,6 +326,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { map(block => { return block.extras.pool; }), + retry({ count: 3, delay: 2000 }), catchError(() => { return of(null); }) @@ -332,18 +347,21 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { accelerated: isAccelerated, }; }), + retry({ count: 3, delay: 2000 }), catchError(() => { return of(null); }) ) : of(isCoinbase ? { coinbase: true } : null) ]); }), - catchError(() => { + catchError((e) => { return of(null); }) ).subscribe(([pool, auditStatus]) => { this.pool = pool; this.auditStatus = auditStatus; + + this.setIsAccelerated(); }); this.mempoolPositionSubscription = this.stateService.mempoolTxPosition$.subscribe(txPosition => { @@ -475,7 +493,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { this.getTransactionTime(); } } else { - this.fetchAcceleration$.next(tx.status.block_hash); + this.fetchAcceleration$.next(tx.status.block_height); this.fetchMiningInfo$.next({ hash: tx.status.block_hash, height: tx.status.block_height, txid: tx.txid }); this.transactionTime = 0; } @@ -537,7 +555,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { } else { this.audioService.playSound('magic'); } - this.fetchAcceleration$.next(block.id); + this.fetchAcceleration$.next(block.height); this.fetchMiningInfo$.next({ hash: block.id, height: block.height, txid: this.tx.txid }); } }); @@ -666,10 +684,11 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { relatives.reduce((prev, val) => prev + val.fee, 0); this.tx.effectiveFeePerVsize = totalFees / (totalWeight / 4); } else { - this.tx.effectiveFeePerVsize = cpfpInfo.effectiveFeePerVsize; + this.tx.effectiveFeePerVsize = cpfpInfo.effectiveFeePerVsize || this.tx.effectiveFeePerVsize || this.tx.feePerVsize || (this.tx.fee / (this.tx.weight / 4)); } if (cpfpInfo.acceleration) { this.tx.acceleration = cpfpInfo.acceleration; + this.setIsAccelerated(); } this.cpfpInfo = cpfpInfo; @@ -681,6 +700,11 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01)); } + setIsAccelerated() { + console.log(this.tx.acceleration, this.accelerationInfo, this.pool, this.accelerationInfo?.pools); + this.isAcceleration = (this.tx.acceleration || (this.accelerationInfo && this.pool && this.accelerationInfo.pools.some(pool => (pool === this.pool.id || pool?.['pool_unique_id'] === this.pool.id)))); + } + setFeatures(): void { if (this.tx) { this.segwitEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'segwit'); @@ -720,6 +744,11 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { } resetTransaction() { + if (!this.firstLoad) { + this.stateService.ref = ''; + } else { + this.firstLoad = false; + } this.error = undefined; this.tx = null; this.setFeatures(); @@ -742,6 +771,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { this.pool = null; this.auditStatus = null; document.body.scrollTo(0, 0); + this.isAcceleration = false; this.leaveTransaction(); } @@ -814,6 +844,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { } ngOnDestroy() { + this.stateService.ref = ''; this.subscription.unsubscribe(); this.fetchCpfpSubscription.unsubscribe(); this.fetchRbfSubscription.unsubscribe(); diff --git a/frontend/src/app/components/transactions-list/transactions-list.component.scss b/frontend/src/app/components/transactions-list/transactions-list.component.scss index b80c4da4c..2bae3de2c 100644 --- a/frontend/src/app/components/transactions-list/transactions-list.component.scss +++ b/frontend/src/app/components/transactions-list/transactions-list.component.scss @@ -13,15 +13,15 @@ } } .green { - color:#28a745; + color: var(--green); } .red { - color:#dc3545; + color: var(--red); } .grey { - color:#6c757d; + color: var(--grey); } .mobile-bottomcol { @@ -69,7 +69,7 @@ td.amount.large { text-align: right; } .sats { - color: #ffffff66; + color: var(--transparent-fg); font-size: 11px; } } @@ -112,7 +112,7 @@ td.amount.large { padding: 0.75rem; font-size: 12px; &:first-child { - color: #ffffff66; + color: var(--transparent-fg); white-space: pre-wrap; width: 150px; } @@ -138,7 +138,7 @@ h2 { } .highlight { - background-color: #181b2d; + background-color: var(--stat-box-bg); } .summary { @@ -159,7 +159,7 @@ h2 { } .grey-info-text { - color:#6c757d; + color: var(--grey); font-style: italic; font-size: 12px; } diff --git a/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.scss b/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.scss index 97cfcddb7..0c973ad00 100644 --- a/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.scss +++ b/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.scss @@ -3,7 +3,7 @@ background: rgba(#11131f, 0.95); border-radius: 4px; box-shadow: 1px 1px 10px rgba(0,0,0,0.5); - color: #b1b1b1; + color: var(--tooltip-grey); padding: 10px 15px; text-align: left; pointer-events: none; diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html index 9f491affc..3b044f28d 100644 --- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html +++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html @@ -77,12 +77,12 @@ - + - + diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss index 454d92bbf..e39d54e59 100644 --- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss +++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss @@ -30,7 +30,7 @@ stroke: url(#output-highlight-gradient); } &.zerovalue { - stroke: #1bd8f4; + stroke: var(--info); } } } diff --git a/frontend/src/app/dashboard/dashboard.component.html b/frontend/src/app/dashboard/dashboard.component.html index 1e5efd217..1b3eef543 100644 --- a/frontend/src/app/dashboard/dashboard.component.html +++ b/frontend/src/app/dashboard/dashboard.component.html @@ -20,7 +20,7 @@
Mempool Goggles™ : {{ goggleCycle[goggleIndex].name }}
  - +
@@ -64,7 +64,7 @@
Recent Replacements
  - +
@@ -98,7 +98,7 @@
Recent Blocks
  - +
diff --git a/frontend/src/app/dashboard/dashboard.component.scss b/frontend/src/app/dashboard/dashboard.component.scss index 01eb7f73d..3acfbf9bb 100644 --- a/frontend/src/app/dashboard/dashboard.component.scss +++ b/frontend/src/app/dashboard/dashboard.component.scss @@ -7,12 +7,12 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); height: 100%; } .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 1rem; } @@ -25,7 +25,7 @@ .progress { display: inline-flex; width: 100%; - background-color: #2d3348; + background-color: var(--secondary); height: 1.1rem; max-width: 180px; } @@ -101,7 +101,7 @@ .card-text { font-size: 18px; span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } .bitcoin-color { @@ -399,11 +399,11 @@ .goggle-badge { margin: 6px 5px 8px; background: none; - border: solid 2px #105fb0; + border: solid 2px var(--primary); cursor: pointer; &.active { - background: #105fb0; + background: var(--primary); } } @@ -418,7 +418,7 @@ } .card-liquid { - background-color: #1d1f31; + background-color: var(--bg); height: 418px; @media (min-width: 992px) { height: 512px; diff --git a/frontend/src/app/docs/api-docs/api-docs-nav.component.scss b/frontend/src/app/docs/api-docs/api-docs-nav.component.scss index 9db2f56e9..4609ed2fd 100644 --- a/frontend/src/app/docs/api-docs/api-docs-nav.component.scss +++ b/frontend/src/app/docs/api-docs/api-docs-nav.component.scss @@ -1,12 +1,12 @@ p { - color: #4a68b9; + color: var(--title-fg); font-weight: 700; margin: 10px 0; margin: 15px 0 10px 0; } a { - color: #fff; + color: var(--fg); text-decoration: none; display: block; margin: 5px 0; @@ -17,13 +17,13 @@ a { text-align: center; padding: 20px; margin: 20px 20px 20px 0; - background-color: #1d1f31; + background-color: var(--bg); border-radius: 12px; } #enterprise-cta-desktop p { margin: 0 auto 16px auto; - color: #fff; + color: var(--fg); font-weight: 400; } diff --git a/frontend/src/app/docs/api-docs/api-docs.component.html b/frontend/src/app/docs/api-docs/api-docs.component.html index 6a561a4f0..eb3ab3323 100644 --- a/frontend/src/app/docs/api-docs/api-docs.component.html +++ b/frontend/src/app/docs/api-docs/api-docs.component.html @@ -190,11 +190,11 @@ -

If it's been a while and your transaction hasn't confirmed, your transaction is probably using a lower feerate relative to other transactions currently in the mempool. Depending on how you made your transaction, there may be ways to accelerate the process.

There's no need to panic—a Bitcoin transaction will always either confirm completely (or not at all) at some point. As long as you have your transaction's ID, you can always see where your funds are.

This site only provides data about the Bitcoin network—it cannot help you get your transaction confirmed quicker.

+

If it's been a while and your transaction hasn't confirmed, your transaction is probably using a lower feerate relative to other transactions currently in the mempool. Depending on how you made your transaction, there may be ways to accelerate the process.

There's no need to panic—a Bitcoin transaction will always either confirm completely (or not at all) at some point. As long as you have your transaction's ID, you can always see where your funds are.

This site only provides data about the Bitcoin network. To get help with a transaction, get in touch with the entity that helped make the transaction (wallet software, exchange company, etc).

-

To get your transaction confirmed quicker, you will need to increase its effective feerate.

If your transaction was created with RBF enabled, your stuck transaction can simply be replaced with a new one that has a higher fee.

Otherwise, if you control any of the stuck transaction's outputs, you can use CPFP to increase your stuck transaction's effective feerate.

If you are not sure how to do RBF or CPFP, work with the tool you used to make the transaction (wallet software, exchange company, etc). This website only provides data about the Bitcoin network, so there is nothing it can do to help you get your transaction confirmed quicker.

+

To get your transaction confirmed quicker, you will need to increase its effective feerate.

If your transaction was created with RBF enabled, your stuck transaction can simply be replaced with a new one that has a higher fee. Otherwise, if you control any of the stuck transaction's outputs, you can use CPFP to increase your stuck transaction's effective feerate.

If you are not sure how to do RBF or CPFP, work with the tool you used to make the transaction (wallet software, exchange company, etc).

Another option to get your transaction confirmed more quickly is Mempool Accelerator™. This service is still in development, but you can sign up for the waitlist to be notified when it's ready.

diff --git a/frontend/src/app/docs/api-docs/api-docs.component.scss b/frontend/src/app/docs/api-docs/api-docs.component.scss index a139288e7..ce8c37121 100644 --- a/frontend/src/app/docs/api-docs/api-docs.component.scss +++ b/frontend/src/app/docs/api-docs/api-docs.component.scss @@ -17,7 +17,7 @@ } code { - background-color: #1d1f31; + background-color: var(--bg); font-family: Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New; } @@ -95,7 +95,7 @@ ul.no-bull.block-audit code{ .nav-tabs .nav-link.active { border-bottom: 1px solid #fff; @media (min-width: 676px){ - border-bottom: 1px solid #11131f; + border-bottom: 1px solid var(--active-bg); } } @@ -113,7 +113,7 @@ ul.no-bull.block-audit code{ padding: 0px; } .nav-tabs .nav-link.active { - border-bottom: 1px solid #11131f; + border-bottom: 1px solid var(--active-bg); } .subtitle { display: flex; @@ -158,17 +158,17 @@ ul.no-bull.block-audit code{ top: 80px; overflow-y: auto; height: calc(100vh - 75px); - scrollbar-color: #2d3348 #11131f; + scrollbar-color: var(--secondary) var(--active-bg); scrollbar-width: thin; } ::-webkit-scrollbar { width: 3px; } ::-webkit-scrollbar-track { - background: #11131f; + background: var(--active-bg); } ::-webkit-scrollbar-thumb { - background-color: #2d3348; + background-color: var(--secondary); border-radius: 5px; border: none; } @@ -196,8 +196,8 @@ h3 { .endpoint-container .section-header { display: block; - background-color: #2d3348; - color: #1bd8f4; + background-color: var(--secondary); + color: var(--info); padding: 1rem 1.3rem 1rem 1.3rem; font-weight: bold; border-radius: 0.25rem; @@ -211,8 +211,8 @@ h3 { } .endpoint-container .section-header span { - color: #fff; - background-color: #653b9c; + color: var(--fg); + background-color: var(--tertiary); font-size: 12px; text-transform: uppercase; font-weight: 400; @@ -244,7 +244,7 @@ h3 { } #doc-nav-mobile > div { - background-color: #2d3348; + background-color: var(--secondary); z-index: 100; border-radius: 0 0 0.5rem 0.5rem; height: 55vh; @@ -253,9 +253,9 @@ h3 { #doc-nav-mobile button { width: 100%; - background-color: #105fb0; - color: #fff; - border-color: #105fb0; + background-color: var(--primary); + color: var(--fg); + border-color: var(--primary); border-radius: 0.5rem 0.5rem 0 0; } @@ -303,7 +303,7 @@ h3 { } #disclaimer { - background-color: #1d1f31; + background-color: var(--bg); padding: 24px; margin: 24px 0; } @@ -318,7 +318,7 @@ h3 { #enterprise-cta-mobile { padding: 20px; - background-color: #1d1f31; + background-color: var(--bg); border-radius: 0.25rem; text-align: center; position: fixed; @@ -343,8 +343,8 @@ h3 { } #enterprise-cta-mobile .btn-secondary:hover { - background-color: #2d3348; - border-color: #2d3348; + background-color: var(--secondary); + border-color: var(--secondary); } #enterprise-cta-mobile .no-line-break { @@ -438,7 +438,7 @@ dl { dt { font-weight: bold; - color: #4a68b9; + color: var(--title-fg); padding: 5px 0; } @@ -447,7 +447,7 @@ dd { & > dl { padding-left: 1em; - border-left: 2px solid #4a68b9; + border-left: 2px solid var(--title-fg); margin-left: 1em; margin-top: 5px; } diff --git a/frontend/src/app/docs/code-template/code-template.component.scss b/frontend/src/app/docs/code-template/code-template.component.scss index 4d3288dfd..960787af0 100644 --- a/frontend/src/app/docs/code-template/code-template.component.scss +++ b/frontend/src/app/docs/code-template/code-template.component.scss @@ -3,7 +3,7 @@ } code { - background-color: #1d1f31; + background-color: var(--bg); font-family: Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New; } @@ -25,7 +25,7 @@ li.nav-item { .nav-tabs .nav-link.active { border-bottom: 1px solid #fff; @media (min-width: 676px){ - border-bottom: 1px solid #11131f; + border-bottom: 1px solid var(--active-bg); } } @@ -43,7 +43,7 @@ li.nav-item { padding: 0px; } .nav-tabs .nav-link.active { - border-bottom: 1px solid #11131f; + border-bottom: 1px solid var(--active-bg); } .subtitle { display: flex; @@ -87,7 +87,7 @@ pre { display: block; font-size: 87.5%; color: #f18920; - background-color: #1d1f31; + background-color: var(--bg); padding: 30px; code{ background-color: transparent; diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts index 6d28612f0..dfc594e49 100644 --- a/frontend/src/app/interfaces/node-api.interface.ts +++ b/frontend/src/app/interfaces/node-api.interface.ts @@ -394,8 +394,11 @@ export interface Acceleration { blockHash: string; blockHeight: number; - acceleratedFee?: number; + acceleratedFeeRate?: number; boost?: number; + + boostCost?: number; + boostRate?: number; } export interface AccelerationHistoryParams { diff --git a/frontend/src/app/lightning/channel/channel-box/channel-box.component.scss b/frontend/src/app/lightning/channel/channel-box/channel-box.component.scss index f157f380a..2306dd261 100644 --- a/frontend/src/app/lightning/channel/channel-box/channel-box.component.scss +++ b/frontend/src/app/lightning/channel/channel-box/channel-box.component.scss @@ -13,7 +13,7 @@ } .shared-block { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } diff --git a/frontend/src/app/lightning/channel/channel-close-box/channel-close-box.component.scss b/frontend/src/app/lightning/channel/channel-close-box/channel-close-box.component.scss index f55550eb3..12a8cb53c 100644 --- a/frontend/src/app/lightning/channel/channel-close-box/channel-close-box.component.scss +++ b/frontend/src/app/lightning/channel/channel-close-box/channel-close-box.component.scss @@ -60,19 +60,19 @@ justify-content: center; &.left { - background: #105fb0; + background: var(--primary); } &.center { background: repeating-linear-gradient( 60deg, - #105fb0 0, - #105fb0 12px, - #1a9436 12px, - #1a9436 24px + var(--primary) 0, + var(--primary) 12px, + var(--success) 12px, + var(--success) 24px ); } &.right { - background: #1a9436; + background: var(--success); } .value { @@ -93,10 +93,10 @@ .bar.center { background: repeating-linear-gradient( 60deg, - #105fb0 0, - #105fb0 8px, - #1a9436 8px, - #1a9436 16px + var(--primary) 0, + var(--primary) 8px, + var(--success) 8px, + var(--success) 16px ) } } diff --git a/frontend/src/app/lightning/channel/channel-preview.component.scss b/frontend/src/app/lightning/channel/channel-preview.component.scss index 6b6ac5152..cdd30204c 100644 --- a/frontend/src/app/lightning/channel/channel-preview.component.scss +++ b/frontend/src/app/lightning/channel/channel-preview.component.scss @@ -34,7 +34,7 @@ } .row.nodes { - background: #181b2d; + background: var(--stat-box-bg); margin: 15px 0 0; } @@ -53,7 +53,7 @@ width: 470px; min-width: 470px; padding: 0; - background: #181b2d; + background: var(--stat-box-bg); max-height: 350px; overflow: hidden; } diff --git a/frontend/src/app/lightning/channel/channel.component.html b/frontend/src/app/lightning/channel/channel.component.html index b9d9e09a4..290199210 100644 --- a/frontend/src/app/lightning/channel/channel.component.html +++ b/frontend/src/app/lightning/channel/channel.component.html @@ -1,7 +1,7 @@
-
Lightning channel
+
Lightning channel

{{ channel.short_id }}

@@ -113,7 +113,7 @@
-
Lightning channel
+
Lightning channel

diff --git a/frontend/src/app/lightning/channels-list/channels-list.component.scss b/frontend/src/app/lightning/channels-list/channels-list.component.scss index 80797b550..f45f162c6 100644 --- a/frontend/src/app/lightning/channels-list/channels-list.component.scss +++ b/frontend/src/app/lightning/channels-list/channels-list.component.scss @@ -3,7 +3,7 @@ } .sats { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; top: 0px; } diff --git a/frontend/src/app/lightning/channels-statistics/channels-statistics.component.html b/frontend/src/app/lightning/channels-statistics/channels-statistics.component.html index 31b4c33af..a84def86c 100644 --- a/frontend/src/app/lightning/channels-statistics/channels-statistics.component.html +++ b/frontend/src/app/lightning/channels-statistics/channels-statistics.component.html @@ -1,7 +1,7 @@
avg - | + | med
diff --git a/frontend/src/app/lightning/channels-statistics/channels-statistics.component.scss b/frontend/src/app/lightning/channels-statistics/channels-statistics.component.scss index 30f88f136..614b9bd94 100644 --- a/frontend/src/app/lightning/channels-statistics/channels-statistics.component.scss +++ b/frontend/src/app/lightning/channels-statistics/channels-statistics.component.scss @@ -1,5 +1,5 @@ .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; @@ -57,7 +57,7 @@ margin-bottom: 0; } .card-text span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; top: 0px; } @@ -110,5 +110,5 @@ } .inactive { - color: #ffffff66; + color: var(--transparent-fg); } \ No newline at end of file diff --git a/frontend/src/app/lightning/group/group-preview.component.scss b/frontend/src/app/lightning/group/group-preview.component.scss index 712112f5a..f31c33f47 100644 --- a/frontend/src/app/lightning/group/group-preview.component.scss +++ b/frontend/src/app/lightning/group/group-preview.component.scss @@ -20,7 +20,7 @@ width: 100%; margin: 16px 0 0; padding: 20px 12px; - background: #181b2d; + background: var(--stat-box-bg); font-size: 32px; } @@ -46,7 +46,7 @@ min-height: 272px; max-height: 272px; padding: 0; - background: #181b2d; + background: var(--stat-box-bg); overflow: hidden; margin-top: 16px; } diff --git a/frontend/src/app/lightning/group/group.component.html b/frontend/src/app/lightning/group/group.component.html index c1ffe7f6d..c5999da5c 100644 --- a/frontend/src/app/lightning/group/group.component.html +++ b/frontend/src/app/lightning/group/group.component.html @@ -1,5 +1,5 @@
-
Lightning node group
+
Lightning node group
@@ -44,7 +44,7 @@
-
+
diff --git a/frontend/src/app/lightning/group/group.component.scss b/frontend/src/app/lightning/group/group.component.scss index 6deb4ca14..61bc87ca8 100644 --- a/frontend/src/app/lightning/group/group.component.scss +++ b/frontend/src/app/lightning/group/group.component.scss @@ -12,7 +12,7 @@ h1 { } .qr-wrapper { - background-color: #FFF; + background-color: var(--fg); padding: 10px; padding-bottom: 5px; display: inline-block; diff --git a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html index ec59b7432..490a5d706 100644 --- a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html +++ b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html @@ -65,7 +65,7 @@
Liquidity Ranking
  - +
@@ -79,7 +79,7 @@
Connectivity Ranking
  - +
diff --git a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.scss b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.scss index e6da450df..7fb011146 100644 --- a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.scss +++ b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.scss @@ -10,7 +10,7 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); } .graph-card { @@ -35,10 +35,10 @@ .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .card-title > a { - color: #4a68b9; + color: var(--title-fg); } .card-body.pool-ranking { diff --git a/frontend/src/app/lightning/node-fee-chart/node-fee-chart.component.ts b/frontend/src/app/lightning/node-fee-chart/node-fee-chart.component.ts index f20a5123c..7f329eaf2 100644 --- a/frontend/src/app/lightning/node-fee-chart/node-fee-chart.component.ts +++ b/frontend/src/app/lightning/node-fee-chart/node-fee-chart.component.ts @@ -142,7 +142,7 @@ export class NodeFeeChartComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -205,7 +205,7 @@ export class NodeFeeChartComponent implements OnInit { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, diff --git a/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.ts b/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.ts index f67c83367..35cd8b236 100644 --- a/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.ts +++ b/frontend/src/app/lightning/node-statistics-chart/node-statistics-chart.component.ts @@ -112,7 +112,7 @@ export class NodeStatisticsChartComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -181,7 +181,7 @@ export class NodeStatisticsChartComponent implements OnInit { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, @@ -217,7 +217,7 @@ export class NodeStatisticsChartComponent implements OnInit { symbol: 'none', lineStyle: { type: 'solid', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 1, width: 1, }, diff --git a/frontend/src/app/lightning/node-statistics/node-statistics.component.scss b/frontend/src/app/lightning/node-statistics/node-statistics.component.scss index dc69a4dae..7b3f778b1 100644 --- a/frontend/src/app/lightning/node-statistics/node-statistics.component.scss +++ b/frontend/src/app/lightning/node-statistics/node-statistics.component.scss @@ -1,5 +1,5 @@ .card-title { - color: #4a68b9; + color: var(--title-fg); font-size: 10px; margin-bottom: 4px; font-size: 1rem; @@ -52,7 +52,7 @@ } } .card-text span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; top: 0px; } diff --git a/frontend/src/app/lightning/node/node-preview.component.scss b/frontend/src/app/lightning/node/node-preview.component.scss index da8794010..aac57754d 100644 --- a/frontend/src/app/lightning/node/node-preview.component.scss +++ b/frontend/src/app/lightning/node/node-preview.component.scss @@ -32,7 +32,7 @@ min-height: 408px; max-height: 408px; padding: 0; - background: #181b2d; + background: var(--stat-box-bg); overflow: hidden; margin-top: 6px; } diff --git a/frontend/src/app/lightning/node/node.component.html b/frontend/src/app/lightning/node/node.component.html index 50dab25c7..546b9ecf0 100644 --- a/frontend/src/app/lightning/node/node.component.html +++ b/frontend/src/app/lightning/node/node.component.html @@ -1,7 +1,7 @@
-
Lightning node
+
Lightning node

{{ node.alias }}

@@ -303,7 +303,7 @@
-
Lightning node
+
Lightning node

diff --git a/frontend/src/app/lightning/node/node.component.scss b/frontend/src/app/lightning/node/node.component.scss index 117fc8a2c..9d70bae30 100644 --- a/frontend/src/app/lightning/node/node.component.scss +++ b/frontend/src/app/lightning/node/node.component.scss @@ -14,7 +14,7 @@ } .qr-wrapper { - background-color: #FFF; + background-color: var(--fg); padding: 10px; padding-bottom: 5px; display: inline-block; @@ -89,7 +89,7 @@ app-fiat { .tlv-type { font-size: 12px; - color: #ffffff66; + color: var(--transparent-fg); } .tlv-payload { diff --git a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.html b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.html index b8d0dc12f..8be2e2c14 100644 --- a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.html +++ b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.html @@ -19,7 +19,7 @@
Lightning Nodes Channels World Map
- (Tor nodes excluded) + (Tor nodes excluded)
diff --git a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts index 18edc6ab1..3447348be 100644 --- a/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts +++ b/frontend/src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts @@ -296,7 +296,7 @@ export class NodesChannelsMap implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', diff --git a/frontend/src/app/lightning/nodes-channels/node-channels.component.ts b/frontend/src/app/lightning/nodes-channels/node-channels.component.ts index 1954e429a..fce014e77 100644 --- a/frontend/src/app/lightning/nodes-channels/node-channels.component.ts +++ b/frontend/src/app/lightning/nodes-channels/node-channels.component.ts @@ -96,7 +96,7 @@ export class NodeChannels implements OnChanges { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', }, borderColor: '#000', formatter: (value): string => { diff --git a/frontend/src/app/lightning/nodes-map/nodes-map.component.html b/frontend/src/app/lightning/nodes-map/nodes-map.component.html index d6b793e25..65617f0fd 100644 --- a/frontend/src/app/lightning/nodes-map/nodes-map.component.html +++ b/frontend/src/app/lightning/nodes-map/nodes-map.component.html @@ -4,7 +4,7 @@
Lightning Nodes World Map
- (Tor nodes excluded) + (Tor nodes excluded)
diff --git a/frontend/src/app/lightning/nodes-map/nodes-map.component.ts b/frontend/src/app/lightning/nodes-map/nodes-map.component.ts index 054f1ab6f..50df2f986 100644 --- a/frontend/src/app/lightning/nodes-map/nodes-map.component.ts +++ b/frontend/src/app/lightning/nodes-map/nodes-map.component.ts @@ -196,7 +196,7 @@ export class NodesMap implements OnInit, OnChanges { borderRadius: 0, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', diff --git a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.scss b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.scss index aaea41265..ab8cb92da 100644 --- a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.scss +++ b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.scss @@ -93,12 +93,12 @@ } .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .card-text { font-size: 18px; span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } } diff --git a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts index a7f6da5c2..9784e0a5b 100644 --- a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts +++ b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts @@ -255,7 +255,7 @@ export class NodesNetworksChartComponent implements OnInit, OnChanges { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -352,7 +352,7 @@ export class NodesNetworksChartComponent implements OnInit, OnChanges { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, }, }, @@ -375,7 +375,7 @@ export class NodesNetworksChartComponent implements OnInit, OnChanges { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, }, }, @@ -449,7 +449,7 @@ export class NodesNetworksChartComponent implements OnInit, OnChanges { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 40; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html b/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html index 191a3dbb1..cbe9ed6b1 100644 --- a/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html +++ b/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html @@ -7,7 +7,7 @@
- (Tor nodes excluded) + (Tor nodes excluded)
diff --git a/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.scss b/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.scss index f127d88cd..8d41b72d3 100644 --- a/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.scss +++ b/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.scss @@ -1,5 +1,5 @@ .sats { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; top: 0px; } diff --git a/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts b/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts index 5d80341fe..7eba4f9b7 100644 --- a/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts +++ b/frontend/src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts @@ -85,7 +85,7 @@ export class NodesPerCountryChartComponent implements OnInit { name: country.name.en + (this.isMobile() ? `` : ` (${country.share}%)`), label: { overflow: 'truncate', - color: '#b1b1b1', + color: 'var(--tooltip-grey)', alignTo: 'edge', edgeDistance: edgeDistance, }, @@ -95,7 +95,7 @@ export class NodesPerCountryChartComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', }, borderColor: '#000', formatter: () => { @@ -119,7 +119,7 @@ export class NodesPerCountryChartComponent implements OnInit { name: $localize`Other (${totalShareOther.toFixed(2) + '%'})`, label: { overflow: 'truncate', - color: '#b1b1b1', + color: 'var(--tooltip-grey)', alignTo: 'edge', edgeDistance: edgeDistance }, @@ -128,7 +128,7 @@ export class NodesPerCountryChartComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', }, borderColor: '#000', formatter: () => { @@ -220,7 +220,7 @@ export class NodesPerCountryChartComponent implements OnInit { onSaveChart() { const now = new Date(); - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/lightning/nodes-per-country/nodes-per-country.component.html b/frontend/src/app/lightning/nodes-per-country/nodes-per-country.component.html index be7737894..0d982f127 100644 --- a/frontend/src/app/lightning/nodes-per-country/nodes-per-country.component.html +++ b/frontend/src/app/lightning/nodes-per-country/nodes-per-country.component.html @@ -46,7 +46,7 @@
-
+
diff --git a/frontend/src/app/lightning/nodes-per-country/nodes-per-country.component.scss b/frontend/src/app/lightning/nodes-per-country/nodes-per-country.component.scss index 97d42298c..cd0c0ad0c 100644 --- a/frontend/src/app/lightning/nodes-per-country/nodes-per-country.component.scss +++ b/frontend/src/app/lightning/nodes-per-country/nodes-per-country.component.scss @@ -4,7 +4,7 @@ } .sats { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; top: 0px; } diff --git a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html index 52d74c806..e71e6fb7d 100644 --- a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html +++ b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html @@ -33,7 +33,7 @@
- + (Tor nodes excluded)
diff --git a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.scss b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.scss index 7879c18b1..b9490d579 100644 --- a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.scss +++ b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.scss @@ -89,7 +89,7 @@ } .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -97,7 +97,7 @@ .card-text { font-size: 18px; span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } } diff --git a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts index 5599bc255..429d7ee36 100644 --- a/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts +++ b/frontend/src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts @@ -144,7 +144,7 @@ export class NodesPerISPChartComponent implements OnInit { label: { overflow: 'truncate', width: isMobile() ? 75 : this.widget ? 125 : 250, - color: '#b1b1b1', + color: 'var(--tooltip-grey)', alignTo: 'edge', edgeDistance: edgeDistance, }, @@ -154,7 +154,7 @@ export class NodesPerISPChartComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', }, borderColor: '#000', formatter: () => { @@ -178,7 +178,7 @@ export class NodesPerISPChartComponent implements OnInit { name: $localize`Other (${totalShareOther.toFixed(2) + '%'})`, label: { overflow: 'truncate', - color: '#b1b1b1', + color: 'var(--tooltip-grey)', alignTo: 'edge', edgeDistance: edgeDistance }, @@ -187,7 +187,7 @@ export class NodesPerISPChartComponent implements OnInit { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', }, borderColor: '#000', formatter: () => { @@ -275,7 +275,7 @@ export class NodesPerISPChartComponent implements OnInit { onSaveChart(): void { const now = new Date(); - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.scss b/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.scss index 2fe34ef5e..ca066073b 100644 --- a/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.scss +++ b/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.scss @@ -12,7 +12,7 @@ min-height: 360px; max-height: 360px; padding: 0; - background: #181b2d; + background: var(--stat-box-bg); overflow: hidden; margin-top: 0; } diff --git a/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp.component.html b/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp.component.html index 865d2d2dd..cfb688b8b 100644 --- a/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp.component.html +++ b/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp.component.html @@ -43,7 +43,7 @@
-
+
diff --git a/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp.component.scss b/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp.component.scss index b043d36f8..6e047152e 100644 --- a/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp.component.scss +++ b/frontend/src/app/lightning/nodes-per-isp/nodes-per-isp.component.scss @@ -4,7 +4,7 @@ } .sats { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; top: 0px; } diff --git a/frontend/src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.html b/frontend/src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.html index ef23bc104..11fb9227c 100644 --- a/frontend/src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.html +++ b/frontend/src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.html @@ -8,7 +8,7 @@
Liquidity Ranking
  + style="vertical-align: text-top; font-size: 13px; color: var(--title-fg)">
@@ -22,7 +22,7 @@
Connectivity Ranking
  + style="vertical-align: text-top; font-size: 13px; color: var(--title-fg)">
@@ -36,7 +36,7 @@
Oldest nodes
  + style="vertical-align: text-top; font-size: 13px; color: var(--title-fg)">
diff --git a/frontend/src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.scss b/frontend/src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.scss index 28e80d451..0f94397c6 100644 --- a/frontend/src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.scss +++ b/frontend/src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.scss @@ -9,15 +9,15 @@ } .card { - background-color: #1d1f31; + background-color: var(--bg); } .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .card-title > a { - color: #4a68b9; + color: var(--title-fg); } .card-text { diff --git a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.scss b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.scss index 923a8a3e4..1779394c9 100644 --- a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.scss +++ b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.scss @@ -93,12 +93,12 @@ } .card-title { font-size: 1rem; - color: #4a68b9; + color: var(--title-fg); } .card-text { font-size: 18px; span { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } } diff --git a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts index 2763c319f..44f359ae8 100644 --- a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts +++ b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts @@ -164,7 +164,7 @@ export class LightningStatisticsChartComponent implements OnInit, OnChanges { borderRadius: 4, shadowColor: 'rgba(0, 0, 0, 0.5)', textStyle: { - color: '#b1b1b1', + color: 'var(--tooltip-grey)', align: 'left', }, borderColor: '#000', @@ -239,7 +239,7 @@ export class LightningStatisticsChartComponent implements OnInit, OnChanges { splitLine: { lineStyle: { type: 'dotted', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 0.25, } }, @@ -280,7 +280,7 @@ export class LightningStatisticsChartComponent implements OnInit, OnChanges { symbol: 'none', lineStyle: { type: 'solid', - color: '#ffffff66', + color: 'var(--transparent-fg)', opacity: 1, width: 1, }, @@ -348,7 +348,7 @@ export class LightningStatisticsChartComponent implements OnInit, OnChanges { const now = new Date(); // @ts-ignore this.chartOptions.grid.bottom = 40; - this.chartOptions.backgroundColor = '#11131f'; + this.chartOptions.backgroundColor = 'var(--active-bg)'; this.chartInstance.setOption(this.chartOptions); download(this.chartInstance.getDataURL({ pixelRatio: 2, diff --git a/frontend/src/app/services/services-api.service.ts b/frontend/src/app/services/services-api.service.ts index 4a8314e4b..4cc05294f 100644 --- a/frontend/src/app/services/services-api.service.ts +++ b/frontend/src/app/services/services-api.service.ts @@ -128,12 +128,12 @@ export class ServicesApiServices { return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/estimate`, { txInput: txInput }, { observe: 'response' }); } - accelerate$(txInput: string, userBid: number) { - return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/accelerate`, { txInput: txInput, userBid: userBid }); + accelerate$(txInput: string, userBid: number, accelerationUUID: string) { + return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/accelerate`, { txInput: txInput, userBid: userBid, accelerationUUID: accelerationUUID }); } - accelerateWithCashApp$(txInput: string, userBid: number, token: string, cashtag: string, referenceId: string) { - return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/accelerate/cashapp`, { txInput: txInput, userBid: userBid, token: token, cashtag: cashtag, referenceId: referenceId }); + accelerateWithCashApp$(txInput: string, userBid: number, token: string, cashtag: string, referenceId: string, accelerationUUID: string) { + return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/accelerate/cashapp`, { txInput: txInput, userBid: userBid, token: token, cashtag: cashtag, referenceId: referenceId, accelerationUUID: accelerationUUID }); } getAccelerations$(): Observable { diff --git a/frontend/src/app/services/theme.service.ts b/frontend/src/app/services/theme.service.ts new file mode 100644 index 000000000..da374bf13 --- /dev/null +++ b/frontend/src/app/services/theme.service.ts @@ -0,0 +1,50 @@ +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs'; +import { defaultMempoolFeeColors, contrastMempoolFeeColors } from '../app.constants'; +import { StorageService } from './storage.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ThemeService { + style: HTMLLinkElement; + theme: string = 'default'; + themeChanged$: Subject = new Subject(); + mempoolFeeColors: string[] = defaultMempoolFeeColors; + + constructor( + private storageService: StorageService, + ) { + const theme = this.storageService.getValue('theme-preference') || 'default'; + this.apply(theme); + } + + apply(theme) { + this.theme = theme; + if (theme !== 'default') { + if (theme === 'contrast') { + this.mempoolFeeColors = contrastMempoolFeeColors; + } + try { + if (!this.style) { + this.style = document.createElement('link'); + this.style.rel = 'stylesheet'; + this.style.href = `${theme}.css`; + document.head.appendChild(this.style); + } else { + this.style.href = `${theme}.css`; + } + } catch (err) { + console.log('failed to apply theme stylesheet: ', err); + } + } else { + this.mempoolFeeColors = defaultMempoolFeeColors; + if (this.style) { + this.style.remove(); + this.style = null; + } + } + this.storageService.setValue('theme-preference', theme); + this.themeChanged$.next(this.theme); + } +} diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.html b/frontend/src/app/shared/components/global-footer/global-footer.component.html index cc9cb3538..1a93729d7 100644 --- a/frontend/src/app/shared/components/global-footer/global-footer.component.html +++ b/frontend/src/app/shared/components/global-footer/global-footer.component.html @@ -21,11 +21,17 @@
+
+ +
+
+ +
Matrix -
+

{{ (backendInfo$ | async)?.hostname }} (v{{ (backendInfo$ | async )?.version }}) [{{ (backendInfo$ | async )?.gitCommit | slice:0:8 }}] diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.scss b/frontend/src/app/shared/components/global-footer/global-footer.component.scss index 5467f09c1..2db64e976 100644 --- a/frontend/src/app/shared/components/global-footer/global-footer.component.scss +++ b/frontend/src/app/shared/components/global-footer/global-footer.component.scss @@ -1,5 +1,5 @@ footer { - background-color: #1d1f31; + background-color: var(--bg); margin-top: 30px; &.services { @media (min-width: 768px) { @@ -34,11 +34,11 @@ footer .row.main .branding > p { footer .row.main .branding .btn { display: inline-block; - color: #fff !important; + color: var(--fg) !important; } footer .row.main .branding button.account { - background-color: #2d3348; + background-color: var(--secondary); } footer .row.main .branding .cta { @@ -59,7 +59,7 @@ footer .row.main .links > div:first-child { } footer .links .category { - color: #4a68b9; + color: var(--title-fg); font-weight: 700; } @@ -114,7 +114,7 @@ footer .row.social-links svg { footer .row.version { padding-top: 20px !important; padding-bottom: 20px !important; - background-color: #1d1f31; + background-color: var(--bg); } footer .row.version p { diff --git a/frontend/src/app/shared/components/mempool-error/mempool-error.component.ts b/frontend/src/app/shared/components/mempool-error/mempool-error.component.ts index ac5ac72a1..07b96427d 100644 --- a/frontend/src/app/shared/components/mempool-error/mempool-error.component.ts +++ b/frontend/src/app/shared/components/mempool-error/mempool-error.component.ts @@ -21,6 +21,7 @@ const MempoolErrors = { 'txid_not_in_mempool': `This transaction is not in the mempool.`, 'waitlisted': `You are currently on the wait list. You will get notified once you are granted access.`, 'not_whitelisted_by_any_pool': `You are not whitelisted by any mining pool`, + 'unauthorized': `You are not authorized to do this`, } as { [error: string]: string }; export function isMempoolError(error: string) { diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index 5e58ef080..72d9eb04d 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -34,6 +34,7 @@ import { ReactiveFormsModule } from '@angular/forms'; import { LanguageSelectorComponent } from '../components/language-selector/language-selector.component'; import { FiatSelectorComponent } from '../components/fiat-selector/fiat-selector.component'; import { RateUnitSelectorComponent } from '../components/rate-unit-selector/rate-unit-selector.component'; +import { ThemeSelectorComponent } from '../components/theme-selector/theme-selector.component'; import { BrowserOnlyDirective } from './directives/browser-only.directive'; import { ServerOnlyDirective } from './directives/server-only.directive'; import { ColoredPriceDirective } from './directives/colored-price.directive'; @@ -119,6 +120,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir TxFeeRatingComponent, LanguageSelectorComponent, FiatSelectorComponent, + ThemeSelectorComponent, RateUnitSelectorComponent, ScriptpubkeyTypePipe, RelativeUrlPipe, @@ -257,6 +259,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir LanguageSelectorComponent, FiatSelectorComponent, RateUnitSelectorComponent, + ThemeSelectorComponent, ScriptpubkeyTypePipe, RelativeUrlPipe, Hex2asciiPipe, diff --git a/frontend/src/locale/messages.fa.xlf b/frontend/src/locale/messages.fa.xlf index f1902ce34..eed8aee8a 100644 --- a/frontend/src/locale/messages.fa.xlf +++ b/frontend/src/locale/messages.fa.xlf @@ -954,6 +954,7 @@ Accelerations + شتاب‌دهی‌ها src/app/components/acceleration/accelerations-list/accelerations-list.component.html 2 @@ -987,6 +988,7 @@ Fee Rate + نرخ کارمزد src/app/components/acceleration/accelerations-list/accelerations-list.component.html 12 @@ -996,6 +998,7 @@ Acceleration Bid + پیشنهاد شتاب‌دهی src/app/components/acceleration/accelerations-list/accelerations-list.component.html 13 @@ -1005,6 +1008,7 @@ Requested + درخواست‌شده src/app/components/acceleration/accelerations-list/accelerations-list.component.html 14 @@ -1017,6 +1021,7 @@ Bid Boost + افزایش ناشی از پیشنهاد src/app/components/acceleration/accelerations-list/accelerations-list.component.html 17 @@ -1065,6 +1070,7 @@ Pending + در حال انتظار src/app/components/acceleration/accelerations-list/accelerations-list.component.html 53 @@ -1073,6 +1079,7 @@ Completed 🔄 + کامل‌شده 🔄 src/app/components/acceleration/accelerations-list/accelerations-list.component.html 54,55 @@ -1080,6 +1087,7 @@ Failed 🔄 + ناموفق 🔄 src/app/components/acceleration/accelerations-list/accelerations-list.component.html 55,56 @@ -1088,6 +1096,7 @@ There are no active accelerations + هیچ شتاب‌دهی فعالی وجود ندارد src/app/components/acceleration/accelerations-list/accelerations-list.component.html 96 @@ -1096,6 +1105,7 @@ There are no recent accelerations + هیچ شتاب‌دهی اخیری وجود ندارد src/app/components/acceleration/accelerations-list/accelerations-list.component.html 97 @@ -1104,6 +1114,7 @@ Active Accelerations + شتاب‌دهی‌های فعال src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html 10 @@ -1116,6 +1127,7 @@ Acceleration stats + وضعیت شتاب‌دهی src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html 24 @@ -1124,6 +1136,7 @@ (3 months) + (3 ماه) src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html 25 @@ -1157,6 +1170,7 @@ Recent Accelerations + شتاب‌دهی‌های اخیر src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html 86 @@ -1165,6 +1179,7 @@ Accelerator Dashboard + داشبورد شتاب‌دهی src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts 47 @@ -1176,6 +1191,7 @@ pending + در حال انتظار src/app/components/acceleration/pending-stats/pending-stats.component.html 7 @@ -1184,6 +1200,7 @@ Avg Max Bid + متوسط بیشینه پیشنهاد src/app/components/acceleration/pending-stats/pending-stats.component.html 11 @@ -1196,6 +1213,7 @@ Total Vsize + مجموع اندازه مجازی src/app/components/acceleration/pending-stats/pending-stats.component.html 20 @@ -1208,6 +1226,7 @@ of next block + از بلاک بعدی src/app/components/acceleration/pending-stats/pending-stats.component.html 23 @@ -1216,6 +1235,7 @@ Balance History + تاریخچه موجودی src/app/components/address-graph/address-graph.component.html 6 @@ -1224,6 +1244,7 @@ Balance:Balance + Balance:Balance src/app/components/address-graph/address-graph.component.ts 162 @@ -1231,6 +1252,7 @@ Balances + موجودی‌ها src/app/components/address-group/address-group.component.html 4 @@ -1239,6 +1261,7 @@ Total + مجموع src/app/components/address-group/address-group.component.html 9 @@ -6565,6 +6588,7 @@ Consolidation + تجمیع src/app/dashboard/dashboard.component.ts 79 @@ -6576,6 +6600,7 @@ Coinjoin + هم‌بازضرب src/app/dashboard/dashboard.component.ts 80 @@ -6587,6 +6612,7 @@ Data + داده src/app/dashboard/dashboard.component.ts 81 diff --git a/frontend/src/locale/messages.xlf b/frontend/src/locale/messages.xlf index b4dd11f58..513f64397 100644 --- a/frontend/src/locale/messages.xlf +++ b/frontend/src/locale/messages.xlf @@ -397,7 +397,7 @@ src/app/components/transaction/transaction.component.html - 534 + 581 src/app/components/transactions-list/transactions-list.component.html @@ -464,11 +464,11 @@ src/app/components/transaction/transaction.component.html - 189 + 101 src/app/components/transaction/transaction.component.html - 317 + 229 Transaction Virtual Size transaction.vsize @@ -710,15 +710,15 @@ src/app/components/transaction/transaction.component.html - 106 + 81 src/app/components/transaction/transaction.component.html - 145 + 534 src/app/components/transaction/transaction.component.html - 155 + 543 Accelerate button label transaction.accelerate @@ -727,7 +727,7 @@ If your tx is accelerated to ~ sat/vB src/app/components/accelerate-preview/accelerate-preview.component.html - 249 + 258 accelerator.accelerated-to-description @@ -893,7 +893,7 @@ src/app/components/transaction/transaction.component.html - 188 + 100 src/app/dashboard/dashboard.component.html @@ -1084,7 +1084,7 @@ Accelerator Dashboard src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts - 47 + 51 src/app/components/master-page/master-page.component.html @@ -1139,11 +1139,23 @@ address.balance-history - - Balance:Balance + + Balance src/app/components/address-graph/address-graph.component.ts - 162 + 164 + + + src/app/components/address/address-preview.component.html + 31 + + + src/app/components/address/address.component.html + 39 + + + src/app/components/liquid-reserves-audit/federation-addresses-list/federation-addresses-list.component.html + 9 @@ -1225,22 +1237,6 @@ address.total-sent - - Balance - - src/app/components/address/address-preview.component.html - 31 - - - src/app/components/address/address.component.html - 39 - - - src/app/components/liquid-reserves-audit/federation-addresses-list/federation-addresses-list.component.html - 9 - - address.balance - Transactions @@ -1991,7 +1987,7 @@ src/app/components/transaction/transaction.component.html - 130 + 461 src/app/lightning/node/node.component.html @@ -2028,7 +2024,7 @@ src/app/components/transaction/transaction.component.html - 63 + 449 src/app/shared/components/confirmations/confirmations.component.html @@ -2073,7 +2069,7 @@ src/app/components/transaction/transaction.component.html - 533 + 580 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -2094,11 +2090,11 @@ src/app/components/transaction/transaction.component.html - 191 + 103 src/app/components/transaction/transaction.component.html - 537 + 591 src/app/lightning/channel/channel-box/channel-box.component.html @@ -2123,7 +2119,7 @@ src/app/components/transaction/transaction.component.html - 548 + 612 Effective transaction fee rate transaction.effective-fee-rate @@ -2149,7 +2145,7 @@ src/app/components/transaction/transaction.component.html - 190 + 102 Transaction Weight transaction.weight @@ -2219,7 +2215,7 @@ src/app/components/transaction/transaction.component.html - 81 + 504 Added tx-features.tag.added @@ -2232,7 +2228,7 @@ src/app/components/transaction/transaction.component.html - 82 + 507 Prioritized tx-features.tag.prioritized @@ -2245,7 +2241,7 @@ src/app/components/transaction/transaction.component.html - 83 + 510 Conflict tx-features.tag.conflict @@ -2262,7 +2258,7 @@ src/app/components/transaction/transaction.component.html - 583 + 564 src/app/shared/filters.utils.ts @@ -2356,7 +2352,7 @@ src/app/components/transaction/transaction.component.html - 313 + 225 src/app/dashboard/dashboard.component.html @@ -2395,7 +2391,7 @@ src/app/components/transaction/transaction.component.html - 329 + 241 @@ -2493,7 +2489,7 @@ src/app/components/transaction/transaction.component.html - 53 + 432 block.timestamp @@ -2558,7 +2554,7 @@ src/app/components/transaction/transaction.component.html - 562 + 641 block.miner @@ -2745,7 +2741,7 @@ src/app/components/transaction/transaction.component.html - 339 + 251 transaction.version @@ -2846,7 +2842,7 @@ src/app/components/transaction/transaction.component.html - 74 + 491 Toggle Audit block.toggle-audit @@ -2859,15 +2855,15 @@ src/app/components/transaction/transaction.component.html - 297 + 209 src/app/components/transaction/transaction.component.html - 305 + 217 src/app/components/transaction/transaction.component.html - 465 + 342 src/app/lightning/channel/channel.component.html @@ -4812,7 +4808,7 @@ src/app/components/transaction/transaction.component.html - 355 + 267 transaction.hex @@ -4906,7 +4902,7 @@ src/app/components/transaction/transaction.component.html - 276 + 188 src/app/components/transactions-list/transactions-list.component.html @@ -5440,7 +5436,7 @@ src/app/components/transaction/transaction.component.html - 77 + 495 src/app/components/transactions-list/transactions-list.component.html @@ -5460,7 +5456,7 @@ src/app/components/transaction/transaction.component.ts - 398 + 399 @@ -5471,7 +5467,7 @@ src/app/components/transaction/transaction.component.ts - 402 + 403 @@ -5483,15 +5479,170 @@ RBF replacement transaction.rbf.replacement + + Hide accelerator + + src/app/components/transaction/transaction.component.html + 83 + + hide-accelerator + + + Type + + src/app/components/transaction/transaction.component.html + 99 + + + src/app/components/transactions-list/transactions-list.component.html + 276 + + transactions-list.vout.scriptpubkey-type + + + Descendant + + src/app/components/transaction/transaction.component.html + 110 + + + src/app/components/transaction/transaction.component.html + 122 + + Descendant + transaction.descendant + + + Ancestor + + src/app/components/transaction/transaction.component.html + 134 + + Transaction Ancestor + transaction.ancestor + + + RBF History + + src/app/components/transaction/transaction.component.html + 153 + + RBF History + transaction.rbf-history + + + Flow + + src/app/components/transaction/transaction.component.html + 162 + + + src/app/components/transaction/transaction.component.html + 282 + + Transaction flow + transaction.flow + + + Hide diagram + + src/app/components/transaction/transaction.component.html + 165 + + hide-diagram + + + Show more + + src/app/components/transaction/transaction.component.html + 186 + + + src/app/components/transactions-list/transactions-list.component.html + 171 + + + src/app/components/transactions-list/transactions-list.component.html + 289 + + show-more + + + Inputs & Outputs + + src/app/components/transaction/transaction.component.html + 204 + + + src/app/components/transaction/transaction.component.html + 313 + + Transaction inputs and outputs + transaction.inputs-and-outputs + + + Show diagram + + src/app/components/transaction/transaction.component.html + 208 + + show-diagram + + + Adjusted vsize + + src/app/components/transaction/transaction.component.html + 233 + + Transaction Adjusted VSize + transaction.adjusted-vsize + + + Locktime + + src/app/components/transaction/transaction.component.html + 255 + + transaction.locktime + + + Sigops + + src/app/components/transaction/transaction.component.html + 259 + + Transaction Sigops + transaction.sigops + + + Transaction not found. + + src/app/components/transaction/transaction.component.html + 391 + + transaction.error.transaction-not-found + + + Waiting for it to appear in the mempool... + + src/app/components/transaction/transaction.component.html + 392 + + transaction.error.waiting-for-it-to-appear + + + Error loading transaction data. + + src/app/components/transaction/transaction.component.html + 398 + + transaction.error.loading-transaction-data + Features src/app/components/transaction/transaction.component.html - 68 - - - src/app/components/transaction/transaction.component.html - 163 + 474 src/app/lightning/node/node.component.html @@ -5508,7 +5659,7 @@ This transaction was projected to be included in the block src/app/components/transaction/transaction.component.html - 78 + 497 Expected in block tooltip @@ -5516,7 +5667,7 @@ Expected in Block src/app/components/transaction/transaction.component.html - 78 + 497 Expected in Block tx-features.tag.expected @@ -5525,7 +5676,7 @@ This transaction was seen in the mempool prior to mining src/app/components/transaction/transaction.component.html - 79 + 499 Seen in mempool tooltip @@ -5533,7 +5684,7 @@ Seen in Mempool src/app/components/transaction/transaction.component.html - 79 + 499 Seen in Mempool tx-features.tag.seen @@ -5542,7 +5693,7 @@ This transaction was missing from our mempool prior to mining src/app/components/transaction/transaction.component.html - 80 + 501 Not seen in mempool tooltip @@ -5550,7 +5701,7 @@ Not seen in Mempool src/app/components/transaction/transaction.component.html - 80 + 501 Not seen in Mempool tx-features.tag.not-seen @@ -5559,7 +5710,7 @@ This transaction may have been added out-of-band src/app/components/transaction/transaction.component.html - 81 + 504 Added transaction tooltip @@ -5567,7 +5718,7 @@ This transaction may have been prioritized out-of-band src/app/components/transaction/transaction.component.html - 82 + 507 Prioritized transaction tooltip @@ -5575,23 +5726,15 @@ This transaction conflicted with another version in our mempool src/app/components/transaction/transaction.component.html - 83 + 510 Conflict in mempool tooltip - - Hide accelerator - - src/app/components/transaction/transaction.component.html - 108 - - hide-accelerator - ETA src/app/components/transaction/transaction.component.html - 136 + 526 Transaction ETA transaction.eta @@ -5600,167 +5743,16 @@ In several hours (or more) src/app/components/transaction/transaction.component.html - 144 + 532 Transaction ETA in several hours or more transaction.eta.in-several-hours - - Type - - src/app/components/transaction/transaction.component.html - 187 - - - src/app/components/transactions-list/transactions-list.component.html - 276 - - transactions-list.vout.scriptpubkey-type - - - Descendant - - src/app/components/transaction/transaction.component.html - 198 - - - src/app/components/transaction/transaction.component.html - 210 - - Descendant - transaction.descendant - - - Ancestor - - src/app/components/transaction/transaction.component.html - 222 - - Transaction Ancestor - transaction.ancestor - - - RBF History - - src/app/components/transaction/transaction.component.html - 241 - - RBF History - transaction.rbf-history - - - Flow - - src/app/components/transaction/transaction.component.html - 250 - - - src/app/components/transaction/transaction.component.html - 405 - - Transaction flow - transaction.flow - - - Hide diagram - - src/app/components/transaction/transaction.component.html - 253 - - hide-diagram - - - Show more - - src/app/components/transaction/transaction.component.html - 274 - - - src/app/components/transactions-list/transactions-list.component.html - 171 - - - src/app/components/transactions-list/transactions-list.component.html - 289 - - show-more - - - Inputs & Outputs - - src/app/components/transaction/transaction.component.html - 292 - - - src/app/components/transaction/transaction.component.html - 436 - - Transaction inputs and outputs - transaction.inputs-and-outputs - - - Show diagram - - src/app/components/transaction/transaction.component.html - 296 - - show-diagram - - - Adjusted vsize - - src/app/components/transaction/transaction.component.html - 321 - - Transaction Adjusted VSize - transaction.adjusted-vsize - - - Locktime - - src/app/components/transaction/transaction.component.html - 343 - - transaction.locktime - - - Sigops - - src/app/components/transaction/transaction.component.html - 347 - - Transaction Sigops - transaction.sigops - - - Transaction not found. - - src/app/components/transaction/transaction.component.html - 514 - - transaction.error.transaction-not-found - - - Waiting for it to appear in the mempool... - - src/app/components/transaction/transaction.component.html - 515 - - transaction.error.waiting-for-it-to-appear - - - Error loading transaction data. - - src/app/components/transaction/transaction.component.html - 521 - - transaction.error.loading-transaction-data - Accelerated fee rate src/app/components/transaction/transaction.component.html - 547 + 610 Accelerated transaction fee rate transaction.accelerated-fee-rate diff --git a/frontend/src/locale/messages.zh.xlf b/frontend/src/locale/messages.zh.xlf index 1965a4914..b8ed655bd 100644 --- a/frontend/src/locale/messages.zh.xlf +++ b/frontend/src/locale/messages.zh.xlf @@ -721,6 +721,7 @@ Sign In + 登录 src/app/components/accelerate-preview/accelerate-preview.component.html 214 @@ -1201,6 +1202,7 @@ Balances + 余额 src/app/components/address-group/address-group.component.html 4 @@ -3592,6 +3594,7 @@ halving + 减半 src/app/components/difficulty/difficulty.component.html 10 @@ -4241,6 +4244,7 @@ Dust + 粉尘 src/app/components/liquid-reserves-audit/federation-utxos-list/federation-utxos-list.component.html 15 @@ -4785,6 +4789,7 @@ Other () + 其他( src/app/components/pool-ranking/pool-ranking.component.ts 186 @@ -5057,6 +5062,7 @@ Broadcast Transaction + 广播交易 src/app/components/push-transaction/push-transaction.component.ts 33 @@ -5064,6 +5070,7 @@ Broadcast a transaction to the network using the transaction's hash. + 使用交易的哈希值将交易广播到 网络。 src/app/components/push-transaction/push-transaction.component.ts 34 @@ -5276,6 +5283,7 @@ Block Height + 区块高度 src/app/components/search-form/search-results/search-results.component.html 3 @@ -5284,6 +5292,7 @@ Transaction + 交易 src/app/components/search-form/search-results/search-results.component.html 21 @@ -5292,6 +5301,7 @@ Address + 地址 src/app/components/search-form/search-results/search-results.component.html 27 @@ -5300,6 +5310,7 @@ Block + src/app/components/search-form/search-results/search-results.component.html 33 @@ -5442,6 +5453,8 @@ Immediately + 立刻 + src/app/components/time/time.component.ts 90 @@ -5637,6 +5650,7 @@ before + 之前 src/app/components/time/time.component.ts 214 @@ -5729,6 +5743,7 @@ Get real-time status, addresses, fees, script info, and more for transaction with txid . + 获取 交易的实时状态、地址、费用、脚本信息等,交易 ID 为 src/app/components/transaction/transaction-preview.component.ts 93 @@ -5797,6 +5812,7 @@ Seen in Mempool + 在Mempool中查看 src/app/components/transaction/transaction.component.html 79 @@ -6534,6 +6550,7 @@ Coinjoin + 代币混合 src/app/dashboard/dashboard.component.ts 80 @@ -6556,6 +6573,7 @@ mempool.space merely provides data about the Bitcoin network. It cannot help you with retrieving funds, wallet issues, etc.For any such requests, you need to get in touch with the entity that helped make the transaction (wallet software, exchange company, etc). + mempool.space 仅提供有关比特币网络的数据。它无法帮助您检索资金、解决钱包问题等。对于任何此类请求,您都需要联系帮助进行交易的实体(钱包软件、交易所等)。 src/app/docs/api-docs/api-docs.component.html 15,16 @@ -6657,6 +6675,7 @@ 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. + 获取常见问题的答案,例如:什么是Mempool?为什么我的交易未被确认?如何运行自己的Mempool开源项目实例?等等。 src/app/docs/docs/docs.component.ts 47 @@ -6685,6 +6704,7 @@ WebSocket API + Websocket API src/app/docs/docs/docs.component.ts 59 @@ -7764,6 +7784,7 @@ Overview for the Lightning network node named . See channels, capacity, location, fee stats, and more. + 闪电网络节点 的概览。查看通道、容量、位置、费用统计等。 src/app/lightning/node/node-preview.component.ts 52 @@ -7962,6 +7983,7 @@ See the channels of non-Tor Lightning network nodes visualized on a world map. Hover/tap on points on the map for node names and details. + 在世界地图上查看非Tor的闪电网络节点的通道。将鼠标悬停/点击地图上的点可查看节点名称和详细信息。 src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts 74 @@ -7986,6 +8008,7 @@ See the locations of non-Tor Lightning network nodes visualized on a world map. Hover/tap on points on the map for node names and details. + 在世界地图上查看非 Tor的闪电网络节点的通道。将鼠标悬停/点击地图上的点可查看节点名称和详细信息。 src/app/lightning/nodes-map/nodes-map.component.ts 52 @@ -8061,6 +8084,7 @@ See a geographical breakdown of the Lightning network: how many Lightning nodes are hosted in countries around the world, aggregate BTC capacity for each country, and more. + 查看闪电网络的地理分布:世界各国托管着多少个闪电节点、每个国家的总 BTC 容量等等。 src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts 47 @@ -8131,6 +8155,7 @@ Explore all the Lightning nodes hosted in and see an overview of each node's capacity, number of open channels, and more. + 探索 中托管的所有 Lightning 节点,并查看每个节点的容量、开放通道数量等概览。 src/app/lightning/nodes-per-country/nodes-per-country.component.ts 44 @@ -8480,6 +8505,7 @@ What is a mempool? + 什么是mempool? src/app/shared/components/global-footer/global-footer.component.html 51 @@ -8488,6 +8514,7 @@ What is a block explorer? + 什么是区块浏览器? src/app/shared/components/global-footer/global-footer.component.html 52 @@ -8496,6 +8523,7 @@ What is a mempool explorer? + 什么是内存池浏览器? src/app/shared/components/global-footer/global-footer.component.html 53 @@ -8528,6 +8556,7 @@ Mainnet Explorer + 主网浏览器 src/app/shared/components/global-footer/global-footer.component.html 60 @@ -8536,6 +8565,7 @@ Testnet Explorer + 测试网浏览器 src/app/shared/components/global-footer/global-footer.component.html 61 @@ -8568,6 +8598,7 @@ Tools + 工具 src/app/shared/components/global-footer/global-footer.component.html 68 diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index f38d25bf1..9d246e8dd 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -1,14 +1,25 @@ +/* Theme */ +$bg: #1d1f31; +$active-bg: #11131f; +$hover-bg: #12131e; +$fg: #fff; +$title-fg: #4a68b9; + +$taproot: #eba814; +$taproot-light: #d5a90a; +$taproot-dark: #9d7c05; + /* Bootstrap */ +$body-bg: $bg; +$body-color: $fg; +$gray-800: $bg; +$gray-700: $fg; -$body-bg: #1d1f31; -$body-color: #fff; -$gray-800: #1d1f31; -$gray-700: #fff; - -$nav-tabs-link-active-bg: #11131f; +$nav-tabs-link-active-bg: $active-bg; $primary: #105fb0; $secondary: #2d3348; +$tertiary: #653b9c; $success: #1a9436; $info: #1bd8f4; @@ -16,45 +27,87 @@ $h5-font-size: 1.15rem !default; $pagination-bg: $body-bg; $pagination-border-color: $gray-800; -$pagination-disabled-bg: #FFF; -$pagination-disabled-border-color: #1d1f31; -$pagination-active-color: #fff; -$pagination-active-bg: #653b9c; -$pagination-hover-bg: #12131e; -$pagination-hover-border-color: #1d1f31; -$pagination-disabled-bg: #1d1f31; +$pagination-disabled-bg: $fg; +$pagination-disabled-border-color: $bg; +$pagination-active-color: $fg; +$pagination-active-bg: $tertiary; +$pagination-hover-bg: $hover-bg; +$pagination-hover-border-color: $bg; +$pagination-disabled-bg: $bg; -$custom-select-indicator-color: #FFF; +$custom-select-indicator-color: $fg; .input-group-text { background-color: #1c2031 !important; border: 1px solid #20263e !important; } -$link-color: #1bd8f4; +$link-color: $info; $link-decoration: none !default; $link-hover-color: darken($link-color, 15%) !default; $link-hover-decoration: underline !default; -$dropdown-bg: #1d1f31; -$dropdown-link-color: #fff; +$dropdown-bg: $bg; +$dropdown-link-color: $fg; -$dropdown-link-hover-color: #fff; -$dropdown-link-hover-bg: #11131f; +$dropdown-link-hover-color: $fg; +$dropdown-link-hover-bg: $active-bg; -$dropdown-link-active-color: #fff; -$dropdown-link-active-bg: #11131f; +$dropdown-link-active-color: $fg; +$dropdown-link-active-bg: $active-bg; @import "bootstrap/scss/bootstrap"; @import 'tlite/tlite.css'; +:root { + --bg: #{$bg}; + --active-bg: #{$active-bg}; + --hover-bg: #{$hover-bg}; + --fg: #{$fg}; + --color-fg: #ffffff; + --title-fg: #{$title-fg}; + + --primary: #{$primary}; + --secondary: #{$secondary}; + --tertiary: #{$tertiary}; + --success: #{$success}; + --info: #{$info}; + + --box-bg: #24273e; + --stat-box-bg: #181b2d; + --alert-bg: #3a1c61; + --navbar-bg: #212121; + --transparent-fg: #ffffff66; + --fade-out-box-bg-start: rgba(36, 39, 62, 0); + --fade-out-box-bg-end: rgba(36, 39, 62, 1); + + --testnet: #1d486f; + --signet: #6f1d5d; + --liquid: #116761; + --liquidtestnet: #494a4a; + + --mainnet-alt: #9339f4; + --testnet-alt: #183550; + --signet-alt: #471850; + --liquidtestnet-alt: #272e46; + + --taproot: #eba814; + --taproot-light: #d5a90a; + --taproot-dark: #9d7c05; + + --green: #3bcc49; + --red: #dc3545; + --yellow: #ffd800; + --grey: #6c757d; + --tooltip-grey: #b1b1b1; +} + html, body { height: 100%; } body { - background-color: #11131f; - min-width: 375px; + background-color: var(--active-bg); padding-bottom: 60px; } @@ -82,7 +135,7 @@ main { position: relative; min-width: 0; word-wrap: break-word; - background-color: #24273e; + background-color: var(--box-bg); background-clip: border-box; border: 1px solid rgba(0,0,0,.125); box-shadow: 0.125rem 0.125rem 0.25rem rgba(0,0,0,0.075); @@ -100,35 +153,35 @@ main { } .navbar-nav.liquid > .active { - background-color: #116761 !important; + background-color: var(--liquid) !important; } .navbar-nav.testnet > .active { - background-color: #1d486f !important; + background-color: var(--testnet) !important; } .navbar-nav.signet > .active { - background-color: #6f1d5d !important; + background-color: var(--signet) !important; } .navbar-nav.liquidtestnet > .active { - background-color: #494a4a !important; + background-color: var(--liquidtestnet) !important; } .form-control { color: #fff; - background-color: #2d3348; + background-color: var(--secondary); border: 1px solid rgba(17, 19, 31, 0.2); } .form-control:focus { color: #fff; - background-color: #2d3348; + background-color: var(--secondary); } .btn-purple { - background-color: #653b9c; - border-color: #653b9c; + background-color: var(--tertiary); + border-color: var(--tertiary); } .btn-purple:not(:disabled):not(.disabled):active, .btn-purple:not(:disabled):not(.disabled).active, .show > .btn-purple.dropdown-toggle { @@ -151,12 +204,12 @@ main { } .form-control.form-control-secondary { - color: #fff; - background-color: #2d3348; - border: 1px solid #2d3348; + color: var(--fg); + background-color: var(--secondary); + border: 1px solid var(--secondary); } .form-control.form-control-secondary:focus { - color: #fff; + color: var(--fg); } .h2-match-table { @@ -210,20 +263,20 @@ main { } .symbol { - color: #ffffff66; + color: var(--transparent-fg); font-size: 12px; } .progress-text { span { - color: #fff !important; + color: var(--fg) !important; } } .block-size, .blocks-container { .symbol { font-size: 16px; - color: #fff !important; + color: var(--fg) !important; } } @@ -233,17 +286,17 @@ main { } .title-block { - color: #FFF; + color: var(--fg); padding-top: 20px; padding-bottom: 10px; - border-top: 3px solid #FFF; + border-top: 3px solid var(--fg); display: flex; flex-direction: row; justify-content: space-between; } .title-address, .title-asset { - color: #FFF; + color: var(--fg); padding-bottom: 10px; display: flex; flex-direction: column; @@ -282,11 +335,11 @@ main { } .close { - color: #fff; + color: var(--fg); } .close:hover { - color: #fff; + color: var(--fg); } .white-color { @@ -294,19 +347,19 @@ main { } .green-color { - color: #3bcc49; + color: var(--green); } .red-color { - color: #dc3545; + color: var(--red); } .yellow-color { - color: #ffd800; + color: var(--yellow); } .table-striped tbody tr:nth-of-type(odd) { - background-color: #181b2d; + background-color: var(--stat-box-bg); } .bordertop { @@ -334,10 +387,10 @@ html:lang(ru) .card-title { .tx-wrapper-tooltip-chart, .fees-wrapper-tooltip-chart { - background: rgba(#11131f, 0.95); + background: rgba($active-bg, 0.95); border-radius: 4px; box-shadow: 1px 1px 10px rgba(0,0,0,0.5); - color: #b1b1b1; + color: var(--tooltip-grey); display: flex; flex-direction: column; justify-content: space-between; @@ -347,7 +400,7 @@ html:lang(ru) .card-title { thead { th { font-size: 9px; - color: #b1b1b1; + color: var(--tooltip-grey); text-align: right; &:first-child { text-align: left; @@ -363,7 +416,7 @@ html:lang(ru) .card-title { font-size: 12px; font-weight: 700; margin-bottom: 2px; - color: #fff; + color: var(--fg); .total-value { float: right; } @@ -422,7 +475,7 @@ html:lang(ru) .card-title { .total-label { width: 100%; text-align: left; - color: #fff; + color: var(--fg); margin-top: 5px; font-size: 14px; span { @@ -438,7 +491,7 @@ html:lang(ru) .card-title { thead { th { font-size: 9px; - color: #b1b1b1; + color: var(--tooltip-grey); text-align: right; &:first-child { text-align: left; @@ -518,8 +571,8 @@ html:lang(ru) .card-title { .fees-wrapper-tooltip-chart-advanced, .tx-wrapper-tooltip-chart-advanced { - background: rgba(#1d1f31, 0.98); width: 300px; + background: rgba($bg, 0.98); thead { th { @@ -673,27 +726,27 @@ h1, h2, h3 { } .progress-mempool { - background: repeating-linear-gradient(to right, #2d3348, #2d3348 0%, #105fb0 0%, #9339f4 100%); + background: repeating-linear-gradient(to right, $secondary, $secondary 0%, $primary 0%, var(--mainnet-alt) 100%); } .progress-mempool.testnet { - background: repeating-linear-gradient(to right, #2d3348, #2d3348 0%, #1d486f 0%, #183550 100%); + background: repeating-linear-gradient(to right, $secondary, $secondary 0%, var(--testnet) 0%, var(--testnet-alt) 100%); } .progress-mempool.signet { - background: repeating-linear-gradient(to right, #2d3348, #2d3348 0%, #6f1d5d 0%, #471850 100%); + background: repeating-linear-gradient(to right, $secondary, $secondary 0%, var(--signet) 0%, var(--signet-alt) 100%); } .progress-mempool.liquid { - background: repeating-linear-gradient(to right, #2d3348, #2d3348 0%, #116761 0%, #183550 100%); + background: repeating-linear-gradient(to right, $secondary, $secondary 0%, var(--liquid) 0%, var(--testnet-alt) 100%); } .progress-dark { - background-color: #181b2d; + background-color: var(--stat-box-bg); } .progress-darklight { - background-color: #24273e; + background-color: var(--box-bg); } .progress-light { @@ -701,12 +754,12 @@ h1, h2, h3 { } .progress.progress-health { - background: repeating-linear-gradient(to right, #2d3348, #2d3348 0%, #105fb0 0%, #1a9436 100%); + background: repeating-linear-gradient(to right, $secondary, $secondary 0%, $primary 0%, $success 100%); justify-content: flex-end; } .progress-bar.progress-bar-health { - background: #2d3348; + background: var(--secondary); } .mt-2-5, .my-2-5 { @@ -714,9 +767,9 @@ h1, h2, h3 { } .alert-mempool { - color: #ffffff; - background-color: #653b9c; - border-color: #3a1c61; + color: var(--fg); + background-color: var(--tertiary); + border-color: var(--alert-bg); width: 100%; display: inline-flex; flex-direction: column; @@ -1082,7 +1135,7 @@ th { display: block; width: 100%; padding: 1rem 2rem; - color: #fff; + color: var(--fg); font-weight: bold; &:focus, &:hover, &:active { text-decoration: none; @@ -1096,8 +1149,8 @@ th { } .collapsed { - background-color: #2d3348; - color: #1bd8f4; + background-color: var(--secondary); + color: var(--info); } } @@ -1115,7 +1168,7 @@ th { display: inline-block; width: 100%; justify-content: space-between; - background: #1d1f31; + background: var(--bg); margin: 0; @media (min-width: 550px) { width: auto; @@ -1141,21 +1194,21 @@ th { // Blinking block @keyframes shadowyBackground { 0% { - box-shadow: -10px -15px 75px rgba(#eba814, 1); + box-shadow: -10px -15px 75px rgba($taproot, 1); } 50% { - box-shadow: -10px -15px 75px rgba(#eba814, .3); + box-shadow: -10px -15px 75px rgba($taproot, .3); } 100% { - box-shadow: -10px -15px 75px rgba(#eba814, 1); + box-shadow: -10px -15px 75px rgba($taproot, 1); } } .blink-bg { - color: #fff; - background: repeating-linear-gradient(#9d7c05, #9d7c05 0.163525%, #d5a90a 100%) !important; + color: var(--fg); + background: repeating-linear-gradient($taproot-dark, $taproot-dark 0.163525%, $taproot-light 100%) !important; animation: shadowyBackground 1s infinite; - box-shadow: -10px -15px 75px rgba(#eba814, 1); + box-shadow: -10px -15px 75px rgba($taproot, 1); transition: 100ms all ease-in; } diff --git a/frontend/src/theme-contrast.scss b/frontend/src/theme-contrast.scss new file mode 100644 index 000000000..6c5023466 --- /dev/null +++ b/frontend/src/theme-contrast.scss @@ -0,0 +1,100 @@ +/* Theme */ +$bg: #11131f; +$active-bg: #000000; +$hover-bg: #12131e; +$fg: #fff; +$title-fg: #2055e3; + +$taproot: #eba814; +$taproot-light: #d5a90a; +$taproot-dark: #9d7c05; + +/* Bootstrap */ +$body-bg: $bg; +$body-color: $fg; +$gray-800: $bg; +$gray-700: $fg; + +$nav-tabs-link-active-bg: $active-bg; + +$primary: #007cfa; +$secondary: #272f4e; +$tertiary: #6225b2; +$success: #0aab2f; +$info: #10e0ff; + +$h5-font-size: 1.15rem !default; + +$pagination-bg: $body-bg; +$pagination-border-color: $gray-800; +$pagination-disabled-bg: $fg; +$pagination-disabled-border-color: $bg; +$pagination-active-color: $fg; +$pagination-active-bg: $tertiary; +$pagination-hover-bg: $hover-bg; +$pagination-hover-border-color: $bg; +$pagination-disabled-bg: $bg; + +$custom-select-indicator-color: $fg; + +.input-group-text { + background-color: #1c2031 !important; + border: 1px solid #20263e !important; +} + +$link-color: $info; +$link-decoration: none !default; +$link-hover-color: darken($link-color, 15%) !default; +$link-hover-decoration: underline !default; + +$dropdown-bg: $bg; +$dropdown-link-color: $fg; + +$dropdown-link-hover-color: $fg; +$dropdown-link-hover-bg: $active-bg; + +$dropdown-link-active-color: $fg; +$dropdown-link-active-bg: $active-bg; + +:root { + --bg: #{$bg}; + --active-bg: #{$active-bg}; + --hover-bg: #{$hover-bg}; + --fg: #{$fg}; + --color-fg: #fff; + --title-fg: #{$title-fg}; + + --primary: #{$primary}; + --secondary: #{$secondary}; + --tertiary: #{$tertiary}; + --success: #{$success}; + --info: #{$info}; + + --box-bg: #171c2a; + --stat-box-bg: #0b1018; + --alert-bg: #3a1c61; + --navbar-bg: #212121; + --transparent-fg: #ffffffbb; + --fade-out-box-bg-start: rgba(23, 28, 42, 0); + --fade-out-box-bg-end: rgba(23, 28, 42, 1); + + --testnet: #1d486f; + --signet: #6f1d5d; + --liquid: #116761; + --liquidtestnet: #494a4a; + + --mainnet-alt: #9339f4; + --testnet-alt: #183550; + --signet-alt: #471850; + --liquidtestnet-alt: #272e46; + + --taproot: #eba814; + --taproot-light: #d5a90a; + --taproot-dark: #9d7c05; + + --green: #83fd00; + --red: #ff3d00; + --yellow: #ffcc00; + --grey: #7e7e7e; + --tooltip-grey: #b1b1b1; +}