collection.dart 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. import 'dart:convert';
  2. import 'dart:core';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:photos/models/magic_metadata.dart';
  5. class Collection {
  6. final int id;
  7. final User owner;
  8. final String encryptedKey;
  9. final String keyDecryptionNonce;
  10. final String name;
  11. final String encryptedName;
  12. final String nameDecryptionNonce;
  13. final CollectionType type;
  14. final CollectionAttributes attributes;
  15. final List<User> sharees;
  16. final List<PublicURL> publicURLs;
  17. final int updationTime;
  18. final bool isDeleted;
  19. String mMdEncodedJson;
  20. int mMdVersion = 0;
  21. CollectionMagicMetadata _mmd;
  22. CollectionMagicMetadata get magicMetadata =>
  23. _mmd ?? CollectionMagicMetadata.fromEncodedJson(mMdEncodedJson ?? '{}');
  24. set magicMetadata(val) => _mmd = val;
  25. Collection(
  26. this.id,
  27. this.owner,
  28. this.encryptedKey,
  29. this.keyDecryptionNonce,
  30. this.name,
  31. this.encryptedName,
  32. this.nameDecryptionNonce,
  33. this.type,
  34. this.attributes,
  35. this.sharees,
  36. this.publicURLs,
  37. this.updationTime, {
  38. this.isDeleted = false,
  39. });
  40. bool isArchived() {
  41. return mMdVersion > 0 && magicMetadata.visibility == kVisibilityArchive;
  42. }
  43. static CollectionType typeFromString(String type) {
  44. switch (type) {
  45. case "folder":
  46. return CollectionType.folder;
  47. case "favorites":
  48. return CollectionType.favorites;
  49. }
  50. return CollectionType.album;
  51. }
  52. static String typeToString(CollectionType type) {
  53. switch (type) {
  54. case CollectionType.folder:
  55. return "folder";
  56. case CollectionType.favorites:
  57. return "favorites";
  58. default:
  59. return "album";
  60. }
  61. }
  62. Collection copyWith({
  63. int id,
  64. User owner,
  65. String encryptedKey,
  66. String keyDecryptionNonce,
  67. String name,
  68. String encryptedName,
  69. String nameDecryptionNonce,
  70. CollectionType type,
  71. CollectionAttributes attributes,
  72. List<User> sharees,
  73. List<PublicURL> publicURLs,
  74. int updationTime,
  75. bool isDeleted,
  76. String mMdEncodedJson,
  77. int mMdVersion,
  78. }) {
  79. final Collection result = Collection(
  80. id ?? this.id,
  81. owner ?? this.owner,
  82. encryptedKey ?? this.encryptedKey,
  83. keyDecryptionNonce ?? this.keyDecryptionNonce,
  84. name ?? this.name,
  85. encryptedName ?? this.encryptedName,
  86. nameDecryptionNonce ?? this.nameDecryptionNonce,
  87. type ?? this.type,
  88. attributes ?? this.attributes,
  89. sharees ?? this.sharees,
  90. publicURLs ?? this.publicURLs,
  91. updationTime ?? this.updationTime,
  92. isDeleted: isDeleted ?? this.isDeleted,
  93. );
  94. result.mMdVersion = mMdVersion ?? this.mMdVersion;
  95. result.mMdEncodedJson = mMdEncodedJson ?? this.mMdEncodedJson;
  96. return result;
  97. }
  98. Map<String, dynamic> toMap() {
  99. return {
  100. 'id': id,
  101. 'owner': owner?.toMap(),
  102. 'encryptedKey': encryptedKey,
  103. 'keyDecryptionNonce': keyDecryptionNonce,
  104. 'name': name,
  105. 'encryptedName': encryptedName,
  106. 'nameDecryptionNonce': nameDecryptionNonce,
  107. 'type': typeToString(type),
  108. 'attributes': attributes?.toMap(),
  109. 'sharees': sharees?.map((x) => x?.toMap())?.toList(),
  110. 'publicURLs': publicURLs?.map((x) => x?.toMap())?.toList(),
  111. 'updationTime': updationTime,
  112. 'isDeleted': isDeleted,
  113. };
  114. }
  115. factory Collection.fromMap(Map<String, dynamic> map) {
  116. if (map == null) return null;
  117. final sharees = (map['sharees'] == null || map['sharees'].length == 0)
  118. ? <User>[]
  119. : List<User>.from(map['sharees'].map((x) => User.fromMap(x)));
  120. final publicURLs =
  121. (map['publicURLs'] == null || map['publicURLs'].length == 0)
  122. ? <PublicURL>[]
  123. : List<PublicURL>.from(
  124. map['publicURLs'].map((x) => PublicURL.fromMap(x)),
  125. );
  126. return Collection(
  127. map['id'],
  128. User.fromMap(map['owner']),
  129. map['encryptedKey'],
  130. map['keyDecryptionNonce'],
  131. map['name'],
  132. map['encryptedName'],
  133. map['nameDecryptionNonce'],
  134. typeFromString(map['type']),
  135. CollectionAttributes.fromMap(map['attributes']),
  136. sharees,
  137. publicURLs,
  138. map['updationTime'],
  139. isDeleted: map['isDeleted'] ?? false,
  140. );
  141. }
  142. String toJson() => json.encode(toMap());
  143. factory Collection.fromJson(String source) =>
  144. Collection.fromMap(json.decode(source));
  145. @override
  146. String toString() {
  147. return 'Collection(id: $id, owner: $owner, encryptedKey: $encryptedKey, keyDecryptionNonce: $keyDecryptionNonce, name: $name, encryptedName: $encryptedName, nameDecryptionNonce: $nameDecryptionNonce, type: $type, attributes: $attributes, sharees: $sharees, publicURLs: $publicURLs, updationTime: $updationTime, isDeleted: $isDeleted)';
  148. }
  149. @override
  150. bool operator ==(Object o) {
  151. if (identical(this, o)) return true;
  152. return o is Collection &&
  153. o.id == id &&
  154. o.owner == owner &&
  155. o.encryptedKey == encryptedKey &&
  156. o.keyDecryptionNonce == keyDecryptionNonce &&
  157. o.name == name &&
  158. o.encryptedName == encryptedName &&
  159. o.nameDecryptionNonce == nameDecryptionNonce &&
  160. o.type == type &&
  161. o.attributes == attributes &&
  162. listEquals(o.sharees, sharees) &&
  163. listEquals(o.publicURLs, publicURLs) &&
  164. o.updationTime == updationTime &&
  165. o.isDeleted == isDeleted;
  166. }
  167. @override
  168. int get hashCode {
  169. return id.hashCode ^
  170. owner.hashCode ^
  171. encryptedKey.hashCode ^
  172. keyDecryptionNonce.hashCode ^
  173. name.hashCode ^
  174. encryptedName.hashCode ^
  175. nameDecryptionNonce.hashCode ^
  176. type.hashCode ^
  177. attributes.hashCode ^
  178. sharees.hashCode ^
  179. publicURLs.hashCode ^
  180. updationTime.hashCode ^
  181. isDeleted.hashCode;
  182. }
  183. }
  184. enum CollectionType {
  185. folder,
  186. favorites,
  187. album,
  188. }
  189. class CollectionAttributes {
  190. final String encryptedPath;
  191. final String pathDecryptionNonce;
  192. final int version;
  193. CollectionAttributes({
  194. this.encryptedPath,
  195. this.pathDecryptionNonce,
  196. this.version,
  197. });
  198. CollectionAttributes copyWith({
  199. String encryptedPath,
  200. String pathDecryptionNonce,
  201. int version,
  202. }) {
  203. return CollectionAttributes(
  204. encryptedPath: encryptedPath ?? this.encryptedPath,
  205. pathDecryptionNonce: pathDecryptionNonce ?? this.pathDecryptionNonce,
  206. version: version ?? this.version,
  207. );
  208. }
  209. Map<String, dynamic> toMap() {
  210. final map = <String, dynamic>{};
  211. if (encryptedPath != null) {
  212. map['encryptedPath'] = encryptedPath;
  213. }
  214. if (pathDecryptionNonce != null) {
  215. map['pathDecryptionNonce'] = pathDecryptionNonce;
  216. }
  217. map['version'] = version ?? 0;
  218. return map;
  219. }
  220. factory CollectionAttributes.fromMap(Map<String, dynamic> map) {
  221. if (map == null) return null;
  222. return CollectionAttributes(
  223. encryptedPath: map['encryptedPath'],
  224. pathDecryptionNonce: map['pathDecryptionNonce'],
  225. version: map['version'] ?? 0,
  226. );
  227. }
  228. String toJson() => json.encode(toMap());
  229. factory CollectionAttributes.fromJson(String source) =>
  230. CollectionAttributes.fromMap(json.decode(source));
  231. @override
  232. String toString() =>
  233. 'CollectionAttributes(encryptedPath: $encryptedPath, pathDecryptionNonce: $pathDecryptionNonce, version: $version)';
  234. @override
  235. bool operator ==(Object o) {
  236. if (identical(this, o)) return true;
  237. return o is CollectionAttributes &&
  238. o.encryptedPath == encryptedPath &&
  239. o.pathDecryptionNonce == pathDecryptionNonce &&
  240. o.version == version;
  241. }
  242. @override
  243. int get hashCode =>
  244. encryptedPath.hashCode ^ pathDecryptionNonce.hashCode ^ version.hashCode;
  245. }
  246. class User {
  247. int id;
  248. String email;
  249. String name;
  250. User({
  251. this.id,
  252. this.email,
  253. this.name,
  254. });
  255. User copyWith({
  256. int id,
  257. String email,
  258. String name,
  259. }) {
  260. return User(
  261. id: id ?? this.id,
  262. email: email ?? this.email,
  263. name: name ?? this.name,
  264. );
  265. }
  266. Map<String, dynamic> toMap() {
  267. return {
  268. 'id': id,
  269. 'email': email,
  270. 'name': name,
  271. };
  272. }
  273. factory User.fromMap(Map<String, dynamic> map) {
  274. if (map == null) return null;
  275. return User(
  276. id: map['id'],
  277. email: map['email'],
  278. name: map['name'],
  279. );
  280. }
  281. String toJson() => json.encode(toMap());
  282. factory User.fromJson(String source) => User.fromMap(json.decode(source));
  283. @override
  284. String toString() => 'CollectionOwner(id: $id, email: $email, name: $name)';
  285. @override
  286. bool operator ==(Object o) {
  287. if (identical(this, o)) return true;
  288. return o is User && o.id == id && o.email == email && o.name == name;
  289. }
  290. @override
  291. int get hashCode => id.hashCode ^ email.hashCode ^ name.hashCode;
  292. }
  293. class PublicURL {
  294. String url;
  295. int deviceLimit;
  296. int validTill;
  297. bool enableDownload = true;
  298. bool passwordEnabled = false;
  299. PublicURL({
  300. this.url,
  301. this.deviceLimit,
  302. this.validTill,
  303. this.enableDownload,
  304. this.passwordEnabled,
  305. });
  306. Map<String, dynamic> toMap() {
  307. return {
  308. 'url': url,
  309. 'deviceLimit': deviceLimit,
  310. 'validTill': validTill,
  311. 'enableDownload': enableDownload,
  312. 'passwordEnabled': passwordEnabled,
  313. };
  314. }
  315. factory PublicURL.fromMap(Map<String, dynamic> map) {
  316. if (map == null) return null;
  317. return PublicURL(
  318. url: map['url'],
  319. deviceLimit: map['deviceLimit'],
  320. validTill: map['validTill'] ?? 0,
  321. enableDownload: map['enableDownload'] ?? true,
  322. passwordEnabled: map['passwordEnabled'] ?? false,
  323. );
  324. }
  325. String toJson() => json.encode(toMap());
  326. factory PublicURL.fromJson(String source) =>
  327. PublicURL.fromMap(json.decode(source));
  328. @override
  329. String toString() =>
  330. 'PublicUrl( url: $url, deviceLimit: $deviceLimit, validTill: $validTill, , enableDownload: $enableDownload, , passwordEnabled: $passwordEnabled)';
  331. @override
  332. bool operator ==(Object o) {
  333. if (identical(this, o)) return true;
  334. return o is PublicURL &&
  335. o.deviceLimit == deviceLimit &&
  336. o.url == url &&
  337. o.validTill == validTill &&
  338. o.enableDownload == enableDownload &&
  339. o.passwordEnabled == passwordEnabled;
  340. }
  341. @override
  342. int get hashCode =>
  343. deviceLimit.hashCode ^
  344. url.hashCode ^
  345. validTill.hashCode ^
  346. enableDownload.hashCode ^
  347. passwordEnabled.hashCode;
  348. }