Analytics for themes

This commit is contained in:
Borys Levytskyi
2025-11-11 08:57:57 -05:00
parent f0fefd6546
commit 8751fbaeda
2 changed files with 60 additions and 45 deletions

View File

@@ -21,7 +21,8 @@ export type CommandResultView = {
view: ViewFactory
};
export type AppStateChangeHandler = (state: AppState) => void;
export type AppStateAttribute = keyof AppState;
export type AppStateChangeHandler = (state: AppState, attribute : AppStateAttribute) => void;
type ViewFactory = () => JSX.Element;
@@ -65,12 +66,12 @@ export default class AppState {
const key = generateKey();
this.commandResults.unshift({ key, input, view });
log.debug(`command result added: ${input}`);
this.triggerChanged();
this.triggerChanged('commandResults');
}
clearCommandResults() {
this.commandResults = [];
this.triggerChanged();
this.triggerChanged('commandResults');
}
removeResult(index: number) {
@@ -78,68 +79,72 @@ export default class AppState {
return;
this.commandResults.splice(index, 1);
this.triggerChanged();
this.triggerChanged('commandResults');
}
toggleEmphasizeBytes(value?: boolean) {
this.emphasizeBytes = value !== null && value !== undefined ? value : !this.emphasizeBytes;
this.triggerChanged();
this.triggerChanged('emphasizeBytes');
}
onChange(handler: AppStateChangeHandler) {
this.changeHandlers.push(handler);
}
triggerChanged() {
this.changeHandlers.forEach(h => h(this));
triggerChanged(attribute: AppStateAttribute) {
this.changeHandlers.forEach(h => h(this, attribute));
}
setUiTheme(theme: string) {
if(this.uiTheme === theme)
return;
this.uiTheme = theme;
this.triggerChanged();
this.triggerChanged('uiTheme');
}
toggleDebugMode() {
this.debugMode = !this.debugMode;
this.triggerChanged();
this.triggerChanged('debugMode');
}
toggleShowSettings() {
this.showSettings = !this.showSettings;
this.triggerChanged();
this.triggerChanged('showSettings');
}
toggleAnnotateTypes(value?: boolean) {
this.annotateTypes = value !== null && value !== undefined ? value : !this.annotateTypes;
this.triggerChanged();
this.triggerChanged('annotateTypes');
}
toggleDimExtrBits() {
this.dimExtraBits = !this.dimExtraBits;
this.triggerChanged();
this.triggerChanged('dimExtraBits');
}
toggleCenteredLayout(value?: boolean) {
this.centeredLayout = value !== null && value !== undefined ? value : !this.centeredLayout;
this.triggerChanged();
this.triggerChanged('centeredLayout');
}
registerVisit() {
this.pageVisitsCount++;
this.triggerChanged();
this.triggerChanged('pageVisitsCount');
}
onDonationClicked(): boolean {
if (this.donationClicked === true) return false;
this.donationClicked = true;
this.triggerChanged();
this.triggerChanged('donationClicked');
return true;
}
setCookieDisclaimerHidden(value: boolean) {
this.cookieDisclaimerHidden = value;
this.triggerChanged();
this.triggerChanged('cookieDisclaimerHidden');
}
getPersistData(): PersistedAppData {

View File

@@ -25,10 +25,7 @@ const shellModule = {
cmd.command("light", () => appState.setUiTheme('light'));
cmd.command("midnight", () => appState.setUiTheme('midnight'));
cmd.command("settings", () => appState.toggleShowSettings());
cmd.command("bladerunner", () => {
appState.setUiTheme('bladerunner');
sendAnalyticsEvent({eventCategory: "UI", eventAction: "ThemeChanged", eventLabel: "bladerunner"});
});
cmd.command("bladerunner", () => appState.setUiTheme('bladerunner'));
cmd.command("bladerunner-easter", (c: CommandInput) => {
document.querySelector('.app-root')!.scrollTo(0, 0);
cmd.execute("bladerunner");
@@ -71,18 +68,38 @@ const shellModule = {
});
if(appState.env !== 'prod') {
// Default command for development purposes
registerDefaultCommand(cmd, appState);
};
cmd.onError((input: string, err: Error) => appState.addCommandResult(input, () => <ErrorResultView errorMessage={err.toString()} />));
registerStateChangeHandlers(appState);
}
}
export default shellModule;
function registerStateChangeHandlers(appState: AppState) {
appState.onChange((state: AppState, attribute: keyof AppState) => {
if (attribute === 'uiTheme') {
sendAnalyticsEvent({ eventCategory: "UI", eventAction: `set_theme_${state.uiTheme}` });
}
});
}
function registerDefaultCommand(cmd: CmdShell, appState: AppState) {
cmd.command({
canHandle: (s: string) => s.indexOf('default') === 0,
handle: (s: CommandInput) => {
const executeCommand = (c: string) => {
if(c.length === 0) {
if (c.length === 0) {
return "Default comand: " + localStorage.getItem(STARTUP_COMMAND_KEY);
}
else if(c === 'clear') {
else if (c === 'clear') {
localStorage.removeItem(STARTUP_COMMAND_KEY);
return "Default startup command cleared";
}
@@ -96,12 +113,5 @@ const shellModule = {
appState.addCommandResult(s.input, () => <TextResultView text={result} />);
}
});
};
cmd.onError((input: string, err: Error) => appState.addCommandResult(input, () => <ErrorResultView errorMessage={err.toString()} />));
}
}
export default shellModule;