diff --git a/app/lib/account.dart b/app/lib/account.dart index c8c31298..dc830f2f 100644 --- a/app/lib/account.dart +++ b/app/lib/account.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:clock/clock.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; @@ -52,7 +53,7 @@ class Account with EquatableMixin { } static String newId() { - final timestamp = DateTime.now().millisecondsSinceEpoch; + final timestamp = clock.now().millisecondsSinceEpoch; final random = Random().nextInt(0xFFFFFF); return "${timestamp.toRadixString(16)}-${random.toRadixString(16).padLeft(6, '0')}"; } diff --git a/app/lib/api/api_util.dart b/app/lib/api/api_util.dart index f025d17c..69e45bcf 100644 --- a/app/lib/api/api_util.dart +++ b/app/lib/api/api_util.dart @@ -1,6 +1,7 @@ /// Helper functions working with remote Nextcloud server import 'dart:convert'; +import 'package:clock/clock.dart'; import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; @@ -193,13 +194,13 @@ class InitiateLoginResponse { class InitiateLoginPollOptions { InitiateLoginPollOptions(this.token, String endpoint) : endpoint = Uri.parse(endpoint), - _validUntil = DateTime.now().add(const Duration(minutes: 20)); + _validUntil = clock.now().add(const Duration(minutes: 20)); @override String toString() => _$toString(); bool isTokenValid() { - return DateTime.now().isBefore(_validUntil); + return clock.now().isBefore(_validUntil); } @Format(r"${kDebugMode ? $? : '***'}") diff --git a/app/lib/entity/album.dart b/app/lib/entity/album.dart index 2c69ba31..e85835a1 100644 --- a/app/lib/entity/album.dart +++ b/app/lib/entity/album.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:equatable/equatable.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; @@ -35,7 +36,7 @@ class Album with EquatableMixin { this.shares, this.albumFile, int? savedVersion, - }) : lastUpdated = (lastUpdated ?? DateTime.now()).toUtc(), + }) : lastUpdated = (lastUpdated ?? clock.now()).toUtc(), savedVersion = savedVersion ?? version; static Album? fromJson( @@ -227,7 +228,7 @@ class AlbumShare with EquatableMixin { required this.userId, this.displayName, DateTime? sharedAt, - }) : sharedAt = (sharedAt ?? DateTime.now()).toUtc(); + }) : sharedAt = (sharedAt ?? clock.now()).toUtc(); factory AlbumShare.fromJson(JsonObj json) { return AlbumShare( diff --git a/app/lib/entity/album/data_source.dart b/app/lib/entity/album/data_source.dart index eb85b617..37de0c96 100644 --- a/app/lib/entity/album/data_source.dart +++ b/app/lib/entity/album/data_source.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:math'; +import 'package:clock/clock.dart'; import 'package:drift/drift.dart' as sql; import 'package:kiwi/kiwi.dart'; import 'package:logging/logging.dart'; @@ -94,7 +95,7 @@ class AlbumRemoteDataSource implements AlbumDataSource { String _makeAlbumFileName() { // just make up something - final timestamp = DateTime.now().millisecondsSinceEpoch; + final timestamp = clock.now().millisecondsSinceEpoch; final random = Random().nextInt(0xFFFFFF); return "${timestamp.toRadixString(16)}-${random.toRadixString(16).padLeft(6, '0')}.nc_album.json"; } diff --git a/app/lib/entity/file.dart b/app/lib/entity/file.dart index f5603df9..56a2aef3 100644 --- a/app/lib/entity/file.dart +++ b/app/lib/entity/file.dart @@ -1,5 +1,6 @@ import 'dart:typed_data'; +import 'package:clock/clock.dart'; import 'package:equatable/equatable.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; @@ -93,7 +94,7 @@ class Metadata with EquatableMixin { this.imageWidth, this.imageHeight, this.exif, - }) : lastUpdated = (lastUpdated ?? DateTime.now()).toUtc(); + }) : lastUpdated = (lastUpdated ?? clock.now()).toUtc(); @override // ignore: hash_and_equals diff --git a/app/lib/entity/file_util.dart b/app/lib/entity/file_util.dart index acf23c90..5741c3ca 100644 --- a/app/lib/entity/file_util.dart +++ b/app/lib/entity/file_util.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/api/api_util.dart' as api_util; import 'package:nc_photos/entity/file.dart'; @@ -100,7 +101,8 @@ DateTime getBestDateTime({ DateTime? overrideDateTime, DateTime? dateTimeOriginal, DateTime? lastModified, -}) => overrideDateTime ?? dateTimeOriginal ?? lastModified ?? DateTime.now().toUtc(); +}) => + overrideDateTime ?? dateTimeOriginal ?? lastModified ?? clock.now().toUtc(); final supportedFormatMimes = [ "image/jpeg", diff --git a/app/lib/share_handler.dart b/app/lib/share_handler.dart index a517078a..4a7b82a6 100644 --- a/app/lib/share_handler.dart +++ b/app/lib/share_handler.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:math'; +import 'package:clock/clock.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:kiwi/kiwi.dart'; @@ -317,7 +318,7 @@ class ShareHandler { FileRepo fileRepo, Account account, String name) async { // add a intermediate dir to allow shared dirs having the same name. Since // the dir names are public, we can't add random pre/suffix - final timestamp = DateTime.now().millisecondsSinceEpoch; + final timestamp = clock.now().millisecondsSinceEpoch; final random = Random().nextInt(0xFFFFFF); final dirName = "${timestamp.toRadixString(16)}-${random.toRadixString(16).padLeft(6, "0")}"; diff --git a/app/lib/use_case/list_potential_shared_album.dart b/app/lib/use_case/list_potential_shared_album.dart index 35da903c..674ec53b 100644 --- a/app/lib/use_case/list_potential_shared_album.dart +++ b/app/lib/use_case/list_potential_shared_album.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; import 'package:nc_photos/entity/file.dart'; @@ -44,7 +45,7 @@ class ListPotentialSharedAlbum { final timestamp = int.parse(match.group(1)!, radix: 16); final time = DateTime.fromMillisecondsSinceEpoch(timestamp); _log.fine("[_checkFileName] Timestamp: $time"); - if (time.isAfter(DateTime.now())) { + if (time.isAfter(clock.now())) { _log.warning("[_checkFileName] Invalid timestamp: ${f.path}"); return false; } diff --git a/app/lib/use_case/populate_album.dart b/app/lib/use_case/populate_album.dart index 0815f79e..6d2d5b24 100644 --- a/app/lib/use_case/populate_album.dart +++ b/app/lib/use_case/populate_album.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:kiwi/kiwi.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/account.dart'; @@ -56,7 +57,7 @@ class PopulateAlbum { } products.addAll((result as List).cast().map((f) => AlbumFileItem( addedBy: account.userId, - addedAt: DateTime.now(), + addedAt: clock.now(), file: f, ))); } @@ -73,7 +74,7 @@ class PopulateAlbum { final files = await ListTaggedFile(c)(account, provider.tags); products.addAll(files.map((f) => AlbumFileItem( addedBy: account.userId, - addedAt: DateTime.now(), + addedAt: clock.now(), file: f, ))); return products; @@ -93,7 +94,7 @@ class PopulateAlbum { .where((f) => file_util.isSupportedFormat(f)) .map((f) => AlbumFileItem( addedBy: account.userId, - addedAt: DateTime.now(), + addedAt: clock.now(), file: f, )) .toList(); diff --git a/app/lib/widget/album_browser.dart b/app/lib/widget/album_browser.dart index e973529e..30b62c26 100644 --- a/app/lib/widget/album_browser.dart +++ b/app/lib/widget/album_browser.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:clock/clock.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; @@ -670,7 +671,7 @@ class _AlbumBrowserState extends State items: [ AlbumLabelItem( addedBy: widget.account.userId, - addedAt: DateTime.now(), + addedAt: clock.now(), text: value, ), ..._sortedItems, diff --git a/app/lib/widget/builder/photo_list_item_builder.dart b/app/lib/widget/builder/photo_list_item_builder.dart index 4d07be59..738a4eac 100644 --- a/app/lib/widget/builder/photo_list_item_builder.dart +++ b/app/lib/widget/builder/photo_list_item_builder.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:collection/collection.dart'; import 'package:flutter/widgets.dart'; import 'package:logging/logging.dart'; @@ -134,7 +135,7 @@ class _PhotoListItemBuilder { PhotoListItemBuilderResult _fromSortedItems( Account account, List files) { - final today = DateTime.now(); + final today = clock.now(); final memoryAlbumHelper = smartAlbumConfig != null ? MemoryAlbumHelper( today: today, dayRange: smartAlbumConfig!.memoriesDayRange) diff --git a/app/lib/widget/handler/add_selection_to_album_handler.dart b/app/lib/widget/handler/add_selection_to_album_handler.dart index 00cb26fa..2c0d9c2a 100644 --- a/app/lib/widget/handler/add_selection_to_album_handler.dart +++ b/app/lib/widget/handler/add_selection_to_album_handler.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:flutter/material.dart'; import 'package:kiwi/kiwi.dart'; import 'package:logging/logging.dart'; @@ -48,7 +49,7 @@ class AddSelectionToAlbumHandler { final selected = selectedFiles .map((f) => AlbumFileItem( addedBy: account.userId, - addedAt: DateTime.now(), + addedAt: clock.now(), file: f, )) .toList(); diff --git a/app/lib/widget/handler/double_tap_exit_handler.dart b/app/lib/widget/handler/double_tap_exit_handler.dart index be47198b..26d9a8cf 100644 --- a/app/lib/widget/handler/double_tap_exit_handler.dart +++ b/app/lib/widget/handler/double_tap_exit_handler.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:flutter/material.dart'; import 'package:nc_photos/app_localizations.dart'; import 'package:nc_photos/k.dart' as k; @@ -14,7 +15,7 @@ class DoubleTapExitHandler { if (!Pref().isDoubleTapExitOr()) { return true; } - final now = DateTime.now().toUtc(); + final now = clock.now().toUtc(); _lastBackButtonAt ??= now.subtract(const Duration(days: 1)); if (now.difference(_lastBackButtonAt!) < const Duration(seconds: 5)) { return true; diff --git a/app/lib/widget/photo_list_util.dart b/app/lib/widget/photo_list_util.dart index f2d2df8a..0bbf2b69 100644 --- a/app/lib/widget/photo_list_util.dart +++ b/app/lib/widget/photo_list_util.dart @@ -1,5 +1,6 @@ import 'dart:math' as math; +import 'package:clock/clock.dart'; import 'package:collection/collection.dart'; import 'package:logging/logging.dart'; import 'package:nc_photos/date_time_extension.dart'; @@ -41,7 +42,7 @@ class MemoryAlbumHelper { MemoryAlbumHelper({ DateTime? today, required int dayRange, - }) : today = (today?.toLocal() ?? DateTime.now()).toMidnight(), + }) : today = (today?.toLocal() ?? clock.now()).toMidnight(), dayRange = math.max(dayRange, 0); void addFile(FileDescriptor f) { diff --git a/app/lib/widget/splash.dart b/app/lib/widget/splash.dart index ae94868a..8c8978f6 100644 --- a/app/lib/widget/splash.dart +++ b/app/lib/widget/splash.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:clock/clock.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:kiwi/kiwi.dart'; @@ -46,7 +47,7 @@ class _SplashState extends State { Future _doWork() async { if (Pref().getFirstRunTime() == null) { - await Pref().setFirstRunTime(DateTime.now().millisecondsSinceEpoch); + await Pref().setFirstRunTime(clock.now().millisecondsSinceEpoch); } if (_shouldUpgrade()) { setState(() { diff --git a/app/pubspec.lock b/app/pubspec.lock index 5386bf42..c0f8243b 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -228,7 +228,7 @@ packages: source: hosted version: "0.3.5" clock: - dependency: transitive + dependency: "direct main" description: name: clock url: "https://pub.dartlang.org" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index e380fae0..55b1b962 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -38,6 +38,7 @@ dependencies: bloc_concurrency: ^0.2.0 cached_network_image: ^3.2.1 circular_reveal_animation: ^2.0.1 + clock: ^1.1.1 collection: ^1.15.0 connectivity_plus: ^2.0.2 copy_with: diff --git a/app/test/entity/file_test.dart b/app/test/entity/file_test.dart index 03bade8c..4202aa1a 100644 --- a/app/test/entity/file_test.dart +++ b/app/test/entity/file_test.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:nc_photos/entity/exif.dart'; import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; @@ -837,7 +838,7 @@ void main() { }); test("lastModified", () { - final now = DateTime.now(); + final now = clock.now(); final file = src.copyWith(lastModified: now); expect( file, @@ -1022,7 +1023,7 @@ void main() { }); test("trashbinDeletionTime", () { - final now = DateTime.now(); + final now = clock.now(); final file = src.copyWith(trashbinDeletionTime: now); expect( file, diff --git a/app/test/use_case/inflate_file_descriptor_test.dart b/app/test/use_case/inflate_file_descriptor_test.dart index 02d0097f..2e409ad7 100644 --- a/app/test/use_case/inflate_file_descriptor_test.dart +++ b/app/test/use_case/inflate_file_descriptor_test.dart @@ -1,3 +1,4 @@ +import 'package:clock/clock.dart'; import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/entity/file_descriptor.dart'; import 'package:nc_photos/entity/sqlite/database.dart' as sql; @@ -104,7 +105,7 @@ Future _missing() async { fdMime: null, fdIsArchived: false, fdIsFavorite: false, - fdDateTime: DateTime.now(), + fdDateTime: clock.now(), ), ], ),