Merge pull request #502 from ente-io/migrate-to-null-safety

This commit is contained in:
Neeraj Gupta 2022-09-21 12:56:17 +05:30 committed by GitHub
commit 6f7539eadb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 146 additions and 334 deletions

View file

@ -1,5 +1,3 @@
// @dart=2.9
class InvalidFileError extends ArgumentError {
InvalidFileError(String message) : super(message);
}

View file

@ -262,7 +262,7 @@ class FilesDB {
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 limit,
bool asc,
int visibility = kVisibilityVisible,
int visibility = visibilityVisible,
Set<int> ignoredCollectionIDs,
}) async {
final db = await instance.database;
@ -484,7 +484,7 @@ class FilesDB {
Future<Set<int>> getCollectionIDsOfHiddenFiles(
int ownerID, {
int visibility = kVisibilityArchive,
int visibility = visibilityArchive,
}) async {
final db = await instance.database;
final results = await db.query(
@ -517,7 +517,7 @@ class FilesDB {
where:
'$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))',
whereArgs: [startTime, endTime, ownerID, kVisibilityVisible],
whereArgs: [startTime, endTime, ownerID, visibilityVisible],
orderBy:
'$columnCreationTime ' + order + ', $columnModificationTime ' + order,
limit: limit,
@ -569,7 +569,7 @@ class FilesDB {
int endTime, {
int limit,
bool asc,
int visibility = kVisibilityVisible,
int visibility = visibilityVisible,
}) async {
final db = await instance.database;
final order = (asc ?? false ? 'ASC' : 'DESC');
@ -618,7 +618,7 @@ class FilesDB {
whereClause += " OR ";
}
}
whereClause += ") AND $columnMMdVisibility = $kVisibilityVisible";
whereClause += ") AND $columnMMdVisibility = $visibilityVisible";
final results = await db.query(
filesTable,
where: whereClause,
@ -1168,7 +1168,7 @@ class FilesDB {
SELECT $columnCollectionID, MAX($columnCreationTime) AS max_creation_time
FROM $filesTable
WHERE ($columnCollectionID IS NOT NULL AND $columnCollectionID IS
NOT -1 AND $columnMMdVisibility = $kVisibilityVisible AND
NOT -1 AND $columnMMdVisibility = $visibilityVisible AND
$columnUploadedFileID IS NOT -1)
GROUP BY $columnCollectionID
) latest_files
@ -1366,7 +1366,7 @@ class FilesDB {
row[columnMMdVersion] = file.mMdVersion ?? 0;
row[columnMMdEncodedJson] = file.mMdEncodedJson ?? '{}';
row[columnMMdVisibility] =
file.magicMetadata?.visibility ?? kVisibilityVisible;
file.magicMetadata?.visibility ?? visibilityVisible;
row[columnPubMMdVersion] = file.pubMmdVersion ?? 0;
row[columnPubMMdEncodedJson] = file.pubMmdEncodedJson ?? '{}';
if (file.pubMagicMetadata != null &&
@ -1405,7 +1405,7 @@ class FilesDB {
row[columnMMdVersion] = file.mMdVersion ?? 0;
row[columnMMdEncodedJson] = file.mMdEncodedJson ?? '{}';
row[columnMMdVisibility] =
file.magicMetadata?.visibility ?? kVisibilityVisible;
file.magicMetadata?.visibility ?? visibilityVisible;
row[columnPubMMdVersion] = file.pubMmdVersion ?? 0;
row[columnPubMMdEncodedJson] = file.pubMmdEncodedJson ?? '{}';

View file

@ -18,7 +18,7 @@ class BillingPlans {
factory BillingPlans.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw ArgumentError('argument is null');
throw Exception('Argument is null');
}
return BillingPlans(
@ -53,7 +53,7 @@ class FreePlan {
factory FreePlan.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw ArgumentError('argument is null');
throw Exception('Argument is null');
}
return FreePlan(
@ -97,7 +97,7 @@ class BillingPlan {
factory BillingPlan.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw ArgumentError('argument is null');
throw Exception('Argument is null');
}
return BillingPlan(

View file

@ -1,28 +1,25 @@
// @dart=2.9
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 User? owner;
final String encryptedKey;
final String keyDecryptionNonce;
final String name;
final String? keyDecryptionNonce;
final String? name;
final String encryptedName;
final String nameDecryptionNonce;
final CollectionType type;
final CollectionAttributes attributes;
final List<User> sharees;
final List<PublicURL> publicURLs;
final CollectionAttributes? attributes;
final List<User?>? sharees;
final List<PublicURL?>? publicURLs;
final int updationTime;
final bool isDeleted;
String mMdEncodedJson;
String? mMdEncodedJson;
int mMdVersion = 0;
CollectionMagicMetadata _mmd;
CollectionMagicMetadata? _mmd;
CollectionMagicMetadata get magicMetadata =>
_mmd ?? CollectionMagicMetadata.fromEncodedJson(mMdEncodedJson ?? '{}');
@ -46,7 +43,7 @@ class Collection {
});
bool isArchived() {
return mMdVersion > 0 && magicMetadata.visibility == kVisibilityArchive;
return mMdVersion > 0 && magicMetadata.visibility == visibilityArchive;
}
static CollectionType typeFromString(String type) {
@ -71,21 +68,21 @@ class Collection {
}
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,
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,
@ -118,15 +115,17 @@ class Collection {
'nameDecryptionNonce': nameDecryptionNonce,
'type': typeToString(type),
'attributes': attributes?.toMap(),
'sharees': sharees?.map((x) => x?.toMap())?.toList(),
'publicURLs': publicURLs?.map((x) => x?.toMap())?.toList(),
'sharees': sharees?.map((x) => x?.toMap()).toList(),
'publicURLs': publicURLs?.map((x) => x?.toMap()).toList(),
'updationTime': updationTime,
'isDeleted': isDeleted,
};
}
factory Collection.fromMap(Map<String, dynamic> map) {
if (map == null) return null;
factory Collection.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw Exception('Argument is null');
}
final sharees = (map['sharees'] == null || map['sharees'].length == 0)
? <User>[]
: List<User>.from(map['sharees'].map((x) => User.fromMap(x)));
@ -152,53 +151,6 @@ class Collection {
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 {
@ -208,9 +160,9 @@ enum CollectionType {
}
class CollectionAttributes {
final String encryptedPath;
final String pathDecryptionNonce;
final int version;
final String? encryptedPath;
final String? pathDecryptionNonce;
final int? version;
CollectionAttributes({
this.encryptedPath,
@ -218,18 +170,6 @@ class CollectionAttributes {
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() {
final map = <String, dynamic>{};
if (encryptedPath != null) {
@ -242,8 +182,10 @@ class CollectionAttributes {
return map;
}
factory CollectionAttributes.fromMap(Map<String, dynamic> map) {
if (map == null) return null;
factory CollectionAttributes.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw Exception('Argument is null');
}
return CollectionAttributes(
encryptedPath: map['encryptedPath'],
@ -251,54 +193,19 @@ class CollectionAttributes {
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 {
int id;
int? id;
String email;
String name;
String? name;
User({
this.id,
this.email,
required this.email,
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() {
return {
'id': id,
@ -307,8 +214,10 @@ class User {
};
}
factory User.fromMap(Map<String, dynamic> map) {
if (map == null) return null;
factory User.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw Exception('Argument is null');
}
return User(
id: map['id'],
@ -320,34 +229,21 @@ class User {
String toJson() => json.encode(toMap());
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 {
String url;
int deviceLimit;
int validTill;
bool enableDownload = true;
bool passwordEnabled = false;
bool enableDownload;
bool passwordEnabled;
PublicURL({
this.url,
this.deviceLimit,
this.validTill,
this.enableDownload,
this.passwordEnabled,
required this.url,
required this.deviceLimit,
required this.validTill,
this.enableDownload = true,
this.passwordEnabled = false,
});
Map<String, dynamic> toMap() {
@ -360,8 +256,10 @@ class PublicURL {
};
}
factory PublicURL.fromMap(Map<String, dynamic> map) {
if (map == null) return null;
factory PublicURL.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw Exception('Argument is null');
}
return PublicURL(
url: map['url'],
@ -371,33 +269,4 @@ class PublicURL {
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;
}

View file

@ -33,7 +33,7 @@ class CollectionFileItem {
factory CollectionFileItem.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw ArgumentError('argument is null');
throw Exception('Argument is null');
}
return CollectionFileItem(

View file

@ -1,14 +1,12 @@
// @dart=2.9
import 'dart:convert';
const kVisibilityVisible = 0;
const kVisibilityArchive = 1;
const visibilityVisible = 0;
const visibilityArchive = 1;
const kMagicKeyVisibility = 'visibility';
const magicKeyVisibility = 'visibility';
const kPubMagicKeyEditedTime = 'editedTime';
const kPubMagicKeyEditedName = 'editedName';
const pubMagicKeyEditedTime = 'editedTime';
const pubMagicKeyEditedName = 'editedName';
class MagicMetadata {
// 0 -> visible
@ -16,23 +14,19 @@ class MagicMetadata {
// 2 -> hidden etc?
int visibility;
MagicMetadata({this.visibility});
MagicMetadata({required this.visibility});
factory MagicMetadata.fromEncodedJson(String encodedJson) =>
MagicMetadata.fromJson(jsonDecode(encodedJson));
factory MagicMetadata.fromJson(dynamic json) => MagicMetadata.fromMap(json);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map[kMagicKeyVisibility] = visibility;
return map;
}
factory MagicMetadata.fromMap(Map<String, dynamic> map) {
if (map == null) return null;
factory MagicMetadata.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw Exception('Argument is null');
}
return MagicMetadata(
visibility: map[kMagicKeyVisibility] ?? kVisibilityVisible,
visibility: map[magicKeyVisibility] ?? visibilityVisible,
);
}
}
@ -41,7 +35,7 @@ class PubMagicMetadata {
int editedTime;
String editedName;
PubMagicMetadata({this.editedTime, this.editedName});
PubMagicMetadata({required this.editedTime, required this.editedName});
factory PubMagicMetadata.fromEncodedJson(String encodedJson) =>
PubMagicMetadata.fromJson(jsonDecode(encodedJson));
@ -49,18 +43,13 @@ class PubMagicMetadata {
factory PubMagicMetadata.fromJson(dynamic json) =>
PubMagicMetadata.fromMap(json);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map[kPubMagicKeyEditedTime] = editedTime;
map[kPubMagicKeyEditedName] = editedName;
return map;
}
factory PubMagicMetadata.fromMap(Map<String, dynamic> map) {
if (map == null) return null;
factory PubMagicMetadata.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw Exception('Argument is null');
}
return PubMagicMetadata(
editedTime: map[kPubMagicKeyEditedTime],
editedName: map[kPubMagicKeyEditedName],
editedTime: map[pubMagicKeyEditedTime],
editedName: map[pubMagicKeyEditedName],
);
}
}
@ -71,7 +60,7 @@ class CollectionMagicMetadata {
// 2 -> hidden etc?
int visibility;
CollectionMagicMetadata({this.visibility});
CollectionMagicMetadata({required this.visibility});
factory CollectionMagicMetadata.fromEncodedJson(String encodedJson) =>
CollectionMagicMetadata.fromJson(jsonDecode(encodedJson));
@ -79,16 +68,12 @@ class CollectionMagicMetadata {
factory CollectionMagicMetadata.fromJson(dynamic json) =>
CollectionMagicMetadata.fromMap(json);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map[kMagicKeyVisibility] = visibility;
return map;
}
factory CollectionMagicMetadata.fromMap(Map<String, dynamic> map) {
if (map == null) return null;
factory CollectionMagicMetadata.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw Exception('Argument is null');
}
return CollectionMagicMetadata(
visibility: map[kMagicKeyVisibility] ?? kVisibilityVisible,
visibility: map[magicKeyVisibility] ?? visibilityVisible,
);
}
}

View file

@ -14,7 +14,7 @@ class AlbumSearchResult extends SearchResult {
@override
String name() {
return collectionWithThumbnail.collection.name;
return collectionWithThumbnail.collection.name!;
}
@override

View file

@ -34,7 +34,7 @@ class Subscription {
factory Subscription.fromMap(Map<String, dynamic>? map) {
if (map == null) {
throw ArgumentError("argument is null");
throw Exception("Argument is null");
}
return Subscription(
productID: map['productID'],

View file

@ -1,5 +1,3 @@
// @dart=2.9
import 'dart:math';
import 'package:collection/collection.dart';
@ -11,7 +9,7 @@ class UserDetails {
final int fileCount;
final int sharedCollectionsCount;
final Subscription subscription;
final FamilyData familyData;
final FamilyData? familyData;
UserDetails(
this.email,
@ -28,8 +26,8 @@ class UserDetails {
bool isFamilyAdmin() {
assert(isPartOfFamily(), "verify user is part of family before calling");
final FamilyMember currentUserMember = familyData?.members
?.firstWhere((element) => element.email.trim() == email.trim());
final FamilyMember currentUserMember = familyData!.members!
.firstWhere((element) => element.email.trim() == email.trim());
return currentUserMember.isAdmin;
}
@ -37,24 +35,20 @@ class UserDetails {
// belong to family group. Otherwise, it will return storage consumed by
// current user
int getFamilyOrPersonalUsage() {
return isPartOfFamily() ? familyData.getTotalUsage() : usage;
return isPartOfFamily() ? familyData!.getTotalUsage() : usage;
}
int getFreeStorage() {
return max(
isPartOfFamily()
? (familyData.storage - familyData.getTotalUsage())
? (familyData!.storage - familyData!.getTotalUsage())
: (subscription.storage - (usage)),
0,
);
}
int getTotalStorage() {
return isPartOfFamily() ? familyData.storage : subscription.storage;
}
int getPersonalUsage() {
return usage;
return isPartOfFamily() ? familyData!.storage : subscription.storage;
}
factory UserDetails.fromMap(Map<String, dynamic> map) {
@ -67,17 +61,6 @@ class UserDetails {
FamilyData.fromMap(map['familyData']),
);
}
Map<String, dynamic> toMap() {
return {
'email': email,
'usage': usage,
'fileCount': fileCount,
'sharedCollectionsCount': sharedCollectionsCount,
'subscription': subscription,
'familyData': familyData
};
}
}
class FamilyMember {
@ -96,14 +79,10 @@ class FamilyMember {
map['isAdmin'] as bool,
);
}
Map<String, dynamic> toMap() {
return {'email': email, 'usage': usage, 'id': id, 'isAdmin': isAdmin};
}
}
class FamilyData {
final List<FamilyMember> members;
final List<FamilyMember>? members;
// Storage available based on the family plan
final int storage;
@ -112,13 +91,11 @@ class FamilyData {
FamilyData(this.members, this.storage, this.expiryTime);
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) {
if (map == null) {
return null;
}
static fromMap(Map<String, dynamic>? map) {
if (map == null) return null;
assert(map['members'] != null && map['members'].length >= 0);
final members = List<FamilyMember>.from(
map['members'].map((x) => FamilyMember.fromMap(x)),
@ -129,12 +106,4 @@ class FamilyData {
map['expiryTime'] as int,
);
}
Map<String, dynamic> toMap() {
return {
'members': members.map((x) => x?.toMap())?.toList(),
'storage': storage,
'expiryTime': expiryTime
};
}
}

View file

@ -32,9 +32,9 @@ class FileMagicService {
FileMagicService._privateConstructor();
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);
if (visibility == kVisibilityVisible) {
if (visibility == visibilityVisible) {
// Force reload home gallery to pull in the now unarchived files
Bus.instance.fire(ForceReloadHomeGalleryEvent());
Bus.instance
@ -64,7 +64,8 @@ class FileMagicService {
// read the existing magic metadata and apply new updates to existing data
// current update is simple replace. This will be enhanced in the future,
// as required.
final Map<String, dynamic> jsonToUpdate = jsonDecode(file.pubMmdEncodedJson);
final Map<String, dynamic> jsonToUpdate =
jsonDecode(file.pubMmdEncodedJson);
newMetadataUpdate.forEach((key, value) {
jsonToUpdate[key] = value;
});
@ -134,7 +135,8 @@ class FileMagicService {
// read the existing magic metadata and apply new updates to existing data
// current update is simple replace. This will be enhanced in the future,
// as required.
final Map<String, dynamic> jsonToUpdate = jsonDecode(file.mMdEncodedJson);
final Map<String, dynamic> jsonToUpdate =
jsonDecode(file.mMdEncodedJson);
newMetadataUpdate.forEach((key, value) {
jsonToUpdate[key] = value;
});

View file

@ -46,7 +46,7 @@ class HiddenCollectionsButtonWidget extends StatelessWidget {
const Padding(padding: EdgeInsets.all(6)),
FutureBuilder<int>(
future: FilesDB.instance.fileCountWithVisibility(
kVisibilityArchive,
visibilityArchive,
Configuration.instance.getUserID(),
),
builder: (context, snapshot) {

View file

@ -87,7 +87,7 @@ class ValidityWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (currentSubscription == null) {
return Container();
return const SizedBox.shrink();
}
final endDate = getDateAndMonthAndYear(
DateTime.fromMicrosecondsSinceEpoch(currentSubscription.expiryTime),

View file

@ -106,7 +106,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
if (widget.file.uploadedFileID != null &&
widget.file.ownerID == Configuration.instance.getUserID()) {
final bool isArchived =
widget.file.magicMetadata.visibility == kVisibilityArchive;
widget.file.magicMetadata.visibility == visibilityArchive;
children.add(
Tooltip(
message: isArchived ? "Unhide" : "Hide",
@ -123,7 +123,7 @@ class FadingBottomBarState extends State<FadingBottomBar> {
await changeVisibility(
context,
[widget.file],
isArchived ? kVisibilityVisible : kVisibilityArchive,
isArchived ? visibilityVisible : visibilityArchive,
);
safeRefresh();
},

View file

@ -33,7 +33,7 @@ class ArchivePage extends StatelessWidget {
creationStartTime,
creationEndTime,
Configuration.instance.getUserID(),
visibility: kVisibilityArchive,
visibility: visibilityArchive,
limit: limit,
asc: asc,
);

View file

@ -220,8 +220,8 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
context,
widget.collection,
widget.collection.isArchived()
? kVisibilityVisible
: kVisibilityArchive,
? visibilityVisible
: visibilityArchive,
);
} else if (value == 3) {
await _trashCollection();

View file

@ -382,7 +382,7 @@ class _OverlayWidgetState extends State<OverlayWidget> {
onPressed: () {
_handleVisibilityChangeRequest(
context,
showArchive ? kVisibilityArchive : kVisibilityVisible,
showArchive ? visibilityArchive : visibilityVisible,
);
},
),

View file

@ -1,5 +1,3 @@
// @dart=2.9
import 'package:local_auth/auth_strings.dart';
import 'package:local_auth/local_auth.dart';
import 'package:logging/logging.dart';

View file

@ -1,5 +1,3 @@
// @dart=2.9
import 'dart:math';
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) {
int storageUnitIndex = 0;
while (bytes >= 1024 && storageUnitIndex < kStorageUnits.length - 1) {
while (bytes >= 1024 && storageUnitIndex < storageUnits.length - 1) {
storageUnitIndex++;
bytes = (bytes / 1024).round();
}
return bytes.toString() + " " + kStorageUnits[storageUnitIndex];
return bytes.toString() + " " + storageUnits[storageUnitIndex];
}
String formatBytes(int bytes, [int decimals = 2]) {
@ -24,5 +22,5 @@ String formatBytes(int bytes, [int decimals = 2]) {
const k = 1024;
final int dm = decimals < 0 ? 0 : decimals;
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];
}

View file

@ -1,5 +1,3 @@
// @dart=2.9
import 'dart:async';
import 'package:flutter/material.dart';
@ -7,13 +5,13 @@ import 'package:flutter/material.dart';
class Debouncer {
final Duration _duration;
final ValueNotifier<bool> _debounceActiveNotifier = ValueNotifier(false);
Timer _debounceTimer;
Timer? _debounceTimer;
Debouncer(this._duration);
void run(Future<void> Function() fn) {
if (isActive()) {
_debounceTimer.cancel();
_debounceTimer!.cancel();
}
_debounceTimer = Timer(_duration, () async {
await fn();
@ -24,11 +22,11 @@ class Debouncer {
void cancelDebounce() {
if (_debounceTimer != null) {
_debounceTimer.cancel();
_debounceTimer!.cancel();
}
}
bool isActive() => _debounceTimer != null && _debounceTimer.isActive;
bool isActive() => _debounceTimer != null && _debounceTimer!.isActive;
ValueNotifier<bool> get debounceActiveNotifier {
return _debounceActiveNotifier;

View file

@ -1,5 +1,3 @@
// @dart=2.9
import 'package:shared_preferences/shared_preferences.dart';
enum AlbumSortKey {
@ -13,15 +11,14 @@ class LocalSettings {
static final LocalSettings instance = LocalSettings._privateConstructor();
static const kCollectionSortPref = "collection_sort_pref";
SharedPreferences _prefs;
late SharedPreferences _prefs;
Future<void> init() async {
_prefs = await SharedPreferences.getInstance();
}
AlbumSortKey albumSortKey() {
return AlbumSortKey.values[_prefs.getInt(kCollectionSortPref) ?? 0] ??
AlbumSortKey.lastUpdated;
return AlbumSortKey.values[_prefs.getInt(kCollectionSortPref) ?? 0];
}
Future<bool> setAlbumSortKey(AlbumSortKey key) {

View file

@ -23,14 +23,14 @@ Future<void> changeVisibility(
) async {
final dialog = createProgressDialog(
context,
newVisibility == kVisibilityArchive ? "Hiding..." : "Unhiding...",
newVisibility == visibilityArchive ? "Hiding..." : "Unhiding...",
);
await dialog.show();
try {
await FileMagicService.instance.changeVisibility(files, newVisibility);
showShortToast(
context,
newVisibility == kVisibilityArchive
newVisibility == visibilityArchive
? "Successfully hidden"
: "Successfully unhidden",
);
@ -50,17 +50,17 @@ Future<void> changeCollectionVisibility(
) async {
final dialog = createProgressDialog(
context,
newVisibility == kVisibilityArchive ? "Hiding..." : "Unhiding...",
newVisibility == visibilityArchive ? "Hiding..." : "Unhiding...",
);
await dialog.show();
try {
final Map<String, dynamic> update = {kMagicKeyVisibility: newVisibility};
final Map<String, dynamic> update = {magicKeyVisibility: newVisibility};
await CollectionsService.instance.updateMagicMetadata(collection, update);
// Force reload home gallery to pull in the now unarchived files
Bus.instance.fire(ForceReloadHomeGalleryEvent());
showShortToast(
context,
newVisibility == kVisibilityArchive
newVisibility == visibilityArchive
? "Successfully hidden"
: "Successfully unhidden",
);
@ -82,7 +82,7 @@ Future<bool> editTime(
await _updatePublicMetadata(
context,
files,
kPubMagicKeyEditedTime,
pubMagicKeyEditedTime,
editedTime,
);
return true;
@ -115,7 +115,7 @@ Future<bool> editFilename(
await _updatePublicMetadata(
context,
List.of([file]),
kPubMagicKeyEditedName,
pubMagicKeyEditedName,
result,
);
return true;
@ -152,5 +152,5 @@ Future<void> _updatePublicMetadata(
}
bool _shouldReloadGallery(String key) {
return key == kPubMagicKeyEditedTime;
return key == pubMagicKeyEditedTime;
}

View file

@ -1,10 +1,8 @@
// @dart=2.9
import 'dart:io';
import 'package:flutter/material.dart';
Future<T> routeToPage<T extends Object>(
Future<T?> routeToPage<T extends Object>(
BuildContext context,
Widget page, {
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)
// final PageTransitionsBuilder matchingBuilder = const FadeUpwardsPageTransitionsBuilder(); // Default Android/Linux/Windows
SwipeableRouteBuilder({this.pageBuilder});
SwipeableRouteBuilder({required this.pageBuilder});
@override
Color get barrierColor => null;
Null get barrierColor => null;
@override
String get barrierLabel => null;
Null get barrierLabel => null;
@override
Widget buildPage(
@ -110,21 +108,21 @@ class SwipeableRouteBuilder<T> extends PageRoute<T> {
class TransparentRoute extends PageRoute<void> {
TransparentRoute({
@required this.builder,
RouteSettings settings,
required this.builder,
RouteSettings? settings,
}) : assert(builder != null),
super(settings: settings, fullscreenDialog: false);
final WidgetBuilder builder;
final WidgetBuilder? builder;
@override
bool get opaque => false;
@override
Color get barrierColor => null;
Null get barrierColor => null;
@override
String get barrierLabel => null;
Null get barrierLabel => null;
@override
bool get maintainState => true;
@ -138,7 +136,7 @@ class TransparentRoute extends PageRoute<void> {
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
final result = builder(context);
final result = builder!(context);
return FadeTransition(
opacity: Tween<double>(begin: 0, end: 1).animate(animation),
child: Semantics(