Add full-screen API-key gate
In user-key mode a browser with no stored Ollama key now gets a polished gate instead of the app shell: one masked input with a show/hide toggle, a single Continue button, inline validation errors, and a "?" help sheet with the steps to a free key. - Validates the draft key through /api/health (real 1-token probe) before saving; invalid-key and network failures read differently. - Key still lives only in this browser's localStorage; nothing server-side. - Gate wraps /, /create and deck study; server-key and local-daemon modes skip it; removing the key in Settings brings it back. - Removes the now-redundant dashboard/create API-key banner. - Monochrome corner glows (dark near-black / light near-white), 24px card, 48px field and button, gentle fade/slide-in, reduced-motion aware. - Help modal: centred dialog on desktop, bottom sheet on mobile, closes via X, Escape or backdrop. - README and browser suites updated (34 gate checks, 15 key-flow checks, 12 shipped-default checks; ui/folders/docs/pwa/security/contrast green).
This commit is contained in:
parent
532b5a18fe
commit
dfa7b7502a
13 changed files with 505 additions and 94 deletions
29
README.md
29
README.md
|
|
@ -84,6 +84,14 @@ no database, no data leaving your machine except the requests you send to Ollama
|
|||
| `ordering` | Drag with the mouse/finger, or use ▲▼ buttons, then check |
|
||||
| `short_answer` | Typed answer graded by the AI via `/api/grade`, with a self-check fallback |
|
||||
|
||||
**First run**
|
||||
|
||||
- A full-screen **API-key gate** replaces the app until a key is saved (in `user-key` mode): one
|
||||
masked input with a show/hide toggle, a single **Continue**, and a "?" sheet with the four steps
|
||||
to a free key. The key is validated with a real 1-token probe before it is accepted — invalid
|
||||
keys and network trouble get different inline messages. Removing the key in Settings brings the
|
||||
gate back; `server` and `local` installs skip it entirely.
|
||||
|
||||
**Library & folders**
|
||||
|
||||
- Decks saved locally with title, subject, folder, activity count, date, play count and best score
|
||||
|
|
@ -144,7 +152,7 @@ build too.
|
|||
|
||||
Open <http://localhost:3207>. The app runs without any Ollama configuration — you'll just need a
|
||||
key (or a signed-in daemon) before it can generate a deck. Complete one of the Ollama setups below,
|
||||
then paste the key in **Settings**.
|
||||
then paste the key on the gate (or later in **Settings**).
|
||||
|
||||
`npm run dev` and `npm run build` also copy the pdf.js worker into `public/` automatically (see
|
||||
`scripts/copy-pdf-worker.mjs`), which is what lets the browser parse PDFs.
|
||||
|
|
@ -172,7 +180,7 @@ Who provides the API key is controlled by **`OLLAMA_AUTH`**:
|
|||
|
||||
| `OLLAMA_AUTH` | Key comes from | Use it when |
|
||||
| --- | --- | --- |
|
||||
| **`user-key`** (default) | each browser, pasted in the settings dialog | several people/devices share the app, or you don't want a key on the server |
|
||||
| **`user-key`** (default) | each browser, pasted on the key gate (or in Settings) | several people/devices share the app, or you don't want a key on the server |
|
||||
| `server` | `OLLAMA_API_KEY` in `.env.local` | a single-user install |
|
||||
| `local` | nothing — a daemon signed in with `ollama signin` | you run Ollama locally |
|
||||
|
||||
|
|
@ -185,9 +193,10 @@ VISION_MODEL=gemma4:31b-cloud
|
|||
TEXT_MODEL=gpt-oss:120b-cloud
|
||||
```
|
||||
|
||||
1. Open the app → a banner asks for a key → click **Add API key** (or the ⚙️ button).
|
||||
2. Create a key at <https://ollama.com/settings/keys> and paste it in.
|
||||
3. **Test connection** shows whether Ollama accepted it, and which models are available.
|
||||
1. Open the app — the **key gate** asks for a key on first visit.
|
||||
2. Create one at <https://ollama.com/settings/keys>, paste it in and press **Continue**.
|
||||
3. The gate validates it with a real 1-token request, then drops you into the icebox.
|
||||
**Settings → Test connection** re-checks any time and shows the model list.
|
||||
|
||||
Where the key lives:
|
||||
|
||||
|
|
@ -530,7 +539,7 @@ components/
|
|||
activities/ one component per activity type + shared shell
|
||||
Flashcard.tsx MultipleChoice.tsx TrueFalse.tsx FillBlank.tsx
|
||||
Matching.tsx Ordering.tsx ShortAnswer.tsx shared.tsx index.tsx
|
||||
UploadScreen.tsx StudyFeed.tsx ResultsScreen.tsx DeckCard.tsx ApiKeyBanner.tsx
|
||||
UploadScreen.tsx StudyFeed.tsx ResultsScreen.tsx DeckCard.tsx ApiKeyGate.tsx
|
||||
TabBar.tsx InstallHint.tsx ServiceWorkerRegistrar.tsx FolderBar.tsx
|
||||
LibraryScreen.tsx SettingsDialog.tsx AppHeader.tsx ThemeToggle.tsx icons.tsx ui.tsx
|
||||
lib/
|
||||
|
|
@ -627,7 +636,7 @@ regeneration and “add more”.
|
|||
| A document card is stuck on “Reading page …” | The pdf.js worker may be missing: run `npm run dev`/`npm run build` (they copy it to `public/pdf.worker.min.mjs`) or `node scripts/copy-pdf-worker.mjs` manually. |
|
||||
| PDF uploaded but no activities about its content | The PDF is probably image-only (a scan). Freezmo renders such pages and sends them to the vision model — check the card note (“N scanned pages were turned into images”); if it says “No readable text”, the scan may be too low quality. |
|
||||
| Deck came back in English even though the notes are not | Make sure both model calls succeed (a failed vision step falls back to raw text). The prompts force the notes' language; if you still see translation, switch `TEXT_MODEL` to a stronger instruction-follower such as `gpt-oss:120b-cloud`. |
|
||||
| “Add your Ollama API key first” | Bring-your-own-key mode is active. Paste a key from <https://ollama.com/settings/keys> in the ⚙️ dialog — it is stored only in your browser. |
|
||||
| “Add your Ollama API key first” | Bring-your-own-key mode is active. Paste a key from <https://ollama.com/settings/keys> on the key gate (or in the ⚙️ dialog) — it is stored only in your browser. |
|
||||
| “Ollama rejected this API key” | The key is invalid or revoked. Create a new one and paste it again; the check uses a real 1-token request, so a green tick means it truly works. |
|
||||
| “this model is not included in your free usage” | The key works, but the model is outside your plan. Use one of the ✅ models in the table above, or add credits at <https://ollama.com/settings>. |
|
||||
| “Too many requests — try again in Ns” | You hit a rate limit (12 decks / 40 grades per 5 min by default). Wait, or raise `RATE_LIMIT_*` in `.env.local`. |
|
||||
|
|
@ -745,6 +754,12 @@ Things I chose while building, with the reasoning:
|
|||
density) flags a mismatch, the text model rewrites the JSON back into the original language
|
||||
before generation. Verified both ways: it fires on a synthetic English-but-declared-Czech
|
||||
transcription and never fires on real Czech notes (no extra calls, no added latency).
|
||||
28. **The first screen is the API-key gate.** In `user-key` mode a browser without a key gets a
|
||||
full-screen, monochrome gate instead of the dashboard: one masked input, one Continue button,
|
||||
and a "?" sheet with the steps to a free key. The gate reuses the cached 1-token probe through
|
||||
`/api/health`, so an invalid key and an unreachable Ollama are worded differently. The old
|
||||
dashboard banner is gone; key management stays in Settings, and removing the key brings the
|
||||
gate back. The gate covers `/`, `/create` and deck study, but never `/offline`.
|
||||
14. **`gpt-oss:120b` does all content work — but it cannot read images** (`this model does not
|
||||
support image input`), so `VISION_MODEL` has to stay a multimodal model (`gemma4:31b-cloud`).
|
||||
Text-only inputs — pasted text, PDFs with a text layer, DOCX/PPTX/ODT — never touch the vision
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue