From fc3a56c0dcc49f389326c7da9f6f17a5c42fa772 Mon Sep 17 00:00:00 2001
From: Jake
Date: Sun, 26 Apr 2026 19:30:06 +0100
Subject: [PATCH] =?UTF-8?q?feat(ux):=20B3.6=20=E2=80=94=20editable=20energ?=
=?UTF-8?q?y=20labels=20(global=20+=20per-profile)=20+=20first-tap=20promp?=
=?UTF-8?q?t?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Settings → Energy: edit global energy labels (label + description per
level) with reset-to-defaults. Per-profile override toggle in the
Profiles section ("Customise for this profile" / "Use global").
EnergyChip and Tasks-page energy controls now resolve labels via
resolveEnergyLabels(profile, settings) — global by default, profile
override when present.
First-time prompt: on first energy-chip tap of the day (per profile)
or first-ever tap to Zero, an inline non-modal prompt asks "What does
Zero mean for you today?" with example chips. Per-day gate via
energyPromptLastShownDate; one-shot first-Zero gate via
energyPromptZeroSeen; Settings escape resets both.
Co-Authored-By: Claude Opus 4.7 (1M context)
---
src/lib/components/EnergyChip.svelte | 23 +++-
src/lib/pages/SettingsPage.svelte | 182 ++++++++++++++++++++++++++-
src/lib/pages/TasksPage.svelte | 138 ++++++++++++++++++--
src/lib/stores/page.svelte.ts | 26 +++-
src/lib/types/app.ts | 13 ++
src/lib/utils/time.ts | 12 ++
6 files changed, 375 insertions(+), 19 deletions(-)
diff --git a/src/lib/components/EnergyChip.svelte b/src/lib/components/EnergyChip.svelte
index 8666823..85aaa43 100644
--- a/src/lib/components/EnergyChip.svelte
+++ b/src/lib/components/EnergyChip.svelte
@@ -19,9 +19,16 @@
//
// Callers pass the task's current energy and a setter. This component
// owns no state — the task store is the source of truth.
+ //
+ // B3.6: the displayed string per level now comes from
+ // resolveEnergyLabels(activeProfile, settings) rather than being
+ // hardcoded, so users can rename "Zero" to "Battery dead" without
+ // touching code.
import type { EnergyLevel } from "$lib/types/app";
import { Zap } from "lucide-svelte";
+ import { settings, profiles, page } from "$lib/stores/page.svelte.js";
+ import { resolveEnergyLabels } from "$lib/utils/energyLabels";
let {
energy = null as EnergyLevel | null,
@@ -45,11 +52,21 @@
return CYCLE[(idx + 1) % CYCLE.length];
}
+ // Active profile lookup against the localStorage `profiles` array.
+ // page.activeProfile is "None" or a profile name; we resolve to the
+ // Profile entry (or null) so the resolver can read its override.
+ let activeProfile = $derived(
+ page.activeProfile === "None"
+ ? null
+ : profiles.find((p) => p.name === page.activeProfile) ?? null,
+ );
+ let labels = $derived(resolveEnergyLabels(activeProfile, settings));
+
function labelFor(level: EnergyLevel | null): string {
switch (level) {
- case "high": return "High";
- case "medium": return "Medium";
- case "brain_dead": return "Zero";
+ case "high": return labels.high.label;
+ case "medium": return labels.medium.label;
+ case "brain_dead": return labels.brain_dead.label;
default: return "No energy set";
}
}
diff --git a/src/lib/pages/SettingsPage.svelte b/src/lib/pages/SettingsPage.svelte
index 43ed3d1..97aeb5f 100644
--- a/src/lib/pages/SettingsPage.svelte
+++ b/src/lib/pages/SettingsPage.svelte
@@ -3,7 +3,7 @@
import { onMount, onDestroy } from "svelte";
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
- import { settings, saveSettings, profiles, saveProfiles, templates, createTemplate as createTemplateRow, updateTemplate as updateTemplateRow, deleteTemplate as deleteTemplateRow, page, addProfileTaskList, removeProfileTaskList } from "$lib/stores/page.svelte.js";
+ import { settings, saveSettings, profiles, saveProfiles, templates, createTemplate as createTemplateRow, updateTemplate as updateTemplateRow, deleteTemplate as deleteTemplateRow, page, addProfileTaskList, removeProfileTaskList, defaultEnergyLabels } from "$lib/stores/page.svelte.js";
import Card from "$lib/components/Card.svelte";
import Toggle from "$lib/components/Toggle.svelte";
import SegmentedButton from "$lib/components/SegmentedButton.svelte";
@@ -1625,6 +1625,94 @@
{/if}
+
+
+
+
+
Energy labels
+
+
+
+ Rename the three energy levels and the short description shown when you set one. Profiles can override these — see the Profiles section below.
+
+
+ {#each ["high", "medium", "brain_dead"] as level}
+