diff --git a/integration_test/scenarios/habit/repeat_by_n_day_habit_scenario.dart b/integration_test/scenarios/habit/repeat_by_n_day_habit_scenario.dart index d22dad4b3..59d274e5c 100644 --- a/integration_test/scenarios/habit/repeat_by_n_day_habit_scenario.dart +++ b/integration_test/scenarios/habit/repeat_by_n_day_habit_scenario.dart @@ -241,7 +241,7 @@ void main() => group( expect(message.arguments[2], isFalse); expect(message.arguments[3], isFalse); expect( - message.arguments[4], + DateTime.fromMillisecondsSinceEpoch(message.arguments[4]), equals(testStart .copyWith( hour: defaultStartOfDay.hour, @@ -249,8 +249,7 @@ void main() => group( second: 0, millisecond: 0, microsecond: 0) - .add(const Duration(days: 1)) - .millisecondsSinceEpoch)); + .add(const Duration(days: 1)))); expect(message.arguments[5], const Duration(days: 1).inMilliseconds); expect(message.arguments[6], isFalse); diff --git a/integration_test/scenarios/habit/repeated_habit_scenario.dart b/integration_test/scenarios/habit/repeated_habit_scenario.dart index 133aafc22..e02502ebb 100644 --- a/integration_test/scenarios/habit/repeated_habit_scenario.dart +++ b/integration_test/scenarios/habit/repeated_habit_scenario.dart @@ -203,6 +203,9 @@ void main() => group(_name, () { }); testWidgets(": update.", (widgetTester) async { + widgetTester + .ignoreMockMethodCallHandler(MethodChannelMock.permissionHandler); + await runApplication(); await widgetTester.pumpAndSettle(); await widgetTester.tap(find.text(insertedMemName)); @@ -231,16 +234,22 @@ void main() => group(_name, () { await widgetTester.tap(find.byKey(keySaveMemFab)); await widgetTester.pump(waitSideEffectDuration); - final savedMem = (await dbA.select(defTableMems, + final savedMemId = (await dbA.select(defTableMems, where: "${defColMemsName.name} = ?", whereArgs: [insertedMemName])) - .single; - final savedMemNotification = (await dbA.select( + .single[defPkId.name]; + final savedMemNotifications = (await dbA.select( defTableMemNotifications, where: "${defFkMemNotificationsMemId.name} = ?", - whereArgs: [savedMem[defPkId.name]])); - expect(savedMemNotification[0][defColMemNotificationsTime.name], 0); - expect(savedMemNotification[1][defColMemNotificationsTime.name], 1); + whereArgs: [savedMemId], + orderBy: "id ASC")); + expect(savedMemNotifications, hasLength(2)); + expect(savedMemNotifications[0][defColMemNotificationsType.name], + MemNotificationType.repeat.name); + expect(savedMemNotifications[0][defColMemNotificationsTime.name], 0); + expect(savedMemNotifications[1][defColMemNotificationsType.name], + MemNotificationType.repeatByNDay.name); + expect(savedMemNotifications[1][defColMemNotificationsTime.name], 1); }); }); }); diff --git a/integration_test/scenarios/memo/detail_scenarios.dart b/integration_test/scenarios/memo/detail_scenarios.dart index 712f8fb7c..b7fd51f97 100644 --- a/integration_test/scenarios/memo/detail_scenarios.dart +++ b/integration_test/scenarios/memo/detail_scenarios.dart @@ -176,52 +176,49 @@ void main() => group( }, ); - testWidgets( - ': twice on create.', - retry: maxRetryCount, - (widgetTester) async { - widgetTester.ignoreMockMethodCallHandler( - MethodChannelMock.permissionHandler); - widgetTester.ignoreMockMethodCallHandler( - MethodChannelMock.flutterLocalNotifications); - - await runApplication(); - await widgetTester.pumpAndSettle(); - await widgetTester.tap(newMemFabFinder); - await widgetTester.pumpAndSettle(); - const enteringMemName = - "$saveMemName: twice on create - entering"; - const enteringMemMemo = - "$saveMemMemo: twice on create - entering"; - await widgetTester.enterText( - find.byKey(keyMemName), enteringMemName); - await widgetTester.enterText( - find.byKey(keyMemMemo), enteringMemMemo); - await widgetTester.tap(find.byKey(keySaveMemFab)); - await widgetTester.pumpAndSettle(waitSideEffectDuration); - - const enteringMemMemo2 = "$enteringMemMemo - 2"; - await widgetTester.enterText( - find.byKey(keyMemMemo), enteringMemMemo2); - await widgetTester.tap(find.byKey(keySaveMemFab)); - await widgetTester.pumpAndSettle(waitSideEffectDuration); - - final getCreatedMem = Equals(defColMemsName, enteringMemName); - final mems = await dbA.select(defTableMems, - where: getCreatedMem.where(), - whereArgs: getCreatedMem.whereArgs()); - expect(mems.length, 1); - final getCreatedMemItem = And([ - Equals(defFkMemItemsMemId, mems[0][defPkId.name]), - Equals(defColMemItemsType, MemItemType.memo.name) - ]); - final memItems = await dbA.select(defTableMemItems, - where: getCreatedMemItem.where(), - whereArgs: getCreatedMemItem.whereArgs()); - expect(memItems.single[defColMemItemsValue.name], - enteringMemMemo2); - }, - ); + testWidgets(': twice on create.', retry: maxRetryCount, + (widgetTester) async { + widgetTester.ignoreMockMethodCallHandler( + MethodChannelMock.permissionHandler); + widgetTester.ignoreMockMethodCallHandler( + MethodChannelMock.flutterLocalNotifications); + + await runApplication(); + await widgetTester.pumpAndSettle(); + await widgetTester.tap(newMemFabFinder); + await widgetTester.pumpAndSettle(); + const enteringMemName = + "$saveMemName: twice on create - entering"; + const enteringMemMemo = + "$saveMemMemo: twice on create - entering"; + await widgetTester.enterText( + find.byKey(keyMemName), enteringMemName); + await widgetTester.enterText( + find.byKey(keyMemMemo), enteringMemMemo); + await widgetTester.tap(find.byKey(keySaveMemFab)); + await widgetTester.pumpAndSettle(waitSideEffectDuration); + + const enteringMemMemo2 = "$enteringMemMemo - 2"; + await widgetTester.enterText( + find.byKey(keyMemMemo), enteringMemMemo2); + await widgetTester.tap(find.byKey(keySaveMemFab)); + await widgetTester.pumpAndSettle(waitSideEffectDuration); + + final getCreatedMem = Equals(defColMemsName, enteringMemName); + final mems = await dbA.select(defTableMems, + where: getCreatedMem.where(), + whereArgs: getCreatedMem.whereArgs()); + expect(mems.length, 1); + final getCreatedMemItem = And([ + Equals(defFkMemItemsMemId, mems[0][defPkId.name]), + Equals(defColMemItemsType, MemItemType.memo.name) + ]); + final memItems = await dbA.select(defTableMemItems, + where: getCreatedMemItem.where(), + whereArgs: getCreatedMemItem.whereArgs()); + expect( + memItems.single[defColMemItemsValue.name], enteringMemMemo2); + }); group(': Archive', () { const insertedMemName = "$saveMemName: Archive: inserted"; diff --git a/lib/components/mem/list/actions.dart b/lib/components/mem/list/actions.dart index 94d29104e..139c0e008 100644 --- a/lib/components/mem/list/actions.dart +++ b/lib/components/mem/list/actions.dart @@ -1,9 +1,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mem/components/mem/list/states.dart'; import 'package:mem/logger/log_service.dart'; -import 'package:mem/mems/mem_item.dart'; import 'package:mem/mems/mem_item_repository.dart'; import 'package:mem/repositories/mem.dart'; +import 'package:mem/repositories/mem_item_entity.dart'; import 'package:mem/repositories/mem_repository.dart'; import 'package:mem/mems/states.dart'; @@ -38,12 +38,10 @@ final loadMemList = FutureProvider( ); for (var mem in mems) { ref.read(memItemsProvider.notifier).upsertAll( - await MemItemRepository() - .ship(memId: mem.id) - .then((v) => v.map((e) => e.toV1())), + await MemItemRepository().ship(memId: mem.id), (current, updating) => - current is SavedMemItem && - updating is SavedMemItem && + current is SavedMemItemEntity && + updating is SavedMemItemEntity && current.id == updating.id, ); } diff --git a/lib/components/mem/list/states.dart b/lib/components/mem/list/states.dart index 8b5c1e5d1..16aa4dad7 100644 --- a/lib/components/mem/list/states.dart +++ b/lib/components/mem/list/states.dart @@ -12,7 +12,7 @@ import 'package:mem/notifications/mem_notifications.dart'; import 'package:mem/repositories/act_entity.dart'; import 'package:mem/repositories/act_repository.dart'; import 'package:mem/repositories/mem.dart'; -import 'package:mem/repositories/mem_notification.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; import 'package:mem/repositories/mem_notification_repository.dart'; import 'package:mem/settings/states.dart'; @@ -216,12 +216,13 @@ final latestActsByMemProvider = StateNotifierProvider.autoDispose< ), ); final savedMemNotificationsProvider = StateNotifierProvider.autoDispose< - ListValueStateNotifier, List>( + ListValueStateNotifier, + List>( (ref) => v( () => ListValueStateNotifier( ref.watch( memNotificationsProvider.select( - (value) => value.whereType().toList()), + (value) => value.whereType().toList()), ), initializer: (current, notifier) => v( () async { @@ -229,17 +230,15 @@ final savedMemNotificationsProvider = StateNotifierProvider.autoDispose< final memIds = ref.read(memsProvider).whereType().map((e) => e.id); - final actsByMemIds = await MemNotificationRepository() - .ship( - memIdsIn: memIds, - ) - .then((value) => value.map((e) => e.toV1())); + final actsByMemIds = await MemNotificationRepository().ship( + memIdsIn: memIds, + ); ref.read(memNotificationsProvider.notifier).upsertAll( actsByMemIds, (current, updating) => - current is SavedMemNotification && - updating is SavedMemNotification && + current is SavedMemNotificationEntity && + updating is SavedMemNotificationEntity && current.id == updating.id, ); } diff --git a/lib/core/mem_detail.dart b/lib/core/mem_detail.dart index b1288fce7..c951a7954 100644 --- a/lib/core/mem_detail.dart +++ b/lib/core/mem_detail.dart @@ -1,10 +1,15 @@ import 'package:mem/core/mem.dart'; -import 'package:mem/core/mem_item.dart'; import 'package:mem/core/mem_notification.dart'; +import 'package:mem/repositories/mem_item_entity.dart'; +// FIXME 定義するべきではない気がする +// - Mem, MemItems, MemNotificationsの関係はどのレイヤーのもの? +// - Entity~~かDomain~~ +// - DBのFK制約が絡むしEntityかも +// - Repositoryも絡んでいくはず class MemDetail { final MemV1 mem; - final List memItems; + final List memItems; final List? notifications; MemDetail(this.mem, this.memItems, [this.notifications]); diff --git a/lib/core/mem_item.dart b/lib/core/mem_item.dart index bc06ba123..0fecf618b 100644 --- a/lib/core/mem_item.dart +++ b/lib/core/mem_item.dart @@ -1,5 +1,3 @@ -import 'package:mem/framework/repository/entity.dart'; - enum MemItemType { memo, } @@ -9,35 +7,5 @@ class MemItemV2 { final MemItemType type; final dynamic value; - MemItemV2(this.memId, this.type, this.value); // coverage:ignore-line - -// factory MemItemV2.memo(int? memId) => MemItemV2(memId, MemItemType.memo, ""); -} - -class MemItem extends EntityV1 { - // 未保存のMemに紐づくMemItemはmemIdをintで持つことができないため暫定的にnullableにしている - final int? memId; - final MemItemType type; - final dynamic value; - - MemItem(this.memId, this.type, this.value); - - factory MemItem.memo(int? memId) => MemItem(memId, MemItemType.memo, ""); - - MemItem copiedWith({ - int Function()? memId, - dynamic Function()? value, - }) => - MemItem( - memId == null ? this.memId : memId(), - type, - value == null ? this.value : value(), - ); - - @override - String toString() => "${super.toString()}: ${{ - "memId": memId, - "type": type, - "value": value, - }}"; + MemItemV2(this.memId, this.type, this.value); } diff --git a/lib/core/mem_notification.dart b/lib/core/mem_notification.dart index 1924bf9c8..7c27f068d 100644 --- a/lib/core/mem_notification.dart +++ b/lib/core/mem_notification.dart @@ -1,14 +1,26 @@ import 'package:collection/collection.dart'; import 'package:intl/intl.dart'; import 'package:mem/core/date_and_time/date_and_time.dart'; -import 'package:mem/framework/repository/entity.dart'; import 'package:mem/logger/log_service.dart'; const _repeatedMessage = "Repeat"; const _repeatByDayOfWeekMessage = "Repeat by day of week"; const _afterActStartedMessage = "Finish?"; -class MemNotification extends EntityV1 { +enum MemNotificationType { + repeat, + repeatByNDay, + repeatByDayOfWeek, + afterActStarted; + + factory MemNotificationType.fromName(String name) => + MemNotificationType.values.singleWhere( + (element) => element.name == name, + orElse: () => throw Exception('Unexpected name: "$name".'), + ); +} + +class MemNotification { // 未保存のMemに紐づくMemNotificationはmemIdをintで持つことができないため暫定的にnullableにしている final int? memId; final MemNotificationType type; @@ -17,6 +29,27 @@ class MemNotification extends EntityV1 { MemNotification(this.memId, this.type, this.time, this.message); + static MemNotification initialByType( + int? memId, + MemNotificationType type, { + int? Function()? time, + }) { + switch (type) { + case MemNotificationType.repeat: + return MemNotification( + memId, type, time == null ? null : time(), _repeatedMessage); + case MemNotificationType.repeatByNDay: + return MemNotification( + memId, type, time == null ? 1 : time(), _repeatedMessage); + case MemNotificationType.repeatByDayOfWeek: + return MemNotification(memId, type, time == null ? null : time(), + _repeatByDayOfWeekMessage); + case MemNotificationType.afterActStarted: + return MemNotification( + memId, type, time == null ? null : time(), _afterActStartedMessage); + } + } + bool isEnabled() => time != null; bool isRepeated() => type == MemNotificationType.repeat; @@ -27,39 +60,6 @@ class MemNotification extends EntityV1 { bool isAfterActStarted() => type == MemNotificationType.afterActStarted; - factory MemNotification.repeated(int? memId) => MemNotification( - memId, MemNotificationType.repeat, null, _repeatedMessage); - - factory MemNotification.repeatByNDay(int? memId) => MemNotification( - memId, MemNotificationType.repeatByNDay, 1, _repeatedMessage); - - factory MemNotification.repeatByDayOfWeek(int? memId, int time) => - MemNotification(memId, MemNotificationType.repeatByDayOfWeek, time, - _repeatByDayOfWeekMessage); - - factory MemNotification.afterActStarted(int? memId) => MemNotification(memId, - MemNotificationType.afterActStarted, null, _afterActStartedMessage); - - MemNotification copiedWith({ - int Function()? memId, - int? Function()? time, - String Function()? message, - }) => - MemNotification( - memId == null ? this.memId : memId(), - type, - time == null ? this.time : time(), - message == null ? this.message : message(), - ); - - @override - String toString() => "${super.toString()}: ${{ - "memId": memId, - "type": type, - "time": time, - "message": message, - }}"; - static String? toOneLine( Iterable memNotifications, String Function(String at) buildRepeatedNotificationText, @@ -118,20 +118,27 @@ class MemNotification extends EntityV1 { String Function(String nDay, String at) buildRepeatEveryNDayNotificationText, String Function(DateAndTime dateAndTime) formatToTimeOfDay, - ) { - if (repeatByNDay != null && (repeatByNDay.time ?? 0) > 1) { - return buildRepeatEveryNDayNotificationText( - repeatByNDay.time.toString(), - formatToTimeOfDay( - DateAndTime(0, 0, 0, 0, 0, repeat.time), - ), + ) => + v( + () { + if (repeatByNDay != null && (repeatByNDay.time ?? 0) > 1) { + return buildRepeatEveryNDayNotificationText( + repeatByNDay.time.toString(), + formatToTimeOfDay( + DateAndTime(0, 0, 0, 0, 0, repeat.time), + ), + ); + } else { + return buildRepeatedNotificationText(formatToTimeOfDay( + DateAndTime(0, 0, 0, 0, 0, repeat.time), + )); + } + }, + { + 'repeat': repeat, + 'repeatByNDay': repeatByNDay, + }, ); - } else { - return buildRepeatedNotificationText(formatToTimeOfDay( - DateAndTime(0, 0, 0, 0, 0, repeat.time), - )); - } - } static String _oneLineRepeatByDaysOfWeek( Iterable repeatByDayOfWeeks, @@ -147,7 +154,9 @@ class MemNotification extends EntityV1 { .map((e) => dateFormat.format(e)) .join(", "); }, - {'repeatByDayOfWeeks': repeatByDayOfWeeks}, + { + 'repeatByDayOfWeeks': repeatByDayOfWeeks, + }, ); static String _oneLineAfterAct( @@ -157,26 +166,3 @@ class MemNotification extends EntityV1 { buildAfterActStartedNotificationText(DateFormat(DateFormat.HOUR24_MINUTE) .format(DateAndTime(0, 0, 0, 0, 0, afterActStarted.time))); } - -enum MemNotificationType { - repeat, - repeatByNDay, - repeatByDayOfWeek, - afterActStarted; - - factory MemNotificationType.fromName(String name) => - MemNotificationType.values.singleWhere( - (element) => element.name == name, - orElse: () => throw Exception('Unexpected name: "$name".'), - ); -} - -class MemNotificationV2 { - // 未保存のMemに紐づくMemNotificationはmemIdをintで持つことができないため暫定的にnullableにしている - final int? memId; - final MemNotificationType type; - final int? time; - final String message; - - MemNotificationV2(this.memId, this.type, this.time, this.message); -} diff --git a/lib/framework/repository/entity.dart b/lib/framework/repository/entity.dart index e257a140d..facecb877 100644 --- a/lib/framework/repository/entity.dart +++ b/lib/framework/repository/entity.dart @@ -25,8 +25,8 @@ mixin Entity { (runtimeType == other.runtimeType && hashCode == other.hashCode); } -mixin Copyable on Entity { - Entity copiedWith(); +mixin Copyable on Entity { + T copiedWith(); } // memo // - view, domain, dataのそれぞれの領域で似た内容でも型が変わることになるはず diff --git a/lib/mems/actions.dart b/lib/mems/actions.dart index 7a6f48820..7c0a91533 100644 --- a/lib/mems/actions.dart +++ b/lib/mems/actions.dart @@ -1,9 +1,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mem/logger/log_service.dart'; -import 'package:mem/mems/mem_item.dart'; import 'package:mem/mems/mem_service.dart'; import 'package:mem/mems/states.dart'; import 'package:mem/repositories/mem.dart'; +import 'package:mem/repositories/mem_item_entity.dart'; final undoRemoveMem = FutureProvider.autoDispose.family( (ref, memId) => v( @@ -19,10 +19,12 @@ final undoRemoveMem = FutureProvider.autoDispose.family( ref.read(memsProvider.notifier).add(removeUndoneMem); for (var element in removeUndone.memItems) { ref.read(memItemsProvider.notifier).upsertAll( - [element], + [ + element, + ], (current, updating) => - current is SavedMemItem && - updating is SavedMemItem && + current is SavedMemItemEntity && + updating is SavedMemItemEntity && current.id == updating.id, ); } diff --git a/lib/mems/detail/actions.dart b/lib/mems/detail/actions.dart index 35df55107..39938e487 100644 --- a/lib/mems/detail/actions.dart +++ b/lib/mems/detail/actions.dart @@ -4,8 +4,8 @@ import 'package:mem/logger/log_service.dart'; import 'package:mem/mems/detail/states.dart'; import 'package:mem/mems/mem_client.dart'; import 'package:mem/repositories/mem.dart'; -import 'package:mem/repositories/mem_notification.dart'; import 'package:mem/mems/states.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; final _memClient = MemClient(); @@ -37,8 +37,8 @@ final saveMem = ref.read(memNotificationsProvider.notifier).upsertAll( saved.notifications ?? [], (tmp, item) => - tmp is SavedMemNotification && - item is SavedMemNotification && + tmp is SavedMemNotificationEntity && + item is SavedMemNotificationEntity && tmp.id == item.id, removeWhere: (current) => current.isRepeatByDayOfWeek(), ); @@ -59,8 +59,9 @@ final archiveMem = Provider.autoDispose.family, int?>( .updatedBy(archived.mem); ref.read(memsProvider.notifier).upsertAll( [archived.mem], - (tmp, item) => - tmp is SavedMemV1 && item is SavedMemV1 ? tmp.id == item.id : false); + (tmp, item) => tmp is SavedMemV1 && item is SavedMemV1 + ? tmp.id == item.id + : false); return archived; }, @@ -80,8 +81,9 @@ final unarchiveMem = Provider.autoDispose.family, int?>( .updatedBy(unarchived.mem); ref.read(memsProvider.notifier).upsertAll( [unarchived.mem], - (tmp, item) => - tmp is SavedMemV1 && item is SavedMemV1 ? tmp.id == item.id : false); + (tmp, item) => tmp is SavedMemV1 && item is SavedMemV1 + ? tmp.id == item.id + : false); return unarchived; }, diff --git a/lib/mems/detail/mem_items_view.dart b/lib/mems/detail/mem_items_view.dart index 88d035089..97e0b3797 100644 --- a/lib/mems/detail/mem_items_view.dart +++ b/lib/mems/detail/mem_items_view.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mem/components/l10n.dart'; -import 'package:mem/core/mem_item.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/mems/detail/states.dart'; -import 'package:mem/mems/mem_item.dart'; +import 'package:mem/repositories/mem_item_entity.dart'; const keyMemMemo = Key("mem-memo"); @@ -21,7 +20,8 @@ class MemItemsFormFields extends ConsumerWidget { () => ref.read(memItemsByMemIdProvider(_memId).notifier).upsertAll( [previous.copiedWith(value: () => entered)], (current, updating) => current.type == updating.type && - (current is SavedMemItem && updating is SavedMemItem) + (current is SavedMemItemEntity && + updating is SavedMemItemEntity) ? current.id == updating.id : true, ), @@ -35,8 +35,8 @@ class MemItemsFormFields extends ConsumerWidget { } class _MemItemsFormFields extends StatelessWidget { - final List _memItems; - final void Function(dynamic entered, MemItem previous) _onChanged; + final List _memItems; + final void Function(dynamic entered, MemItemEntity previous) _onChanged; const _MemItemsFormFields(this._memItems, this._onChanged); diff --git a/lib/mems/detail/notifications/after_act_started_notification_view.dart b/lib/mems/detail/notifications/after_act_started_notification_view.dart index 2e08a5d4a..0d6c12596 100644 --- a/lib/mems/detail/notifications/after_act_started_notification_view.dart +++ b/lib/mems/detail/notifications/after_act_started_notification_view.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mem/components/time_text_form_field.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/mems/detail/states.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; const keyMemAfterActStartedNotification = Key("mem-after-act-started-notification"); @@ -31,13 +32,19 @@ class AfterActStartedNotificationView extends ConsumerWidget { onTimeChanged: (picked) => ref .read(memNotificationsByMemIdProvider(_memId).notifier) .upsertAll( - [notification.copiedWith(time: () => picked)], + [ + (notification as MemNotificationEntity) + .copiedWith(time: () => picked) + ], (current, updating) => current.type == updating.type, ), onMessageChanged: (value) => ref .read(memNotificationsByMemIdProvider(_memId).notifier) .upsertAll( - [notification.copiedWith(message: () => value)], + [ + (notification as MemNotificationEntity) + .copiedWith(message: () => value) + ], (current, updating) => current.type == updating.type, ), ); diff --git a/lib/mems/detail/notifications/mem_notifications_view.dart b/lib/mems/detail/notifications/mem_notifications_view.dart index 9502bf5b0..027cce098 100644 --- a/lib/mems/detail/notifications/mem_notifications_view.dart +++ b/lib/mems/detail/notifications/mem_notifications_view.dart @@ -11,7 +11,7 @@ import 'package:mem/values/durations.dart'; import 'mem_notifications_page.dart'; -const keyMemNotificationsView = Key("mem-notifications"); +const keyMemNotificationsView = Key('mem-notifications'); class MemNotificationsView extends ConsumerWidget { final int? _memId; @@ -25,14 +25,14 @@ class MemNotificationsView extends ConsumerWidget { ref.watch(memNotificationsByMemIdProvider(_memId)), ), { - "_memId": _memId, + '_memId': _memId, }, ); } class _MemNotificationsView extends StatelessWidget { final int? _memId; - final List _memNotifications; + final Iterable _memNotifications; const _MemNotificationsView( this._memId, @@ -83,8 +83,8 @@ class _MemNotificationsView extends StatelessWidget { ); }, { - "_memId": _memId, - "_memNotifications": _memNotifications, + '_memId': _memId, + '_memNotifications': _memNotifications, }, ); } diff --git a/lib/mems/detail/notifications/mem_repeat_by_day_of_week_notification_view.dart b/lib/mems/detail/notifications/mem_repeat_by_day_of_week_notification_view.dart index 3ca5d37e5..e926f6a03 100644 --- a/lib/mems/detail/notifications/mem_repeat_by_day_of_week_notification_view.dart +++ b/lib/mems/detail/notifications/mem_repeat_by_day_of_week_notification_view.dart @@ -6,9 +6,10 @@ import 'package:intl/intl.dart'; import 'package:mem/core/mem_notification.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/mems/detail/states.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; const keyMemRepeatByDaysOfWeekNotification = - Key("mem-repeat-by-days-of-week-notification"); + Key('mem-repeat-by-days-of-week-notification'); class MemRepeatByDaysOfWeekNotificationView extends ConsumerWidget { final int? _memId; @@ -33,7 +34,11 @@ class MemRepeatByDaysOfWeekNotificationView extends ConsumerWidget { (e) => daysOfWeek.singleWhereOrNull( (element) => element.time == e) ?? - MemNotification.repeatByDayOfWeek(_memId, e), + MemNotificationEntity.initialByType( + _memId, + MemNotificationType.repeatByDayOfWeek, + time: () => e, + ), ), (current, updating) => current.type == updating.type && @@ -43,12 +48,17 @@ class MemRepeatByDaysOfWeekNotificationView extends ConsumerWidget { current.memId == _memId && !selected.contains(current.time), ), - {'selected': selected, 'daysOfWeek': daysOfWeek}, +// coverage:ignore-start + { +// coverage:ignore-end + 'selected': selected, + 'daysOfWeek': daysOfWeek, + }, ), ); }, { - "_memId": _memId, + '_memId': _memId, }, ); } diff --git a/lib/mems/detail/notifications/mem_repeat_by_n_day_notification_view.dart b/lib/mems/detail/notifications/mem_repeat_by_n_day_notification_view.dart index 44833aa52..9b71b6b90 100644 --- a/lib/mems/detail/notifications/mem_repeat_by_n_day_notification_view.dart +++ b/lib/mems/detail/notifications/mem_repeat_by_n_day_notification_view.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mem/components/l10n.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/mems/detail/states.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; import 'package:mem/values/dimens.dart'; const keyMemRepeatByNDayNotification = Key("mem-repeat-by-n-day-notification"); @@ -27,9 +28,9 @@ class MemRepeatByNDayNotificationView extends ConsumerWidget { ) .upsertAll( [ - notification.copiedWith( + (notification as MemNotificationEntity).copiedWith( time: () => value, - ) + ), ], (current, updating) => current.type == updating.type, ); diff --git a/lib/mems/detail/notifications/mem_repeated_notification_view.dart b/lib/mems/detail/notifications/mem_repeated_notification_view.dart index 621d1a89d..5e8353b13 100644 --- a/lib/mems/detail/notifications/mem_repeated_notification_view.dart +++ b/lib/mems/detail/notifications/mem_repeated_notification_view.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mem/components/date_and_time/time_of_day_view.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/mems/detail/states.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; import 'package:mem/settings/states.dart'; import 'package:mem/values/constants.dart'; @@ -16,12 +17,13 @@ class MemRepeatedNotificationView extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => v( () { - final memRepeatNotification = - ref.watch(memNotificationsByMemIdProvider(_memId).select( - (v) => v.singleWhere( - (element) => element.isRepeated(), + final memRepeatNotification = ref.watch( + memNotificationsByMemIdProvider(_memId).select( + (v) => v.singleWhere( + (element) => element.isRepeated(), + ), ), - )); + ); return _MemRepeatedNotificationView( memRepeatNotification.time, @@ -30,7 +32,7 @@ class MemRepeatedNotificationView extends ConsumerWidget { .read(memNotificationsByMemIdProvider(_memId).notifier) .upsertAll( [ - memRepeatNotification.copiedWith( + (memRepeatNotification as MemNotificationEntity).copiedWith( time: () => picked, ) ], diff --git a/lib/mems/detail/states.dart b/lib/mems/detail/states.dart index b45510159..90c1114f1 100644 --- a/lib/mems/detail/states.dart +++ b/lib/mems/detail/states.dart @@ -6,10 +6,10 @@ import 'package:mem/core/mem_notification.dart'; import 'package:mem/components/list_value_state_notifier.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/components/value_state_notifier.dart'; -import 'package:mem/mems/mem_item.dart'; import 'package:mem/mems/mem_item_repository.dart'; import 'package:mem/mems/states.dart'; -import 'package:mem/repositories/mem_notification.dart'; +import 'package:mem/repositories/mem_item_entity.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; import 'package:mem/repositories/mem_notification_repository.dart'; final editingMemByMemIdProvider = StateNotifierProvider.autoDispose @@ -23,7 +23,7 @@ final editingMemByMemIdProvider = StateNotifierProvider.autoDispose ); final memItemsByMemIdProvider = StateNotifierProvider.family< - ListValueStateNotifier, List, int?>( + ListValueStateNotifier, List, int?>( (ref, memId) => v( () => ListValueStateNotifier( [ @@ -34,23 +34,21 @@ final memItemsByMemIdProvider = StateNotifierProvider.family< ), ), ) ?? - MemItem.memo(memId), + MemItemEntity(memId, MemItemType.memo, "") ], initializer: (current, notifier) async { if (memId != null) { ref.read(memItemsProvider.notifier).upsertAll( - await MemItemRepository() - .ship(memId: memId) - .then((v) => v.map((e) => e.toV1())), + await MemItemRepository().ship(memId: memId), (current, updating) => - current is SavedMemItem && - updating is SavedMemItem && + current is SavedMemItemEntity && + updating is SavedMemItemEntity && current.id == updating.id, ); } }, ), - {"memId": memId}, + {'memId': memId}, ), ); @@ -105,22 +103,23 @@ final memNotificationsByMemIdProvider = StateNotifierProvider.autoDispose [ ...memNotificationsByMemId, if (memNotificationsByMemId.every((element) => !element.isRepeated())) - MemNotification.repeated(memId), + MemNotificationEntity.initialByType( + memId, MemNotificationType.repeat), if (memNotificationsByMemId .every((element) => !element.isRepeatByNDay())) - MemNotification.repeatByNDay(memId), + MemNotificationEntity.initialByType( + memId, MemNotificationType.repeatByNDay), if (memNotificationsByMemId .every((element) => !element.isAfterActStarted())) - MemNotification.afterActStarted(memId), + MemNotificationEntity.initialByType( + memId, MemNotificationType.afterActStarted), ], initializer: (current, notifier) => v( () async { if (memId != null && - current.whereType().isEmpty) { + current.whereType().isEmpty) { ref.read(memNotificationsProvider.notifier).upsertAll( - await MemNotificationRepository() - .ship(memId: memId) - .then((value) => value.map((e) => e.toV1())), + await MemNotificationRepository().ship(memId: memId), (current, updating) => updating.isRepeatByDayOfWeek() ? current.memId == updating.memId && current.type == updating.type && diff --git a/lib/mems/list/item/subtitle.dart b/lib/mems/list/item/subtitle.dart index bf280ff7c..b8ce5e8f1 100644 --- a/lib/mems/list/item/subtitle.dart +++ b/lib/mems/list/item/subtitle.dart @@ -8,7 +8,7 @@ import 'package:mem/logger/log_service.dart'; import 'package:mem/mems/detail/notifications/mem_notifications_text.dart'; import 'package:mem/mems/detail/states.dart'; import 'package:mem/mems/states.dart'; -import 'package:mem/repositories/mem_notification.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; class MemListItemSubtitle extends ConsumerWidget { final int _memId; @@ -22,7 +22,7 @@ class MemListItemSubtitle extends ConsumerWidget { ref.watch(memByMemIdProvider(_memId))?.period, ref.watch( memNotificationsByMemIdProvider(_memId).select( - (v) => v.whereType(), + (v) => v.whereType(), ), ), ), @@ -35,7 +35,7 @@ class MemListItemSubtitle extends ConsumerWidget { class _MemListItemSubtitle extends StatelessWidget { final int _memId; final DateAndTimePeriod? _memPeriod; - final Iterable _savedMemNotifications; + final Iterable _savedMemNotifications; const _MemListItemSubtitle( this._memId, diff --git a/lib/mems/list/item/view.dart b/lib/mems/list/item/view.dart index 34f296027..208f03809 100644 --- a/lib/mems/list/item/view.dart +++ b/lib/mems/list/item/view.dart @@ -13,7 +13,7 @@ import 'package:mem/mems/list/item/subtitle.dart'; import 'package:mem/mems/states.dart'; import 'package:mem/repositories/act_entity.dart'; import 'package:mem/repositories/mem.dart'; -import 'package:mem/repositories/mem_notification.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; import 'package:mem/values/colors.dart'; import 'actions.dart'; @@ -73,7 +73,8 @@ class _MemListItemView extends ListTile { void Function(SavedActEntity? act) onActButtonTapped, ) : super( leading: memNotifications - .where((e) => e is SavedMemNotification && e.isEnabled()) + .where((e) => + e is SavedMemNotificationEntity && e.isEnabled()) .isEmpty && activeAct == null ? MemDoneCheckbox( @@ -100,13 +101,15 @@ class _MemListItemView extends ListTile { ), subtitle: mem.period == null && memNotifications - .where((e) => e is SavedMemNotification && e.isEnabled()) + .where((e) => + e is SavedMemNotificationEntity && e.isEnabled()) .isEmpty ? null : MemListItemSubtitle(mem.id), isThreeLine: mem.period != null && memNotifications - .where((e) => e is SavedMemNotification && e.isEnabled()) + .where( + (e) => e is SavedMemNotificationEntity && e.isEnabled()) .isNotEmpty, tileColor: mem.isArchived ? secondaryGreyColor : null, onTap: () => onTap(mem.id), diff --git a/lib/mems/mem_client.dart b/lib/mems/mem_client.dart index e149bac8a..86969dffc 100644 --- a/lib/mems/mem_client.dart +++ b/lib/mems/mem_client.dart @@ -1,11 +1,11 @@ import 'package:mem/core/mem.dart'; import 'package:mem/core/mem_detail.dart'; -import 'package:mem/core/mem_item.dart'; import 'package:mem/core/mem_notification.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/notifications/notification_client.dart'; import 'package:mem/repositories/mem.dart'; -import 'package:mem/repositories/mem_notification.dart'; +import 'package:mem/repositories/mem_item_entity.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; import 'mem_service.dart'; @@ -15,7 +15,7 @@ class MemClient { Future save( MemV1 mem, - List memItemList, + List memItemList, List memNotificationList, ) => v( @@ -32,7 +32,7 @@ class MemClient { (saved.mem as SavedMemV1).id, savedMem: saved.mem as SavedMemV1, savedMemNotifications: - saved.notifications?.whereType(), + saved.notifications?.whereType(), ); return saved; @@ -78,8 +78,8 @@ class MemClient { _notificationClient.registerMemNotifications( (unarchived.mem as SavedMemV1).id, savedMem: unarchived.mem as SavedMemV1, - savedMemNotifications: - unarchived.notifications?.whereType(), + savedMemNotifications: unarchived.notifications + ?.whereType(), ); return unarchived; diff --git a/lib/mems/mem_item.dart b/lib/mems/mem_item.dart deleted file mode 100644 index b0ab25f98..000000000 --- a/lib/mems/mem_item.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:mem/core/mem_item.dart'; -import 'package:mem/framework/repository/database_tuple_entity.dart'; - -class SavedMemItem extends MemItem with SavedDatabaseTupleMixinV1 { - @override - int get memId => super.memId as int; - - SavedMemItem(super.memId, super.type, super.value); - - @override - SavedMemItem copiedWith({ - int Function()? memId, - dynamic Function()? value, - }) => - SavedMemItem( - memId == null ? this.memId : memId(), - type, - value == null ? this.value : value(), - )..copiedFrom(this); -} diff --git a/lib/mems/mem_service.dart b/lib/mems/mem_service.dart index 998abc6b5..359d18def 100644 --- a/lib/mems/mem_service.dart +++ b/lib/mems/mem_service.dart @@ -2,12 +2,10 @@ import 'package:collection/collection.dart'; import 'package:mem/core/mem_detail.dart'; import 'package:mem/core/mem_notification.dart'; import 'package:mem/logger/log_service.dart'; -import 'package:mem/mems/mem_item.dart'; import 'package:mem/mems/mem_item_repository.dart'; import 'package:mem/repositories/mem.dart'; import 'package:mem/repositories/mem_entity.dart'; import 'package:mem/repositories/mem_item_entity.dart'; -import 'package:mem/repositories/mem_notification.dart'; import 'package:mem/repositories/mem_notification_entity.dart'; import 'package:mem/repositories/mem_notification_repository.dart'; import 'package:mem/repositories/mem_repository.dart'; @@ -30,21 +28,20 @@ class MemService { : await _memRepository.receive(MemEntity.fromV1(mem))) .toV1(); - final savedMemItems = (await Future.wait( - memDetail.memItems.map((e) => (e is SavedMemItem && !undo - ? _memItemRepository.replace( - SavedMemItemEntity.fromV1( - e.copiedWith(memId: () => savedMem.id)), - ) - : _memItemRepository.receive( - MemItemEntity.fromV1( - e.copiedWith(memId: () => savedMem.id)), - )) - .then((value) => value.toV1())))); + final savedMemItems = await Future.wait( + memDetail.memItems.map((e) => (e is SavedMemItemEntity && !undo + ? _memItemRepository.replace( + e.copiedWith(memId: () => savedMem.id) + as SavedMemItemEntity, + ) + : _memItemRepository.receive( + e.copiedWith(memId: () => savedMem.id), + ))), + ); final memNotifications = memDetail.notifications; final returnMemNotifications = - List.empty(growable: true); + List.empty(growable: true); if (memNotifications == null) { await _memNotificationRepository.waste(memId: savedMem.id); } else { @@ -52,17 +49,15 @@ class MemService { .where((e) => !e.isRepeatByDayOfWeek()) .map((e) { if (e.isEnabled()) { - return (e is SavedMemNotification && !undo - ? _memNotificationRepository.replace( - SavedMemNotificationEntity.fromV1(e.copiedWith( - memId: () => savedMem.id, - ))) - : _memNotificationRepository.receive( - MemNotificationEntity.fromV1(e.copiedWith( - memId: () => savedMem.id, - )), - )) - .then((v) => v.toV1()); + return (e is SavedMemNotificationEntity && !undo + ? _memNotificationRepository.replace((e).copiedWith( + memId: () => savedMem.id, + )) + : _memNotificationRepository.receive( + (e as MemNotificationEntity).copiedWith( + memId: () => savedMem.id, + ), + )); } else { return _memNotificationRepository .waste( @@ -82,15 +77,11 @@ class MemService { .groupListsBy((e) => e.time) .entries) { returnMemNotifications.add( - await _memNotificationRepository - .receive( - MemNotificationEntity.fromV1( - entry.value.first.copiedWith( - memId: () => savedMem.id, - ), - ), - ) - .then((value) => value.toV1()), + await _memNotificationRepository.receive( + (entry.value.first as MemNotificationEntity).copiedWith( + memId: () => savedMem.id, + ), + ), ); } } @@ -98,7 +89,9 @@ class MemService { return MemDetail( savedMem, savedMemItems, - returnMemNotifications.whereType().toList(), + returnMemNotifications + .whereType() + .toList(), ); }, { @@ -134,12 +127,10 @@ class MemService { final archivedMem = await _memRepository .archive(SavedMemEntity.fromV1(mem)) .then((v) => v.toV1()); - final archivedMemItems = await _memItemRepository - .archiveBy(memId: archivedMem.id) - .then((v) => v.map((e) => e.toV1())); - final archivedMemNotifications = await _memNotificationRepository - .archiveBy(memId: archivedMem.id) - .then((v) => v.map((e) => e.toV1())); + final archivedMemItems = + await _memItemRepository.archiveBy(memId: archivedMem.id); + final archivedMemNotifications = + await _memNotificationRepository.archiveBy(memId: archivedMem.id); return MemDetail( archivedMem, @@ -157,12 +148,10 @@ class MemService { final unarchivedMem = await _memRepository .unarchive(SavedMemEntity.fromV1(mem)) .then((value) => value.toV1()); - final unarchivedMemItems = await _memItemRepository - .unarchiveBy(memId: unarchivedMem.id) - .then((v) => v.map((e) => e.toV1())); + final unarchivedMemItems = + await _memItemRepository.unarchiveBy(memId: unarchivedMem.id); final unarchivedMemNotifications = await _memNotificationRepository - .unarchiveBy(memId: unarchivedMem.id) - .then((v) => v.map((e) => e.toV1())); + .unarchiveBy(memId: unarchivedMem.id); return MemDetail( unarchivedMem, diff --git a/lib/mems/states.dart b/lib/mems/states.dart index acce11735..6544cc429 100644 --- a/lib/mems/states.dart +++ b/lib/mems/states.dart @@ -3,19 +3,19 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mem/components/list_value_state_notifier.dart'; import 'package:mem/core/mem.dart'; import 'package:mem/core/mem_detail.dart'; -import 'package:mem/core/mem_item.dart'; import 'package:mem/components/value_state_notifier.dart'; import 'package:mem/core/mem_notification.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/repositories/mem.dart'; +import 'package:mem/repositories/mem_item_entity.dart'; import 'package:mem/repositories/mem_repository.dart'; final memsProvider = StateNotifierProvider, List>( (ref) => v(() => ListValueStateNotifier([])), ); -final memItemsProvider = - StateNotifierProvider, List>( +final memItemsProvider = StateNotifierProvider< + ListValueStateNotifier, List>( (ref) => v( () => ListValueStateNotifier([]), ), @@ -84,7 +84,7 @@ final removedMemProvider = ), ); final removedMemItemsProvider = StateNotifierProvider.family< - ValueStateNotifier?>, List?, int>( + ValueStateNotifier?>, List?, int>( (ref, memId) => v( () => ValueStateNotifier(null), memId, diff --git a/lib/notifications/mem_notifications.dart b/lib/notifications/mem_notifications.dart index 58e5da715..544fd28f7 100644 --- a/lib/notifications/mem_notifications.dart +++ b/lib/notifications/mem_notifications.dart @@ -4,7 +4,7 @@ import 'package:mem/core/act.dart'; import 'package:mem/core/mem_notification.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/repositories/mem.dart'; -import 'package:mem/repositories/mem_notification.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; import 'notification_client.dart'; import 'notification/type.dart'; @@ -17,7 +17,7 @@ class MemNotifications { static Schedule periodicScheduleOf( SavedMemV1 savedMem, TimeOfDay startOfDay, - Iterable memNotifications, + Iterable memNotifications, Act? latestAct, DateTime now, ) => @@ -69,7 +69,7 @@ class MemNotifications { if (latestAct?.isActive == true) { return null; } else if (memNotifications - .whereType() + .whereType() .where((e) => !e.isAfterActStarted()) .isNotEmpty) { final repeatAt = memNotifications diff --git a/lib/notifications/notification_channels.dart b/lib/notifications/notification_channels.dart index 590983e36..6611f1adb 100644 --- a/lib/notifications/notification_channels.dart +++ b/lib/notifications/notification_channels.dart @@ -35,14 +35,13 @@ class NotificationChannels { break; case NotificationType.repeat: body = ((await MemNotificationRepository().ship(memId: memId))) - .singleWhereOrNull( - (element) => element.toV1().isRepeated()) + .singleWhereOrNull((element) => element.isRepeated()) ?.message ?? "Repeat"; break; case NotificationType.afterActStarted: body = ((await MemNotificationRepository().ship(memId: memId))) - .singleWhere((element) => element.toV1().isAfterActStarted()) + .singleWhere((element) => element.isAfterActStarted()) .message; break; case NotificationType.activeAct: diff --git a/lib/notifications/notification_client.dart b/lib/notifications/notification_client.dart index 68c0c6b0a..6664fb57f 100644 --- a/lib/notifications/notification_client.dart +++ b/lib/notifications/notification_client.dart @@ -6,7 +6,7 @@ import 'package:mem/components/l10n.dart'; import 'package:mem/logger/log_service.dart'; import 'package:mem/repositories/act_repository.dart'; import 'package:mem/repositories/mem.dart'; -import 'package:mem/repositories/mem_notification.dart'; +import 'package:mem/repositories/mem_notification_entity.dart'; import 'package:mem/repositories/mem_notification_repository.dart'; import 'package:mem/repositories/mem_repository.dart'; import 'package:mem/settings/client.dart'; @@ -128,7 +128,7 @@ class NotificationClient { Future registerMemNotifications( int memId, { SavedMemV1? savedMem, - Iterable? savedMemNotifications, + Iterable? savedMemNotifications, }) => v( () async { @@ -153,9 +153,7 @@ class NotificationClient { mem, startOfDay, savedMemNotifications ?? - await _memNotificationRepository - .ship(memId: memId) - .then((value) => value.map((e) => e.toV1())), + await _memNotificationRepository.ship(memId: memId), latestAct, DateTime.now(), ) @@ -196,9 +194,8 @@ class NotificationClient { ); final now = DateTime.now(); - final memNotifications = await _memNotificationRepository - .ship(memId: memId) - .then((value) => value.map((e) => e.toV1())); + final memNotifications = + await _memNotificationRepository.ship(memId: memId); for (var notification in memNotifications.where((element) => element.isEnabled() && element.isAfterActStarted())) { await _scheduleClient.receive( @@ -256,9 +253,8 @@ class NotificationClient { Future _shouldNotify(int memId) => v( () async { - final savedMemNotifications = await _memNotificationRepository - .ship(memId: memId) - .then((value) => value.map((e) => e.toV1())); + final savedMemNotifications = + await _memNotificationRepository.ship(memId: memId); final repeatByDayOfWeekMemNotifications = savedMemNotifications.where( (element) => element.isEnabled() && element.isRepeatByDayOfWeek(), ); diff --git a/lib/repositories/act_entity.dart b/lib/repositories/act_entity.dart index 4227c16a0..01a3d74c6 100644 --- a/lib/repositories/act_entity.dart +++ b/lib/repositories/act_entity.dart @@ -5,7 +5,7 @@ import 'package:mem/databases/table_definitions/acts.dart'; import 'package:mem/framework/repository/database_tuple_entity.dart'; import 'package:mem/framework/repository/entity.dart'; -class ActEntity extends Act with Entity, Copyable { +class ActEntity extends Act with Entity, Copyable { ActEntity(super.memId, super.period); ActEntity.fromMap(Map map) @@ -30,7 +30,7 @@ class ActEntity extends Act with Entity, Copyable { ); @override - Entity copiedWith({ + ActEntity copiedWith({ int Function()? memId, DateAndTimePeriod Function()? period, }) => diff --git a/lib/repositories/mem_item_entity.dart b/lib/repositories/mem_item_entity.dart index ae5112a3e..c17f91244 100644 --- a/lib/repositories/mem_item_entity.dart +++ b/lib/repositories/mem_item_entity.dart @@ -1,11 +1,9 @@ import 'package:mem/core/mem_item.dart'; -import 'package:mem/databases/table_definitions/base.dart'; import 'package:mem/databases/table_definitions/mem_items.dart'; import 'package:mem/framework/repository/database_tuple_entity.dart'; import 'package:mem/framework/repository/entity.dart'; -import 'package:mem/mems/mem_item.dart'; -class MemItemEntity extends MemItemV2 with Entity { +class MemItemEntity extends MemItemV2 with Entity, Copyable { MemItemEntity(super.memId, super.type, super.value); MemItemEntity.fromMap(Map map) @@ -17,16 +15,23 @@ class MemItemEntity extends MemItemV2 with Entity { map[defColMemItemsValue.name], ); - MemItemEntity.fromV1(MemItem memItem) - : this.fromMap( - MemItemEntity(memItem.memId, memItem.type, memItem.value).toMap); - @override Map get toMap => { defFkMemItemsMemId.name: memId, defColMemItemsType.name: type.name, defColMemItemsValue.name: value, }; + + @override + MemItemEntity copiedWith({ + int Function()? memId, + dynamic Function()? value, + }) => + MemItemEntity( + memId == null ? this.memId : memId(), + type, + value == null ? this.value : value(), + ); } class SavedMemItemEntity extends MemItemEntity with DatabaseTupleEntity { @@ -34,41 +39,20 @@ class SavedMemItemEntity extends MemItemEntity with DatabaseTupleEntity { withMap(map); } - SavedMemItemEntity.fromV1(SavedMemItem savedMemItem) - : this.fromMap( - MemItemEntity.fromV1(savedMemItem).toMap - ..addAll( - { - defPkId.name: savedMemItem.id, - defColCreatedAt.name: savedMemItem.createdAt, - defColUpdatedAt.name: savedMemItem.updatedAt, - defColArchivedAt.name: savedMemItem.archivedAt - }, - ), - ); - - SavedMemItem toV1() => SavedMemItem(memId, type, value) - ..id = id - ..createdAt = createdAt - ..updatedAt = updatedAt - ..archivedAt = archivedAt; - -// @override -// SavedMemItemEntity copiedWith({ -// int Function()? memId, -// MemItemType Function()? type, -// dynamic Function()? value, -// }) => -// SavedMemItemEntity.fromMap( -// toMap -// ..addAll( -// super -// .copiedWith( -// memId: memId, -// type: type, -// value: value, -// ) -// .toMap, -// ), -// ); + @override + MemItemEntity copiedWith({ + int Function()? memId, + dynamic Function()? value, + }) => + SavedMemItemEntity.fromMap( + toMap + ..addAll( + super + .copiedWith( + memId: memId, + value: value, + ) + .toMap, + ), + ); } diff --git a/lib/repositories/mem_notification.dart b/lib/repositories/mem_notification.dart deleted file mode 100644 index 46333111a..000000000 --- a/lib/repositories/mem_notification.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:mem/core/mem_notification.dart'; -import 'package:mem/framework/repository/database_tuple_entity.dart'; - -class SavedMemNotification extends MemNotification - with SavedDatabaseTupleMixinV1 { - @override - int get memId => super.memId as int; - - SavedMemNotification(super.memId, super.type, super.time, super.message); - - @override - SavedMemNotification copiedWith({ - int Function()? memId, - int? Function()? time, - String Function()? message, - }) => - SavedMemNotification( - memId == null ? this.memId : memId(), - type, - time == null ? this.time : time(), - message == null ? this.message : message(), - )..copiedFrom(this); -} diff --git a/lib/repositories/mem_notification_entity.dart b/lib/repositories/mem_notification_entity.dart index 5660b98d5..393cda82c 100644 --- a/lib/repositories/mem_notification_entity.dart +++ b/lib/repositories/mem_notification_entity.dart @@ -1,11 +1,13 @@ import 'package:mem/core/mem_notification.dart'; -import 'package:mem/databases/table_definitions/base.dart'; import 'package:mem/databases/table_definitions/mem_notifications.dart'; import 'package:mem/framework/repository/database_tuple_entity.dart'; import 'package:mem/framework/repository/entity.dart'; -import 'package:mem/repositories/mem_notification.dart'; -class MemNotificationEntity extends MemNotificationV2 with Entity { +class MemNotificationEntity extends MemNotification + with Entity, Copyable { + MemNotificationEntity(super.memId, super.type, super.time, super.message) + : super(); + MemNotificationEntity.fromMap(Map map) : super( map[defFkMemNotificationsMemId.name], @@ -14,8 +16,14 @@ class MemNotificationEntity extends MemNotificationV2 with Entity { map[defColMemNotificationsMessage.name], ); - MemNotificationEntity.fromV1(MemNotification v1) - : super(v1.memId, v1.type, v1.time, v1.message); + static MemNotificationEntity initialByType( + int? memId, + MemNotificationType type, { + int? Function()? time, + }) { + final core = MemNotification.initialByType(memId, type, time: time); + return MemNotificationEntity(memId, type, core.time, core.message); + } @override Map get toMap => { @@ -24,6 +32,19 @@ class MemNotificationEntity extends MemNotificationV2 with Entity { defColMemNotificationsTime.name: time, defColMemNotificationsMessage.name: message, }; + + @override + MemNotificationEntity copiedWith({ + int? Function()? memId, + int? Function()? time, + String Function()? message, + }) => + MemNotificationEntity( + memId == null ? this.memId : memId(), + type, + time == null ? this.time : time(), + message == null ? this.message : message(), + ); } class SavedMemNotificationEntity extends MemNotificationEntity @@ -34,24 +55,22 @@ class SavedMemNotificationEntity extends MemNotificationEntity withMap(map); } - SavedMemNotificationEntity.fromV1( - SavedMemNotification v1, - ) : this.fromMap( - MemNotificationEntity.fromV1(v1).toMap - ..addAll( - { - defPkId.name: v1.id, - defColCreatedAt.name: v1.createdAt, - defColUpdatedAt.name: v1.updatedAt, - defColArchivedAt.name: v1.archivedAt - }, - ), - ); - - SavedMemNotification toV1() => - SavedMemNotification(memId, type, time, message) - ..id = id - ..createdAt = createdAt - ..updatedAt = updatedAt - ..archivedAt = archivedAt; + @override + SavedMemNotificationEntity copiedWith({ + int? Function()? memId, + int? Function()? time, + String Function()? message, + }) => + SavedMemNotificationEntity.fromMap( + toMap + ..addAll( + super + .copiedWith( + memId: memId, + time: time, + message: message, + ) + .toMap, + ), + ); } diff --git a/test/core/mem_notification_test.dart b/test/core/mem_notification_test.dart index 39caf79cc..5f1e17d3b 100644 --- a/test/core/mem_notification_test.dart +++ b/test/core/mem_notification_test.dart @@ -11,8 +11,8 @@ void main() { const memId = 1; const time = 2; - final repeatByDayOfWeek = - MemNotification.repeatByDayOfWeek(memId, time); + final repeatByDayOfWeek = MemNotification(memId, + MemNotificationType.repeatByDayOfWeek, time, "repeatByDayOfWeek"); expect(repeatByDayOfWeek.isRepeatByDayOfWeek(), isTrue); expect(repeatByDayOfWeek.memId, equals(memId)); @@ -20,190 +20,118 @@ void main() { }, ); - group( - 'toOneLine', - () { - String buildRepeatedNotificationText(String at) => "repeat at $at"; - String buildRepeatEveryNDayNotificationText(String nDay, String at) => - "repeat at $at by $nDay"; - String buildAfterActStartedNotificationText(String at) => - "after act at $at"; - String formatToTimeOfDay(DateAndTime dateAndTime) => - "${dateAndTime.hour}:${dateAndTime.minute}"; - - test( - 'no enables.', - () { - const memId = 1; - - final oneLine = MemNotification.toOneLine( - [ - MemNotification( - memId, MemNotificationType.repeat, null, "message") - ], - (at) => fail("no call"), - (nDay, at) => fail("no call"), - (a) => fail("no call"), - (dateAndTime) => fail("no call"), - ); - - expect(oneLine, isNull); - }, - ); - - group( - 'repeat', - () { - test( - 'repeat at 0:0.', - () { - const memId = 1; - const repeatAt = 0; - - final oneLine = MemNotification.toOneLine( - [ - MemNotification.repeated(memId).copiedWith( - time: () => repeatAt, - ) - ], - buildRepeatedNotificationText, - (nDay, at) => fail("no call"), - (a) => fail("no call"), - formatToTimeOfDay, - ); - - expect( - oneLine, - equals(buildRepeatedNotificationText(formatToTimeOfDay( - DateAndTime(0, 0, 0, 0, 0, repeatAt))))); - }, - ); - - test( - 'repeat at 05:00 by 2 day.', - () { - const memId = 1; - const repeatAt = (5 * 60) * 60; - const repeatByNDay = 2; - - final oneLine = MemNotification.toOneLine( - [ - MemNotification.repeated(memId).copiedWith( - time: () => repeatAt, - ), - MemNotification.repeatByNDay(memId).copiedWith( - time: () => repeatByNDay, - ) - ], - (at) => fail("no call"), - buildRepeatEveryNDayNotificationText, - (at) => fail("no call"), - formatToTimeOfDay, - ); - - expect( - oneLine, - equals(buildRepeatEveryNDayNotificationText( - repeatByNDay.toString(), - formatToTimeOfDay( - DateAndTime(0, 0, 0, 0, 0, repeatAt))))); - }, - ); - - test( - 'repeat at 12:00 by 3 day on Mon.', - () { - const memId = 1; - const repeatAt = (5 * 60) * 60; - const repeatByNDay = 2; - - final oneLine = MemNotification.toOneLine( - [ - MemNotification.repeated(memId).copiedWith( - time: () => repeatAt, - ), - MemNotification.repeatByNDay(memId).copiedWith( - time: () => repeatByNDay, - ), - MemNotification.repeatByDayOfWeek(memId, 1), - ], - (at) => fail("no call"), - buildRepeatEveryNDayNotificationText, - (at) => fail("no call"), - formatToTimeOfDay, - ); - - expect( - oneLine, - equals( - "${buildRepeatEveryNDayNotificationText( - repeatByNDay.toString(), - formatToTimeOfDay( - DateAndTime(0, 0, 0, 0, 0, repeatAt), - ), - )}, Mon", - )); - }, - ); - }, - ); - - test( - 'repeat by Tue.', - () { - const memId = 1; - - final oneLine = MemNotification.toOneLine( - [MemNotification.repeatByDayOfWeek(memId, 2)], - buildRepeatedNotificationText, - (a, b) => "$a, $b", - (a) => a, - formatToTimeOfDay, - ); - - expect(oneLine, equals("Tue")); - }, - ); - - test( - 'after act', - () { - const memId = 1; - const time = 2; - final oneLine = MemNotification.toOneLine( - [ - MemNotification.afterActStarted(memId).copiedWith( - time: () => time, - ) - ], - (a) => fail("no call"), - (a, b) => fail("no call"), - buildAfterActStartedNotificationText, - formatToTimeOfDay, - ); - - expect( - oneLine, - buildAfterActStartedNotificationText( - DateFormat(DateFormat.HOUR24_MINUTE) - .format(DateAndTime(0, 0, 0, 0, 0, time)))); - }, - ); - }, - ); + group('toOneLine', () { + String buildRepeatedNotificationText(String at) => "repeat at $at"; + String buildRepeatEveryNDayNotificationText(String nDay, String at) => + "repeat at $at by $nDay"; + String buildAfterActStartedNotificationText(String at) => + "after act at $at"; + String formatToTimeOfDay(DateAndTime dateAndTime) => + "${dateAndTime.hour}:${dateAndTime.minute}"; + + test('no enables.', () { + const memId = 1; + + final oneLine = MemNotification.toOneLine([ + MemNotification(memId, MemNotificationType.repeat, null, "repeat") + ], (at) => fail("no call"), (nDay, at) => fail("no call"), + (a) => fail("no call"), (dateAndTime) => fail("no call")); + + expect(oneLine, isNull); + }); + + group('repeat', () { + test('repeat at 0:0.', () { + const memId = 1; + const repeatAt = 0; + + final oneLine = MemNotification.toOneLine([ + MemNotification(memId, MemNotificationType.repeat, repeatAt, "") + ], buildRepeatedNotificationText, (nDay, at) => fail("no call"), + (a) => fail("no call"), formatToTimeOfDay); + + expect( + oneLine, + equals(buildRepeatedNotificationText( + formatToTimeOfDay(DateAndTime(0, 0, 0, 0, 0, repeatAt))))); + }); + + test('repeat at 05:00 by 2 day.', () { + const memId = 1; + const repeatAt = (5 * 60) * 60; + const repeatByNDay = 2; + + final oneLine = MemNotification.toOneLine([ + MemNotification(memId, MemNotificationType.repeat, repeatAt, ""), + MemNotification( + memId, MemNotificationType.repeatByNDay, repeatByNDay, "") + ], (at) => fail("no call"), buildRepeatEveryNDayNotificationText, + (at) => fail("no call"), formatToTimeOfDay); + + expect( + oneLine, + equals(buildRepeatEveryNDayNotificationText( + repeatByNDay.toString(), + formatToTimeOfDay(DateAndTime(0, 0, 0, 0, 0, repeatAt))))); + }); + + test('repeat at 12:00 by 3 day on Mon.', () { + const memId = 1; + const repeatAt = (5 * 60) * 60; + const repeatByNDay = 2; + + final oneLine = MemNotification.toOneLine([ + MemNotification(memId, MemNotificationType.repeat, repeatAt, ""), + MemNotification( + memId, MemNotificationType.repeatByNDay, repeatByNDay, ""), + MemNotification(memId, MemNotificationType.repeatByDayOfWeek, 1, "") + ], (at) => fail("no call"), buildRepeatEveryNDayNotificationText, + (at) => fail("no call"), formatToTimeOfDay); + + expect( + oneLine, + equals("${buildRepeatEveryNDayNotificationText( + repeatByNDay.toString(), + formatToTimeOfDay(DateAndTime(0, 0, 0, 0, 0, repeatAt)), + )}, Mon")); + }); + }); + + test('repeat by Tue.', () { + const memId = 1; + + final oneLine = MemNotification.toOneLine([ + MemNotification(memId, MemNotificationType.repeatByDayOfWeek, 2, + "repeatByDayOfWeek") + ], buildRepeatedNotificationText, (a, b) => "$a, $b", (a) => a, + formatToTimeOfDay); + + expect(oneLine, equals("Tue")); + }); + + test('after act', () { + const memId = 1; + const time = 2; + final oneLine = MemNotification.toOneLine([ + MemNotification(memId, MemNotificationType.afterActStarted, time, "") + ], (a) => fail("no call"), (a, b) => fail("no call"), + buildAfterActStartedNotificationText, formatToTimeOfDay); + + expect( + oneLine, + buildAfterActStartedNotificationText( + DateFormat(DateFormat.HOUR24_MINUTE) + .format(DateAndTime(0, 0, 0, 0, 0, time)))); + }); + }); }); test('MemNotificationType from unexpected name throw.', () { const name = 'unexpected name'; - expect( - () => MemNotificationType.fromName(name), - throwsA( - (e) { - expect(e.message, 'Unexpected name: "$name".'); - return true; - }, - ), - ); + expect(() => MemNotificationType.fromName(name), throwsA((e) { + expect(e.message, 'Unexpected name: "$name".'); + return true; + })); }); }