mirror of
https://github.com/mempool/mempool.git
synced 2025-06-01 18:49:44 +02:00
More contrast theme fixes
This commit is contained in:
parent
c251b5831b
commit
d68904fec0
@ -70,14 +70,14 @@ export const contrastMempoolFeeColors = [
|
||||
'edac31',
|
||||
'f6ad2b',
|
||||
'ffaf24',
|
||||
'ffaf24',
|
||||
'ffaf24',
|
||||
'ffaf24',
|
||||
'ffaf24',
|
||||
'ffaf24',
|
||||
'ffaf24',
|
||||
'ffaf24',
|
||||
'ffaf24',
|
||||
'ffb01e',
|
||||
'ffb118',
|
||||
'ffb212',
|
||||
'ffb30c',
|
||||
'ffb406',
|
||||
'ffb500',
|
||||
'ffb600',
|
||||
'ffb700',
|
||||
];
|
||||
|
||||
export const chartColors = [
|
||||
|
@ -9,7 +9,7 @@ import { Price } from '../../services/price.service';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { ThemeService } from 'src/app/services/theme.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { defaultColorFunction, setOpacity, defaultFeeColors, defaultAuditFeeColors, defaultMarginalFeeColors, defaultAuditColors } 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';
|
||||
|
||||
@ -21,9 +21,6 @@ const unmatchedAuditColors = {
|
||||
prioritized: setOpacity(defaultAuditColors.prioritized, unmatchedOpacity),
|
||||
accelerated: setOpacity(defaultAuditColors.accelerated, unmatchedOpacity),
|
||||
};
|
||||
const unmatchedContrastFeeColors = contrastFeeColors.map(c => setOpacity(c, unmatchedOpacity));
|
||||
const unmatchedContrastAuditFeeColors = contrastAuditFeeColors.map(c => setOpacity(c, unmatchedOpacity));
|
||||
const unmatchedContrastMarginalFeeColors = contrastMarginalFeeColors.map(c => setOpacity(c, unmatchedOpacity));
|
||||
const unmatchedContrastAuditColors = {
|
||||
censored: setOpacity(contrastAuditColors.censored, unmatchedOpacity),
|
||||
missing: setOpacity(contrastAuditColors.missing, unmatchedOpacity),
|
||||
@ -580,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 defaultColorFunction(tx);
|
||||
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 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)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -69,7 +69,11 @@ 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();
|
||||
}
|
||||
|
||||
updateAllColors(): void {
|
||||
this.dirty = true;
|
||||
if (this.initialised && this.scene) {
|
||||
this.updateColors(performance.now(), 50);
|
||||
@ -92,7 +96,7 @@ export default class BlockScene {
|
||||
});
|
||||
this.layout = new BlockLayout({ width: this.gridWidth, height: this.gridHeight });
|
||||
txs.forEach(tx => {
|
||||
const txView = new TxView(tx, this, this.theme);
|
||||
const txView = new TxView(tx, this);
|
||||
this.txs[tx.txid] = txView;
|
||||
this.place(txView);
|
||||
this.saveGridToScreenPosition(txView);
|
||||
@ -138,7 +142,7 @@ export default class BlockScene {
|
||||
});
|
||||
txs.forEach(tx => {
|
||||
if (!this.txs[tx.txid]) {
|
||||
this.txs[tx.txid] = new TxView(tx, this, this.theme);
|
||||
this.txs[tx.txid] = new TxView(tx, this);
|
||||
}
|
||||
});
|
||||
|
||||
@ -180,7 +184,7 @@ export default class BlockScene {
|
||||
if (resetLayout) {
|
||||
add.forEach(tx => {
|
||||
if (!this.txs[tx.txid]) {
|
||||
this.txs[tx.txid] = new TxView(tx, this, this.theme);
|
||||
this.txs[tx.txid] = new TxView(tx, this);
|
||||
}
|
||||
});
|
||||
this.layout = new BlockLayout({ width: this.gridWidth, height: this.gridHeight });
|
||||
@ -200,7 +204,7 @@ export default class BlockScene {
|
||||
|
||||
// try to insert new txs directly
|
||||
const remaining = [];
|
||||
add.map(tx => new TxView(tx, this, this.theme)).sort(feeRateDescending).forEach(tx => {
|
||||
add.map(tx => new TxView(tx, this)).sort(feeRateDescending).forEach(tx => {
|
||||
if (!this.tryInsertByFee(tx)) {
|
||||
remaining.push(tx);
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import { hexToColor } from './utils';
|
||||
import BlockScene from './block-scene';
|
||||
import { TransactionStripped } from '../../interfaces/node-api.interface';
|
||||
import { TransactionFlags } from '../../shared/filters.utils';
|
||||
import { feeLevels } from '../../app.constants';
|
||||
import { ThemeService } from 'src/app/services/theme.service';
|
||||
|
||||
const hoverTransitionTime = 300;
|
||||
const defaultHoverColor = hexToColor('1bd8f4');
|
||||
@ -38,7 +36,6 @@ export default class TxView implements TransactionStripped {
|
||||
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'prioritized' | 'censored' | 'selected' | 'rbf' | 'accelerated';
|
||||
context?: 'projected' | 'actual';
|
||||
scene?: BlockScene;
|
||||
theme: ThemeService;
|
||||
|
||||
initialised: boolean;
|
||||
vertexArray: FastVertexArray;
|
||||
@ -53,7 +50,7 @@ export default class TxView implements TransactionStripped {
|
||||
|
||||
dirty: boolean;
|
||||
|
||||
constructor(tx: TransactionStripped, scene: BlockScene, theme: ThemeService) {
|
||||
constructor(tx: TransactionStripped, scene: BlockScene) {
|
||||
this.scene = scene;
|
||||
this.context = tx.context;
|
||||
this.txid = tx.txid;
|
||||
@ -69,7 +66,6 @@ export default class TxView implements TransactionStripped {
|
||||
this.bigintFlags = tx.flags ? (BigInt(tx.flags) | (this.acc ? TransactionFlags.acceleration : 0n)): 0n;
|
||||
this.initialised = false;
|
||||
this.vertexArray = scene.vertexArray;
|
||||
this.theme = theme;
|
||||
|
||||
this.hover = false;
|
||||
|
||||
@ -142,10 +138,10 @@ export default class TxView implements TransactionStripped {
|
||||
|
||||
// Temporarily override the tx color
|
||||
// returns minimum transition end time
|
||||
setHover(hoverOn: boolean, color: Color | void): number {
|
||||
setHover(hoverOn: boolean, color: Color | void = defaultHoverColor): number {
|
||||
if (hoverOn) {
|
||||
this.hover = true;
|
||||
this.hoverColor = color || defaultHoverColor;
|
||||
this.hoverColor = color;
|
||||
|
||||
this.sprite.update({
|
||||
...this.hoverColor,
|
||||
|
@ -45,9 +45,28 @@ interface ColorPalette {
|
||||
}
|
||||
|
||||
// precomputed colors
|
||||
export const defaultFeeColors = mempoolFeeColors.map(hexToColor);
|
||||
export const defaultAuditFeeColors = defaultFeeColors.map((color) => darken(desaturate(color, 0.3), 0.9));
|
||||
export const defaultMarginalFeeColors = defaultFeeColors.map((color) => darken(desaturate(color, 0.8), 1.1));
|
||||
const defaultColors: { [key: string]: ColorPalette } = {
|
||||
fee: {
|
||||
base: defaultMempoolFeeColors.map(hexToColor),
|
||||
audit: [],
|
||||
marginal: [],
|
||||
baseLevel: (tx: TxView, rate: number) => feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1
|
||||
},
|
||||
}
|
||||
for (const key in defaultColors) {
|
||||
const base = defaultColors[key].base;
|
||||
defaultColors[key].audit = base.map((color) => darken(desaturate(color, 0.3), 0.9));
|
||||
defaultColors[key].marginal = base.map((color) => darken(desaturate(color, 0.8), 1.1));
|
||||
defaultColors['unmatched' + key] = {
|
||||
base: defaultColors[key].base.map(c => setOpacity(c, 0.2)),
|
||||
audit: defaultColors[key].audit.map(c => setOpacity(c, 0.2)),
|
||||
marginal: defaultColors[key].marginal.map(c => setOpacity(c, 0.2)),
|
||||
baseLevel: defaultColors[key].baseLevel,
|
||||
};
|
||||
}
|
||||
|
||||
export { defaultColors as defaultColors };
|
||||
|
||||
export const defaultAuditColors = {
|
||||
censored: hexToColor('f344df'),
|
||||
missing: darken(desaturate(hexToColor('f344df'), 0.3), 0.7),
|
||||
@ -56,9 +75,28 @@ export const defaultAuditColors = {
|
||||
accelerated: hexToColor('8f5ff6'),
|
||||
};
|
||||
|
||||
export const contrastFeeColors = contrastMempoolFeeColors.map(hexToColor);
|
||||
export const contrastAuditFeeColors = contrastFeeColors.map((color) => darken(desaturate(color, 0.3), 0.9));
|
||||
export const contrastMarginalFeeColors = contrastFeeColors.map((color) => darken(desaturate(color, 0.8), 1.1));
|
||||
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),
|
||||
@ -74,8 +112,8 @@ export function defaultColorFunction(
|
||||
relativeTime?: number,
|
||||
): Color {
|
||||
const rate = tx.fee / tx.vsize; // color by simple single-tx fee rate
|
||||
const feeLevelIndex = feeLevels.findIndex((feeLvl) => Math.max(1, rate) < feeLvl) - 1;
|
||||
const feeLevelColor = feeColors[feeLevelIndex] || feeColors[mempoolFeeColors.length - 1];
|
||||
const levelIndex = colors.baseLevel(tx, rate, relativeTime || (Date.now() / 1000));
|
||||
const levelColor = colors.base[levelIndex] || colors.base[defaultMempoolFeeColors.length - 1];
|
||||
// Normal mode
|
||||
if (!tx.scene?.highlightingEnabled) {
|
||||
if (tx.acc) {
|
||||
@ -92,7 +130,7 @@ export function defaultColorFunction(
|
||||
case 'missing':
|
||||
case 'sigop':
|
||||
case 'rbf':
|
||||
return marginalFeeColors[feeLevelIndex] || marginalFeeColors[mempoolFeeColors.length - 1];
|
||||
return colors.marginal[levelIndex] || colors.marginal[defaultMempoolFeeColors.length - 1];
|
||||
case 'fresh':
|
||||
case 'freshcpfp':
|
||||
return auditColors.missing;
|
||||
@ -101,12 +139,12 @@ export function defaultColorFunction(
|
||||
case 'prioritized':
|
||||
return auditColors.prioritized;
|
||||
case 'selected':
|
||||
return marginalFeeColors[feeLevelIndex] || marginalFeeColors[mempoolFeeColors.length - 1];
|
||||
return colors.marginal[levelIndex] || colors.marginal[defaultMempoolFeeColors.length - 1];
|
||||
case 'accelerated':
|
||||
return auditColors.accelerated;
|
||||
case 'found':
|
||||
if (tx.context === 'projected') {
|
||||
return auditFeeColors[feeLevelIndex] || auditFeeColors[mempoolFeeColors.length - 1];
|
||||
return colors.audit[levelIndex] || colors.audit[defaultMempoolFeeColors.length - 1];
|
||||
} else {
|
||||
return levelColor;
|
||||
}
|
||||
@ -119,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 {
|
||||
@ -139,13 +187,3 @@ export function ageColorFunction(
|
||||
a: color.a * (1 - ageLevel)
|
||||
};
|
||||
}
|
||||
|
||||
export function contrastColorFunction(
|
||||
tx: TxView,
|
||||
feeColors: Color[] = contrastFeeColors,
|
||||
auditFeeColors: Color[] = contrastAuditFeeColors,
|
||||
marginalFeeColors: Color[] = contrastMarginalFeeColors,
|
||||
auditColors: { [status: string]: Color } = contrastAuditColors
|
||||
): Color {
|
||||
return defaultColorFunction(tx, feeColors, auditFeeColors, marginalFeeColors, auditColors);
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
height: 100%;
|
||||
|
||||
.face {
|
||||
fill: #11131f;
|
||||
fill: var(--active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ export class LbtcPegsGraphComponent implements OnInit, OnChanges {
|
||||
type: 'line',
|
||||
},
|
||||
formatter: (params: any) => {
|
||||
const colorSpan = (color: string) => `<span class="indicator" style="background-color: var(--liquid);"></span>`;
|
||||
const colorSpan = (color: string) => `<span class="indicator" style="background-color: ${color};"></span>`;
|
||||
let itemFormatted = '<div class="title">' + params[0].axisValue + '</div>';
|
||||
for (let index = params.length - 1; index >= 0; index--) {
|
||||
const item = params[index];
|
||||
@ -137,7 +137,7 @@ export class LbtcPegsGraphComponent implements OnInit, OnChanges {
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dotted',
|
||||
color: 'var(--transparent-fg)',
|
||||
color: '#ffffff66',
|
||||
opacity: 0.25,
|
||||
}
|
||||
}
|
||||
@ -153,11 +153,11 @@ export class LbtcPegsGraphComponent implements OnInit, OnChanges {
|
||||
showSymbol: false,
|
||||
areaStyle: {
|
||||
opacity: 0.2,
|
||||
color: 'var(--liquid)',
|
||||
color: '#116761',
|
||||
},
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
color: 'var(--liquid)',
|
||||
color: '#116761',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user