From 1b8bbaa22f35ac34183c7cc50b29a0151dcd66ac Mon Sep 17 00:00:00 2001 From: ayushya Date: Mon, 28 Sep 2026 17:37:03 -0400 Subject: [PATCH] Fix every item's "created" date reading January 1970 Nextcloud's WebDAV server has no real per-file creation-time tracking for most setups, so its creationdate property routinely comes back as a placeholder Unix-epoch date ("Thu, 01 Jan 1970 00:00:00 GMT") instead of being omitted. _parseDavDate parsed that "successfully" into a real (if bogus) DateTime, so every item's dateCreated stuck at the epoch instead of falling back to lastModified as it would for a genuinely missing/unparseable value. Add _parseDavCreationDate, which treats that placeholder the same as an absent value, and use it at all four PROPFIND/SEARCH call sites that read creationdate (folder listing, search, favorites, recent). --- .claude/context/server.md | 9 +++++++++ lib/services/nextcloud_service.dart | 21 +++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/.claude/context/server.md b/.claude/context/server.md index 5887f71..8fb0f78 100644 --- a/.claude/context/server.md +++ b/.claude/context/server.md @@ -73,6 +73,15 @@ rather than needing a rewrite for multi-account support. there is no WebDAV client dependency. `_parseDavDate`/`_davPath` in this file exist because WebDAV responses use RFC 1123 dates and either bare paths or full URLs for `href`; reuse them rather than re-deriving. + `creationdate` specifically needs `_parseDavCreationDate`, not + `_parseDavDate` directly - Nextcloud has no real per-file creation-time + tracking for most setups, so that property routinely comes back as a + placeholder Unix-epoch date rather than being omitted, which + `_parseDavDate` alone parses "successfully" into a real (if bogus) + January 1970 `DateTime`. `_parseDavCreationDate` treats that placeholder + as absent instead, so `NextcloudItem.dateCreated` falls back to + `lastModified` (its constructor's default) the same as it would for a + missing/unparseable value. - **Everything else** (shares, activity, trash, favorites, quota, user info, file versions) goes through Nextcloud's OCS APIs (`/ocs/v2.php/...`), JSON in, with the `OCS-APIRequest: true` header required on every OCS call. diff --git a/lib/services/nextcloud_service.dart b/lib/services/nextcloud_service.dart index ed3b0fe..3d673f3 100644 --- a/lib/services/nextcloud_service.dart +++ b/lib/services/nextcloud_service.dart @@ -44,6 +44,19 @@ DateTime? _parseDavDate(String? raw) { } } +/// Nextcloud's WebDAV server has no real per-file creation-time tracking +/// for most setups, so its `creationdate` property routinely comes back as +/// a placeholder Unix-epoch date ("Thu, 01 Jan 1970 00:00:00 GMT") instead +/// of being omitted - [_parseDavDate] parses that "successfully" into a +/// real (if bogus) `DateTime`, so every item's created date read January +/// 1970. Treat it as absent instead, the same as a missing/unparseable +/// value: `NextcloudItem`'s constructor then falls back to `lastModified`. +DateTime? _parseDavCreationDate(String? raw) { + final parsed = _parseDavDate(raw); + if (parsed != null && parsed.millisecondsSinceEpoch <= 0) return null; + return parsed; +} + /// The OCS Activity API reports each event's time as an ISO 8601 string in /// a `datetime` field (e.g. "2025-09-15T12:34:56+00:00") - there is no /// numeric `timestamp` field despite that being a very easy name to guess. @@ -356,7 +369,7 @@ class NextcloudService { final size = int.tryParse(sizeStr ?? '0') ?? 0; final lastMod = _parseDavDate(lastModStr) ?? DateTime.now(); - final created = _parseDavDate(createdStr); + final created = _parseDavCreationDate(createdStr); final itemType = NextcloudItem.deduceType(name, isCollection, mimeType); final validId = (fileId != null && fileId.isNotEmpty) ? fileId : name; @@ -671,7 +684,7 @@ class NextcloudService { final size = int.tryParse(sizeStr ?? '0') ?? 0; final lastMod = _parseDavDate(lastModStr) ?? DateTime.now(); - final created = _parseDavDate(createdStr); + final created = _parseDavCreationDate(createdStr); final itemType = NextcloudItem.deduceType(name, false, mimeType); final validId = (fileId != null && fileId.isNotEmpty) ? fileId : name; @@ -835,7 +848,7 @@ class NextcloudService { final size = int.tryParse(sizeStr ?? '0') ?? 0; final lastMod = _parseDavDate(lastModStr) ?? DateTime.now(); - final created = _parseDavDate(createdStr); + final created = _parseDavCreationDate(createdStr); final itemType = NextcloudItem.deduceType(name, isCollection, mimeType); final validId = (fileId != null && fileId.isNotEmpty) ? fileId : name; @@ -1000,7 +1013,7 @@ class NextcloudService { final size = int.tryParse(sizeStr ?? '0') ?? 0; final lastMod = _parseDavDate(lastModStr) ?? DateTime.now(); - final created = _parseDavDate(createdStr); + final created = _parseDavCreationDate(createdStr); final itemType = NextcloudItem.deduceType(name, false, mimeType); final validId = (fileId != null && fileId.isNotEmpty) ? fileId : name;