diff --git a/lib/features/journal/state/entry_controller.g.dart b/lib/features/journal/state/entry_controller.g.dart index 1d706d736..5da8739d1 100644 --- a/lib/features/journal/state/entry_controller.g.dart +++ b/lib/features/journal/state/entry_controller.g.dart @@ -6,7 +6,7 @@ part of 'entry_controller.dart'; // RiverpodGenerator // ************************************************************************** -String _$entryControllerHash() => r'5d783ad17f1134a347f4b77fc195e0e30ff9f492'; +String _$entryControllerHash() => r'0351cbdbc5f6d55f59be5df11993d0e57e85aa01'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/features/journal/state/journal_card_controller.dart b/lib/features/journal/state/journal_card_controller.dart new file mode 100644 index 000000000..7cbb0f865 --- /dev/null +++ b/lib/features/journal/state/journal_card_controller.dart @@ -0,0 +1,45 @@ +import 'dart:async'; + +import 'package:lotti/classes/journal_entities.dart'; +import 'package:lotti/database/database.dart'; +import 'package:lotti/get_it.dart'; +import 'package:lotti/services/db_notification.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'journal_card_controller.g.dart'; + +@riverpod +class JournalCardController extends _$JournalCardController { + JournalCardController() { + listen(); + } + + late final String entryId; + StreamSubscription<({DatabaseType type, String id})>? _updateSubscription; + final JournalDb _journalDb = getIt(); + final UpdateNotifications _updateNotifications = getIt(); + + void listen() { + _updateSubscription = + _updateNotifications.updateStream.listen((event) async { + if (event.id == entryId) { + final latest = await _fetch(); + if (latest != state.value) { + state = AsyncData(latest); + } + } + }); + } + + @override + Future build({required String id}) async { + entryId = id; + ref.onDispose(() => _updateSubscription?.cancel()); + final entry = await _fetch(); + return entry; + } + + Future _fetch() async { + return _journalDb.journalEntityById(entryId); + } +} diff --git a/lib/features/journal/state/journal_card_controller.g.dart b/lib/features/journal/state/journal_card_controller.g.dart new file mode 100644 index 000000000..ed2ff0d8b --- /dev/null +++ b/lib/features/journal/state/journal_card_controller.g.dart @@ -0,0 +1,177 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'journal_card_controller.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$journalCardControllerHash() => + r'9047001102dd6fafaa529c634ef7cc35339948a3'; + +/// Copied from Dart SDK +class _SystemHash { + _SystemHash._(); + + static int combine(int hash, int value) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + value); + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); + return hash ^ (hash >> 6); + } + + static int finish(int hash) { + // ignore: parameter_assignments + hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); + // ignore: parameter_assignments + hash = hash ^ (hash >> 11); + return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); + } +} + +abstract class _$JournalCardController + extends BuildlessAutoDisposeAsyncNotifier { + late final String id; + + FutureOr build({ + required String id, + }); +} + +/// See also [JournalCardController]. +@ProviderFor(JournalCardController) +const journalCardControllerProvider = JournalCardControllerFamily(); + +/// See also [JournalCardController]. +class JournalCardControllerFamily extends Family> { + /// See also [JournalCardController]. + const JournalCardControllerFamily(); + + /// See also [JournalCardController]. + JournalCardControllerProvider call({ + required String id, + }) { + return JournalCardControllerProvider( + id: id, + ); + } + + @override + JournalCardControllerProvider getProviderOverride( + covariant JournalCardControllerProvider provider, + ) { + return call( + id: provider.id, + ); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'journalCardControllerProvider'; +} + +/// See also [JournalCardController]. +class JournalCardControllerProvider + extends AutoDisposeAsyncNotifierProviderImpl { + /// See also [JournalCardController]. + JournalCardControllerProvider({ + required String id, + }) : this._internal( + () => JournalCardController()..id = id, + from: journalCardControllerProvider, + name: r'journalCardControllerProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') + ? null + : _$journalCardControllerHash, + dependencies: JournalCardControllerFamily._dependencies, + allTransitiveDependencies: + JournalCardControllerFamily._allTransitiveDependencies, + id: id, + ); + + JournalCardControllerProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.id, + }) : super.internal(); + + final String id; + + @override + FutureOr runNotifierBuild( + covariant JournalCardController notifier, + ) { + return notifier.build( + id: id, + ); + } + + @override + Override overrideWith(JournalCardController Function() create) { + return ProviderOverride( + origin: this, + override: JournalCardControllerProvider._internal( + () => create()..id = id, + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + id: id, + ), + ); + } + + @override + AutoDisposeAsyncNotifierProviderElement + createElement() { + return _JournalCardControllerProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is JournalCardControllerProvider && other.id == id; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, id.hashCode); + + return _SystemHash.finish(hash); + } +} + +mixin JournalCardControllerRef + on AutoDisposeAsyncNotifierProviderRef { + /// The parameter `id` of this provider. + String get id; +} + +class _JournalCardControllerProviderElement + extends AutoDisposeAsyncNotifierProviderElement with JournalCardControllerRef { + _JournalCardControllerProviderElement(super.provider); + + @override + String get id => (origin as JournalCardControllerProvider).id; +} +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/lib/widgets/journal/journal_card.dart b/lib/widgets/journal/journal_card.dart index 0e80968f4..8a717d380 100644 --- a/lib/widgets/journal/journal_card.dart +++ b/lib/widgets/journal/journal_card.dart @@ -2,8 +2,10 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_rating/flutter_rating.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lotti/classes/journal_entities.dart'; import 'package:lotti/database/database.dart'; +import 'package:lotti/features/journal/state/journal_card_controller.dart'; import 'package:lotti/get_it.dart'; import 'package:lotti/services/nav_service.dart'; import 'package:lotti/themes/colors.dart'; @@ -187,7 +189,7 @@ class JournalCardTitle extends StatelessWidget { } } -class JournalCard extends StatefulWidget { +class JournalCard extends ConsumerStatefulWidget { const JournalCard({ required this.item, super.key, @@ -200,62 +202,57 @@ class JournalCard extends StatefulWidget { final bool showLinkedDuration; @override - State createState() => _JournalCardState(); + ConsumerState createState() => _JournalCardState(); } -class _JournalCardState extends State { +class _JournalCardState extends ConsumerState { @override Widget build(BuildContext context) { - return StreamBuilder( - stream: getIt().watchEntityById(widget.item.meta.id), - builder: ( - BuildContext context, - AsyncSnapshot snapshot, - ) { - final updatedItem = snapshot.data ?? widget.item; - if (updatedItem.meta.deletedAt != null) { - return const SizedBox.shrink(); - } - void onTap() { - if (getIt().tasksTabActive()) { - beamToNamed('/tasks/${updatedItem.meta.id}'); - } else { - beamToNamed('/journal/${updatedItem.meta.id}'); - } - } + final provider = journalCardControllerProvider(id: widget.item.meta.id); + final entryState = ref.watch(provider).value; + final updatedItem = entryState ?? widget.item; - final errorColor = Theme.of(context).colorScheme.error; + if (updatedItem.meta.deletedAt != null) { + return const SizedBox.shrink(); + } + void onTap() { + if (getIt().tasksTabActive()) { + beamToNamed('/tasks/${updatedItem.meta.id}'); + } else { + beamToNamed('/journal/${updatedItem.meta.id}'); + } + } - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 5), - child: Card( - child: ListTile( - leading: updatedItem.maybeMap( - journalAudio: (item) { - final transcripts = item.data.transcripts; - return LeadingIcon( - Icons.mic_rounded, - color: transcripts != null && transcripts.isNotEmpty - ? Theme.of(context).colorScheme.outline - : errorColor.withOpacity(0.4), - ); - }, - quantitative: (_) => LeadingIcon(MdiIcons.heart), - measurement: (_) => LeadingIcon(MdiIcons.numeric), - habitCompletion: (habitCompletion) => - HabitCompletionColorIcon(habitCompletion.data.habitId), - orElse: () => null, - ), - title: JournalCardTitle( - item: updatedItem, - maxHeight: widget.maxHeight, - showLinkedDuration: widget.showLinkedDuration, - ), - onTap: onTap, - ), + final errorColor = Theme.of(context).colorScheme.error; + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 5), + child: Card( + child: ListTile( + leading: updatedItem.maybeMap( + journalAudio: (item) { + final transcripts = item.data.transcripts; + return LeadingIcon( + Icons.mic_rounded, + color: transcripts != null && transcripts.isNotEmpty + ? Theme.of(context).colorScheme.outline + : errorColor.withOpacity(0.4), + ); + }, + quantitative: (_) => LeadingIcon(MdiIcons.heart), + measurement: (_) => LeadingIcon(MdiIcons.numeric), + habitCompletion: (habitCompletion) => + HabitCompletionColorIcon(habitCompletion.data.habitId), + orElse: () => null, ), - ); - }, + title: JournalCardTitle( + item: updatedItem, + maxHeight: widget.maxHeight, + showLinkedDuration: widget.showLinkedDuration, + ), + onTap: onTap, + ), + ), ); } } diff --git a/pubspec.lock b/pubspec.lock index 752f89b78..1b28b452a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -173,18 +173,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "1414d6d733a85d8ad2f1dfcb3ea7945759e35a123cb99ccfac75d0758f75edfa" + sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7" url: "https://pub.dev" source: hosted - version: "2.4.10" + version: "2.4.11" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" + sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe url: "https://pub.dev" source: hosted - version: "7.3.0" + version: "7.3.1" built_collection: dependency: transitive description: @@ -1899,10 +1899,10 @@ packages: dependency: transitive description: name: permission_handler_apple - sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662 + sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0 url: "https://pub.dev" source: hosted - version: "9.4.4" + version: "9.4.5" permission_handler_html: dependency: transitive description: @@ -2752,10 +2752,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e" + sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" url: "https://pub.dev" source: hosted - version: "6.2.6" + version: "6.3.0" url_launcher_android: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 27264bf8a..763f0c6c8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: lotti description: Achieve your goals and keep your data private with Lotti. publish_to: 'none' -version: 0.9.475+2553 +version: 0.9.476+2554 msix_config: display_name: LottiApp