Phones only (<=639px); desktop markup is untouched.
- New deck is a 3-step flow: progress (1/3 + bar) and a fixed Back/Next
bar above the tab bar. Step 1 = Add photos or files / Camera / Paste
text instead (no drop zone or paste copy on touch), step 2 = folder,
difficulty and count with defaults plus one collapsed focus/notes row,
step 3 = one summary line (photos/docs/text · difficulty · count ·
folder) with Freeze. Going Back keeps every input; step transitions
respect prefers-reduced-motion.
- Make my homework is a 2-step flow sharing the same pattern; tapping a
mode card starts it (no separate CTA on phones), with a short preview
of the assignment on step 2. The hero is now 'Make my homework' /
'Udělej mi úkol' everywhere ('Solve your homework' is gone) and the
intro is one line.
- Library: stats line removed, folder row and 'Unorganized' heading
hidden until folders exist (New folder lives in the drawer), Import is
a small icon button beside the tabs. Deck and homework cards are
compact on phones: title, one meta line (activities · difficulty ·
best), a one-line description that expands on tap, the whole card
tappable and a small Study/Open pill instead of the full-width button.
- Settings sheet on phones: no .env.local subtitle; Language stays first;
one Connection card (status dot + 'Connected · 2 models ready', key
field with the eye inside, Save only when edited, auto re-check on
save, refresh icon instead of Test connection); privacy one-liner with
a More expander (daemon tip inside); raw health rows behind one
collapsed Details list; Remove key as a small danger button at the very
bottom (same confirmation).
- Decorative orbs on phones moved further off the screen edges so they
never glow under cards or primary buttons.
- Shared markup for folder/difficulty/count and mode cards keeps one
source of state; new lib/use-phone.ts gates the layouts.
Verified: new declutter suite 116/116 (360 + 390, EN + CS, photo + PDF +
pasted text, Back keeps input, summaries, settings flow), regression
74/74, mobile 52/52, i18n 25/25. Lint + build clean. SW freezmo-v20.
22 lines
607 B
TypeScript
22 lines
607 B
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
/**
|
|
* True on phone-sized viewports (≤639px), false during SSR and on desktop.
|
|
* The mobile-only step flows switch on this; everything wider keeps the
|
|
* desktop layout untouched.
|
|
*/
|
|
export function useIsPhone(): boolean {
|
|
const [phone, setPhone] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const query = window.matchMedia("(max-width: 639px)");
|
|
const sync = () => setPhone(query.matches);
|
|
sync();
|
|
query.addEventListener("change", sync);
|
|
return () => query.removeEventListener("change", sync);
|
|
}, []);
|
|
|
|
return phone;
|
|
}
|