Fix block overview graph on contrast theme

This commit is contained in:
natsoni 2024-04-05 18:36:32 +09:00
parent 621a6ea42d
commit cde3d878b1
No known key found for this signature in database
GPG Key ID: C65917583181743B
5 changed files with 48 additions and 95 deletions

View File

@ -9,7 +9,7 @@ import { Price } from '../../services/price.service';
import { StateService } from '../../services/state.service'; import { StateService } from '../../services/state.service';
import { ThemeService } from 'src/app/services/theme.service'; import { ThemeService } from 'src/app/services/theme.service';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { defaultColorFunction, setOpacity, defaultFeeColors, defaultAuditFeeColors, defaultMarginalFeeColors, defaultAuditColors } from './utils'; import { defaultColorFunction, setOpacity, defaultFeeColors, defaultAuditFeeColors, defaultMarginalFeeColors, defaultAuditColors, contrastFeeColors, contrastAuditFeeColors, contrastMarginalFeeColors, contrastAuditColors, contrastColorFunction } from './utils';
import { ActiveFilter, FilterMode, toFlags } from '../../shared/filters.utils'; import { ActiveFilter, FilterMode, toFlags } from '../../shared/filters.utils';
import { detectWebGL } from '../../shared/graphs.utils'; import { detectWebGL } from '../../shared/graphs.utils';
@ -24,6 +24,16 @@ const unmatchedAuditColors = {
prioritized: setOpacity(defaultAuditColors.prioritized, unmatchedOpacity), prioritized: setOpacity(defaultAuditColors.prioritized, unmatchedOpacity),
accelerated: setOpacity(defaultAuditColors.accelerated, 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),
added: setOpacity(contrastAuditColors.added, unmatchedOpacity),
prioritized: setOpacity(contrastAuditColors.prioritized, unmatchedOpacity),
accelerated: setOpacity(contrastAuditColors.accelerated, unmatchedOpacity),
};
@Component({ @Component({
selector: 'app-block-overview-graph', selector: 'app-block-overview-graph',
@ -108,8 +118,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
this.initCanvas(); this.initCanvas();
this.resizeCanvas(); this.resizeCanvas();
this.themeChangedSubscription = this.themeService.themeChanged$.subscribe(() => { this.themeChangedSubscription = this.themeService.themeChanged$.subscribe(() => {
// force full re-render this.scene.setColorFunction(this.getColorFunction());
this.resizeCanvas();
}); });
} }
} }
@ -567,9 +576,15 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
getFilterColorFunction(flags: bigint): ((tx: TxView) => Color) { getFilterColorFunction(flags: bigint): ((tx: TxView) => Color) {
return (tx: TxView) => { return (tx: TxView) => {
if ((this.filterMode === 'and' && (tx.bigintFlags & flags) === flags) || (this.filterMode === 'or' && (flags === 0n || (tx.bigintFlags & flags) > 0n))) { if ((this.filterMode === 'and' && (tx.bigintFlags & flags) === flags) || (this.filterMode === 'or' && (flags === 0n || (tx.bigintFlags & flags) > 0n))) {
return defaultColorFunction(tx); return this.themeService.theme !== 'default' ? contrastColorFunction(tx) : defaultColorFunction(tx);
} else { } else {
return defaultColorFunction( return this.themeService.theme !== 'default' ? contrastColorFunction(
tx,
unmatchedContrastFeeColors,
unmatchedContrastAuditFeeColors,
unmatchedContrastMarginalFeeColors,
unmatchedContrastAuditColors
) : defaultColorFunction(
tx, tx,
unmatchedFeeColors, unmatchedFeeColors,
unmatchedAuditFeeColors, unmatchedAuditFeeColors,

View File

@ -2,7 +2,7 @@ import { FastVertexArray } from './fast-vertex-array';
import TxView from './tx-view'; import TxView from './tx-view';
import { TransactionStripped } from '../../interfaces/node-api.interface'; import { TransactionStripped } from '../../interfaces/node-api.interface';
import { Color, Position, Square, ViewUpdateParams } from './sprite-types'; import { Color, Position, Square, ViewUpdateParams } from './sprite-types';
import { defaultColorFunction } from './utils'; import { defaultColorFunction, contrastColorFunction } from './utils';
import { ThemeService } from 'src/app/services/theme.service'; import { ThemeService } from 'src/app/services/theme.service';
export default class BlockScene { export default class BlockScene {
@ -69,7 +69,7 @@ export default class BlockScene {
} }
setColorFunction(colorFunction: ((tx: TxView) => Color) | null): void { setColorFunction(colorFunction: ((tx: TxView) => Color) | null): void {
this.getColor = colorFunction || defaultColorFunction; this.theme.theme !== 'default' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction;
this.dirty = true; this.dirty = true;
if (this.initialised && this.scene) { if (this.initialised && this.scene) {
this.updateColors(performance.now(), 50); this.updateColors(performance.now(), 50);
@ -241,7 +241,7 @@ export default class BlockScene {
this.flip = flip; this.flip = flip;
this.vertexArray = vertexArray; this.vertexArray = vertexArray;
this.highlightingEnabled = highlighting; this.highlightingEnabled = highlighting;
this.getColor = colorFunction || defaultColorFunction; theme.theme !== 'default' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction;
this.theme = theme; this.theme = theme;
this.scene = { this.scene = {

View File

@ -145,7 +145,7 @@ export default class TxView implements TransactionStripped {
setHover(hoverOn: boolean, color: Color | void): number { setHover(hoverOn: boolean, color: Color | void): number {
if (hoverOn) { if (hoverOn) {
this.hover = true; this.hover = true;
this.hoverColor = color || this.theme.defaultHoverColor; this.hoverColor = color || defaultHoverColor;
this.sprite.update({ this.sprite.update({
...this.hoverColor, ...this.hoverColor,
@ -195,30 +195,4 @@ export default class TxView implements TransactionStripped {
this.dirty = false; this.dirty = false;
return performance.now() + hoverTransitionTime; return performance.now() + hoverTransitionTime;
} }
getColor(): Color {
const feeLevelIndex = feeLevels.findIndex((feeLvl) => Math.max(1, this.feerate) < feeLvl) - 1;
const feeLevelColor = this.theme.feeColors[feeLevelIndex] || this.theme.feeColors[this.theme.mempoolFeeColors.length - 1];
// Block audit
switch(this.status) {
case 'censored':
return this.theme.auditColors.censored;
case 'missing':
return this.theme.auditColors.missing;
case 'fresh':
return this.theme.auditColors.missing;
case 'added':
return this.theme.auditColors.added;
case 'selected':
return this.theme.auditColors.selected;
case 'found':
if (this.context === 'projected') {
return this.theme.auditFeeColors[feeLevelIndex] || this.theme.auditFeeColors[this.theme.mempoolFeeColors.length - 1];
} else {
return feeLevelColor;
}
default:
return feeLevelColor;
}
}
} }

View File

@ -1,4 +1,4 @@
import { feeLevels, defaultMempoolFeeColors } from '../../app.constants'; import { feeLevels, defaultMempoolFeeColors, contrastMempoolFeeColors } from '../../app.constants';
import { Color } from './sprite-types'; import { Color } from './sprite-types';
import TxView from './tx-view'; import TxView from './tx-view';
@ -46,7 +46,18 @@ export const defaultAuditColors = {
missing: darken(desaturate(hexToColor('f344df'), 0.3), 0.7), missing: darken(desaturate(hexToColor('f344df'), 0.3), 0.7),
added: hexToColor('0099ff'), added: hexToColor('0099ff'),
prioritized: darken(desaturate(hexToColor('0099ff'), 0.3), 0.7), prioritized: darken(desaturate(hexToColor('0099ff'), 0.3), 0.7),
accelerated: hexToColor('8F5FF6'), 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));
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( export function defaultColorFunction(
@ -100,4 +111,14 @@ export function defaultColorFunction(
return feeLevelColor; return feeLevelColor;
} }
} }
}
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);
} }

View File

@ -1,22 +1,8 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { audit, Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { Color } from '../components/block-overview-graph/sprite-types';
import { defaultMempoolFeeColors, contrastMempoolFeeColors } from '../app.constants'; import { defaultMempoolFeeColors, contrastMempoolFeeColors } from '../app.constants';
import { StorageService } from './storage.service'; import { StorageService } from './storage.service';
const defaultAuditColors = {
censored: hexToColor('f344df'),
missing: darken(desaturate(hexToColor('f344df'), 0.3), 0.7),
added: hexToColor('0099ff'),
selected: darken(desaturate(hexToColor('0099ff'), 0.3), 0.7),
};
const contrastAuditColors = {
censored: hexToColor('ffa8ff'),
missing: darken(desaturate(hexToColor('ffa8ff'), 0.3), 0.7),
added: hexToColor('00bb98'),
selected: darken(desaturate(hexToColor('00bb98'), 0.3), 0.7),
};
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
@ -26,12 +12,6 @@ export class ThemeService {
themeChanged$: Subject<string> = new Subject(); themeChanged$: Subject<string> = new Subject();
mempoolFeeColors: string[] = defaultMempoolFeeColors; mempoolFeeColors: string[] = defaultMempoolFeeColors;
/* block visualization colors */
defaultHoverColor: Color;
feeColors: Color[];
auditFeeColors: Color[];
auditColors: { [category: string]: Color } = defaultAuditColors;
constructor( constructor(
private storageService: StorageService, private storageService: StorageService,
) { ) {
@ -44,7 +24,6 @@ export class ThemeService {
if (theme !== 'default') { if (theme !== 'default') {
if (theme === 'contrast') { if (theme === 'contrast') {
this.mempoolFeeColors = contrastMempoolFeeColors; this.mempoolFeeColors = contrastMempoolFeeColors;
this.auditColors = contrastAuditColors;
} }
try { try {
if (!this.style) { if (!this.style) {
@ -60,48 +39,12 @@ export class ThemeService {
} }
} else { } else {
this.mempoolFeeColors = defaultMempoolFeeColors; this.mempoolFeeColors = defaultMempoolFeeColors;
this.auditColors = defaultAuditColors;
if (this.style) { if (this.style) {
this.style.remove(); this.style.remove();
this.style = null; this.style = null;
} }
} }
this.updateFeeColors();
this.storageService.setValue('theme-preference', theme); this.storageService.setValue('theme-preference', theme);
this.themeChanged$.next(this.theme); this.themeChanged$.next(this.theme);
} }
updateFeeColors() {
this.defaultHoverColor = hexToColor('1bd8f4');
this.feeColors = this.mempoolFeeColors.map(hexToColor);
this.auditFeeColors = this.feeColors.map((color) => darken(desaturate(color, 0.3), 0.9));
}
}
export function hexToColor(hex: string): Color {
return {
r: parseInt(hex.slice(0, 2), 16) / 255,
g: parseInt(hex.slice(2, 4), 16) / 255,
b: parseInt(hex.slice(4, 6), 16) / 255,
a: 1
};
}
export function desaturate(color: Color, amount: number): Color {
const gray = (color.r + color.g + color.b) / 6;
return {
r: color.r + ((gray - color.r) * amount),
g: color.g + ((gray - color.g) * amount),
b: color.b + ((gray - color.b) * amount),
a: color.a,
};
}
export function darken(color: Color, amount: number): Color {
return {
r: color.r * amount,
g: color.g * amount,
b: color.b * amount,
a: color.a,
}
} }