diff --git a/CHANGELOG.md b/CHANGELOG.md index f3f15d6..b41b573 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V ## [Unreleased] +## [0.20.0] - 2026-10-31 + +### Changed +- App-Verknüpfungen (App-Icon gedrückt halten): Statt „Capture“ und „Triage“, die nur die Startseite öffneten, gibt es jetzt **Quick Dump**, **Neue Aufgabe** und **Einkaufsliste** mit eigenen Symbolen. Jede öffnet den passenden Bereich mit dem Eingabefeld (Quick-Dump-Fenster, „Neue Aufgabe“, neuer Listeneintrag). Alte Verknüpfungen führen weiter zum Quick Dump. Neue Verknüpfungen übernimmt Android, sobald es die App aktualisiert (oder nach Neuinstallation). + ## [0.19.0] - 2026-10-31 ### Added @@ -440,7 +445,8 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V - Geteilte Listen (Einkaufs-, Pack- und Checklisten) mit `#Kategorie`-Gruppierung, Mengenangaben und Echtzeit-Abhaken. - Benutzer-, Gruppen- und Admin-Verwaltung (Ersteinrichtungs-Assistent, Einladungscodes, Profilbilder, persönliche API-Keys & Webhook-Ingest `/api/v1/webhooks/ingest`, JSON-Datenexport) sowie CSS-Theme-Engine mit 4 Themes (`Dark`, `Light`, `High Contrast`, `Soft`) und PWA-Unterstützung. -[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.19.0...dev +[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.20.0...dev +[0.20.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.19.0...v0.20.0 [0.19.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.18.1...v0.19.0 [0.18.1]: https://git.dsit.me/sandrodach/MindSift/compare/v0.18.0...v0.18.1 [0.18.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.17.4...v0.18.0 diff --git a/README.md b/README.md index b17cd37..b3401e6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Self-Hosted](https://img.shields.io/badge/100%25-Self--Hosted-2563eb?style=flat-square)](#) [![Docker](https://img.shields.io/badge/Deployment-Single%20Container-2496ed?style=flat-square&logo=docker&logoColor=white)](#-schnellstart) [![SQLite](https://img.shields.io/badge/Daten-SQLite-003b57?style=flat-square&logo=sqlite&logoColor=white)](#-deine-daten-gehören-dir) -[![Version](https://img.shields.io/badge/Version-v0.19.0-16a34a?style=flat-square)](CHANGELOG.md) +[![Version](https://img.shields.io/badge/Version-v0.20.0-16a34a?style=flat-square)](CHANGELOG.md) **MindSift** ist eine selbst gehostete Schaltstelle für spontane Gedanken, Aufgaben mit Kanban-Board, hierarchische Outliner-Notizen, die mehrere Personen gleichzeitig bearbeiten können, und gemeinsame Listen. Alles läuft als ein einzelner Container mit eingebetteter SQLite-Datenbank, auf deinem eigenen Server. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 508c0ed..cee0a00 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "mindsift-frontend", - "version": "0.19.0", + "version": "0.20.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mindsift-frontend", - "version": "0.19.0", + "version": "0.20.0", "license": "Unlicense", "dependencies": { "@fontsource-variable/inter": "5.3.0", diff --git a/frontend/package.json b/frontend/package.json index 314e944..c49a278 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "mindsift-frontend", "private": true, - "version": "0.19.0", + "version": "0.20.0", "license": "Unlicense", "type": "module", "scripts": { diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json index 45f3b94..e07f867 100644 --- a/frontend/public/manifest.json +++ b/frontend/public/manifest.json @@ -65,16 +65,43 @@ }, "shortcuts": [ { - "name": "Gedanke sofort erfassen", - "short_name": "Capture", - "description": "Öffnet MindSift mit Fokus im Eingabefeld", - "url": "/?mode=capture" + "name": "Quick Dump", + "short_name": "Quick Dump", + "description": "Gedanken schnell in die Triage werfen", + "url": "/?shortcut=quickdump", + "icons": [ + { + "src": "/shortcut-quickdump.png", + "sizes": "192x192", + "type": "image/png" + } + ] }, { - "name": "Triage starten", - "short_name": "Triage", - "description": "Gedanken im Kartendeck aussortieren", - "url": "/?tab=triage" + "name": "Neue Aufgabe", + "short_name": "Aufgabe", + "description": "Direkt eine neue Aufgabe anlegen", + "url": "/?shortcut=task", + "icons": [ + { + "src": "/shortcut-task.png", + "sizes": "192x192", + "type": "image/png" + } + ] + }, + { + "name": "Einkaufsliste", + "short_name": "Einkaufsliste", + "description": "Einen Eintrag zur Einkaufsliste hinzufügen", + "url": "/?shortcut=list", + "icons": [ + { + "src": "/shortcut-list.png", + "sizes": "192x192", + "type": "image/png" + } + ] } ] } diff --git a/frontend/public/shortcut-list.png b/frontend/public/shortcut-list.png new file mode 100644 index 0000000..b5fbb9f Binary files /dev/null and b/frontend/public/shortcut-list.png differ diff --git a/frontend/public/shortcut-quickdump.png b/frontend/public/shortcut-quickdump.png new file mode 100644 index 0000000..61aeb08 Binary files /dev/null and b/frontend/public/shortcut-quickdump.png differ diff --git a/frontend/public/shortcut-task.png b/frontend/public/shortcut-task.png new file mode 100644 index 0000000..5c8b76f Binary files /dev/null and b/frontend/public/shortcut-task.png differ diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f6f356c..1a0f95a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -245,6 +245,34 @@ export const App: React.FC = () => { }; const { isMenuOpen, setIsMenuOpen, closeMenu, setGroups, primaryAction, setPrimaryAction } = useMobileActions(); + const primaryActionRef = useRef(primaryAction); + primaryActionRef.current = primaryAction; + + // App icon shortcuts (manifest "shortcuts", long-press on the icon): open the tab and its input right away. + // ?shortcut=quickdump|task|list; the old links (?mode=capture, ?tab=triage) still lead to the Quick Dump. + const [pendingShortcut, setPendingShortcut] = useState(() => { + const params = new URLSearchParams(window.location.search); + const target = params.get('shortcut') || (params.get('mode') === 'capture' || params.get('tab') === 'triage' ? 'quickdump' : ''); + return ({ quickdump: 'triage', task: 'tasks', list: 'lists' } as Record)[target] || null; + }); + useEffect(() => { + if (!pendingShortcut || !user) return; + if (activeTab !== pendingShortcut) { + setActiveTab(pendingShortcut); + return; + } + const target = pendingShortcut; + setPendingShortcut(null); + const url = new URL(window.location.href); + ['shortcut', 'mode', 'tab'].forEach((k) => url.searchParams.delete(k)); + window.history.replaceState({}, '', url.pathname + url.search + url.hash); + // The view registers its "+" action once it is mounted, so wait a moment (no cleanup: resetting + // pendingShortcut above re-runs this effect and must not cancel the timer) + window.setTimeout(() => { + if (target === 'triage') handleTriggerAddButton(); + else if (window.innerWidth < 640 || target === 'lists') primaryActionRef.current?.(); + }, 400); + }, [pendingShortcut, user?.id, activeTab]); useEffect(() => { closeMenu();