Commit Graph

9 Commits

Author SHA1 Message Date
RomanNum3ral b8fdd9b421
Add Nextcloud Files browsing (browse/download/upload/delete/rename)
New Files section reachable from Agenda's top bar: a WebDAV browser
against /remote.php/dav/files/<user>/ with folder navigation, file
download-and-open (via FileProvider + a viewer Intent), upload from
the system file picker, delete, create folder, and rename (WebDAV
MOVE). Extends DavXml's existing multistatus parser with
getcontentlength/getlastmodified rather than writing a second parser,
since the response/propstat/status merging logic it already has is
the fiddly part.

Verified live against the real account: browsed real folders/files,
created and deleted a test folder, and confirmed a file downloads
and reaches a view Intent correctly (no viewer app installed on the
emulator to actually open it, but the FileProvider hand-off worked).
2026-07-18 14:02:22 -04:00
RomanNum3ral 2bf9a32ead
Add Nextcloud Talk text chat (read/send, no calls)
New Talk section reachable from Agenda's top bar: a conversation
list and a per-room chat screen with send + live updates via the
Talk chat API's long-poll (lookIntoFuture=1). No call/WebRTC
signaling - text only, per the scoped-down request for this item.

Uses the same OCS app-password auth as CalDAV. One real gotcha:
Nextcloud Talk versions each feature area of its OCS API
independently - Room/Call are at api/v4 on this server, but the
Chat endpoints are still api/v1; hitting v4/chat/{token} returns a
misleading generic "invalid query" 404 even fully authenticated.
2026-07-18 13:29:15 -04:00
RomanNum3ral 33d6469bbe
Add Authentik/SSO login via Nextcloud Login Flow v2; fix Tasks widget minHeight
Login Flow v2 opens Nextcloud's own browser login page in a Custom Tab
(androidx.browser), so any SSO backend configured server-side (Authentik
via user_oidc) and WebAuthn hardware-key prompts work without NCal
implementing OIDC/OAuth2 itself - the flow ends with a normal app
password, stored the same way as manual login.

The Tasks widget's minHeight was pinned exactly to its 4-row default
size (Android's 70*cells-30 formula), leaving no slack to ever resize
shorter. Lowered to 110dp (2 rows) so it can actually be resized to a
2x3 layout, which was verified to render cleanly.
2026-07-18 13:01:46 -04:00
RomanNum3ral d31894f980
Bump Gradle to 8.13 and Android Gradle Plugin to 8.13.2
AGP 8.13.2 requires Gradle >= 8.13; this was left uncommitted from a
prior session and the working tree had drifted from what the project
actually needs to build.
2026-07-18 13:01:14 -04:00
RomanNum3ral f3f8d76cda
Add monthly-ordinal recurrence support ("the 3rd Thursday", "the last Friday")
Extends the Repeats picker's BYDAY support (which deliberately excluded
ordinaled rules) to cover FREQ=MONTHLY with a single ordinaled BYDAY, via
RFC 5545's ByDay(num, weekday) - "the 3rd Thursday of the month" or "the
last Friday", not just a fixed day-of-month.

- CalendarItem.recurrenceByDayOrdinal (1..4, or -1 for "last") pairs with the
  existing recurrenceByDay field, reused as a singleton for this mode.
- RecurrenceUtils gets a new walker using TemporalAdjusters.dayOfWeekInMonth,
  correctly skipping months where the Nth weekday doesn't exist (RFC 5545:
  no occurrence that month, not a rollover) and correctly preserving local
  time-of-day across DST boundaries.
- Repeats picker: a 2-item "Monthly on day N" vs "Monthly on the Nth
  <weekday>" dropdown, weekday always derived from the current Starts/Due
  date rather than picked separately.

Verified live against the real Nextcloud server (created a "3rd Friday"
event, confirmed it round-tripped to the correct RRULE and resolved to the
correct date next month) and cleaned up afterward.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 05:56:25 -04:00
RomanNum3ral 3d0f6589a9
Add offline resilience, undo-delete, search, week view, BYDAY recurrence, import/export, and single-occurrence recurring edits
Closes out the full post-launch feature backlog:
- Offline write resilience for save/delete, with automatic flush on reconnect
- Undo-after-delete via a snackbar, with a fresh-UID recreate (Nextcloud's
  trashbin rejects reusing a just-deleted item's UID)
- Custom (non-preset) reminder offsets
- Search across events and tasks
- Week view alongside the existing Agenda/Month views
- BYDAY support in the Repeats picker ("every Mon/Wed/Fri"), including a
  proper RRULE evaluator extension for it
- Import/export .ics via the system share sheet and file picker
- Single-occurrence recurring-event editing/deleting ("this event only" vs
  "all events") via RFC 5545 RECURRENCE-ID overrides and EXDATE

A repository-wide write mutex now serializes sync against save/delete/undo,
fixing a real race where a background sync could clobber a just-written item.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 18:53:39 -04:00
RomanNum3ral 79cc6925e8
Fix the two remaining known limitations: recurring item date editing, field-by-field conflict merge
- CalendarItem gains recurrenceMasterStart/End/Due, the true unresolved
  master date, tracked separately from start/end/due (which hold the
  resolved next occurrence for a recurring item). The edit screen now shows
  and edits the real master date for recurring items instead of disabling
  those fields outright, with a note that the change applies to the whole
  series. Verified against a real recurring event on-device.
- New util/ConflictDiff.kt computes exactly which user-editable fields
  differ between a local edit and the server's version after a 412. The
  conflict dialog is now a per-field mine/theirs picker (with "All
  mine"/"All theirs" shortcuts) instead of an all-or-nothing choice.
- Extracted statusLabel() to util/StatusLabels.kt so both the edit screen
  and the new conflict diff can share it.
- Two more test files (ConflictDiffTest, extended IcsMapperTest).
2026-07-17 08:51:35 -04:00
RomanNum3ral 14ee70d71d
Fix remaining known limitations: recurrence editing, subtask tree parity, conflict resolution
- Recurrence picker (Daily/Weekly/Monthly/Yearly, interval, end condition) for
  both events and tasks, backed by a real RRULE. Fixes a latent bug from the
  prior RRULE-preservation change: editing a recurring item was writing the
  resolved *next occurrence* back as the master DTSTART, silently shifting the
  whole series forward on every edit - start/end/due are now correctly
  read-only for recurring items instead.
- Periodic background sync (WorkManager, ~30 min, network-gated) so widgets
  stay fresh without opening the app; auto-refresh on app open too.
- Tasks widget now renders the same parent/child tree as the in-app Tasks
  screen (util/TaskTree.kt shared by both) instead of a flat due-date list.
- Conflict resolution: a stale save (HTTP 412) shows both versions and lets
  you keep your edit or take theirs, instead of just an error banner.
- First test suite for the project (IcsMapperTest, TaskTreeTest).
2026-07-16 21:02:48 -04:00
RomanNum3ral 75f5e6024b Initial commit: NCal, a native Nextcloud CalDAV client for Android
One app for both events and tasks, talking directly to Nextcloud's CalDAV
endpoint - no DAVx5, no Google Play Services, no third-party services.
Encrypted at rest (SQLCipher DB, EncryptedSharedPreferences, Keystore-backed
widget state), HTTPS-only networking, home screen widgets, reminders,
subtasks, and full VTODO field support (status/priority/%complete/location/url).
2026-07-16 18:19:03 -04:00