implemented Nextcloud file previews for unknown file types using fileId and has-preview flags, updated file models, and refined manual refresh logic.

This commit is contained in:
2026-05-13 19:44:26 +02:00
parent 843686358f
commit 092f9b622b
6 changed files with 174 additions and 41 deletions
@@ -15,6 +15,16 @@ class CacheableFile {
DateTime? modifiedAt;
String? sort;
/// Nextcloud's instance-local file id (`oc:fileid`). Used to address the
/// preview API by id, which is more reliable than the path-based variant
/// on some server configurations.
int? fileId;
/// Server's answer to "can I render a thumbnail for this file?"
/// (`nc:has-preview`). Lets the file viewer skip the placeholder text
/// when a preview is going to load anyway.
bool? hasPreview;
CacheableFile({
required this.path,
required this.isDirectory,
@@ -24,6 +34,8 @@ class CacheableFile {
this.eTag,
this.createdAt,
this.modifiedAt,
this.fileId,
this.hasPreview,
});
CacheableFile.fromDavFile(WebDavFile file) {
@@ -35,6 +47,8 @@ class CacheableFile {
eTag = file.etag;
createdAt = file.createdDate;
modifiedAt = file.lastModified;
fileId = int.tryParse(file.fileId ?? '');
hasPreview = file.hasPreview;
}
factory CacheableFile.fromJson(Map<String, dynamic> json) =>
@@ -20,6 +20,8 @@ CacheableFile _$CacheableFileFromJson(Map<String, dynamic> json) =>
modifiedAt: json['modifiedAt'] == null
? null
: DateTime.parse(json['modifiedAt'] as String),
fileId: (json['fileId'] as num?)?.toInt(),
hasPreview: json['hasPreview'] as bool?,
)..sort = json['sort'] as String?;
Map<String, dynamic> _$CacheableFileToJson(CacheableFile instance) =>
@@ -33,4 +35,6 @@ Map<String, dynamic> _$CacheableFileToJson(CacheableFile instance) =>
'createdAt': instance.createdAt?.toIso8601String(),
'modifiedAt': instance.modifiedAt?.toIso8601String(),
'sort': instance.sort,
'fileId': instance.fileId,
'hasPreview': instance.hasPreview,
};
@@ -25,8 +25,23 @@ class ListFiles extends WebdavApi<ListFilesParams> {
Future<ListFilesResponse> run() async {
final webdav = await WebdavApi.webdav;
final timeout = _isRoot ? _rootTimeout : _subfolderTimeout;
// Explicit prop list — without it the server omits OC-namespaced
// properties like oc:fileid, which the preview endpoint relies on.
final prop = WebDavPropWithoutValues.fromBools(
davgetlastmodified: true,
davgetetag: true,
davgetcontenttype: true,
davgetcontentlength: true,
davresourcetype: true,
ocfileid: true,
ocsize: true,
nccreationtime: true,
nchaspreview: true,
);
final davFiles =
(await webdav.propfind(PathUri.parse(params.path)).timeout(timeout))
(await webdav
.propfind(PathUri.parse(params.path), prop: prop)
.timeout(timeout))
.toWebDavFiles();
final files = davFiles.map(CacheableFile.fromDavFile).toSet();