Rough edges: mobile 100dvh, session-expiry in chat, sticky error toasts, journal date filter #93

Merged
steve merged 2 commits from fix/rough-edges into main 2026-07-22 03:54:03 +00:00
3 changed files with 16 additions and 4 deletions
Showing only changes of commit 757ac7394d - Show all commits
+8 -1
View File
@@ -17,9 +17,16 @@ interface ToastState {
let nextId = 1 let nextId = 1
// Error toasts no longer auto-dismiss (#85), so a burst of failures could grow
// the stack without bound and push older ones off-screen. Cap it: keep the most
// recent MAX_TOASTS and drop the oldest, so the newest — the one that just
// happened — is always visible.
const MAX_TOASTS = 4
export const useToastStore = create<ToastState>((set) => ({ export const useToastStore = create<ToastState>((set) => ({
toasts: [], toasts: [],
push: (message, tone = 'info') => set((s) => ({ toasts: [...s.toasts, { id: nextId++, message, tone }] })), push: (message, tone = 'info') =>
set((s) => ({ toasts: [...s.toasts, { id: nextId++, message, tone }].slice(-MAX_TOASTS) })),
dismiss: (id) => set((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) })), dismiss: (id) => set((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) })),
})) }))
+7 -2
View File
@@ -16,6 +16,11 @@ import {
import type { EditorObject } from './types' import type { EditorObject } from './types'
import { objectDisplayName } from './kinds' import { objectDisplayName } from './kinds'
// Shared styling for the small From/To date inputs, so the two stay in step and
// don't drift from each other.
const dateInputClass =
'rounded-md border border-border bg-surface px-1.5 py-1 text-fg outline-none focus-visible:ring-2 focus-visible:ring-accent/40'
/** /**
* The garden's journal: write an entry, read the season back. * The garden's journal: write an entry, read the season back.
* *
1
@@ -86,7 +91,7 @@ export function JournalPanel({
value={from} value={from}
max={to || undefined} max={to || undefined}
onChange={(e) => setFrom(e.target.value)} onChange={(e) => setFrom(e.target.value)}
className="rounded-md border border-border bg-surface px-1.5 py-1 text-fg outline-none focus-visible:ring-2 focus-visible:ring-accent/40" className={dateInputClass}
/> />
</label> </label>
<label className="flex items-center gap-1"> <label className="flex items-center gap-1">
@@ -96,7 +101,7 @@ export function JournalPanel({
value={to} value={to}
min={from || undefined} min={from || undefined}
onChange={(e) => setTo(e.target.value)} onChange={(e) => setTo(e.target.value)}
className="rounded-md border border-border bg-surface px-1.5 py-1 text-fg outline-none focus-visible:ring-2 focus-visible:ring-accent/40" className={dateInputClass}
/> />
</label> </label>
{(from || to) && ( {(from || to) && (
+1 -1
View File
@@ -53,7 +53,7 @@ export function PublicGardenPage() {
} }
return ( return (
<div className="flex h-[calc(100vh-8rem)] flex-col gap-3"> <div className="flex h-[calc(100dvh-8rem)] flex-col gap-3">
<div className="flex flex-wrap items-center gap-2"> <div className="flex flex-wrap items-center gap-2">
<h1 className="truncate text-lg font-semibold tracking-tight" title={garden.name}> <h1 className="truncate text-lg font-semibold tracking-tight" title={garden.name}>
{garden.name} {garden.name}