123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- import 'dart:convert';
- import 'dart:core';
- import 'package:flutter/foundation.dart';
- import 'package:photos/models/magic_metadata.dart';
- class Collection {
- final int id;
- final User? owner;
- final String encryptedKey;
- final String? keyDecryptionNonce;
- final String? name;
- // encryptedName & nameDecryptionNonce will be null for collections
- // created before we started encrypting collection name
- final String? encryptedName;
- final String? nameDecryptionNonce;
- final CollectionType type;
- final CollectionAttributes attributes;
- final List<User?>? sharees;
- final List<PublicURL?>? publicURLs;
- final int updationTime;
- final bool isDeleted;
- String? mMdEncodedJson;
- int mMdVersion = 0;
- CollectionMagicMetadata? _mmd;
- CollectionMagicMetadata get magicMetadata =>
- _mmd ?? CollectionMagicMetadata.fromEncodedJson(mMdEncodedJson ?? '{}');
- set magicMetadata(val) => _mmd = val;
- Collection(
- this.id,
- this.owner,
- this.encryptedKey,
- this.keyDecryptionNonce,
- this.name,
- this.encryptedName,
- this.nameDecryptionNonce,
- this.type,
- this.attributes,
- this.sharees,
- this.publicURLs,
- this.updationTime, {
- this.isDeleted = false,
- });
- bool isArchived() {
- return mMdVersion > 0 && magicMetadata.visibility == visibilityArchive;
- }
- // hasLink returns true if there's any link attached to the collection
- // including expired links
- bool get hasLink => publicURLs != null && publicURLs!.isNotEmpty;
- // hasSharees returns true if the collection is shared with other ente users
- bool get hasSharees => sharees != null && sharees!.isNotEmpty;
- bool isHidden() {
- if (isDefaultHidden()) {
- return true;
- }
- return mMdVersion > 0 && (magicMetadata.visibility == visibilityHidden);
- }
- bool isDefaultHidden() {
- return (magicMetadata.subType ?? 0) == subTypeDefaultHidden;
- }
- bool isSharedFilesCollection() {
- return (magicMetadata.subType ?? 0) == subTypeSharedFilesCollection;
- }
- List<User> getSharees() {
- final List<User> result = [];
- if (sharees == null) {
- return result;
- }
- for (final User? u in sharees!) {
- if (u != null) {
- result.add(u);
- }
- }
- return result;
- }
- bool isOwner(int userID) {
- return (owner?.id ?? 0) == userID;
- }
- String get collectionName => name ?? "Unnamed collection";
- void updateSharees(List<User> newSharees) {
- sharees?.clear();
- sharees?.addAll(newSharees);
- }
- static CollectionType typeFromString(String type) {
- switch (type) {
- case "folder":
- return CollectionType.folder;
- case "favorites":
- return CollectionType.favorites;
- case "uncategorized":
- return CollectionType.uncategorized;
- case "album":
- return CollectionType.album;
- case "unknown":
- return CollectionType.unknown;
- }
- debugPrint("unexpected collection type $type");
- return CollectionType.unknown;
- }
- static String typeToString(CollectionType type) {
- switch (type) {
- case CollectionType.folder:
- return "folder";
- case CollectionType.favorites:
- return "favorites";
- case CollectionType.album:
- return "album";
- case CollectionType.uncategorized:
- return "uncategorized";
- case CollectionType.unknown:
- return "unknown";
- }
- }
- Collection copyWith({
- int? id,
- User? owner,
- String? encryptedKey,
- String? keyDecryptionNonce,
- String? name,
- String? encryptedName,
- String? nameDecryptionNonce,
- CollectionType? type,
- CollectionAttributes? attributes,
- List<User>? sharees,
- List<PublicURL>? publicURLs,
- int? updationTime,
- bool? isDeleted,
- String? mMdEncodedJson,
- int? mMdVersion,
- }) {
- final Collection result = Collection(
- id ?? this.id,
- owner ?? this.owner,
- encryptedKey ?? this.encryptedKey,
- keyDecryptionNonce ?? this.keyDecryptionNonce,
- name ?? this.name,
- encryptedName ?? this.encryptedName,
- nameDecryptionNonce ?? this.nameDecryptionNonce,
- type ?? this.type,
- attributes ?? this.attributes,
- sharees ?? this.sharees,
- publicURLs ?? this.publicURLs,
- updationTime ?? this.updationTime,
- isDeleted: isDeleted ?? this.isDeleted,
- );
- result.mMdVersion = mMdVersion ?? this.mMdVersion;
- result.mMdEncodedJson = mMdEncodedJson ?? this.mMdEncodedJson;
- return result;
- }
- Map<String, dynamic> toMap() {
- return {
- 'id': id,
- 'owner': owner?.toMap(),
- 'encryptedKey': encryptedKey,
- 'keyDecryptionNonce': keyDecryptionNonce,
- 'name': name,
- 'encryptedName': encryptedName,
- 'nameDecryptionNonce': nameDecryptionNonce,
- 'type': typeToString(type),
- 'attributes': attributes.toMap(),
- 'sharees': sharees?.map((x) => x?.toMap()).toList(),
- 'publicURLs': publicURLs?.map((x) => x?.toMap()).toList(),
- 'updationTime': updationTime,
- 'isDeleted': isDeleted,
- };
- }
- static fromMap(Map<String, dynamic>? map) {
- if (map == null) return null;
- final sharees = (map['sharees'] == null || map['sharees'].length == 0)
- ? <User>[]
- : List<User>.from(map['sharees'].map((x) => User.fromMap(x)));
- final publicURLs =
- (map['publicURLs'] == null || map['publicURLs'].length == 0)
- ? <PublicURL>[]
- : List<PublicURL>.from(
- map['publicURLs'].map((x) => PublicURL.fromMap(x)),
- );
- return Collection(
- map['id'],
- User.fromMap(map['owner']),
- map['encryptedKey'],
- map['keyDecryptionNonce'],
- map['name'],
- map['encryptedName'],
- map['nameDecryptionNonce'],
- typeFromString(map['type']),
- CollectionAttributes.fromMap(map['attributes']),
- sharees,
- publicURLs,
- map['updationTime'],
- isDeleted: map['isDeleted'] ?? false,
- );
- }
- }
- enum CollectionType {
- folder,
- favorites,
- uncategorized,
- album,
- unknown,
- }
- extension CollectionTypeExtn on CollectionType {
- bool get canDelete =>
- this != CollectionType.favorites && this != CollectionType.uncategorized;
- }
- enum CollectionParticipantRole {
- unknown,
- viewer,
- collaborator,
- owner,
- }
- extension CollectionParticipantRoleExtn on CollectionParticipantRole {
- static CollectionParticipantRole fromString(String? val) {
- if ((val ?? '') == '') {
- return CollectionParticipantRole.viewer;
- }
- for (var x in CollectionParticipantRole.values) {
- if (x.name.toUpperCase() == val!.toUpperCase()) {
- return x;
- }
- }
- return CollectionParticipantRole.unknown;
- }
- String toStringVal() {
- return name.toUpperCase();
- }
- }
- class CollectionAttributes {
- final String? encryptedPath;
- final String? pathDecryptionNonce;
- final int? version;
- CollectionAttributes({
- this.encryptedPath,
- this.pathDecryptionNonce,
- this.version,
- });
- Map<String, dynamic> toMap() {
- final map = <String, dynamic>{};
- if (encryptedPath != null) {
- map['encryptedPath'] = encryptedPath;
- }
- if (pathDecryptionNonce != null) {
- map['pathDecryptionNonce'] = pathDecryptionNonce;
- }
- map['version'] = version ?? 0;
- return map;
- }
- static fromMap(Map<String, dynamic>? map) {
- if (map == null) return null;
- return CollectionAttributes(
- encryptedPath: map['encryptedPath'],
- pathDecryptionNonce: map['pathDecryptionNonce'],
- version: map['version'] ?? 0,
- );
- }
- }
- class User {
- int? id;
- String email;
- String? name;
- String? role;
- User({
- this.id,
- required this.email,
- this.name,
- this.role,
- });
- bool get isViewer => role == null || role?.toUpperCase() == 'VIEWER';
- bool get isCollaborator =>
- role != null && role?.toUpperCase() == 'COLLABORATOR';
- Map<String, dynamic> toMap() {
- return {'id': id, 'email': email, 'name': name, 'role': role};
- }
- static fromMap(Map<String, dynamic>? map) {
- if (map == null) return null;
- return User(
- id: map['id'],
- email: map['email'],
- name: map['name'],
- role: map['role'] ?? 'VIEWER',
- );
- }
- String toJson() => json.encode(toMap());
- factory User.fromJson(String source) => User.fromMap(json.decode(source));
- }
- class PublicURL {
- String url;
- int deviceLimit;
- int validTill;
- bool enableDownload;
- bool enableCollect;
- bool passwordEnabled;
- PublicURL({
- required this.url,
- required this.deviceLimit,
- required this.validTill,
- this.enableDownload = true,
- this.passwordEnabled = false,
- this.enableCollect = false,
- });
- Map<String, dynamic> toMap() {
- return {
- 'url': url,
- 'deviceLimit': deviceLimit,
- 'validTill': validTill,
- 'enableDownload': enableDownload,
- 'passwordEnabled': passwordEnabled,
- 'enableCollect': enableCollect,
- };
- }
- bool get hasExpiry => validTill != 0;
- // isExpired indicates whether the link has expired or not
- bool get isExpired =>
- hasExpiry && validTill < DateTime.now().microsecondsSinceEpoch;
- static fromMap(Map<String, dynamic>? map) {
- if (map == null) return null;
- return PublicURL(
- url: map['url'],
- deviceLimit: map['deviceLimit'],
- validTill: map['validTill'] ?? 0,
- enableDownload: map['enableDownload'] ?? true,
- passwordEnabled: map['passwordEnabled'] ?? false,
- enableCollect: map['enableCollect'] ?? false,
- );
- }
- }
|