feat(recipe): Wake-Lock-Schalter + Profil-Chip nur Lucide + Save-Text
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m16s
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m16s
1) ProfileSwitcher-Chip: Profil-Emoji (avatar_emoji) ist jetzt aus dem
Header-Badge raus — immer CircleUser-Icon vor dem Namen. Im Profil-
Auswahl-Modal bleiben die individuellen Emojis erhalten, damit User
ihr Profil dort weiterhin erkennen. Unused .emoji CSS entfernt.
2) Preview-Button: "In meine Sammlung speichern" → "Rezept in Kochwas
speichern". Klarer, was die App heißt.
3) Wake-Lock-Schalter:
- Erklärung: navigator.wakeLock.request('screen') hindert Android/iOS
daran, das Display zu dimmen/zu sperren, solange der Tab sichtbar
ist. Beim Kochen sehr nützlich — Hände sind klebrig.
- Neuer Toggle-Button im Rezept-Detail, zweite Aktion-Zeile zwischen
"Heute gekocht" und "Löschen": Lightbulb (an, gelb-gehighlighted)
oder LightbulbOff (aus).
- Preference wird in localStorage persistiert (kochwas.wakeLock),
Default an. Gilt für alle Rezepte.
- visibilitychange-Handler re-requestet den Sentinel, wenn User den
Tab wieder nach vorne holt und die Pref an ist.
- release-Event räumt wakeLock-Variable sauber auf.
This commit is contained in:
@@ -24,11 +24,10 @@
|
||||
</script>
|
||||
|
||||
<button class="chip" onclick={() => (showModal = true)} aria-label="Profil wechseln">
|
||||
<span class="icon"><CircleUser size={20} strokeWidth={1.75} /></span>
|
||||
{#if profileStore.active}
|
||||
<span class="emoji">{profileStore.active.avatar_emoji ?? '🙂'}</span>
|
||||
<span class="name">{profileStore.active.name}</span>
|
||||
{:else}
|
||||
<span class="icon"><CircleUser size={20} strokeWidth={1.75} /></span>
|
||||
<span class="name">Profil wählen</span>
|
||||
{/if}
|
||||
</button>
|
||||
@@ -105,9 +104,6 @@
|
||||
.chip:hover {
|
||||
background: #f4f8f5;
|
||||
}
|
||||
.emoji {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
.icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<span>Speichern…</span>
|
||||
{:else}
|
||||
<BookmarkPlus size={18} strokeWidth={2} />
|
||||
<span>In meine Sammlung speichern</span>
|
||||
<span>Rezept in Kochwas speichern</span>
|
||||
{/if}
|
||||
</button>
|
||||
<button type="button" class="btn ghost" onclick={() => history.back()}>Zurück</button>
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
Trash2,
|
||||
ChefHat,
|
||||
Check,
|
||||
X
|
||||
X,
|
||||
Lightbulb,
|
||||
LightbulbOff
|
||||
} from 'lucide-svelte';
|
||||
import RecipeView from '$lib/components/RecipeView.svelte';
|
||||
import StarRating from '$lib/components/StarRating.svelte';
|
||||
@@ -225,29 +227,62 @@
|
||||
void wishlistStore.refresh();
|
||||
}
|
||||
|
||||
// Wake-Lock
|
||||
// Wake-Lock — Bildschirm beim Kochen nicht dimmen lassen.
|
||||
// Browser-API navigator.wakeLock.request('screen') verhindert auto-lock
|
||||
// und -dimmen, solange der Tab sichtbar ist. Sobald der Tab in den
|
||||
// Hintergrund geht, verliert der Sentinel seine Wirkung von selbst; wir
|
||||
// re-requesten bei visibilitychange.
|
||||
let wakeLockEnabled = $state(true);
|
||||
let wakeLock: WakeLockSentinel | null = null;
|
||||
async function requestWakeLock() {
|
||||
|
||||
async function acquireWakeLock() {
|
||||
if (wakeLock || !wakeLockEnabled) return;
|
||||
try {
|
||||
if ('wakeLock' in navigator) {
|
||||
wakeLock = await navigator.wakeLock.request('screen');
|
||||
wakeLock.addEventListener('release', () => {
|
||||
wakeLock = null;
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// silently ignore
|
||||
// User hat es gecancelt oder Browser unterstützt es nicht — ignorieren
|
||||
}
|
||||
}
|
||||
|
||||
async function releaseWakeLock() {
|
||||
if (!wakeLock) return;
|
||||
try {
|
||||
await wakeLock.release();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
wakeLock = null;
|
||||
}
|
||||
|
||||
function toggleWakeLock() {
|
||||
wakeLockEnabled = !wakeLockEnabled;
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem('kochwas.wakeLock', wakeLockEnabled ? '1' : '0');
|
||||
}
|
||||
if (wakeLockEnabled) void acquireWakeLock();
|
||||
else void releaseWakeLock();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
void requestWakeLock();
|
||||
const stored = localStorage.getItem('kochwas.wakeLock');
|
||||
if (stored !== null) wakeLockEnabled = stored === '1';
|
||||
if (wakeLockEnabled) void acquireWakeLock();
|
||||
const onVisibility = () => {
|
||||
if (document.visibilityState === 'visible' && !wakeLock) void requestWakeLock();
|
||||
if (document.visibilityState === 'visible' && wakeLockEnabled && !wakeLock) {
|
||||
void acquireWakeLock();
|
||||
}
|
||||
};
|
||||
document.addEventListener('visibilitychange', onVisibility);
|
||||
return () => document.removeEventListener('visibilitychange', onVisibility);
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (wakeLock) void wakeLock.release();
|
||||
void releaseWakeLock();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -314,6 +349,22 @@
|
||||
<span class="count">({cookingLog.length})</span>
|
||||
{/if}
|
||||
</button>
|
||||
<button
|
||||
class="btn"
|
||||
class:screen-on={wakeLockEnabled}
|
||||
onclick={toggleWakeLock}
|
||||
aria-label={wakeLockEnabled
|
||||
? 'Bildschirm bleibt an — zum Deaktivieren klicken'
|
||||
: 'Bildschirm darf dimmen — zum Aktivieren klicken'}
|
||||
>
|
||||
{#if wakeLockEnabled}
|
||||
<Lightbulb size={18} strokeWidth={2} />
|
||||
<span>Bildschirm an</span>
|
||||
{:else}
|
||||
<LightbulbOff size={18} strokeWidth={2} />
|
||||
<span>Bildschirm aus</span>
|
||||
{/if}
|
||||
</button>
|
||||
<button class="btn danger" onclick={deleteRecipe}>
|
||||
<Trash2 size={18} strokeWidth={2} />
|
||||
<span>Löschen</span>
|
||||
@@ -476,6 +527,11 @@
|
||||
border-color: #b7d6c2;
|
||||
background: #eaf4ed;
|
||||
}
|
||||
.btn.screen-on {
|
||||
color: #b07e00;
|
||||
border-color: #e6d48a;
|
||||
background: #fff6d7;
|
||||
}
|
||||
.btn.primary {
|
||||
background: #2b6a3d;
|
||||
color: white;
|
||||
|
||||
Reference in New Issue
Block a user