mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-02 06:46:22 +01:00
Correctly show shared items in a collaborative nc album
This commit is contained in:
parent
d2886e55c1
commit
4d9644ac18
28 changed files with 1347 additions and 98 deletions
|
@ -7,8 +7,9 @@ import 'package:logging/logging.dart';
|
|||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
import 'package:nc_photos/exception.dart';
|
||||
import 'package:np_api/np_api.dart';
|
||||
import 'package:np_api/np_api.dart' hide NcAlbumItem;
|
||||
import 'package:to_string/to_string.dart';
|
||||
|
||||
part 'api_util.g.dart';
|
||||
|
@ -76,6 +77,18 @@ String getFilePreviewUrlByFileId(
|
|||
return url;
|
||||
}
|
||||
|
||||
/// Return the preview image URL for an item in [NcAlbum]. We can't use the
|
||||
/// generic file preview url because collaborative albums do not create a file
|
||||
/// share for photos not belonging to you, that means you can only access the
|
||||
/// file view the Photos API
|
||||
String getNcAlbumFilePreviewUrl(
|
||||
Account account,
|
||||
NcAlbumItem item, {
|
||||
required int width,
|
||||
required int height,
|
||||
}) =>
|
||||
"${account.url}/apps/photos/api/v1/preview/${item.fileId}?x=$width&y=$height";
|
||||
|
||||
String getFileUrl(Account account, FileDescriptor file) {
|
||||
return "${account.url}/${getFileUrlRelative(file)}";
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:nc_photos/entity/face.dart';
|
|||
import 'package:nc_photos/entity/favorite.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/nc_album.dart';
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
import 'package:nc_photos/entity/person.dart';
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
import 'package:nc_photos/entity/sharee.dart';
|
||||
|
@ -35,7 +36,6 @@ class ApiFavoriteConverter {
|
|||
}
|
||||
}
|
||||
|
||||
@npLog
|
||||
class ApiFileConverter {
|
||||
static File fromApi(api.File file) {
|
||||
final metadata = file.customProperties?["com.nkming.nc_photos:metadata"]
|
||||
|
@ -79,26 +79,12 @@ class ApiFileConverter {
|
|||
?.run((obj) => ImageLocation.fromJson(jsonDecode(obj))),
|
||||
);
|
||||
}
|
||||
|
||||
static String _hrefToPath(String href) {
|
||||
final rawPath = href.trimLeftAny("/");
|
||||
final pos = rawPath.indexOf("remote.php");
|
||||
if (pos == -1) {
|
||||
// what?
|
||||
_log.warning("[_hrefToPath] Unknown href value: $rawPath");
|
||||
return rawPath;
|
||||
} else {
|
||||
return rawPath.substring(pos);
|
||||
}
|
||||
}
|
||||
|
||||
static final _log = _$ApiFileConverterNpLog.log;
|
||||
}
|
||||
|
||||
class ApiNcAlbumConverter {
|
||||
static NcAlbum fromApi(api.NcAlbum album) {
|
||||
return NcAlbum(
|
||||
path: album.href,
|
||||
path: _hrefToPath(album.href),
|
||||
lastPhoto: (album.lastPhoto ?? -1) < 0 ? null : album.lastPhoto,
|
||||
nbItems: album.nbItems ?? 0,
|
||||
location: album.location,
|
||||
|
@ -106,7 +92,30 @@ class ApiNcAlbumConverter {
|
|||
?.run((d) => DateTime.fromMillisecondsSinceEpoch(d * 1000)),
|
||||
dateEnd: (album.dateRange?["end"] as int?)
|
||||
?.run((d) => DateTime.fromMillisecondsSinceEpoch(d * 1000)),
|
||||
collaborators: const [],
|
||||
collaborators: album.collaborators
|
||||
.map((c) => NcAlbumCollaborator(
|
||||
id: c.id.toCi(),
|
||||
label: c.label,
|
||||
type: c.type,
|
||||
))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ApiNcAlbumItemConverter {
|
||||
static NcAlbumItem fromApi(api.NcAlbumItem item) {
|
||||
return NcAlbumItem(
|
||||
path: _hrefToPath(item.href),
|
||||
fileId: item.fileId!,
|
||||
contentLength: item.contentLength,
|
||||
contentType: item.contentType,
|
||||
etag: item.etag,
|
||||
lastModified: item.lastModified,
|
||||
hasPreview: item.hasPreview,
|
||||
isFavorite: item.favorite,
|
||||
fileMetadataWidth: item.fileMetadataSize?["width"],
|
||||
fileMetadataHeight: item.fileMetadataSize?["height"],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -188,3 +197,19 @@ class ApiTaggedFileConverter {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _hrefToPath(String href) {
|
||||
final rawPath = href.trimLeftAny("/");
|
||||
final pos = rawPath.indexOf("remote.php");
|
||||
if (pos == -1) {
|
||||
// what?
|
||||
_$_NpLog.log.warning("[_hrefToPath] Unknown href value: $rawPath");
|
||||
return rawPath;
|
||||
} else {
|
||||
return rawPath.substring(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@npLog
|
||||
// ignore: camel_case_types
|
||||
class _ {}
|
||||
|
|
|
@ -6,9 +6,9 @@ part of 'entity_converter.dart';
|
|||
// NpLogGenerator
|
||||
// **************************************************************************
|
||||
|
||||
extension _$ApiFileConverterNpLog on ApiFileConverter {
|
||||
extension _$_NpLog on _ {
|
||||
// ignore: unused_element
|
||||
Logger get _log => log;
|
||||
|
||||
static final log = Logger("api.entity_converter.ApiFileConverter");
|
||||
static final log = Logger("api.entity_converter._");
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:nc_photos/entity/collection/adapter/adapter_mixin.dart';
|
|||
import 'package:nc_photos/entity/collection/content_provider/nc_album.dart';
|
||||
import 'package:nc_photos/entity/collection_item.dart';
|
||||
import 'package:nc_photos/entity/collection_item/basic_item.dart';
|
||||
import 'package:nc_photos/entity/collection_item/nc_album_item_adapter.dart';
|
||||
import 'package:nc_photos/entity/collection_item/new_item.dart';
|
||||
import 'package:nc_photos/entity/collection_item/util.dart';
|
||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||
|
@ -41,14 +42,20 @@ class CollectionNcAlbumAdapter
|
|||
@override
|
||||
Stream<List<CollectionItem>> listItem() {
|
||||
return ListNcAlbumItem(_c)(account, _provider.album)
|
||||
.asyncMap((items) => FindFileDescriptor(_c)(
|
||||
account,
|
||||
items.map((e) => e.fileId).toList(),
|
||||
onFileNotFound: (fileId) {
|
||||
_log.severe("[listItem] File not found: $fileId");
|
||||
},
|
||||
))
|
||||
.map((files) => files.map(BasicCollectionFileItem.new).toList());
|
||||
.asyncMap((items) async {
|
||||
final found = await FindFileDescriptor(_c)(
|
||||
account,
|
||||
items.map((e) => e.fileId).toList(),
|
||||
onFileNotFound: (fileId) {
|
||||
// happens when this is a file shared with you
|
||||
_log.warning("[listItem] File not found: $fileId");
|
||||
},
|
||||
);
|
||||
return items.map((i) {
|
||||
final f = found.firstWhereOrNull((e) => e.fdId == i.fileId);
|
||||
return CollectionFileItemNcAlbumItemAdapter(i, f);
|
||||
}).toList();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -41,13 +41,19 @@ class CollectionNcAlbumProvider
|
|||
List<CollectionCapability> get capabilities => [
|
||||
CollectionCapability.manualItem,
|
||||
CollectionCapability.rename,
|
||||
// CollectionCapability.share,
|
||||
];
|
||||
|
||||
@override
|
||||
CollectionItemSort get itemSort => CollectionItemSort.dateDescending;
|
||||
|
||||
@override
|
||||
List<CollectionShare> get shares => [];
|
||||
List<CollectionShare> get shares => album.collaborators
|
||||
.map((c) => CollectionShare(
|
||||
userId: c.id,
|
||||
username: c.label,
|
||||
))
|
||||
.toList();
|
||||
|
||||
@override
|
||||
String? getCoverUrl(
|
||||
|
|
20
app/lib/entity/collection_item/nc_album_item_adapter.dart
Normal file
20
app/lib/entity/collection_item/nc_album_item_adapter.dart
Normal file
|
@ -0,0 +1,20 @@
|
|||
import 'package:nc_photos/entity/collection_item.dart';
|
||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
import 'package:to_string/to_string.dart';
|
||||
|
||||
part 'nc_album_item_adapter.g.dart';
|
||||
|
||||
@toString
|
||||
class CollectionFileItemNcAlbumItemAdapter extends CollectionFileItem {
|
||||
const CollectionFileItemNcAlbumItemAdapter(this.item, [this.localFile]);
|
||||
|
||||
@override
|
||||
String toString() => _$toString();
|
||||
|
||||
@override
|
||||
FileDescriptor get file => localFile ?? item.toFile();
|
||||
|
||||
final NcAlbumItem item;
|
||||
final FileDescriptor? localFile;
|
||||
}
|
15
app/lib/entity/collection_item/nc_album_item_adapter.g.dart
Normal file
15
app/lib/entity/collection_item/nc_album_item_adapter.g.dart
Normal file
|
@ -0,0 +1,15 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'nc_album_item_adapter.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// ToStringGenerator
|
||||
// **************************************************************************
|
||||
|
||||
extension _$CollectionFileItemNcAlbumItemAdapterToString
|
||||
on CollectionFileItemNcAlbumItemAdapter {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "CollectionFileItemNcAlbumItemAdapter {item: $item, localFile: ${localFile == null ? null : "${localFile!.fdPath}"}}";
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
import 'package:copy_with/copy_with.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:np_common/ci_string.dart';
|
||||
import 'package:np_common/string_extension.dart';
|
||||
import 'package:np_common/type.dart';
|
||||
import 'package:to_string/to_string.dart';
|
||||
|
||||
part 'nc_album.g.dart';
|
||||
|
@ -109,4 +111,31 @@ extension NcAlbumExtension on NcAlbum {
|
|||
int get identityHashCode => path.hashCode;
|
||||
}
|
||||
|
||||
class NcAlbumCollaborator {}
|
||||
@toString
|
||||
class NcAlbumCollaborator {
|
||||
const NcAlbumCollaborator({
|
||||
required this.id,
|
||||
required this.label,
|
||||
required this.type,
|
||||
});
|
||||
|
||||
factory NcAlbumCollaborator.fromJson(JsonObj json) => NcAlbumCollaborator(
|
||||
id: CiString(json["id"]),
|
||||
label: json["label"],
|
||||
type: json["type"],
|
||||
);
|
||||
|
||||
JsonObj toJson() => {
|
||||
"id": id.raw,
|
||||
"label": label,
|
||||
"type": type,
|
||||
};
|
||||
|
||||
@override
|
||||
String toString() => _$toString();
|
||||
|
||||
final CiString id;
|
||||
final String label;
|
||||
// right now it's unclear what this variable represents
|
||||
final int type;
|
||||
}
|
||||
|
|
|
@ -67,3 +67,10 @@ extension _$NcAlbumToString on NcAlbum {
|
|||
return "NcAlbum {path: $path, lastPhoto: $lastPhoto, nbItems: $nbItems, location: $location, dateStart: $dateStart, dateEnd: $dateEnd, collaborators: [length: ${collaborators.length}]}";
|
||||
}
|
||||
}
|
||||
|
||||
extension _$NcAlbumCollaboratorToString on NcAlbumCollaborator {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "NcAlbumCollaborator {id: $id, label: $label, type: $type}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import 'package:logging/logging.dart';
|
|||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/api/entity_converter.dart';
|
||||
import 'package:nc_photos/entity/nc_album.dart';
|
||||
import 'package:nc_photos/entity/nc_album/item.dart';
|
||||
import 'package:nc_photos/entity/nc_album/repo.dart';
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||
import 'package:nc_photos/entity/sqlite/type_converter.dart';
|
||||
import 'package:nc_photos/exception.dart';
|
||||
|
@ -85,9 +85,21 @@ class NcAlbumRemoteDataSource implements NcAlbumDataSource {
|
|||
_log.info(
|
||||
"[getItems] account: ${account.userId}, album: ${album.strippedPath}");
|
||||
final response = await ApiUtil.fromAccount(account).files().propfind(
|
||||
path: album.path,
|
||||
fileid: 1,
|
||||
);
|
||||
path: album.path,
|
||||
getlastmodified: 1,
|
||||
getetag: 1,
|
||||
getcontenttype: 1,
|
||||
getcontentlength: 1,
|
||||
hasPreview: 1,
|
||||
fileid: 1,
|
||||
favorite: 1,
|
||||
customProperties: [
|
||||
"nc:file-metadata-size",
|
||||
"nc:face-detections",
|
||||
"nc:realpath",
|
||||
"oc:permissions",
|
||||
],
|
||||
);
|
||||
if (!response.isGood) {
|
||||
_log.severe("[getItems] Failed requesting server: $response");
|
||||
throw ApiException(
|
||||
|
@ -96,11 +108,10 @@ class NcAlbumRemoteDataSource implements NcAlbumDataSource {
|
|||
);
|
||||
}
|
||||
|
||||
final apiFiles = await api.FileParser().parse(response.body);
|
||||
final apiFiles = await api.NcAlbumItemParser().parse(response.body);
|
||||
return apiFiles
|
||||
.where((f) => f.fileId != null)
|
||||
.map(ApiFileConverter.fromApi)
|
||||
.map((f) => NcAlbumItem(f.fileId!))
|
||||
.map(ApiNcAlbumItemConverter.fromApi)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +172,19 @@ class NcAlbumSqliteDbDataSource implements NcAlbumCacheDataSource {
|
|||
parentRelativePath: album.strippedPath,
|
||||
);
|
||||
});
|
||||
return dbItems.map((i) => NcAlbumItem(i.fileId)).toList();
|
||||
return dbItems
|
||||
.map((i) {
|
||||
try {
|
||||
return SqliteNcAlbumItemConverter.fromSql(
|
||||
account.userId.toString(), album.strippedPath, i);
|
||||
} catch (e, stackTrace) {
|
||||
_log.severe(
|
||||
"[getItems] Failed while converting DB entry", e, stackTrace);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.whereNotNull()
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -213,25 +236,32 @@ class NcAlbumSqliteDbDataSource implements NcAlbumCacheDataSource {
|
|||
final existingItems = await db.ncAlbumItemsByParent(
|
||||
parent: dbAlbum!,
|
||||
);
|
||||
final idDiff = list_util.diff(
|
||||
existingItems.map((e) => e.fileId).sorted((a, b) => a.compareTo(b)),
|
||||
remote.map((e) => e.fileId).sorted((a, b) => a.compareTo(b)),
|
||||
final diff = list_util.diffWith<NcAlbumItem>(
|
||||
existingItems
|
||||
.map((e) => SqliteNcAlbumItemConverter.fromSql(
|
||||
account.userId.raw, album.strippedPath, e))
|
||||
.sorted(NcAlbumItemExtension.identityComparator),
|
||||
remote.sorted(NcAlbumItemExtension.identityComparator),
|
||||
NcAlbumItemExtension.identityComparator,
|
||||
);
|
||||
if (idDiff.onlyInA.isNotEmpty || idDiff.onlyInB.isNotEmpty) {
|
||||
if (diff.onlyInA.isNotEmpty || diff.onlyInB.isNotEmpty) {
|
||||
await db.batch((batch) async {
|
||||
for (final id in idDiff.onlyInB) {
|
||||
for (final item in diff.onlyInB) {
|
||||
// new
|
||||
batch.insert(
|
||||
db.ncAlbumItems,
|
||||
SqliteNcAlbumItemConverter.toSql(dbAlbum, id),
|
||||
SqliteNcAlbumItemConverter.toSql(dbAlbum, item),
|
||||
);
|
||||
}
|
||||
final rmIds = diff.onlyInA.map((e) => e.fileId).toList();
|
||||
if (rmIds.isNotEmpty) {
|
||||
// removed
|
||||
batch.deleteWhere(
|
||||
db.ncAlbumItems,
|
||||
(sql.$NcAlbumItemsTable t) =>
|
||||
t.parent.equals(dbAlbum.rowId) & t.fileId.isIn(rmIds),
|
||||
);
|
||||
}
|
||||
// removed
|
||||
batch.deleteWhere(
|
||||
db.ncAlbumItems,
|
||||
(sql.$NcAlbumItemsTable t) =>
|
||||
t.parent.equals(dbAlbum.rowId) & t.fileId.isIn(idDiff.onlyInA),
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
class NcAlbumItem {
|
||||
const NcAlbumItem(this.fileId);
|
||||
|
||||
final int fileId;
|
||||
}
|
|
@ -3,7 +3,7 @@ import 'dart:async';
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/entity/nc_album.dart';
|
||||
import 'package:nc_photos/entity/nc_album/item.dart';
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
import 'package:np_codegen/np_codegen.dart';
|
||||
|
||||
part 'repo.g.dart';
|
||||
|
|
95
app/lib/entity/nc_album_item.dart
Normal file
95
app/lib/entity/nc_album_item.dart
Normal file
|
@ -0,0 +1,95 @@
|
|||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:np_common/string_extension.dart';
|
||||
import 'package:to_string/to_string.dart';
|
||||
|
||||
part 'nc_album_item.g.dart';
|
||||
|
||||
@ToString(ignoreNull: true)
|
||||
class NcAlbumItem {
|
||||
const NcAlbumItem({
|
||||
required this.path,
|
||||
required this.fileId,
|
||||
this.contentLength,
|
||||
this.contentType,
|
||||
this.etag,
|
||||
this.lastModified,
|
||||
this.hasPreview,
|
||||
this.isFavorite,
|
||||
this.fileMetadataWidth,
|
||||
this.fileMetadataHeight,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => _$toString();
|
||||
|
||||
final String path;
|
||||
final int fileId;
|
||||
final int? contentLength;
|
||||
final String? contentType;
|
||||
final String? etag;
|
||||
final DateTime? lastModified;
|
||||
final bool? hasPreview;
|
||||
final bool? isFavorite;
|
||||
final int? fileMetadataWidth;
|
||||
final int? fileMetadataHeight;
|
||||
}
|
||||
|
||||
extension NcAlbumItemExtension on NcAlbumItem {
|
||||
/// Return the path of this file with the DAV part stripped
|
||||
///
|
||||
/// WebDAV file path: remote.php/dav/photos/{userId}/albums/{album}/{strippedPath}.
|
||||
/// If this path points to the user's root album path, return "."
|
||||
String get strippedPath {
|
||||
if (!path.startsWith("remote.php/dav/photos/")) {
|
||||
return path;
|
||||
}
|
||||
var begin = "remote.php/dav/photos/".length;
|
||||
begin = path.indexOf("/", begin);
|
||||
if (begin == -1) {
|
||||
return path;
|
||||
}
|
||||
if (path.slice(begin, begin + 7) != "/albums") {
|
||||
return path;
|
||||
}
|
||||
// /albums/
|
||||
begin += 8;
|
||||
begin = path.indexOf("/", begin);
|
||||
if (begin == -1) {
|
||||
return path;
|
||||
}
|
||||
final stripped = path.slice(begin + 1);
|
||||
if (stripped.isEmpty) {
|
||||
return ".";
|
||||
} else {
|
||||
return stripped;
|
||||
}
|
||||
}
|
||||
|
||||
bool compareIdentity(NcAlbumItem other) => fileId == other.fileId;
|
||||
|
||||
int get identityHashCode => fileId.hashCode;
|
||||
|
||||
static int identityComparator(NcAlbumItem a, NcAlbumItem b) =>
|
||||
a.fileId.compareTo(b.fileId);
|
||||
|
||||
File toFile() {
|
||||
Metadata? metadata;
|
||||
if (fileMetadataWidth != null && fileMetadataHeight != null) {
|
||||
metadata = Metadata(
|
||||
imageWidth: fileMetadataWidth,
|
||||
imageHeight: fileMetadataHeight,
|
||||
);
|
||||
}
|
||||
return File(
|
||||
path: path,
|
||||
fileId: fileId,
|
||||
contentLength: contentLength,
|
||||
contentType: contentType,
|
||||
etag: etag,
|
||||
lastModified: lastModified,
|
||||
hasPreview: hasPreview,
|
||||
isFavorite: isFavorite,
|
||||
metadata: metadata,
|
||||
);
|
||||
}
|
||||
}
|
14
app/lib/entity/nc_album_item.g.dart
Normal file
14
app/lib/entity/nc_album_item.g.dart
Normal file
|
@ -0,0 +1,14 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'nc_album_item.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// ToStringGenerator
|
||||
// **************************************************************************
|
||||
|
||||
extension _$NcAlbumItemToString on NcAlbumItem {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "NcAlbumItem {path: $path, fileId: $fileId, ${contentLength == null ? "" : "contentLength: $contentLength, "}${contentType == null ? "" : "contentType: $contentType, "}${etag == null ? "" : "etag: $etag, "}${lastModified == null ? "" : "lastModified: $lastModified, "}${hasPreview == null ? "" : "hasPreview: $hasPreview, "}${isFavorite == null ? "" : "isFavorite: $isFavorite, "}${fileMetadataWidth == null ? "" : "fileMetadataWidth: $fileMetadataWidth, "}${fileMetadataHeight == null ? "" : "fileMetadataHeight: $fileMetadataHeight"}}";
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ class SqliteDb extends _$SqliteDb {
|
|||
SqliteDb.connect(DatabaseConnection connection) : super.connect(connection);
|
||||
|
||||
@override
|
||||
get schemaVersion => 4;
|
||||
get schemaVersion => 5;
|
||||
|
||||
@override
|
||||
get migration => MigrationStrategy(
|
||||
|
@ -98,6 +98,10 @@ class SqliteDb extends _$SqliteDb {
|
|||
if (from < 4) {
|
||||
await m.addColumn(albums, albums.fileEtag);
|
||||
}
|
||||
if (from < 5) {
|
||||
await m.createTable(ncAlbums);
|
||||
await m.createTable(ncAlbumItems);
|
||||
}
|
||||
});
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout("[onUpgrade] Failed upgrading sqlite db", e, stackTrace);
|
||||
|
|
|
@ -4166,6 +4166,7 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
final String? location;
|
||||
final DateTime? dateStart;
|
||||
final DateTime? dateEnd;
|
||||
final String collaborators;
|
||||
NcAlbum(
|
||||
{required this.rowId,
|
||||
required this.account,
|
||||
|
@ -4174,7 +4175,8 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
required this.nbItems,
|
||||
this.location,
|
||||
this.dateStart,
|
||||
this.dateEnd});
|
||||
this.dateEnd,
|
||||
required this.collaborators});
|
||||
factory NcAlbum.fromData(Map<String, dynamic> data, {String? prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
return NcAlbum(
|
||||
|
@ -4194,6 +4196,8 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
.mapFromDatabaseResponse(data['${effectivePrefix}date_start'])),
|
||||
dateEnd: $NcAlbumsTable.$converter1.mapToDart(const DateTimeType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}date_end'])),
|
||||
collaborators: const StringType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}collaborators'])!,
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -4217,6 +4221,7 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
final converter = $NcAlbumsTable.$converter1;
|
||||
map['date_end'] = Variable<DateTime?>(converter.mapToSql(dateEnd));
|
||||
}
|
||||
map['collaborators'] = Variable<String>(collaborators);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -4238,6 +4243,7 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
dateEnd: dateEnd == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(dateEnd),
|
||||
collaborators: Value(collaborators),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4253,6 +4259,7 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
location: serializer.fromJson<String?>(json['location']),
|
||||
dateStart: serializer.fromJson<DateTime?>(json['dateStart']),
|
||||
dateEnd: serializer.fromJson<DateTime?>(json['dateEnd']),
|
||||
collaborators: serializer.fromJson<String>(json['collaborators']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -4267,6 +4274,7 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
'location': serializer.toJson<String?>(location),
|
||||
'dateStart': serializer.toJson<DateTime?>(dateStart),
|
||||
'dateEnd': serializer.toJson<DateTime?>(dateEnd),
|
||||
'collaborators': serializer.toJson<String>(collaborators),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4278,7 +4286,8 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
int? nbItems,
|
||||
Value<String?> location = const Value.absent(),
|
||||
Value<DateTime?> dateStart = const Value.absent(),
|
||||
Value<DateTime?> dateEnd = const Value.absent()}) =>
|
||||
Value<DateTime?> dateEnd = const Value.absent(),
|
||||
String? collaborators}) =>
|
||||
NcAlbum(
|
||||
rowId: rowId ?? this.rowId,
|
||||
account: account ?? this.account,
|
||||
|
@ -4288,6 +4297,7 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
location: location.present ? location.value : this.location,
|
||||
dateStart: dateStart.present ? dateStart.value : this.dateStart,
|
||||
dateEnd: dateEnd.present ? dateEnd.value : this.dateEnd,
|
||||
collaborators: collaborators ?? this.collaborators,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
|
@ -4299,14 +4309,15 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
..write('nbItems: $nbItems, ')
|
||||
..write('location: $location, ')
|
||||
..write('dateStart: $dateStart, ')
|
||||
..write('dateEnd: $dateEnd')
|
||||
..write('dateEnd: $dateEnd, ')
|
||||
..write('collaborators: $collaborators')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(rowId, account, relativePath, lastPhoto,
|
||||
nbItems, location, dateStart, dateEnd);
|
||||
nbItems, location, dateStart, dateEnd, collaborators);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
|
@ -4318,7 +4329,8 @@ class NcAlbum extends DataClass implements Insertable<NcAlbum> {
|
|||
other.nbItems == this.nbItems &&
|
||||
other.location == this.location &&
|
||||
other.dateStart == this.dateStart &&
|
||||
other.dateEnd == this.dateEnd);
|
||||
other.dateEnd == this.dateEnd &&
|
||||
other.collaborators == this.collaborators);
|
||||
}
|
||||
|
||||
class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
||||
|
@ -4330,6 +4342,7 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
final Value<String?> location;
|
||||
final Value<DateTime?> dateStart;
|
||||
final Value<DateTime?> dateEnd;
|
||||
final Value<String> collaborators;
|
||||
const NcAlbumsCompanion({
|
||||
this.rowId = const Value.absent(),
|
||||
this.account = const Value.absent(),
|
||||
|
@ -4339,6 +4352,7 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
this.location = const Value.absent(),
|
||||
this.dateStart = const Value.absent(),
|
||||
this.dateEnd = const Value.absent(),
|
||||
this.collaborators = const Value.absent(),
|
||||
});
|
||||
NcAlbumsCompanion.insert({
|
||||
this.rowId = const Value.absent(),
|
||||
|
@ -4349,9 +4363,11 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
this.location = const Value.absent(),
|
||||
this.dateStart = const Value.absent(),
|
||||
this.dateEnd = const Value.absent(),
|
||||
required String collaborators,
|
||||
}) : account = Value(account),
|
||||
relativePath = Value(relativePath),
|
||||
nbItems = Value(nbItems);
|
||||
nbItems = Value(nbItems),
|
||||
collaborators = Value(collaborators);
|
||||
static Insertable<NcAlbum> custom({
|
||||
Expression<int>? rowId,
|
||||
Expression<int>? account,
|
||||
|
@ -4361,6 +4377,7 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
Expression<String?>? location,
|
||||
Expression<DateTime?>? dateStart,
|
||||
Expression<DateTime?>? dateEnd,
|
||||
Expression<String>? collaborators,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (rowId != null) 'row_id': rowId,
|
||||
|
@ -4371,6 +4388,7 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
if (location != null) 'location': location,
|
||||
if (dateStart != null) 'date_start': dateStart,
|
||||
if (dateEnd != null) 'date_end': dateEnd,
|
||||
if (collaborators != null) 'collaborators': collaborators,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -4382,7 +4400,8 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
Value<int>? nbItems,
|
||||
Value<String?>? location,
|
||||
Value<DateTime?>? dateStart,
|
||||
Value<DateTime?>? dateEnd}) {
|
||||
Value<DateTime?>? dateEnd,
|
||||
Value<String>? collaborators}) {
|
||||
return NcAlbumsCompanion(
|
||||
rowId: rowId ?? this.rowId,
|
||||
account: account ?? this.account,
|
||||
|
@ -4392,6 +4411,7 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
location: location ?? this.location,
|
||||
dateStart: dateStart ?? this.dateStart,
|
||||
dateEnd: dateEnd ?? this.dateEnd,
|
||||
collaborators: collaborators ?? this.collaborators,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4425,6 +4445,9 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
final converter = $NcAlbumsTable.$converter1;
|
||||
map['date_end'] = Variable<DateTime?>(converter.mapToSql(dateEnd.value));
|
||||
}
|
||||
if (collaborators.present) {
|
||||
map['collaborators'] = Variable<String>(collaborators.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -4438,7 +4461,8 @@ class NcAlbumsCompanion extends UpdateCompanion<NcAlbum> {
|
|||
..write('nbItems: $nbItems, ')
|
||||
..write('location: $location, ')
|
||||
..write('dateStart: $dateStart, ')
|
||||
..write('dateEnd: $dateEnd')
|
||||
..write('dateEnd: $dateEnd, ')
|
||||
..write('collaborators: $collaborators')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -4496,6 +4520,12 @@ class $NcAlbumsTable extends NcAlbums with TableInfo<$NcAlbumsTable, NcAlbum> {
|
|||
GeneratedColumn<DateTime?>('date_end', aliasedName, true,
|
||||
type: const IntType(), requiredDuringInsert: false)
|
||||
.withConverter<DateTime>($NcAlbumsTable.$converter1);
|
||||
final VerificationMeta _collaboratorsMeta =
|
||||
const VerificationMeta('collaborators');
|
||||
@override
|
||||
late final GeneratedColumn<String?> collaborators = GeneratedColumn<String?>(
|
||||
'collaborators', aliasedName, false,
|
||||
type: const StringType(), requiredDuringInsert: true);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [
|
||||
rowId,
|
||||
|
@ -4505,7 +4535,8 @@ class $NcAlbumsTable extends NcAlbums with TableInfo<$NcAlbumsTable, NcAlbum> {
|
|||
nbItems,
|
||||
location,
|
||||
dateStart,
|
||||
dateEnd
|
||||
dateEnd,
|
||||
collaborators
|
||||
];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'nc_albums';
|
||||
|
@ -4550,6 +4581,14 @@ class $NcAlbumsTable extends NcAlbums with TableInfo<$NcAlbumsTable, NcAlbum> {
|
|||
}
|
||||
context.handle(_dateStartMeta, const VerificationResult.success());
|
||||
context.handle(_dateEndMeta, const VerificationResult.success());
|
||||
if (data.containsKey('collaborators')) {
|
||||
context.handle(
|
||||
_collaboratorsMeta,
|
||||
collaborators.isAcceptableOrUnknown(
|
||||
data['collaborators']!, _collaboratorsMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_collaboratorsMeta);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -4579,9 +4618,29 @@ class $NcAlbumsTable extends NcAlbums with TableInfo<$NcAlbumsTable, NcAlbum> {
|
|||
class NcAlbumItem extends DataClass implements Insertable<NcAlbumItem> {
|
||||
final int rowId;
|
||||
final int parent;
|
||||
final String relativePath;
|
||||
final int fileId;
|
||||
final int? contentLength;
|
||||
final String? contentType;
|
||||
final String? etag;
|
||||
final DateTime? lastModified;
|
||||
final bool? hasPreview;
|
||||
final bool? isFavorite;
|
||||
final int? fileMetadataWidth;
|
||||
final int? fileMetadataHeight;
|
||||
NcAlbumItem(
|
||||
{required this.rowId, required this.parent, required this.fileId});
|
||||
{required this.rowId,
|
||||
required this.parent,
|
||||
required this.relativePath,
|
||||
required this.fileId,
|
||||
this.contentLength,
|
||||
this.contentType,
|
||||
this.etag,
|
||||
this.lastModified,
|
||||
this.hasPreview,
|
||||
this.isFavorite,
|
||||
this.fileMetadataWidth,
|
||||
this.fileMetadataHeight});
|
||||
factory NcAlbumItem.fromData(Map<String, dynamic> data, {String? prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
return NcAlbumItem(
|
||||
|
@ -4589,8 +4648,27 @@ class NcAlbumItem extends DataClass implements Insertable<NcAlbumItem> {
|
|||
.mapFromDatabaseResponse(data['${effectivePrefix}row_id'])!,
|
||||
parent: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}parent'])!,
|
||||
relativePath: const StringType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}relative_path'])!,
|
||||
fileId: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}file_id'])!,
|
||||
contentLength: const IntType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}content_length']),
|
||||
contentType: const StringType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}content_type']),
|
||||
etag: const StringType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}etag']),
|
||||
lastModified: $NcAlbumItemsTable.$converter0.mapToDart(
|
||||
const DateTimeType().mapFromDatabaseResponse(
|
||||
data['${effectivePrefix}last_modified'])),
|
||||
hasPreview: const BoolType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}has_preview']),
|
||||
isFavorite: const BoolType()
|
||||
.mapFromDatabaseResponse(data['${effectivePrefix}is_favorite']),
|
||||
fileMetadataWidth: const IntType().mapFromDatabaseResponse(
|
||||
data['${effectivePrefix}file_metadata_width']),
|
||||
fileMetadataHeight: const IntType().mapFromDatabaseResponse(
|
||||
data['${effectivePrefix}file_metadata_height']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -4598,7 +4676,34 @@ class NcAlbumItem extends DataClass implements Insertable<NcAlbumItem> {
|
|||
final map = <String, Expression>{};
|
||||
map['row_id'] = Variable<int>(rowId);
|
||||
map['parent'] = Variable<int>(parent);
|
||||
map['relative_path'] = Variable<String>(relativePath);
|
||||
map['file_id'] = Variable<int>(fileId);
|
||||
if (!nullToAbsent || contentLength != null) {
|
||||
map['content_length'] = Variable<int?>(contentLength);
|
||||
}
|
||||
if (!nullToAbsent || contentType != null) {
|
||||
map['content_type'] = Variable<String?>(contentType);
|
||||
}
|
||||
if (!nullToAbsent || etag != null) {
|
||||
map['etag'] = Variable<String?>(etag);
|
||||
}
|
||||
if (!nullToAbsent || lastModified != null) {
|
||||
final converter = $NcAlbumItemsTable.$converter0;
|
||||
map['last_modified'] =
|
||||
Variable<DateTime?>(converter.mapToSql(lastModified));
|
||||
}
|
||||
if (!nullToAbsent || hasPreview != null) {
|
||||
map['has_preview'] = Variable<bool?>(hasPreview);
|
||||
}
|
||||
if (!nullToAbsent || isFavorite != null) {
|
||||
map['is_favorite'] = Variable<bool?>(isFavorite);
|
||||
}
|
||||
if (!nullToAbsent || fileMetadataWidth != null) {
|
||||
map['file_metadata_width'] = Variable<int?>(fileMetadataWidth);
|
||||
}
|
||||
if (!nullToAbsent || fileMetadataHeight != null) {
|
||||
map['file_metadata_height'] = Variable<int?>(fileMetadataHeight);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -4606,7 +4711,30 @@ class NcAlbumItem extends DataClass implements Insertable<NcAlbumItem> {
|
|||
return NcAlbumItemsCompanion(
|
||||
rowId: Value(rowId),
|
||||
parent: Value(parent),
|
||||
relativePath: Value(relativePath),
|
||||
fileId: Value(fileId),
|
||||
contentLength: contentLength == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(contentLength),
|
||||
contentType: contentType == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(contentType),
|
||||
etag: etag == null && nullToAbsent ? const Value.absent() : Value(etag),
|
||||
lastModified: lastModified == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(lastModified),
|
||||
hasPreview: hasPreview == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(hasPreview),
|
||||
isFavorite: isFavorite == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(isFavorite),
|
||||
fileMetadataWidth: fileMetadataWidth == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(fileMetadataWidth),
|
||||
fileMetadataHeight: fileMetadataHeight == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(fileMetadataHeight),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4616,7 +4744,16 @@ class NcAlbumItem extends DataClass implements Insertable<NcAlbumItem> {
|
|||
return NcAlbumItem(
|
||||
rowId: serializer.fromJson<int>(json['rowId']),
|
||||
parent: serializer.fromJson<int>(json['parent']),
|
||||
relativePath: serializer.fromJson<String>(json['relativePath']),
|
||||
fileId: serializer.fromJson<int>(json['fileId']),
|
||||
contentLength: serializer.fromJson<int?>(json['contentLength']),
|
||||
contentType: serializer.fromJson<String?>(json['contentType']),
|
||||
etag: serializer.fromJson<String?>(json['etag']),
|
||||
lastModified: serializer.fromJson<DateTime?>(json['lastModified']),
|
||||
hasPreview: serializer.fromJson<bool?>(json['hasPreview']),
|
||||
isFavorite: serializer.fromJson<bool?>(json['isFavorite']),
|
||||
fileMetadataWidth: serializer.fromJson<int?>(json['fileMetadataWidth']),
|
||||
fileMetadataHeight: serializer.fromJson<int?>(json['fileMetadataHeight']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -4625,69 +4762,203 @@ class NcAlbumItem extends DataClass implements Insertable<NcAlbumItem> {
|
|||
return <String, dynamic>{
|
||||
'rowId': serializer.toJson<int>(rowId),
|
||||
'parent': serializer.toJson<int>(parent),
|
||||
'relativePath': serializer.toJson<String>(relativePath),
|
||||
'fileId': serializer.toJson<int>(fileId),
|
||||
'contentLength': serializer.toJson<int?>(contentLength),
|
||||
'contentType': serializer.toJson<String?>(contentType),
|
||||
'etag': serializer.toJson<String?>(etag),
|
||||
'lastModified': serializer.toJson<DateTime?>(lastModified),
|
||||
'hasPreview': serializer.toJson<bool?>(hasPreview),
|
||||
'isFavorite': serializer.toJson<bool?>(isFavorite),
|
||||
'fileMetadataWidth': serializer.toJson<int?>(fileMetadataWidth),
|
||||
'fileMetadataHeight': serializer.toJson<int?>(fileMetadataHeight),
|
||||
};
|
||||
}
|
||||
|
||||
NcAlbumItem copyWith({int? rowId, int? parent, int? fileId}) => NcAlbumItem(
|
||||
NcAlbumItem copyWith(
|
||||
{int? rowId,
|
||||
int? parent,
|
||||
String? relativePath,
|
||||
int? fileId,
|
||||
Value<int?> contentLength = const Value.absent(),
|
||||
Value<String?> contentType = const Value.absent(),
|
||||
Value<String?> etag = const Value.absent(),
|
||||
Value<DateTime?> lastModified = const Value.absent(),
|
||||
Value<bool?> hasPreview = const Value.absent(),
|
||||
Value<bool?> isFavorite = const Value.absent(),
|
||||
Value<int?> fileMetadataWidth = const Value.absent(),
|
||||
Value<int?> fileMetadataHeight = const Value.absent()}) =>
|
||||
NcAlbumItem(
|
||||
rowId: rowId ?? this.rowId,
|
||||
parent: parent ?? this.parent,
|
||||
relativePath: relativePath ?? this.relativePath,
|
||||
fileId: fileId ?? this.fileId,
|
||||
contentLength:
|
||||
contentLength.present ? contentLength.value : this.contentLength,
|
||||
contentType: contentType.present ? contentType.value : this.contentType,
|
||||
etag: etag.present ? etag.value : this.etag,
|
||||
lastModified:
|
||||
lastModified.present ? lastModified.value : this.lastModified,
|
||||
hasPreview: hasPreview.present ? hasPreview.value : this.hasPreview,
|
||||
isFavorite: isFavorite.present ? isFavorite.value : this.isFavorite,
|
||||
fileMetadataWidth: fileMetadataWidth.present
|
||||
? fileMetadataWidth.value
|
||||
: this.fileMetadataWidth,
|
||||
fileMetadataHeight: fileMetadataHeight.present
|
||||
? fileMetadataHeight.value
|
||||
: this.fileMetadataHeight,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('NcAlbumItem(')
|
||||
..write('rowId: $rowId, ')
|
||||
..write('parent: $parent, ')
|
||||
..write('fileId: $fileId')
|
||||
..write('relativePath: $relativePath, ')
|
||||
..write('fileId: $fileId, ')
|
||||
..write('contentLength: $contentLength, ')
|
||||
..write('contentType: $contentType, ')
|
||||
..write('etag: $etag, ')
|
||||
..write('lastModified: $lastModified, ')
|
||||
..write('hasPreview: $hasPreview, ')
|
||||
..write('isFavorite: $isFavorite, ')
|
||||
..write('fileMetadataWidth: $fileMetadataWidth, ')
|
||||
..write('fileMetadataHeight: $fileMetadataHeight')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(rowId, parent, fileId);
|
||||
int get hashCode => Object.hash(
|
||||
rowId,
|
||||
parent,
|
||||
relativePath,
|
||||
fileId,
|
||||
contentLength,
|
||||
contentType,
|
||||
etag,
|
||||
lastModified,
|
||||
hasPreview,
|
||||
isFavorite,
|
||||
fileMetadataWidth,
|
||||
fileMetadataHeight);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is NcAlbumItem &&
|
||||
other.rowId == this.rowId &&
|
||||
other.parent == this.parent &&
|
||||
other.fileId == this.fileId);
|
||||
other.relativePath == this.relativePath &&
|
||||
other.fileId == this.fileId &&
|
||||
other.contentLength == this.contentLength &&
|
||||
other.contentType == this.contentType &&
|
||||
other.etag == this.etag &&
|
||||
other.lastModified == this.lastModified &&
|
||||
other.hasPreview == this.hasPreview &&
|
||||
other.isFavorite == this.isFavorite &&
|
||||
other.fileMetadataWidth == this.fileMetadataWidth &&
|
||||
other.fileMetadataHeight == this.fileMetadataHeight);
|
||||
}
|
||||
|
||||
class NcAlbumItemsCompanion extends UpdateCompanion<NcAlbumItem> {
|
||||
final Value<int> rowId;
|
||||
final Value<int> parent;
|
||||
final Value<String> relativePath;
|
||||
final Value<int> fileId;
|
||||
final Value<int?> contentLength;
|
||||
final Value<String?> contentType;
|
||||
final Value<String?> etag;
|
||||
final Value<DateTime?> lastModified;
|
||||
final Value<bool?> hasPreview;
|
||||
final Value<bool?> isFavorite;
|
||||
final Value<int?> fileMetadataWidth;
|
||||
final Value<int?> fileMetadataHeight;
|
||||
const NcAlbumItemsCompanion({
|
||||
this.rowId = const Value.absent(),
|
||||
this.parent = const Value.absent(),
|
||||
this.relativePath = const Value.absent(),
|
||||
this.fileId = const Value.absent(),
|
||||
this.contentLength = const Value.absent(),
|
||||
this.contentType = const Value.absent(),
|
||||
this.etag = const Value.absent(),
|
||||
this.lastModified = const Value.absent(),
|
||||
this.hasPreview = const Value.absent(),
|
||||
this.isFavorite = const Value.absent(),
|
||||
this.fileMetadataWidth = const Value.absent(),
|
||||
this.fileMetadataHeight = const Value.absent(),
|
||||
});
|
||||
NcAlbumItemsCompanion.insert({
|
||||
this.rowId = const Value.absent(),
|
||||
required int parent,
|
||||
required String relativePath,
|
||||
required int fileId,
|
||||
this.contentLength = const Value.absent(),
|
||||
this.contentType = const Value.absent(),
|
||||
this.etag = const Value.absent(),
|
||||
this.lastModified = const Value.absent(),
|
||||
this.hasPreview = const Value.absent(),
|
||||
this.isFavorite = const Value.absent(),
|
||||
this.fileMetadataWidth = const Value.absent(),
|
||||
this.fileMetadataHeight = const Value.absent(),
|
||||
}) : parent = Value(parent),
|
||||
relativePath = Value(relativePath),
|
||||
fileId = Value(fileId);
|
||||
static Insertable<NcAlbumItem> custom({
|
||||
Expression<int>? rowId,
|
||||
Expression<int>? parent,
|
||||
Expression<String>? relativePath,
|
||||
Expression<int>? fileId,
|
||||
Expression<int?>? contentLength,
|
||||
Expression<String?>? contentType,
|
||||
Expression<String?>? etag,
|
||||
Expression<DateTime?>? lastModified,
|
||||
Expression<bool?>? hasPreview,
|
||||
Expression<bool?>? isFavorite,
|
||||
Expression<int?>? fileMetadataWidth,
|
||||
Expression<int?>? fileMetadataHeight,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (rowId != null) 'row_id': rowId,
|
||||
if (parent != null) 'parent': parent,
|
||||
if (relativePath != null) 'relative_path': relativePath,
|
||||
if (fileId != null) 'file_id': fileId,
|
||||
if (contentLength != null) 'content_length': contentLength,
|
||||
if (contentType != null) 'content_type': contentType,
|
||||
if (etag != null) 'etag': etag,
|
||||
if (lastModified != null) 'last_modified': lastModified,
|
||||
if (hasPreview != null) 'has_preview': hasPreview,
|
||||
if (isFavorite != null) 'is_favorite': isFavorite,
|
||||
if (fileMetadataWidth != null) 'file_metadata_width': fileMetadataWidth,
|
||||
if (fileMetadataHeight != null)
|
||||
'file_metadata_height': fileMetadataHeight,
|
||||
});
|
||||
}
|
||||
|
||||
NcAlbumItemsCompanion copyWith(
|
||||
{Value<int>? rowId, Value<int>? parent, Value<int>? fileId}) {
|
||||
{Value<int>? rowId,
|
||||
Value<int>? parent,
|
||||
Value<String>? relativePath,
|
||||
Value<int>? fileId,
|
||||
Value<int?>? contentLength,
|
||||
Value<String?>? contentType,
|
||||
Value<String?>? etag,
|
||||
Value<DateTime?>? lastModified,
|
||||
Value<bool?>? hasPreview,
|
||||
Value<bool?>? isFavorite,
|
||||
Value<int?>? fileMetadataWidth,
|
||||
Value<int?>? fileMetadataHeight}) {
|
||||
return NcAlbumItemsCompanion(
|
||||
rowId: rowId ?? this.rowId,
|
||||
parent: parent ?? this.parent,
|
||||
relativePath: relativePath ?? this.relativePath,
|
||||
fileId: fileId ?? this.fileId,
|
||||
contentLength: contentLength ?? this.contentLength,
|
||||
contentType: contentType ?? this.contentType,
|
||||
etag: etag ?? this.etag,
|
||||
lastModified: lastModified ?? this.lastModified,
|
||||
hasPreview: hasPreview ?? this.hasPreview,
|
||||
isFavorite: isFavorite ?? this.isFavorite,
|
||||
fileMetadataWidth: fileMetadataWidth ?? this.fileMetadataWidth,
|
||||
fileMetadataHeight: fileMetadataHeight ?? this.fileMetadataHeight,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4700,9 +4971,38 @@ class NcAlbumItemsCompanion extends UpdateCompanion<NcAlbumItem> {
|
|||
if (parent.present) {
|
||||
map['parent'] = Variable<int>(parent.value);
|
||||
}
|
||||
if (relativePath.present) {
|
||||
map['relative_path'] = Variable<String>(relativePath.value);
|
||||
}
|
||||
if (fileId.present) {
|
||||
map['file_id'] = Variable<int>(fileId.value);
|
||||
}
|
||||
if (contentLength.present) {
|
||||
map['content_length'] = Variable<int?>(contentLength.value);
|
||||
}
|
||||
if (contentType.present) {
|
||||
map['content_type'] = Variable<String?>(contentType.value);
|
||||
}
|
||||
if (etag.present) {
|
||||
map['etag'] = Variable<String?>(etag.value);
|
||||
}
|
||||
if (lastModified.present) {
|
||||
final converter = $NcAlbumItemsTable.$converter0;
|
||||
map['last_modified'] =
|
||||
Variable<DateTime?>(converter.mapToSql(lastModified.value));
|
||||
}
|
||||
if (hasPreview.present) {
|
||||
map['has_preview'] = Variable<bool?>(hasPreview.value);
|
||||
}
|
||||
if (isFavorite.present) {
|
||||
map['is_favorite'] = Variable<bool?>(isFavorite.value);
|
||||
}
|
||||
if (fileMetadataWidth.present) {
|
||||
map['file_metadata_width'] = Variable<int?>(fileMetadataWidth.value);
|
||||
}
|
||||
if (fileMetadataHeight.present) {
|
||||
map['file_metadata_height'] = Variable<int?>(fileMetadataHeight.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -4711,7 +5011,16 @@ class NcAlbumItemsCompanion extends UpdateCompanion<NcAlbumItem> {
|
|||
return (StringBuffer('NcAlbumItemsCompanion(')
|
||||
..write('rowId: $rowId, ')
|
||||
..write('parent: $parent, ')
|
||||
..write('fileId: $fileId')
|
||||
..write('relativePath: $relativePath, ')
|
||||
..write('fileId: $fileId, ')
|
||||
..write('contentLength: $contentLength, ')
|
||||
..write('contentType: $contentType, ')
|
||||
..write('etag: $etag, ')
|
||||
..write('lastModified: $lastModified, ')
|
||||
..write('hasPreview: $hasPreview, ')
|
||||
..write('isFavorite: $isFavorite, ')
|
||||
..write('fileMetadataWidth: $fileMetadataWidth, ')
|
||||
..write('fileMetadataHeight: $fileMetadataHeight')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -4737,13 +5046,83 @@ class $NcAlbumItemsTable extends NcAlbumItems
|
|||
type: const IntType(),
|
||||
requiredDuringInsert: true,
|
||||
defaultConstraints: 'REFERENCES nc_albums (row_id) ON DELETE CASCADE');
|
||||
final VerificationMeta _relativePathMeta =
|
||||
const VerificationMeta('relativePath');
|
||||
@override
|
||||
late final GeneratedColumn<String?> relativePath = GeneratedColumn<String?>(
|
||||
'relative_path', aliasedName, false,
|
||||
type: const StringType(), requiredDuringInsert: true);
|
||||
final VerificationMeta _fileIdMeta = const VerificationMeta('fileId');
|
||||
@override
|
||||
late final GeneratedColumn<int?> fileId = GeneratedColumn<int?>(
|
||||
'file_id', aliasedName, false,
|
||||
type: const IntType(), requiredDuringInsert: true);
|
||||
final VerificationMeta _contentLengthMeta =
|
||||
const VerificationMeta('contentLength');
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [rowId, parent, fileId];
|
||||
late final GeneratedColumn<int?> contentLength = GeneratedColumn<int?>(
|
||||
'content_length', aliasedName, true,
|
||||
type: const IntType(), requiredDuringInsert: false);
|
||||
final VerificationMeta _contentTypeMeta =
|
||||
const VerificationMeta('contentType');
|
||||
@override
|
||||
late final GeneratedColumn<String?> contentType = GeneratedColumn<String?>(
|
||||
'content_type', aliasedName, true,
|
||||
type: const StringType(), requiredDuringInsert: false);
|
||||
final VerificationMeta _etagMeta = const VerificationMeta('etag');
|
||||
@override
|
||||
late final GeneratedColumn<String?> etag = GeneratedColumn<String?>(
|
||||
'etag', aliasedName, true,
|
||||
type: const StringType(), requiredDuringInsert: false);
|
||||
final VerificationMeta _lastModifiedMeta =
|
||||
const VerificationMeta('lastModified');
|
||||
@override
|
||||
late final GeneratedColumnWithTypeConverter<DateTime, DateTime?>
|
||||
lastModified = GeneratedColumn<DateTime?>(
|
||||
'last_modified', aliasedName, true,
|
||||
type: const IntType(), requiredDuringInsert: false)
|
||||
.withConverter<DateTime>($NcAlbumItemsTable.$converter0);
|
||||
final VerificationMeta _hasPreviewMeta = const VerificationMeta('hasPreview');
|
||||
@override
|
||||
late final GeneratedColumn<bool?> hasPreview = GeneratedColumn<bool?>(
|
||||
'has_preview', aliasedName, true,
|
||||
type: const BoolType(),
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints: 'CHECK (has_preview IN (0, 1))');
|
||||
final VerificationMeta _isFavoriteMeta = const VerificationMeta('isFavorite');
|
||||
@override
|
||||
late final GeneratedColumn<bool?> isFavorite = GeneratedColumn<bool?>(
|
||||
'is_favorite', aliasedName, true,
|
||||
type: const BoolType(),
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints: 'CHECK (is_favorite IN (0, 1))');
|
||||
final VerificationMeta _fileMetadataWidthMeta =
|
||||
const VerificationMeta('fileMetadataWidth');
|
||||
@override
|
||||
late final GeneratedColumn<int?> fileMetadataWidth = GeneratedColumn<int?>(
|
||||
'file_metadata_width', aliasedName, true,
|
||||
type: const IntType(), requiredDuringInsert: false);
|
||||
final VerificationMeta _fileMetadataHeightMeta =
|
||||
const VerificationMeta('fileMetadataHeight');
|
||||
@override
|
||||
late final GeneratedColumn<int?> fileMetadataHeight = GeneratedColumn<int?>(
|
||||
'file_metadata_height', aliasedName, true,
|
||||
type: const IntType(), requiredDuringInsert: false);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [
|
||||
rowId,
|
||||
parent,
|
||||
relativePath,
|
||||
fileId,
|
||||
contentLength,
|
||||
contentType,
|
||||
etag,
|
||||
lastModified,
|
||||
hasPreview,
|
||||
isFavorite,
|
||||
fileMetadataWidth,
|
||||
fileMetadataHeight
|
||||
];
|
||||
@override
|
||||
String get aliasedName => _alias ?? 'nc_album_items';
|
||||
@override
|
||||
|
@ -4763,12 +5142,61 @@ class $NcAlbumItemsTable extends NcAlbumItems
|
|||
} else if (isInserting) {
|
||||
context.missing(_parentMeta);
|
||||
}
|
||||
if (data.containsKey('relative_path')) {
|
||||
context.handle(
|
||||
_relativePathMeta,
|
||||
relativePath.isAcceptableOrUnknown(
|
||||
data['relative_path']!, _relativePathMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_relativePathMeta);
|
||||
}
|
||||
if (data.containsKey('file_id')) {
|
||||
context.handle(_fileIdMeta,
|
||||
fileId.isAcceptableOrUnknown(data['file_id']!, _fileIdMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_fileIdMeta);
|
||||
}
|
||||
if (data.containsKey('content_length')) {
|
||||
context.handle(
|
||||
_contentLengthMeta,
|
||||
contentLength.isAcceptableOrUnknown(
|
||||
data['content_length']!, _contentLengthMeta));
|
||||
}
|
||||
if (data.containsKey('content_type')) {
|
||||
context.handle(
|
||||
_contentTypeMeta,
|
||||
contentType.isAcceptableOrUnknown(
|
||||
data['content_type']!, _contentTypeMeta));
|
||||
}
|
||||
if (data.containsKey('etag')) {
|
||||
context.handle(
|
||||
_etagMeta, etag.isAcceptableOrUnknown(data['etag']!, _etagMeta));
|
||||
}
|
||||
context.handle(_lastModifiedMeta, const VerificationResult.success());
|
||||
if (data.containsKey('has_preview')) {
|
||||
context.handle(
|
||||
_hasPreviewMeta,
|
||||
hasPreview.isAcceptableOrUnknown(
|
||||
data['has_preview']!, _hasPreviewMeta));
|
||||
}
|
||||
if (data.containsKey('is_favorite')) {
|
||||
context.handle(
|
||||
_isFavoriteMeta,
|
||||
isFavorite.isAcceptableOrUnknown(
|
||||
data['is_favorite']!, _isFavoriteMeta));
|
||||
}
|
||||
if (data.containsKey('file_metadata_width')) {
|
||||
context.handle(
|
||||
_fileMetadataWidthMeta,
|
||||
fileMetadataWidth.isAcceptableOrUnknown(
|
||||
data['file_metadata_width']!, _fileMetadataWidthMeta));
|
||||
}
|
||||
if (data.containsKey('file_metadata_height')) {
|
||||
context.handle(
|
||||
_fileMetadataHeightMeta,
|
||||
fileMetadataHeight.isAcceptableOrUnknown(
|
||||
data['file_metadata_height']!, _fileMetadataHeightMeta));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -4788,6 +5216,9 @@ class $NcAlbumItemsTable extends NcAlbumItems
|
|||
$NcAlbumItemsTable createAlias(String alias) {
|
||||
return $NcAlbumItemsTable(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
static TypeConverter<DateTime, DateTime> $converter0 =
|
||||
const SqliteDateTimeConverter();
|
||||
}
|
||||
|
||||
abstract class _$SqliteDb extends GeneratedDatabase {
|
||||
|
|
|
@ -137,6 +137,7 @@ class NcAlbums extends Table {
|
|||
dateTime().map(const SqliteDateTimeConverter()).nullable()();
|
||||
DateTimeColumn get dateEnd =>
|
||||
dateTime().map(const SqliteDateTimeConverter()).nullable()();
|
||||
TextColumn get collaborators => text()();
|
||||
|
||||
@override
|
||||
List<Set<Column>>? get uniqueKeys => [
|
||||
|
@ -148,7 +149,17 @@ class NcAlbumItems extends Table {
|
|||
IntColumn get rowId => integer().autoIncrement()();
|
||||
IntColumn get parent =>
|
||||
integer().references(NcAlbums, #rowId, onDelete: KeyAction.cascade)();
|
||||
TextColumn get relativePath => text()();
|
||||
IntColumn get fileId => integer()();
|
||||
IntColumn get contentLength => integer().nullable()();
|
||||
TextColumn get contentType => text().nullable()();
|
||||
TextColumn get etag => text().nullable()();
|
||||
DateTimeColumn get lastModified =>
|
||||
dateTime().map(const SqliteDateTimeConverter()).nullable()();
|
||||
BoolColumn get hasPreview => boolean().nullable()();
|
||||
BoolColumn get isFavorite => boolean().nullable()();
|
||||
IntColumn get fileMetadataWidth => integer().nullable()();
|
||||
IntColumn get fileMetadataHeight => integer().nullable()();
|
||||
|
||||
@override
|
||||
List<Set<Column>>? get uniqueKeys => [
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:nc_photos/entity/exif.dart';
|
|||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||
import 'package:nc_photos/entity/nc_album.dart';
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
import 'package:nc_photos/entity/person.dart';
|
||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||
import 'package:nc_photos/entity/tag.dart';
|
||||
|
@ -254,15 +255,21 @@ class SqlitePersonConverter {
|
|||
}
|
||||
|
||||
class SqliteNcAlbumConverter {
|
||||
static NcAlbum fromSql(String userId, sql.NcAlbum ncAlbum) => NcAlbum(
|
||||
path: "remote.php/dav/photos/$userId/albums/${ncAlbum.relativePath}",
|
||||
lastPhoto: ncAlbum.lastPhoto,
|
||||
nbItems: ncAlbum.nbItems,
|
||||
location: ncAlbum.location,
|
||||
dateStart: ncAlbum.dateStart,
|
||||
dateEnd: ncAlbum.dateEnd,
|
||||
collaborators: [],
|
||||
);
|
||||
static NcAlbum fromSql(String userId, sql.NcAlbum ncAlbum) {
|
||||
final json = ncAlbum.collaborators
|
||||
.run((obj) => (jsonDecode(obj) as List).cast<Map>());
|
||||
return NcAlbum(
|
||||
path: "remote.php/dav/photos/$userId/albums/${ncAlbum.relativePath}",
|
||||
lastPhoto: ncAlbum.lastPhoto,
|
||||
nbItems: ncAlbum.nbItems,
|
||||
location: ncAlbum.location,
|
||||
dateStart: ncAlbum.dateStart,
|
||||
dateEnd: ncAlbum.dateEnd,
|
||||
collaborators: json
|
||||
.map((e) => NcAlbumCollaborator.fromJson(e.cast<String, dynamic>()))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
static sql.NcAlbumsCompanion toSql(sql.Account? dbAccount, NcAlbum ncAlbum) =>
|
||||
sql.NcAlbumsCompanion(
|
||||
|
@ -274,19 +281,44 @@ class SqliteNcAlbumConverter {
|
|||
location: Value(ncAlbum.location),
|
||||
dateStart: Value(ncAlbum.dateStart),
|
||||
dateEnd: Value(ncAlbum.dateEnd),
|
||||
collaborators: Value(
|
||||
jsonEncode(ncAlbum.collaborators.map((c) => c.toJson()).toList())),
|
||||
);
|
||||
}
|
||||
|
||||
class SqliteNcAlbumItemConverter {
|
||||
static int fromSql(sql.NcAlbumItem item) => item.fileId;
|
||||
static NcAlbumItem fromSql(
|
||||
String userId, String albumRelativePath, sql.NcAlbumItem item) =>
|
||||
NcAlbumItem(
|
||||
path:
|
||||
"remote.php/dav/photos/$userId/albums/$albumRelativePath/${item.relativePath}",
|
||||
fileId: item.fileId,
|
||||
contentLength: item.contentLength,
|
||||
contentType: item.contentType,
|
||||
etag: item.etag,
|
||||
lastModified: item.lastModified,
|
||||
hasPreview: item.hasPreview,
|
||||
isFavorite: item.isFavorite,
|
||||
fileMetadataWidth: item.fileMetadataWidth,
|
||||
fileMetadataHeight: item.fileMetadataHeight,
|
||||
);
|
||||
|
||||
static sql.NcAlbumItemsCompanion toSql(
|
||||
sql.NcAlbum parent,
|
||||
int fileId,
|
||||
NcAlbumItem item,
|
||||
) =>
|
||||
sql.NcAlbumItemsCompanion(
|
||||
parent: Value(parent.rowId),
|
||||
fileId: Value(fileId),
|
||||
relativePath: Value(item.strippedPath),
|
||||
fileId: Value(item.fileId),
|
||||
contentLength: Value(item.contentLength),
|
||||
contentType: Value(item.contentType),
|
||||
etag: Value(item.etag),
|
||||
lastModified: Value(item.lastModified),
|
||||
hasPreview: Value(item.hasPreview),
|
||||
isFavorite: Value(item.isFavorite),
|
||||
fileMetadataWidth: Value(item.fileMetadataWidth),
|
||||
fileMetadataHeight: Value(item.fileMetadataHeight),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/nc_album.dart';
|
||||
import 'package:nc_photos/entity/nc_album/item.dart';
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
|
||||
class ListNcAlbumItem {
|
||||
ListNcAlbumItem(this._c) : assert(require(_c));
|
||||
|
|
|
@ -25,6 +25,7 @@ import 'package:nc_photos/download_handler.dart';
|
|||
import 'package:nc_photos/entity/collection.dart';
|
||||
import 'package:nc_photos/entity/collection/adapter.dart';
|
||||
import 'package:nc_photos/entity/collection_item.dart';
|
||||
import 'package:nc_photos/entity/collection_item/nc_album_item_adapter.dart';
|
||||
import 'package:nc_photos/entity/collection_item/new_item.dart';
|
||||
import 'package:nc_photos/entity/collection_item/sorter.dart';
|
||||
import 'package:nc_photos/entity/collection_item/util.dart';
|
||||
|
|
|
@ -47,7 +47,8 @@ class _PhotoItem extends _FileItem {
|
|||
required super.original,
|
||||
required super.file,
|
||||
required this.account,
|
||||
}) : _previewUrl = NetworkRectThumbnail.imageUrlForFile(account, file);
|
||||
}) : _previewUrl = _getCollectionFilePreviewUrl(
|
||||
account, original as CollectionFileItem);
|
||||
|
||||
@override
|
||||
StaggeredTile get staggeredTile => const StaggeredTile.count(1, 1);
|
||||
|
@ -75,7 +76,8 @@ class _VideoItem extends _FileItem {
|
|||
required super.original,
|
||||
required super.file,
|
||||
required this.account,
|
||||
}) : _previewUrl = NetworkRectThumbnail.imageUrlForFile(account, file);
|
||||
}) : _previewUrl = _getCollectionFilePreviewUrl(
|
||||
account, original as CollectionFileItem);
|
||||
|
||||
@override
|
||||
StaggeredTile get staggeredTile => const StaggeredTile.count(1, 1);
|
||||
|
@ -174,3 +176,13 @@ class _DateItem extends _Item {
|
|||
|
||||
final DateTime date;
|
||||
}
|
||||
|
||||
String _getCollectionFilePreviewUrl(Account account, CollectionFileItem item) {
|
||||
if (item is CollectionFileItemNcAlbumItemAdapter) {
|
||||
return item.localFile == null
|
||||
? NetworkRectThumbnail.imageUrlForNcAlbumFile(account, item.item)
|
||||
: NetworkRectThumbnail.imageUrlForFile(account, item.file);
|
||||
} else {
|
||||
return NetworkRectThumbnail.imageUrlForFile(account, item.file);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:nc_photos/account.dart';
|
|||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||
import 'package:nc_photos/cache_manager_util.dart';
|
||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/np_api_util.dart';
|
||||
|
||||
|
@ -36,6 +37,14 @@ class NetworkRectThumbnail extends StatelessWidget {
|
|||
isKeepAspectRatio: true,
|
||||
);
|
||||
|
||||
static String imageUrlForNcAlbumFile(Account account, NcAlbumItem item) =>
|
||||
api_util.getNcAlbumFilePreviewUrl(
|
||||
account,
|
||||
item,
|
||||
width: k.photoThumbSize,
|
||||
height: k.photoThumbSize,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final child = FittedBox(
|
||||
|
|
|
@ -3,6 +3,7 @@ export 'src/entity/entity.dart';
|
|||
export 'src/entity/face_parser.dart';
|
||||
export 'src/entity/favorite_parser.dart';
|
||||
export 'src/entity/file_parser.dart';
|
||||
export 'src/entity/nc_album_item_parser.dart';
|
||||
export 'src/entity/nc_album_parser.dart';
|
||||
export 'src/entity/person_parser.dart';
|
||||
export 'src/entity/share_parser.dart';
|
||||
|
|
|
@ -111,6 +111,55 @@ class NcAlbum with EquatableMixin {
|
|||
required this.nbItems,
|
||||
required this.location,
|
||||
required this.dateRange,
|
||||
required this.collaborators,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => _$toString();
|
||||
|
||||
@override
|
||||
List<Object?> get props =>
|
||||
[href, lastPhoto, nbItems, location, dateRange, collaborators];
|
||||
|
||||
final String href;
|
||||
final int? lastPhoto;
|
||||
final int? nbItems;
|
||||
final String? location;
|
||||
final JsonObj? dateRange;
|
||||
final List<NcAlbumCollaborator> collaborators;
|
||||
}
|
||||
|
||||
@toString
|
||||
class NcAlbumCollaborator with EquatableMixin {
|
||||
const NcAlbumCollaborator({
|
||||
required this.id,
|
||||
required this.label,
|
||||
required this.type,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => _$toString();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id, label, type];
|
||||
|
||||
final String id;
|
||||
final String label;
|
||||
final int type;
|
||||
}
|
||||
|
||||
@ToString(ignoreNull: true)
|
||||
class NcAlbumItem with EquatableMixin {
|
||||
const NcAlbumItem({
|
||||
required this.href,
|
||||
this.fileId,
|
||||
this.contentLength,
|
||||
this.contentType,
|
||||
this.etag,
|
||||
this.lastModified,
|
||||
this.hasPreview,
|
||||
this.favorite,
|
||||
this.fileMetadataSize,
|
||||
});
|
||||
|
||||
@override
|
||||
|
@ -119,17 +168,25 @@ class NcAlbum with EquatableMixin {
|
|||
@override
|
||||
List<Object?> get props => [
|
||||
href,
|
||||
lastPhoto,
|
||||
nbItems,
|
||||
location,
|
||||
dateRange,
|
||||
fileId,
|
||||
contentLength,
|
||||
contentType,
|
||||
etag,
|
||||
lastModified,
|
||||
hasPreview,
|
||||
favorite,
|
||||
fileMetadataSize,
|
||||
];
|
||||
|
||||
final String href;
|
||||
final int? lastPhoto;
|
||||
final int? nbItems;
|
||||
final String? location;
|
||||
final JsonObj? dateRange;
|
||||
final int? fileId;
|
||||
final int? contentLength;
|
||||
final String? contentType;
|
||||
final String? etag;
|
||||
final DateTime? lastModified;
|
||||
final bool? hasPreview;
|
||||
final bool? favorite;
|
||||
final JsonObj? fileMetadataSize;
|
||||
}
|
||||
|
||||
@toString
|
||||
|
|
|
@ -30,7 +30,21 @@ extension _$FileToString on File {
|
|||
extension _$NcAlbumToString on NcAlbum {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "NcAlbum {href: $href, lastPhoto: $lastPhoto, nbItems: $nbItems, location: $location, dateRange: $dateRange}";
|
||||
return "NcAlbum {href: $href, lastPhoto: $lastPhoto, nbItems: $nbItems, location: $location, dateRange: $dateRange, collaborators: $collaborators}";
|
||||
}
|
||||
}
|
||||
|
||||
extension _$NcAlbumCollaboratorToString on NcAlbumCollaborator {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "NcAlbumCollaborator {id: $id, label: $label, type: $type}";
|
||||
}
|
||||
}
|
||||
|
||||
extension _$NcAlbumItemToString on NcAlbumItem {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "NcAlbumItem {href: $href, ${fileId == null ? "" : "fileId: $fileId, "}${contentLength == null ? "" : "contentLength: $contentLength, "}${contentType == null ? "" : "contentType: $contentType, "}${etag == null ? "" : "etag: $etag, "}${lastModified == null ? "" : "lastModified: $lastModified, "}${hasPreview == null ? "" : "hasPreview: $hasPreview, "}${favorite == null ? "" : "favorite: $favorite, "}${fileMetadataSize == null ? "" : "fileMetadataSize: $fileMetadataSize"}}";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
140
np_api/lib/src/entity/nc_album_item_parser.dart
Normal file
140
np_api/lib/src/entity/nc_album_item_parser.dart
Normal file
|
@ -0,0 +1,140 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:np_api/src/entity/entity.dart';
|
||||
import 'package:np_api/src/entity/parser.dart';
|
||||
import 'package:np_common/log.dart';
|
||||
import 'package:np_common/type.dart';
|
||||
import 'package:xml/xml.dart';
|
||||
|
||||
class NcAlbumItemParser extends XmlResponseParser {
|
||||
Future<List<NcAlbumItem>> parse(String response) =>
|
||||
compute(_parseNcAlbumItemsIsolate, response);
|
||||
|
||||
List<NcAlbumItem> _parse(XmlDocument xml) =>
|
||||
parseT<NcAlbumItem>(xml, _toNcAlbumItem);
|
||||
|
||||
/// Map <DAV:response> contents to NcAlbumItem
|
||||
NcAlbumItem _toNcAlbumItem(XmlElement element) {
|
||||
String? href;
|
||||
int? fileId;
|
||||
int? contentLength;
|
||||
String? contentType;
|
||||
String? etag;
|
||||
DateTime? lastModified;
|
||||
bool? hasPreview;
|
||||
bool? favorite;
|
||||
JsonObj? fileMetadataSize;
|
||||
// unclear what the value types are
|
||||
// "nc:face-detections"
|
||||
// "nc:realpath"
|
||||
// "oc:permissions"
|
||||
|
||||
for (final child in element.children.whereType<XmlElement>()) {
|
||||
if (child.matchQualifiedName("href",
|
||||
prefix: "DAV:", namespaces: namespaces)) {
|
||||
href = Uri.decodeComponent(child.innerText);
|
||||
} else if (child.matchQualifiedName("propstat",
|
||||
prefix: "DAV:", namespaces: namespaces)) {
|
||||
final status = child.children
|
||||
.whereType<XmlElement>()
|
||||
.firstWhere((element) => element.matchQualifiedName("status",
|
||||
prefix: "DAV:", namespaces: namespaces))
|
||||
.innerText;
|
||||
if (!status.contains(" 200 ")) {
|
||||
continue;
|
||||
}
|
||||
final prop = child.children.whereType<XmlElement>().firstWhere(
|
||||
(element) => element.matchQualifiedName("prop",
|
||||
prefix: "DAV:", namespaces: namespaces));
|
||||
final propParser = _PropParser(namespaces: namespaces);
|
||||
propParser.parse(prop);
|
||||
fileId = propParser.fileId;
|
||||
contentLength = propParser.contentLength;
|
||||
contentType = propParser.contentType;
|
||||
etag = propParser.etag;
|
||||
lastModified = propParser.lastModified;
|
||||
hasPreview = propParser.hasPreview;
|
||||
favorite = propParser.favorite;
|
||||
fileMetadataSize = propParser.fileMetadataSize;
|
||||
}
|
||||
}
|
||||
|
||||
return NcAlbumItem(
|
||||
href: href!,
|
||||
fileId: fileId,
|
||||
contentLength: contentLength,
|
||||
contentType: contentType,
|
||||
etag: etag,
|
||||
lastModified: lastModified,
|
||||
hasPreview: hasPreview,
|
||||
favorite: favorite,
|
||||
fileMetadataSize: fileMetadataSize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PropParser {
|
||||
_PropParser({
|
||||
this.namespaces = const {},
|
||||
});
|
||||
|
||||
/// Parse <DAV:prop> element contents
|
||||
void parse(XmlElement element) {
|
||||
for (final child in element.children.whereType<XmlElement>()) {
|
||||
if (child.matchQualifiedName("getlastmodified",
|
||||
prefix: "DAV:", namespaces: namespaces)) {
|
||||
_lastModified = HttpDate.parse(child.innerText);
|
||||
} else if (child.matchQualifiedName("getetag",
|
||||
prefix: "DAV:", namespaces: namespaces)) {
|
||||
_etag = child.innerText.replaceAll("\"", "");
|
||||
} else if (child.matchQualifiedName("getcontenttype",
|
||||
prefix: "DAV:", namespaces: namespaces)) {
|
||||
_contentType = child.innerText;
|
||||
} else if (child.matchQualifiedName("getcontentlength",
|
||||
prefix: "DAV:", namespaces: namespaces)) {
|
||||
_contentLength = int.parse(child.innerText);
|
||||
} else if (child.matchQualifiedName("fileid",
|
||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
||||
_fileId = int.parse(child.innerText);
|
||||
} else if (child.matchQualifiedName("favorite",
|
||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
||||
_favorite = child.innerText != "0";
|
||||
} else if (child.matchQualifiedName("has-preview",
|
||||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||
_hasPreview = child.innerText == "true";
|
||||
} else if (child.matchQualifiedName("file-metadata-size",
|
||||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||
_fileMetadataSize =
|
||||
child.innerText.isEmpty ? null : jsonDecode(child.innerText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DateTime? get lastModified => _lastModified;
|
||||
String? get etag => _etag;
|
||||
String? get contentType => _contentType;
|
||||
int? get contentLength => _contentLength;
|
||||
int? get fileId => _fileId;
|
||||
bool? get favorite => _favorite;
|
||||
bool? get hasPreview => _hasPreview;
|
||||
JsonObj? get fileMetadataSize => _fileMetadataSize;
|
||||
|
||||
final Map<String, String> namespaces;
|
||||
|
||||
DateTime? _lastModified;
|
||||
String? _etag;
|
||||
String? _contentType;
|
||||
int? _contentLength;
|
||||
int? _fileId;
|
||||
bool? _favorite;
|
||||
bool? _hasPreview;
|
||||
JsonObj? _fileMetadataSize;
|
||||
}
|
||||
|
||||
List<NcAlbumItem> _parseNcAlbumItemsIsolate(String response) {
|
||||
initLog();
|
||||
final xml = XmlDocument.parse(response);
|
||||
return NcAlbumItemParser()._parse(xml);
|
||||
}
|
|
@ -20,6 +20,7 @@ class NcAlbumParser extends XmlResponseParser {
|
|||
int? nbItems;
|
||||
String? location;
|
||||
JsonObj? dateRange;
|
||||
List<NcAlbumCollaborator>? collaborators;
|
||||
|
||||
for (final child in element.children.whereType<XmlElement>()) {
|
||||
if (child.matchQualifiedName("href",
|
||||
|
@ -44,6 +45,7 @@ class NcAlbumParser extends XmlResponseParser {
|
|||
nbItems = propParser.nbItems;
|
||||
location = propParser.location;
|
||||
dateRange = propParser.dateRange;
|
||||
collaborators = propParser.collaborators;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,6 +55,7 @@ class NcAlbumParser extends XmlResponseParser {
|
|||
nbItems: nbItems,
|
||||
location: location,
|
||||
dateRange: dateRange,
|
||||
collaborators: collaborators ?? const [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -79,14 +82,44 @@ class _PropParser {
|
|||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||
_dateRange =
|
||||
child.innerText.isEmpty ? null : jsonDecode(child.innerText);
|
||||
} else if (child.matchQualifiedName("collaborators",
|
||||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||
for (final cc in child.children.whereType<XmlElement>()) {
|
||||
if (cc.matchQualifiedName("collaborator",
|
||||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||
_collaborators ??= [];
|
||||
_collaborators!.add(_parseCollaborator(cc));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NcAlbumCollaborator _parseCollaborator(XmlElement element) {
|
||||
late String id;
|
||||
late String label;
|
||||
late int type;
|
||||
for (final child in element.children.whereType<XmlElement>()) {
|
||||
switch (child.localName) {
|
||||
case "id":
|
||||
id = child.innerText;
|
||||
break;
|
||||
case "label":
|
||||
label = child.innerText;
|
||||
break;
|
||||
case "type":
|
||||
type = int.parse(child.innerText);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NcAlbumCollaborator(id: id, label: label, type: type);
|
||||
}
|
||||
|
||||
int? get lastPhoto => _lastPhoto;
|
||||
int? get nbItems => _nbItems;
|
||||
String? get location => _location;
|
||||
JsonObj? get dateRange => _dateRange;
|
||||
List<NcAlbumCollaborator>? get collaborators => _collaborators;
|
||||
|
||||
final Map<String, String> namespaces;
|
||||
|
||||
|
@ -94,6 +127,7 @@ class _PropParser {
|
|||
int? _nbItems;
|
||||
String? _location;
|
||||
JsonObj? _dateRange;
|
||||
List<NcAlbumCollaborator>? _collaborators;
|
||||
}
|
||||
|
||||
List<NcAlbum> _parseNcAlbumsIsolate(String response) {
|
||||
|
|
247
np_api/test/entity/nc_album_parser_test.dart
Normal file
247
np_api/test/entity/nc_album_parser_test.dart
Normal file
|
@ -0,0 +1,247 @@
|
|||
import 'package:np_api/np_api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group("NcAlbumParser", () {
|
||||
test("no album", _noAlbum);
|
||||
test("empty", _empty);
|
||||
test("basic", _basic);
|
||||
test("collaborative", _collaborative);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _noAlbum() async {
|
||||
const xml = """
|
||||
<?xml version="1.0"?>
|
||||
<d:multistatus xmlns:d="DAV:"
|
||||
xmlns:s="http://sabredav.org/ns"
|
||||
xmlns:oc="http://owncloud.org/ns"
|
||||
xmlns:nc="http://nextcloud.org/ns">
|
||||
<d:response>
|
||||
<d:href>/remote.php/dav/photos/admin/albums/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<nc:last-photo/>
|
||||
<nc:nbItems/>
|
||||
<nc:location/>
|
||||
<nc:dateRange/>
|
||||
<nc:collaborators/>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 404 Not Found</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
""";
|
||||
final results = await NcAlbumParser().parse(xml);
|
||||
expect(
|
||||
results,
|
||||
[
|
||||
const NcAlbum(
|
||||
href: "/remote.php/dav/photos/admin/albums/",
|
||||
lastPhoto: null,
|
||||
nbItems: null,
|
||||
location: null,
|
||||
dateRange: null,
|
||||
collaborators: [],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _empty() async {
|
||||
const xml = """
|
||||
<?xml version="1.0"?>
|
||||
<d:multistatus xmlns:d="DAV:"
|
||||
xmlns:s="http://sabredav.org/ns"
|
||||
xmlns:oc="http://owncloud.org/ns"
|
||||
xmlns:nc="http://nextcloud.org/ns">
|
||||
<d:response>
|
||||
<d:href>/remote.php/dav/photos/admin/albums/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<nc:last-photo/>
|
||||
<nc:nbItems/>
|
||||
<nc:location/>
|
||||
<nc:dateRange/>
|
||||
<nc:collaborators/>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 404 Not Found</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/remote.php/dav/photos/admin/albums/test/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<nc:last-photo>-1</nc:last-photo>
|
||||
<nc:nbItems>0</nc:nbItems>
|
||||
<nc:location></nc:location>
|
||||
<nc:dateRange>{"start":null,"end":null}</nc:dateRange>
|
||||
<nc:collaborators/>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
""";
|
||||
final results = await NcAlbumParser().parse(xml);
|
||||
expect(
|
||||
results,
|
||||
[
|
||||
const NcAlbum(
|
||||
href: "/remote.php/dav/photos/admin/albums/",
|
||||
lastPhoto: null,
|
||||
nbItems: null,
|
||||
location: null,
|
||||
dateRange: null,
|
||||
collaborators: [],
|
||||
),
|
||||
const NcAlbum(
|
||||
href: "/remote.php/dav/photos/admin/albums/test/",
|
||||
lastPhoto: -1,
|
||||
nbItems: 0,
|
||||
location: null,
|
||||
dateRange: <String, dynamic>{
|
||||
"start": null,
|
||||
"end": null,
|
||||
},
|
||||
collaborators: [],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _basic() async {
|
||||
const xml = """
|
||||
<?xml version="1.0"?>
|
||||
<d:multistatus xmlns:d="DAV:"
|
||||
xmlns:s="http://sabredav.org/ns"
|
||||
xmlns:oc="http://owncloud.org/ns"
|
||||
xmlns:nc="http://nextcloud.org/ns">
|
||||
<d:response>
|
||||
<d:href>/remote.php/dav/photos/admin/albums/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<nc:last-photo/>
|
||||
<nc:nbItems/>
|
||||
<nc:location/>
|
||||
<nc:dateRange/>
|
||||
<nc:collaborators/>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 404 Not Found</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/remote.php/dav/photos/admin/albums/test/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<nc:last-photo>1</nc:last-photo>
|
||||
<nc:nbItems>1</nc:nbItems>
|
||||
<nc:location></nc:location>
|
||||
<nc:dateRange>{"start":1577934245,"end":1580702706}</nc:dateRange>
|
||||
<nc:collaborators/>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
""";
|
||||
final results = await NcAlbumParser().parse(xml);
|
||||
expect(
|
||||
results,
|
||||
[
|
||||
const NcAlbum(
|
||||
href: "/remote.php/dav/photos/admin/albums/",
|
||||
lastPhoto: null,
|
||||
nbItems: null,
|
||||
location: null,
|
||||
dateRange: null,
|
||||
collaborators: [],
|
||||
),
|
||||
const NcAlbum(
|
||||
href: "/remote.php/dav/photos/admin/albums/test/",
|
||||
lastPhoto: 1,
|
||||
nbItems: 1,
|
||||
location: null,
|
||||
dateRange: <String, dynamic>{
|
||||
"start": 1577934245,
|
||||
"end": 1580702706,
|
||||
},
|
||||
collaborators: [],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _collaborative() async {
|
||||
const xml = """
|
||||
<?xml version="1.0"?>
|
||||
<d:multistatus xmlns:d="DAV:"
|
||||
xmlns:s="http://sabredav.org/ns"
|
||||
xmlns:oc="http://owncloud.org/ns"
|
||||
xmlns:nc="http://nextcloud.org/ns">
|
||||
<d:response>
|
||||
<d:href>/remote.php/dav/photos/admin/albums/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<nc:last-photo/>
|
||||
<nc:nbItems/>
|
||||
<nc:location/>
|
||||
<nc:dateRange/>
|
||||
<nc:collaborators/>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 404 Not Found</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/remote.php/dav/photos/admin/albums/test/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<nc:last-photo>1</nc:last-photo>
|
||||
<nc:nbItems>1</nc:nbItems>
|
||||
<nc:location></nc:location>
|
||||
<nc:dateRange>{"start":1577934245,"end":1580702706}</nc:dateRange>
|
||||
<nc:collaborators>
|
||||
<nc:collaborator>
|
||||
<id>user2</id>
|
||||
<label>User2</label>
|
||||
<type>0</type>
|
||||
</nc:collaborator>
|
||||
</nc:collaborators>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
""";
|
||||
final results = await NcAlbumParser().parse(xml);
|
||||
expect(
|
||||
results,
|
||||
[
|
||||
const NcAlbum(
|
||||
href: "/remote.php/dav/photos/admin/albums/",
|
||||
lastPhoto: null,
|
||||
nbItems: null,
|
||||
location: null,
|
||||
dateRange: null,
|
||||
collaborators: [],
|
||||
),
|
||||
const NcAlbum(
|
||||
href: "/remote.php/dav/photos/admin/albums/test/",
|
||||
lastPhoto: 1,
|
||||
nbItems: 1,
|
||||
location: null,
|
||||
dateRange: <String, dynamic>{
|
||||
"start": 1577934245,
|
||||
"end": 1580702706,
|
||||
},
|
||||
collaborators: [
|
||||
NcAlbumCollaborator(
|
||||
id: "user2",
|
||||
label: "User2",
|
||||
type: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue