Skip to content

Commit

Permalink
refactor(neon_framework)!: use package:timezone TZDateTime for dates
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolas Rimikis <leptopoda@users.noreply.github.com>
  • Loading branch information
Leptopoda committed Mar 13, 2024
1 parent d1fcfbd commit c320200
Show file tree
Hide file tree
Showing 23 changed files with 86 additions and 46 deletions.
5 changes: 3 additions & 2 deletions packages/neon/neon_files/lib/src/blocs/files.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import 'package:path_provider/path_provider.dart';
import 'package:queue/queue.dart';
import 'package:rxdart/rxdart.dart';
import 'package:share_plus/share_plus.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:universal_io/io.dart';

sealed class FilesBloc implements InteractiveBloc {
Expand All @@ -30,7 +31,7 @@ sealed class FilesBloc implements InteractiveBloc {

void uploadFile(PathUri uri, String localPath);

void uploadMemory(PathUri uri, Uint8List bytes, {DateTime? lastModified});
void uploadMemory(PathUri uri, Uint8List bytes, {tz.TZDateTime? lastModified});

void openFile(PathUri uri, String etag, String? mimeType);

Expand Down Expand Up @@ -115,7 +116,7 @@ class _FilesBloc extends InteractiveBloc implements FilesBloc {
}

@override
Future<void> uploadMemory(PathUri uri, Uint8List bytes, {DateTime? lastModified}) async {
Future<void> uploadMemory(PathUri uri, Uint8List bytes, {tz.TZDateTime? lastModified}) async {
await wrapAction(
() async {
final task = FilesUploadTaskMemory(
Expand Down
3 changes: 2 additions & 1 deletion packages/neon/neon_files/lib/src/models/file_details.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:meta/meta.dart';
import 'package:neon_files/src/utils/task.dart';
import 'package:nextcloud/webdav.dart';
import 'package:timezone/timezone.dart' as tz;

@immutable
class FileDetails {
Expand Down Expand Up @@ -73,7 +74,7 @@ class FileDetails {

final String? mimeType;

final DateTime? lastModified;
final tz.TZDateTime? lastModified;

final bool? hasPreview;

Expand Down
9 changes: 5 additions & 4 deletions packages/neon/neon_files/lib/src/utils/task.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:typed_data';

import 'package:meta/meta.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:universal_io/io.dart';

sealed class FilesTask {
Expand Down Expand Up @@ -34,7 +35,7 @@ sealed class FilesUploadTask extends FilesTask {

final int? size;

final DateTime? lastModified;
final tz.TZDateTime? lastModified;
}

sealed class FilesTaskIO extends FilesTask {
Expand Down Expand Up @@ -83,10 +84,10 @@ class FilesUploadTaskIO extends FilesTaskIO implements FilesUploadTask {
late final FileStat _stat = file.statSync();

@override
late int? size = _stat.size;
late int size = _stat.size;

@override
late DateTime? lastModified = _stat.modified;
late tz.TZDateTime lastModified = tz.TZDateTime.from(_stat.modified, tz.UTC);

Future<void> execute(NextcloudClient client) async {
await client.webdav.putFile(
Expand Down Expand Up @@ -129,7 +130,7 @@ class FilesUploadTaskMemory extends FilesTaskMemory implements FilesUploadTask {
final int? size;

@override
final DateTime? lastModified;
final tz.TZDateTime? lastModified;

Future<void> execute(NextcloudClient client) async {
await client.webdav.putStream(
Expand Down
1 change: 1 addition & 0 deletions packages/neon/neon_files/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ dependencies:
queue: ^3.0.0
rxdart: ^0.27.0
share_plus: ^7.0.0
timezone: ^0.9.2
universal_io: ^2.0.0

dev_dependencies:
Expand Down
3 changes: 2 additions & 1 deletion packages/neon/neon_notifications/lib/src/pages/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:neon_notifications/l10n/localizations.dart';
import 'package:neon_notifications/src/blocs/notifications.dart';
import 'package:nextcloud/ids.dart';
import 'package:nextcloud/notifications.dart' as notifications;
import 'package:timezone/timezone.dart' as tz;

class NotificationsMainPage extends StatefulWidget {
const NotificationsMainPage({
Expand Down Expand Up @@ -84,7 +85,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
),
],
RelativeTime(
date: DateTime.parse(notification.datetime).toUtc(),
date: tz.TZDateTime.parse(tz.UTC, notification.datetime),
),
],
),
Expand Down
1 change: 1 addition & 0 deletions packages/neon/neon_notifications/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies:
path: packages/neon_framework
nextcloud: ^5.0.2
rxdart: ^0.27.0
timezone: ^0.9.2

dev_dependencies:
build_runner: ^2.4.8
Expand Down
2 changes: 1 addition & 1 deletion packages/neon/neon_talk/lib/src/widgets/message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ class TalkCommentMessage extends StatelessWidget {
tz.UTC,
chatMessage.timestamp,
);
DateTime? previousDate;
tz.TZDateTime? previousDate;
if (previousChatMessage != null) {
previousDate = DateTimeUtils.fromSecondsSinceEpoch(
tz.UTC,
Expand Down
9 changes: 5 additions & 4 deletions packages/neon_framework/lib/src/blocs/user_status.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:nextcloud/nextcloud.dart';
import 'package:nextcloud/user_status.dart' as user_status;
import 'package:nextcloud/utils.dart';
import 'package:rxdart/rxdart.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:window_manager/window_manager.dart';

/// Bloc for managing user statuses.
Expand Down Expand Up @@ -42,14 +43,14 @@ abstract class UserStatusBloc implements InteractiveBloc {
/// Predefined status messages received from [predefinedStatuses].
void setPredefinedMessage({
required String id,
required DateTime? clearAt,
required tz.TZDateTime? clearAt,
});

/// Set a custom status [message] with the [icon] and [clearAt].
void setCustomMessage({
required String? message,
required String? icon,
required DateTime? clearAt,
required tz.TZDateTime? clearAt,
});

/// Clear the current status message.
Expand Down Expand Up @@ -211,7 +212,7 @@ class _UserStatusBloc extends InteractiveBloc implements UserStatusBloc {
@override
Future<void> setPredefinedMessage({
required String id,
required DateTime? clearAt,
required tz.TZDateTime? clearAt,
}) async {
await wrapAction(
() async {
Expand All @@ -230,7 +231,7 @@ class _UserStatusBloc extends InteractiveBloc implements UserStatusBloc {
Future<void> setCustomMessage({
required String? message,
required String? icon,
required DateTime? clearAt,
required tz.TZDateTime? clearAt,
}) async {
await wrapAction(
() async {
Expand Down
3 changes: 2 additions & 1 deletion packages/neon_framework/lib/src/pages/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import 'package:neon_framework/src/widgets/dialog.dart';
import 'package:neon_framework/src/widgets/error.dart';
import 'package:nextcloud/utils.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:url_launcher/url_launcher_string.dart';

final _log = Logger('SettingsPage');
Expand Down Expand Up @@ -249,7 +250,7 @@ class _SettingsPageState extends State<SettingsPage> {
final settingsExportHelper = _buildSettingsExportHelper(context);

try {
final fileName = 'nextcloud-neon-settings-${DateTime.timestamp().secondsSinceEpoch}.json';
final fileName = 'nextcloud-neon-settings-${tz.TZDateTime.now(tz.UTC).secondsSinceEpoch}.json';

final data = settingsExportHelper.exportToFile();
await NeonPlatform.instance.saveFileWithPickDialog(fileName, 'application/json', data);
Expand Down
5 changes: 3 additions & 2 deletions packages/neon_framework/lib/src/storage/request_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:neon_framework/src/utils/request_manager.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:timezone/timezone.dart' as tz;

final _log = Logger('RequestCache');

Expand Down Expand Up @@ -168,9 +169,9 @@ CREATE TABLE "cache" (
return CacheParameters(
etag: row?['etag'] as String?,
expires: expires != null
? DateTime.fromMillisecondsSinceEpoch(
? tz.TZDateTime.fromMillisecondsSinceEpoch(
tz.UTC,
expires,
isUtc: true,
)
: null,
);
Expand Down
3 changes: 2 additions & 1 deletion packages/neon_framework/lib/src/utils/push_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import 'package:neon_framework/src/utils/request_manager.dart';
import 'package:neon_framework/storage.dart';
import 'package:nextcloud/notifications.dart' as notifications;
import 'package:rxdart/rxdart.dart';
import 'package:timezone/timezone.dart' as tz;

final _log = Logger('PushUtils');

Expand Down Expand Up @@ -152,7 +153,7 @@ class PushUtils {
}
final title = (notification?.subject ?? pushNotification.subject.subject)!;
final message = (notification?.message.isNotEmpty ?? false) ? notification!.message : null;
final when = notification != null ? DateTime.parse(notification.datetime).toUtc() : null;
final when = notification != null ? tz.TZDateTime.parse(tz.UTC, notification.datetime) : null;

await localNotificationsPlugin.show(
_getNotificationID(instance, pushNotification),
Expand Down
11 changes: 6 additions & 5 deletions packages/neon_framework/lib/src/utils/relative_time.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import 'package:meta/meta.dart';
import 'package:neon_framework/l10n/localizations.dart';
import 'package:timezone/timezone.dart' as tz;

/// Extension for formatting the difference between two [DateTime]s.
/// Extension for formatting the difference between two [tz.TZDateTime]s.
@internal
extension RelativeTimeFormatDateTime on DateTime {
extension RelativeTimeFormatDateTime on tz.TZDateTime {
/// Format the relative time between this and [to].
///
/// If [to] is unspecified [DateTime.timestamp] will be used.
/// If [to] is unspecified the current time in the 'UTC' timezone will be used.
/// Set [includeSign] to skip the parts that tell if the difference is into the future or into the past.
/// It should only be used if it is already clear from the context if it is about the future or the past.
String formatRelative(
NeonLocalizations localizations, {
bool includeSign = true,
DateTime? to,
tz.TZDateTime? to,
}) =>
difference(to ?? DateTime.timestamp()).formatRelative(
difference(to ?? tz.TZDateTime.now(tz.UTC)).formatRelative(
localizations,
includeSign: includeSign,
);
Expand Down
12 changes: 9 additions & 3 deletions packages/neon_framework/lib/src/utils/request_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:neon_framework/src/models/account.dart';
import 'package:neon_framework/storage.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:rxdart/rxdart.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:xml/xml.dart' as xml;

final _log = Logger('RequestManager');
Expand Down Expand Up @@ -365,7 +366,12 @@ class CacheParameters {

/// Parse the cache parameters from HTTP response headers.
factory CacheParameters.parseHeaders(Map<String, dynamic> headers) {
final expiry = headers.containsKey('expires') ? parseHttpDate(headers['expires']! as String) : null;
tz.TZDateTime? expiry;
if (headers.containsKey('expires')) {
final parsed = parseHttpDate(headers['expires']! as String);
expiry = tz.TZDateTime.from(parsed, tz.UTC);
}

return CacheParameters(
etag: headers['etag'] as String?,
expires: _isExpired(expiry) ? null : expiry,
Expand All @@ -376,12 +382,12 @@ class CacheParameters {
final String? etag;

/// `Expires` of the resource.
final DateTime? expires;
final tz.TZDateTime? expires;

/// Whether the resource has expired based on [expires].
bool get isExpired => _isExpired(expires);

static bool _isExpired(DateTime? date) => date?.isBefore(DateTime.timestamp()) ?? true;
static bool _isExpired(tz.TZDateTime? date) => date?.isBefore(tz.TZDateTime.now(tz.UTC)) ?? true;

@override
bool operator ==(Object other) => other is CacheParameters && other.etag == etag && other.expires == expires;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:meta/meta.dart';
import 'package:neon_framework/l10n/localizations.dart';
import 'package:neon_framework/src/utils/relative_time.dart';
import 'package:nextcloud/user_status.dart' as user_status;
import 'package:timezone/timezone.dart' as tz;

@internal
extension ClearAt on user_status.ClearAt {
Expand All @@ -25,16 +26,16 @@ extension ClearAt on user_status.ClearAt {
throw ArgumentError('Unknown ClearAt $this');
}

DateTime? toDateTime([DateTime? base]) {
base = base?.toUtc() ?? DateTime.timestamp();
tz.TZDateTime? toDateTime([tz.TZDateTime? base]) {
base = base?.toUtc() ?? tz.TZDateTime.now(tz.UTC);

switch (type) {
case user_status.ClearAt_Type.endOf:
switch (time.clearAtTimeType) {
case user_status.ClearAtTimeType.day:
return DateTime.utc(base.year, base.month, base.day).add(const Duration(days: 1));
return tz.TZDateTime.utc(base.year, base.month, base.day).add(const Duration(days: 1));
case user_status.ClearAtTimeType.week:
return DateTime.utc(base.year, base.month, base.day).add(Duration(days: 8 - base.weekday));
return tz.TZDateTime.utc(base.year, base.month, base.day).add(Duration(days: 8 - base.weekday));
}
case user_status.ClearAt_Type.period:
return base.add(Duration(seconds: time.$int!));
Expand Down
2 changes: 1 addition & 1 deletion packages/neon_framework/lib/src/widgets/dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ class NeonUserStatusDialog extends StatefulWidget {
final Account account;

/// The current time, only used for testing.
final DateTime? now;
final tz.TZDateTime? now;

@override
State<NeonUserStatusDialog> createState() => _NeonUserStatusDialogState();
Expand Down
3 changes: 2 additions & 1 deletion packages/neon_framework/lib/src/widgets/image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import 'package:neon_framework/src/widgets/error.dart';
import 'package:neon_framework/src/widgets/linear_progress_indicator.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:rxdart/rxdart.dart';
import 'package:timezone/timezone.dart' as tz;

/// The signature of a function building a widget displaying [error].
typedef ErrorWidgetBuilder = Widget? Function(BuildContext context, Object? error);
Expand Down Expand Up @@ -191,7 +192,7 @@ class NeonApiImage extends StatefulWidget {
final String? etag;

/// The expiration date used for invalidating the cache.
final DateTime? expires;
final tz.TZDateTime? expires;

/// {@macro NeonImage.svgHint}
final bool isSvgHint;
Expand Down
5 changes: 3 additions & 2 deletions packages/neon_framework/lib/src/widgets/relative_time.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:neon_framework/l10n/localizations.dart';
import 'package:neon_framework/src/utils/relative_time.dart';
import 'package:timezone/timezone.dart' as tz;

/// Shows the time elapsed since a [DateTime] and periodically updates itself.
/// Shows the time elapsed since a [tz.TZDateTime] and periodically updates itself.
class RelativeTime extends StatefulWidget {
/// Creates a new relative DateTime widget.
const RelativeTime({
Expand All @@ -14,7 +15,7 @@ class RelativeTime extends StatefulWidget {
});

/// The timestamp to be displayed.
final DateTime date;
final tz.TZDateTime date;

/// The text style of the calculated time.
///
Expand Down
3 changes: 2 additions & 1 deletion packages/neon_framework/test/dialog_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:nextcloud/user_status.dart' as user_status;
import 'package:nextcloud/utils.dart';
import 'package:rxdart/rxdart.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:timezone/timezone.dart' as tz;

void main() {
group('dialog', () {
Expand Down Expand Up @@ -209,7 +210,7 @@ void main() {
testWidgets('NeonUserStatusDialog', (tester) async {
SharedPreferences.setMockInitialValues({});

final now = DateTime.utc(2024, 1, 20);
final now = tz.TZDateTime.utc(2024, 1, 20);

final status = BehaviorSubject.seeded(
Result.success(
Expand Down
7 changes: 4 additions & 3 deletions packages/neon_framework/test/persistence_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:neon_framework/src/storage/request_cache.dart';
import 'package:neon_framework/src/storage/sqlite_persistence.dart';
import 'package:neon_framework/src/utils/request_manager.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:timezone/timezone.dart' as tz;

void main() {
group('Persistences', () {
Expand Down Expand Up @@ -44,9 +45,9 @@ void main() {

parameters = CacheParameters(
etag: 'etag',
expires: DateTime.fromMillisecondsSinceEpoch(
DateTime.timestamp().millisecondsSinceEpoch,
isUtc: true,
expires: tz.TZDateTime.fromMillisecondsSinceEpoch(
tz.UTC,
tz.TZDateTime.now(tz.UTC).millisecondsSinceEpoch,
),
);
await cache.updateParameters('key', parameters);
Expand Down
Loading

0 comments on commit c320200

Please sign in to comment.