Merge pull request #502 from ente-io/migrate-to-null-safety
This commit is contained in:
commit
6f7539eadb
|
@ -1,5 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
class InvalidFileError extends ArgumentError {
|
class InvalidFileError extends ArgumentError {
|
||||||
InvalidFileError(String message) : super(message);
|
InvalidFileError(String message) : super(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,7 +262,7 @@ class FilesDB {
|
||||||
ALTER TABLE $filesTable ADD COLUMN $columnMMdVersion INTEGER DEFAULT 0;
|
ALTER TABLE $filesTable ADD COLUMN $columnMMdVersion INTEGER DEFAULT 0;
|
||||||
''',
|
''',
|
||||||
'''
|
'''
|
||||||
ALTER TABLE $filesTable ADD COLUMN $columnMMdVisibility INTEGER DEFAULT $kVisibilityVisible;
|
ALTER TABLE $filesTable ADD COLUMN $columnMMdVisibility INTEGER DEFAULT $visibilityVisible;
|
||||||
'''
|
'''
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -461,7 +461,7 @@ class FilesDB {
|
||||||
int ownerID, {
|
int ownerID, {
|
||||||
int limit,
|
int limit,
|
||||||
bool asc,
|
bool asc,
|
||||||
int visibility = kVisibilityVisible,
|
int visibility = visibilityVisible,
|
||||||
Set<int> ignoredCollectionIDs,
|
Set<int> ignoredCollectionIDs,
|
||||||
}) async {
|
}) async {
|
||||||
final db = await instance.database;
|
final db = await instance.database;
|
||||||
|
@ -484,7 +484,7 @@ class FilesDB {
|
||||||
|
|
||||||
Future<Set<int>> getCollectionIDsOfHiddenFiles(
|
Future<Set<int>> getCollectionIDsOfHiddenFiles(
|
||||||
int ownerID, {
|
int ownerID, {
|
||||||
int visibility = kVisibilityArchive,
|
int visibility = visibilityArchive,
|
||||||
}) async {
|
}) async {
|
||||||
final db = await instance.database;
|
final db = await instance.database;
|
||||||
final results = await db.query(
|
final results = await db.query(
|
||||||
|
@ -517,7 +517,7 @@ class FilesDB {
|
||||||
where:
|
where:
|
||||||
'$columnCreationTime >= ? AND $columnCreationTime <= ? AND ($columnOwnerID IS NULL OR $columnOwnerID = ?) AND ($columnMMdVisibility IS NULL OR $columnMMdVisibility = ?)'
|
'$columnCreationTime >= ? AND $columnCreationTime <= ? AND ($columnOwnerID IS NULL OR $columnOwnerID = ?) AND ($columnMMdVisibility IS NULL OR $columnMMdVisibility = ?)'
|
||||||
' AND ($columnLocalID IS NOT NULL OR ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1))',
|
' AND ($columnLocalID IS NOT NULL OR ($columnCollectionID IS NOT NULL AND $columnCollectionID IS NOT -1))',
|
||||||
whereArgs: [startTime, endTime, ownerID, kVisibilityVisible],
|
whereArgs: [startTime, endTime, ownerID, visibilityVisible],
|
||||||
orderBy:
|
orderBy:
|
||||||
'$columnCreationTime ' + order + ', $columnModificationTime ' + order,
|
'$columnCreationTime ' + order + ', $columnModificationTime ' + order,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
|
@ -569,7 +569,7 @@ class FilesDB {
|
||||||
int endTime, {
|
int endTime, {
|
||||||
int limit,
|
int limit,
|
||||||
bool asc,
|
bool asc,
|
||||||
int visibility = kVisibilityVisible,
|
int visibility = visibilityVisible,
|
||||||
}) async {
|
}) async {
|
||||||
final db = await instance.database;
|
final db = await instance.database;
|
||||||
final order = (asc ?? false ? 'ASC' : 'DESC');
|
final order = (asc ?? false ? 'ASC' : 'DESC');
|
||||||
|
@ -618,7 +618,7 @@ class FilesDB {
|
||||||
whereClause += " OR ";
|
whereClause += " OR ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
whereClause += ") AND $columnMMdVisibility = $kVisibilityVisible";
|
whereClause += ") AND $columnMMdVisibility = $visibilityVisible";
|
||||||
final results = await db.query(
|
final results = await db.query(
|
||||||
filesTable,
|
filesTable,
|
||||||
where: whereClause,
|
where: whereClause,
|
||||||
|
@ -1168,7 +1168,7 @@ class FilesDB {
|
||||||
SELECT $columnCollectionID, MAX($columnCreationTime) AS max_creation_time
|
SELECT $columnCollectionID, MAX($columnCreationTime) AS max_creation_time
|
||||||
FROM $filesTable
|
FROM $filesTable
|
||||||
WHERE ($columnCollectionID IS NOT NULL AND $columnCollectionID IS
|
WHERE ($columnCollectionID IS NOT NULL AND $columnCollectionID IS
|
||||||
NOT -1 AND $columnMMdVisibility = $kVisibilityVisible AND
|
NOT -1 AND $columnMMdVisibility = $visibilityVisible AND
|
||||||
$columnUploadedFileID IS NOT -1)
|
$columnUploadedFileID IS NOT -1)
|
||||||
GROUP BY $columnCollectionID
|
GROUP BY $columnCollectionID
|
||||||
) latest_files
|
) latest_files
|
||||||
|
@ -1366,7 +1366,7 @@ class FilesDB {
|
||||||
row[columnMMdVersion] = file.mMdVersion ?? 0;
|
row[columnMMdVersion] = file.mMdVersion ?? 0;
|
||||||
row[columnMMdEncodedJson] = file.mMdEncodedJson ?? '{}';
|
row[columnMMdEncodedJson] = file.mMdEncodedJson ?? '{}';
|
||||||
row[columnMMdVisibility] =
|
row[columnMMdVisibility] =
|
||||||
file.magicMetadata?.visibility ?? kVisibilityVisible;
|
file.magicMetadata?.visibility ?? visibilityVisible;
|
||||||
row[columnPubMMdVersion] = file.pubMmdVersion ?? 0;
|
row[columnPubMMdVersion] = file.pubMmdVersion ?? 0;
|
||||||
row[columnPubMMdEncodedJson] = file.pubMmdEncodedJson ?? '{}';
|
row[columnPubMMdEncodedJson] = file.pubMmdEncodedJson ?? '{}';
|
||||||
if (file.pubMagicMetadata != null &&
|
if (file.pubMagicMetadata != null &&
|
||||||
|
@ -1405,7 +1405,7 @@ class FilesDB {
|
||||||
row[columnMMdVersion] = file.mMdVersion ?? 0;
|
row[columnMMdVersion] = file.mMdVersion ?? 0;
|
||||||
row[columnMMdEncodedJson] = file.mMdEncodedJson ?? '{}';
|
row[columnMMdEncodedJson] = file.mMdEncodedJson ?? '{}';
|
||||||
row[columnMMdVisibility] =
|
row[columnMMdVisibility] =
|
||||||
file.magicMetadata?.visibility ?? kVisibilityVisible;
|
file.magicMetadata?.visibility ?? visibilityVisible;
|
||||||
|
|
||||||
row[columnPubMMdVersion] = file.pubMmdVersion ?? 0;
|
row[columnPubMMdVersion] = file.pubMmdVersion ?? 0;
|
||||||
row[columnPubMMdEncodedJson] = file.pubMmdEncodedJson ?? '{}';
|
row[columnPubMMdEncodedJson] = file.pubMmdEncodedJson ?? '{}';
|
||||||
|
|
|
@ -18,7 +18,7 @@ class BillingPlans {
|
||||||
|
|
||||||
factory BillingPlans.fromMap(Map<String, dynamic>? map) {
|
factory BillingPlans.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
throw ArgumentError('argument is null');
|
throw Exception('Argument is null');
|
||||||
}
|
}
|
||||||
|
|
||||||
return BillingPlans(
|
return BillingPlans(
|
||||||
|
@ -53,7 +53,7 @@ class FreePlan {
|
||||||
|
|
||||||
factory FreePlan.fromMap(Map<String, dynamic>? map) {
|
factory FreePlan.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
throw ArgumentError('argument is null');
|
throw Exception('Argument is null');
|
||||||
}
|
}
|
||||||
|
|
||||||
return FreePlan(
|
return FreePlan(
|
||||||
|
@ -97,7 +97,7 @@ class BillingPlan {
|
||||||
|
|
||||||
factory BillingPlan.fromMap(Map<String, dynamic>? map) {
|
factory BillingPlan.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
throw ArgumentError('argument is null');
|
throw Exception('Argument is null');
|
||||||
}
|
}
|
||||||
|
|
||||||
return BillingPlan(
|
return BillingPlan(
|
||||||
|
|
|
@ -1,28 +1,25 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:photos/models/magic_metadata.dart';
|
import 'package:photos/models/magic_metadata.dart';
|
||||||
|
|
||||||
class Collection {
|
class Collection {
|
||||||
final int id;
|
final int id;
|
||||||
final User owner;
|
final User? owner;
|
||||||
final String encryptedKey;
|
final String encryptedKey;
|
||||||
final String keyDecryptionNonce;
|
final String? keyDecryptionNonce;
|
||||||
final String name;
|
final String? name;
|
||||||
final String encryptedName;
|
final String encryptedName;
|
||||||
final String nameDecryptionNonce;
|
final String nameDecryptionNonce;
|
||||||
final CollectionType type;
|
final CollectionType type;
|
||||||
final CollectionAttributes attributes;
|
final CollectionAttributes? attributes;
|
||||||
final List<User> sharees;
|
final List<User?>? sharees;
|
||||||
final List<PublicURL> publicURLs;
|
final List<PublicURL?>? publicURLs;
|
||||||
final int updationTime;
|
final int updationTime;
|
||||||
final bool isDeleted;
|
final bool isDeleted;
|
||||||
String mMdEncodedJson;
|
String? mMdEncodedJson;
|
||||||
int mMdVersion = 0;
|
int mMdVersion = 0;
|
||||||
CollectionMagicMetadata _mmd;
|
CollectionMagicMetadata? _mmd;
|
||||||
|
|
||||||
CollectionMagicMetadata get magicMetadata =>
|
CollectionMagicMetadata get magicMetadata =>
|
||||||
_mmd ?? CollectionMagicMetadata.fromEncodedJson(mMdEncodedJson ?? '{}');
|
_mmd ?? CollectionMagicMetadata.fromEncodedJson(mMdEncodedJson ?? '{}');
|
||||||
|
@ -46,7 +43,7 @@ class Collection {
|
||||||
});
|
});
|
||||||
|
|
||||||
bool isArchived() {
|
bool isArchived() {
|
||||||
return mMdVersion > 0 && magicMetadata.visibility == kVisibilityArchive;
|
return mMdVersion > 0 && magicMetadata.visibility == visibilityArchive;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CollectionType typeFromString(String type) {
|
static CollectionType typeFromString(String type) {
|
||||||
|
@ -71,21 +68,21 @@ class Collection {
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection copyWith({
|
Collection copyWith({
|
||||||
int id,
|
int? id,
|
||||||
User owner,
|
User? owner,
|
||||||
String encryptedKey,
|
String? encryptedKey,
|
||||||
String keyDecryptionNonce,
|
String? keyDecryptionNonce,
|
||||||
String name,
|
String? name,
|
||||||
String encryptedName,
|
String? encryptedName,
|
||||||
String nameDecryptionNonce,
|
String? nameDecryptionNonce,
|
||||||
CollectionType type,
|
CollectionType? type,
|
||||||
CollectionAttributes attributes,
|
CollectionAttributes? attributes,
|
||||||
List<User> sharees,
|
List<User>? sharees,
|
||||||
List<PublicURL> publicURLs,
|
List<PublicURL>? publicURLs,
|
||||||
int updationTime,
|
int? updationTime,
|
||||||
bool isDeleted,
|
bool? isDeleted,
|
||||||
String mMdEncodedJson,
|
String? mMdEncodedJson,
|
||||||
int mMdVersion,
|
int? mMdVersion,
|
||||||
}) {
|
}) {
|
||||||
final Collection result = Collection(
|
final Collection result = Collection(
|
||||||
id ?? this.id,
|
id ?? this.id,
|
||||||
|
@ -118,15 +115,17 @@ class Collection {
|
||||||
'nameDecryptionNonce': nameDecryptionNonce,
|
'nameDecryptionNonce': nameDecryptionNonce,
|
||||||
'type': typeToString(type),
|
'type': typeToString(type),
|
||||||
'attributes': attributes?.toMap(),
|
'attributes': attributes?.toMap(),
|
||||||
'sharees': sharees?.map((x) => x?.toMap())?.toList(),
|
'sharees': sharees?.map((x) => x?.toMap()).toList(),
|
||||||
'publicURLs': publicURLs?.map((x) => x?.toMap())?.toList(),
|
'publicURLs': publicURLs?.map((x) => x?.toMap()).toList(),
|
||||||
'updationTime': updationTime,
|
'updationTime': updationTime,
|
||||||
'isDeleted': isDeleted,
|
'isDeleted': isDeleted,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
factory Collection.fromMap(Map<String, dynamic> map) {
|
factory Collection.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) return null;
|
if (map == null) {
|
||||||
|
throw Exception('Argument is null');
|
||||||
|
}
|
||||||
final sharees = (map['sharees'] == null || map['sharees'].length == 0)
|
final sharees = (map['sharees'] == null || map['sharees'].length == 0)
|
||||||
? <User>[]
|
? <User>[]
|
||||||
: List<User>.from(map['sharees'].map((x) => User.fromMap(x)));
|
: List<User>.from(map['sharees'].map((x) => User.fromMap(x)));
|
||||||
|
@ -152,53 +151,6 @@ class Collection {
|
||||||
isDeleted: map['isDeleted'] ?? false,
|
isDeleted: map['isDeleted'] ?? false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
|
|
||||||
factory Collection.fromJson(String source) =>
|
|
||||||
Collection.fromMap(json.decode(source));
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
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)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object o) {
|
|
||||||
if (identical(this, o)) return true;
|
|
||||||
|
|
||||||
return o is Collection &&
|
|
||||||
o.id == id &&
|
|
||||||
o.owner == owner &&
|
|
||||||
o.encryptedKey == encryptedKey &&
|
|
||||||
o.keyDecryptionNonce == keyDecryptionNonce &&
|
|
||||||
o.name == name &&
|
|
||||||
o.encryptedName == encryptedName &&
|
|
||||||
o.nameDecryptionNonce == nameDecryptionNonce &&
|
|
||||||
o.type == type &&
|
|
||||||
o.attributes == attributes &&
|
|
||||||
listEquals(o.sharees, sharees) &&
|
|
||||||
listEquals(o.publicURLs, publicURLs) &&
|
|
||||||
o.updationTime == updationTime &&
|
|
||||||
o.isDeleted == isDeleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
return id.hashCode ^
|
|
||||||
owner.hashCode ^
|
|
||||||
encryptedKey.hashCode ^
|
|
||||||
keyDecryptionNonce.hashCode ^
|
|
||||||
name.hashCode ^
|
|
||||||
encryptedName.hashCode ^
|
|
||||||
nameDecryptionNonce.hashCode ^
|
|
||||||
type.hashCode ^
|
|
||||||
attributes.hashCode ^
|
|
||||||
sharees.hashCode ^
|
|
||||||
publicURLs.hashCode ^
|
|
||||||
updationTime.hashCode ^
|
|
||||||
isDeleted.hashCode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CollectionType {
|
enum CollectionType {
|
||||||
|
@ -208,9 +160,9 @@ enum CollectionType {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CollectionAttributes {
|
class CollectionAttributes {
|
||||||
final String encryptedPath;
|
final String? encryptedPath;
|
||||||
final String pathDecryptionNonce;
|
final String? pathDecryptionNonce;
|
||||||
final int version;
|
final int? version;
|
||||||
|
|
||||||
CollectionAttributes({
|
CollectionAttributes({
|
||||||
this.encryptedPath,
|
this.encryptedPath,
|
||||||
|
@ -218,18 +170,6 @@ class CollectionAttributes {
|
||||||
this.version,
|
this.version,
|
||||||
});
|
});
|
||||||
|
|
||||||
CollectionAttributes copyWith({
|
|
||||||
String encryptedPath,
|
|
||||||
String pathDecryptionNonce,
|
|
||||||
int version,
|
|
||||||
}) {
|
|
||||||
return CollectionAttributes(
|
|
||||||
encryptedPath: encryptedPath ?? this.encryptedPath,
|
|
||||||
pathDecryptionNonce: pathDecryptionNonce ?? this.pathDecryptionNonce,
|
|
||||||
version: version ?? this.version,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
final map = <String, dynamic>{};
|
final map = <String, dynamic>{};
|
||||||
if (encryptedPath != null) {
|
if (encryptedPath != null) {
|
||||||
|
@ -242,8 +182,10 @@ class CollectionAttributes {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
factory CollectionAttributes.fromMap(Map<String, dynamic> map) {
|
factory CollectionAttributes.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) return null;
|
if (map == null) {
|
||||||
|
throw Exception('Argument is null');
|
||||||
|
}
|
||||||
|
|
||||||
return CollectionAttributes(
|
return CollectionAttributes(
|
||||||
encryptedPath: map['encryptedPath'],
|
encryptedPath: map['encryptedPath'],
|
||||||
|
@ -251,54 +193,19 @@ class CollectionAttributes {
|
||||||
version: map['version'] ?? 0,
|
version: map['version'] ?? 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
|
|
||||||
factory CollectionAttributes.fromJson(String source) =>
|
|
||||||
CollectionAttributes.fromMap(json.decode(source));
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() =>
|
|
||||||
'CollectionAttributes(encryptedPath: $encryptedPath, pathDecryptionNonce: $pathDecryptionNonce, version: $version)';
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object o) {
|
|
||||||
if (identical(this, o)) return true;
|
|
||||||
|
|
||||||
return o is CollectionAttributes &&
|
|
||||||
o.encryptedPath == encryptedPath &&
|
|
||||||
o.pathDecryptionNonce == pathDecryptionNonce &&
|
|
||||||
o.version == version;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
encryptedPath.hashCode ^ pathDecryptionNonce.hashCode ^ version.hashCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class User {
|
class User {
|
||||||
int id;
|
int? id;
|
||||||
String email;
|
String email;
|
||||||
String name;
|
String? name;
|
||||||
|
|
||||||
User({
|
User({
|
||||||
this.id,
|
this.id,
|
||||||
this.email,
|
required this.email,
|
||||||
this.name,
|
this.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
User copyWith({
|
|
||||||
int id,
|
|
||||||
String email,
|
|
||||||
String name,
|
|
||||||
}) {
|
|
||||||
return User(
|
|
||||||
id: id ?? this.id,
|
|
||||||
email: email ?? this.email,
|
|
||||||
name: name ?? this.name,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return {
|
return {
|
||||||
'id': id,
|
'id': id,
|
||||||
|
@ -307,8 +214,10 @@ class User {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
factory User.fromMap(Map<String, dynamic> map) {
|
factory User.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) return null;
|
if (map == null) {
|
||||||
|
throw Exception('Argument is null');
|
||||||
|
}
|
||||||
|
|
||||||
return User(
|
return User(
|
||||||
id: map['id'],
|
id: map['id'],
|
||||||
|
@ -320,34 +229,21 @@ class User {
|
||||||
String toJson() => json.encode(toMap());
|
String toJson() => json.encode(toMap());
|
||||||
|
|
||||||
factory User.fromJson(String source) => User.fromMap(json.decode(source));
|
factory User.fromJson(String source) => User.fromMap(json.decode(source));
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'CollectionOwner(id: $id, email: $email, name: $name)';
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object o) {
|
|
||||||
if (identical(this, o)) return true;
|
|
||||||
|
|
||||||
return o is User && o.id == id && o.email == email && o.name == name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => id.hashCode ^ email.hashCode ^ name.hashCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PublicURL {
|
class PublicURL {
|
||||||
String url;
|
String url;
|
||||||
int deviceLimit;
|
int deviceLimit;
|
||||||
int validTill;
|
int validTill;
|
||||||
bool enableDownload = true;
|
bool enableDownload;
|
||||||
bool passwordEnabled = false;
|
bool passwordEnabled;
|
||||||
|
|
||||||
PublicURL({
|
PublicURL({
|
||||||
this.url,
|
required this.url,
|
||||||
this.deviceLimit,
|
required this.deviceLimit,
|
||||||
this.validTill,
|
required this.validTill,
|
||||||
this.enableDownload,
|
this.enableDownload = true,
|
||||||
this.passwordEnabled,
|
this.passwordEnabled = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
|
@ -360,8 +256,10 @@ class PublicURL {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
factory PublicURL.fromMap(Map<String, dynamic> map) {
|
factory PublicURL.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) return null;
|
if (map == null) {
|
||||||
|
throw Exception('Argument is null');
|
||||||
|
}
|
||||||
|
|
||||||
return PublicURL(
|
return PublicURL(
|
||||||
url: map['url'],
|
url: map['url'],
|
||||||
|
@ -371,33 +269,4 @@ class PublicURL {
|
||||||
passwordEnabled: map['passwordEnabled'] ?? false,
|
passwordEnabled: map['passwordEnabled'] ?? false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
|
|
||||||
factory PublicURL.fromJson(String source) =>
|
|
||||||
PublicURL.fromMap(json.decode(source));
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() =>
|
|
||||||
'PublicUrl( url: $url, deviceLimit: $deviceLimit, validTill: $validTill, , enableDownload: $enableDownload, , passwordEnabled: $passwordEnabled)';
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object o) {
|
|
||||||
if (identical(this, o)) return true;
|
|
||||||
|
|
||||||
return o is PublicURL &&
|
|
||||||
o.deviceLimit == deviceLimit &&
|
|
||||||
o.url == url &&
|
|
||||||
o.validTill == validTill &&
|
|
||||||
o.enableDownload == enableDownload &&
|
|
||||||
o.passwordEnabled == passwordEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
deviceLimit.hashCode ^
|
|
||||||
url.hashCode ^
|
|
||||||
validTill.hashCode ^
|
|
||||||
enableDownload.hashCode ^
|
|
||||||
passwordEnabled.hashCode;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class CollectionFileItem {
|
||||||
|
|
||||||
factory CollectionFileItem.fromMap(Map<String, dynamic>? map) {
|
factory CollectionFileItem.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
throw ArgumentError('argument is null');
|
throw Exception('Argument is null');
|
||||||
}
|
}
|
||||||
|
|
||||||
return CollectionFileItem(
|
return CollectionFileItem(
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
const kVisibilityVisible = 0;
|
const visibilityVisible = 0;
|
||||||
const kVisibilityArchive = 1;
|
const visibilityArchive = 1;
|
||||||
|
|
||||||
const kMagicKeyVisibility = 'visibility';
|
const magicKeyVisibility = 'visibility';
|
||||||
|
|
||||||
const kPubMagicKeyEditedTime = 'editedTime';
|
const pubMagicKeyEditedTime = 'editedTime';
|
||||||
const kPubMagicKeyEditedName = 'editedName';
|
const pubMagicKeyEditedName = 'editedName';
|
||||||
|
|
||||||
class MagicMetadata {
|
class MagicMetadata {
|
||||||
// 0 -> visible
|
// 0 -> visible
|
||||||
|
@ -16,23 +14,19 @@ class MagicMetadata {
|
||||||
// 2 -> hidden etc?
|
// 2 -> hidden etc?
|
||||||
int visibility;
|
int visibility;
|
||||||
|
|
||||||
MagicMetadata({this.visibility});
|
MagicMetadata({required this.visibility});
|
||||||
|
|
||||||
factory MagicMetadata.fromEncodedJson(String encodedJson) =>
|
factory MagicMetadata.fromEncodedJson(String encodedJson) =>
|
||||||
MagicMetadata.fromJson(jsonDecode(encodedJson));
|
MagicMetadata.fromJson(jsonDecode(encodedJson));
|
||||||
|
|
||||||
factory MagicMetadata.fromJson(dynamic json) => MagicMetadata.fromMap(json);
|
factory MagicMetadata.fromJson(dynamic json) => MagicMetadata.fromMap(json);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
factory MagicMetadata.fromMap(Map<String, dynamic>? map) {
|
||||||
final map = <String, dynamic>{};
|
if (map == null) {
|
||||||
map[kMagicKeyVisibility] = visibility;
|
throw Exception('Argument is null');
|
||||||
return map;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
factory MagicMetadata.fromMap(Map<String, dynamic> map) {
|
|
||||||
if (map == null) return null;
|
|
||||||
return MagicMetadata(
|
return MagicMetadata(
|
||||||
visibility: map[kMagicKeyVisibility] ?? kVisibilityVisible,
|
visibility: map[magicKeyVisibility] ?? visibilityVisible,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +35,7 @@ class PubMagicMetadata {
|
||||||
int editedTime;
|
int editedTime;
|
||||||
String editedName;
|
String editedName;
|
||||||
|
|
||||||
PubMagicMetadata({this.editedTime, this.editedName});
|
PubMagicMetadata({required this.editedTime, required this.editedName});
|
||||||
|
|
||||||
factory PubMagicMetadata.fromEncodedJson(String encodedJson) =>
|
factory PubMagicMetadata.fromEncodedJson(String encodedJson) =>
|
||||||
PubMagicMetadata.fromJson(jsonDecode(encodedJson));
|
PubMagicMetadata.fromJson(jsonDecode(encodedJson));
|
||||||
|
@ -49,18 +43,13 @@ class PubMagicMetadata {
|
||||||
factory PubMagicMetadata.fromJson(dynamic json) =>
|
factory PubMagicMetadata.fromJson(dynamic json) =>
|
||||||
PubMagicMetadata.fromMap(json);
|
PubMagicMetadata.fromMap(json);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
factory PubMagicMetadata.fromMap(Map<String, dynamic>? map) {
|
||||||
final map = <String, dynamic>{};
|
if (map == null) {
|
||||||
map[kPubMagicKeyEditedTime] = editedTime;
|
throw Exception('Argument is null');
|
||||||
map[kPubMagicKeyEditedName] = editedName;
|
}
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
factory PubMagicMetadata.fromMap(Map<String, dynamic> map) {
|
|
||||||
if (map == null) return null;
|
|
||||||
return PubMagicMetadata(
|
return PubMagicMetadata(
|
||||||
editedTime: map[kPubMagicKeyEditedTime],
|
editedTime: map[pubMagicKeyEditedTime],
|
||||||
editedName: map[kPubMagicKeyEditedName],
|
editedName: map[pubMagicKeyEditedName],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +60,7 @@ class CollectionMagicMetadata {
|
||||||
// 2 -> hidden etc?
|
// 2 -> hidden etc?
|
||||||
int visibility;
|
int visibility;
|
||||||
|
|
||||||
CollectionMagicMetadata({this.visibility});
|
CollectionMagicMetadata({required this.visibility});
|
||||||
|
|
||||||
factory CollectionMagicMetadata.fromEncodedJson(String encodedJson) =>
|
factory CollectionMagicMetadata.fromEncodedJson(String encodedJson) =>
|
||||||
CollectionMagicMetadata.fromJson(jsonDecode(encodedJson));
|
CollectionMagicMetadata.fromJson(jsonDecode(encodedJson));
|
||||||
|
@ -79,16 +68,12 @@ class CollectionMagicMetadata {
|
||||||
factory CollectionMagicMetadata.fromJson(dynamic json) =>
|
factory CollectionMagicMetadata.fromJson(dynamic json) =>
|
||||||
CollectionMagicMetadata.fromMap(json);
|
CollectionMagicMetadata.fromMap(json);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
factory CollectionMagicMetadata.fromMap(Map<String, dynamic>? map) {
|
||||||
final map = <String, dynamic>{};
|
if (map == null) {
|
||||||
map[kMagicKeyVisibility] = visibility;
|
throw Exception('Argument is null');
|
||||||
return map;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
factory CollectionMagicMetadata.fromMap(Map<String, dynamic> map) {
|
|
||||||
if (map == null) return null;
|
|
||||||
return CollectionMagicMetadata(
|
return CollectionMagicMetadata(
|
||||||
visibility: map[kMagicKeyVisibility] ?? kVisibilityVisible,
|
visibility: map[magicKeyVisibility] ?? visibilityVisible,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class AlbumSearchResult extends SearchResult {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String name() {
|
String name() {
|
||||||
return collectionWithThumbnail.collection.name;
|
return collectionWithThumbnail.collection.name!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Subscription {
|
||||||
|
|
||||||
factory Subscription.fromMap(Map<String, dynamic>? map) {
|
factory Subscription.fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
throw ArgumentError("argument is null");
|
throw Exception("Argument is null");
|
||||||
}
|
}
|
||||||
return Subscription(
|
return Subscription(
|
||||||
productID: map['productID'],
|
productID: map['productID'],
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
@ -11,7 +9,7 @@ class UserDetails {
|
||||||
final int fileCount;
|
final int fileCount;
|
||||||
final int sharedCollectionsCount;
|
final int sharedCollectionsCount;
|
||||||
final Subscription subscription;
|
final Subscription subscription;
|
||||||
final FamilyData familyData;
|
final FamilyData? familyData;
|
||||||
|
|
||||||
UserDetails(
|
UserDetails(
|
||||||
this.email,
|
this.email,
|
||||||
|
@ -28,8 +26,8 @@ class UserDetails {
|
||||||
|
|
||||||
bool isFamilyAdmin() {
|
bool isFamilyAdmin() {
|
||||||
assert(isPartOfFamily(), "verify user is part of family before calling");
|
assert(isPartOfFamily(), "verify user is part of family before calling");
|
||||||
final FamilyMember currentUserMember = familyData?.members
|
final FamilyMember currentUserMember = familyData!.members!
|
||||||
?.firstWhere((element) => element.email.trim() == email.trim());
|
.firstWhere((element) => element.email.trim() == email.trim());
|
||||||
return currentUserMember.isAdmin;
|
return currentUserMember.isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,24 +35,20 @@ class UserDetails {
|
||||||
// belong to family group. Otherwise, it will return storage consumed by
|
// belong to family group. Otherwise, it will return storage consumed by
|
||||||
// current user
|
// current user
|
||||||
int getFamilyOrPersonalUsage() {
|
int getFamilyOrPersonalUsage() {
|
||||||
return isPartOfFamily() ? familyData.getTotalUsage() : usage;
|
return isPartOfFamily() ? familyData!.getTotalUsage() : usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFreeStorage() {
|
int getFreeStorage() {
|
||||||
return max(
|
return max(
|
||||||
isPartOfFamily()
|
isPartOfFamily()
|
||||||
? (familyData.storage - familyData.getTotalUsage())
|
? (familyData!.storage - familyData!.getTotalUsage())
|
||||||
: (subscription.storage - (usage)),
|
: (subscription.storage - (usage)),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getTotalStorage() {
|
int getTotalStorage() {
|
||||||
return isPartOfFamily() ? familyData.storage : subscription.storage;
|
return isPartOfFamily() ? familyData!.storage : subscription.storage;
|
||||||
}
|
|
||||||
|
|
||||||
int getPersonalUsage() {
|
|
||||||
return usage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
factory UserDetails.fromMap(Map<String, dynamic> map) {
|
factory UserDetails.fromMap(Map<String, dynamic> map) {
|
||||||
|
@ -67,17 +61,6 @@ class UserDetails {
|
||||||
FamilyData.fromMap(map['familyData']),
|
FamilyData.fromMap(map['familyData']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
return {
|
|
||||||
'email': email,
|
|
||||||
'usage': usage,
|
|
||||||
'fileCount': fileCount,
|
|
||||||
'sharedCollectionsCount': sharedCollectionsCount,
|
|
||||||
'subscription': subscription,
|
|
||||||
'familyData': familyData
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FamilyMember {
|
class FamilyMember {
|
||||||
|
@ -96,14 +79,10 @@ class FamilyMember {
|
||||||
map['isAdmin'] as bool,
|
map['isAdmin'] as bool,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
return {'email': email, 'usage': usage, 'id': id, 'isAdmin': isAdmin};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FamilyData {
|
class FamilyData {
|
||||||
final List<FamilyMember> members;
|
final List<FamilyMember>? members;
|
||||||
|
|
||||||
// Storage available based on the family plan
|
// Storage available based on the family plan
|
||||||
final int storage;
|
final int storage;
|
||||||
|
@ -112,13 +91,11 @@ class FamilyData {
|
||||||
FamilyData(this.members, this.storage, this.expiryTime);
|
FamilyData(this.members, this.storage, this.expiryTime);
|
||||||
|
|
||||||
int getTotalUsage() {
|
int getTotalUsage() {
|
||||||
return members.map((e) => e.usage).toList().sum;
|
return members!.map((e) => e.usage).toList().sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
factory FamilyData.fromMap(Map<String, dynamic> map) {
|
static fromMap(Map<String, dynamic>? map) {
|
||||||
if (map == null) {
|
if (map == null) return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
assert(map['members'] != null && map['members'].length >= 0);
|
assert(map['members'] != null && map['members'].length >= 0);
|
||||||
final members = List<FamilyMember>.from(
|
final members = List<FamilyMember>.from(
|
||||||
map['members'].map((x) => FamilyMember.fromMap(x)),
|
map['members'].map((x) => FamilyMember.fromMap(x)),
|
||||||
|
@ -129,12 +106,4 @@ class FamilyData {
|
||||||
map['expiryTime'] as int,
|
map['expiryTime'] as int,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
return {
|
|
||||||
'members': members.map((x) => x?.toMap())?.toList(),
|
|
||||||
'storage': storage,
|
|
||||||
'expiryTime': expiryTime
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,9 @@ class FileMagicService {
|
||||||
FileMagicService._privateConstructor();
|
FileMagicService._privateConstructor();
|
||||||
|
|
||||||
Future<void> changeVisibility(List<File> files, int visibility) async {
|
Future<void> changeVisibility(List<File> files, int visibility) async {
|
||||||
final Map<String, dynamic> update = {kMagicKeyVisibility: visibility};
|
final Map<String, dynamic> update = {magicKeyVisibility: visibility};
|
||||||
await _updateMagicData(files, update);
|
await _updateMagicData(files, update);
|
||||||
if (visibility == kVisibilityVisible) {
|
if (visibility == visibilityVisible) {
|
||||||
// Force reload home gallery to pull in the now unarchived files
|
// Force reload home gallery to pull in the now unarchived files
|
||||||
Bus.instance.fire(ForceReloadHomeGalleryEvent());
|
Bus.instance.fire(ForceReloadHomeGalleryEvent());
|
||||||
Bus.instance
|
Bus.instance
|
||||||
|
@ -64,7 +64,8 @@ class FileMagicService {
|
||||||
// read the existing magic metadata and apply new updates to existing data
|
// read the existing magic metadata and apply new updates to existing data
|
||||||
// current update is simple replace. This will be enhanced in the future,
|
// current update is simple replace. This will be enhanced in the future,
|
||||||
// as required.
|
// as required.
|
||||||
final Map<String, dynamic> jsonToUpdate = jsonDecode(file.pubMmdEncodedJson);
|
final Map<String, dynamic> jsonToUpdate =
|
||||||
|
jsonDecode(file.pubMmdEncodedJson);
|
||||||
newMetadataUpdate.forEach((key, value) {
|
newMetadataUpdate.forEach((key, value) {
|
||||||
jsonToUpdate[key] = value;
|
jsonToUpdate[key] = value;
|
||||||
});
|
});
|
||||||
|
@ -134,7 +135,8 @@ class FileMagicService {
|
||||||
// read the existing magic metadata and apply new updates to existing data
|
// read the existing magic metadata and apply new updates to existing data
|
||||||
// current update is simple replace. This will be enhanced in the future,
|
// current update is simple replace. This will be enhanced in the future,
|
||||||
// as required.
|
// as required.
|
||||||
final Map<String, dynamic> jsonToUpdate = jsonDecode(file.mMdEncodedJson);
|
final Map<String, dynamic> jsonToUpdate =
|
||||||
|
jsonDecode(file.mMdEncodedJson);
|
||||||
newMetadataUpdate.forEach((key, value) {
|
newMetadataUpdate.forEach((key, value) {
|
||||||
jsonToUpdate[key] = value;
|
jsonToUpdate[key] = value;
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,7 +46,7 @@ class HiddenCollectionsButtonWidget extends StatelessWidget {
|
||||||
const Padding(padding: EdgeInsets.all(6)),
|
const Padding(padding: EdgeInsets.all(6)),
|
||||||
FutureBuilder<int>(
|
FutureBuilder<int>(
|
||||||
future: FilesDB.instance.fileCountWithVisibility(
|
future: FilesDB.instance.fileCountWithVisibility(
|
||||||
kVisibilityArchive,
|
visibilityArchive,
|
||||||
Configuration.instance.getUserID(),
|
Configuration.instance.getUserID(),
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
|
|
|
@ -87,7 +87,7 @@ class ValidityWidget extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (currentSubscription == null) {
|
if (currentSubscription == null) {
|
||||||
return Container();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
final endDate = getDateAndMonthAndYear(
|
final endDate = getDateAndMonthAndYear(
|
||||||
DateTime.fromMicrosecondsSinceEpoch(currentSubscription.expiryTime),
|
DateTime.fromMicrosecondsSinceEpoch(currentSubscription.expiryTime),
|
||||||
|
|
|
@ -106,7 +106,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
|
||||||
if (widget.file.uploadedFileID != null &&
|
if (widget.file.uploadedFileID != null &&
|
||||||
widget.file.ownerID == Configuration.instance.getUserID()) {
|
widget.file.ownerID == Configuration.instance.getUserID()) {
|
||||||
final bool isArchived =
|
final bool isArchived =
|
||||||
widget.file.magicMetadata.visibility == kVisibilityArchive;
|
widget.file.magicMetadata.visibility == visibilityArchive;
|
||||||
children.add(
|
children.add(
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message: isArchived ? "Unhide" : "Hide",
|
message: isArchived ? "Unhide" : "Hide",
|
||||||
|
@ -123,7 +123,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
|
||||||
await changeVisibility(
|
await changeVisibility(
|
||||||
context,
|
context,
|
||||||
[widget.file],
|
[widget.file],
|
||||||
isArchived ? kVisibilityVisible : kVisibilityArchive,
|
isArchived ? visibilityVisible : visibilityArchive,
|
||||||
);
|
);
|
||||||
safeRefresh();
|
safeRefresh();
|
||||||
},
|
},
|
||||||
|
|
|
@ -33,7 +33,7 @@ class ArchivePage extends StatelessWidget {
|
||||||
creationStartTime,
|
creationStartTime,
|
||||||
creationEndTime,
|
creationEndTime,
|
||||||
Configuration.instance.getUserID(),
|
Configuration.instance.getUserID(),
|
||||||
visibility: kVisibilityArchive,
|
visibility: visibilityArchive,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
asc: asc,
|
asc: asc,
|
||||||
);
|
);
|
||||||
|
|
|
@ -220,8 +220,8 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
|
||||||
context,
|
context,
|
||||||
widget.collection,
|
widget.collection,
|
||||||
widget.collection.isArchived()
|
widget.collection.isArchived()
|
||||||
? kVisibilityVisible
|
? visibilityVisible
|
||||||
: kVisibilityArchive,
|
: visibilityArchive,
|
||||||
);
|
);
|
||||||
} else if (value == 3) {
|
} else if (value == 3) {
|
||||||
await _trashCollection();
|
await _trashCollection();
|
||||||
|
|
|
@ -382,7 +382,7 @@ class _OverlayWidgetState extends State<OverlayWidget> {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_handleVisibilityChangeRequest(
|
_handleVisibilityChangeRequest(
|
||||||
context,
|
context,
|
||||||
showArchive ? kVisibilityArchive : kVisibilityVisible,
|
showArchive ? visibilityArchive : visibilityVisible,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
import 'package:local_auth/auth_strings.dart';
|
import 'package:local_auth/auth_strings.dart';
|
||||||
import 'package:local_auth/local_auth.dart';
|
import 'package:local_auth/local_auth.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
double convertBytesToGBs(final int bytes, {int precision = 2}) {
|
double convertBytesToGBs(final int bytes, {int precision = 2}) {
|
||||||
|
@ -8,15 +6,15 @@ double convertBytesToGBs(final int bytes, {int precision = 2}) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final kStorageUnits = ["bytes", "KB", "MB", "GB"];
|
final storageUnits = ["bytes", "KB", "MB", "GB"];
|
||||||
|
|
||||||
String convertBytesToReadableFormat(int bytes) {
|
String convertBytesToReadableFormat(int bytes) {
|
||||||
int storageUnitIndex = 0;
|
int storageUnitIndex = 0;
|
||||||
while (bytes >= 1024 && storageUnitIndex < kStorageUnits.length - 1) {
|
while (bytes >= 1024 && storageUnitIndex < storageUnits.length - 1) {
|
||||||
storageUnitIndex++;
|
storageUnitIndex++;
|
||||||
bytes = (bytes / 1024).round();
|
bytes = (bytes / 1024).round();
|
||||||
}
|
}
|
||||||
return bytes.toString() + " " + kStorageUnits[storageUnitIndex];
|
return bytes.toString() + " " + storageUnits[storageUnitIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
String formatBytes(int bytes, [int decimals = 2]) {
|
String formatBytes(int bytes, [int decimals = 2]) {
|
||||||
|
@ -24,5 +22,5 @@ String formatBytes(int bytes, [int decimals = 2]) {
|
||||||
const k = 1024;
|
const k = 1024;
|
||||||
final int dm = decimals < 0 ? 0 : decimals;
|
final int dm = decimals < 0 ? 0 : decimals;
|
||||||
final int i = (log(bytes) / log(k)).floor();
|
final int i = (log(bytes) / log(k)).floor();
|
||||||
return ((bytes / pow(k, i)).toStringAsFixed(dm)) + ' ' + kStorageUnits[i];
|
return ((bytes / pow(k, i)).toStringAsFixed(dm)) + ' ' + storageUnits[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -7,13 +5,13 @@ import 'package:flutter/material.dart';
|
||||||
class Debouncer {
|
class Debouncer {
|
||||||
final Duration _duration;
|
final Duration _duration;
|
||||||
final ValueNotifier<bool> _debounceActiveNotifier = ValueNotifier(false);
|
final ValueNotifier<bool> _debounceActiveNotifier = ValueNotifier(false);
|
||||||
Timer _debounceTimer;
|
Timer? _debounceTimer;
|
||||||
|
|
||||||
Debouncer(this._duration);
|
Debouncer(this._duration);
|
||||||
|
|
||||||
void run(Future<void> Function() fn) {
|
void run(Future<void> Function() fn) {
|
||||||
if (isActive()) {
|
if (isActive()) {
|
||||||
_debounceTimer.cancel();
|
_debounceTimer!.cancel();
|
||||||
}
|
}
|
||||||
_debounceTimer = Timer(_duration, () async {
|
_debounceTimer = Timer(_duration, () async {
|
||||||
await fn();
|
await fn();
|
||||||
|
@ -24,11 +22,11 @@ class Debouncer {
|
||||||
|
|
||||||
void cancelDebounce() {
|
void cancelDebounce() {
|
||||||
if (_debounceTimer != null) {
|
if (_debounceTimer != null) {
|
||||||
_debounceTimer.cancel();
|
_debounceTimer!.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isActive() => _debounceTimer != null && _debounceTimer.isActive;
|
bool isActive() => _debounceTimer != null && _debounceTimer!.isActive;
|
||||||
|
|
||||||
ValueNotifier<bool> get debounceActiveNotifier {
|
ValueNotifier<bool> get debounceActiveNotifier {
|
||||||
return _debounceActiveNotifier;
|
return _debounceActiveNotifier;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
enum AlbumSortKey {
|
enum AlbumSortKey {
|
||||||
|
@ -13,15 +11,14 @@ class LocalSettings {
|
||||||
|
|
||||||
static final LocalSettings instance = LocalSettings._privateConstructor();
|
static final LocalSettings instance = LocalSettings._privateConstructor();
|
||||||
static const kCollectionSortPref = "collection_sort_pref";
|
static const kCollectionSortPref = "collection_sort_pref";
|
||||||
SharedPreferences _prefs;
|
late SharedPreferences _prefs;
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
_prefs = await SharedPreferences.getInstance();
|
_prefs = await SharedPreferences.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
AlbumSortKey albumSortKey() {
|
AlbumSortKey albumSortKey() {
|
||||||
return AlbumSortKey.values[_prefs.getInt(kCollectionSortPref) ?? 0] ??
|
return AlbumSortKey.values[_prefs.getInt(kCollectionSortPref) ?? 0];
|
||||||
AlbumSortKey.lastUpdated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> setAlbumSortKey(AlbumSortKey key) {
|
Future<bool> setAlbumSortKey(AlbumSortKey key) {
|
||||||
|
|
|
@ -23,14 +23,14 @@ Future<void> changeVisibility(
|
||||||
) async {
|
) async {
|
||||||
final dialog = createProgressDialog(
|
final dialog = createProgressDialog(
|
||||||
context,
|
context,
|
||||||
newVisibility == kVisibilityArchive ? "Hiding..." : "Unhiding...",
|
newVisibility == visibilityArchive ? "Hiding..." : "Unhiding...",
|
||||||
);
|
);
|
||||||
await dialog.show();
|
await dialog.show();
|
||||||
try {
|
try {
|
||||||
await FileMagicService.instance.changeVisibility(files, newVisibility);
|
await FileMagicService.instance.changeVisibility(files, newVisibility);
|
||||||
showShortToast(
|
showShortToast(
|
||||||
context,
|
context,
|
||||||
newVisibility == kVisibilityArchive
|
newVisibility == visibilityArchive
|
||||||
? "Successfully hidden"
|
? "Successfully hidden"
|
||||||
: "Successfully unhidden",
|
: "Successfully unhidden",
|
||||||
);
|
);
|
||||||
|
@ -50,17 +50,17 @@ Future<void> changeCollectionVisibility(
|
||||||
) async {
|
) async {
|
||||||
final dialog = createProgressDialog(
|
final dialog = createProgressDialog(
|
||||||
context,
|
context,
|
||||||
newVisibility == kVisibilityArchive ? "Hiding..." : "Unhiding...",
|
newVisibility == visibilityArchive ? "Hiding..." : "Unhiding...",
|
||||||
);
|
);
|
||||||
await dialog.show();
|
await dialog.show();
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic> update = {kMagicKeyVisibility: newVisibility};
|
final Map<String, dynamic> update = {magicKeyVisibility: newVisibility};
|
||||||
await CollectionsService.instance.updateMagicMetadata(collection, update);
|
await CollectionsService.instance.updateMagicMetadata(collection, update);
|
||||||
// Force reload home gallery to pull in the now unarchived files
|
// Force reload home gallery to pull in the now unarchived files
|
||||||
Bus.instance.fire(ForceReloadHomeGalleryEvent());
|
Bus.instance.fire(ForceReloadHomeGalleryEvent());
|
||||||
showShortToast(
|
showShortToast(
|
||||||
context,
|
context,
|
||||||
newVisibility == kVisibilityArchive
|
newVisibility == visibilityArchive
|
||||||
? "Successfully hidden"
|
? "Successfully hidden"
|
||||||
: "Successfully unhidden",
|
: "Successfully unhidden",
|
||||||
);
|
);
|
||||||
|
@ -82,7 +82,7 @@ Future<bool> editTime(
|
||||||
await _updatePublicMetadata(
|
await _updatePublicMetadata(
|
||||||
context,
|
context,
|
||||||
files,
|
files,
|
||||||
kPubMagicKeyEditedTime,
|
pubMagicKeyEditedTime,
|
||||||
editedTime,
|
editedTime,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
|
@ -115,7 +115,7 @@ Future<bool> editFilename(
|
||||||
await _updatePublicMetadata(
|
await _updatePublicMetadata(
|
||||||
context,
|
context,
|
||||||
List.of([file]),
|
List.of([file]),
|
||||||
kPubMagicKeyEditedName,
|
pubMagicKeyEditedName,
|
||||||
result,
|
result,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
|
@ -152,5 +152,5 @@ Future<void> _updatePublicMetadata(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _shouldReloadGallery(String key) {
|
bool _shouldReloadGallery(String key) {
|
||||||
return key == kPubMagicKeyEditedTime;
|
return key == pubMagicKeyEditedTime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
// @dart=2.9
|
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
Future<T> routeToPage<T extends Object>(
|
Future<T?> routeToPage<T extends Object>(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
Widget page, {
|
Widget page, {
|
||||||
bool forceCustomPageRoute = false,
|
bool forceCustomPageRoute = false,
|
||||||
|
@ -63,13 +61,13 @@ class SwipeableRouteBuilder<T> extends PageRoute<T> {
|
||||||
const CupertinoPageTransitionsBuilder(); // Default iOS/macOS (to get the swipe right to go back gesture)
|
const CupertinoPageTransitionsBuilder(); // Default iOS/macOS (to get the swipe right to go back gesture)
|
||||||
// final PageTransitionsBuilder matchingBuilder = const FadeUpwardsPageTransitionsBuilder(); // Default Android/Linux/Windows
|
// final PageTransitionsBuilder matchingBuilder = const FadeUpwardsPageTransitionsBuilder(); // Default Android/Linux/Windows
|
||||||
|
|
||||||
SwipeableRouteBuilder({this.pageBuilder});
|
SwipeableRouteBuilder({required this.pageBuilder});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color get barrierColor => null;
|
Null get barrierColor => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get barrierLabel => null;
|
Null get barrierLabel => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildPage(
|
Widget buildPage(
|
||||||
|
@ -110,21 +108,21 @@ class SwipeableRouteBuilder<T> extends PageRoute<T> {
|
||||||
|
|
||||||
class TransparentRoute extends PageRoute<void> {
|
class TransparentRoute extends PageRoute<void> {
|
||||||
TransparentRoute({
|
TransparentRoute({
|
||||||
@required this.builder,
|
required this.builder,
|
||||||
RouteSettings settings,
|
RouteSettings? settings,
|
||||||
}) : assert(builder != null),
|
}) : assert(builder != null),
|
||||||
super(settings: settings, fullscreenDialog: false);
|
super(settings: settings, fullscreenDialog: false);
|
||||||
|
|
||||||
final WidgetBuilder builder;
|
final WidgetBuilder? builder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get opaque => false;
|
bool get opaque => false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color get barrierColor => null;
|
Null get barrierColor => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get barrierLabel => null;
|
Null get barrierLabel => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get maintainState => true;
|
bool get maintainState => true;
|
||||||
|
@ -138,7 +136,7 @@ class TransparentRoute extends PageRoute<void> {
|
||||||
Animation<double> animation,
|
Animation<double> animation,
|
||||||
Animation<double> secondaryAnimation,
|
Animation<double> secondaryAnimation,
|
||||||
) {
|
) {
|
||||||
final result = builder(context);
|
final result = builder!(context);
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: Tween<double>(begin: 0, end: 1).animate(animation),
|
opacity: Tween<double>(begin: 0, end: 1).animate(animation),
|
||||||
child: Semantics(
|
child: Semantics(
|
||||||
|
|
Loading…
Reference in a new issue