Commit Graph
31 Commits
Author SHA1 Message Date
nmemmertandClaude Sonnet 5.5 e22d26bf17 Save settings on the server and sync them to every device
build-container / build (push) Successful in 2m2s
Preferences lived only in the browser, so clearing it, using another device or the separate iOS
home-screen storage lost them. They are now saved in /data/settings.json (the audiobooks sign-in
encrypted), loaded at start-up, and existing browser-only values are uploaded once. A failed save
is reported instead of silent.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:59:01 -04:00
nmemmertandClaude Sonnet 5.5 d3642a7736 iCloud: find calendars whatever way Apple writes their component list
build-container / build (push) Successful in 2m6s
Apple's listing was recognised as calendars but then discarded by the events/tasks filter.
Read component names from anywhere in the entry (any quoting or prefix), treat a missing or
empty list as events, and keep calendars as event calendars if every one would otherwise be
dropped. Errors now show each item with its component types.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:57:06 -04:00
nmemmertandClaude Sonnet 5.5 a4e0e24ab7 iCloud: recognise Apple's calendar entries; say what was seen when none match
build-container / build (push) Successful in 1m56s
Apple writes <calendar xmlns="urn:ietf:params:xml:ns:caldav"/> (attributes, no prefix), which the
previous pattern missed, so a valid sign-in reported "No calendars found". Match it with a
lookahead, check the HTTP status of the listing, and name what iCloud returned if nothing matches.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:46:24 -04:00
nmemmertandClaude Sonnet 5.5 044589686c PWA for iPhone and iPad: PNG icons, splash screens, manifest; stay signed in for 180 days
build-container / build (push) Successful in 1m56s
- iOS ignores SVG touch icons: add 120/152/167/180 apple-touch-icons, 192/512 and maskable manifest icons,
  and 25 splash screens (every iPhone size, iPad portrait+landscape incl. 12.9")
- Icons and splash screens are public so iOS can fetch them without a session
- Manifest: id, scope, categories, shortcuts; iOS standalone polish (no callout, no overscroll)
- Sessions last SESSION_DAYS (default 180) and renew daily while in use
- tools/make-icons.py regenerates the artwork

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:44:39 -04:00
nmemmertandClaude Sonnet 5.5 916882e55d Tasks tab: NE Hub lists plus iCloud reminder lists where Apple exposes them
build-container / build (push) Successful in 1m43s
- Lists, quick add, due dates, notes, complete/reopen, delete; Home card for overdue/due today
- iCloud VTODO lists read and written over CalDAV (If-Match, edits patch the latest copy so
  priority/alarms survive); NE Hub lists work regardless
- Fix: text inside a nested VALARM was read as the task's / event's own description and then
  written back on edit; nested components are now skipped (regression tests added)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:41:59 -04:00
nmemmertandClaude Sonnet 5.5 5c7917e57c Show whether the data folder is a real volume (Settings and startup log)
build-container / build (push) Successful in 1m56s
Passkeys, calendars and sessions were being lost on redeploy. The server now
reports whether /data is a mounted volume, whether it is writable, what it
holds, and where the session secret comes from, so a wiped volume is obvious.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:36:17 -04:00
nmemmertandClaude Sonnet 5.5 18266267e5 Search: DuckDuckGo instant answer card
build-container / build (push) Successful in 2m5s
The server asks DuckDuckGo's instant-answer service (summary, definition, quick
answers) and Search shows it as a card above the app's own results when there
is one. Lookups are cached for 10 minutes and a failure never breaks Search.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:31:42 -04:00
nmemmertandClaude Sonnet 5.5 64c91f9e0a Search: hand the question to Duck.ai or DuckDuckGo
build-container / build (push) Successful in 2m3s
Both refuse to be framed and Duck.ai has no public API, so Search shows
"Ask Duck.ai" and "Search the web" buttons that open a new tab with the
query pre-filled.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:30:30 -04:00
nmemmertandClaude Sonnet 5.5 ee2678d9ed Podcast tab: show podcast.necloud.us inside the app
build-container / build (push) Successful in 1m44s
Audio and Podcast now share kept-alive frames that stay loaded while hidden.
A plain-http address still falls back to a launcher (a secure page cannot
frame http content).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:18:42 -04:00
nmemmertandClaude Sonnet 5.5 5466506ffb Calendar: add events (NE Hub calendar + iCloud) and a Podcast tab
build-container / build (push) Successful in 1m55s
- Add, edit and delete events; month/agenda views open them on tap
- NE Hub calendar stored on the server and published as a private ICS subscribe link
- iCloud CalDAV read/write with an app-specific password (encrypted at rest,
  only *.icloud.com contacted, event addresses checked against the calendar)
- Edits patch the existing entry so alarms/attendees survive; writes use If-Match / If-None-Match
- Time zone definitions (VTIMEZONE) generated so other apps read times correctly
- Podcast tab (PODCAST_URL) alongside Podcast Admin

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:08:41 -04:00
nmemmertandClaude Sonnet 5.5 7beb06678c Rename the Verse admin tab to Podcast Admin
build-container / build (push) Successful in 2m7s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:04:26 -04:00
nmemmertandClaude Sonnet 5.5 bd58fe73cc Add a Verse admin tab that opens versebyversewithnate.us/admin
build-container / build (push) Successful in 2m36s
The site sends X-Frame-Options: SAMEORIGIN, so it cannot be embedded; the tab
and a Home tile open it in its own browser tab. Address is VERSE_URL.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 15:01:50 -04:00
nmemmertandClaude Sonnet 5.5 6ec98d2527 Passkeys: one-time invite codes to enrol another device
build-container / build (push) Successful in 2m14s
A signed-in device creates a short-lived, single-use code in Settings
("Invite a device"); the new device enters it on the sign-in page to create
its own passkey. Codes are throttled like other secrets and cannot be used
by signed-out clients to create more codes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:56:19 -04:00
nmemmertandClaude Sonnet 5.5 e8b46bb3aa Music: choose which Plex music library to browse
build-container / build (push) Successful in 1m54s
Lists every music library on the server, remembers the choice per server,
and shows it under the title with a picker.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:48:27 -04:00
nmemmertandClaude Sonnet 5.5 f14a726f32 Log data location and counts at startup; give the compose volume a fixed name
build-container / build (push) Successful in 1m59s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:46:55 -04:00
nmemmertandClaude Sonnet 5.5 e9397f1f21 Calendar: month grid view
build-container / build (push) Successful in 1m45s
Month view (default) with event dots on phones and event labels on
tablet/desktop, tap a day to see its events, previous/next/today.
The agenda list stays available.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:45:24 -04:00
nmemmertandClaude Sonnet 5.5 96fb6d807c Fix truncated responses from compressed upstreams
build-container / build (push) Successful in 2m21s
fetch() decompresses transparently, but the proxies forwarded the upstream
content-length, so browsers cut compressed Plex/Seafile responses short and
JSON.parse failed. Ask Plex for identity encoding and drop the stale length
whenever the upstream response was encoded.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:41:14 -04:00
nmemmertandClaude Sonnet 5.5 4227883a29 Plex: group connection failures so public/relay results are visible
build-container / build (push) Successful in 2m20s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:34:06 -04:00
nmemmertandClaude Sonnet 5.5 b5fb8b9c03 Keep the audiobooks frame alive when switching tabs
build-container / build (push) Successful in 2m12s
The frame was rebuilt with the page content on every route change, which
stopped playback. It now lives outside the view and is only shown or hidden.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:33:09 -04:00
nmemmertandClaude Sonnet 5.5 cff7e9e59c Plex: read the server identity as JSON or XML and show ids on mismatch
build-container / build (push) Successful in 2m3s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:27:42 -04:00
nmemmertandClaude Sonnet 5.5 732b73677b Plex: try the server's LAN address first, allow a manual address
build-container / build (push) Successful in 2m6s
Connecting through plex.direct names failed from the container (DNS and
hairpin NAT). Try http://<lan-ip>:<port> first, verify the server's
machine identifier before sending the token, and let the user type an
address when discovery fails.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:20:39 -04:00
nmemmertandClaude Sonnet 5.5 4456c03cd0 Office tab: create, list and edit documents in place, saved in Seafile
build-container / build (push) Successful in 2m19s
- Choose where documents are saved (library + folder picker, like Files); remembered
- New document/spreadsheet/presentation asks for a name and shows the save location
- Documents in that location are listed in the tab; opening one edits it inside the tab
  with the navigation visible and a Back to Office button
- Fix double slash in editor URLs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:19:52 -04:00
nmemmertandClaude Sonnet 5.5 b5603d2488 Office tab: create documents, spreadsheets and presentations
build-container / build (push) Successful in 2m49s
The Office tab was just the OnlyOffice welcome page. It now offers New
document/spreadsheet/presentation, creates the file in Seafile from a valid
blank template (empty 0-byte files often will not open in the editor) and
opens it in the editor. Files > New uses the same templates.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:17:03 -04:00
nmemmertandClaude Sonnet 5.5 cd48ccf8e0 Report why each Plex connection failed
build-container / build (push) Successful in 2m25s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:11:37 -04:00
nmemmertandClaude Sonnet 5.5 943f510ec4 Use PUBLIC_URL for the passkey origin; warn on weak cookie secrets
build-container / build (push) Successful in 2m39s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 14:00:44 -04:00
nmemmertandClaude Sonnet 5.5 1b49ee6cb4 Add DNS servers to the compose service
build-container / build (push) Successful in 1m36s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 13:59:31 -04:00
nmemmertandClaude Sonnet 5.5 a4907e0cee Show the underlying cause when Seafile is unreachable
build-container / build (push) Successful in 2m25s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 13:49:10 -04:00
nmemmertandClaude Sonnet 5.5 34a8d28059 Put the environment settings in docker-compose.yml
build-container / build (push) Canceled after 0s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 13:31:01 -04:00
nmemmertandClaude Sonnet 5.5 0be9a3cd10 Build the container for x86 (amd64) only
build-container / build (push) Successful in 2m31s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 13:25:55 -04:00
nmemmertandClaude Sonnet 5.5 cf23472ad6 Add search, calendar, music queue/resume, file actions, More menu
build-container / build (push) Canceled after 0s
- Calendar agenda from private ICS feeds (recurrence, EXDATE, overrides, time zones, SSRF guard)
- Search across libraries, files (recursive fallback) and Plex
- Home dashboard: now playing, today's agenda, recent files
- Files: rename, move, share link, preview, create new documents
- Music: recently added, play next / add to queue, queue sheet, resume on launch
- Phone tab bar shows four tabs plus a More menu

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 13:24:54 -04:00
nmemmertandClaude Sonnet 5.5 55e0c39171 NE Hub: Seafile, OnlyOffice, Plex, calendar and mail in one PWA
build-container / build (push) Canceled after 4m16s
- Mobile-first PWA (phone tab bar with More menu, iPad/desktop rail)
- Passkey (WebAuthn) sign-in gates the whole app; first passkey via setup code
- Files: Seafile browse/upload/new doc/rename/move/share link/preview/delete
- In-app OnlyOffice editing with JWT-signed configs and save-back to Seafile
- Plex music player via plex.tv sign-in and a server-side proxy
- Calendar agenda from private ICS links (recurrence + time zones)
- Search, Home dashboard, webmail deep links, audiobooks frame
- Dockerfile, compose, and a Gitea Actions workflow that builds the image

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 13:22:03 -04:00