From 23867a1784a549227a75365278280ba19cdc55f0 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Thu, 20 Mar 2025 17:31:02 -0400 Subject: [PATCH 1/6] ui cleanup --- assets/images/handshake.png | Bin 43924 -> 0 bytes assets/images/toilet.png | Bin 28325 -> 0 bytes assets/images/toilet.svg | 9 +++ lib/account_manager/views/profile_widget.dart | 6 +- lib/chat_list/views/chat_list_widget.dart | 3 +- .../chat_single_contact_item_widget.dart | 4 +- lib/contacts/views/availability_widget.dart | 57 ++++++++------- lib/contacts/views/contacts_page.dart | 69 ++++++++---------- lib/layout/default_app_bar.dart | 9 ++- lib/layout/home/home_account_ready.dart | 8 +- .../scale_theme/scale_app_bar_theme.dart | 31 ++++++++ lib/theme/models/scale_theme/scale_theme.dart | 7 +- .../models/scale_theme/scale_tile_theme.dart | 1 - lib/theme/views/slider_tile.dart | 4 +- lib/theme/views/wallpaper_preferences.dart | 10 ++- lib/theme/views/widget_helpers.dart | 4 +- pubspec.yaml | 3 +- 17 files changed, 135 insertions(+), 90 deletions(-) delete mode 100644 assets/images/handshake.png delete mode 100644 assets/images/toilet.png create mode 100644 assets/images/toilet.svg create mode 100644 lib/theme/models/scale_theme/scale_app_bar_theme.dart diff --git a/assets/images/handshake.png b/assets/images/handshake.png deleted file mode 100644 index d40fad1c889f016d4a61f59f17350a99b9ef0e31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43924 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 diff --git a/assets/images/toilet.png b/assets/images/toilet.png deleted file mode 100644 index 6c0efa2a51a8399cf5af75529780da71f17a58d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28325 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 diff --git a/assets/images/toilet.svg b/assets/images/toilet.svg new file mode 100644 index 0000000..0984274 --- /dev/null +++ b/assets/images/toilet.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/lib/account_manager/views/profile_widget.dart b/lib/account_manager/views/profile_widget.dart index 672b13a..c026856 100644 --- a/lib/account_manager/views/profile_widget.dart +++ b/lib/account_manager/views/profile_widget.dart @@ -43,7 +43,7 @@ class ProfileWidget extends StatelessWidget { : scale.primaryScale.borderText, width: 2), borderRadius: BorderRadius.all( - Radius.circular(12 * scaleConfig.borderRadiusScale))), + Radius.circular(8 * scaleConfig.borderRadiusScale))), ), child: Row(children: [ const Spacer(), @@ -54,7 +54,7 @@ class ProfileWidget extends StatelessWidget { ? scale.primaryScale.border : scale.primaryScale.borderText), textAlign: TextAlign.left, - ).paddingAll(12), + ).paddingAll(8), if (_profile.pronouns.isNotEmpty && _showPronouns) Text('(${_profile.pronouns})', textAlign: TextAlign.right, @@ -62,7 +62,7 @@ class ProfileWidget extends StatelessWidget { color: scaleConfig.preferBorders ? scale.primaryScale.border : scale.primaryScale.primary)) - .paddingAll(12), + .paddingAll(8), const Spacer() ]), ); diff --git a/lib/chat_list/views/chat_list_widget.dart b/lib/chat_list/views/chat_list_widget.dart index f9a6ad3..73bd7e6 100644 --- a/lib/chat_list/views/chat_list_widget.dart +++ b/lib/chat_list/views/chat_list_widget.dart @@ -83,7 +83,8 @@ class ChatListWidget extends StatelessWidget { }, filter: (value) => _itemFilter(contactMap, chatList, value), - spaceBetweenSearchAndList: 4, + searchFieldPadding: + const EdgeInsets.fromLTRB(0, 0, 0, 4), inputDecoration: InputDecoration( labelText: translate('chat_list.search'), ), diff --git a/lib/chat_list/views/chat_single_contact_item_widget.dart b/lib/chat_list/views/chat_single_contact_item_widget.dart index 3bdf645..5191fdd 100644 --- a/lib/chat_list/views/chat_single_contact_item_widget.dart +++ b/lib/chat_list/views/chat_single_contact_item_widget.dart @@ -50,7 +50,7 @@ class ChatSingleContactItemWidget extends StatelessWidget { final avatar = AvatarWidget( name: name, - size: 34, + size: 32, borderColor: scaleTheme.config.useVisualIndicators ? scaleTheme.scheme.primaryScale.primaryText : scaleTheme.scheme.primaryScale.subtleBorder, @@ -75,7 +75,7 @@ class ChatSingleContactItemWidget extends StatelessWidget { trailing: AvailabilityWidget( availability: availability, color: scaleTileTheme.textColor, - ), + ).fit(fit: BoxFit.scaleDown), onTap: () { singleFuture(activeChatCubit, () async { activeChatCubit.setActiveChat(_localConversationRecordKey); diff --git a/lib/contacts/views/availability_widget.dart b/lib/contacts/views/availability_widget.dart index a79f774..75ef0a8 100644 --- a/lib/contacts/views/availability_widget.dart +++ b/lib/contacts/views/availability_widget.dart @@ -1,35 +1,39 @@ import 'package:awesome_extensions/awesome_extensions.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_translate/flutter_translate.dart'; import '../../proto/proto.dart' as proto; +import '../../theme/theme.dart'; class AvailabilityWidget extends StatelessWidget { const AvailabilityWidget( {required this.availability, required this.color, this.vertical = true, - this.iconSize = 24, + this.size = 32, super.key}); static Widget availabilityIcon(proto.Availability availability, Color color, {double size = 24}) { - late final Widget iconData; + late final Widget icon; switch (availability) { case proto.Availability.AVAILABILITY_AWAY: - iconData = ImageIcon(const AssetImage('assets/images/toilet.png'), - size: size, color: color); + icon = SvgPicture.asset('assets/images/toilet.svg', + width: size, + height: size, + colorFilter: ColorFilter.mode(color, BlendMode.srcATop)); case proto.Availability.AVAILABILITY_BUSY: - iconData = Icon(Icons.event_busy, size: size); + icon = Icon(Icons.event_busy, size: size); case proto.Availability.AVAILABILITY_FREE: - iconData = Icon(Icons.event_available, size: size); + icon = Icon(Icons.event_available, size: size); case proto.Availability.AVAILABILITY_OFFLINE: - iconData = Icon(Icons.cloud_off, size: size); + icon = Icon(Icons.cloud_off, size: size); case proto.Availability.AVAILABILITY_UNSPECIFIED: - iconData = Icon(Icons.question_mark, size: size); + icon = Icon(Icons.question_mark, size: size); } - return iconData; + return icon; } static String availabilityName(proto.Availability availability) { @@ -53,26 +57,25 @@ class AvailabilityWidget extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); final textTheme = theme.textTheme; - // final scale = theme.extension()!; - // final scaleConfig = theme.extension()!; final name = availabilityName(availability); - final icon = availabilityIcon(availability, color, size: iconSize); + final icon = availabilityIcon(availability, color, size: size * 2 / 3); return vertical - ? Column( - mainAxisSize: MainAxisSize.min, - //mainAxisAlignment: MainAxisAlignment.center, - children: [ - icon, - Text(name, style: textTheme.labelSmall!.copyWith(color: color)) - .paddingLTRB(0, 0, 0, 0) - ]) - : Row(mainAxisSize: MainAxisSize.min, children: [ - icon, - Text(name, style: textTheme.labelLarge!.copyWith(color: color)) - .paddingLTRB(8, 0, 0, 0) - ]); + ? ConstrainedBox( + constraints: BoxConstraints.tightFor(width: size), + child: Column(mainAxisSize: MainAxisSize.min, children: [ + icon, + Text(name, style: textTheme.labelSmall!.copyWith(color: color)) + .fit(fit: BoxFit.scaleDown) + ])) + : ConstrainedBox( + constraints: BoxConstraints.tightFor(height: size), + child: Row(mainAxisSize: MainAxisSize.min, children: [ + icon, + Text(name, style: textTheme.labelLarge!.copyWith(color: color)) + .paddingLTRB(size / 4, 0, 0, 0) + ])); } //////////////////////////////////////////////////////////////////////////// @@ -80,7 +83,7 @@ class AvailabilityWidget extends StatelessWidget { final proto.Availability availability; final Color color; final bool vertical; - final double iconSize; + final double size; @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { @@ -89,7 +92,7 @@ class AvailabilityWidget extends StatelessWidget { ..add( DiagnosticsProperty('availability', availability)) ..add(DiagnosticsProperty('vertical', vertical)) - ..add(DoubleProperty('iconSize', iconSize)) + ..add(DoubleProperty('size', size)) ..add(ColorProperty('color', color)); } } diff --git a/lib/contacts/views/contacts_page.dart b/lib/contacts/views/contacts_page.dart index 28217e6..0f1731d 100644 --- a/lib/contacts/views/contacts_page.dart +++ b/lib/contacts/views/contacts_page.dart @@ -1,6 +1,5 @@ import 'package:async_tools/async_tools.dart'; import 'package:awesome_extensions/awesome_extensions.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_translate/flutter_translate.dart'; import 'package:provider/provider.dart'; @@ -30,8 +29,10 @@ class _ContactsPageState extends State { @override Widget build(BuildContext context) { final theme = Theme.of(context); - final scale = theme.extension()!; - final appBarIconColor = scale.primaryScale.borderText; + final scaleTheme = theme.extension()!; + final appBarTheme = scaleTheme.appBarTheme(); + final scaleScheme = theme.extension()!; + final scale = scaleScheme.scale(ScaleKind.primary); final enableSplit = !isMobileSize(context); final enableLeft = enableSplit || _selectedContact == null; @@ -39,9 +40,11 @@ class _ContactsPageState extends State { return StyledScaffold( appBar: DefaultAppBar( - title: Text(!enableSplit && enableRight - ? translate('contacts_dialog.edit_contact') - : translate('contacts_dialog.contacts')), + title: Text( + !enableSplit && enableRight + ? translate('contacts_dialog.edit_contact') + : translate('contacts_dialog.contacts'), + ), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { @@ -60,41 +63,29 @@ class _ContactsPageState extends State { ), actions: [ if (_selectedContact != null) - FittedBox( - fit: BoxFit.scaleDown, - child: Column(mainAxisSize: MainAxisSize.min, children: [ - IconButton( - icon: const Icon(Icons.chat_bubble), - color: appBarIconColor, - tooltip: translate('contacts_dialog.new_chat'), - onPressed: () async { - await _onChatStarted(_selectedContact!); - }), - Text(translate('contacts_dialog.new_chat'), - style: theme.textTheme.labelSmall! - .copyWith(color: appBarIconColor)), - ])).paddingLTRB(8, 0, 8, 0), + IconButton( + icon: const Icon(Icons.chat_bubble), + iconSize: 24, + color: appBarTheme.iconColor, + tooltip: translate('contacts_dialog.new_chat'), + onPressed: () async { + await _onChatStarted(_selectedContact!); + }).paddingLTRB(8, 0, 8, 0), if (enableSplit && _selectedContact != null) - FittedBox( - fit: BoxFit.scaleDown, - child: Column(mainAxisSize: MainAxisSize.min, children: [ - IconButton( - icon: const Icon(Icons.close), - color: appBarIconColor, - tooltip: translate('contacts_dialog.close_contact'), - onPressed: () async { - await _onContactSelected(null); - }), - Text(translate('contacts_dialog.close_contact'), - style: theme.textTheme.labelSmall! - .copyWith(color: appBarIconColor)), - ])).paddingLTRB(8, 0, 8, 0), + IconButton( + icon: const Icon(Icons.close), + iconSize: 24, + color: appBarTheme.iconColor, + tooltip: translate('contacts_dialog.close_contact'), + onPressed: () async { + await _onContactSelected(null); + }).paddingLTRB(8, 0, 8, 0), ]), body: LayoutBuilder(builder: (context, constraint) { final maxWidth = constraint.maxWidth; return ColoredBox( - color: scale.primaryScale.appBackground, + color: scale.appBackground, child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ Offstage( @@ -104,20 +95,20 @@ class _ContactsPageState extends State { ? maxWidth : (maxWidth / 3).clamp(200, 500), child: DecoratedBox( - decoration: BoxDecoration( - color: scale.primaryScale.subtleBackground), + decoration: + BoxDecoration(color: scale.subtleBackground), child: ContactsBrowser( selectedContactRecordKey: _selectedContact ?.localConversationRecordKey .toVeilid(), onContactSelected: _onContactSelected, onStartChat: _onChatStarted, - ).paddingLTRB(8, 0, 8, 8)))), + ).paddingLTRB(4, 0, 4, 8)))), if (enableRight && enableLeft) Container( constraints: const BoxConstraints(minWidth: 1, maxWidth: 1), - color: scale.primaryScale.subtleBorder), + color: scale.subtleBorder), if (enableRight) if (_selectedContact == null) const NoContactWidget().expanded() diff --git a/lib/layout/default_app_bar.dart b/lib/layout/default_app_bar.dart index fbf2360..b9c0b41 100644 --- a/lib/layout/default_app_bar.dart +++ b/lib/layout/default_app_bar.dart @@ -4,9 +4,12 @@ import 'package:flutter_svg/flutter_svg.dart'; class DefaultAppBar extends AppBar { DefaultAppBar( - {required super.title, super.key, Widget? leading, super.actions}) + {super.title, + super.flexibleSpace, + super.key, + Widget? leading, + super.actions}) : super( - titleSpacing: 0, leading: leading ?? Container( margin: const EdgeInsets.all(4), @@ -14,6 +17,6 @@ class DefaultAppBar extends AppBar { color: Colors.black.withAlpha(32), shape: BoxShape.circle), child: - SvgPicture.asset('assets/images/vlogo.svg', height: 32) + SvgPicture.asset('assets/images/vlogo.svg', height: 24) .paddingAll(4))); } diff --git a/lib/layout/home/home_account_ready.dart b/lib/layout/home/home_account_ready.dart index 5f90c9f..3674a08 100644 --- a/lib/layout/home/home_account_ready.dart +++ b/lib/layout/home/home_account_ready.dart @@ -33,7 +33,7 @@ class _HomeAccountReadyState extends State { color: scaleConfig.preferBorders ? scale.primaryScale.border : scale.primaryScale.borderText, - constraints: const BoxConstraints.expand(height: 48, width: 48), + constraints: const BoxConstraints.expand(height: 40, width: 40), style: ButtonStyle( backgroundColor: WidgetStateProperty.all( scaleConfig.preferBorders @@ -50,7 +50,7 @@ class _HomeAccountReadyState extends State { : scale.primaryScale.borderText, width: 2), borderRadius: BorderRadius.all( - Radius.circular(12 * scaleConfig.borderRadiusScale))), + Radius.circular(8 * scaleConfig.borderRadiusScale))), )), tooltip: translate('menu.accounts_menu_tooltip'), onPressed: () async { @@ -68,7 +68,7 @@ class _HomeAccountReadyState extends State { color: scaleConfig.preferBorders ? scale.primaryScale.border : scale.primaryScale.borderText, - constraints: const BoxConstraints.expand(height: 48, width: 48), + constraints: const BoxConstraints.expand(height: 40, width: 40), style: ButtonStyle( backgroundColor: WidgetStateProperty.all( scaleConfig.preferBorders @@ -85,7 +85,7 @@ class _HomeAccountReadyState extends State { : scale.primaryScale.borderText, width: 2), borderRadius: BorderRadius.all( - Radius.circular(12 * scaleConfig.borderRadiusScale))), + Radius.circular(8 * scaleConfig.borderRadiusScale))), )), tooltip: translate('menu.contacts_tooltip'), onPressed: () async { diff --git a/lib/theme/models/scale_theme/scale_app_bar_theme.dart b/lib/theme/models/scale_theme/scale_app_bar_theme.dart new file mode 100644 index 0000000..ea8e83e --- /dev/null +++ b/lib/theme/models/scale_theme/scale_app_bar_theme.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +import 'scale_theme.dart'; + +class ScaleAppBarTheme { + ScaleAppBarTheme({ + required this.textStyle, + required this.iconColor, + required this.backgroundColor, + }); + + final TextStyle textStyle; + final Color iconColor; + final Color backgroundColor; +} + +extension ScaleAppBarThemeExt on ScaleTheme { + ScaleAppBarTheme appBarTheme({ScaleKind scaleKind = ScaleKind.primary}) { + final scale = scheme.scale(scaleKind); + + final textStyle = textTheme.titleLarge!.copyWith(color: scale.borderText); + final iconColor = scale.borderText; + final backgroundColor = scale.border; + + return ScaleAppBarTheme( + textStyle: textStyle, + iconColor: iconColor, + backgroundColor: backgroundColor, + ); + } +} diff --git a/lib/theme/models/scale_theme/scale_theme.dart b/lib/theme/models/scale_theme/scale_theme.dart index e787c0e..43ca641 100644 --- a/lib/theme/models/scale_theme/scale_theme.dart +++ b/lib/theme/models/scale_theme/scale_theme.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'scale_input_decorator_theme.dart'; import 'scale_scheme.dart'; +export 'scale_app_bar_theme.dart'; export 'scale_color.dart'; export 'scale_input_decorator_theme.dart'; export 'scale_scheme.dart'; @@ -137,8 +138,10 @@ class ScaleTheme extends ThemeExtension { return scheme.primaryScale.subtleBorder; })), appBarTheme: baseThemeData.appBarTheme.copyWith( - backgroundColor: scheme.primaryScale.border, - foregroundColor: scheme.primaryScale.borderText), + backgroundColor: scheme.primaryScale.border, + foregroundColor: scheme.primaryScale.borderText, + toolbarHeight: 40, + ), bottomSheetTheme: baseThemeData.bottomSheetTheme.copyWith( elevation: 0, modalElevation: 0, diff --git a/lib/theme/models/scale_theme/scale_tile_theme.dart b/lib/theme/models/scale_theme/scale_tile_theme.dart index da2c3cd..d549157 100644 --- a/lib/theme/models/scale_theme/scale_tile_theme.dart +++ b/lib/theme/models/scale_theme/scale_tile_theme.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'scale_scheme.dart'; import 'scale_theme.dart'; class ScaleTileTheme { diff --git a/lib/theme/views/slider_tile.dart b/lib/theme/views/slider_tile.dart index d293fa6..8e5f178 100644 --- a/lib/theme/views/slider_tile.dart +++ b/lib/theme/views/slider_tile.dart @@ -125,15 +125,13 @@ class SliderTile extends StatelessWidget { child: ListTile( onTap: onTap, dense: true, - visualDensity: - const VisualDensity(horizontal: -4, vertical: -4), title: Text( title, overflow: TextOverflow.fade, softWrap: false, ), subtitle: subtitle.isNotEmpty ? Text(subtitle) : null, - minTileHeight: 48, + minTileHeight: 52, iconColor: scaleTileTheme.textColor, textColor: scaleTileTheme.textColor, leading: diff --git a/lib/theme/views/wallpaper_preferences.dart b/lib/theme/views/wallpaper_preferences.dart index 48f0a6a..e90022c 100644 --- a/lib/theme/views/wallpaper_preferences.dart +++ b/lib/theme/views/wallpaper_preferences.dart @@ -14,10 +14,18 @@ Widget buildSettingsPageWallpaperPreferences( required ThemeSwitcherState switcher}) { final preferencesRepository = PreferencesRepository.instance; final themePreferences = preferencesRepository.value.themePreference; + final theme = Theme.of(context); + final scale = theme.extension()!; + final textTheme = theme.textTheme; + return FormBuilderCheckbox( name: formFieldEnableWallpaper, - title: Text(translate('settings_page.enable_wallpaper')), + title: Text(translate('settings_page.enable_wallpaper'), + style: textTheme.labelMedium), initialValue: themePreferences.enableWallpaper, + side: BorderSide(color: scale.primaryScale.border, width: 2), + checkColor: scale.primaryScale.borderText, + activeColor: scale.primaryScale.border, onChanged: (value) async { if (value != null) { final newThemePrefs = diff --git a/lib/theme/views/widget_helpers.dart b/lib/theme/views/widget_helpers.dart index 1b768dd..910074e 100644 --- a/lib/theme/views/widget_helpers.dart +++ b/lib/theme/views/widget_helpers.dart @@ -442,7 +442,7 @@ Widget styledTitleContainer({ color: borderColor ?? scale.primaryScale.border, shape: RoundedRectangleBorder( borderRadius: - BorderRadius.circular(12 * scaleConfig.borderRadiusScale), + BorderRadius.circular(8 * scaleConfig.borderRadiusScale), )), child: Column(children: [ Text( @@ -456,7 +456,7 @@ Widget styledTitleContainer({ backgroundColor ?? scale.primaryScale.subtleBackground, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( - 12 * scaleConfig.borderRadiusScale), + 8 * scaleConfig.borderRadiusScale), )), child: child) .paddingAll(4) diff --git a/pubspec.yaml b/pubspec.yaml index 5206f5d..a37a8ab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -176,10 +176,9 @@ flutter: - assets/images/splash.svg - assets/images/title.svg - assets/images/vlogo.svg + - assets/images/toilet.svg # Raster Images - assets/images/ellet.png - - assets/images/handshake.png - - assets/images/toilet.png # Printing - assets/js/pdf/3.2.146/pdf.min.js # Sounds From 2141dbff214b06da8aea303121b0395fa9c06be6 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 21 Mar 2025 11:33:58 -0400 Subject: [PATCH 2/6] deadlock cleanup --- .../cubits/account_info_cubit.dart | 1 - .../cubits/local_accounts_cubit.dart | 1 - .../cubits/per_account_collection_cubit.dart | 55 ++++++----- .../cubits/user_logins_cubit.dart | 1 - .../views/edit_account_page.dart | 24 +++-- .../views/edit_profile_form.dart | 3 - lib/app.dart | 4 +- lib/chat/views/chat_component_widget.dart | 2 +- lib/chat_list/cubits/chat_list_cubit.dart | 2 - .../views/create_invitation_dialog.dart | 1 + .../views/scan_invitation_dialog.dart | 4 +- lib/contacts/cubits/contact_list_cubit.dart | 6 +- lib/contacts/views/edit_contact_form.dart | 3 - .../views/empty_contact_list_widget.dart | 5 +- .../active_conversations_bloc_map_cubit.dart | 3 +- lib/layout/home/drawer_menu/drawer_menu.dart | 19 ++-- lib/layout/home/home_screen.dart | 3 +- .../views/notifications_preferences.dart | 9 -- lib/theme/models/radix_generator.dart | 2 +- lib/theme/models/scale_theme/scale_color.dart | 12 +-- .../scale_custom_dropdown_theme.dart | 2 +- .../models/scale_theme/scale_scheme.dart | 16 ++-- lib/theme/models/scale_theme/scale_theme.dart | 25 ++++- lib/theme/models/theme_preference.dart | 7 +- lib/theme/views/scanner_error_widget.dart | 4 - lib/theme/views/styled_alert.dart | 9 +- lib/theme/views/wallpaper_preferences.dart | 4 - .../repository/processor_repository.dart | 7 -- .../example/test/widget_test.dart | 5 +- .../lib/dht_support/src/dht_log/dht_log.dart | 38 ++++---- .../src/dht_log/dht_log_spine.dart | 18 ++-- .../src/dht_record/dht_record.dart | 44 ++++----- .../src/dht_record/dht_record_pool.dart | 95 ++++++++++--------- .../src/dht_short_array/dht_short_array.dart | 40 ++++---- .../dht_short_array_cubit.dart | 1 - .../dht_short_array/dht_short_array_head.dart | 9 +- .../dht_short_array_write.dart | 4 +- .../src/interfaces/dht_closeable.dart | 6 +- pubspec.lock | 7 +- pubspec.yaml | 6 +- 40 files changed, 254 insertions(+), 253 deletions(-) diff --git a/lib/account_manager/cubits/account_info_cubit.dart b/lib/account_manager/cubits/account_info_cubit.dart index d9d93fc..a5eab11 100644 --- a/lib/account_manager/cubits/account_info_cubit.dart +++ b/lib/account_manager/cubits/account_info_cubit.dart @@ -23,7 +23,6 @@ class AccountInfoCubit extends Cubit { if (acctInfo != null) { emit(acctInfo); } - break; } }); } diff --git a/lib/account_manager/cubits/local_accounts_cubit.dart b/lib/account_manager/cubits/local_accounts_cubit.dart index 704d8c5..3781297 100644 --- a/lib/account_manager/cubits/local_accounts_cubit.dart +++ b/lib/account_manager/cubits/local_accounts_cubit.dart @@ -20,7 +20,6 @@ class LocalAccountsCubit extends Cubit switch (change) { case AccountRepositoryChange.localAccounts: emit(_accountRepository.getLocalAccounts()); - break; // Ignore these case AccountRepositoryChange.userLogins: case AccountRepositoryChange.activeLocalAccount: diff --git a/lib/account_manager/cubits/per_account_collection_cubit.dart b/lib/account_manager/cubits/per_account_collection_cubit.dart index 089443a..fc2d447 100644 --- a/lib/account_manager/cubits/per_account_collection_cubit.dart +++ b/lib/account_manager/cubits/per_account_collection_cubit.dart @@ -15,6 +15,9 @@ import '../../notifications/notifications.dart'; import '../../proto/proto.dart' as proto; import '../account_manager.dart'; +const _kAccountRecordSubscriptionListenKey = + 'accountRecordSubscriptionListenKey'; + class PerAccountCollectionCubit extends Cubit { PerAccountCollectionCubit({ required Locator locator, @@ -32,6 +35,7 @@ class PerAccountCollectionCubit extends Cubit { await _processor.close(); await accountInfoCubit.close(); await _accountRecordSubscription?.cancel(); + await serialFutureClose((this, _kAccountRecordSubscriptionListenKey)); await accountRecordCubit?.close(); await activeSingleContactChatBlocMapCubitUpdater.close(); @@ -83,7 +87,7 @@ class PerAccountCollectionCubit extends Cubit { accountRecordCubit = null; // Update state to 'loading' - nextState = _updateAccountRecordState(nextState, null); + nextState = await _updateAccountRecordState(nextState, null); emit(nextState); } else { ///////////////// Logged in /////////////////// @@ -95,20 +99,22 @@ class PerAccountCollectionCubit extends Cubit { // Update state to value nextState = - _updateAccountRecordState(nextState, accountRecordCubit!.state); + await _updateAccountRecordState(nextState, accountRecordCubit!.state); emit(nextState); // Subscribe AccountRecordCubit _accountRecordSubscription ??= accountRecordCubit!.stream.listen((avAccountRecordState) { - emit(_updateAccountRecordState(state, avAccountRecordState)); + serialFuture((this, _kAccountRecordSubscriptionListenKey), () async { + emit(await _updateAccountRecordState(state, avAccountRecordState)); + }); }); } } - PerAccountCollectionState _updateAccountRecordState( + Future _updateAccountRecordState( PerAccountCollectionState prevState, - AsyncValue? avAccountRecordState) { + AsyncValue? avAccountRecordState) async { // Get next state final nextState = prevState.copyWith(avAccountRecordState: avAccountRecordState); @@ -121,8 +127,8 @@ class PerAccountCollectionCubit extends Cubit { .avAccountRecordState?.asData?.value.contactInvitationRecords .toVeilid(); - final contactInvitationListCubit = contactInvitationListCubitUpdater.update( - accountInfo.userLogin == null || + final contactInvitationListCubit = await contactInvitationListCubitUpdater + .update(accountInfo.userLogin == null || contactInvitationListRecordPointer == null ? null : (accountInfo, contactInvitationListRecordPointer)); @@ -131,34 +137,35 @@ class PerAccountCollectionCubit extends Cubit { final contactListRecordPointer = nextState.avAccountRecordState?.asData?.value.contactList.toVeilid(); - final contactListCubit = contactListCubitUpdater.update( + final contactListCubit = await contactListCubitUpdater.update( accountInfo.userLogin == null || contactListRecordPointer == null ? null : (accountInfo, contactListRecordPointer)); // WaitingInvitationsBlocMapCubit - final waitingInvitationsBlocMapCubit = waitingInvitationsBlocMapCubitUpdater - .update(accountInfo.userLogin == null || - contactInvitationListCubit == null || - contactListCubit == null - ? null - : ( - accountInfo, - accountRecordCubit!, - contactInvitationListCubit, - contactListCubit, - _locator(), - )); + final waitingInvitationsBlocMapCubit = + await waitingInvitationsBlocMapCubitUpdater.update( + accountInfo.userLogin == null || + contactInvitationListCubit == null || + contactListCubit == null + ? null + : ( + accountInfo, + accountRecordCubit!, + contactInvitationListCubit, + contactListCubit, + _locator(), + )); // ActiveChatCubit - final activeChatCubit = activeChatCubitUpdater + final activeChatCubit = await activeChatCubitUpdater .update((accountInfo.userLogin == null) ? null : true); // ChatListCubit final chatListRecordPointer = nextState.avAccountRecordState?.asData?.value.chatList.toVeilid(); - final chatListCubit = chatListCubitUpdater.update( + final chatListCubit = await chatListCubitUpdater.update( accountInfo.userLogin == null || chatListRecordPointer == null || activeChatCubit == null @@ -167,7 +174,7 @@ class PerAccountCollectionCubit extends Cubit { // ActiveConversationsBlocMapCubit final activeConversationsBlocMapCubit = - activeConversationsBlocMapCubitUpdater.update( + await activeConversationsBlocMapCubitUpdater.update( accountRecordCubit == null || chatListCubit == null || contactListCubit == null @@ -181,7 +188,7 @@ class PerAccountCollectionCubit extends Cubit { // ActiveSingleContactChatBlocMapCubit final activeSingleContactChatBlocMapCubit = - activeSingleContactChatBlocMapCubitUpdater.update( + await activeSingleContactChatBlocMapCubitUpdater.update( accountInfo.userLogin == null || activeConversationsBlocMapCubit == null ? null diff --git a/lib/account_manager/cubits/user_logins_cubit.dart b/lib/account_manager/cubits/user_logins_cubit.dart index 734ced3..5623a34 100644 --- a/lib/account_manager/cubits/user_logins_cubit.dart +++ b/lib/account_manager/cubits/user_logins_cubit.dart @@ -17,7 +17,6 @@ class UserLoginsCubit extends Cubit { switch (change) { case AccountRepositoryChange.userLogins: emit(_accountRepository.getUserLogins()); - break; // Ignore these case AccountRepositoryChange.localAccounts: case AccountRepositoryChange.activeLocalAccount: diff --git a/lib/account_manager/views/edit_account_page.dart b/lib/account_manager/views/edit_account_page.dart index 81b67eb..bd18967 100644 --- a/lib/account_manager/views/edit_account_page.dart +++ b/lib/account_manager/views/edit_account_page.dart @@ -61,6 +61,13 @@ class _EditAccountPageState extends WindowSetupState { ); Future _onRemoveAccount() async { + // dismiss the keyboard by unfocusing the textfield + FocusScope.of(context).unfocus(); + await asyncSleep(const Duration(milliseconds: 250)); + if (!mounted) { + return; + } + final confirmed = await StyledDialog.show( context: context, title: translate('edit_account_page.remove_account_confirm'), @@ -87,10 +94,7 @@ class _EditAccountPageState extends WindowSetupState { ])) ]).paddingAll(24) ])); - if (confirmed != null && confirmed && mounted) { - // dismiss the keyboard by unfocusing the textfield - FocusScope.of(context).unfocus(); - + if (confirmed != null && confirmed) { try { setState(() { _isInAsyncCall = true; @@ -125,6 +129,13 @@ class _EditAccountPageState extends WindowSetupState { } Future _onDestroyAccount() async { + // dismiss the keyboard by unfocusing the textfield + FocusScope.of(context).unfocus(); + await asyncSleep(const Duration(milliseconds: 250)); + if (!mounted) { + return; + } + final confirmed = await StyledDialog.show( context: context, title: translate('edit_account_page.destroy_account_confirm'), @@ -154,10 +165,7 @@ class _EditAccountPageState extends WindowSetupState { ])) ]).paddingAll(24) ])); - if (confirmed != null && confirmed && mounted) { - // dismiss the keyboard by unfocusing the textfield - FocusScope.of(context).unfocus(); - + if (confirmed != null && confirmed) { try { setState(() { _isInAsyncCall = true; diff --git a/lib/account_manager/views/edit_profile_form.dart b/lib/account_manager/views/edit_profile_form.dart index d6bb504..80bd2b3 100644 --- a/lib/account_manager/views/edit_profile_form.dart +++ b/lib/account_manager/views/edit_profile_form.dart @@ -282,9 +282,6 @@ class _EditProfileFormState extends State { FormBuilderCheckbox( name: EditProfileForm.formFieldAutoAway, initialValue: _savedValue.autoAway, - side: BorderSide(color: scale.primaryScale.border, width: 2), - checkColor: scale.primaryScale.borderText, - activeColor: scale.primaryScale.border, title: Text(translate('account.form_auto_away'), style: textTheme.labelMedium), onChanged: (v) { diff --git a/lib/app.dart b/lib/app.dart index 519f2bb..f8241da 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -47,7 +47,7 @@ class VeilidChatApp extends StatelessWidget { final ThemeData initialThemeData; - void _reloadTheme(BuildContext context) { + void reloadTheme(BuildContext context) { singleFuture(this, () async { log.info('Reloading theme'); @@ -95,7 +95,7 @@ class VeilidChatApp extends StatelessWidget { }, child: Actions(actions: >{ ReloadThemeIntent: CallbackAction( - onInvoke: (intent) => _reloadTheme(context)), + onInvoke: (intent) => reloadTheme(context)), AttachDetachIntent: CallbackAction( onInvoke: (intent) => _attachDetach(context)), }, child: Focus(autofocus: true, child: builder(context))))); diff --git a/lib/chat/views/chat_component_widget.dart b/lib/chat/views/chat_component_widget.dart index f41ba47..1646772 100644 --- a/lib/chat/views/chat_component_widget.dart +++ b/lib/chat/views/chat_component_widget.dart @@ -120,7 +120,7 @@ class ChatComponentWidget extends StatelessWidget { return Column( children: [ Container( - height: 40, + height: 48, decoration: BoxDecoration( color: scale.border, ), diff --git a/lib/chat_list/cubits/chat_list_cubit.dart b/lib/chat_list/cubits/chat_list_cubit.dart index 6bb88c1..3ae3db1 100644 --- a/lib/chat_list/cubits/chat_list_cubit.dart +++ b/lib/chat_list/cubits/chat_list_cubit.dart @@ -86,14 +86,12 @@ class ChatListCubit extends DHTShortArrayCubit // Nothing to do here return; } - break; case proto.Chat_Kind.group: if (c.group.localConversationRecordKey == contact.localConversationRecordKey) { throw StateError('direct conversation record key should' ' not be used for group chats!'); } - break; case proto.Chat_Kind.notSet: throw StateError('unknown chat kind'); } diff --git a/lib/contact_invitation/views/create_invitation_dialog.dart b/lib/contact_invitation/views/create_invitation_dialog.dart index d835de8..581e8d6 100644 --- a/lib/contact_invitation/views/create_invitation_dialog.dart +++ b/lib/contact_invitation/views/create_invitation_dialog.dart @@ -191,6 +191,7 @@ class _CreateInvitationDialogState extends State { mainAxisSize: MainAxisSize.min, children: [ TextField( + autofocus: true, controller: _recipientTextController, onChanged: (value) { setState(() {}); diff --git a/lib/contact_invitation/views/scan_invitation_dialog.dart b/lib/contact_invitation/views/scan_invitation_dialog.dart index 645640e..fa8bba9 100644 --- a/lib/contact_invitation/views/scan_invitation_dialog.dart +++ b/lib/contact_invitation/views/scan_invitation_dialog.dart @@ -86,7 +86,7 @@ class ScannerOverlay extends CustomPainter { final cutoutPath = Path()..addRect(scanWindow); final backgroundPaint = Paint() - ..color = Colors.black.withOpacity(0.5) + ..color = Colors.black.withAlpha(127) ..style = PaintingStyle.fill ..blendMode = BlendMode.dstOut; @@ -188,7 +188,7 @@ class ScanInvitationDialogState extends State { child: Container( alignment: Alignment.bottomCenter, height: 100, - color: Colors.black.withOpacity(0.4), + color: Colors.black.withAlpha(127), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ diff --git a/lib/contacts/cubits/contact_list_cubit.dart b/lib/contacts/cubits/contact_list_cubit.dart index df70cc0..a0591ad 100644 --- a/lib/contacts/cubits/contact_list_cubit.dart +++ b/lib/contacts/cubits/contact_list_cubit.dart @@ -149,10 +149,14 @@ class ContactListCubit extends DHTShortArrayCubit { // Mark the conversation records for deletion await DHTRecordPool.instance .deleteRecord(deletedItem.localConversationRecordKey.toVeilid()); + } on Exception catch (e) { + log.debug('error deleting local conversation record: $e', e); + } + try { await DHTRecordPool.instance .deleteRecord(deletedItem.remoteConversationRecordKey.toVeilid()); } on Exception catch (e) { - log.debug('error deleting conversation records: $e', e); + log.debug('error deleting remote conversation record: $e', e); } } } diff --git a/lib/contacts/views/edit_contact_form.dart b/lib/contacts/views/edit_contact_form.dart index 5477c60..514f019 100644 --- a/lib/contacts/views/edit_contact_form.dart +++ b/lib/contacts/views/edit_contact_form.dart @@ -195,9 +195,6 @@ class _EditContactFormState extends State { FormBuilderCheckbox( name: EditContactForm.formFieldShowAvailability, initialValue: _savedValue.showAvailability, - side: BorderSide(color: scale.primaryScale.border, width: 2), - checkColor: scale.primaryScale.borderText, - activeColor: scale.primaryScale.border, title: Text(translate('contact_form.form_show_availability'), style: textTheme.labelMedium), ), diff --git a/lib/contacts/views/empty_contact_list_widget.dart b/lib/contacts/views/empty_contact_list_widget.dart index 2563a1d..e6912fd 100644 --- a/lib/contacts/views/empty_contact_list_widget.dart +++ b/lib/contacts/views/empty_contact_list_widget.dart @@ -15,8 +15,7 @@ class EmptyContactListWidget extends StatelessWidget { final textTheme = theme.textTheme; final scale = theme.extension()!; - return Expanded( - child: Column( + return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.center, @@ -35,6 +34,6 @@ class EmptyContactListWidget extends StatelessWidget { ), ), ], - )); + ); } } diff --git a/lib/conversation/cubits/active_conversations_bloc_map_cubit.dart b/lib/conversation/cubits/active_conversations_bloc_map_cubit.dart index fbf0e80..08a249f 100644 --- a/lib/conversation/cubits/active_conversations_bloc_map_cubit.dart +++ b/lib/conversation/cubits/active_conversations_bloc_map_cubit.dart @@ -50,7 +50,7 @@ typedef ActiveConversationsBlocMapState // We currently only build the cubits for the chats that are active, not // archived chats or contacts that are not actively in a chat. // -// TODO: Polling contacts for new inactive chats is yet to be done +// TODO(crioux): Polling contacts for new inactive chats is yet to be done // class ActiveConversationsBlocMapCubit extends BlocMapCubit, ActiveConversationCubit> @@ -166,7 +166,6 @@ class ActiveConversationsBlocMapCubit extends BlocMapCubit { // ? grayColorFilter // : null) // .paddingLTRB(0, 0, 16, 0), - SvgPicture.asset( - height: 48, - 'assets/images/title.svg', - colorFilter: scaleConfig.useVisualIndicators - ? grayColorFilter - : src96StencilFilter), + GestureDetector( + onLongPress: () async { + context + .findAncestorWidgetOfExactType()! + .reloadTheme(context); + }, + child: SvgPicture.asset( + height: 48, + 'assets/images/title.svg', + colorFilter: scaleConfig.useVisualIndicators + ? grayColorFilter + : src96StencilFilter)), ]))), Text(translate('menu.accounts'), style: theme.textTheme.titleMedium!.copyWith( diff --git a/lib/layout/home/home_screen.dart b/lib/layout/home/home_screen.dart index a534415..3d1b14f 100644 --- a/lib/layout/home/home_screen.dart +++ b/lib/layout/home/home_screen.dart @@ -66,10 +66,11 @@ class HomeScreenState extends State final scale = theme.extension()!; final scaleConfig = theme.extension()!; - await showWarningWidgetModal( + await showAlertWidgetModal( context: context, title: translate('splash.beta_title'), child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ + const Icon(Icons.warning, size: 64), RichText( textAlign: TextAlign.center, text: TextSpan( diff --git a/lib/notifications/views/notifications_preferences.dart b/lib/notifications/views/notifications_preferences.dart index 95d4a1e..82f3555 100644 --- a/lib/notifications/views/notifications_preferences.dart +++ b/lib/notifications/views/notifications_preferences.dart @@ -129,9 +129,6 @@ Widget buildSettingsPageNotificationPreferences( // Display Beta Warning FormBuilderCheckbox( name: formFieldDisplayBetaWarning, - side: BorderSide(color: scale.primaryScale.border, width: 2), - checkColor: scale.primaryScale.borderText, - activeColor: scale.primaryScale.border, title: Text(translate('settings_page.display_beta_warning'), style: textTheme.labelMedium), initialValue: notificationsPreference.displayBetaWarning, @@ -147,9 +144,6 @@ Widget buildSettingsPageNotificationPreferences( // Enable Badge FormBuilderCheckbox( name: formFieldEnableBadge, - side: BorderSide(color: scale.primaryScale.border, width: 2), - checkColor: scale.primaryScale.borderText, - activeColor: scale.primaryScale.border, title: Text(translate('settings_page.enable_badge'), style: textTheme.labelMedium), initialValue: notificationsPreference.enableBadge, @@ -164,9 +158,6 @@ Widget buildSettingsPageNotificationPreferences( // Enable Notifications FormBuilderCheckbox( name: formFieldEnableNotifications, - side: BorderSide(color: scale.primaryScale.border, width: 2), - checkColor: scale.primaryScale.borderText, - activeColor: scale.primaryScale.border, title: Text(translate('settings_page.enable_notifications'), style: textTheme.labelMedium), initialValue: notificationsPreference.enableNotifications, diff --git a/lib/theme/models/radix_generator.dart b/lib/theme/models/radix_generator.dart index 3e3b0e6..ce05769 100644 --- a/lib/theme/models/radix_generator.dart +++ b/lib/theme/models/radix_generator.dart @@ -638,7 +638,7 @@ ThemeData radixGenerator(Brightness brightness, RadixThemeColor themeColor) { useVisualIndicators: false, preferBorders: false, borderRadiusScale: 1, - wallpaperAlpha: wallpaperAlpha(brightness, themeColor), + wallpaperOpacity: wallpaperAlpha(brightness, themeColor), ); final scaleTheme = ScaleTheme( diff --git a/lib/theme/models/scale_theme/scale_color.dart b/lib/theme/models/scale_theme/scale_color.dart index e50a01b..d79d878 100644 --- a/lib/theme/models/scale_theme/scale_color.dart +++ b/lib/theme/models/scale_theme/scale_color.dart @@ -50,11 +50,11 @@ class ScaleColor { Color? subtleBorder, Color? border, Color? hoverBorder, - Color? background, - Color? hoverBackground, + Color? primary, + Color? hoverPrimary, Color? subtleText, Color? appText, - Color? foregroundText, + Color? primaryText, Color? borderText, Color? dialogBorder, Color? dialogBorderText, @@ -72,11 +72,11 @@ class ScaleColor { subtleBorder: subtleBorder ?? this.subtleBorder, border: border ?? this.border, hoverBorder: hoverBorder ?? this.hoverBorder, - primary: background ?? this.primary, - hoverPrimary: hoverBackground ?? this.hoverPrimary, + primary: primary ?? this.primary, + hoverPrimary: hoverPrimary ?? this.hoverPrimary, subtleText: subtleText ?? this.subtleText, appText: appText ?? this.appText, - primaryText: foregroundText ?? this.primaryText, + primaryText: primaryText ?? this.primaryText, borderText: borderText ?? this.borderText, dialogBorder: dialogBorder ?? this.dialogBorder, dialogBorderText: dialogBorderText ?? this.dialogBorderText, diff --git a/lib/theme/models/scale_theme/scale_custom_dropdown_theme.dart b/lib/theme/models/scale_theme/scale_custom_dropdown_theme.dart index 692ec85..2c5eb1c 100644 --- a/lib/theme/models/scale_theme/scale_custom_dropdown_theme.dart +++ b/lib/theme/models/scale_theme/scale_custom_dropdown_theme.dart @@ -68,7 +68,7 @@ extension ScaleCustomDropdownThemeExt on ScaleTheme { listItemDecoration: null, ); - final disabledDecoration = CustomDropdownDisabledDecoration( + const disabledDecoration = CustomDropdownDisabledDecoration( fillColor: null, shadow: null, suffixIcon: null, diff --git a/lib/theme/models/scale_theme/scale_scheme.dart b/lib/theme/models/scale_theme/scale_scheme.dart index dd88b4f..8363476 100644 --- a/lib/theme/models/scale_theme/scale_scheme.dart +++ b/lib/theme/models/scale_theme/scale_scheme.dart @@ -111,27 +111,27 @@ class ScaleConfig extends ThemeExtension { required this.useVisualIndicators, required this.preferBorders, required this.borderRadiusScale, - required double wallpaperAlpha, - }) : _wallpaperAlpha = wallpaperAlpha; + required this.wallpaperOpacity, + }); final bool useVisualIndicators; final bool preferBorders; final double borderRadiusScale; - final double _wallpaperAlpha; + final double wallpaperOpacity; - int get wallpaperAlpha => _wallpaperAlpha.toInt(); + int get wallpaperAlpha => wallpaperOpacity.toInt(); @override ScaleConfig copyWith( {bool? useVisualIndicators, bool? preferBorders, double? borderRadiusScale, - double? wallpaperAlpha}) => + double? wallpaperOpacity}) => ScaleConfig( useVisualIndicators: useVisualIndicators ?? this.useVisualIndicators, preferBorders: preferBorders ?? this.preferBorders, borderRadiusScale: borderRadiusScale ?? this.borderRadiusScale, - wallpaperAlpha: wallpaperAlpha ?? this._wallpaperAlpha, + wallpaperOpacity: wallpaperOpacity ?? this.wallpaperOpacity, ); @override @@ -145,7 +145,7 @@ class ScaleConfig extends ThemeExtension { preferBorders: t < .5 ? preferBorders : other.preferBorders, borderRadiusScale: lerpDouble(borderRadiusScale, other.borderRadiusScale, t) ?? 1, - wallpaperAlpha: - lerpDouble(_wallpaperAlpha, other._wallpaperAlpha, t) ?? 1); + wallpaperOpacity: + lerpDouble(wallpaperOpacity, other.wallpaperOpacity, t) ?? 1); } } diff --git a/lib/theme/models/scale_theme/scale_theme.dart b/lib/theme/models/scale_theme/scale_theme.dart index 43ca641..ef430d2 100644 --- a/lib/theme/models/scale_theme/scale_theme.dart +++ b/lib/theme/models/scale_theme/scale_theme.dart @@ -84,6 +84,24 @@ class ScaleTheme extends ThemeExtension { scheme.primaryScale.borderText, scheme.primaryScale.primary, 0.25); }); + WidgetStateProperty checkboxFillColorWidgetStateProperty() => + WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.selected)) { + if (states.contains(WidgetState.disabled)) { + return scheme.grayScale.primary.withAlpha(0x7F); + } else if (states.contains(WidgetState.pressed)) { + return scheme.primaryScale.hoverBorder; + } else if (states.contains(WidgetState.hovered)) { + return scheme.primaryScale.hoverBorder; + } else if (states.contains(WidgetState.focused)) { + return scheme.primaryScale.border; + } + return scheme.primaryScale.border; + } else { + return Colors.transparent; + } + }); + // WidgetStateProperty elementBackgroundWidgetStateProperty() { // return null; // } @@ -140,7 +158,7 @@ class ScaleTheme extends ThemeExtension { appBarTheme: baseThemeData.appBarTheme.copyWith( backgroundColor: scheme.primaryScale.border, foregroundColor: scheme.primaryScale.borderText, - toolbarHeight: 40, + toolbarHeight: 48, ), bottomSheetTheme: baseThemeData.bottomSheetTheme.copyWith( elevation: 0, @@ -150,6 +168,11 @@ class ScaleTheme extends ThemeExtension { topLeft: Radius.circular(16 * config.borderRadiusScale), topRight: Radius.circular(16 * config.borderRadiusScale)))), canvasColor: scheme.primaryScale.subtleBackground, + checkboxTheme: baseThemeData.checkboxTheme.copyWith( + side: BorderSide(color: scheme.primaryScale.border, width: 2), + checkColor: elementColorWidgetStateProperty(), + fillColor: checkboxFillColorWidgetStateProperty(), + ), chipTheme: baseThemeData.chipTheme.copyWith( backgroundColor: scheme.primaryScale.elementBackground, selectedColor: scheme.primaryScale.activeElementBackground, diff --git a/lib/theme/models/theme_preference.dart b/lib/theme/models/theme_preference.dart index dc2e082..4be6b4e 100644 --- a/lib/theme/models/theme_preference.dart +++ b/lib/theme/models/theme_preference.dart @@ -1,6 +1,5 @@ import 'package:change_case/change_case.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_svg/svg.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -103,7 +102,7 @@ extension ThemePreferencesExt on ThemePreferences { useVisualIndicators: true, preferBorders: false, borderRadiusScale: 1, - wallpaperAlpha: 255), + wallpaperOpacity: 255), primaryFront: Colors.black, primaryBack: Colors.white, secondaryFront: Colors.black, @@ -123,7 +122,7 @@ extension ThemePreferencesExt on ThemePreferences { useVisualIndicators: true, preferBorders: true, borderRadiusScale: 0.2, - wallpaperAlpha: 208), + wallpaperOpacity: 208), primaryFront: const Color(0xFF000000), primaryBack: const Color(0xFF00FF00), secondaryFront: const Color(0xFF000000), @@ -141,7 +140,7 @@ extension ThemePreferencesExt on ThemePreferences { useVisualIndicators: true, preferBorders: true, borderRadiusScale: 0.2, - wallpaperAlpha: 192), + wallpaperOpacity: 192), primaryFront: const Color(0xFF000000), primaryBack: const Color(0xFF00FF00), secondaryFront: const Color(0xFF000000), diff --git a/lib/theme/views/scanner_error_widget.dart b/lib/theme/views/scanner_error_widget.dart index 0926128..d5463f4 100644 --- a/lib/theme/views/scanner_error_widget.dart +++ b/lib/theme/views/scanner_error_widget.dart @@ -14,16 +14,12 @@ class ScannerErrorWidget extends StatelessWidget { switch (error.errorCode) { case MobileScannerErrorCode.controllerUninitialized: errorMessage = 'Controller not ready.'; - break; case MobileScannerErrorCode.permissionDenied: errorMessage = 'Permission denied'; - break; case MobileScannerErrorCode.unsupported: errorMessage = 'Scanning is unsupported on this device'; - break; default: errorMessage = 'Generic Error'; - break; } return ColoredBox( diff --git a/lib/theme/views/styled_alert.dart b/lib/theme/views/styled_alert.dart index 82218e8..8602c22 100644 --- a/lib/theme/views/styled_alert.dart +++ b/lib/theme/views/styled_alert.dart @@ -11,6 +11,7 @@ AlertStyle _alertStyle(BuildContext context) { return AlertStyle( animationType: AnimationType.grow, + isCloseButton: false, //animationDuration: const Duration(milliseconds: 200), alertBorder: RoundedRectangleBorder( side: !scaleConfig.useVisualIndicators @@ -131,7 +132,7 @@ Future showErrorStacktraceModal( ); } -Future showWarningModal( +Future showAlertModal( {required BuildContext context, required String title, required String text}) async { @@ -139,7 +140,7 @@ Future showWarningModal( context: context, style: _alertStyle(context), useRootNavigator: false, - type: AlertType.warning, + type: AlertType.none, title: title, desc: text, buttons: [ @@ -161,7 +162,7 @@ Future showWarningModal( ).show(); } -Future showWarningWidgetModal( +Future showAlertWidgetModal( {required BuildContext context, required String title, required Widget child}) async { @@ -169,7 +170,7 @@ Future showWarningWidgetModal( context: context, style: _alertStyle(context), useRootNavigator: false, - type: AlertType.warning, + type: AlertType.none, title: title, content: child, buttons: [ diff --git a/lib/theme/views/wallpaper_preferences.dart b/lib/theme/views/wallpaper_preferences.dart index e90022c..f9ae94c 100644 --- a/lib/theme/views/wallpaper_preferences.dart +++ b/lib/theme/views/wallpaper_preferences.dart @@ -15,7 +15,6 @@ Widget buildSettingsPageWallpaperPreferences( final preferencesRepository = PreferencesRepository.instance; final themePreferences = preferencesRepository.value.themePreference; final theme = Theme.of(context); - final scale = theme.extension()!; final textTheme = theme.textTheme; return FormBuilderCheckbox( @@ -23,9 +22,6 @@ Widget buildSettingsPageWallpaperPreferences( title: Text(translate('settings_page.enable_wallpaper'), style: textTheme.labelMedium), initialValue: themePreferences.enableWallpaper, - side: BorderSide(color: scale.primaryScale.border, width: 2), - checkColor: scale.primaryScale.borderText, - activeColor: scale.primaryScale.border, onChanged: (value) async { if (value != null) { final newThemePrefs = diff --git a/lib/veilid_processor/repository/processor_repository.dart b/lib/veilid_processor/repository/processor_repository.dart index 3622219..7ff2482 100644 --- a/lib/veilid_processor/repository/processor_repository.dart +++ b/lib/veilid_processor/repository/processor_repository.dart @@ -44,13 +44,6 @@ class ProcessorRepository { log.info('Veilid version: $veilidVersion'); - // HACK: In case of hot restart shut down first - try { - await Veilid.instance.shutdownVeilidCore(); - } on Exception { - // Do nothing on failure here - } - final updateStream = await Veilid.instance .startupVeilidCore(await getVeilidConfig(kIsWeb, VeilidChatApp.name)); _updateSubscription = updateStream.listen((update) { diff --git a/packages/veilid_support/example/test/widget_test.dart b/packages/veilid_support/example/test/widget_test.dart index 092d222..d5cfa06 100644 --- a/packages/veilid_support/example/test/widget_test.dart +++ b/packages/veilid_support/example/test/widget_test.dart @@ -5,13 +5,12 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. +import 'package:example/main.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:example/main.dart'; - void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { + testWidgets('Counter increments smoke test', (tester) async { // Build our app and trigger a frame. await tester.pumpWidget(const MyApp()); diff --git a/packages/veilid_support/lib/dht_support/src/dht_log/dht_log.dart b/packages/veilid_support/lib/dht_support/src/dht_log/dht_log.dart index bba3306..8f88ce1 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_log/dht_log.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_log/dht_log.dart @@ -171,32 +171,31 @@ class DHTLog implements DHTDeleteable { /// Add a reference to this log @override - Future ref() async => _mutex.protect(() async { - _openCount++; - }); + void ref() { + _openCount++; + } /// Free all resources for the DHTLog @override - Future close() async => _mutex.protect(() async { - if (_openCount == 0) { - throw StateError('already closed'); - } - _openCount--; - if (_openCount != 0) { - return false; - } - await _watchController?.close(); - _watchController = null; - await _spine.close(); - return true; - }); + Future close() async { + if (_openCount == 0) { + throw StateError('already closed'); + } + _openCount--; + if (_openCount != 0) { + return false; + } + // + await _watchController?.close(); + _watchController = null; + await _spine.close(); + return true; + } /// Free all resources for the DHTLog and delete it from the DHT /// Will wait until the short array is closed to delete it @override - Future delete() async { - await _spine.delete(); - } + Future delete() => _spine.delete(); //////////////////////////////////////////////////////////////////////////// // Public API @@ -306,7 +305,6 @@ class DHTLog implements DHTDeleteable { // Openable int _openCount; - final _mutex = Mutex(debugLockTimeout: kIsDebugMode ? 60 : null); // Watch mutex to ensure we keep the representation valid final Mutex _listenMutex = Mutex(debugLockTimeout: kIsDebugMode ? 60 : null); diff --git a/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_spine.dart b/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_spine.dart index 1ea48be..8eff1b6 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_spine.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_spine.dart @@ -24,13 +24,11 @@ class _DHTLogPosition extends DHTCloseable { /// Add a reference to this log @override - Future ref() async { - await shortArray.ref(); - } + void ref() => shortArray.ref(); /// Free all resources for the DHTLogPosition @override - Future close() async => _dhtLogSpine._segmentClosed(_segmentNumber); + Future close() => _dhtLogSpine._segmentClosed(_segmentNumber); } class _DHTLogSegmentLookup extends Equatable { @@ -124,12 +122,8 @@ class _DHTLogSpine { }); } - Future delete() async { - await _spineMutex.protect(() async { - // Will deep delete all segment records as they are children - await _spineRecord.delete(); - }); - } + // Will deep delete all segment records as they are children + Future delete() async => _spineMutex.protect(_spineRecord.delete); Future operate(Future Function(_DHTLogSpine) closure) async => // ignore: prefer_expression_function_bodies @@ -431,7 +425,7 @@ class _DHTLogSpine { late DHTShortArray shortArray; if (openedSegment != null) { // If so, return a ref - await openedSegment.ref(); + openedSegment.ref(); shortArray = openedSegment; } else { // Otherwise open a segment @@ -453,7 +447,7 @@ class _DHTLogSpine { // LRU cache the segment number if (!_openCache.remove(segmentNumber)) { // If this is new to the cache ref it when it goes in - await shortArray.ref(); + shortArray.ref(); } _openCache.add(segmentNumber); if (_openCache.length > _openCacheSize) { diff --git a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record.dart b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record.dart index bddb4e7..0a51ba1 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record.dart @@ -64,34 +64,35 @@ class DHTRecord implements DHTDeleteable { /// Add a reference to this DHTRecord @override - Future ref() async => _mutex.protect(() async { - _openCount++; - }); + void ref() { + _openCount++; + } /// Free all resources for the DHTRecord @override - Future close() async => _mutex.protect(() async { - if (_openCount == 0) { - throw StateError('already closed'); - } - _openCount--; - if (_openCount != 0) { - return false; - } + Future close() async { + if (_openCount == 0) { + throw StateError('already closed'); + } + _openCount--; + if (_openCount != 0) { + return false; + } - await serialFutureClose((this, _sfListen)); - await _watchController?.close(); - _watchController = null; - await DHTRecordPool.instance._recordClosed(this); - return true; - }); + await _watchController?.close(); + _watchController = null; + await serialFutureClose((this, _sfListen)); + + await DHTRecordPool.instance._recordClosed(this); + + return true; + } /// Free all resources for the DHTRecord and delete it from the DHT - /// Will wait until the record is closed to delete it + /// Returns true if the deletion was processed immediately + /// Returns false if the deletion was marked for later @override - Future delete() async => _mutex.protect(() async { - await DHTRecordPool.instance.deleteRecord(key); - }); + Future delete() async => DHTRecordPool.instance.deleteRecord(key); //////////////////////////////////////////////////////////////////////////// // Public API @@ -562,7 +563,6 @@ class DHTRecord implements DHTDeleteable { final KeyPair? _writer; final VeilidCrypto _crypto; final String debugName; - final _mutex = Mutex(debugLockTimeout: kIsDebugMode ? 60 : null); int _openCount; StreamController? _watchController; _WatchState? _watchState; diff --git a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.dart b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.dart index 3f55687..15c955d 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.dart @@ -479,25 +479,29 @@ class DHTRecordPool with TableDBBackedJson { // Called when a DHTRecord is closed // Cleans up the opened record housekeeping and processes any late deletions Future _recordClosed(DHTRecord record) async { - await _recordTagLock.protect(record.key, - closure: () => _mutex.protect(() async { - final key = record.key; + final key = record.key; + await _recordTagLock.protect(key, closure: () async { + await _mutex.protect(() async { + log('closeDHTRecord: debugName=${record.debugName} key=$key'); - log('closeDHTRecord: debugName=${record.debugName} key=$key'); + final openedRecordInfo = _opened[key]; + if (openedRecordInfo == null || + !openedRecordInfo.records.remove(record)) { + throw StateError('record already closed'); + } + if (openedRecordInfo.records.isNotEmpty) { + return; + } + _opened.remove(key); + await _routingContext.closeDHTRecord(key); + await _checkForLateDeletesInner(key); + }); - final openedRecordInfo = _opened[key]; - if (openedRecordInfo == null || - !openedRecordInfo.records.remove(record)) { - throw StateError('record already closed'); - } - if (openedRecordInfo.records.isEmpty) { - await _watchStateProcessors.remove(key); - await _routingContext.closeDHTRecord(key); - _opened.remove(key); - - await _checkForLateDeletesInner(key); - } - })); + // This happens after the mutex is released + // because the record has already been removed from _opened + // which means that updates to the state processor won't happen + await _watchStateProcessors.remove(key); + }); } // Check to see if this key can finally be deleted @@ -929,40 +933,37 @@ class DHTRecordPool with TableDBBackedJson { } /// Ticker to check watch state change requests - Future tick() async { - final now = veilid.now(); + Future tick() async => _mutex.protect(() async { + // See if any opened records need watch state changes + final now = veilid.now(); + for (final kv in _opened.entries) { + final openedRecordKey = kv.key; + final openedRecordInfo = kv.value; - await _mutex.protect(() async { - // See if any opened records need watch state changes - for (final kv in _opened.entries) { - final openedRecordKey = kv.key; - final openedRecordInfo = kv.value; + var wantsWatchStateUpdate = + openedRecordInfo.shared.needsWatchStateUpdate; - var wantsWatchStateUpdate = - openedRecordInfo.shared.needsWatchStateUpdate; + // Check if we have reached renewal time for the watch + if (openedRecordInfo.shared.unionWatchState != null && + openedRecordInfo.shared.unionWatchState!.renewalTime != null && + now.value > + openedRecordInfo.shared.unionWatchState!.renewalTime!.value) { + wantsWatchStateUpdate = true; + } - // Check if we have reached renewal time for the watch - if (openedRecordInfo.shared.unionWatchState != null && - openedRecordInfo.shared.unionWatchState!.renewalTime != null && - now.value > - openedRecordInfo.shared.unionWatchState!.renewalTime!.value) { - wantsWatchStateUpdate = true; + if (wantsWatchStateUpdate) { + // Update union watch state + final unionWatchState = + _collectUnionWatchState(openedRecordInfo.records); + + _watchStateProcessors.updateState( + openedRecordKey, + unionWatchState, + (newState) => + _watchStateChange(openedRecordKey, unionWatchState)); + } } - - if (wantsWatchStateUpdate) { - // Update union watch state - final unionWatchState = - _collectUnionWatchState(openedRecordInfo.records); - - _watchStateProcessors.updateState( - openedRecordKey, - unionWatchState, - (newState) => - _watchStateChange(openedRecordKey, unionWatchState)); - } - } - }); - } + }); ////////////////////////////////////////////////////////////// // AsyncTableDBBacked diff --git a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array.dart b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array.dart index c0ec901..8101a7a 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array.dart @@ -148,33 +148,32 @@ class DHTShortArray implements DHTDeleteable { /// Add a reference to this shortarray @override - Future ref() async => _mutex.protect(() async { - _openCount++; - }); + void ref() { + _openCount++; + } /// Free all resources for the DHTShortArray @override - Future close() async => _mutex.protect(() async { - if (_openCount == 0) { - throw StateError('already closed'); - } - _openCount--; - if (_openCount != 0) { - return false; - } + Future close() async { + if (_openCount == 0) { + throw StateError('already closed'); + } + _openCount--; + if (_openCount != 0) { + return false; + } - await _watchController?.close(); - _watchController = null; - await _head.close(); - return true; - }); + await _watchController?.close(); + _watchController = null; + await _head.close(); + return true; + } /// Free all resources for the DHTShortArray and delete it from the DHT - /// Will wait until the short array is closed to delete it + /// Returns true if the deletion was processed immediately + /// Returns false if the deletion was marked for later @override - Future delete() async { - await _head.delete(); - } + Future delete() async => _head.delete(); //////////////////////////////////////////////////////////////////////////// // Public API @@ -289,7 +288,6 @@ class DHTShortArray implements DHTDeleteable { // Openable int _openCount; - final _mutex = Mutex(debugLockTimeout: kIsDebugMode ? 60 : null); // Watch mutex to ensure we keep the representation valid final Mutex _listenMutex = Mutex(debugLockTimeout: kIsDebugMode ? 60 : null); diff --git a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_cubit.dart b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_cubit.dart index 8bdda7c..ab56c77 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_cubit.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_cubit.dart @@ -8,7 +8,6 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart'; import 'package:meta/meta.dart'; import '../../../veilid_support.dart'; -import '../interfaces/refreshable_cubit.dart'; @immutable class DHTShortArrayElementState extends Equatable { diff --git a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_head.dart b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_head.dart index 4a2c79a..0aaed19 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_head.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_head.dart @@ -65,12 +65,9 @@ class _DHTShortArrayHead { }); } - Future delete() async { - await _headMutex.protect(() async { - // Will deep delete all linked records as they are children - await _headRecord.delete(); - }); - } + /// Returns true if the deletion was processed immediately + /// Returns false if the deletion was marked for later + Future delete() => _headMutex.protect(_headRecord.delete); Future operate(Future Function(_DHTShortArrayHead) closure) async => // ignore: prefer_expression_function_bodies diff --git a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_write.dart b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_write.dart index c52a7b2..f3e1ac3 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_write.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_write.dart @@ -40,7 +40,7 @@ class _DHTShortArrayWrite extends _DHTShortArrayRead } } if (!success) { - throw DHTExceptionOutdated(); + throw const DHTExceptionOutdated(); } } @@ -97,7 +97,7 @@ class _DHTShortArrayWrite extends _DHTShortArrayRead } } if (!success) { - throw DHTExceptionOutdated(); + throw const DHTExceptionOutdated(); } } diff --git a/packages/veilid_support/lib/dht_support/src/interfaces/dht_closeable.dart b/packages/veilid_support/lib/dht_support/src/interfaces/dht_closeable.dart index c913340..0fb10ab 100644 --- a/packages/veilid_support/lib/dht_support/src/interfaces/dht_closeable.dart +++ b/packages/veilid_support/lib/dht_support/src/interfaces/dht_closeable.dart @@ -4,7 +4,7 @@ import 'package:meta/meta.dart'; abstract class DHTCloseable { // Public interface - Future ref(); + void ref(); Future close(); // Internal implementation @@ -15,7 +15,9 @@ abstract class DHTCloseable { } abstract class DHTDeleteable extends DHTCloseable { - Future delete(); + /// Returns true if the deletion was processed immediately + /// Returns false if the deletion was marked for later + Future delete(); } extension DHTCloseableExt on DHTCloseable { diff --git a/pubspec.lock b/pubspec.lock index fa60f63..b4df49f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -156,10 +156,9 @@ packages: bloc_advanced_tools: dependency: "direct main" description: - name: bloc_advanced_tools - sha256: "977f3c7e3f9a19aec2f2c734ae99c8f0799c1b78f9fd7e4dce91a2dbf773e11b" - url: "https://pub.dev" - source: hosted + path: "../bloc_advanced_tools" + relative: true + source: path version: "0.1.9" blurry_modal_progress_hud: dependency: "direct main" diff --git a/pubspec.yaml b/pubspec.yaml index a37a8ab..b909a16 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -111,11 +111,11 @@ dependencies: xterm: ^4.0.0 zxing2: ^0.2.3 -# dependency_overrides: +dependency_overrides: # async_tools: # path: ../dart_async_tools -# bloc_advanced_tools: -# path: ../bloc_advanced_tools + bloc_advanced_tools: + path: ../bloc_advanced_tools # searchable_listview: # path: ../Searchable-Listview # flutter_chat_ui: From 739df7c427de01cf7131278597ae9d3bf7248dda Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 21 Mar 2025 14:50:17 -0400 Subject: [PATCH 3/6] dependency upgrades --- packages/veilid_support/example/.gitignore | 2 + .../example/integration_test/app_test.dart | 90 +++++++++---------- .../veilid_support/example/macos/Podfile.lock | 6 +- .../xcshareddata/xcschemes/Runner.xcscheme | 1 + .../example/macos/Runner/AppDelegate.swift | 4 + packages/veilid_support/example/pubspec.lock | 81 +++++++---------- packages/veilid_support/example/pubspec.yaml | 6 +- packages/veilid_support/pubspec.lock | 69 +++++++------- packages/veilid_support/pubspec.yaml | 46 +++++----- pubspec.lock | 83 ++++++++--------- pubspec.yaml | 37 ++++---- 11 files changed, 206 insertions(+), 219 deletions(-) diff --git a/packages/veilid_support/example/.gitignore b/packages/veilid_support/example/.gitignore index 29a3a50..79c113f 100644 --- a/packages/veilid_support/example/.gitignore +++ b/packages/veilid_support/example/.gitignore @@ -5,9 +5,11 @@ *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ migrate_working_dir/ # IntelliJ related diff --git a/packages/veilid_support/example/integration_test/app_test.dart b/packages/veilid_support/example/integration_test/app_test.dart index 6912fd3..5dc7acd 100644 --- a/packages/veilid_support/example/integration_test/app_test.dart +++ b/packages/veilid_support/example/integration_test/app_test.dart @@ -36,6 +36,51 @@ void main() { setUpAll(veilidFixture.attach); tearDownAll(veilidFixture.detach); + group('DHT Support Tests', () { + setUpAll(updateProcessorFixture.setUp); + setUpAll(tickerFixture.setUp); + tearDownAll(tickerFixture.tearDown); + tearDownAll(updateProcessorFixture.tearDown); + + test('create pool', testDHTRecordPoolCreate); + + group('DHTRecordPool Tests', () { + setUpAll(dhtRecordPoolFixture.setUp); + tearDownAll(dhtRecordPoolFixture.tearDown); + + test('create/delete record', testDHTRecordCreateDelete); + test('record scopes', testDHTRecordScopes); + test('create/delete deep record', testDHTRecordDeepCreateDelete); + }); + + group('DHTShortArray Tests', () { + setUpAll(dhtRecordPoolFixture.setUp); + tearDownAll(dhtRecordPoolFixture.tearDown); + + for (final stride in [256, 16 /*64, 32, 16, 8, 4, 2, 1 */]) { + test('create shortarray stride=$stride', + makeTestDHTShortArrayCreateDelete(stride: stride)); + test('add shortarray stride=$stride', + makeTestDHTShortArrayAdd(stride: stride)); + } + }); + + group('DHTLog Tests', () { + setUpAll(dhtRecordPoolFixture.setUp); + tearDownAll(dhtRecordPoolFixture.tearDown); + + for (final stride in [256, 16 /*64, 32, 16, 8, 4, 2, 1 */]) { + test('create log stride=$stride', + makeTestDHTLogCreateDelete(stride: stride)); + test( + timeout: const Timeout(Duration(seconds: 480)), + 'add/truncate log stride=$stride', + makeTestDHTLogAddTruncate(stride: stride), + ); + } + }); + }); + group('TableDB Tests', () { group('TableDBArray Tests', () { // test('create/delete TableDBArray', testTableDBArrayCreateDelete); @@ -146,51 +191,6 @@ void main() { }); }); }); - - group('DHT Support Tests', () { - setUpAll(updateProcessorFixture.setUp); - setUpAll(tickerFixture.setUp); - tearDownAll(tickerFixture.tearDown); - tearDownAll(updateProcessorFixture.tearDown); - - test('create pool', testDHTRecordPoolCreate); - - group('DHTRecordPool Tests', () { - setUpAll(dhtRecordPoolFixture.setUp); - tearDownAll(dhtRecordPoolFixture.tearDown); - - test('create/delete record', testDHTRecordCreateDelete); - test('record scopes', testDHTRecordScopes); - test('create/delete deep record', testDHTRecordDeepCreateDelete); - }); - - group('DHTShortArray Tests', () { - setUpAll(dhtRecordPoolFixture.setUp); - tearDownAll(dhtRecordPoolFixture.tearDown); - - for (final stride in [256, 16 /*64, 32, 16, 8, 4, 2, 1 */]) { - test('create shortarray stride=$stride', - makeTestDHTShortArrayCreateDelete(stride: stride)); - test('add shortarray stride=$stride', - makeTestDHTShortArrayAdd(stride: stride)); - } - }); - - group('DHTLog Tests', () { - setUpAll(dhtRecordPoolFixture.setUp); - tearDownAll(dhtRecordPoolFixture.tearDown); - - for (final stride in [256, 16 /*64, 32, 16, 8, 4, 2, 1 */]) { - test('create log stride=$stride', - makeTestDHTLogCreateDelete(stride: stride)); - test( - timeout: const Timeout(Duration(seconds: 480)), - 'add/truncate log stride=$stride', - makeTestDHTLogAddTruncate(stride: stride), - ); - } - }); - }); }); }); } diff --git a/packages/veilid_support/example/macos/Podfile.lock b/packages/veilid_support/example/macos/Podfile.lock index 6a58494..a2618bd 100644 --- a/packages/veilid_support/example/macos/Podfile.lock +++ b/packages/veilid_support/example/macos/Podfile.lock @@ -21,9 +21,9 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - veilid: a54f57b7bcf0e4e072fe99272d76ca126b2026d0 + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + veilid: 319e2e78836d7b3d08203596d0b4a0e244b68d29 PODFILE CHECKSUM: 16208599a12443d53889ba2270a4985981cfb204 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/packages/veilid_support/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/veilid_support/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 15368ec..ac78810 100644 --- a/packages/veilid_support/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/veilid_support/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -59,6 +59,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/packages/veilid_support/example/macos/Runner/AppDelegate.swift b/packages/veilid_support/example/macos/Runner/AppDelegate.swift index 8e02df2..b3c1761 100644 --- a/packages/veilid_support/example/macos/Runner/AppDelegate.swift +++ b/packages/veilid_support/example/macos/Runner/AppDelegate.swift @@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } } diff --git a/packages/veilid_support/example/pubspec.lock b/packages/veilid_support/example/pubspec.lock index 3844db3..6ef291b 100644 --- a/packages/veilid_support/example/pubspec.lock +++ b/packages/veilid_support/example/pubspec.lock @@ -5,31 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + sha256: dc27559385e905ad30838356c5f5d574014ba39872d732111cd07ac0beff4c57 url: "https://pub.dev" source: hosted - version: "76.0.0" - _macros: - dependency: transitive - description: dart - source: sdk - version: "0.3.3" + version: "80.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + sha256: "192d1c5b944e7e53b24b5586db760db934b177d4147c42fbca8c8c5f1eb8d11e" url: "https://pub.dev" source: hosted - version: "6.11.0" + version: "7.3.0" args: dependency: transitive description: name: args - sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" async: dependency: transitive description: @@ -42,26 +37,26 @@ packages: dependency: "direct dev" description: name: async_tools - sha256: bbded696bfcb1437d0ca510ac047f261f9c7494fea2c488dd32ba2800e7f49e8 + sha256: afd5426e76631172f8ce6a6359b264b092fa9d2a52cd2528100115be9525e067 url: "https://pub.dev" source: hosted - version: "0.1.7" + version: "0.1.9" bloc: dependency: transitive description: name: bloc - sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e" + sha256: "52c10575f4445c61dd9e0cafcc6356fdd827c4c64dd7945ef3c4105f6b6ac189" url: "https://pub.dev" source: hosted - version: "8.1.4" + version: "9.0.0" bloc_advanced_tools: dependency: transitive description: name: bloc_advanced_tools - sha256: d8a680d8a0469456399fb26bae9f7a1d2a1420b5bdf75e204e0fadab9edb0811 + sha256: "7c7f294b425552c2d4831b01ad0d3e1f33f2bdf9acfb7b639caa072781d228cf" url: "https://pub.dev" source: hosted - version: "0.1.8" + version: "0.1.10" boolean_selector: dependency: transitive description: @@ -162,18 +157,18 @@ packages: dependency: transitive description: name: fast_immutable_collections - sha256: c3c73f4f989d3302066e4ec94e6ec73b5dc872592d02194f49f1352d64126b8c + sha256: "95a69b9380483dff49ae2c12c9eb92e2b4e1aeff481a33c2a20883471771598a" url: "https://pub.dev" source: hosted - version: "10.2.4" + version: "11.0.3" ffi: dependency: transitive description: name: ffi - sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" file: dependency: transitive description: @@ -214,10 +209,10 @@ packages: dependency: transitive description: name: freezed_annotation - sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "3.0.0" frontend_server_client: dependency: transitive description: @@ -280,10 +275,10 @@ packages: dependency: transitive description: name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "0.7.2" json_annotation: dependency: transitive description: @@ -320,10 +315,10 @@ packages: dependency: "direct dev" description: name: lint_hard - sha256: "638d2cce6d3d5499826be71311d18cded797a51351eaa1aee7a35a2f0f9bc46e" + sha256: ffe7058cb49e021d244d67e650a63380445b56643c2849c6929e938246b99058 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "6.0.0" logging: dependency: transitive description: @@ -340,14 +335,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" - macros: - dependency: transitive - description: - name: macros - sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" - url: "https://pub.dev" - source: hosted - version: "0.1.3-main.0" matcher: dependency: transitive description: @@ -392,10 +379,10 @@ packages: dependency: transitive description: name: package_config - sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.2.0" path: dependency: transitive description: @@ -416,10 +403,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" + sha256: "0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12" url: "https://pub.dev" source: hosted - version: "2.2.15" + version: "2.2.16" path_provider_foundation: dependency: transitive description: @@ -496,10 +483,10 @@ packages: dependency: transitive description: name: pub_semver - sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.2.0" shelf: dependency: transitive description: @@ -528,10 +515,10 @@ packages: dependency: transitive description: name: shelf_web_socket - sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.0" sky_engine: dependency: transitive description: flutter @@ -698,10 +685,10 @@ packages: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" web_socket: dependency: transitive description: @@ -751,5 +738,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.7.0-0 <4.0.0" - flutter: ">=3.24.0" + dart: ">=3.7.0 <4.0.0" + flutter: ">=3.27.0" diff --git a/packages/veilid_support/example/pubspec.yaml b/packages/veilid_support/example/pubspec.yaml index c043a1b..b8333e6 100644 --- a/packages/veilid_support/example/pubspec.yaml +++ b/packages/veilid_support/example/pubspec.yaml @@ -14,11 +14,11 @@ dependencies: path: ../ dev_dependencies: - async_tools: ^0.1.6 + async_tools: ^0.1.9 integration_test: sdk: flutter - lint_hard: ^5.0.0 - test: ^1.25.2 + lint_hard: ^6.0.0 + test: ^1.25.15 veilid_test: path: ../../../../veilid/veilid-flutter/packages/veilid_test diff --git a/packages/veilid_support/pubspec.lock b/packages/veilid_support/pubspec.lock index 447a27c..e3dfcdd 100644 --- a/packages/veilid_support/pubspec.lock +++ b/packages/veilid_support/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: args - sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" async: dependency: transitive description: @@ -36,26 +36,27 @@ packages: async_tools: dependency: "direct main" description: - path: "../../../dart_async_tools" - relative: true - source: path - version: "0.1.7" + name: async_tools + sha256: afd5426e76631172f8ce6a6359b264b092fa9d2a52cd2528100115be9525e067 + url: "https://pub.dev" + source: hosted + version: "0.1.9" bloc: dependency: "direct main" description: name: bloc - sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e" + sha256: "52c10575f4445c61dd9e0cafcc6356fdd827c4c64dd7945ef3c4105f6b6ac189" url: "https://pub.dev" source: hosted - version: "8.1.4" + version: "9.0.0" bloc_advanced_tools: dependency: "direct main" description: name: bloc_advanced_tools - sha256: d8a680d8a0469456399fb26bae9f7a1d2a1420b5bdf75e204e0fadab9edb0811 + sha256: "7c7f294b425552c2d4831b01ad0d3e1f33f2bdf9acfb7b639caa072781d228cf" url: "https://pub.dev" source: hosted - version: "0.1.8" + version: "0.1.10" boolean_selector: dependency: transitive description: @@ -124,10 +125,10 @@ packages: dependency: transitive description: name: built_value - sha256: "28a712df2576b63c6c005c465989a348604960c0958d28be5303ba9baa841ac2" + sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4 url: "https://pub.dev" source: hosted - version: "8.9.3" + version: "8.9.5" change_case: dependency: transitive description: @@ -220,18 +221,18 @@ packages: dependency: "direct main" description: name: fast_immutable_collections - sha256: c3c73f4f989d3302066e4ec94e6ec73b5dc872592d02194f49f1352d64126b8c + sha256: "95a69b9380483dff49ae2c12c9eb92e2b4e1aeff481a33c2a20883471771598a" url: "https://pub.dev" source: hosted - version: "10.2.4" + version: "11.0.3" ffi: dependency: transitive description: name: ffi - sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" file: dependency: transitive description: @@ -262,18 +263,18 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c" + sha256: "7ed2ddaa47524976d5f2aa91432a79da36a76969edd84170777ac5bea82d797c" url: "https://pub.dev" source: hosted - version: "2.5.8" + version: "3.0.4" freezed_annotation: dependency: "direct main" description: name: freezed_annotation - sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "3.0.0" frontend_server_client: dependency: transitive description: @@ -342,10 +343,10 @@ packages: dependency: transitive description: name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "0.7.2" json_annotation: dependency: "direct main" description: @@ -366,10 +367,10 @@ packages: dependency: "direct dev" description: name: lint_hard - sha256: "638d2cce6d3d5499826be71311d18cded797a51351eaa1aee7a35a2f0f9bc46e" + sha256: ffe7058cb49e021d244d67e650a63380445b56643c2849c6929e938246b99058 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "6.0.0" logging: dependency: transitive description: @@ -430,10 +431,10 @@ packages: dependency: transitive description: name: package_config - sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67" + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.2.0" path: dependency: "direct main" description: @@ -454,10 +455,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" + sha256: "0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12" url: "https://pub.dev" source: hosted - version: "2.2.15" + version: "2.2.16" path_provider_foundation: dependency: transitive description: @@ -526,10 +527,10 @@ packages: dependency: transitive description: name: pub_semver - sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd" + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.2.0" pubspec_parse: dependency: transitive description: @@ -746,10 +747,10 @@ packages: dependency: transitive description: name: web - sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" web_socket: dependency: transitive description: @@ -791,5 +792,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.7.0-0 <4.0.0" - flutter: ">=3.24.0" + dart: ">=3.7.0 <4.0.0" + flutter: ">=3.27.0" diff --git a/packages/veilid_support/pubspec.yaml b/packages/veilid_support/pubspec.yaml index bcd965d..5aff89e 100644 --- a/packages/veilid_support/pubspec.yaml +++ b/packages/veilid_support/pubspec.yaml @@ -1,40 +1,40 @@ name: veilid_support description: Veilid Support Library -publish_to: 'none' +publish_to: "none" version: 1.0.2+0 environment: - sdk: '>=3.2.0 <4.0.0' + sdk: ">=3.2.0 <4.0.0" dependencies: - async_tools: ^0.1.7 - bloc: ^8.1.4 - bloc_advanced_tools: ^0.1.8 - charcode: ^1.3.1 - collection: ^1.18.0 - equatable: ^2.0.5 - fast_immutable_collections: ^10.2.3 - freezed_annotation: ^2.4.1 + async_tools: ^0.1.9 + bloc: ^9.0.0 + bloc_advanced_tools: ^0.1.10 + charcode: ^1.4.0 + collection: ^1.19.1 + equatable: ^2.0.7 + fast_immutable_collections: ^11.0.3 + freezed_annotation: ^3.0.0 json_annotation: ^4.9.0 loggy: ^2.0.3 - meta: ^1.12.0 + meta: ^1.16.0 - path: ^1.9.0 - path_provider: ^2.1.3 + path: ^1.9.1 + path_provider: ^2.1.5 protobuf: ^3.1.0 veilid: # veilid: ^0.0.1 path: ../../../veilid/veilid-flutter -dependency_overrides: - async_tools: - path: ../../../dart_async_tools -# bloc_advanced_tools: -# path: ../../../bloc_advanced_tools +# dependency_overrides: +# async_tools: +# path: ../../../dart_async_tools +# bloc_advanced_tools: +# path: ../../../bloc_advanced_tools dev_dependencies: - build_runner: ^2.4.10 - freezed: ^2.5.2 - json_serializable: ^6.8.0 - lint_hard: ^5.0.0 - test: ^1.25.2 + build_runner: ^2.4.15 + freezed: ^3.0.4 + json_serializable: ^6.9.4 + lint_hard: ^6.0.0 + test: ^1.25.15 diff --git a/pubspec.lock b/pubspec.lock index b4df49f..ea4a216 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -93,10 +93,10 @@ packages: dependency: "direct main" description: name: async_tools - sha256: a258558160d6adc18612d0c635ce0d18ceabc022f7933ce78ca4806075d79578 + sha256: afd5426e76631172f8ce6a6359b264b092fa9d2a52cd2528100115be9525e067 url: "https://pub.dev" source: hosted - version: "0.1.8" + version: "0.1.9" auto_size_text: dependency: "direct main" description: @@ -149,17 +149,18 @@ packages: dependency: "direct main" description: name: bloc - sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e" + sha256: "52c10575f4445c61dd9e0cafcc6356fdd827c4c64dd7945ef3c4105f6b6ac189" url: "https://pub.dev" source: hosted - version: "8.1.4" + version: "9.0.0" bloc_advanced_tools: dependency: "direct main" description: - path: "../bloc_advanced_tools" - relative: true - source: path - version: "0.1.9" + name: bloc_advanced_tools + sha256: "7c7f294b425552c2d4831b01ad0d3e1f33f2bdf9acfb7b639caa072781d228cf" + url: "https://pub.dev" + source: hosted + version: "0.1.10" blurry_modal_progress_hud: dependency: "direct main" description: @@ -284,10 +285,10 @@ packages: dependency: transitive description: name: camera_avfoundation - sha256: "3057ada0b30402e3a9b6dffec365c9736a36edbf04abaecc67c4309eadc86b49" + sha256: ba48b65a3a97004276ede882e6b838d9667642ff462c95a8bb57ca8a82b6bd25 url: "https://pub.dev" source: hosted - version: "0.9.18+9" + version: "0.9.18+11" camera_platform_interface: dependency: transitive description: @@ -476,10 +477,10 @@ packages: dependency: "direct main" description: name: fast_immutable_collections - sha256: c3c73f4f989d3302066e4ec94e6ec73b5dc872592d02194f49f1352d64126b8c + sha256: "95a69b9380483dff49ae2c12c9eb92e2b4e1aeff481a33c2a20883471771598a" url: "https://pub.dev" source: hosted - version: "10.2.4" + version: "11.0.3" ffi: dependency: transitive description: @@ -529,10 +530,10 @@ packages: dependency: "direct main" description: name: flutter_bloc - sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a + sha256: "1046d719fbdf230330d3443187cc33cc11963d15c9089f6cc56faa42a4c5f0cc" url: "https://pub.dev" source: hosted - version: "8.1.6" + version: "9.1.0" flutter_cache_manager: dependency: transitive description: @@ -562,18 +563,18 @@ packages: dependency: "direct main" description: name: flutter_form_builder - sha256: "375da52998c72f80dec9187bd93afa7ab202b89d5d066699368ff96d39fd4876" + sha256: aa3901466c70b69ae6c7f3d03fcbccaec5fde179d3fded0b10203144b546ad28 url: "https://pub.dev" source: hosted - version: "9.7.0" + version: "10.0.1" flutter_hooks: dependency: "direct main" description: name: flutter_hooks - sha256: cde36b12f7188c85286fba9b38cc5a902e7279f36dd676967106c041dc9dde70 + sha256: b772e710d16d7a20c0740c4f855095026b31c7eb5ba3ab67d2bd52021cd9461d url: "https://pub.dev" source: hosted - version: "0.20.5" + version: "0.21.2" flutter_link_previewer: dependency: transitive description: @@ -692,18 +693,18 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c" + sha256: "7ed2ddaa47524976d5f2aa91432a79da36a76969edd84170777ac5bea82d797c" url: "https://pub.dev" source: hosted - version: "2.5.8" + version: "3.0.4" freezed_annotation: dependency: "direct main" description: name: freezed_annotation - sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "3.0.0" frontend_server_client: dependency: transitive description: @@ -752,14 +753,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" - hive: - dependency: transitive - description: - name: hive - sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" - url: "https://pub.dev" - source: hosted - version: "2.2.3" html: dependency: transitive description: @@ -792,14 +785,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" - hydrated_bloc: - dependency: "direct main" - description: - name: hydrated_bloc - sha256: af35b357739fe41728df10bec03aad422cdc725a1e702e03af9d2a41ea05160c - url: "https://pub.dev" - source: hosted - version: "9.1.5" icons_launcher: dependency: "direct dev" description: @@ -876,10 +861,10 @@ packages: dependency: "direct dev" description: name: lint_hard - sha256: "638d2cce6d3d5499826be71311d18cded797a51351eaa1aee7a35a2f0f9bc46e" + sha256: ffe7058cb49e021d244d67e650a63380445b56643c2849c6929e938246b99058 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "6.0.0" logging: dependency: transitive description: @@ -1192,14 +1177,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + qr_code_dart_decoder: + dependency: transitive + description: + name: qr_code_dart_decoder + sha256: "6da7eda27726d504bed3c30eabf78ddca3eb9265e1c8dc49b30ef5974b9c267f" + url: "https://pub.dev" + source: hosted + version: "0.0.5" qr_code_dart_scan: dependency: "direct main" description: name: qr_code_dart_scan - sha256: a21340c4a2ca14e2e114915940fcad166f15c1a065fed8b4fede4a4aba5bc4ff + sha256: bc4fc6f400b4350c6946d123c7871e156459703a61f8fa57d7144df9bbb46610 url: "https://pub.dev" source: hosted - version: "0.9.11" + version: "0.10.0" qr_flutter: dependency: "direct main" description: @@ -1418,10 +1411,10 @@ packages: dependency: "direct main" description: name: sliver_expandable - sha256: ae20eb848bd0ba9dd704732ad654438ac5a5bea2b023fa3cf80a086166d96d97 + sha256: "046d8912ebd072bf9d8e8161e50a4669c520f691fce8bfcbae4ada6982b18ba3" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" sliver_fill_remaining_box_adapter: dependency: "direct main" description: @@ -1895,4 +1888,4 @@ packages: version: "1.1.2" sdks: dart: ">=3.7.0 <4.0.0" - flutter: ">=3.27.0" + flutter: ">=3.29.0" diff --git a/pubspec.yaml b/pubspec.yaml index b909a16..379d2f2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,13 +15,13 @@ dependencies: animated_theme_switcher: ^2.0.10 ansicolor: ^2.0.3 archive: ^4.0.4 - async_tools: ^0.1.8 + async_tools: ^0.1.9 auto_size_text: ^3.0.0 awesome_extensions: ^2.0.21 badges: ^3.1.2 basic_utils: ^5.8.2 - bloc: ^8.1.4 - bloc_advanced_tools: ^0.1.9 + bloc: ^9.0.0 + bloc_advanced_tools: ^0.1.10 blurry_modal_progress_hud: ^1.1.1 change_case: ^2.2.0 charcode: ^1.4.0 @@ -30,20 +30,20 @@ dependencies: cupertino_icons: ^1.0.8 equatable: ^2.0.7 expansion_tile_group: ^2.2.0 - fast_immutable_collections: ^10.2.4 + fast_immutable_collections: ^11.0.3 file_saver: ^0.2.14 fixnum: ^1.1.1 flutter: sdk: flutter flutter_animate: ^4.5.2 - flutter_bloc: ^8.1.6 + flutter_bloc: ^9.1.0 flutter_chat_types: ^3.6.2 flutter_chat_ui: git: url: https://gitlab.com/veilid/flutter-chat-ui.git ref: main - flutter_form_builder: ^9.7.0 - flutter_hooks: ^0.20.5 + flutter_form_builder: ^10.0.1 + flutter_hooks: ^0.21.2 flutter_localizations: sdk: flutter flutter_native_splash: ^2.4.5 @@ -54,9 +54,8 @@ dependencies: flutter_translate: ^4.1.0 flutter_zoom_drawer: ^3.2.0 form_builder_validators: ^11.1.2 - freezed_annotation: ^2.4.4 + freezed_annotation: ^3.0.0 go_router: ^14.8.1 - hydrated_bloc: ^9.1.5 image: ^4.5.3 intl: ^0.19.0 json_annotation: ^4.9.0 @@ -73,7 +72,7 @@ dependencies: printing: ^5.14.2 protobuf: ^3.1.0 provider: ^6.1.2 - qr_code_dart_scan: ^0.9.11 + qr_code_dart_scan: ^0.10.0 qr_flutter: ^4.1.0 radix_colors: ^1.0.4 reorderable_grid: ^1.0.10 @@ -87,7 +86,7 @@ dependencies: share_plus: ^10.1.4 shared_preferences: ^2.5.2 signal_strength_indicator: ^0.4.1 - sliver_expandable: ^1.1.1 + sliver_expandable: ^1.1.2 sliver_fill_remaining_box_adapter: ^1.0.0 sliver_tools: ^0.2.12 sorted_list: @@ -111,22 +110,22 @@ dependencies: xterm: ^4.0.0 zxing2: ^0.2.3 -dependency_overrides: +# dependency_overrides: # async_tools: # path: ../dart_async_tools - bloc_advanced_tools: - path: ../bloc_advanced_tools -# searchable_listview: -# path: ../Searchable-Listview +# bloc_advanced_tools: +# path: ../bloc_advanced_tools +# searchable_listview: +# path: ../Searchable-Listview # flutter_chat_ui: -# path: ../flutter_chat_ui +# path: ../flutter_chat_ui dev_dependencies: build_runner: ^2.4.15 - freezed: ^2.5.8 + freezed: ^3.0.4 icons_launcher: ^3.0.1 json_serializable: ^6.9.4 - lint_hard: ^5.0.0 + lint_hard: ^6.0.0 flutter_native_splash: color: "#8588D0" From d6b1c2090609545297adf3fb1bec18f7e09b0444 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 22 Mar 2025 21:43:37 -0400 Subject: [PATCH 4/6] debugging work --- lib/account_manager/models/account_info.dart | 9 +- .../models/local_account/local_account.dart | 2 +- .../local_account/local_account.freezed.dart | 488 ++++++----- .../models/local_account/local_account.g.dart | 6 +- .../per_account_collection_state.dart | 22 +- .../per_account_collection_state.freezed.dart | 665 +++++++-------- .../models/user_login/user_login.dart | 2 +- .../models/user_login/user_login.freezed.dart | 398 +++++---- .../models/user_login/user_login.g.dart | 5 +- lib/chat/cubits/chat_component_cubit.dart | 10 +- lib/chat/models/chat_component_state.dart | 2 +- .../models/chat_component_state.freezed.dart | 361 ++++----- lib/chat/models/message_state.dart | 2 +- lib/chat/models/message_state.freezed.dart | 257 +++--- lib/chat/models/message_state.g.dart | 6 +- lib/chat/models/window_state.dart | 2 +- lib/chat/models/window_state.freezed.dart | 264 +++--- lib/chat_list/cubits/chat_list_cubit.dart | 2 +- lib/chat_list/views/chat_list_widget.dart | 4 +- .../cubits/contact_invitation_list_cubit.dart | 2 +- .../waiting_invitations_bloc_map_cubit.dart | 2 +- .../models/notifications_preference.dart | 2 +- .../notifications_preference.freezed.dart | 565 +++++++------ .../models/notifications_preference.g.dart | 8 +- .../models/notifications_state.dart | 4 +- .../models/notifications_state.freezed.dart | 452 ++++++----- lib/proto/proto.dart | 292 +++++++ lib/proto/veilidchat.pb.dart | 20 +- lib/proto/veilidchat.pbjson.dart | 35 +- lib/proto/veilidchat.proto | 1 + lib/router/cubits/router_cubit.dart | 2 +- lib/router/cubits/router_cubit.freezed.dart | 241 +++--- lib/router/cubits/router_cubit.g.dart | 5 +- lib/settings/models/preferences.dart | 4 +- lib/settings/models/preferences.freezed.dart | 761 +++++++++--------- lib/settings/models/preferences.g.dart | 12 +- lib/theme/models/theme_preference.dart | 2 +- .../models/theme_preference.freezed.dart | 356 ++++---- lib/theme/models/theme_preference.g.dart | 8 +- lib/tools/loggy.dart | 6 + lib/tools/state_logger.dart | 10 +- .../models/processor_connection_state.dart | 2 +- .../processor_connection_state.freezed.dart | 317 ++++---- .../lib/dht_support/proto/proto.dart | 42 + .../src/dht_log/dht_log_cubit.dart | 8 + .../src/dht_log/dht_log_spine.dart | 5 +- .../src/dht_record/dht_record.dart | 4 +- .../src/dht_record/dht_record_pool.dart | 45 +- .../dht_record/dht_record_pool.freezed.dart | 623 +++++++------- .../src/dht_record/dht_record_pool.g.dart | 16 +- .../src/dht_record/extensions.dart | 57 ++ .../dht_short_array_cubit.dart | 23 +- .../dht_short_array/dht_short_array_head.dart | 10 +- .../dht_short_array_write.dart | 4 +- .../identity_support/account_record_info.dart | 2 +- .../account_record_info.freezed.dart | 277 +++---- .../account_record_info.g.dart | 8 +- .../lib/identity_support/identity.dart | 2 +- .../identity_support/identity.freezed.dart | 231 +++--- .../lib/identity_support/identity.g.dart | 6 +- .../identity_support/identity_instance.dart | 2 +- .../identity_instance.freezed.dart | 284 +++---- .../identity_support/identity_instance.g.dart | 8 +- .../lib/identity_support/super_identity.dart | 2 +- .../super_identity.freezed.dart | 330 ++++---- .../identity_support/super_identity.g.dart | 6 +- packages/veilid_support/lib/proto/proto.dart | 24 + .../veilid_support/lib/src/dynamic_debug.dart | 130 +++ .../veilid_support/lib/veilid_support.dart | 3 +- packages/veilid_support/pubspec.lock | 2 +- packages/veilid_support/pubspec.yaml | 1 + 71 files changed, 4155 insertions(+), 3616 deletions(-) create mode 100644 packages/veilid_support/lib/dht_support/src/dht_record/extensions.dart create mode 100644 packages/veilid_support/lib/src/dynamic_debug.dart diff --git a/lib/account_manager/models/account_info.dart b/lib/account_manager/models/account_info.dart index 12ed5e1..8f57add 100644 --- a/lib/account_manager/models/account_info.dart +++ b/lib/account_manager/models/account_info.dart @@ -13,7 +13,7 @@ enum AccountInfoStatus { } @immutable -class AccountInfo extends Equatable { +class AccountInfo extends Equatable implements ToDebugMap { const AccountInfo({ required this.status, required this.localAccount, @@ -30,6 +30,13 @@ class AccountInfo extends Equatable { localAccount, userLogin, ]; + + @override + Map toDebugMap() => { + 'status': status, + 'localAccount': localAccount, + 'userLogin': userLogin, + }; } extension AccountInfoExt on AccountInfo { diff --git a/lib/account_manager/models/local_account/local_account.dart b/lib/account_manager/models/local_account/local_account.dart index 76070ae..1ec6d22 100644 --- a/lib/account_manager/models/local_account/local_account.dart +++ b/lib/account_manager/models/local_account/local_account.dart @@ -16,7 +16,7 @@ part 'local_account.freezed.dart'; // This is the root of the account information tree for VeilidChat // @freezed -class LocalAccount with _$LocalAccount { +sealed class LocalAccount with _$LocalAccount { const factory LocalAccount({ // The super identity key record for the account, // containing the publicKey in the currentIdentity diff --git a/lib/account_manager/models/local_account/local_account.freezed.dart b/lib/account_manager/models/local_account/local_account.freezed.dart index effc69a..e2c3c55 100644 --- a/lib/account_manager/models/local_account/local_account.freezed.dart +++ b/lib/account_manager/models/local_account/local_account.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,238 +10,43 @@ part of 'local_account.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -LocalAccount _$LocalAccountFromJson(Map json) { - return _LocalAccount.fromJson(json); -} - /// @nodoc mixin _$LocalAccount { // The super identity key record for the account, // containing the publicKey in the currentIdentity - SuperIdentity get superIdentity => - throw _privateConstructorUsedError; // The encrypted currentIdentity secret that goes with + SuperIdentity + get superIdentity; // The encrypted currentIdentity secret that goes with // the identityPublicKey with appended salt @Uint8ListJsonConverter() - Uint8List get identitySecretBytes => - throw _privateConstructorUsedError; // The kind of encryption input used on the account - EncryptionKeyType get encryptionKeyType => - throw _privateConstructorUsedError; // If account is not hidden, password can be retrieved via - bool get biometricsEnabled => - throw _privateConstructorUsedError; // Keep account hidden unless account password is entered + Uint8List + get identitySecretBytes; // The kind of encryption input used on the account + EncryptionKeyType + get encryptionKeyType; // If account is not hidden, password can be retrieved via + bool + get biometricsEnabled; // Keep account hidden unless account password is entered // (tries all hidden accounts with auth method (no biometrics)) - bool get hiddenAccount => - throw _privateConstructorUsedError; // Display name for account until it is unlocked - String get name => throw _privateConstructorUsedError; - - /// Serializes this LocalAccount to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + bool get hiddenAccount; // Display name for account until it is unlocked + String get name; /// Create a copy of LocalAccount /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $LocalAccountCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$LocalAccountCopyWithImpl( + this as LocalAccount, _$identity); -/// @nodoc -abstract class $LocalAccountCopyWith<$Res> { - factory $LocalAccountCopyWith( - LocalAccount value, $Res Function(LocalAccount) then) = - _$LocalAccountCopyWithImpl<$Res, LocalAccount>; - @useResult - $Res call( - {SuperIdentity superIdentity, - @Uint8ListJsonConverter() Uint8List identitySecretBytes, - EncryptionKeyType encryptionKeyType, - bool biometricsEnabled, - bool hiddenAccount, - String name}); - - $SuperIdentityCopyWith<$Res> get superIdentity; -} - -/// @nodoc -class _$LocalAccountCopyWithImpl<$Res, $Val extends LocalAccount> - implements $LocalAccountCopyWith<$Res> { - _$LocalAccountCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of LocalAccount - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? superIdentity = null, - Object? identitySecretBytes = null, - Object? encryptionKeyType = null, - Object? biometricsEnabled = null, - Object? hiddenAccount = null, - Object? name = null, - }) { - return _then(_value.copyWith( - superIdentity: null == superIdentity - ? _value.superIdentity - : superIdentity // ignore: cast_nullable_to_non_nullable - as SuperIdentity, - identitySecretBytes: null == identitySecretBytes - ? _value.identitySecretBytes - : identitySecretBytes // ignore: cast_nullable_to_non_nullable - as Uint8List, - encryptionKeyType: null == encryptionKeyType - ? _value.encryptionKeyType - : encryptionKeyType // ignore: cast_nullable_to_non_nullable - as EncryptionKeyType, - biometricsEnabled: null == biometricsEnabled - ? _value.biometricsEnabled - : biometricsEnabled // ignore: cast_nullable_to_non_nullable - as bool, - hiddenAccount: null == hiddenAccount - ? _value.hiddenAccount - : hiddenAccount // ignore: cast_nullable_to_non_nullable - as bool, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - ) as $Val); - } - - /// Create a copy of LocalAccount - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $SuperIdentityCopyWith<$Res> get superIdentity { - return $SuperIdentityCopyWith<$Res>(_value.superIdentity, (value) { - return _then(_value.copyWith(superIdentity: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$LocalAccountImplCopyWith<$Res> - implements $LocalAccountCopyWith<$Res> { - factory _$$LocalAccountImplCopyWith( - _$LocalAccountImpl value, $Res Function(_$LocalAccountImpl) then) = - __$$LocalAccountImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {SuperIdentity superIdentity, - @Uint8ListJsonConverter() Uint8List identitySecretBytes, - EncryptionKeyType encryptionKeyType, - bool biometricsEnabled, - bool hiddenAccount, - String name}); - - @override - $SuperIdentityCopyWith<$Res> get superIdentity; -} - -/// @nodoc -class __$$LocalAccountImplCopyWithImpl<$Res> - extends _$LocalAccountCopyWithImpl<$Res, _$LocalAccountImpl> - implements _$$LocalAccountImplCopyWith<$Res> { - __$$LocalAccountImplCopyWithImpl( - _$LocalAccountImpl _value, $Res Function(_$LocalAccountImpl) _then) - : super(_value, _then); - - /// Create a copy of LocalAccount - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? superIdentity = null, - Object? identitySecretBytes = null, - Object? encryptionKeyType = null, - Object? biometricsEnabled = null, - Object? hiddenAccount = null, - Object? name = null, - }) { - return _then(_$LocalAccountImpl( - superIdentity: null == superIdentity - ? _value.superIdentity - : superIdentity // ignore: cast_nullable_to_non_nullable - as SuperIdentity, - identitySecretBytes: null == identitySecretBytes - ? _value.identitySecretBytes - : identitySecretBytes // ignore: cast_nullable_to_non_nullable - as Uint8List, - encryptionKeyType: null == encryptionKeyType - ? _value.encryptionKeyType - : encryptionKeyType // ignore: cast_nullable_to_non_nullable - as EncryptionKeyType, - biometricsEnabled: null == biometricsEnabled - ? _value.biometricsEnabled - : biometricsEnabled // ignore: cast_nullable_to_non_nullable - as bool, - hiddenAccount: null == hiddenAccount - ? _value.hiddenAccount - : hiddenAccount // ignore: cast_nullable_to_non_nullable - as bool, - name: null == name - ? _value.name - : name // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$LocalAccountImpl implements _LocalAccount { - const _$LocalAccountImpl( - {required this.superIdentity, - @Uint8ListJsonConverter() required this.identitySecretBytes, - required this.encryptionKeyType, - required this.biometricsEnabled, - required this.hiddenAccount, - required this.name}); - - factory _$LocalAccountImpl.fromJson(Map json) => - _$$LocalAccountImplFromJson(json); - -// The super identity key record for the account, -// containing the publicKey in the currentIdentity - @override - final SuperIdentity superIdentity; -// The encrypted currentIdentity secret that goes with -// the identityPublicKey with appended salt - @override - @Uint8ListJsonConverter() - final Uint8List identitySecretBytes; -// The kind of encryption input used on the account - @override - final EncryptionKeyType encryptionKeyType; -// If account is not hidden, password can be retrieved via - @override - final bool biometricsEnabled; -// Keep account hidden unless account password is entered -// (tries all hidden accounts with auth method (no biometrics)) - @override - final bool hiddenAccount; -// Display name for account until it is unlocked - @override - final String name; - - @override - String toString() { - return 'LocalAccount(superIdentity: $superIdentity, identitySecretBytes: $identitySecretBytes, encryptionKeyType: $encryptionKeyType, biometricsEnabled: $biometricsEnabled, hiddenAccount: $hiddenAccount, name: $name)'; - } + /// Serializes this LocalAccount to a JSON map. + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$LocalAccountImpl && + other is LocalAccount && (identical(other.superIdentity, superIdentity) || other.superIdentity == superIdentity) && const DeepCollectionEquality() @@ -265,60 +71,250 @@ class _$LocalAccountImpl implements _LocalAccount { hiddenAccount, name); - /// Create a copy of LocalAccount - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$LocalAccountImplCopyWith<_$LocalAccountImpl> get copyWith => - __$$LocalAccountImplCopyWithImpl<_$LocalAccountImpl>(this, _$identity); - - @override - Map toJson() { - return _$$LocalAccountImplToJson( - this, - ); + String toString() { + return 'LocalAccount(superIdentity: $superIdentity, identitySecretBytes: $identitySecretBytes, encryptionKeyType: $encryptionKeyType, biometricsEnabled: $biometricsEnabled, hiddenAccount: $hiddenAccount, name: $name)'; } } -abstract class _LocalAccount implements LocalAccount { - const factory _LocalAccount( - {required final SuperIdentity superIdentity, - @Uint8ListJsonConverter() required final Uint8List identitySecretBytes, - required final EncryptionKeyType encryptionKeyType, - required final bool biometricsEnabled, - required final bool hiddenAccount, - required final String name}) = _$LocalAccountImpl; +/// @nodoc +abstract mixin class $LocalAccountCopyWith<$Res> { + factory $LocalAccountCopyWith( + LocalAccount value, $Res Function(LocalAccount) _then) = + _$LocalAccountCopyWithImpl; + @useResult + $Res call( + {SuperIdentity superIdentity, + @Uint8ListJsonConverter() Uint8List identitySecretBytes, + EncryptionKeyType encryptionKeyType, + bool biometricsEnabled, + bool hiddenAccount, + String name}); - factory _LocalAccount.fromJson(Map json) = - _$LocalAccountImpl.fromJson; + $SuperIdentityCopyWith<$Res> get superIdentity; +} + +/// @nodoc +class _$LocalAccountCopyWithImpl<$Res> implements $LocalAccountCopyWith<$Res> { + _$LocalAccountCopyWithImpl(this._self, this._then); + + final LocalAccount _self; + final $Res Function(LocalAccount) _then; + + /// Create a copy of LocalAccount + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? superIdentity = null, + Object? identitySecretBytes = null, + Object? encryptionKeyType = null, + Object? biometricsEnabled = null, + Object? hiddenAccount = null, + Object? name = null, + }) { + return _then(_self.copyWith( + superIdentity: null == superIdentity + ? _self.superIdentity + : superIdentity // ignore: cast_nullable_to_non_nullable + as SuperIdentity, + identitySecretBytes: null == identitySecretBytes + ? _self.identitySecretBytes + : identitySecretBytes // ignore: cast_nullable_to_non_nullable + as Uint8List, + encryptionKeyType: null == encryptionKeyType + ? _self.encryptionKeyType + : encryptionKeyType // ignore: cast_nullable_to_non_nullable + as EncryptionKeyType, + biometricsEnabled: null == biometricsEnabled + ? _self.biometricsEnabled + : biometricsEnabled // ignore: cast_nullable_to_non_nullable + as bool, + hiddenAccount: null == hiddenAccount + ? _self.hiddenAccount + : hiddenAccount // ignore: cast_nullable_to_non_nullable + as bool, + name: null == name + ? _self.name + : name // ignore: cast_nullable_to_non_nullable + as String, + )); + } + + /// Create a copy of LocalAccount + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $SuperIdentityCopyWith<$Res> get superIdentity { + return $SuperIdentityCopyWith<$Res>(_self.superIdentity, (value) { + return _then(_self.copyWith(superIdentity: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _LocalAccount implements LocalAccount { + const _LocalAccount( + {required this.superIdentity, + @Uint8ListJsonConverter() required this.identitySecretBytes, + required this.encryptionKeyType, + required this.biometricsEnabled, + required this.hiddenAccount, + required this.name}); + factory _LocalAccount.fromJson(Map json) => + _$LocalAccountFromJson(json); // The super identity key record for the account, // containing the publicKey in the currentIdentity @override - SuperIdentity - get superIdentity; // The encrypted currentIdentity secret that goes with + final SuperIdentity superIdentity; +// The encrypted currentIdentity secret that goes with // the identityPublicKey with appended salt @override @Uint8ListJsonConverter() - Uint8List - get identitySecretBytes; // The kind of encryption input used on the account + final Uint8List identitySecretBytes; +// The kind of encryption input used on the account @override - EncryptionKeyType - get encryptionKeyType; // If account is not hidden, password can be retrieved via + final EncryptionKeyType encryptionKeyType; +// If account is not hidden, password can be retrieved via @override - bool - get biometricsEnabled; // Keep account hidden unless account password is entered + final bool biometricsEnabled; +// Keep account hidden unless account password is entered // (tries all hidden accounts with auth method (no biometrics)) @override - bool get hiddenAccount; // Display name for account until it is unlocked + final bool hiddenAccount; +// Display name for account until it is unlocked @override - String get name; + final String name; /// Create a copy of LocalAccount /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$LocalAccountImplCopyWith<_$LocalAccountImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$LocalAccountCopyWith<_LocalAccount> get copyWith => + __$LocalAccountCopyWithImpl<_LocalAccount>(this, _$identity); + + @override + Map toJson() { + return _$LocalAccountToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _LocalAccount && + (identical(other.superIdentity, superIdentity) || + other.superIdentity == superIdentity) && + const DeepCollectionEquality() + .equals(other.identitySecretBytes, identitySecretBytes) && + (identical(other.encryptionKeyType, encryptionKeyType) || + other.encryptionKeyType == encryptionKeyType) && + (identical(other.biometricsEnabled, biometricsEnabled) || + other.biometricsEnabled == biometricsEnabled) && + (identical(other.hiddenAccount, hiddenAccount) || + other.hiddenAccount == hiddenAccount) && + (identical(other.name, name) || other.name == name)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + superIdentity, + const DeepCollectionEquality().hash(identitySecretBytes), + encryptionKeyType, + biometricsEnabled, + hiddenAccount, + name); + + @override + String toString() { + return 'LocalAccount(superIdentity: $superIdentity, identitySecretBytes: $identitySecretBytes, encryptionKeyType: $encryptionKeyType, biometricsEnabled: $biometricsEnabled, hiddenAccount: $hiddenAccount, name: $name)'; + } } + +/// @nodoc +abstract mixin class _$LocalAccountCopyWith<$Res> + implements $LocalAccountCopyWith<$Res> { + factory _$LocalAccountCopyWith( + _LocalAccount value, $Res Function(_LocalAccount) _then) = + __$LocalAccountCopyWithImpl; + @override + @useResult + $Res call( + {SuperIdentity superIdentity, + @Uint8ListJsonConverter() Uint8List identitySecretBytes, + EncryptionKeyType encryptionKeyType, + bool biometricsEnabled, + bool hiddenAccount, + String name}); + + @override + $SuperIdentityCopyWith<$Res> get superIdentity; +} + +/// @nodoc +class __$LocalAccountCopyWithImpl<$Res> + implements _$LocalAccountCopyWith<$Res> { + __$LocalAccountCopyWithImpl(this._self, this._then); + + final _LocalAccount _self; + final $Res Function(_LocalAccount) _then; + + /// Create a copy of LocalAccount + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? superIdentity = null, + Object? identitySecretBytes = null, + Object? encryptionKeyType = null, + Object? biometricsEnabled = null, + Object? hiddenAccount = null, + Object? name = null, + }) { + return _then(_LocalAccount( + superIdentity: null == superIdentity + ? _self.superIdentity + : superIdentity // ignore: cast_nullable_to_non_nullable + as SuperIdentity, + identitySecretBytes: null == identitySecretBytes + ? _self.identitySecretBytes + : identitySecretBytes // ignore: cast_nullable_to_non_nullable + as Uint8List, + encryptionKeyType: null == encryptionKeyType + ? _self.encryptionKeyType + : encryptionKeyType // ignore: cast_nullable_to_non_nullable + as EncryptionKeyType, + biometricsEnabled: null == biometricsEnabled + ? _self.biometricsEnabled + : biometricsEnabled // ignore: cast_nullable_to_non_nullable + as bool, + hiddenAccount: null == hiddenAccount + ? _self.hiddenAccount + : hiddenAccount // ignore: cast_nullable_to_non_nullable + as bool, + name: null == name + ? _self.name + : name // ignore: cast_nullable_to_non_nullable + as String, + )); + } + + /// Create a copy of LocalAccount + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $SuperIdentityCopyWith<$Res> get superIdentity { + return $SuperIdentityCopyWith<$Res>(_self.superIdentity, (value) { + return _then(_self.copyWith(superIdentity: value)); + }); + } +} + +// dart format on diff --git a/lib/account_manager/models/local_account/local_account.g.dart b/lib/account_manager/models/local_account/local_account.g.dart index b60c226..40d55e5 100644 --- a/lib/account_manager/models/local_account/local_account.g.dart +++ b/lib/account_manager/models/local_account/local_account.g.dart @@ -6,8 +6,8 @@ part of 'local_account.dart'; // JsonSerializableGenerator // ************************************************************************** -_$LocalAccountImpl _$$LocalAccountImplFromJson(Map json) => - _$LocalAccountImpl( +_LocalAccount _$LocalAccountFromJson(Map json) => + _LocalAccount( superIdentity: SuperIdentity.fromJson(json['super_identity']), identitySecretBytes: const Uint8ListJsonConverter() .fromJson(json['identity_secret_bytes']), @@ -18,7 +18,7 @@ _$LocalAccountImpl _$$LocalAccountImplFromJson(Map json) => name: json['name'] as String, ); -Map _$$LocalAccountImplToJson(_$LocalAccountImpl instance) => +Map _$LocalAccountToJson(_LocalAccount instance) => { 'super_identity': instance.superIdentity.toJson(), 'identity_secret_bytes': diff --git a/lib/account_manager/models/per_account_collection_state/per_account_collection_state.dart b/lib/account_manager/models/per_account_collection_state/per_account_collection_state.dart index 9e0a6f0..24a394c 100644 --- a/lib/account_manager/models/per_account_collection_state/per_account_collection_state.dart +++ b/lib/account_manager/models/per_account_collection_state/per_account_collection_state.dart @@ -2,6 +2,7 @@ import 'package:async_tools/async_tools.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:veilid_support/veilid_support.dart'; import '../../../chat/chat.dart'; import '../../../chat_list/chat_list.dart'; @@ -14,7 +15,9 @@ import '../../account_manager.dart'; part 'per_account_collection_state.freezed.dart'; @freezed -class PerAccountCollectionState with _$PerAccountCollectionState { +sealed class PerAccountCollectionState + with _$PerAccountCollectionState + implements ToDebugMap { const factory PerAccountCollectionState({ required AccountInfo accountInfo, required AsyncValue? avAccountRecordState, @@ -29,6 +32,23 @@ class PerAccountCollectionState with _$PerAccountCollectionState { required ActiveSingleContactChatBlocMapCubit? activeSingleContactChatBlocMapCubit, }) = _PerAccountCollectionState; + const PerAccountCollectionState._(); + + @override + Map toDebugMap() => { + 'accountInfo': accountInfo, + 'avAccountRecordState': avAccountRecordState, + 'accountInfoCubit': accountInfoCubit, + 'accountRecordCubit': accountRecordCubit, + 'contactInvitationListCubit': contactInvitationListCubit, + 'contactListCubit': contactListCubit, + 'waitingInvitationsBlocMapCubit': waitingInvitationsBlocMapCubit, + 'activeChatCubit': activeChatCubit, + 'chatListCubit': chatListCubit, + 'activeConversationsBlocMapCubit': activeConversationsBlocMapCubit, + 'activeSingleContactChatBlocMapCubit': + activeSingleContactChatBlocMapCubit, + }; } extension PerAccountCollectionStateExt on PerAccountCollectionState { diff --git a/lib/account_manager/models/per_account_collection_state/per_account_collection_state.freezed.dart b/lib/account_manager/models/per_account_collection_state/per_account_collection_state.freezed.dart index 1aa0c7e..4c2e219 100644 --- a/lib/account_manager/models/per_account_collection_state/per_account_collection_state.freezed.dart +++ b/lib/account_manager/models/per_account_collection_state/per_account_collection_state.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,311 +10,36 @@ part of 'per_account_collection_state.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - /// @nodoc mixin _$PerAccountCollectionState { - AccountInfo get accountInfo => throw _privateConstructorUsedError; - AsyncValue? get avAccountRecordState => - throw _privateConstructorUsedError; - AccountInfoCubit? get accountInfoCubit => throw _privateConstructorUsedError; - AccountRecordCubit? get accountRecordCubit => - throw _privateConstructorUsedError; - ContactInvitationListCubit? get contactInvitationListCubit => - throw _privateConstructorUsedError; - ContactListCubit? get contactListCubit => throw _privateConstructorUsedError; - WaitingInvitationsBlocMapCubit? get waitingInvitationsBlocMapCubit => - throw _privateConstructorUsedError; - ActiveChatCubit? get activeChatCubit => throw _privateConstructorUsedError; - ChatListCubit? get chatListCubit => throw _privateConstructorUsedError; - ActiveConversationsBlocMapCubit? get activeConversationsBlocMapCubit => - throw _privateConstructorUsedError; - ActiveSingleContactChatBlocMapCubit? - get activeSingleContactChatBlocMapCubit => - throw _privateConstructorUsedError; + AccountInfo get accountInfo; + AsyncValue? get avAccountRecordState; + AccountInfoCubit? get accountInfoCubit; + AccountRecordCubit? get accountRecordCubit; + ContactInvitationListCubit? get contactInvitationListCubit; + ContactListCubit? get contactListCubit; + WaitingInvitationsBlocMapCubit? get waitingInvitationsBlocMapCubit; + ActiveChatCubit? get activeChatCubit; + ChatListCubit? get chatListCubit; + ActiveConversationsBlocMapCubit? get activeConversationsBlocMapCubit; + ActiveSingleContactChatBlocMapCubit? get activeSingleContactChatBlocMapCubit; /// Create a copy of PerAccountCollectionState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $PerAccountCollectionStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $PerAccountCollectionStateCopyWith<$Res> { - factory $PerAccountCollectionStateCopyWith(PerAccountCollectionState value, - $Res Function(PerAccountCollectionState) then) = - _$PerAccountCollectionStateCopyWithImpl<$Res, PerAccountCollectionState>; - @useResult - $Res call( - {AccountInfo accountInfo, - AsyncValue? avAccountRecordState, - AccountInfoCubit? accountInfoCubit, - AccountRecordCubit? accountRecordCubit, - ContactInvitationListCubit? contactInvitationListCubit, - ContactListCubit? contactListCubit, - WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit, - ActiveChatCubit? activeChatCubit, - ChatListCubit? chatListCubit, - ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit, - ActiveSingleContactChatBlocMapCubit? - activeSingleContactChatBlocMapCubit}); - - $AsyncValueCopyWith? get avAccountRecordState; -} - -/// @nodoc -class _$PerAccountCollectionStateCopyWithImpl<$Res, - $Val extends PerAccountCollectionState> - implements $PerAccountCollectionStateCopyWith<$Res> { - _$PerAccountCollectionStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of PerAccountCollectionState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? accountInfo = null, - Object? avAccountRecordState = freezed, - Object? accountInfoCubit = freezed, - Object? accountRecordCubit = freezed, - Object? contactInvitationListCubit = freezed, - Object? contactListCubit = freezed, - Object? waitingInvitationsBlocMapCubit = freezed, - Object? activeChatCubit = freezed, - Object? chatListCubit = freezed, - Object? activeConversationsBlocMapCubit = freezed, - Object? activeSingleContactChatBlocMapCubit = freezed, - }) { - return _then(_value.copyWith( - accountInfo: null == accountInfo - ? _value.accountInfo - : accountInfo // ignore: cast_nullable_to_non_nullable - as AccountInfo, - avAccountRecordState: freezed == avAccountRecordState - ? _value.avAccountRecordState - : avAccountRecordState // ignore: cast_nullable_to_non_nullable - as AsyncValue?, - accountInfoCubit: freezed == accountInfoCubit - ? _value.accountInfoCubit - : accountInfoCubit // ignore: cast_nullable_to_non_nullable - as AccountInfoCubit?, - accountRecordCubit: freezed == accountRecordCubit - ? _value.accountRecordCubit - : accountRecordCubit // ignore: cast_nullable_to_non_nullable - as AccountRecordCubit?, - contactInvitationListCubit: freezed == contactInvitationListCubit - ? _value.contactInvitationListCubit - : contactInvitationListCubit // ignore: cast_nullable_to_non_nullable - as ContactInvitationListCubit?, - contactListCubit: freezed == contactListCubit - ? _value.contactListCubit - : contactListCubit // ignore: cast_nullable_to_non_nullable - as ContactListCubit?, - waitingInvitationsBlocMapCubit: freezed == waitingInvitationsBlocMapCubit - ? _value.waitingInvitationsBlocMapCubit - : waitingInvitationsBlocMapCubit // ignore: cast_nullable_to_non_nullable - as WaitingInvitationsBlocMapCubit?, - activeChatCubit: freezed == activeChatCubit - ? _value.activeChatCubit - : activeChatCubit // ignore: cast_nullable_to_non_nullable - as ActiveChatCubit?, - chatListCubit: freezed == chatListCubit - ? _value.chatListCubit - : chatListCubit // ignore: cast_nullable_to_non_nullable - as ChatListCubit?, - activeConversationsBlocMapCubit: freezed == - activeConversationsBlocMapCubit - ? _value.activeConversationsBlocMapCubit - : activeConversationsBlocMapCubit // ignore: cast_nullable_to_non_nullable - as ActiveConversationsBlocMapCubit?, - activeSingleContactChatBlocMapCubit: freezed == - activeSingleContactChatBlocMapCubit - ? _value.activeSingleContactChatBlocMapCubit - : activeSingleContactChatBlocMapCubit // ignore: cast_nullable_to_non_nullable - as ActiveSingleContactChatBlocMapCubit?, - ) as $Val); - } - - /// Create a copy of PerAccountCollectionState - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $AsyncValueCopyWith? get avAccountRecordState { - if (_value.avAccountRecordState == null) { - return null; - } - - return $AsyncValueCopyWith(_value.avAccountRecordState!, - (value) { - return _then(_value.copyWith(avAccountRecordState: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$PerAccountCollectionStateImplCopyWith<$Res> - implements $PerAccountCollectionStateCopyWith<$Res> { - factory _$$PerAccountCollectionStateImplCopyWith( - _$PerAccountCollectionStateImpl value, - $Res Function(_$PerAccountCollectionStateImpl) then) = - __$$PerAccountCollectionStateImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {AccountInfo accountInfo, - AsyncValue? avAccountRecordState, - AccountInfoCubit? accountInfoCubit, - AccountRecordCubit? accountRecordCubit, - ContactInvitationListCubit? contactInvitationListCubit, - ContactListCubit? contactListCubit, - WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit, - ActiveChatCubit? activeChatCubit, - ChatListCubit? chatListCubit, - ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit, - ActiveSingleContactChatBlocMapCubit? - activeSingleContactChatBlocMapCubit}); - - @override - $AsyncValueCopyWith? get avAccountRecordState; -} - -/// @nodoc -class __$$PerAccountCollectionStateImplCopyWithImpl<$Res> - extends _$PerAccountCollectionStateCopyWithImpl<$Res, - _$PerAccountCollectionStateImpl> - implements _$$PerAccountCollectionStateImplCopyWith<$Res> { - __$$PerAccountCollectionStateImplCopyWithImpl( - _$PerAccountCollectionStateImpl _value, - $Res Function(_$PerAccountCollectionStateImpl) _then) - : super(_value, _then); - - /// Create a copy of PerAccountCollectionState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? accountInfo = null, - Object? avAccountRecordState = freezed, - Object? accountInfoCubit = freezed, - Object? accountRecordCubit = freezed, - Object? contactInvitationListCubit = freezed, - Object? contactListCubit = freezed, - Object? waitingInvitationsBlocMapCubit = freezed, - Object? activeChatCubit = freezed, - Object? chatListCubit = freezed, - Object? activeConversationsBlocMapCubit = freezed, - Object? activeSingleContactChatBlocMapCubit = freezed, - }) { - return _then(_$PerAccountCollectionStateImpl( - accountInfo: null == accountInfo - ? _value.accountInfo - : accountInfo // ignore: cast_nullable_to_non_nullable - as AccountInfo, - avAccountRecordState: freezed == avAccountRecordState - ? _value.avAccountRecordState - : avAccountRecordState // ignore: cast_nullable_to_non_nullable - as AsyncValue?, - accountInfoCubit: freezed == accountInfoCubit - ? _value.accountInfoCubit - : accountInfoCubit // ignore: cast_nullable_to_non_nullable - as AccountInfoCubit?, - accountRecordCubit: freezed == accountRecordCubit - ? _value.accountRecordCubit - : accountRecordCubit // ignore: cast_nullable_to_non_nullable - as AccountRecordCubit?, - contactInvitationListCubit: freezed == contactInvitationListCubit - ? _value.contactInvitationListCubit - : contactInvitationListCubit // ignore: cast_nullable_to_non_nullable - as ContactInvitationListCubit?, - contactListCubit: freezed == contactListCubit - ? _value.contactListCubit - : contactListCubit // ignore: cast_nullable_to_non_nullable - as ContactListCubit?, - waitingInvitationsBlocMapCubit: freezed == waitingInvitationsBlocMapCubit - ? _value.waitingInvitationsBlocMapCubit - : waitingInvitationsBlocMapCubit // ignore: cast_nullable_to_non_nullable - as WaitingInvitationsBlocMapCubit?, - activeChatCubit: freezed == activeChatCubit - ? _value.activeChatCubit - : activeChatCubit // ignore: cast_nullable_to_non_nullable - as ActiveChatCubit?, - chatListCubit: freezed == chatListCubit - ? _value.chatListCubit - : chatListCubit // ignore: cast_nullable_to_non_nullable - as ChatListCubit?, - activeConversationsBlocMapCubit: freezed == - activeConversationsBlocMapCubit - ? _value.activeConversationsBlocMapCubit - : activeConversationsBlocMapCubit // ignore: cast_nullable_to_non_nullable - as ActiveConversationsBlocMapCubit?, - activeSingleContactChatBlocMapCubit: freezed == - activeSingleContactChatBlocMapCubit - ? _value.activeSingleContactChatBlocMapCubit - : activeSingleContactChatBlocMapCubit // ignore: cast_nullable_to_non_nullable - as ActiveSingleContactChatBlocMapCubit?, - )); - } -} - -/// @nodoc - -class _$PerAccountCollectionStateImpl implements _PerAccountCollectionState { - const _$PerAccountCollectionStateImpl( - {required this.accountInfo, - required this.avAccountRecordState, - required this.accountInfoCubit, - required this.accountRecordCubit, - required this.contactInvitationListCubit, - required this.contactListCubit, - required this.waitingInvitationsBlocMapCubit, - required this.activeChatCubit, - required this.chatListCubit, - required this.activeConversationsBlocMapCubit, - required this.activeSingleContactChatBlocMapCubit}); - - @override - final AccountInfo accountInfo; - @override - final AsyncValue? avAccountRecordState; - @override - final AccountInfoCubit? accountInfoCubit; - @override - final AccountRecordCubit? accountRecordCubit; - @override - final ContactInvitationListCubit? contactInvitationListCubit; - @override - final ContactListCubit? contactListCubit; - @override - final WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit; - @override - final ActiveChatCubit? activeChatCubit; - @override - final ChatListCubit? chatListCubit; - @override - final ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit; - @override - final ActiveSingleContactChatBlocMapCubit? - activeSingleContactChatBlocMapCubit; - - @override - String toString() { - return 'PerAccountCollectionState(accountInfo: $accountInfo, avAccountRecordState: $avAccountRecordState, accountInfoCubit: $accountInfoCubit, accountRecordCubit: $accountRecordCubit, contactInvitationListCubit: $contactInvitationListCubit, contactListCubit: $contactListCubit, waitingInvitationsBlocMapCubit: $waitingInvitationsBlocMapCubit, activeChatCubit: $activeChatCubit, chatListCubit: $chatListCubit, activeConversationsBlocMapCubit: $activeConversationsBlocMapCubit, activeSingleContactChatBlocMapCubit: $activeSingleContactChatBlocMapCubit)'; - } + _$PerAccountCollectionStateCopyWithImpl( + this as PerAccountCollectionState, _$identity); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$PerAccountCollectionStateImpl && + other is PerAccountCollectionState && (identical(other.accountInfo, accountInfo) || other.accountInfo == accountInfo) && (identical(other.avAccountRecordState, avAccountRecordState) || @@ -361,61 +87,350 @@ class _$PerAccountCollectionStateImpl implements _PerAccountCollectionState { activeConversationsBlocMapCubit, activeSingleContactChatBlocMapCubit); + @override + String toString() { + return 'PerAccountCollectionState(accountInfo: $accountInfo, avAccountRecordState: $avAccountRecordState, accountInfoCubit: $accountInfoCubit, accountRecordCubit: $accountRecordCubit, contactInvitationListCubit: $contactInvitationListCubit, contactListCubit: $contactListCubit, waitingInvitationsBlocMapCubit: $waitingInvitationsBlocMapCubit, activeChatCubit: $activeChatCubit, chatListCubit: $chatListCubit, activeConversationsBlocMapCubit: $activeConversationsBlocMapCubit, activeSingleContactChatBlocMapCubit: $activeSingleContactChatBlocMapCubit)'; + } +} + +/// @nodoc +abstract mixin class $PerAccountCollectionStateCopyWith<$Res> { + factory $PerAccountCollectionStateCopyWith(PerAccountCollectionState value, + $Res Function(PerAccountCollectionState) _then) = + _$PerAccountCollectionStateCopyWithImpl; + @useResult + $Res call( + {AccountInfo accountInfo, + AsyncValue? avAccountRecordState, + AccountInfoCubit? accountInfoCubit, + AccountRecordCubit? accountRecordCubit, + ContactInvitationListCubit? contactInvitationListCubit, + ContactListCubit? contactListCubit, + WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit, + ActiveChatCubit? activeChatCubit, + ChatListCubit? chatListCubit, + ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit, + ActiveSingleContactChatBlocMapCubit? + activeSingleContactChatBlocMapCubit}); + + $AsyncValueCopyWith? get avAccountRecordState; +} + +/// @nodoc +class _$PerAccountCollectionStateCopyWithImpl<$Res> + implements $PerAccountCollectionStateCopyWith<$Res> { + _$PerAccountCollectionStateCopyWithImpl(this._self, this._then); + + final PerAccountCollectionState _self; + final $Res Function(PerAccountCollectionState) _then; + + /// Create a copy of PerAccountCollectionState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? accountInfo = null, + Object? avAccountRecordState = freezed, + Object? accountInfoCubit = freezed, + Object? accountRecordCubit = freezed, + Object? contactInvitationListCubit = freezed, + Object? contactListCubit = freezed, + Object? waitingInvitationsBlocMapCubit = freezed, + Object? activeChatCubit = freezed, + Object? chatListCubit = freezed, + Object? activeConversationsBlocMapCubit = freezed, + Object? activeSingleContactChatBlocMapCubit = freezed, + }) { + return _then(_self.copyWith( + accountInfo: null == accountInfo + ? _self.accountInfo + : accountInfo // ignore: cast_nullable_to_non_nullable + as AccountInfo, + avAccountRecordState: freezed == avAccountRecordState + ? _self.avAccountRecordState! + : avAccountRecordState // ignore: cast_nullable_to_non_nullable + as AsyncValue?, + accountInfoCubit: freezed == accountInfoCubit + ? _self.accountInfoCubit + : accountInfoCubit // ignore: cast_nullable_to_non_nullable + as AccountInfoCubit?, + accountRecordCubit: freezed == accountRecordCubit + ? _self.accountRecordCubit + : accountRecordCubit // ignore: cast_nullable_to_non_nullable + as AccountRecordCubit?, + contactInvitationListCubit: freezed == contactInvitationListCubit + ? _self.contactInvitationListCubit + : contactInvitationListCubit // ignore: cast_nullable_to_non_nullable + as ContactInvitationListCubit?, + contactListCubit: freezed == contactListCubit + ? _self.contactListCubit + : contactListCubit // ignore: cast_nullable_to_non_nullable + as ContactListCubit?, + waitingInvitationsBlocMapCubit: freezed == waitingInvitationsBlocMapCubit + ? _self.waitingInvitationsBlocMapCubit + : waitingInvitationsBlocMapCubit // ignore: cast_nullable_to_non_nullable + as WaitingInvitationsBlocMapCubit?, + activeChatCubit: freezed == activeChatCubit + ? _self.activeChatCubit + : activeChatCubit // ignore: cast_nullable_to_non_nullable + as ActiveChatCubit?, + chatListCubit: freezed == chatListCubit + ? _self.chatListCubit + : chatListCubit // ignore: cast_nullable_to_non_nullable + as ChatListCubit?, + activeConversationsBlocMapCubit: freezed == + activeConversationsBlocMapCubit + ? _self.activeConversationsBlocMapCubit + : activeConversationsBlocMapCubit // ignore: cast_nullable_to_non_nullable + as ActiveConversationsBlocMapCubit?, + activeSingleContactChatBlocMapCubit: freezed == + activeSingleContactChatBlocMapCubit + ? _self.activeSingleContactChatBlocMapCubit + : activeSingleContactChatBlocMapCubit // ignore: cast_nullable_to_non_nullable + as ActiveSingleContactChatBlocMapCubit?, + )); + } + /// Create a copy of PerAccountCollectionState /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') - _$$PerAccountCollectionStateImplCopyWith<_$PerAccountCollectionStateImpl> - get copyWith => __$$PerAccountCollectionStateImplCopyWithImpl< - _$PerAccountCollectionStateImpl>(this, _$identity); + $AsyncValueCopyWith? get avAccountRecordState { + if (_self.avAccountRecordState == null) { + return null; + } + + return $AsyncValueCopyWith(_self.avAccountRecordState!, + (value) { + return _then(_self.copyWith(avAccountRecordState: value)); + }); + } } -abstract class _PerAccountCollectionState implements PerAccountCollectionState { - const factory _PerAccountCollectionState( - {required final AccountInfo accountInfo, - required final AsyncValue? avAccountRecordState, - required final AccountInfoCubit? accountInfoCubit, - required final AccountRecordCubit? accountRecordCubit, - required final ContactInvitationListCubit? contactInvitationListCubit, - required final ContactListCubit? contactListCubit, - required final WaitingInvitationsBlocMapCubit? - waitingInvitationsBlocMapCubit, - required final ActiveChatCubit? activeChatCubit, - required final ChatListCubit? chatListCubit, - required final ActiveConversationsBlocMapCubit? - activeConversationsBlocMapCubit, - required final ActiveSingleContactChatBlocMapCubit? - activeSingleContactChatBlocMapCubit}) = - _$PerAccountCollectionStateImpl; +/// @nodoc + +class _PerAccountCollectionState extends PerAccountCollectionState { + const _PerAccountCollectionState( + {required this.accountInfo, + required this.avAccountRecordState, + required this.accountInfoCubit, + required this.accountRecordCubit, + required this.contactInvitationListCubit, + required this.contactListCubit, + required this.waitingInvitationsBlocMapCubit, + required this.activeChatCubit, + required this.chatListCubit, + required this.activeConversationsBlocMapCubit, + required this.activeSingleContactChatBlocMapCubit}) + : super._(); @override - AccountInfo get accountInfo; + final AccountInfo accountInfo; @override - AsyncValue? get avAccountRecordState; + final AsyncValue? avAccountRecordState; @override - AccountInfoCubit? get accountInfoCubit; + final AccountInfoCubit? accountInfoCubit; @override - AccountRecordCubit? get accountRecordCubit; + final AccountRecordCubit? accountRecordCubit; @override - ContactInvitationListCubit? get contactInvitationListCubit; + final ContactInvitationListCubit? contactInvitationListCubit; @override - ContactListCubit? get contactListCubit; + final ContactListCubit? contactListCubit; @override - WaitingInvitationsBlocMapCubit? get waitingInvitationsBlocMapCubit; + final WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit; @override - ActiveChatCubit? get activeChatCubit; + final ActiveChatCubit? activeChatCubit; @override - ChatListCubit? get chatListCubit; + final ChatListCubit? chatListCubit; @override - ActiveConversationsBlocMapCubit? get activeConversationsBlocMapCubit; + final ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit; @override - ActiveSingleContactChatBlocMapCubit? get activeSingleContactChatBlocMapCubit; + final ActiveSingleContactChatBlocMapCubit? + activeSingleContactChatBlocMapCubit; /// Create a copy of PerAccountCollectionState /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$PerAccountCollectionStateImplCopyWith<_$PerAccountCollectionStateImpl> - get copyWith => throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$PerAccountCollectionStateCopyWith<_PerAccountCollectionState> + get copyWith => + __$PerAccountCollectionStateCopyWithImpl<_PerAccountCollectionState>( + this, _$identity); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _PerAccountCollectionState && + (identical(other.accountInfo, accountInfo) || + other.accountInfo == accountInfo) && + (identical(other.avAccountRecordState, avAccountRecordState) || + other.avAccountRecordState == avAccountRecordState) && + (identical(other.accountInfoCubit, accountInfoCubit) || + other.accountInfoCubit == accountInfoCubit) && + (identical(other.accountRecordCubit, accountRecordCubit) || + other.accountRecordCubit == accountRecordCubit) && + (identical(other.contactInvitationListCubit, + contactInvitationListCubit) || + other.contactInvitationListCubit == + contactInvitationListCubit) && + (identical(other.contactListCubit, contactListCubit) || + other.contactListCubit == contactListCubit) && + (identical(other.waitingInvitationsBlocMapCubit, + waitingInvitationsBlocMapCubit) || + other.waitingInvitationsBlocMapCubit == + waitingInvitationsBlocMapCubit) && + (identical(other.activeChatCubit, activeChatCubit) || + other.activeChatCubit == activeChatCubit) && + (identical(other.chatListCubit, chatListCubit) || + other.chatListCubit == chatListCubit) && + (identical(other.activeConversationsBlocMapCubit, + activeConversationsBlocMapCubit) || + other.activeConversationsBlocMapCubit == + activeConversationsBlocMapCubit) && + (identical(other.activeSingleContactChatBlocMapCubit, + activeSingleContactChatBlocMapCubit) || + other.activeSingleContactChatBlocMapCubit == + activeSingleContactChatBlocMapCubit)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + accountInfo, + avAccountRecordState, + accountInfoCubit, + accountRecordCubit, + contactInvitationListCubit, + contactListCubit, + waitingInvitationsBlocMapCubit, + activeChatCubit, + chatListCubit, + activeConversationsBlocMapCubit, + activeSingleContactChatBlocMapCubit); + + @override + String toString() { + return 'PerAccountCollectionState(accountInfo: $accountInfo, avAccountRecordState: $avAccountRecordState, accountInfoCubit: $accountInfoCubit, accountRecordCubit: $accountRecordCubit, contactInvitationListCubit: $contactInvitationListCubit, contactListCubit: $contactListCubit, waitingInvitationsBlocMapCubit: $waitingInvitationsBlocMapCubit, activeChatCubit: $activeChatCubit, chatListCubit: $chatListCubit, activeConversationsBlocMapCubit: $activeConversationsBlocMapCubit, activeSingleContactChatBlocMapCubit: $activeSingleContactChatBlocMapCubit)'; + } } + +/// @nodoc +abstract mixin class _$PerAccountCollectionStateCopyWith<$Res> + implements $PerAccountCollectionStateCopyWith<$Res> { + factory _$PerAccountCollectionStateCopyWith(_PerAccountCollectionState value, + $Res Function(_PerAccountCollectionState) _then) = + __$PerAccountCollectionStateCopyWithImpl; + @override + @useResult + $Res call( + {AccountInfo accountInfo, + AsyncValue? avAccountRecordState, + AccountInfoCubit? accountInfoCubit, + AccountRecordCubit? accountRecordCubit, + ContactInvitationListCubit? contactInvitationListCubit, + ContactListCubit? contactListCubit, + WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit, + ActiveChatCubit? activeChatCubit, + ChatListCubit? chatListCubit, + ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit, + ActiveSingleContactChatBlocMapCubit? + activeSingleContactChatBlocMapCubit}); + + @override + $AsyncValueCopyWith? get avAccountRecordState; +} + +/// @nodoc +class __$PerAccountCollectionStateCopyWithImpl<$Res> + implements _$PerAccountCollectionStateCopyWith<$Res> { + __$PerAccountCollectionStateCopyWithImpl(this._self, this._then); + + final _PerAccountCollectionState _self; + final $Res Function(_PerAccountCollectionState) _then; + + /// Create a copy of PerAccountCollectionState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? accountInfo = null, + Object? avAccountRecordState = freezed, + Object? accountInfoCubit = freezed, + Object? accountRecordCubit = freezed, + Object? contactInvitationListCubit = freezed, + Object? contactListCubit = freezed, + Object? waitingInvitationsBlocMapCubit = freezed, + Object? activeChatCubit = freezed, + Object? chatListCubit = freezed, + Object? activeConversationsBlocMapCubit = freezed, + Object? activeSingleContactChatBlocMapCubit = freezed, + }) { + return _then(_PerAccountCollectionState( + accountInfo: null == accountInfo + ? _self.accountInfo + : accountInfo // ignore: cast_nullable_to_non_nullable + as AccountInfo, + avAccountRecordState: freezed == avAccountRecordState + ? _self.avAccountRecordState + : avAccountRecordState // ignore: cast_nullable_to_non_nullable + as AsyncValue?, + accountInfoCubit: freezed == accountInfoCubit + ? _self.accountInfoCubit + : accountInfoCubit // ignore: cast_nullable_to_non_nullable + as AccountInfoCubit?, + accountRecordCubit: freezed == accountRecordCubit + ? _self.accountRecordCubit + : accountRecordCubit // ignore: cast_nullable_to_non_nullable + as AccountRecordCubit?, + contactInvitationListCubit: freezed == contactInvitationListCubit + ? _self.contactInvitationListCubit + : contactInvitationListCubit // ignore: cast_nullable_to_non_nullable + as ContactInvitationListCubit?, + contactListCubit: freezed == contactListCubit + ? _self.contactListCubit + : contactListCubit // ignore: cast_nullable_to_non_nullable + as ContactListCubit?, + waitingInvitationsBlocMapCubit: freezed == waitingInvitationsBlocMapCubit + ? _self.waitingInvitationsBlocMapCubit + : waitingInvitationsBlocMapCubit // ignore: cast_nullable_to_non_nullable + as WaitingInvitationsBlocMapCubit?, + activeChatCubit: freezed == activeChatCubit + ? _self.activeChatCubit + : activeChatCubit // ignore: cast_nullable_to_non_nullable + as ActiveChatCubit?, + chatListCubit: freezed == chatListCubit + ? _self.chatListCubit + : chatListCubit // ignore: cast_nullable_to_non_nullable + as ChatListCubit?, + activeConversationsBlocMapCubit: freezed == + activeConversationsBlocMapCubit + ? _self.activeConversationsBlocMapCubit + : activeConversationsBlocMapCubit // ignore: cast_nullable_to_non_nullable + as ActiveConversationsBlocMapCubit?, + activeSingleContactChatBlocMapCubit: freezed == + activeSingleContactChatBlocMapCubit + ? _self.activeSingleContactChatBlocMapCubit + : activeSingleContactChatBlocMapCubit // ignore: cast_nullable_to_non_nullable + as ActiveSingleContactChatBlocMapCubit?, + )); + } + + /// Create a copy of PerAccountCollectionState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $AsyncValueCopyWith? get avAccountRecordState { + if (_self.avAccountRecordState == null) { + return null; + } + + return $AsyncValueCopyWith(_self.avAccountRecordState!, + (value) { + return _then(_self.copyWith(avAccountRecordState: value)); + }); + } +} + +// dart format on diff --git a/lib/account_manager/models/user_login/user_login.dart b/lib/account_manager/models/user_login/user_login.dart index 7c024cf..d43fdfd 100644 --- a/lib/account_manager/models/user_login/user_login.dart +++ b/lib/account_manager/models/user_login/user_login.dart @@ -9,7 +9,7 @@ part 'user_login.g.dart'; // User logins are stored in the user_logins tablestore table // indexed by the accountSuperIdentityRecordKey @freezed -class UserLogin with _$UserLogin { +sealed class UserLogin with _$UserLogin { const factory UserLogin({ // SuperIdentity record key for the user // used to index the local accounts table diff --git a/lib/account_manager/models/user_login/user_login.freezed.dart b/lib/account_manager/models/user_login/user_login.freezed.dart index 2804a77..b0c6070 100644 --- a/lib/account_manager/models/user_login/user_login.freezed.dart +++ b/lib/account_manager/models/user_login/user_login.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,195 +10,36 @@ part of 'user_login.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -UserLogin _$UserLoginFromJson(Map json) { - return _UserLogin.fromJson(json); -} - /// @nodoc mixin _$UserLogin { // SuperIdentity record key for the user // used to index the local accounts table - Typed get superIdentityRecordKey => - throw _privateConstructorUsedError; // The identity secret as unlocked from the local accounts table - Typed get identitySecret => - throw _privateConstructorUsedError; // The account record key, owner key and secret pulled from the identity - AccountRecordInfo get accountRecordInfo => - throw _privateConstructorUsedError; // The time this login was most recently used - Timestamp get lastActive => throw _privateConstructorUsedError; - - /// Serializes this UserLogin to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + TypedKey + get superIdentityRecordKey; // The identity secret as unlocked from the local accounts table + TypedSecret + get identitySecret; // The account record key, owner key and secret pulled from the identity + AccountRecordInfo + get accountRecordInfo; // The time this login was most recently used + Timestamp get lastActive; /// Create a copy of UserLogin /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $UserLoginCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$UserLoginCopyWithImpl(this as UserLogin, _$identity); -/// @nodoc -abstract class $UserLoginCopyWith<$Res> { - factory $UserLoginCopyWith(UserLogin value, $Res Function(UserLogin) then) = - _$UserLoginCopyWithImpl<$Res, UserLogin>; - @useResult - $Res call( - {Typed superIdentityRecordKey, - Typed identitySecret, - AccountRecordInfo accountRecordInfo, - Timestamp lastActive}); - - $AccountRecordInfoCopyWith<$Res> get accountRecordInfo; -} - -/// @nodoc -class _$UserLoginCopyWithImpl<$Res, $Val extends UserLogin> - implements $UserLoginCopyWith<$Res> { - _$UserLoginCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of UserLogin - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? superIdentityRecordKey = null, - Object? identitySecret = null, - Object? accountRecordInfo = null, - Object? lastActive = null, - }) { - return _then(_value.copyWith( - superIdentityRecordKey: null == superIdentityRecordKey - ? _value.superIdentityRecordKey - : superIdentityRecordKey // ignore: cast_nullable_to_non_nullable - as Typed, - identitySecret: null == identitySecret - ? _value.identitySecret - : identitySecret // ignore: cast_nullable_to_non_nullable - as Typed, - accountRecordInfo: null == accountRecordInfo - ? _value.accountRecordInfo - : accountRecordInfo // ignore: cast_nullable_to_non_nullable - as AccountRecordInfo, - lastActive: null == lastActive - ? _value.lastActive - : lastActive // ignore: cast_nullable_to_non_nullable - as Timestamp, - ) as $Val); - } - - /// Create a copy of UserLogin - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $AccountRecordInfoCopyWith<$Res> get accountRecordInfo { - return $AccountRecordInfoCopyWith<$Res>(_value.accountRecordInfo, (value) { - return _then(_value.copyWith(accountRecordInfo: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$UserLoginImplCopyWith<$Res> - implements $UserLoginCopyWith<$Res> { - factory _$$UserLoginImplCopyWith( - _$UserLoginImpl value, $Res Function(_$UserLoginImpl) then) = - __$$UserLoginImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {Typed superIdentityRecordKey, - Typed identitySecret, - AccountRecordInfo accountRecordInfo, - Timestamp lastActive}); - - @override - $AccountRecordInfoCopyWith<$Res> get accountRecordInfo; -} - -/// @nodoc -class __$$UserLoginImplCopyWithImpl<$Res> - extends _$UserLoginCopyWithImpl<$Res, _$UserLoginImpl> - implements _$$UserLoginImplCopyWith<$Res> { - __$$UserLoginImplCopyWithImpl( - _$UserLoginImpl _value, $Res Function(_$UserLoginImpl) _then) - : super(_value, _then); - - /// Create a copy of UserLogin - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? superIdentityRecordKey = null, - Object? identitySecret = null, - Object? accountRecordInfo = null, - Object? lastActive = null, - }) { - return _then(_$UserLoginImpl( - superIdentityRecordKey: null == superIdentityRecordKey - ? _value.superIdentityRecordKey - : superIdentityRecordKey // ignore: cast_nullable_to_non_nullable - as Typed, - identitySecret: null == identitySecret - ? _value.identitySecret - : identitySecret // ignore: cast_nullable_to_non_nullable - as Typed, - accountRecordInfo: null == accountRecordInfo - ? _value.accountRecordInfo - : accountRecordInfo // ignore: cast_nullable_to_non_nullable - as AccountRecordInfo, - lastActive: null == lastActive - ? _value.lastActive - : lastActive // ignore: cast_nullable_to_non_nullable - as Timestamp, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$UserLoginImpl implements _UserLogin { - const _$UserLoginImpl( - {required this.superIdentityRecordKey, - required this.identitySecret, - required this.accountRecordInfo, - required this.lastActive}); - - factory _$UserLoginImpl.fromJson(Map json) => - _$$UserLoginImplFromJson(json); - -// SuperIdentity record key for the user -// used to index the local accounts table - @override - final Typed superIdentityRecordKey; -// The identity secret as unlocked from the local accounts table - @override - final Typed identitySecret; -// The account record key, owner key and secret pulled from the identity - @override - final AccountRecordInfo accountRecordInfo; -// The time this login was most recently used - @override - final Timestamp lastActive; - - @override - String toString() { - return 'UserLogin(superIdentityRecordKey: $superIdentityRecordKey, identitySecret: $identitySecret, accountRecordInfo: $accountRecordInfo, lastActive: $lastActive)'; - } + /// Serializes this UserLogin to a JSON map. + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$UserLoginImpl && + other is UserLogin && (identical(other.superIdentityRecordKey, superIdentityRecordKey) || other.superIdentityRecordKey == superIdentityRecordKey) && (identical(other.identitySecret, identitySecret) || @@ -213,50 +55,204 @@ class _$UserLoginImpl implements _UserLogin { int get hashCode => Object.hash(runtimeType, superIdentityRecordKey, identitySecret, accountRecordInfo, lastActive); - /// Create a copy of UserLogin - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$UserLoginImplCopyWith<_$UserLoginImpl> get copyWith => - __$$UserLoginImplCopyWithImpl<_$UserLoginImpl>(this, _$identity); - - @override - Map toJson() { - return _$$UserLoginImplToJson( - this, - ); + String toString() { + return 'UserLogin(superIdentityRecordKey: $superIdentityRecordKey, identitySecret: $identitySecret, accountRecordInfo: $accountRecordInfo, lastActive: $lastActive)'; } } -abstract class _UserLogin implements UserLogin { - const factory _UserLogin( - {required final Typed superIdentityRecordKey, - required final Typed identitySecret, - required final AccountRecordInfo accountRecordInfo, - required final Timestamp lastActive}) = _$UserLoginImpl; +/// @nodoc +abstract mixin class $UserLoginCopyWith<$Res> { + factory $UserLoginCopyWith(UserLogin value, $Res Function(UserLogin) _then) = + _$UserLoginCopyWithImpl; + @useResult + $Res call( + {Typed superIdentityRecordKey, + Typed identitySecret, + AccountRecordInfo accountRecordInfo, + Timestamp lastActive}); - factory _UserLogin.fromJson(Map json) = - _$UserLoginImpl.fromJson; + $AccountRecordInfoCopyWith<$Res> get accountRecordInfo; +} + +/// @nodoc +class _$UserLoginCopyWithImpl<$Res> implements $UserLoginCopyWith<$Res> { + _$UserLoginCopyWithImpl(this._self, this._then); + + final UserLogin _self; + final $Res Function(UserLogin) _then; + + /// Create a copy of UserLogin + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? superIdentityRecordKey = null, + Object? identitySecret = null, + Object? accountRecordInfo = null, + Object? lastActive = null, + }) { + return _then(_self.copyWith( + superIdentityRecordKey: null == superIdentityRecordKey + ? _self.superIdentityRecordKey! + : superIdentityRecordKey // ignore: cast_nullable_to_non_nullable + as Typed, + identitySecret: null == identitySecret + ? _self.identitySecret! + : identitySecret // ignore: cast_nullable_to_non_nullable + as Typed, + accountRecordInfo: null == accountRecordInfo + ? _self.accountRecordInfo + : accountRecordInfo // ignore: cast_nullable_to_non_nullable + as AccountRecordInfo, + lastActive: null == lastActive + ? _self.lastActive + : lastActive // ignore: cast_nullable_to_non_nullable + as Timestamp, + )); + } + + /// Create a copy of UserLogin + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $AccountRecordInfoCopyWith<$Res> get accountRecordInfo { + return $AccountRecordInfoCopyWith<$Res>(_self.accountRecordInfo, (value) { + return _then(_self.copyWith(accountRecordInfo: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _UserLogin implements UserLogin { + const _UserLogin( + {required this.superIdentityRecordKey, + required this.identitySecret, + required this.accountRecordInfo, + required this.lastActive}); + factory _UserLogin.fromJson(Map json) => + _$UserLoginFromJson(json); // SuperIdentity record key for the user // used to index the local accounts table @override - Typed - get superIdentityRecordKey; // The identity secret as unlocked from the local accounts table + final Typed superIdentityRecordKey; +// The identity secret as unlocked from the local accounts table @override - Typed - get identitySecret; // The account record key, owner key and secret pulled from the identity + final Typed identitySecret; +// The account record key, owner key and secret pulled from the identity @override - AccountRecordInfo - get accountRecordInfo; // The time this login was most recently used + final AccountRecordInfo accountRecordInfo; +// The time this login was most recently used @override - Timestamp get lastActive; + final Timestamp lastActive; /// Create a copy of UserLogin /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$UserLoginImplCopyWith<_$UserLoginImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$UserLoginCopyWith<_UserLogin> get copyWith => + __$UserLoginCopyWithImpl<_UserLogin>(this, _$identity); + + @override + Map toJson() { + return _$UserLoginToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _UserLogin && + (identical(other.superIdentityRecordKey, superIdentityRecordKey) || + other.superIdentityRecordKey == superIdentityRecordKey) && + (identical(other.identitySecret, identitySecret) || + other.identitySecret == identitySecret) && + (identical(other.accountRecordInfo, accountRecordInfo) || + other.accountRecordInfo == accountRecordInfo) && + (identical(other.lastActive, lastActive) || + other.lastActive == lastActive)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, superIdentityRecordKey, + identitySecret, accountRecordInfo, lastActive); + + @override + String toString() { + return 'UserLogin(superIdentityRecordKey: $superIdentityRecordKey, identitySecret: $identitySecret, accountRecordInfo: $accountRecordInfo, lastActive: $lastActive)'; + } } + +/// @nodoc +abstract mixin class _$UserLoginCopyWith<$Res> + implements $UserLoginCopyWith<$Res> { + factory _$UserLoginCopyWith( + _UserLogin value, $Res Function(_UserLogin) _then) = + __$UserLoginCopyWithImpl; + @override + @useResult + $Res call( + {Typed superIdentityRecordKey, + Typed identitySecret, + AccountRecordInfo accountRecordInfo, + Timestamp lastActive}); + + @override + $AccountRecordInfoCopyWith<$Res> get accountRecordInfo; +} + +/// @nodoc +class __$UserLoginCopyWithImpl<$Res> implements _$UserLoginCopyWith<$Res> { + __$UserLoginCopyWithImpl(this._self, this._then); + + final _UserLogin _self; + final $Res Function(_UserLogin) _then; + + /// Create a copy of UserLogin + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? superIdentityRecordKey = null, + Object? identitySecret = null, + Object? accountRecordInfo = null, + Object? lastActive = null, + }) { + return _then(_UserLogin( + superIdentityRecordKey: null == superIdentityRecordKey + ? _self.superIdentityRecordKey + : superIdentityRecordKey // ignore: cast_nullable_to_non_nullable + as Typed, + identitySecret: null == identitySecret + ? _self.identitySecret + : identitySecret // ignore: cast_nullable_to_non_nullable + as Typed, + accountRecordInfo: null == accountRecordInfo + ? _self.accountRecordInfo + : accountRecordInfo // ignore: cast_nullable_to_non_nullable + as AccountRecordInfo, + lastActive: null == lastActive + ? _self.lastActive + : lastActive // ignore: cast_nullable_to_non_nullable + as Timestamp, + )); + } + + /// Create a copy of UserLogin + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $AccountRecordInfoCopyWith<$Res> get accountRecordInfo { + return $AccountRecordInfoCopyWith<$Res>(_self.accountRecordInfo, (value) { + return _then(_self.copyWith(accountRecordInfo: value)); + }); + } +} + +// dart format on diff --git a/lib/account_manager/models/user_login/user_login.g.dart b/lib/account_manager/models/user_login/user_login.g.dart index 173d853..fa5314b 100644 --- a/lib/account_manager/models/user_login/user_login.g.dart +++ b/lib/account_manager/models/user_login/user_login.g.dart @@ -6,8 +6,7 @@ part of 'user_login.dart'; // JsonSerializableGenerator // ************************************************************************** -_$UserLoginImpl _$$UserLoginImplFromJson(Map json) => - _$UserLoginImpl( +_UserLogin _$UserLoginFromJson(Map json) => _UserLogin( superIdentityRecordKey: Typed.fromJson( json['super_identity_record_key']), identitySecret: @@ -17,7 +16,7 @@ _$UserLoginImpl _$$UserLoginImplFromJson(Map json) => lastActive: Timestamp.fromJson(json['last_active']), ); -Map _$$UserLoginImplToJson(_$UserLoginImpl instance) => +Map _$UserLoginToJson(_UserLogin instance) => { 'super_identity_record_key': instance.superIdentityRecordKey.toJson(), 'identity_secret': instance.identitySecret.toJson(), diff --git a/lib/chat/cubits/chat_component_cubit.dart b/lib/chat/cubits/chat_component_cubit.dart index 9e50e02..7ea9e95 100644 --- a/lib/chat/cubits/chat_component_cubit.dart +++ b/lib/chat/cubits/chat_component_cubit.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:async_tools/async_tools.dart'; -import 'package:bloc_advanced_tools/bloc_advanced_tools.dart'; import 'package:fast_immutable_collections/fast_immutable_collections.dart'; import 'package:fixnum/fixnum.dart'; import 'package:flutter/widgets.dart'; @@ -184,9 +183,7 @@ class ChatComponentCubit extends Cubit { emit(_convertMessages(state, avMessagesState)); } - void _onChangedContacts( - BlocBusyState>>> - bavContacts) { + void _onChangedContacts(DHTShortArrayCubitState bavContacts) { // Rewrite users when contacts change singleFuture((this, _sfChangedContacts), _updateConversationSubscriptions); } @@ -353,6 +350,7 @@ class ChatComponentCubit extends Cubit { case proto.Message_Kind.membership: case proto.Message_Kind.moderation: case proto.Message_Kind.notSet: + case proto.Message_Kind.readReceipt: return (currentState, null); } } @@ -440,9 +438,7 @@ class ChatComponentCubit extends Cubit { final Map>> _conversationSubscriptions = {}; late StreamSubscription _messagesSubscription; - late StreamSubscription< - BlocBusyState< - AsyncValue>>>> + late StreamSubscription> _contactListSubscription; double scrollOffset = 0; } diff --git a/lib/chat/models/chat_component_state.dart b/lib/chat/models/chat_component_state.dart index b06b413..82e492d 100644 --- a/lib/chat/models/chat_component_state.dart +++ b/lib/chat/models/chat_component_state.dart @@ -13,7 +13,7 @@ import 'window_state.dart'; part 'chat_component_state.freezed.dart'; @freezed -class ChatComponentState with _$ChatComponentState { +sealed class ChatComponentState with _$ChatComponentState { const factory ChatComponentState( { // GlobalKey for the chat diff --git a/lib/chat/models/chat_component_state.freezed.dart b/lib/chat/models/chat_component_state.freezed.dart index f967997..ae3acee 100644 --- a/lib/chat/models/chat_component_state.freezed.dart +++ b/lib/chat/models/chat_component_state.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,44 +10,78 @@ part of 'chat_component_state.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - /// @nodoc mixin _$ChatComponentState { // GlobalKey for the chat - GlobalKey get chatKey => - throw _privateConstructorUsedError; // ScrollController for the chat - AutoScrollController get scrollController => - throw _privateConstructorUsedError; // TextEditingController for the chat - InputTextFieldController get textEditingController => - throw _privateConstructorUsedError; // Local user - User? get localUser => - throw _privateConstructorUsedError; // Active remote users - IMap, User> get remoteUsers => - throw _privateConstructorUsedError; // Historical remote users - IMap, User> get historicalRemoteUsers => - throw _privateConstructorUsedError; // Unknown users - IMap, User> get unknownUsers => - throw _privateConstructorUsedError; // Messages state - AsyncValue> get messageWindow => - throw _privateConstructorUsedError; // Title of the chat - String get title => throw _privateConstructorUsedError; + GlobalKey get chatKey; // ScrollController for the chat + AutoScrollController + get scrollController; // TextEditingController for the chat + InputTextFieldController get textEditingController; // Local user + User? get localUser; // Active remote users + IMap get remoteUsers; // Historical remote users + IMap get historicalRemoteUsers; // Unknown users + IMap get unknownUsers; // Messages state + AsyncValue> get messageWindow; // Title of the chat + String get title; /// Create a copy of ChatComponentState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $ChatComponentStateCopyWith get copyWith => - throw _privateConstructorUsedError; + _$ChatComponentStateCopyWithImpl( + this as ChatComponentState, _$identity); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is ChatComponentState && + (identical(other.chatKey, chatKey) || other.chatKey == chatKey) && + (identical(other.scrollController, scrollController) || + other.scrollController == scrollController) && + (identical(other.textEditingController, textEditingController) || + other.textEditingController == textEditingController) && + (identical(other.localUser, localUser) || + other.localUser == localUser) && + (identical(other.remoteUsers, remoteUsers) || + other.remoteUsers == remoteUsers) && + (identical(other.historicalRemoteUsers, historicalRemoteUsers) || + other.historicalRemoteUsers == historicalRemoteUsers) && + (identical(other.unknownUsers, unknownUsers) || + other.unknownUsers == unknownUsers) && + (identical(other.messageWindow, messageWindow) || + other.messageWindow == messageWindow) && + (identical(other.title, title) || other.title == title)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + chatKey, + scrollController, + textEditingController, + localUser, + remoteUsers, + historicalRemoteUsers, + unknownUsers, + messageWindow, + title); + + @override + String toString() { + return 'ChatComponentState(chatKey: $chatKey, scrollController: $scrollController, textEditingController: $textEditingController, localUser: $localUser, remoteUsers: $remoteUsers, historicalRemoteUsers: $historicalRemoteUsers, unknownUsers: $unknownUsers, messageWindow: $messageWindow, title: $title)'; + } } /// @nodoc -abstract class $ChatComponentStateCopyWith<$Res> { +abstract mixin class $ChatComponentStateCopyWith<$Res> { factory $ChatComponentStateCopyWith( - ChatComponentState value, $Res Function(ChatComponentState) then) = - _$ChatComponentStateCopyWithImpl<$Res, ChatComponentState>; + ChatComponentState value, $Res Function(ChatComponentState) _then) = + _$ChatComponentStateCopyWithImpl; @useResult $Res call( {GlobalKey chatKey, @@ -63,14 +98,12 @@ abstract class $ChatComponentStateCopyWith<$Res> { } /// @nodoc -class _$ChatComponentStateCopyWithImpl<$Res, $Val extends ChatComponentState> +class _$ChatComponentStateCopyWithImpl<$Res> implements $ChatComponentStateCopyWith<$Res> { - _$ChatComponentStateCopyWithImpl(this._value, this._then); + _$ChatComponentStateCopyWithImpl(this._self, this._then); - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; + final ChatComponentState _self; + final $Res Function(ChatComponentState) _then; /// Create a copy of ChatComponentState /// with the given fields replaced by the non-null parameter values. @@ -87,44 +120,44 @@ class _$ChatComponentStateCopyWithImpl<$Res, $Val extends ChatComponentState> Object? messageWindow = null, Object? title = null, }) { - return _then(_value.copyWith( + return _then(_self.copyWith( chatKey: null == chatKey - ? _value.chatKey + ? _self.chatKey : chatKey // ignore: cast_nullable_to_non_nullable as GlobalKey, scrollController: null == scrollController - ? _value.scrollController + ? _self.scrollController : scrollController // ignore: cast_nullable_to_non_nullable as AutoScrollController, textEditingController: null == textEditingController - ? _value.textEditingController + ? _self.textEditingController : textEditingController // ignore: cast_nullable_to_non_nullable as InputTextFieldController, localUser: freezed == localUser - ? _value.localUser + ? _self.localUser : localUser // ignore: cast_nullable_to_non_nullable as User?, remoteUsers: null == remoteUsers - ? _value.remoteUsers + ? _self.remoteUsers! : remoteUsers // ignore: cast_nullable_to_non_nullable as IMap, User>, historicalRemoteUsers: null == historicalRemoteUsers - ? _value.historicalRemoteUsers + ? _self.historicalRemoteUsers! : historicalRemoteUsers // ignore: cast_nullable_to_non_nullable as IMap, User>, unknownUsers: null == unknownUsers - ? _value.unknownUsers + ? _self.unknownUsers! : unknownUsers // ignore: cast_nullable_to_non_nullable as IMap, User>, messageWindow: null == messageWindow - ? _value.messageWindow + ? _self.messageWindow : messageWindow // ignore: cast_nullable_to_non_nullable as AsyncValue>, title: null == title - ? _value.title + ? _self.title : title // ignore: cast_nullable_to_non_nullable as String, - ) as $Val); + )); } /// Create a copy of ChatComponentState @@ -132,104 +165,17 @@ class _$ChatComponentStateCopyWithImpl<$Res, $Val extends ChatComponentState> @override @pragma('vm:prefer-inline') $AsyncValueCopyWith, $Res> get messageWindow { - return $AsyncValueCopyWith, $Res>(_value.messageWindow, + return $AsyncValueCopyWith, $Res>(_self.messageWindow, (value) { - return _then(_value.copyWith(messageWindow: value) as $Val); + return _then(_self.copyWith(messageWindow: value)); }); } } /// @nodoc -abstract class _$$ChatComponentStateImplCopyWith<$Res> - implements $ChatComponentStateCopyWith<$Res> { - factory _$$ChatComponentStateImplCopyWith(_$ChatComponentStateImpl value, - $Res Function(_$ChatComponentStateImpl) then) = - __$$ChatComponentStateImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {GlobalKey chatKey, - AutoScrollController scrollController, - InputTextFieldController textEditingController, - User? localUser, - IMap, User> remoteUsers, - IMap, User> historicalRemoteUsers, - IMap, User> unknownUsers, - AsyncValue> messageWindow, - String title}); - @override - $AsyncValueCopyWith, $Res> get messageWindow; -} - -/// @nodoc -class __$$ChatComponentStateImplCopyWithImpl<$Res> - extends _$ChatComponentStateCopyWithImpl<$Res, _$ChatComponentStateImpl> - implements _$$ChatComponentStateImplCopyWith<$Res> { - __$$ChatComponentStateImplCopyWithImpl(_$ChatComponentStateImpl _value, - $Res Function(_$ChatComponentStateImpl) _then) - : super(_value, _then); - - /// Create a copy of ChatComponentState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? chatKey = null, - Object? scrollController = null, - Object? textEditingController = null, - Object? localUser = freezed, - Object? remoteUsers = null, - Object? historicalRemoteUsers = null, - Object? unknownUsers = null, - Object? messageWindow = null, - Object? title = null, - }) { - return _then(_$ChatComponentStateImpl( - chatKey: null == chatKey - ? _value.chatKey - : chatKey // ignore: cast_nullable_to_non_nullable - as GlobalKey, - scrollController: null == scrollController - ? _value.scrollController - : scrollController // ignore: cast_nullable_to_non_nullable - as AutoScrollController, - textEditingController: null == textEditingController - ? _value.textEditingController - : textEditingController // ignore: cast_nullable_to_non_nullable - as InputTextFieldController, - localUser: freezed == localUser - ? _value.localUser - : localUser // ignore: cast_nullable_to_non_nullable - as User?, - remoteUsers: null == remoteUsers - ? _value.remoteUsers - : remoteUsers // ignore: cast_nullable_to_non_nullable - as IMap, User>, - historicalRemoteUsers: null == historicalRemoteUsers - ? _value.historicalRemoteUsers - : historicalRemoteUsers // ignore: cast_nullable_to_non_nullable - as IMap, User>, - unknownUsers: null == unknownUsers - ? _value.unknownUsers - : unknownUsers // ignore: cast_nullable_to_non_nullable - as IMap, User>, - messageWindow: null == messageWindow - ? _value.messageWindow - : messageWindow // ignore: cast_nullable_to_non_nullable - as AsyncValue>, - title: null == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String, - )); - } -} - -/// @nodoc - -class _$ChatComponentStateImpl implements _ChatComponentState { - const _$ChatComponentStateImpl( +class _ChatComponentState implements ChatComponentState { + const _ChatComponentState( {required this.chatKey, required this.scrollController, required this.textEditingController, @@ -268,16 +214,19 @@ class _$ChatComponentStateImpl implements _ChatComponentState { @override final String title; + /// Create a copy of ChatComponentState + /// with the given fields replaced by the non-null parameter values. @override - String toString() { - return 'ChatComponentState(chatKey: $chatKey, scrollController: $scrollController, textEditingController: $textEditingController, localUser: $localUser, remoteUsers: $remoteUsers, historicalRemoteUsers: $historicalRemoteUsers, unknownUsers: $unknownUsers, messageWindow: $messageWindow, title: $title)'; - } + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$ChatComponentStateCopyWith<_ChatComponentState> get copyWith => + __$ChatComponentStateCopyWithImpl<_ChatComponentState>(this, _$identity); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$ChatComponentStateImpl && + other is _ChatComponentState && (identical(other.chatKey, chatKey) || other.chatKey == chatKey) && (identical(other.scrollController, scrollController) || other.scrollController == scrollController) && @@ -309,56 +258,108 @@ class _$ChatComponentStateImpl implements _ChatComponentState { messageWindow, title); + @override + String toString() { + return 'ChatComponentState(chatKey: $chatKey, scrollController: $scrollController, textEditingController: $textEditingController, localUser: $localUser, remoteUsers: $remoteUsers, historicalRemoteUsers: $historicalRemoteUsers, unknownUsers: $unknownUsers, messageWindow: $messageWindow, title: $title)'; + } +} + +/// @nodoc +abstract mixin class _$ChatComponentStateCopyWith<$Res> + implements $ChatComponentStateCopyWith<$Res> { + factory _$ChatComponentStateCopyWith( + _ChatComponentState value, $Res Function(_ChatComponentState) _then) = + __$ChatComponentStateCopyWithImpl; + @override + @useResult + $Res call( + {GlobalKey chatKey, + AutoScrollController scrollController, + InputTextFieldController textEditingController, + User? localUser, + IMap, User> remoteUsers, + IMap, User> historicalRemoteUsers, + IMap, User> unknownUsers, + AsyncValue> messageWindow, + String title}); + + @override + $AsyncValueCopyWith, $Res> get messageWindow; +} + +/// @nodoc +class __$ChatComponentStateCopyWithImpl<$Res> + implements _$ChatComponentStateCopyWith<$Res> { + __$ChatComponentStateCopyWithImpl(this._self, this._then); + + final _ChatComponentState _self; + final $Res Function(_ChatComponentState) _then; + /// Create a copy of ChatComponentState /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') - _$$ChatComponentStateImplCopyWith<_$ChatComponentStateImpl> get copyWith => - __$$ChatComponentStateImplCopyWithImpl<_$ChatComponentStateImpl>( - this, _$identity); -} - -abstract class _ChatComponentState implements ChatComponentState { - const factory _ChatComponentState( - {required final GlobalKey chatKey, - required final AutoScrollController scrollController, - required final InputTextFieldController textEditingController, - required final User? localUser, - required final IMap, User> remoteUsers, - required final IMap, User> - historicalRemoteUsers, - required final IMap, User> unknownUsers, - required final AsyncValue> messageWindow, - required final String title}) = _$ChatComponentStateImpl; - -// GlobalKey for the chat - @override - GlobalKey get chatKey; // ScrollController for the chat - @override - AutoScrollController - get scrollController; // TextEditingController for the chat - @override - InputTextFieldController get textEditingController; // Local user - @override - User? get localUser; // Active remote users - @override - IMap, User> - get remoteUsers; // Historical remote users - @override - IMap, User> - get historicalRemoteUsers; // Unknown users - @override - IMap, User> get unknownUsers; // Messages state - @override - AsyncValue> get messageWindow; // Title of the chat - @override - String get title; + $Res call({ + Object? chatKey = null, + Object? scrollController = null, + Object? textEditingController = null, + Object? localUser = freezed, + Object? remoteUsers = null, + Object? historicalRemoteUsers = null, + Object? unknownUsers = null, + Object? messageWindow = null, + Object? title = null, + }) { + return _then(_ChatComponentState( + chatKey: null == chatKey + ? _self.chatKey + : chatKey // ignore: cast_nullable_to_non_nullable + as GlobalKey, + scrollController: null == scrollController + ? _self.scrollController + : scrollController // ignore: cast_nullable_to_non_nullable + as AutoScrollController, + textEditingController: null == textEditingController + ? _self.textEditingController + : textEditingController // ignore: cast_nullable_to_non_nullable + as InputTextFieldController, + localUser: freezed == localUser + ? _self.localUser + : localUser // ignore: cast_nullable_to_non_nullable + as User?, + remoteUsers: null == remoteUsers + ? _self.remoteUsers + : remoteUsers // ignore: cast_nullable_to_non_nullable + as IMap, User>, + historicalRemoteUsers: null == historicalRemoteUsers + ? _self.historicalRemoteUsers + : historicalRemoteUsers // ignore: cast_nullable_to_non_nullable + as IMap, User>, + unknownUsers: null == unknownUsers + ? _self.unknownUsers + : unknownUsers // ignore: cast_nullable_to_non_nullable + as IMap, User>, + messageWindow: null == messageWindow + ? _self.messageWindow + : messageWindow // ignore: cast_nullable_to_non_nullable + as AsyncValue>, + title: null == title + ? _self.title + : title // ignore: cast_nullable_to_non_nullable + as String, + )); + } /// Create a copy of ChatComponentState /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$ChatComponentStateImplCopyWith<_$ChatComponentStateImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + $AsyncValueCopyWith, $Res> get messageWindow { + return $AsyncValueCopyWith, $Res>(_self.messageWindow, + (value) { + return _then(_self.copyWith(messageWindow: value)); + }); + } } + +// dart format on diff --git a/lib/chat/models/message_state.dart b/lib/chat/models/message_state.dart index 8eacc8e..cf82021 100644 --- a/lib/chat/models/message_state.dart +++ b/lib/chat/models/message_state.dart @@ -24,7 +24,7 @@ enum MessageSendState { } @freezed -class MessageState with _$MessageState { +sealed class MessageState with _$MessageState { const factory MessageState({ // Content of the message @JsonKey(fromJson: messageFromJson, toJson: messageToJson) diff --git a/lib/chat/models/message_state.freezed.dart b/lib/chat/models/message_state.freezed.dart index baafea6..0900f8b 100644 --- a/lib/chat/models/message_state.freezed.dart +++ b/lib/chat/models/message_state.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,99 +10,69 @@ part of 'message_state.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -MessageState _$MessageStateFromJson(Map json) { - return _MessageState.fromJson(json); -} - /// @nodoc -mixin _$MessageState { +mixin _$MessageState implements DiagnosticableTreeMixin { // Content of the message @JsonKey(fromJson: messageFromJson, toJson: messageToJson) - proto.Message get content => - throw _privateConstructorUsedError; // Sent timestamp - Timestamp get sentTimestamp => - throw _privateConstructorUsedError; // Reconciled timestamp - Timestamp? get reconciledTimestamp => - throw _privateConstructorUsedError; // The state of the message - MessageSendState? get sendState => throw _privateConstructorUsedError; - - /// Serializes this MessageState to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + proto.Message get content; // Sent timestamp + Timestamp get sentTimestamp; // Reconciled timestamp + Timestamp? get reconciledTimestamp; // The state of the message + MessageSendState? get sendState; /// Create a copy of MessageState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) - $MessageStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $MessageStateCopyWith<$Res> { - factory $MessageStateCopyWith( - MessageState value, $Res Function(MessageState) then) = - _$MessageStateCopyWithImpl<$Res, MessageState>; - @useResult - $Res call( - {@JsonKey(fromJson: messageFromJson, toJson: messageToJson) - proto.Message content, - Timestamp sentTimestamp, - Timestamp? reconciledTimestamp, - MessageSendState? sendState}); -} - -/// @nodoc -class _$MessageStateCopyWithImpl<$Res, $Val extends MessageState> - implements $MessageStateCopyWith<$Res> { - _$MessageStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') + $MessageStateCopyWith get copyWith => + _$MessageStateCopyWithImpl( + this as MessageState, _$identity); + + /// Serializes this MessageState to a JSON map. + Map toJson(); + @override - $Res call({ - Object? content = null, - Object? sentTimestamp = null, - Object? reconciledTimestamp = freezed, - Object? sendState = freezed, - }) { - return _then(_value.copyWith( - content: null == content - ? _value.content - : content // ignore: cast_nullable_to_non_nullable - as proto.Message, - sentTimestamp: null == sentTimestamp - ? _value.sentTimestamp - : sentTimestamp // ignore: cast_nullable_to_non_nullable - as Timestamp, - reconciledTimestamp: freezed == reconciledTimestamp - ? _value.reconciledTimestamp - : reconciledTimestamp // ignore: cast_nullable_to_non_nullable - as Timestamp?, - sendState: freezed == sendState - ? _value.sendState - : sendState // ignore: cast_nullable_to_non_nullable - as MessageSendState?, - ) as $Val); + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + properties + ..add(DiagnosticsProperty('type', 'MessageState')) + ..add(DiagnosticsProperty('content', content)) + ..add(DiagnosticsProperty('sentTimestamp', sentTimestamp)) + ..add(DiagnosticsProperty('reconciledTimestamp', reconciledTimestamp)) + ..add(DiagnosticsProperty('sendState', sendState)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is MessageState && + (identical(other.content, content) || other.content == content) && + (identical(other.sentTimestamp, sentTimestamp) || + other.sentTimestamp == sentTimestamp) && + (identical(other.reconciledTimestamp, reconciledTimestamp) || + other.reconciledTimestamp == reconciledTimestamp) && + (identical(other.sendState, sendState) || + other.sendState == sendState)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, content, sentTimestamp, reconciledTimestamp, sendState); + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'MessageState(content: $content, sentTimestamp: $sentTimestamp, reconciledTimestamp: $reconciledTimestamp, sendState: $sendState)'; } } /// @nodoc -abstract class _$$MessageStateImplCopyWith<$Res> - implements $MessageStateCopyWith<$Res> { - factory _$$MessageStateImplCopyWith( - _$MessageStateImpl value, $Res Function(_$MessageStateImpl) then) = - __$$MessageStateImplCopyWithImpl<$Res>; - @override +abstract mixin class $MessageStateCopyWith<$Res> { + factory $MessageStateCopyWith( + MessageState value, $Res Function(MessageState) _then) = + _$MessageStateCopyWithImpl; @useResult $Res call( {@JsonKey(fromJson: messageFromJson, toJson: messageToJson) @@ -112,12 +83,11 @@ abstract class _$$MessageStateImplCopyWith<$Res> } /// @nodoc -class __$$MessageStateImplCopyWithImpl<$Res> - extends _$MessageStateCopyWithImpl<$Res, _$MessageStateImpl> - implements _$$MessageStateImplCopyWith<$Res> { - __$$MessageStateImplCopyWithImpl( - _$MessageStateImpl _value, $Res Function(_$MessageStateImpl) _then) - : super(_value, _then); +class _$MessageStateCopyWithImpl<$Res> implements $MessageStateCopyWith<$Res> { + _$MessageStateCopyWithImpl(this._self, this._then); + + final MessageState _self; + final $Res Function(MessageState) _then; /// Create a copy of MessageState /// with the given fields replaced by the non-null parameter values. @@ -129,21 +99,21 @@ class __$$MessageStateImplCopyWithImpl<$Res> Object? reconciledTimestamp = freezed, Object? sendState = freezed, }) { - return _then(_$MessageStateImpl( + return _then(_self.copyWith( content: null == content - ? _value.content + ? _self.content : content // ignore: cast_nullable_to_non_nullable as proto.Message, sentTimestamp: null == sentTimestamp - ? _value.sentTimestamp + ? _self.sentTimestamp : sentTimestamp // ignore: cast_nullable_to_non_nullable as Timestamp, reconciledTimestamp: freezed == reconciledTimestamp - ? _value.reconciledTimestamp + ? _self.reconciledTimestamp : reconciledTimestamp // ignore: cast_nullable_to_non_nullable as Timestamp?, sendState: freezed == sendState - ? _value.sendState + ? _self.sendState : sendState // ignore: cast_nullable_to_non_nullable as MessageSendState?, )); @@ -152,16 +122,15 @@ class __$$MessageStateImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$MessageStateImpl with DiagnosticableTreeMixin implements _MessageState { - const _$MessageStateImpl( +class _MessageState with DiagnosticableTreeMixin implements MessageState { + const _MessageState( {@JsonKey(fromJson: messageFromJson, toJson: messageToJson) required this.content, required this.sentTimestamp, required this.reconciledTimestamp, required this.sendState}); - - factory _$MessageStateImpl.fromJson(Map json) => - _$$MessageStateImplFromJson(json); + factory _MessageState.fromJson(Map json) => + _$MessageStateFromJson(json); // Content of the message @override @@ -177,14 +146,23 @@ class _$MessageStateImpl with DiagnosticableTreeMixin implements _MessageState { @override final MessageSendState? sendState; + /// Create a copy of MessageState + /// with the given fields replaced by the non-null parameter values. @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'MessageState(content: $content, sentTimestamp: $sentTimestamp, reconciledTimestamp: $reconciledTimestamp, sendState: $sendState)'; + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$MessageStateCopyWith<_MessageState> get copyWith => + __$MessageStateCopyWithImpl<_MessageState>(this, _$identity); + + @override + Map toJson() { + return _$MessageStateToJson( + this, + ); } @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); properties ..add(DiagnosticsProperty('type', 'MessageState')) ..add(DiagnosticsProperty('content', content)) @@ -197,7 +175,7 @@ class _$MessageStateImpl with DiagnosticableTreeMixin implements _MessageState { bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$MessageStateImpl && + other is _MessageState && (identical(other.content, content) || other.content == content) && (identical(other.sentTimestamp, sentTimestamp) || other.sentTimestamp == sentTimestamp) && @@ -212,48 +190,65 @@ class _$MessageStateImpl with DiagnosticableTreeMixin implements _MessageState { int get hashCode => Object.hash( runtimeType, content, sentTimestamp, reconciledTimestamp, sendState); - /// Create a copy of MessageState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$MessageStateImplCopyWith<_$MessageStateImpl> get copyWith => - __$$MessageStateImplCopyWithImpl<_$MessageStateImpl>(this, _$identity); - - @override - Map toJson() { - return _$$MessageStateImplToJson( - this, - ); + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'MessageState(content: $content, sentTimestamp: $sentTimestamp, reconciledTimestamp: $reconciledTimestamp, sendState: $sendState)'; } } -abstract class _MessageState implements MessageState { - const factory _MessageState( +/// @nodoc +abstract mixin class _$MessageStateCopyWith<$Res> + implements $MessageStateCopyWith<$Res> { + factory _$MessageStateCopyWith( + _MessageState value, $Res Function(_MessageState) _then) = + __$MessageStateCopyWithImpl; + @override + @useResult + $Res call( {@JsonKey(fromJson: messageFromJson, toJson: messageToJson) - required final proto.Message content, - required final Timestamp sentTimestamp, - required final Timestamp? reconciledTimestamp, - required final MessageSendState? sendState}) = _$MessageStateImpl; + proto.Message content, + Timestamp sentTimestamp, + Timestamp? reconciledTimestamp, + MessageSendState? sendState}); +} - factory _MessageState.fromJson(Map json) = - _$MessageStateImpl.fromJson; +/// @nodoc +class __$MessageStateCopyWithImpl<$Res> + implements _$MessageStateCopyWith<$Res> { + __$MessageStateCopyWithImpl(this._self, this._then); -// Content of the message - @override - @JsonKey(fromJson: messageFromJson, toJson: messageToJson) - proto.Message get content; // Sent timestamp - @override - Timestamp get sentTimestamp; // Reconciled timestamp - @override - Timestamp? get reconciledTimestamp; // The state of the message - @override - MessageSendState? get sendState; + final _MessageState _self; + final $Res Function(_MessageState) _then; /// Create a copy of MessageState /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$MessageStateImplCopyWith<_$MessageStateImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + $Res call({ + Object? content = null, + Object? sentTimestamp = null, + Object? reconciledTimestamp = freezed, + Object? sendState = freezed, + }) { + return _then(_MessageState( + content: null == content + ? _self.content + : content // ignore: cast_nullable_to_non_nullable + as proto.Message, + sentTimestamp: null == sentTimestamp + ? _self.sentTimestamp + : sentTimestamp // ignore: cast_nullable_to_non_nullable + as Timestamp, + reconciledTimestamp: freezed == reconciledTimestamp + ? _self.reconciledTimestamp + : reconciledTimestamp // ignore: cast_nullable_to_non_nullable + as Timestamp?, + sendState: freezed == sendState + ? _self.sendState + : sendState // ignore: cast_nullable_to_non_nullable + as MessageSendState?, + )); + } } + +// dart format on diff --git a/lib/chat/models/message_state.g.dart b/lib/chat/models/message_state.g.dart index 99899a7..daae37f 100644 --- a/lib/chat/models/message_state.g.dart +++ b/lib/chat/models/message_state.g.dart @@ -6,8 +6,8 @@ part of 'message_state.dart'; // JsonSerializableGenerator // ************************************************************************** -_$MessageStateImpl _$$MessageStateImplFromJson(Map json) => - _$MessageStateImpl( +_MessageState _$MessageStateFromJson(Map json) => + _MessageState( content: messageFromJson(json['content'] as Map), sentTimestamp: Timestamp.fromJson(json['sent_timestamp']), reconciledTimestamp: json['reconciled_timestamp'] == null @@ -18,7 +18,7 @@ _$MessageStateImpl _$$MessageStateImplFromJson(Map json) => : MessageSendState.fromJson(json['send_state']), ); -Map _$$MessageStateImplToJson(_$MessageStateImpl instance) => +Map _$MessageStateToJson(_MessageState instance) => { 'content': messageToJson(instance.content), 'sent_timestamp': instance.sentTimestamp.toJson(), diff --git a/lib/chat/models/window_state.dart b/lib/chat/models/window_state.dart index 91cde8a..14a94a5 100644 --- a/lib/chat/models/window_state.dart +++ b/lib/chat/models/window_state.dart @@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; part 'window_state.freezed.dart'; @freezed -class WindowState with _$WindowState { +sealed class WindowState with _$WindowState { const factory WindowState({ // List of objects in the window required IList window, diff --git a/lib/chat/models/window_state.freezed.dart b/lib/chat/models/window_state.freezed.dart index 59ff754..38a2ec1 100644 --- a/lib/chat/models/window_state.freezed.dart +++ b/lib/chat/models/window_state.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,98 +10,71 @@ part of 'window_state.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - /// @nodoc -mixin _$WindowState { +mixin _$WindowState implements DiagnosticableTreeMixin { // List of objects in the window - IList get window => - throw _privateConstructorUsedError; // Total number of objects (windowTail max) - int get length => - throw _privateConstructorUsedError; // One past the end of the last element - int get windowTail => - throw _privateConstructorUsedError; // The total number of elements to try to keep in the window - int get windowCount => - throw _privateConstructorUsedError; // If we should have the tail following the array - bool get follow => throw _privateConstructorUsedError; + IList get window; // Total number of objects (windowTail max) + int get length; // One past the end of the last element + int get windowTail; // The total number of elements to try to keep in the window + int get windowCount; // If we should have the tail following the array + bool get follow; /// Create a copy of WindowState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) - $WindowStateCopyWith> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $WindowStateCopyWith { - factory $WindowStateCopyWith( - WindowState value, $Res Function(WindowState) then) = - _$WindowStateCopyWithImpl>; - @useResult - $Res call( - {IList window, - int length, - int windowTail, - int windowCount, - bool follow}); -} - -/// @nodoc -class _$WindowStateCopyWithImpl> - implements $WindowStateCopyWith { - _$WindowStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of WindowState - /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') + $WindowStateCopyWith> get copyWith => + _$WindowStateCopyWithImpl>( + this as WindowState, _$identity); + @override - $Res call({ - Object? window = null, - Object? length = null, - Object? windowTail = null, - Object? windowCount = null, - Object? follow = null, - }) { - return _then(_value.copyWith( - window: null == window - ? _value.window - : window // ignore: cast_nullable_to_non_nullable - as IList, - length: null == length - ? _value.length - : length // ignore: cast_nullable_to_non_nullable - as int, - windowTail: null == windowTail - ? _value.windowTail - : windowTail // ignore: cast_nullable_to_non_nullable - as int, - windowCount: null == windowCount - ? _value.windowCount - : windowCount // ignore: cast_nullable_to_non_nullable - as int, - follow: null == follow - ? _value.follow - : follow // ignore: cast_nullable_to_non_nullable - as bool, - ) as $Val); + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + properties + ..add(DiagnosticsProperty('type', 'WindowState<$T>')) + ..add(DiagnosticsProperty('window', window)) + ..add(DiagnosticsProperty('length', length)) + ..add(DiagnosticsProperty('windowTail', windowTail)) + ..add(DiagnosticsProperty('windowCount', windowCount)) + ..add(DiagnosticsProperty('follow', follow)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is WindowState && + const DeepCollectionEquality().equals(other.window, window) && + (identical(other.length, length) || other.length == length) && + (identical(other.windowTail, windowTail) || + other.windowTail == windowTail) && + (identical(other.windowCount, windowCount) || + other.windowCount == windowCount) && + (identical(other.follow, follow) || other.follow == follow)); + } + + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(window), + length, + windowTail, + windowCount, + follow); + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'WindowState<$T>(window: $window, length: $length, windowTail: $windowTail, windowCount: $windowCount, follow: $follow)'; } } /// @nodoc -abstract class _$$WindowStateImplCopyWith - implements $WindowStateCopyWith { - factory _$$WindowStateImplCopyWith(_$WindowStateImpl value, - $Res Function(_$WindowStateImpl) then) = - __$$WindowStateImplCopyWithImpl; - @override +abstract mixin class $WindowStateCopyWith { + factory $WindowStateCopyWith( + WindowState value, $Res Function(WindowState) _then) = + _$WindowStateCopyWithImpl; @useResult $Res call( {IList window, @@ -111,12 +85,12 @@ abstract class _$$WindowStateImplCopyWith } /// @nodoc -class __$$WindowStateImplCopyWithImpl - extends _$WindowStateCopyWithImpl> - implements _$$WindowStateImplCopyWith { - __$$WindowStateImplCopyWithImpl( - _$WindowStateImpl _value, $Res Function(_$WindowStateImpl) _then) - : super(_value, _then); +class _$WindowStateCopyWithImpl + implements $WindowStateCopyWith { + _$WindowStateCopyWithImpl(this._self, this._then); + + final WindowState _self; + final $Res Function(WindowState) _then; /// Create a copy of WindowState /// with the given fields replaced by the non-null parameter values. @@ -129,25 +103,25 @@ class __$$WindowStateImplCopyWithImpl Object? windowCount = null, Object? follow = null, }) { - return _then(_$WindowStateImpl( + return _then(_self.copyWith( window: null == window - ? _value.window + ? _self.window : window // ignore: cast_nullable_to_non_nullable as IList, length: null == length - ? _value.length + ? _self.length : length // ignore: cast_nullable_to_non_nullable as int, windowTail: null == windowTail - ? _value.windowTail + ? _self.windowTail : windowTail // ignore: cast_nullable_to_non_nullable as int, windowCount: null == windowCount - ? _value.windowCount + ? _self.windowCount : windowCount // ignore: cast_nullable_to_non_nullable as int, follow: null == follow - ? _value.follow + ? _self.follow : follow // ignore: cast_nullable_to_non_nullable as bool, )); @@ -156,10 +130,8 @@ class __$$WindowStateImplCopyWithImpl /// @nodoc -class _$WindowStateImpl - with DiagnosticableTreeMixin - implements _WindowState { - const _$WindowStateImpl( +class _WindowState with DiagnosticableTreeMixin implements WindowState { + const _WindowState( {required this.window, required this.length, required this.windowTail, @@ -182,14 +154,16 @@ class _$WindowStateImpl @override final bool follow; + /// Create a copy of WindowState + /// with the given fields replaced by the non-null parameter values. @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'WindowState<$T>(window: $window, length: $length, windowTail: $windowTail, windowCount: $windowCount, follow: $follow)'; - } + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$WindowStateCopyWith> get copyWith => + __$WindowStateCopyWithImpl>(this, _$identity); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); properties ..add(DiagnosticsProperty('type', 'WindowState<$T>')) ..add(DiagnosticsProperty('window', window)) @@ -203,7 +177,7 @@ class _$WindowStateImpl bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$WindowStateImpl && + other is _WindowState && const DeepCollectionEquality().equals(other.window, window) && (identical(other.length, length) || other.length == length) && (identical(other.windowTail, windowTail) || @@ -222,40 +196,70 @@ class _$WindowStateImpl windowCount, follow); + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'WindowState<$T>(window: $window, length: $length, windowTail: $windowTail, windowCount: $windowCount, follow: $follow)'; + } +} + +/// @nodoc +abstract mixin class _$WindowStateCopyWith + implements $WindowStateCopyWith { + factory _$WindowStateCopyWith( + _WindowState value, $Res Function(_WindowState) _then) = + __$WindowStateCopyWithImpl; + @override + @useResult + $Res call( + {IList window, + int length, + int windowTail, + int windowCount, + bool follow}); +} + +/// @nodoc +class __$WindowStateCopyWithImpl + implements _$WindowStateCopyWith { + __$WindowStateCopyWithImpl(this._self, this._then); + + final _WindowState _self; + final $Res Function(_WindowState) _then; + /// Create a copy of WindowState /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') - _$$WindowStateImplCopyWith> get copyWith => - __$$WindowStateImplCopyWithImpl>( - this, _$identity); + $Res call({ + Object? window = null, + Object? length = null, + Object? windowTail = null, + Object? windowCount = null, + Object? follow = null, + }) { + return _then(_WindowState( + window: null == window + ? _self.window + : window // ignore: cast_nullable_to_non_nullable + as IList, + length: null == length + ? _self.length + : length // ignore: cast_nullable_to_non_nullable + as int, + windowTail: null == windowTail + ? _self.windowTail + : windowTail // ignore: cast_nullable_to_non_nullable + as int, + windowCount: null == windowCount + ? _self.windowCount + : windowCount // ignore: cast_nullable_to_non_nullable + as int, + follow: null == follow + ? _self.follow + : follow // ignore: cast_nullable_to_non_nullable + as bool, + )); + } } -abstract class _WindowState implements WindowState { - const factory _WindowState( - {required final IList window, - required final int length, - required final int windowTail, - required final int windowCount, - required final bool follow}) = _$WindowStateImpl; - -// List of objects in the window - @override - IList get window; // Total number of objects (windowTail max) - @override - int get length; // One past the end of the last element - @override - int get windowTail; // The total number of elements to try to keep in the window - @override - int get windowCount; // If we should have the tail following the array - @override - bool get follow; - - /// Create a copy of WindowState - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$WindowStateImplCopyWith> get copyWith => - throw _privateConstructorUsedError; -} +// dart format on diff --git a/lib/chat_list/cubits/chat_list_cubit.dart b/lib/chat_list/cubits/chat_list_cubit.dart index 3ae3db1..ae31f29 100644 --- a/lib/chat_list/cubits/chat_list_cubit.dart +++ b/lib/chat_list/cubits/chat_list_cubit.dart @@ -13,7 +13,7 @@ import '../../proto/proto.dart' as proto; ////////////////////////////////////////////////// // Mutable state for per-account chat list -typedef ChatListCubitState = DHTShortArrayBusyState; +typedef ChatListCubitState = DHTShortArrayCubitState; class ChatListCubit extends DHTShortArrayCubit with StateMapFollowable { diff --git a/lib/chat_list/views/chat_list_widget.dart b/lib/chat_list/views/chat_list_widget.dart index 73bd7e6..cce416c 100644 --- a/lib/chat_list/views/chat_list_widget.dart +++ b/lib/chat_list/views/chat_list_widget.dart @@ -8,7 +8,6 @@ import 'package:veilid_support/veilid_support.dart'; import '../../contacts/contacts.dart'; import '../../proto/proto.dart' as proto; -import '../../proto/proto.dart'; import '../../theme/theme.dart'; import '../chat_list.dart'; @@ -26,7 +25,7 @@ class ChatListWidget extends StatelessWidget { } List _itemFilter(IMap contactMap, - IList> chatList, String filter) { + IList> chatList, String filter) { final lowerValue = filter.toLowerCase(); return chatList.map((x) => x.value).where((c) { switch (c.whichKind()) { @@ -48,7 +47,6 @@ class ChatListWidget extends StatelessWidget { } @override - // ignore: prefer_expression_function_bodies Widget build(BuildContext context) { final contactListV = context.watch().state; diff --git a/lib/contact_invitation/cubits/contact_invitation_list_cubit.dart b/lib/contact_invitation/cubits/contact_invitation_list_cubit.dart index 768cf2f..332341d 100644 --- a/lib/contact_invitation/cubits/contact_invitation_list_cubit.dart +++ b/lib/contact_invitation/cubits/contact_invitation_list_cubit.dart @@ -27,7 +27,7 @@ typedef GetEncryptionKeyCallback = Future Function( ////////////////////////////////////////////////// typedef ContactInvitiationListState - = DHTShortArrayBusyState; + = DHTShortArrayCubitState; ////////////////////////////////////////////////// // Mutable state for per-account contact invitations diff --git a/lib/contact_invitation/cubits/waiting_invitations_bloc_map_cubit.dart b/lib/contact_invitation/cubits/waiting_invitations_bloc_map_cubit.dart index 953575d..197ba8c 100644 --- a/lib/contact_invitation/cubits/waiting_invitations_bloc_map_cubit.dart +++ b/lib/contact_invitation/cubits/waiting_invitations_bloc_map_cubit.dart @@ -18,7 +18,7 @@ typedef WaitingInvitationsBlocMapState class WaitingInvitationsBlocMapCubit extends BlocMapCubit, WaitingInvitationCubit> with - StateMapFollower, + StateMapFollower, TypedKey, proto.ContactInvitationRecord> { WaitingInvitationsBlocMapCubit( {required AccountInfo accountInfo, diff --git a/lib/notifications/models/notifications_preference.dart b/lib/notifications/models/notifications_preference.dart index 35385c6..913cb25 100644 --- a/lib/notifications/models/notifications_preference.dart +++ b/lib/notifications/models/notifications_preference.dart @@ -5,7 +5,7 @@ part 'notifications_preference.freezed.dart'; part 'notifications_preference.g.dart'; @freezed -class NotificationsPreference with _$NotificationsPreference { +sealed class NotificationsPreference with _$NotificationsPreference { const factory NotificationsPreference({ @Default(true) bool displayBetaWarning, @Default(true) bool enableBadge, diff --git a/lib/notifications/models/notifications_preference.freezed.dart b/lib/notifications/models/notifications_preference.freezed.dart index 0335ad8..55f700a 100644 --- a/lib/notifications/models/notifications_preference.freezed.dart +++ b/lib/notifications/models/notifications_preference.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,270 +10,37 @@ part of 'notifications_preference.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -NotificationsPreference _$NotificationsPreferenceFromJson( - Map json) { - return _NotificationsPreference.fromJson(json); -} - /// @nodoc mixin _$NotificationsPreference { - bool get displayBetaWarning => throw _privateConstructorUsedError; - bool get enableBadge => throw _privateConstructorUsedError; - bool get enableNotifications => throw _privateConstructorUsedError; - MessageNotificationContent get messageNotificationContent => - throw _privateConstructorUsedError; - NotificationMode get onInvitationAcceptedMode => - throw _privateConstructorUsedError; - SoundEffect get onInvitationAcceptedSound => - throw _privateConstructorUsedError; - NotificationMode get onMessageReceivedMode => - throw _privateConstructorUsedError; - SoundEffect get onMessageReceivedSound => throw _privateConstructorUsedError; - SoundEffect get onMessageSentSound => throw _privateConstructorUsedError; - - /// Serializes this NotificationsPreference to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + bool get displayBetaWarning; + bool get enableBadge; + bool get enableNotifications; + MessageNotificationContent get messageNotificationContent; + NotificationMode get onInvitationAcceptedMode; + SoundEffect get onInvitationAcceptedSound; + NotificationMode get onMessageReceivedMode; + SoundEffect get onMessageReceivedSound; + SoundEffect get onMessageSentSound; /// Create a copy of NotificationsPreference /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $NotificationsPreferenceCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$NotificationsPreferenceCopyWithImpl( + this as NotificationsPreference, _$identity); -/// @nodoc -abstract class $NotificationsPreferenceCopyWith<$Res> { - factory $NotificationsPreferenceCopyWith(NotificationsPreference value, - $Res Function(NotificationsPreference) then) = - _$NotificationsPreferenceCopyWithImpl<$Res, NotificationsPreference>; - @useResult - $Res call( - {bool displayBetaWarning, - bool enableBadge, - bool enableNotifications, - MessageNotificationContent messageNotificationContent, - NotificationMode onInvitationAcceptedMode, - SoundEffect onInvitationAcceptedSound, - NotificationMode onMessageReceivedMode, - SoundEffect onMessageReceivedSound, - SoundEffect onMessageSentSound}); -} - -/// @nodoc -class _$NotificationsPreferenceCopyWithImpl<$Res, - $Val extends NotificationsPreference> - implements $NotificationsPreferenceCopyWith<$Res> { - _$NotificationsPreferenceCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of NotificationsPreference - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? displayBetaWarning = null, - Object? enableBadge = null, - Object? enableNotifications = null, - Object? messageNotificationContent = null, - Object? onInvitationAcceptedMode = null, - Object? onInvitationAcceptedSound = null, - Object? onMessageReceivedMode = null, - Object? onMessageReceivedSound = null, - Object? onMessageSentSound = null, - }) { - return _then(_value.copyWith( - displayBetaWarning: null == displayBetaWarning - ? _value.displayBetaWarning - : displayBetaWarning // ignore: cast_nullable_to_non_nullable - as bool, - enableBadge: null == enableBadge - ? _value.enableBadge - : enableBadge // ignore: cast_nullable_to_non_nullable - as bool, - enableNotifications: null == enableNotifications - ? _value.enableNotifications - : enableNotifications // ignore: cast_nullable_to_non_nullable - as bool, - messageNotificationContent: null == messageNotificationContent - ? _value.messageNotificationContent - : messageNotificationContent // ignore: cast_nullable_to_non_nullable - as MessageNotificationContent, - onInvitationAcceptedMode: null == onInvitationAcceptedMode - ? _value.onInvitationAcceptedMode - : onInvitationAcceptedMode // ignore: cast_nullable_to_non_nullable - as NotificationMode, - onInvitationAcceptedSound: null == onInvitationAcceptedSound - ? _value.onInvitationAcceptedSound - : onInvitationAcceptedSound // ignore: cast_nullable_to_non_nullable - as SoundEffect, - onMessageReceivedMode: null == onMessageReceivedMode - ? _value.onMessageReceivedMode - : onMessageReceivedMode // ignore: cast_nullable_to_non_nullable - as NotificationMode, - onMessageReceivedSound: null == onMessageReceivedSound - ? _value.onMessageReceivedSound - : onMessageReceivedSound // ignore: cast_nullable_to_non_nullable - as SoundEffect, - onMessageSentSound: null == onMessageSentSound - ? _value.onMessageSentSound - : onMessageSentSound // ignore: cast_nullable_to_non_nullable - as SoundEffect, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$NotificationsPreferenceImplCopyWith<$Res> - implements $NotificationsPreferenceCopyWith<$Res> { - factory _$$NotificationsPreferenceImplCopyWith( - _$NotificationsPreferenceImpl value, - $Res Function(_$NotificationsPreferenceImpl) then) = - __$$NotificationsPreferenceImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {bool displayBetaWarning, - bool enableBadge, - bool enableNotifications, - MessageNotificationContent messageNotificationContent, - NotificationMode onInvitationAcceptedMode, - SoundEffect onInvitationAcceptedSound, - NotificationMode onMessageReceivedMode, - SoundEffect onMessageReceivedSound, - SoundEffect onMessageSentSound}); -} - -/// @nodoc -class __$$NotificationsPreferenceImplCopyWithImpl<$Res> - extends _$NotificationsPreferenceCopyWithImpl<$Res, - _$NotificationsPreferenceImpl> - implements _$$NotificationsPreferenceImplCopyWith<$Res> { - __$$NotificationsPreferenceImplCopyWithImpl( - _$NotificationsPreferenceImpl _value, - $Res Function(_$NotificationsPreferenceImpl) _then) - : super(_value, _then); - - /// Create a copy of NotificationsPreference - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? displayBetaWarning = null, - Object? enableBadge = null, - Object? enableNotifications = null, - Object? messageNotificationContent = null, - Object? onInvitationAcceptedMode = null, - Object? onInvitationAcceptedSound = null, - Object? onMessageReceivedMode = null, - Object? onMessageReceivedSound = null, - Object? onMessageSentSound = null, - }) { - return _then(_$NotificationsPreferenceImpl( - displayBetaWarning: null == displayBetaWarning - ? _value.displayBetaWarning - : displayBetaWarning // ignore: cast_nullable_to_non_nullable - as bool, - enableBadge: null == enableBadge - ? _value.enableBadge - : enableBadge // ignore: cast_nullable_to_non_nullable - as bool, - enableNotifications: null == enableNotifications - ? _value.enableNotifications - : enableNotifications // ignore: cast_nullable_to_non_nullable - as bool, - messageNotificationContent: null == messageNotificationContent - ? _value.messageNotificationContent - : messageNotificationContent // ignore: cast_nullable_to_non_nullable - as MessageNotificationContent, - onInvitationAcceptedMode: null == onInvitationAcceptedMode - ? _value.onInvitationAcceptedMode - : onInvitationAcceptedMode // ignore: cast_nullable_to_non_nullable - as NotificationMode, - onInvitationAcceptedSound: null == onInvitationAcceptedSound - ? _value.onInvitationAcceptedSound - : onInvitationAcceptedSound // ignore: cast_nullable_to_non_nullable - as SoundEffect, - onMessageReceivedMode: null == onMessageReceivedMode - ? _value.onMessageReceivedMode - : onMessageReceivedMode // ignore: cast_nullable_to_non_nullable - as NotificationMode, - onMessageReceivedSound: null == onMessageReceivedSound - ? _value.onMessageReceivedSound - : onMessageReceivedSound // ignore: cast_nullable_to_non_nullable - as SoundEffect, - onMessageSentSound: null == onMessageSentSound - ? _value.onMessageSentSound - : onMessageSentSound // ignore: cast_nullable_to_non_nullable - as SoundEffect, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$NotificationsPreferenceImpl implements _NotificationsPreference { - const _$NotificationsPreferenceImpl( - {this.displayBetaWarning = true, - this.enableBadge = true, - this.enableNotifications = true, - this.messageNotificationContent = - MessageNotificationContent.nameAndContent, - this.onInvitationAcceptedMode = NotificationMode.inAppOrPush, - this.onInvitationAcceptedSound = SoundEffect.beepBaDeep, - this.onMessageReceivedMode = NotificationMode.inAppOrPush, - this.onMessageReceivedSound = SoundEffect.boop, - this.onMessageSentSound = SoundEffect.bonk}); - - factory _$NotificationsPreferenceImpl.fromJson(Map json) => - _$$NotificationsPreferenceImplFromJson(json); - - @override - @JsonKey() - final bool displayBetaWarning; - @override - @JsonKey() - final bool enableBadge; - @override - @JsonKey() - final bool enableNotifications; - @override - @JsonKey() - final MessageNotificationContent messageNotificationContent; - @override - @JsonKey() - final NotificationMode onInvitationAcceptedMode; - @override - @JsonKey() - final SoundEffect onInvitationAcceptedSound; - @override - @JsonKey() - final NotificationMode onMessageReceivedMode; - @override - @JsonKey() - final SoundEffect onMessageReceivedSound; - @override - @JsonKey() - final SoundEffect onMessageSentSound; - - @override - String toString() { - return 'NotificationsPreference(displayBetaWarning: $displayBetaWarning, enableBadge: $enableBadge, enableNotifications: $enableNotifications, messageNotificationContent: $messageNotificationContent, onInvitationAcceptedMode: $onInvitationAcceptedMode, onInvitationAcceptedSound: $onInvitationAcceptedSound, onMessageReceivedMode: $onMessageReceivedMode, onMessageReceivedSound: $onMessageReceivedSound, onMessageSentSound: $onMessageSentSound)'; - } + /// Serializes this NotificationsPreference to a JSON map. + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$NotificationsPreferenceImpl && + other is NotificationsPreference && (identical(other.displayBetaWarning, displayBetaWarning) || other.displayBetaWarning == displayBetaWarning) && (identical(other.enableBadge, enableBadge) || @@ -311,61 +79,286 @@ class _$NotificationsPreferenceImpl implements _NotificationsPreference { onMessageReceivedSound, onMessageSentSound); - /// Create a copy of NotificationsPreference - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$NotificationsPreferenceImplCopyWith<_$NotificationsPreferenceImpl> - get copyWith => __$$NotificationsPreferenceImplCopyWithImpl< - _$NotificationsPreferenceImpl>(this, _$identity); - - @override - Map toJson() { - return _$$NotificationsPreferenceImplToJson( - this, - ); + String toString() { + return 'NotificationsPreference(displayBetaWarning: $displayBetaWarning, enableBadge: $enableBadge, enableNotifications: $enableNotifications, messageNotificationContent: $messageNotificationContent, onInvitationAcceptedMode: $onInvitationAcceptedMode, onInvitationAcceptedSound: $onInvitationAcceptedSound, onMessageReceivedMode: $onMessageReceivedMode, onMessageReceivedSound: $onMessageReceivedSound, onMessageSentSound: $onMessageSentSound)'; } } -abstract class _NotificationsPreference implements NotificationsPreference { - const factory _NotificationsPreference( - {final bool displayBetaWarning, - final bool enableBadge, - final bool enableNotifications, - final MessageNotificationContent messageNotificationContent, - final NotificationMode onInvitationAcceptedMode, - final SoundEffect onInvitationAcceptedSound, - final NotificationMode onMessageReceivedMode, - final SoundEffect onMessageReceivedSound, - final SoundEffect onMessageSentSound}) = _$NotificationsPreferenceImpl; +/// @nodoc +abstract mixin class $NotificationsPreferenceCopyWith<$Res> { + factory $NotificationsPreferenceCopyWith(NotificationsPreference value, + $Res Function(NotificationsPreference) _then) = + _$NotificationsPreferenceCopyWithImpl; + @useResult + $Res call( + {bool displayBetaWarning, + bool enableBadge, + bool enableNotifications, + MessageNotificationContent messageNotificationContent, + NotificationMode onInvitationAcceptedMode, + SoundEffect onInvitationAcceptedSound, + NotificationMode onMessageReceivedMode, + SoundEffect onMessageReceivedSound, + SoundEffect onMessageSentSound}); +} - factory _NotificationsPreference.fromJson(Map json) = - _$NotificationsPreferenceImpl.fromJson; +/// @nodoc +class _$NotificationsPreferenceCopyWithImpl<$Res> + implements $NotificationsPreferenceCopyWith<$Res> { + _$NotificationsPreferenceCopyWithImpl(this._self, this._then); + + final NotificationsPreference _self; + final $Res Function(NotificationsPreference) _then; + + /// Create a copy of NotificationsPreference + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? displayBetaWarning = null, + Object? enableBadge = null, + Object? enableNotifications = null, + Object? messageNotificationContent = null, + Object? onInvitationAcceptedMode = null, + Object? onInvitationAcceptedSound = null, + Object? onMessageReceivedMode = null, + Object? onMessageReceivedSound = null, + Object? onMessageSentSound = null, + }) { + return _then(_self.copyWith( + displayBetaWarning: null == displayBetaWarning + ? _self.displayBetaWarning + : displayBetaWarning // ignore: cast_nullable_to_non_nullable + as bool, + enableBadge: null == enableBadge + ? _self.enableBadge + : enableBadge // ignore: cast_nullable_to_non_nullable + as bool, + enableNotifications: null == enableNotifications + ? _self.enableNotifications + : enableNotifications // ignore: cast_nullable_to_non_nullable + as bool, + messageNotificationContent: null == messageNotificationContent + ? _self.messageNotificationContent + : messageNotificationContent // ignore: cast_nullable_to_non_nullable + as MessageNotificationContent, + onInvitationAcceptedMode: null == onInvitationAcceptedMode + ? _self.onInvitationAcceptedMode + : onInvitationAcceptedMode // ignore: cast_nullable_to_non_nullable + as NotificationMode, + onInvitationAcceptedSound: null == onInvitationAcceptedSound + ? _self.onInvitationAcceptedSound + : onInvitationAcceptedSound // ignore: cast_nullable_to_non_nullable + as SoundEffect, + onMessageReceivedMode: null == onMessageReceivedMode + ? _self.onMessageReceivedMode + : onMessageReceivedMode // ignore: cast_nullable_to_non_nullable + as NotificationMode, + onMessageReceivedSound: null == onMessageReceivedSound + ? _self.onMessageReceivedSound + : onMessageReceivedSound // ignore: cast_nullable_to_non_nullable + as SoundEffect, + onMessageSentSound: null == onMessageSentSound + ? _self.onMessageSentSound + : onMessageSentSound // ignore: cast_nullable_to_non_nullable + as SoundEffect, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _NotificationsPreference implements NotificationsPreference { + const _NotificationsPreference( + {this.displayBetaWarning = true, + this.enableBadge = true, + this.enableNotifications = true, + this.messageNotificationContent = + MessageNotificationContent.nameAndContent, + this.onInvitationAcceptedMode = NotificationMode.inAppOrPush, + this.onInvitationAcceptedSound = SoundEffect.beepBaDeep, + this.onMessageReceivedMode = NotificationMode.inAppOrPush, + this.onMessageReceivedSound = SoundEffect.boop, + this.onMessageSentSound = SoundEffect.bonk}); + factory _NotificationsPreference.fromJson(Map json) => + _$NotificationsPreferenceFromJson(json); @override - bool get displayBetaWarning; + @JsonKey() + final bool displayBetaWarning; @override - bool get enableBadge; + @JsonKey() + final bool enableBadge; @override - bool get enableNotifications; + @JsonKey() + final bool enableNotifications; @override - MessageNotificationContent get messageNotificationContent; + @JsonKey() + final MessageNotificationContent messageNotificationContent; @override - NotificationMode get onInvitationAcceptedMode; + @JsonKey() + final NotificationMode onInvitationAcceptedMode; @override - SoundEffect get onInvitationAcceptedSound; + @JsonKey() + final SoundEffect onInvitationAcceptedSound; @override - NotificationMode get onMessageReceivedMode; + @JsonKey() + final NotificationMode onMessageReceivedMode; @override - SoundEffect get onMessageReceivedSound; + @JsonKey() + final SoundEffect onMessageReceivedSound; @override - SoundEffect get onMessageSentSound; + @JsonKey() + final SoundEffect onMessageSentSound; /// Create a copy of NotificationsPreference /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$NotificationsPreferenceImplCopyWith<_$NotificationsPreferenceImpl> - get copyWith => throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$NotificationsPreferenceCopyWith<_NotificationsPreference> get copyWith => + __$NotificationsPreferenceCopyWithImpl<_NotificationsPreference>( + this, _$identity); + + @override + Map toJson() { + return _$NotificationsPreferenceToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _NotificationsPreference && + (identical(other.displayBetaWarning, displayBetaWarning) || + other.displayBetaWarning == displayBetaWarning) && + (identical(other.enableBadge, enableBadge) || + other.enableBadge == enableBadge) && + (identical(other.enableNotifications, enableNotifications) || + other.enableNotifications == enableNotifications) && + (identical(other.messageNotificationContent, + messageNotificationContent) || + other.messageNotificationContent == + messageNotificationContent) && + (identical( + other.onInvitationAcceptedMode, onInvitationAcceptedMode) || + other.onInvitationAcceptedMode == onInvitationAcceptedMode) && + (identical(other.onInvitationAcceptedSound, + onInvitationAcceptedSound) || + other.onInvitationAcceptedSound == onInvitationAcceptedSound) && + (identical(other.onMessageReceivedMode, onMessageReceivedMode) || + other.onMessageReceivedMode == onMessageReceivedMode) && + (identical(other.onMessageReceivedSound, onMessageReceivedSound) || + other.onMessageReceivedSound == onMessageReceivedSound) && + (identical(other.onMessageSentSound, onMessageSentSound) || + other.onMessageSentSound == onMessageSentSound)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + displayBetaWarning, + enableBadge, + enableNotifications, + messageNotificationContent, + onInvitationAcceptedMode, + onInvitationAcceptedSound, + onMessageReceivedMode, + onMessageReceivedSound, + onMessageSentSound); + + @override + String toString() { + return 'NotificationsPreference(displayBetaWarning: $displayBetaWarning, enableBadge: $enableBadge, enableNotifications: $enableNotifications, messageNotificationContent: $messageNotificationContent, onInvitationAcceptedMode: $onInvitationAcceptedMode, onInvitationAcceptedSound: $onInvitationAcceptedSound, onMessageReceivedMode: $onMessageReceivedMode, onMessageReceivedSound: $onMessageReceivedSound, onMessageSentSound: $onMessageSentSound)'; + } } + +/// @nodoc +abstract mixin class _$NotificationsPreferenceCopyWith<$Res> + implements $NotificationsPreferenceCopyWith<$Res> { + factory _$NotificationsPreferenceCopyWith(_NotificationsPreference value, + $Res Function(_NotificationsPreference) _then) = + __$NotificationsPreferenceCopyWithImpl; + @override + @useResult + $Res call( + {bool displayBetaWarning, + bool enableBadge, + bool enableNotifications, + MessageNotificationContent messageNotificationContent, + NotificationMode onInvitationAcceptedMode, + SoundEffect onInvitationAcceptedSound, + NotificationMode onMessageReceivedMode, + SoundEffect onMessageReceivedSound, + SoundEffect onMessageSentSound}); +} + +/// @nodoc +class __$NotificationsPreferenceCopyWithImpl<$Res> + implements _$NotificationsPreferenceCopyWith<$Res> { + __$NotificationsPreferenceCopyWithImpl(this._self, this._then); + + final _NotificationsPreference _self; + final $Res Function(_NotificationsPreference) _then; + + /// Create a copy of NotificationsPreference + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? displayBetaWarning = null, + Object? enableBadge = null, + Object? enableNotifications = null, + Object? messageNotificationContent = null, + Object? onInvitationAcceptedMode = null, + Object? onInvitationAcceptedSound = null, + Object? onMessageReceivedMode = null, + Object? onMessageReceivedSound = null, + Object? onMessageSentSound = null, + }) { + return _then(_NotificationsPreference( + displayBetaWarning: null == displayBetaWarning + ? _self.displayBetaWarning + : displayBetaWarning // ignore: cast_nullable_to_non_nullable + as bool, + enableBadge: null == enableBadge + ? _self.enableBadge + : enableBadge // ignore: cast_nullable_to_non_nullable + as bool, + enableNotifications: null == enableNotifications + ? _self.enableNotifications + : enableNotifications // ignore: cast_nullable_to_non_nullable + as bool, + messageNotificationContent: null == messageNotificationContent + ? _self.messageNotificationContent + : messageNotificationContent // ignore: cast_nullable_to_non_nullable + as MessageNotificationContent, + onInvitationAcceptedMode: null == onInvitationAcceptedMode + ? _self.onInvitationAcceptedMode + : onInvitationAcceptedMode // ignore: cast_nullable_to_non_nullable + as NotificationMode, + onInvitationAcceptedSound: null == onInvitationAcceptedSound + ? _self.onInvitationAcceptedSound + : onInvitationAcceptedSound // ignore: cast_nullable_to_non_nullable + as SoundEffect, + onMessageReceivedMode: null == onMessageReceivedMode + ? _self.onMessageReceivedMode + : onMessageReceivedMode // ignore: cast_nullable_to_non_nullable + as NotificationMode, + onMessageReceivedSound: null == onMessageReceivedSound + ? _self.onMessageReceivedSound + : onMessageReceivedSound // ignore: cast_nullable_to_non_nullable + as SoundEffect, + onMessageSentSound: null == onMessageSentSound + ? _self.onMessageSentSound + : onMessageSentSound // ignore: cast_nullable_to_non_nullable + as SoundEffect, + )); + } +} + +// dart format on diff --git a/lib/notifications/models/notifications_preference.g.dart b/lib/notifications/models/notifications_preference.g.dart index d22b4b5..d1d5e89 100644 --- a/lib/notifications/models/notifications_preference.g.dart +++ b/lib/notifications/models/notifications_preference.g.dart @@ -6,9 +6,9 @@ part of 'notifications_preference.dart'; // JsonSerializableGenerator // ************************************************************************** -_$NotificationsPreferenceImpl _$$NotificationsPreferenceImplFromJson( +_NotificationsPreference _$NotificationsPreferenceFromJson( Map json) => - _$NotificationsPreferenceImpl( + _NotificationsPreference( displayBetaWarning: json['display_beta_warning'] as bool? ?? true, enableBadge: json['enable_badge'] as bool? ?? true, enableNotifications: json['enable_notifications'] as bool? ?? true, @@ -33,8 +33,8 @@ _$NotificationsPreferenceImpl _$$NotificationsPreferenceImplFromJson( : SoundEffect.fromJson(json['on_message_sent_sound']), ); -Map _$$NotificationsPreferenceImplToJson( - _$NotificationsPreferenceImpl instance) => +Map _$NotificationsPreferenceToJson( + _NotificationsPreference instance) => { 'display_beta_warning': instance.displayBetaWarning, 'enable_badge': instance.enableBadge, diff --git a/lib/notifications/models/notifications_state.dart b/lib/notifications/models/notifications_state.dart index d001ce2..6248bba 100644 --- a/lib/notifications/models/notifications_state.dart +++ b/lib/notifications/models/notifications_state.dart @@ -9,7 +9,7 @@ enum NotificationType { } @freezed -class NotificationItem with _$NotificationItem { +sealed class NotificationItem with _$NotificationItem { const factory NotificationItem( {required NotificationType type, required String text, @@ -17,7 +17,7 @@ class NotificationItem with _$NotificationItem { } @freezed -class NotificationsState with _$NotificationsState { +sealed class NotificationsState with _$NotificationsState { const factory NotificationsState({required IList queue}) = _NotificationsState; } diff --git a/lib/notifications/models/notifications_state.freezed.dart b/lib/notifications/models/notifications_state.freezed.dart index e052e7a..8633702 100644 --- a/lib/notifications/models/notifications_state.freezed.dart +++ b/lib/notifications/models/notifications_state.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,137 +10,28 @@ part of 'notifications_state.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - /// @nodoc mixin _$NotificationItem { - NotificationType get type => throw _privateConstructorUsedError; - String get text => throw _privateConstructorUsedError; - String? get title => throw _privateConstructorUsedError; + NotificationType get type; + String get text; + String? get title; /// Create a copy of NotificationItem /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $NotificationItemCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $NotificationItemCopyWith<$Res> { - factory $NotificationItemCopyWith( - NotificationItem value, $Res Function(NotificationItem) then) = - _$NotificationItemCopyWithImpl<$Res, NotificationItem>; - @useResult - $Res call({NotificationType type, String text, String? title}); -} - -/// @nodoc -class _$NotificationItemCopyWithImpl<$Res, $Val extends NotificationItem> - implements $NotificationItemCopyWith<$Res> { - _$NotificationItemCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of NotificationItem - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? type = null, - Object? text = null, - Object? title = freezed, - }) { - return _then(_value.copyWith( - type: null == type - ? _value.type - : type // ignore: cast_nullable_to_non_nullable - as NotificationType, - text: null == text - ? _value.text - : text // ignore: cast_nullable_to_non_nullable - as String, - title: freezed == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String?, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$NotificationItemImplCopyWith<$Res> - implements $NotificationItemCopyWith<$Res> { - factory _$$NotificationItemImplCopyWith(_$NotificationItemImpl value, - $Res Function(_$NotificationItemImpl) then) = - __$$NotificationItemImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({NotificationType type, String text, String? title}); -} - -/// @nodoc -class __$$NotificationItemImplCopyWithImpl<$Res> - extends _$NotificationItemCopyWithImpl<$Res, _$NotificationItemImpl> - implements _$$NotificationItemImplCopyWith<$Res> { - __$$NotificationItemImplCopyWithImpl(_$NotificationItemImpl _value, - $Res Function(_$NotificationItemImpl) _then) - : super(_value, _then); - - /// Create a copy of NotificationItem - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? type = null, - Object? text = null, - Object? title = freezed, - }) { - return _then(_$NotificationItemImpl( - type: null == type - ? _value.type - : type // ignore: cast_nullable_to_non_nullable - as NotificationType, - text: null == text - ? _value.text - : text // ignore: cast_nullable_to_non_nullable - as String, - title: freezed == title - ? _value.title - : title // ignore: cast_nullable_to_non_nullable - as String?, - )); - } -} - -/// @nodoc - -class _$NotificationItemImpl implements _NotificationItem { - const _$NotificationItemImpl( - {required this.type, required this.text, this.title}); - - @override - final NotificationType type; - @override - final String text; - @override - final String? title; - - @override - String toString() { - return 'NotificationItem(type: $type, text: $text, title: $title)'; - } + _$NotificationItemCopyWithImpl( + this as NotificationItem, _$identity); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$NotificationItemImpl && + other is NotificationItem && (identical(other.type, type) || other.type == type) && (identical(other.text, text) || other.text == text) && (identical(other.title, title) || other.title == title)); @@ -148,101 +40,185 @@ class _$NotificationItemImpl implements _NotificationItem { @override int get hashCode => Object.hash(runtimeType, type, text, title); - /// Create a copy of NotificationItem - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$NotificationItemImplCopyWith<_$NotificationItemImpl> get copyWith => - __$$NotificationItemImplCopyWithImpl<_$NotificationItemImpl>( - this, _$identity); -} - -abstract class _NotificationItem implements NotificationItem { - const factory _NotificationItem( - {required final NotificationType type, - required final String text, - final String? title}) = _$NotificationItemImpl; - - @override - NotificationType get type; - @override - String get text; - @override - String? get title; - - /// Create a copy of NotificationItem - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$NotificationItemImplCopyWith<_$NotificationItemImpl> get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -mixin _$NotificationsState { - IList get queue => throw _privateConstructorUsedError; - - /// Create a copy of NotificationsState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - $NotificationsStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $NotificationsStateCopyWith<$Res> { - factory $NotificationsStateCopyWith( - NotificationsState value, $Res Function(NotificationsState) then) = - _$NotificationsStateCopyWithImpl<$Res, NotificationsState>; - @useResult - $Res call({IList queue}); -} - -/// @nodoc -class _$NotificationsStateCopyWithImpl<$Res, $Val extends NotificationsState> - implements $NotificationsStateCopyWith<$Res> { - _$NotificationsStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of NotificationsState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? queue = null, - }) { - return _then(_value.copyWith( - queue: null == queue - ? _value.queue - : queue // ignore: cast_nullable_to_non_nullable - as IList, - ) as $Val); + String toString() { + return 'NotificationItem(type: $type, text: $text, title: $title)'; } } /// @nodoc -abstract class _$$NotificationsStateImplCopyWith<$Res> - implements $NotificationsStateCopyWith<$Res> { - factory _$$NotificationsStateImplCopyWith(_$NotificationsStateImpl value, - $Res Function(_$NotificationsStateImpl) then) = - __$$NotificationsStateImplCopyWithImpl<$Res>; +abstract mixin class $NotificationItemCopyWith<$Res> { + factory $NotificationItemCopyWith( + NotificationItem value, $Res Function(NotificationItem) _then) = + _$NotificationItemCopyWithImpl; + @useResult + $Res call({NotificationType type, String text, String? title}); +} + +/// @nodoc +class _$NotificationItemCopyWithImpl<$Res> + implements $NotificationItemCopyWith<$Res> { + _$NotificationItemCopyWithImpl(this._self, this._then); + + final NotificationItem _self; + final $Res Function(NotificationItem) _then; + + /// Create a copy of NotificationItem + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') @override + $Res call({ + Object? type = null, + Object? text = null, + Object? title = freezed, + }) { + return _then(_self.copyWith( + type: null == type + ? _self.type + : type // ignore: cast_nullable_to_non_nullable + as NotificationType, + text: null == text + ? _self.text + : text // ignore: cast_nullable_to_non_nullable + as String, + title: freezed == title + ? _self.title + : title // ignore: cast_nullable_to_non_nullable + as String?, + )); + } +} + +/// @nodoc + +class _NotificationItem implements NotificationItem { + const _NotificationItem({required this.type, required this.text, this.title}); + + @override + final NotificationType type; + @override + final String text; + @override + final String? title; + + /// Create a copy of NotificationItem + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$NotificationItemCopyWith<_NotificationItem> get copyWith => + __$NotificationItemCopyWithImpl<_NotificationItem>(this, _$identity); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _NotificationItem && + (identical(other.type, type) || other.type == type) && + (identical(other.text, text) || other.text == text) && + (identical(other.title, title) || other.title == title)); + } + + @override + int get hashCode => Object.hash(runtimeType, type, text, title); + + @override + String toString() { + return 'NotificationItem(type: $type, text: $text, title: $title)'; + } +} + +/// @nodoc +abstract mixin class _$NotificationItemCopyWith<$Res> + implements $NotificationItemCopyWith<$Res> { + factory _$NotificationItemCopyWith( + _NotificationItem value, $Res Function(_NotificationItem) _then) = + __$NotificationItemCopyWithImpl; + @override + @useResult + $Res call({NotificationType type, String text, String? title}); +} + +/// @nodoc +class __$NotificationItemCopyWithImpl<$Res> + implements _$NotificationItemCopyWith<$Res> { + __$NotificationItemCopyWithImpl(this._self, this._then); + + final _NotificationItem _self; + final $Res Function(_NotificationItem) _then; + + /// Create a copy of NotificationItem + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? type = null, + Object? text = null, + Object? title = freezed, + }) { + return _then(_NotificationItem( + type: null == type + ? _self.type + : type // ignore: cast_nullable_to_non_nullable + as NotificationType, + text: null == text + ? _self.text + : text // ignore: cast_nullable_to_non_nullable + as String, + title: freezed == title + ? _self.title + : title // ignore: cast_nullable_to_non_nullable + as String?, + )); + } +} + +/// @nodoc +mixin _$NotificationsState { + IList get queue; + + /// Create a copy of NotificationsState + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $NotificationsStateCopyWith get copyWith => + _$NotificationsStateCopyWithImpl( + this as NotificationsState, _$identity); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is NotificationsState && + const DeepCollectionEquality().equals(other.queue, queue)); + } + + @override + int get hashCode => + Object.hash(runtimeType, const DeepCollectionEquality().hash(queue)); + + @override + String toString() { + return 'NotificationsState(queue: $queue)'; + } +} + +/// @nodoc +abstract mixin class $NotificationsStateCopyWith<$Res> { + factory $NotificationsStateCopyWith( + NotificationsState value, $Res Function(NotificationsState) _then) = + _$NotificationsStateCopyWithImpl; @useResult $Res call({IList queue}); } /// @nodoc -class __$$NotificationsStateImplCopyWithImpl<$Res> - extends _$NotificationsStateCopyWithImpl<$Res, _$NotificationsStateImpl> - implements _$$NotificationsStateImplCopyWith<$Res> { - __$$NotificationsStateImplCopyWithImpl(_$NotificationsStateImpl _value, - $Res Function(_$NotificationsStateImpl) _then) - : super(_value, _then); +class _$NotificationsStateCopyWithImpl<$Res> + implements $NotificationsStateCopyWith<$Res> { + _$NotificationsStateCopyWithImpl(this._self, this._then); + + final NotificationsState _self; + final $Res Function(NotificationsState) _then; /// Create a copy of NotificationsState /// with the given fields replaced by the non-null parameter values. @@ -251,9 +227,9 @@ class __$$NotificationsStateImplCopyWithImpl<$Res> $Res call({ Object? queue = null, }) { - return _then(_$NotificationsStateImpl( + return _then(_self.copyWith( queue: null == queue - ? _value.queue + ? _self.queue : queue // ignore: cast_nullable_to_non_nullable as IList, )); @@ -262,22 +238,25 @@ class __$$NotificationsStateImplCopyWithImpl<$Res> /// @nodoc -class _$NotificationsStateImpl implements _NotificationsState { - const _$NotificationsStateImpl({required this.queue}); +class _NotificationsState implements NotificationsState { + const _NotificationsState({required this.queue}); @override final IList queue; + /// Create a copy of NotificationsState + /// with the given fields replaced by the non-null parameter values. @override - String toString() { - return 'NotificationsState(queue: $queue)'; - } + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$NotificationsStateCopyWith<_NotificationsState> get copyWith => + __$NotificationsStateCopyWithImpl<_NotificationsState>(this, _$identity); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$NotificationsStateImpl && + other is _NotificationsState && const DeepCollectionEquality().equals(other.queue, queue)); } @@ -285,28 +264,45 @@ class _$NotificationsStateImpl implements _NotificationsState { int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(queue)); + @override + String toString() { + return 'NotificationsState(queue: $queue)'; + } +} + +/// @nodoc +abstract mixin class _$NotificationsStateCopyWith<$Res> + implements $NotificationsStateCopyWith<$Res> { + factory _$NotificationsStateCopyWith( + _NotificationsState value, $Res Function(_NotificationsState) _then) = + __$NotificationsStateCopyWithImpl; + @override + @useResult + $Res call({IList queue}); +} + +/// @nodoc +class __$NotificationsStateCopyWithImpl<$Res> + implements _$NotificationsStateCopyWith<$Res> { + __$NotificationsStateCopyWithImpl(this._self, this._then); + + final _NotificationsState _self; + final $Res Function(_NotificationsState) _then; + /// Create a copy of NotificationsState /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') - _$$NotificationsStateImplCopyWith<_$NotificationsStateImpl> get copyWith => - __$$NotificationsStateImplCopyWithImpl<_$NotificationsStateImpl>( - this, _$identity); + $Res call({ + Object? queue = null, + }) { + return _then(_NotificationsState( + queue: null == queue + ? _self.queue + : queue // ignore: cast_nullable_to_non_nullable + as IList, + )); + } } -abstract class _NotificationsState implements NotificationsState { - const factory _NotificationsState( - {required final IList queue}) = - _$NotificationsStateImpl; - - @override - IList get queue; - - /// Create a copy of NotificationsState - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$NotificationsStateImplCopyWith<_$NotificationsStateImpl> get copyWith => - throw _privateConstructorUsedError; -} +// dart format on diff --git a/lib/proto/proto.dart b/lib/proto/proto.dart index 6ad8432..21c988a 100644 --- a/lib/proto/proto.dart +++ b/lib/proto/proto.dart @@ -1,3 +1,6 @@ +import 'package:veilid_support/veilid_support.dart'; +import 'veilidchat.pb.dart' as vcproto; + export 'package:veilid_support/dht_support/proto/proto.dart'; export 'package:veilid_support/proto/proto.dart'; @@ -6,3 +9,292 @@ export 'veilidchat.pb.dart'; export 'veilidchat.pbenum.dart'; export 'veilidchat.pbjson.dart'; export 'veilidchat.pbserver.dart'; + +void registerVeilidchatProtoToDebug() { + dynamic toDebug(dynamic obj) { + if (obj is vcproto.DHTDataReference) { + return { + 'dhtData': obj.dhtData, + 'hash': obj.hash, + }; + } + if (obj is vcproto.BlockStoreDataReference) { + return { + 'block': obj.block, + }; + } + if (obj is vcproto.DataReference) { + return { + 'kind': obj.whichKind(), + if (obj.whichKind() == vcproto.DataReference_Kind.dhtData) + 'dhtData': obj.dhtData, + if (obj.whichKind() == vcproto.DataReference_Kind.blockStoreData) + 'blockStoreData': obj.blockStoreData, + }; + } + if (obj is vcproto.Attachment) { + return { + 'kind': obj.whichKind(), + if (obj.whichKind() == vcproto.Attachment_Kind.media) + 'media': obj.media, + 'signature': obj.signature, + }; + } + if (obj is vcproto.AttachmentMedia) { + return { + 'mime': obj.mime, + 'name': obj.name, + 'content': obj.content, + }; + } + if (obj is vcproto.Permissions) { + return { + 'canAddMembers': obj.canAddMembers, + 'canEditInfo': obj.canEditInfo, + 'moderated': obj.moderated, + }; + } + if (obj is vcproto.Membership) { + return { + 'watchers': obj.watchers, + 'moderated': obj.moderated, + 'talkers': obj.talkers, + 'moderators': obj.moderators, + 'admins': obj.admins, + }; + } + if (obj is vcproto.ChatSettings) { + return { + 'title': obj.title, + 'description': obj.description, + 'icon': obj.icon, + 'defaultExpiration': obj.defaultExpiration, + }; + } + if (obj is vcproto.ChatSettings) { + return { + 'title': obj.title, + 'description': obj.description, + 'icon': obj.icon, + 'defaultExpiration': obj.defaultExpiration, + }; + } + if (obj is vcproto.Message) { + return { + 'id': obj.id, + 'author': obj.author, + 'timestamp': obj.timestamp, + 'kind': obj.whichKind(), + if (obj.whichKind() == vcproto.Message_Kind.text) 'text': obj.text, + if (obj.whichKind() == vcproto.Message_Kind.secret) + 'secret': obj.secret, + if (obj.whichKind() == vcproto.Message_Kind.delete) + 'delete': obj.delete, + if (obj.whichKind() == vcproto.Message_Kind.erase) 'erase': obj.erase, + if (obj.whichKind() == vcproto.Message_Kind.settings) + 'settings': obj.settings, + if (obj.whichKind() == vcproto.Message_Kind.permissions) + 'permissions': obj.permissions, + if (obj.whichKind() == vcproto.Message_Kind.membership) + 'membership': obj.membership, + if (obj.whichKind() == vcproto.Message_Kind.moderation) + 'moderation': obj.moderation, + 'signature': obj.signature, + }; + } + if (obj is vcproto.Message_Text) { + return { + 'text': obj.text, + 'topic': obj.topic, + 'replyId': obj.replyId, + 'expiration': obj.expiration, + 'viewLimit': obj.viewLimit, + 'attachments': obj.attachments, + }; + } + if (obj is vcproto.Message_Secret) { + return { + 'ciphertext': obj.ciphertext, + 'expiration': obj.expiration, + }; + } + if (obj is vcproto.Message_ControlDelete) { + return { + 'ids': obj.ids, + }; + } + if (obj is vcproto.Message_ControlErase) { + return { + 'timestamp': obj.timestamp, + }; + } + if (obj is vcproto.Message_ControlSettings) { + return { + 'settings': obj.settings, + }; + } + if (obj is vcproto.Message_ControlPermissions) { + return { + 'permissions': obj.permissions, + }; + } + if (obj is vcproto.Message_ControlMembership) { + return { + 'membership': obj.membership, + }; + } + if (obj is vcproto.Message_ControlModeration) { + return { + 'acceptedIds': obj.acceptedIds, + 'rejectdIds': obj.rejectedIds, + }; + } + if (obj is vcproto.Message_ControlModeration) { + return { + 'acceptedIds': obj.acceptedIds, + 'rejectdIds': obj.rejectedIds, + }; + } + if (obj is vcproto.Message_ControlReadReceipt) { + return { + 'readIds': obj.readIds, + }; + } + if (obj is vcproto.ReconciledMessage) { + return { + 'content': obj.content, + 'reconciledTime': obj.reconciledTime, + }; + } + if (obj is vcproto.Conversation) { + return { + 'profile': obj.profile, + 'superIdentityJson': obj.superIdentityJson, + 'messages': obj.messages + }; + } + if (obj is vcproto.ChatMember) { + return { + 'remoteIdentityPublicKey': obj.remoteIdentityPublicKey, + 'remoteConversationRecordKey': obj.remoteConversationRecordKey, + }; + } + if (obj is vcproto.DirectChat) { + return { + 'settings': obj.settings, + 'localConversationRecordKey': obj.localConversationRecordKey, + 'remoteMember': obj.remoteMember, + }; + } + if (obj is vcproto.GroupChat) { + return { + 'settings': obj.settings, + 'membership': obj.membership, + 'permissions': obj.permissions, + 'localConversationRecordKey': obj.localConversationRecordKey, + 'remoteMembers': obj.remoteMembers, + }; + } + if (obj is vcproto.Chat) { + return { + 'kind': obj.whichKind(), + if (obj.whichKind() == vcproto.Chat_Kind.direct) 'direct': obj.direct, + if (obj.whichKind() == vcproto.Chat_Kind.group) 'group': obj.group, + }; + } + if (obj is vcproto.Profile) { + return { + 'name': obj.name, + 'pronouns': obj.pronouns, + 'about': obj.about, + 'status': obj.status, + 'availability': obj.availability, + 'avatar': obj.avatar, + 'timestamp': obj.timestamp, + }; + } + if (obj is vcproto.Account) { + return { + 'profile': obj.profile, + 'invisible': obj.invisible, + 'autoAwayTimeoutMin': obj.autoAwayTimeoutMin, + 'contact_list': obj.contactList, + 'contactInvitationRecords': obj.contactInvitationRecords, + 'chatList': obj.chatList, + 'groupChatList': obj.groupChatList, + 'freeMessage': obj.freeMessage, + 'busyMessage': obj.busyMessage, + 'awayMessage': obj.awayMessage, + 'autodetectAway': obj.autodetectAway, + }; + } + if (obj is vcproto.Contact) { + return { + 'nickname': obj.nickname, + 'profile': obj.profile, + 'superIdentityJson': obj.superIdentityJson, + 'identityPublicKey': obj.identityPublicKey, + 'remoteConversationRecordKey': obj.remoteConversationRecordKey, + 'localConversationRecordKey': obj.localConversationRecordKey, + 'showAvailability': obj.showAvailability, + 'notes': obj.notes, + }; + } + if (obj is vcproto.ContactInvitation) { + return { + 'contactRequestInboxKey': obj.contactRequestInboxKey, + 'writerSecret': obj.writerSecret, + }; + } + if (obj is vcproto.SignedContactInvitation) { + return { + 'contactInvitation': obj.contactInvitation, + 'identitySignature': obj.identitySignature, + }; + } + if (obj is vcproto.ContactRequest) { + return { + 'encryptionKeyType': obj.encryptionKeyType, + 'private': obj.private, + }; + } + if (obj is vcproto.ContactRequestPrivate) { + return { + 'writerKey': obj.writerKey, + 'profile': obj.profile, + 'superIdentityRecordKey': obj.superIdentityRecordKey, + 'chatRecordKey': obj.chatRecordKey, + 'expiration': obj.expiration, + }; + } + if (obj is vcproto.ContactResponse) { + return { + 'accept': obj.accept, + 'superIdentityRecordKey': obj.superIdentityRecordKey, + 'remoteConversationRecordKey': obj.remoteConversationRecordKey, + }; + } + if (obj is vcproto.SignedContactResponse) { + return { + 'contactResponse': obj.contactResponse, + 'identitySignature': obj.identitySignature, + }; + } + if (obj is vcproto.ContactInvitationRecord) { + return { + 'contactRequestInbox': obj.contactRequestInbox, + 'writerKey': obj.writerKey, + 'writerSecret': obj.writerSecret, + 'localConversationRecordKey': obj.localConversationRecordKey, + 'expiration': obj.expiration, + 'invitation': obj.invitation, + 'message': obj.message, + 'recipient': obj.recipient, + }; + } + + return obj; + } + + DynamicDebug.registerToDebug(toDebug); +} diff --git a/lib/proto/veilidchat.pb.dart b/lib/proto/veilidchat.pb.dart index 245f9f3..67805ae 100644 --- a/lib/proto/veilidchat.pb.dart +++ b/lib/proto/veilidchat.pb.dart @@ -1216,6 +1216,7 @@ enum Message_Kind { permissions, membership, moderation, + readReceipt, notSet } @@ -1234,6 +1235,7 @@ class Message extends $pb.GeneratedMessage { Message_ControlMembership? membership, Message_ControlModeration? moderation, $0.Signature? signature, + Message_ControlReadReceipt? readReceipt, }) { final $result = create(); if (id != null) { @@ -1272,6 +1274,9 @@ class Message extends $pb.GeneratedMessage { if (signature != null) { $result.signature = signature; } + if (readReceipt != null) { + $result.readReceipt = readReceipt; + } return $result; } Message._() : super(); @@ -1287,10 +1292,11 @@ class Message extends $pb.GeneratedMessage { 9 : Message_Kind.permissions, 10 : Message_Kind.membership, 11 : Message_Kind.moderation, + 13 : Message_Kind.readReceipt, 0 : Message_Kind.notSet }; static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Message', package: const $pb.PackageName(_omitMessageNames ? '' : 'veilidchat'), createEmptyInstance: create) - ..oo(0, [4, 5, 6, 7, 8, 9, 10, 11]) + ..oo(0, [4, 5, 6, 7, 8, 9, 10, 11, 13]) ..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'id', $pb.PbFieldType.OY) ..aOM<$0.TypedKey>(2, _omitFieldNames ? '' : 'author', subBuilder: $0.TypedKey.create) ..a<$fixnum.Int64>(3, _omitFieldNames ? '' : 'timestamp', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO) @@ -1303,6 +1309,7 @@ class Message extends $pb.GeneratedMessage { ..aOM(10, _omitFieldNames ? '' : 'membership', subBuilder: Message_ControlMembership.create) ..aOM(11, _omitFieldNames ? '' : 'moderation', subBuilder: Message_ControlModeration.create) ..aOM<$0.Signature>(12, _omitFieldNames ? '' : 'signature', subBuilder: $0.Signature.create) + ..aOM(13, _omitFieldNames ? '' : 'readReceipt', protoName: 'readReceipt', subBuilder: Message_ControlReadReceipt.create) ..hasRequiredFields = false ; @@ -1462,6 +1469,17 @@ class Message extends $pb.GeneratedMessage { void clearSignature() => clearField(12); @$pb.TagNumber(12) $0.Signature ensureSignature() => $_ensure(11); + + @$pb.TagNumber(13) + Message_ControlReadReceipt get readReceipt => $_getN(12); + @$pb.TagNumber(13) + set readReceipt(Message_ControlReadReceipt v) { setField(13, v); } + @$pb.TagNumber(13) + $core.bool hasReadReceipt() => $_has(12); + @$pb.TagNumber(13) + void clearReadReceipt() => clearField(13); + @$pb.TagNumber(13) + Message_ControlReadReceipt ensureReadReceipt() => $_ensure(12); } /// Locally stored messages for chats diff --git a/lib/proto/veilidchat.pbjson.dart b/lib/proto/veilidchat.pbjson.dart index 81bf741..0958343 100644 --- a/lib/proto/veilidchat.pbjson.dart +++ b/lib/proto/veilidchat.pbjson.dart @@ -215,6 +215,7 @@ const Message$json = { {'1': 'permissions', '3': 9, '4': 1, '5': 11, '6': '.veilidchat.Message.ControlPermissions', '9': 0, '10': 'permissions'}, {'1': 'membership', '3': 10, '4': 1, '5': 11, '6': '.veilidchat.Message.ControlMembership', '9': 0, '10': 'membership'}, {'1': 'moderation', '3': 11, '4': 1, '5': 11, '6': '.veilidchat.Message.ControlModeration', '9': 0, '10': 'moderation'}, + {'1': 'readReceipt', '3': 13, '4': 1, '5': 11, '6': '.veilidchat.Message.ControlReadReceipt', '9': 0, '10': 'readReceipt'}, {'1': 'signature', '3': 12, '4': 1, '5': 11, '6': '.veilid.Signature', '10': 'signature'}, ], '3': [Message_Text$json, Message_Secret$json, Message_ControlDelete$json, Message_ControlErase$json, Message_ControlSettings$json, Message_ControlPermissions$json, Message_ControlMembership$json, Message_ControlModeration$json, Message_ControlReadReceipt$json], @@ -318,22 +319,24 @@ final $typed_data.Uint8List messageDescriptor = $convert.base64Decode( 'twZXJtaXNzaW9ucxgJIAEoCzImLnZlaWxpZGNoYXQuTWVzc2FnZS5Db250cm9sUGVybWlzc2lv' 'bnNIAFILcGVybWlzc2lvbnMSRwoKbWVtYmVyc2hpcBgKIAEoCzIlLnZlaWxpZGNoYXQuTWVzc2' 'FnZS5Db250cm9sTWVtYmVyc2hpcEgAUgptZW1iZXJzaGlwEkcKCm1vZGVyYXRpb24YCyABKAsy' - 'JS52ZWlsaWRjaGF0Lk1lc3NhZ2UuQ29udHJvbE1vZGVyYXRpb25IAFIKbW9kZXJhdGlvbhIvCg' - 'lzaWduYXR1cmUYDCABKAsyES52ZWlsaWQuU2lnbmF0dXJlUglzaWduYXR1cmUa5QEKBFRleHQS' - 'EgoEdGV4dBgBIAEoCVIEdGV4dBIZCgV0b3BpYxgCIAEoCUgAUgV0b3BpY4gBARIeCghyZXBseV' - '9pZBgDIAEoDEgBUgdyZXBseUlkiAEBEh4KCmV4cGlyYXRpb24YBCABKARSCmV4cGlyYXRpb24S' - 'HQoKdmlld19saW1pdBgFIAEoDVIJdmlld0xpbWl0EjgKC2F0dGFjaG1lbnRzGAYgAygLMhYudm' - 'VpbGlkY2hhdC5BdHRhY2htZW50UgthdHRhY2htZW50c0IICgZfdG9waWNCCwoJX3JlcGx5X2lk' - 'GkgKBlNlY3JldBIeCgpjaXBoZXJ0ZXh0GAEgASgMUgpjaXBoZXJ0ZXh0Eh4KCmV4cGlyYXRpb2' - '4YAiABKARSCmV4cGlyYXRpb24aIQoNQ29udHJvbERlbGV0ZRIQCgNpZHMYASADKAxSA2lkcxos' - 'CgxDb250cm9sRXJhc2USHAoJdGltZXN0YW1wGAEgASgEUgl0aW1lc3RhbXAaRwoPQ29udHJvbF' - 'NldHRpbmdzEjQKCHNldHRpbmdzGAEgASgLMhgudmVpbGlkY2hhdC5DaGF0U2V0dGluZ3NSCHNl' - 'dHRpbmdzGk8KEkNvbnRyb2xQZXJtaXNzaW9ucxI5CgtwZXJtaXNzaW9ucxgBIAEoCzIXLnZlaW' - 'xpZGNoYXQuUGVybWlzc2lvbnNSC3Blcm1pc3Npb25zGksKEUNvbnRyb2xNZW1iZXJzaGlwEjYK' - 'Cm1lbWJlcnNoaXAYASABKAsyFi52ZWlsaWRjaGF0Lk1lbWJlcnNoaXBSCm1lbWJlcnNoaXAaWQ' - 'oRQ29udHJvbE1vZGVyYXRpb24SIQoMYWNjZXB0ZWRfaWRzGAEgAygMUgthY2NlcHRlZElkcxIh' - 'CgxyZWplY3RlZF9pZHMYAiADKAxSC3JlamVjdGVkSWRzGi8KEkNvbnRyb2xSZWFkUmVjZWlwdB' - 'IZCghyZWFkX2lkcxgBIAMoDFIHcmVhZElkc0IGCgRraW5k'); + 'JS52ZWlsaWRjaGF0Lk1lc3NhZ2UuQ29udHJvbE1vZGVyYXRpb25IAFIKbW9kZXJhdGlvbhJKCg' + 'tyZWFkUmVjZWlwdBgNIAEoCzImLnZlaWxpZGNoYXQuTWVzc2FnZS5Db250cm9sUmVhZFJlY2Vp' + 'cHRIAFILcmVhZFJlY2VpcHQSLwoJc2lnbmF0dXJlGAwgASgLMhEudmVpbGlkLlNpZ25hdHVyZV' + 'IJc2lnbmF0dXJlGuUBCgRUZXh0EhIKBHRleHQYASABKAlSBHRleHQSGQoFdG9waWMYAiABKAlI' + 'AFIFdG9waWOIAQESHgoIcmVwbHlfaWQYAyABKAxIAVIHcmVwbHlJZIgBARIeCgpleHBpcmF0aW' + '9uGAQgASgEUgpleHBpcmF0aW9uEh0KCnZpZXdfbGltaXQYBSABKA1SCXZpZXdMaW1pdBI4Cgth' + 'dHRhY2htZW50cxgGIAMoCzIWLnZlaWxpZGNoYXQuQXR0YWNobWVudFILYXR0YWNobWVudHNCCA' + 'oGX3RvcGljQgsKCV9yZXBseV9pZBpICgZTZWNyZXQSHgoKY2lwaGVydGV4dBgBIAEoDFIKY2lw' + 'aGVydGV4dBIeCgpleHBpcmF0aW9uGAIgASgEUgpleHBpcmF0aW9uGiEKDUNvbnRyb2xEZWxldG' + 'USEAoDaWRzGAEgAygMUgNpZHMaLAoMQ29udHJvbEVyYXNlEhwKCXRpbWVzdGFtcBgBIAEoBFIJ' + 'dGltZXN0YW1wGkcKD0NvbnRyb2xTZXR0aW5ncxI0CghzZXR0aW5ncxgBIAEoCzIYLnZlaWxpZG' + 'NoYXQuQ2hhdFNldHRpbmdzUghzZXR0aW5ncxpPChJDb250cm9sUGVybWlzc2lvbnMSOQoLcGVy' + 'bWlzc2lvbnMYASABKAsyFy52ZWlsaWRjaGF0LlBlcm1pc3Npb25zUgtwZXJtaXNzaW9ucxpLCh' + 'FDb250cm9sTWVtYmVyc2hpcBI2CgptZW1iZXJzaGlwGAEgASgLMhYudmVpbGlkY2hhdC5NZW1i' + 'ZXJzaGlwUgptZW1iZXJzaGlwGlkKEUNvbnRyb2xNb2RlcmF0aW9uEiEKDGFjY2VwdGVkX2lkcx' + 'gBIAMoDFILYWNjZXB0ZWRJZHMSIQoMcmVqZWN0ZWRfaWRzGAIgAygMUgtyZWplY3RlZElkcxov' + 'ChJDb250cm9sUmVhZFJlY2VpcHQSGQoIcmVhZF9pZHMYASADKAxSB3JlYWRJZHNCBgoEa2luZA' + '=='); @$core.Deprecated('Use reconciledMessageDescriptor instead') const ReconciledMessage$json = { diff --git a/lib/proto/veilidchat.proto b/lib/proto/veilidchat.proto index e669959..5bff89c 100644 --- a/lib/proto/veilidchat.proto +++ b/lib/proto/veilidchat.proto @@ -228,6 +228,7 @@ message Message { ControlPermissions permissions = 9; ControlMembership membership = 10; ControlModeration moderation = 11; + ControlReadReceipt readReceipt = 13; } // Author signature over all of the fields and attachment signatures diff --git a/lib/router/cubits/router_cubit.dart b/lib/router/cubits/router_cubit.dart index 6684c45..1492c51 100644 --- a/lib/router/cubits/router_cubit.dart +++ b/lib/router/cubits/router_cubit.dart @@ -22,7 +22,7 @@ part 'router_cubit.g.dart'; final _rootNavKey = GlobalKey(debugLabel: 'rootNavKey'); @freezed -class RouterState with _$RouterState { +sealed class RouterState with _$RouterState { const factory RouterState({ required bool hasAnyAccount, }) = _RouterState; diff --git a/lib/router/cubits/router_cubit.freezed.dart b/lib/router/cubits/router_cubit.freezed.dart index 8377607..0f5b285 100644 --- a/lib/router/cubits/router_cubit.freezed.dart +++ b/lib/router/cubits/router_cubit.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,118 +10,25 @@ part of 'router_cubit.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -RouterState _$RouterStateFromJson(Map json) { - return _RouterState.fromJson(json); -} - /// @nodoc -mixin _$RouterState { - bool get hasAnyAccount => throw _privateConstructorUsedError; - - /// Serializes this RouterState to a JSON map. - Map toJson() => throw _privateConstructorUsedError; +mixin _$RouterState implements DiagnosticableTreeMixin { + bool get hasAnyAccount; /// Create a copy of RouterState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $RouterStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$RouterStateCopyWithImpl(this as RouterState, _$identity); -/// @nodoc -abstract class $RouterStateCopyWith<$Res> { - factory $RouterStateCopyWith( - RouterState value, $Res Function(RouterState) then) = - _$RouterStateCopyWithImpl<$Res, RouterState>; - @useResult - $Res call({bool hasAnyAccount}); -} - -/// @nodoc -class _$RouterStateCopyWithImpl<$Res, $Val extends RouterState> - implements $RouterStateCopyWith<$Res> { - _$RouterStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of RouterState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? hasAnyAccount = null, - }) { - return _then(_value.copyWith( - hasAnyAccount: null == hasAnyAccount - ? _value.hasAnyAccount - : hasAnyAccount // ignore: cast_nullable_to_non_nullable - as bool, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$RouterStateImplCopyWith<$Res> - implements $RouterStateCopyWith<$Res> { - factory _$$RouterStateImplCopyWith( - _$RouterStateImpl value, $Res Function(_$RouterStateImpl) then) = - __$$RouterStateImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({bool hasAnyAccount}); -} - -/// @nodoc -class __$$RouterStateImplCopyWithImpl<$Res> - extends _$RouterStateCopyWithImpl<$Res, _$RouterStateImpl> - implements _$$RouterStateImplCopyWith<$Res> { - __$$RouterStateImplCopyWithImpl( - _$RouterStateImpl _value, $Res Function(_$RouterStateImpl) _then) - : super(_value, _then); - - /// Create a copy of RouterState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? hasAnyAccount = null, - }) { - return _then(_$RouterStateImpl( - hasAnyAccount: null == hasAnyAccount - ? _value.hasAnyAccount - : hasAnyAccount // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$RouterStateImpl with DiagnosticableTreeMixin implements _RouterState { - const _$RouterStateImpl({required this.hasAnyAccount}); - - factory _$RouterStateImpl.fromJson(Map json) => - _$$RouterStateImplFromJson(json); - - @override - final bool hasAnyAccount; - - @override - String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'RouterState(hasAnyAccount: $hasAnyAccount)'; - } + /// Serializes this RouterState to a JSON map. + Map toJson(); @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); properties ..add(DiagnosticsProperty('type', 'RouterState')) ..add(DiagnosticsProperty('hasAnyAccount', hasAnyAccount)); @@ -130,7 +38,7 @@ class _$RouterStateImpl with DiagnosticableTreeMixin implements _RouterState { bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$RouterStateImpl && + other is RouterState && (identical(other.hasAnyAccount, hasAnyAccount) || other.hasAnyAccount == hasAnyAccount)); } @@ -139,36 +47,127 @@ class _$RouterStateImpl with DiagnosticableTreeMixin implements _RouterState { @override int get hashCode => Object.hash(runtimeType, hasAnyAccount); - /// Create a copy of RouterState - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$RouterStateImplCopyWith<_$RouterStateImpl> get copyWith => - __$$RouterStateImplCopyWithImpl<_$RouterStateImpl>(this, _$identity); - - @override - Map toJson() { - return _$$RouterStateImplToJson( - this, - ); + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'RouterState(hasAnyAccount: $hasAnyAccount)'; } } -abstract class _RouterState implements RouterState { - const factory _RouterState({required final bool hasAnyAccount}) = - _$RouterStateImpl; +/// @nodoc +abstract mixin class $RouterStateCopyWith<$Res> { + factory $RouterStateCopyWith( + RouterState value, $Res Function(RouterState) _then) = + _$RouterStateCopyWithImpl; + @useResult + $Res call({bool hasAnyAccount}); +} - factory _RouterState.fromJson(Map json) = - _$RouterStateImpl.fromJson; +/// @nodoc +class _$RouterStateCopyWithImpl<$Res> implements $RouterStateCopyWith<$Res> { + _$RouterStateCopyWithImpl(this._self, this._then); + + final RouterState _self; + final $Res Function(RouterState) _then; + + /// Create a copy of RouterState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? hasAnyAccount = null, + }) { + return _then(_self.copyWith( + hasAnyAccount: null == hasAnyAccount + ? _self.hasAnyAccount + : hasAnyAccount // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _RouterState with DiagnosticableTreeMixin implements RouterState { + const _RouterState({required this.hasAnyAccount}); + factory _RouterState.fromJson(Map json) => + _$RouterStateFromJson(json); @override - bool get hasAnyAccount; + final bool hasAnyAccount; /// Create a copy of RouterState /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$RouterStateImplCopyWith<_$RouterStateImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$RouterStateCopyWith<_RouterState> get copyWith => + __$RouterStateCopyWithImpl<_RouterState>(this, _$identity); + + @override + Map toJson() { + return _$RouterStateToJson( + this, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + properties + ..add(DiagnosticsProperty('type', 'RouterState')) + ..add(DiagnosticsProperty('hasAnyAccount', hasAnyAccount)); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _RouterState && + (identical(other.hasAnyAccount, hasAnyAccount) || + other.hasAnyAccount == hasAnyAccount)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, hasAnyAccount); + + @override + String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { + return 'RouterState(hasAnyAccount: $hasAnyAccount)'; + } } + +/// @nodoc +abstract mixin class _$RouterStateCopyWith<$Res> + implements $RouterStateCopyWith<$Res> { + factory _$RouterStateCopyWith( + _RouterState value, $Res Function(_RouterState) _then) = + __$RouterStateCopyWithImpl; + @override + @useResult + $Res call({bool hasAnyAccount}); +} + +/// @nodoc +class __$RouterStateCopyWithImpl<$Res> implements _$RouterStateCopyWith<$Res> { + __$RouterStateCopyWithImpl(this._self, this._then); + + final _RouterState _self; + final $Res Function(_RouterState) _then; + + /// Create a copy of RouterState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? hasAnyAccount = null, + }) { + return _then(_RouterState( + hasAnyAccount: null == hasAnyAccount + ? _self.hasAnyAccount + : hasAnyAccount // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +// dart format on diff --git a/lib/router/cubits/router_cubit.g.dart b/lib/router/cubits/router_cubit.g.dart index 4d9241c..3623d0e 100644 --- a/lib/router/cubits/router_cubit.g.dart +++ b/lib/router/cubits/router_cubit.g.dart @@ -6,12 +6,11 @@ part of 'router_cubit.dart'; // JsonSerializableGenerator // ************************************************************************** -_$RouterStateImpl _$$RouterStateImplFromJson(Map json) => - _$RouterStateImpl( +_RouterState _$RouterStateFromJson(Map json) => _RouterState( hasAnyAccount: json['has_any_account'] as bool, ); -Map _$$RouterStateImplToJson(_$RouterStateImpl instance) => +Map _$RouterStateToJson(_RouterState instance) => { 'has_any_account': instance.hasAnyAccount, }; diff --git a/lib/settings/models/preferences.dart b/lib/settings/models/preferences.dart index e646c61..3ef683e 100644 --- a/lib/settings/models/preferences.dart +++ b/lib/settings/models/preferences.dart @@ -10,7 +10,7 @@ part 'preferences.g.dart'; // Lock preference changes how frequently the messenger locks its // interface and requires the identitySecretKey to be entered (pin/password/etc) @freezed -class LockPreference with _$LockPreference { +sealed class LockPreference with _$LockPreference { const factory LockPreference({ @Default(0) int inactivityLockSecs, @Default(false) bool lockWhenSwitching, @@ -37,7 +37,7 @@ enum LanguagePreference { // Preferences are stored in a table locally and globally affect all // accounts imported/added and the app in general @freezed -class Preferences with _$Preferences { +sealed class Preferences with _$Preferences { const factory Preferences({ @Default(ThemePreferences.defaults) ThemePreferences themePreference, @Default(LanguagePreference.defaults) LanguagePreference languagePreference, diff --git a/lib/settings/models/preferences.freezed.dart b/lib/settings/models/preferences.freezed.dart index a7ebed3..9e090f5 100644 --- a/lib/settings/models/preferences.freezed.dart +++ b/lib/settings/models/preferences.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,158 +10,31 @@ part of 'preferences.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -LockPreference _$LockPreferenceFromJson(Map json) { - return _LockPreference.fromJson(json); -} - /// @nodoc mixin _$LockPreference { - int get inactivityLockSecs => throw _privateConstructorUsedError; - bool get lockWhenSwitching => throw _privateConstructorUsedError; - bool get lockWithSystemLock => throw _privateConstructorUsedError; - - /// Serializes this LockPreference to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + int get inactivityLockSecs; + bool get lockWhenSwitching; + bool get lockWithSystemLock; /// Create a copy of LockPreference /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $LockPreferenceCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$LockPreferenceCopyWithImpl( + this as LockPreference, _$identity); -/// @nodoc -abstract class $LockPreferenceCopyWith<$Res> { - factory $LockPreferenceCopyWith( - LockPreference value, $Res Function(LockPreference) then) = - _$LockPreferenceCopyWithImpl<$Res, LockPreference>; - @useResult - $Res call( - {int inactivityLockSecs, - bool lockWhenSwitching, - bool lockWithSystemLock}); -} - -/// @nodoc -class _$LockPreferenceCopyWithImpl<$Res, $Val extends LockPreference> - implements $LockPreferenceCopyWith<$Res> { - _$LockPreferenceCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of LockPreference - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? inactivityLockSecs = null, - Object? lockWhenSwitching = null, - Object? lockWithSystemLock = null, - }) { - return _then(_value.copyWith( - inactivityLockSecs: null == inactivityLockSecs - ? _value.inactivityLockSecs - : inactivityLockSecs // ignore: cast_nullable_to_non_nullable - as int, - lockWhenSwitching: null == lockWhenSwitching - ? _value.lockWhenSwitching - : lockWhenSwitching // ignore: cast_nullable_to_non_nullable - as bool, - lockWithSystemLock: null == lockWithSystemLock - ? _value.lockWithSystemLock - : lockWithSystemLock // ignore: cast_nullable_to_non_nullable - as bool, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$LockPreferenceImplCopyWith<$Res> - implements $LockPreferenceCopyWith<$Res> { - factory _$$LockPreferenceImplCopyWith(_$LockPreferenceImpl value, - $Res Function(_$LockPreferenceImpl) then) = - __$$LockPreferenceImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {int inactivityLockSecs, - bool lockWhenSwitching, - bool lockWithSystemLock}); -} - -/// @nodoc -class __$$LockPreferenceImplCopyWithImpl<$Res> - extends _$LockPreferenceCopyWithImpl<$Res, _$LockPreferenceImpl> - implements _$$LockPreferenceImplCopyWith<$Res> { - __$$LockPreferenceImplCopyWithImpl( - _$LockPreferenceImpl _value, $Res Function(_$LockPreferenceImpl) _then) - : super(_value, _then); - - /// Create a copy of LockPreference - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? inactivityLockSecs = null, - Object? lockWhenSwitching = null, - Object? lockWithSystemLock = null, - }) { - return _then(_$LockPreferenceImpl( - inactivityLockSecs: null == inactivityLockSecs - ? _value.inactivityLockSecs - : inactivityLockSecs // ignore: cast_nullable_to_non_nullable - as int, - lockWhenSwitching: null == lockWhenSwitching - ? _value.lockWhenSwitching - : lockWhenSwitching // ignore: cast_nullable_to_non_nullable - as bool, - lockWithSystemLock: null == lockWithSystemLock - ? _value.lockWithSystemLock - : lockWithSystemLock // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$LockPreferenceImpl implements _LockPreference { - const _$LockPreferenceImpl( - {this.inactivityLockSecs = 0, - this.lockWhenSwitching = false, - this.lockWithSystemLock = false}); - - factory _$LockPreferenceImpl.fromJson(Map json) => - _$$LockPreferenceImplFromJson(json); - - @override - @JsonKey() - final int inactivityLockSecs; - @override - @JsonKey() - final bool lockWhenSwitching; - @override - @JsonKey() - final bool lockWithSystemLock; - - @override - String toString() { - return 'LockPreference(inactivityLockSecs: $inactivityLockSecs, lockWhenSwitching: $lockWhenSwitching, lockWithSystemLock: $lockWithSystemLock)'; - } + /// Serializes this LockPreference to a JSON map. + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$LockPreferenceImpl && + other is LockPreference && (identical(other.inactivityLockSecs, inactivityLockSecs) || other.inactivityLockSecs == inactivityLockSecs) && (identical(other.lockWhenSwitching, lockWhenSwitching) || @@ -174,255 +48,187 @@ class _$LockPreferenceImpl implements _LockPreference { int get hashCode => Object.hash( runtimeType, inactivityLockSecs, lockWhenSwitching, lockWithSystemLock); - /// Create a copy of LockPreference - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$LockPreferenceImplCopyWith<_$LockPreferenceImpl> get copyWith => - __$$LockPreferenceImplCopyWithImpl<_$LockPreferenceImpl>( - this, _$identity); - - @override - Map toJson() { - return _$$LockPreferenceImplToJson( - this, - ); + String toString() { + return 'LockPreference(inactivityLockSecs: $inactivityLockSecs, lockWhenSwitching: $lockWhenSwitching, lockWithSystemLock: $lockWithSystemLock)'; } } -abstract class _LockPreference implements LockPreference { - const factory _LockPreference( - {final int inactivityLockSecs, - final bool lockWhenSwitching, - final bool lockWithSystemLock}) = _$LockPreferenceImpl; - - factory _LockPreference.fromJson(Map json) = - _$LockPreferenceImpl.fromJson; - - @override - int get inactivityLockSecs; - @override - bool get lockWhenSwitching; - @override - bool get lockWithSystemLock; - - /// Create a copy of LockPreference - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$LockPreferenceImplCopyWith<_$LockPreferenceImpl> get copyWith => - throw _privateConstructorUsedError; -} - -Preferences _$PreferencesFromJson(Map json) { - return _Preferences.fromJson(json); -} - /// @nodoc -mixin _$Preferences { - ThemePreferences get themePreference => throw _privateConstructorUsedError; - LanguagePreference get languagePreference => - throw _privateConstructorUsedError; - LockPreference get lockPreference => throw _privateConstructorUsedError; - NotificationsPreference get notificationsPreference => - throw _privateConstructorUsedError; - - /// Serializes this Preferences to a JSON map. - Map toJson() => throw _privateConstructorUsedError; - - /// Create a copy of Preferences - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - $PreferencesCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $PreferencesCopyWith<$Res> { - factory $PreferencesCopyWith( - Preferences value, $Res Function(Preferences) then) = - _$PreferencesCopyWithImpl<$Res, Preferences>; +abstract mixin class $LockPreferenceCopyWith<$Res> { + factory $LockPreferenceCopyWith( + LockPreference value, $Res Function(LockPreference) _then) = + _$LockPreferenceCopyWithImpl; @useResult $Res call( - {ThemePreferences themePreference, - LanguagePreference languagePreference, - LockPreference lockPreference, - NotificationsPreference notificationsPreference}); - - $ThemePreferencesCopyWith<$Res> get themePreference; - $LockPreferenceCopyWith<$Res> get lockPreference; - $NotificationsPreferenceCopyWith<$Res> get notificationsPreference; + {int inactivityLockSecs, + bool lockWhenSwitching, + bool lockWithSystemLock}); } /// @nodoc -class _$PreferencesCopyWithImpl<$Res, $Val extends Preferences> - implements $PreferencesCopyWith<$Res> { - _$PreferencesCopyWithImpl(this._value, this._then); +class _$LockPreferenceCopyWithImpl<$Res> + implements $LockPreferenceCopyWith<$Res> { + _$LockPreferenceCopyWithImpl(this._self, this._then); - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; + final LockPreference _self; + final $Res Function(LockPreference) _then; - /// Create a copy of Preferences + /// Create a copy of LockPreference /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ - Object? themePreference = null, - Object? languagePreference = null, - Object? lockPreference = null, - Object? notificationsPreference = null, + Object? inactivityLockSecs = null, + Object? lockWhenSwitching = null, + Object? lockWithSystemLock = null, }) { - return _then(_value.copyWith( - themePreference: null == themePreference - ? _value.themePreference - : themePreference // ignore: cast_nullable_to_non_nullable - as ThemePreferences, - languagePreference: null == languagePreference - ? _value.languagePreference - : languagePreference // ignore: cast_nullable_to_non_nullable - as LanguagePreference, - lockPreference: null == lockPreference - ? _value.lockPreference - : lockPreference // ignore: cast_nullable_to_non_nullable - as LockPreference, - notificationsPreference: null == notificationsPreference - ? _value.notificationsPreference - : notificationsPreference // ignore: cast_nullable_to_non_nullable - as NotificationsPreference, - ) as $Val); - } - - /// Create a copy of Preferences - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $ThemePreferencesCopyWith<$Res> get themePreference { - return $ThemePreferencesCopyWith<$Res>(_value.themePreference, (value) { - return _then(_value.copyWith(themePreference: value) as $Val); - }); - } - - /// Create a copy of Preferences - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $LockPreferenceCopyWith<$Res> get lockPreference { - return $LockPreferenceCopyWith<$Res>(_value.lockPreference, (value) { - return _then(_value.copyWith(lockPreference: value) as $Val); - }); - } - - /// Create a copy of Preferences - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $NotificationsPreferenceCopyWith<$Res> get notificationsPreference { - return $NotificationsPreferenceCopyWith<$Res>( - _value.notificationsPreference, (value) { - return _then(_value.copyWith(notificationsPreference: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$PreferencesImplCopyWith<$Res> - implements $PreferencesCopyWith<$Res> { - factory _$$PreferencesImplCopyWith( - _$PreferencesImpl value, $Res Function(_$PreferencesImpl) then) = - __$$PreferencesImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {ThemePreferences themePreference, - LanguagePreference languagePreference, - LockPreference lockPreference, - NotificationsPreference notificationsPreference}); - - @override - $ThemePreferencesCopyWith<$Res> get themePreference; - @override - $LockPreferenceCopyWith<$Res> get lockPreference; - @override - $NotificationsPreferenceCopyWith<$Res> get notificationsPreference; -} - -/// @nodoc -class __$$PreferencesImplCopyWithImpl<$Res> - extends _$PreferencesCopyWithImpl<$Res, _$PreferencesImpl> - implements _$$PreferencesImplCopyWith<$Res> { - __$$PreferencesImplCopyWithImpl( - _$PreferencesImpl _value, $Res Function(_$PreferencesImpl) _then) - : super(_value, _then); - - /// Create a copy of Preferences - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? themePreference = null, - Object? languagePreference = null, - Object? lockPreference = null, - Object? notificationsPreference = null, - }) { - return _then(_$PreferencesImpl( - themePreference: null == themePreference - ? _value.themePreference - : themePreference // ignore: cast_nullable_to_non_nullable - as ThemePreferences, - languagePreference: null == languagePreference - ? _value.languagePreference - : languagePreference // ignore: cast_nullable_to_non_nullable - as LanguagePreference, - lockPreference: null == lockPreference - ? _value.lockPreference - : lockPreference // ignore: cast_nullable_to_non_nullable - as LockPreference, - notificationsPreference: null == notificationsPreference - ? _value.notificationsPreference - : notificationsPreference // ignore: cast_nullable_to_non_nullable - as NotificationsPreference, + return _then(_self.copyWith( + inactivityLockSecs: null == inactivityLockSecs + ? _self.inactivityLockSecs + : inactivityLockSecs // ignore: cast_nullable_to_non_nullable + as int, + lockWhenSwitching: null == lockWhenSwitching + ? _self.lockWhenSwitching + : lockWhenSwitching // ignore: cast_nullable_to_non_nullable + as bool, + lockWithSystemLock: null == lockWithSystemLock + ? _self.lockWithSystemLock + : lockWithSystemLock // ignore: cast_nullable_to_non_nullable + as bool, )); } } /// @nodoc @JsonSerializable() -class _$PreferencesImpl implements _Preferences { - const _$PreferencesImpl( - {this.themePreference = ThemePreferences.defaults, - this.languagePreference = LanguagePreference.defaults, - this.lockPreference = LockPreference.defaults, - this.notificationsPreference = NotificationsPreference.defaults}); - - factory _$PreferencesImpl.fromJson(Map json) => - _$$PreferencesImplFromJson(json); +class _LockPreference implements LockPreference { + const _LockPreference( + {this.inactivityLockSecs = 0, + this.lockWhenSwitching = false, + this.lockWithSystemLock = false}); + factory _LockPreference.fromJson(Map json) => + _$LockPreferenceFromJson(json); @override @JsonKey() - final ThemePreferences themePreference; + final int inactivityLockSecs; @override @JsonKey() - final LanguagePreference languagePreference; + final bool lockWhenSwitching; @override @JsonKey() - final LockPreference lockPreference; + final bool lockWithSystemLock; + + /// Create a copy of LockPreference + /// with the given fields replaced by the non-null parameter values. @override - @JsonKey() - final NotificationsPreference notificationsPreference; + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$LockPreferenceCopyWith<_LockPreference> get copyWith => + __$LockPreferenceCopyWithImpl<_LockPreference>(this, _$identity); @override - String toString() { - return 'Preferences(themePreference: $themePreference, languagePreference: $languagePreference, lockPreference: $lockPreference, notificationsPreference: $notificationsPreference)'; + Map toJson() { + return _$LockPreferenceToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$PreferencesImpl && + other is _LockPreference && + (identical(other.inactivityLockSecs, inactivityLockSecs) || + other.inactivityLockSecs == inactivityLockSecs) && + (identical(other.lockWhenSwitching, lockWhenSwitching) || + other.lockWhenSwitching == lockWhenSwitching) && + (identical(other.lockWithSystemLock, lockWithSystemLock) || + other.lockWithSystemLock == lockWithSystemLock)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, inactivityLockSecs, lockWhenSwitching, lockWithSystemLock); + + @override + String toString() { + return 'LockPreference(inactivityLockSecs: $inactivityLockSecs, lockWhenSwitching: $lockWhenSwitching, lockWithSystemLock: $lockWithSystemLock)'; + } +} + +/// @nodoc +abstract mixin class _$LockPreferenceCopyWith<$Res> + implements $LockPreferenceCopyWith<$Res> { + factory _$LockPreferenceCopyWith( + _LockPreference value, $Res Function(_LockPreference) _then) = + __$LockPreferenceCopyWithImpl; + @override + @useResult + $Res call( + {int inactivityLockSecs, + bool lockWhenSwitching, + bool lockWithSystemLock}); +} + +/// @nodoc +class __$LockPreferenceCopyWithImpl<$Res> + implements _$LockPreferenceCopyWith<$Res> { + __$LockPreferenceCopyWithImpl(this._self, this._then); + + final _LockPreference _self; + final $Res Function(_LockPreference) _then; + + /// Create a copy of LockPreference + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? inactivityLockSecs = null, + Object? lockWhenSwitching = null, + Object? lockWithSystemLock = null, + }) { + return _then(_LockPreference( + inactivityLockSecs: null == inactivityLockSecs + ? _self.inactivityLockSecs + : inactivityLockSecs // ignore: cast_nullable_to_non_nullable + as int, + lockWhenSwitching: null == lockWhenSwitching + ? _self.lockWhenSwitching + : lockWhenSwitching // ignore: cast_nullable_to_non_nullable + as bool, + lockWithSystemLock: null == lockWithSystemLock + ? _self.lockWithSystemLock + : lockWithSystemLock // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc +mixin _$Preferences { + ThemePreferences get themePreference; + LanguagePreference get languagePreference; + LockPreference get lockPreference; + NotificationsPreference get notificationsPreference; + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $PreferencesCopyWith get copyWith => + _$PreferencesCopyWithImpl(this as Preferences, _$identity); + + /// Serializes this Preferences to a JSON map. + Map toJson(); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is Preferences && (identical(other.themePreference, themePreference) || other.themePreference == themePreference) && (identical(other.languagePreference, languagePreference) || @@ -439,46 +245,253 @@ class _$PreferencesImpl implements _Preferences { int get hashCode => Object.hash(runtimeType, themePreference, languagePreference, lockPreference, notificationsPreference); - /// Create a copy of Preferences - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$PreferencesImplCopyWith<_$PreferencesImpl> get copyWith => - __$$PreferencesImplCopyWithImpl<_$PreferencesImpl>(this, _$identity); - - @override - Map toJson() { - return _$$PreferencesImplToJson( - this, - ); + String toString() { + return 'Preferences(themePreference: $themePreference, languagePreference: $languagePreference, lockPreference: $lockPreference, notificationsPreference: $notificationsPreference)'; } } -abstract class _Preferences implements Preferences { - const factory _Preferences( - {final ThemePreferences themePreference, - final LanguagePreference languagePreference, - final LockPreference lockPreference, - final NotificationsPreference notificationsPreference}) = - _$PreferencesImpl; +/// @nodoc +abstract mixin class $PreferencesCopyWith<$Res> { + factory $PreferencesCopyWith( + Preferences value, $Res Function(Preferences) _then) = + _$PreferencesCopyWithImpl; + @useResult + $Res call( + {ThemePreferences themePreference, + LanguagePreference languagePreference, + LockPreference lockPreference, + NotificationsPreference notificationsPreference}); - factory _Preferences.fromJson(Map json) = - _$PreferencesImpl.fromJson; + $ThemePreferencesCopyWith<$Res> get themePreference; + $LockPreferenceCopyWith<$Res> get lockPreference; + $NotificationsPreferenceCopyWith<$Res> get notificationsPreference; +} + +/// @nodoc +class _$PreferencesCopyWithImpl<$Res> implements $PreferencesCopyWith<$Res> { + _$PreferencesCopyWithImpl(this._self, this._then); + + final Preferences _self; + final $Res Function(Preferences) _then; + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? themePreference = null, + Object? languagePreference = null, + Object? lockPreference = null, + Object? notificationsPreference = null, + }) { + return _then(_self.copyWith( + themePreference: null == themePreference + ? _self.themePreference + : themePreference // ignore: cast_nullable_to_non_nullable + as ThemePreferences, + languagePreference: null == languagePreference + ? _self.languagePreference + : languagePreference // ignore: cast_nullable_to_non_nullable + as LanguagePreference, + lockPreference: null == lockPreference + ? _self.lockPreference + : lockPreference // ignore: cast_nullable_to_non_nullable + as LockPreference, + notificationsPreference: null == notificationsPreference + ? _self.notificationsPreference + : notificationsPreference // ignore: cast_nullable_to_non_nullable + as NotificationsPreference, + )); + } + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ThemePreferencesCopyWith<$Res> get themePreference { + return $ThemePreferencesCopyWith<$Res>(_self.themePreference, (value) { + return _then(_self.copyWith(themePreference: value)); + }); + } + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $LockPreferenceCopyWith<$Res> get lockPreference { + return $LockPreferenceCopyWith<$Res>(_self.lockPreference, (value) { + return _then(_self.copyWith(lockPreference: value)); + }); + } + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $NotificationsPreferenceCopyWith<$Res> get notificationsPreference { + return $NotificationsPreferenceCopyWith<$Res>(_self.notificationsPreference, + (value) { + return _then(_self.copyWith(notificationsPreference: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _Preferences implements Preferences { + const _Preferences( + {this.themePreference = ThemePreferences.defaults, + this.languagePreference = LanguagePreference.defaults, + this.lockPreference = LockPreference.defaults, + this.notificationsPreference = NotificationsPreference.defaults}); + factory _Preferences.fromJson(Map json) => + _$PreferencesFromJson(json); @override - ThemePreferences get themePreference; + @JsonKey() + final ThemePreferences themePreference; @override - LanguagePreference get languagePreference; + @JsonKey() + final LanguagePreference languagePreference; @override - LockPreference get lockPreference; + @JsonKey() + final LockPreference lockPreference; @override - NotificationsPreference get notificationsPreference; + @JsonKey() + final NotificationsPreference notificationsPreference; /// Create a copy of Preferences /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$PreferencesImplCopyWith<_$PreferencesImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$PreferencesCopyWith<_Preferences> get copyWith => + __$PreferencesCopyWithImpl<_Preferences>(this, _$identity); + + @override + Map toJson() { + return _$PreferencesToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _Preferences && + (identical(other.themePreference, themePreference) || + other.themePreference == themePreference) && + (identical(other.languagePreference, languagePreference) || + other.languagePreference == languagePreference) && + (identical(other.lockPreference, lockPreference) || + other.lockPreference == lockPreference) && + (identical( + other.notificationsPreference, notificationsPreference) || + other.notificationsPreference == notificationsPreference)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, themePreference, + languagePreference, lockPreference, notificationsPreference); + + @override + String toString() { + return 'Preferences(themePreference: $themePreference, languagePreference: $languagePreference, lockPreference: $lockPreference, notificationsPreference: $notificationsPreference)'; + } } + +/// @nodoc +abstract mixin class _$PreferencesCopyWith<$Res> + implements $PreferencesCopyWith<$Res> { + factory _$PreferencesCopyWith( + _Preferences value, $Res Function(_Preferences) _then) = + __$PreferencesCopyWithImpl; + @override + @useResult + $Res call( + {ThemePreferences themePreference, + LanguagePreference languagePreference, + LockPreference lockPreference, + NotificationsPreference notificationsPreference}); + + @override + $ThemePreferencesCopyWith<$Res> get themePreference; + @override + $LockPreferenceCopyWith<$Res> get lockPreference; + @override + $NotificationsPreferenceCopyWith<$Res> get notificationsPreference; +} + +/// @nodoc +class __$PreferencesCopyWithImpl<$Res> implements _$PreferencesCopyWith<$Res> { + __$PreferencesCopyWithImpl(this._self, this._then); + + final _Preferences _self; + final $Res Function(_Preferences) _then; + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? themePreference = null, + Object? languagePreference = null, + Object? lockPreference = null, + Object? notificationsPreference = null, + }) { + return _then(_Preferences( + themePreference: null == themePreference + ? _self.themePreference + : themePreference // ignore: cast_nullable_to_non_nullable + as ThemePreferences, + languagePreference: null == languagePreference + ? _self.languagePreference + : languagePreference // ignore: cast_nullable_to_non_nullable + as LanguagePreference, + lockPreference: null == lockPreference + ? _self.lockPreference + : lockPreference // ignore: cast_nullable_to_non_nullable + as LockPreference, + notificationsPreference: null == notificationsPreference + ? _self.notificationsPreference + : notificationsPreference // ignore: cast_nullable_to_non_nullable + as NotificationsPreference, + )); + } + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $ThemePreferencesCopyWith<$Res> get themePreference { + return $ThemePreferencesCopyWith<$Res>(_self.themePreference, (value) { + return _then(_self.copyWith(themePreference: value)); + }); + } + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $LockPreferenceCopyWith<$Res> get lockPreference { + return $LockPreferenceCopyWith<$Res>(_self.lockPreference, (value) { + return _then(_self.copyWith(lockPreference: value)); + }); + } + + /// Create a copy of Preferences + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $NotificationsPreferenceCopyWith<$Res> get notificationsPreference { + return $NotificationsPreferenceCopyWith<$Res>(_self.notificationsPreference, + (value) { + return _then(_self.copyWith(notificationsPreference: value)); + }); + } +} + +// dart format on diff --git a/lib/settings/models/preferences.g.dart b/lib/settings/models/preferences.g.dart index 5813f67..55f21a7 100644 --- a/lib/settings/models/preferences.g.dart +++ b/lib/settings/models/preferences.g.dart @@ -6,23 +6,21 @@ part of 'preferences.dart'; // JsonSerializableGenerator // ************************************************************************** -_$LockPreferenceImpl _$$LockPreferenceImplFromJson(Map json) => - _$LockPreferenceImpl( +_LockPreference _$LockPreferenceFromJson(Map json) => + _LockPreference( inactivityLockSecs: (json['inactivity_lock_secs'] as num?)?.toInt() ?? 0, lockWhenSwitching: json['lock_when_switching'] as bool? ?? false, lockWithSystemLock: json['lock_with_system_lock'] as bool? ?? false, ); -Map _$$LockPreferenceImplToJson( - _$LockPreferenceImpl instance) => +Map _$LockPreferenceToJson(_LockPreference instance) => { 'inactivity_lock_secs': instance.inactivityLockSecs, 'lock_when_switching': instance.lockWhenSwitching, 'lock_with_system_lock': instance.lockWithSystemLock, }; -_$PreferencesImpl _$$PreferencesImplFromJson(Map json) => - _$PreferencesImpl( +_Preferences _$PreferencesFromJson(Map json) => _Preferences( themePreference: json['theme_preference'] == null ? ThemePreferences.defaults : ThemePreferences.fromJson(json['theme_preference']), @@ -37,7 +35,7 @@ _$PreferencesImpl _$$PreferencesImplFromJson(Map json) => : NotificationsPreference.fromJson(json['notifications_preference']), ); -Map _$$PreferencesImplToJson(_$PreferencesImpl instance) => +Map _$PreferencesToJson(_Preferences instance) => { 'theme_preference': instance.themePreference.toJson(), 'language_preference': instance.languagePreference.toJson(), diff --git a/lib/theme/models/theme_preference.dart b/lib/theme/models/theme_preference.dart index 4be6b4e..aaad52d 100644 --- a/lib/theme/models/theme_preference.dart +++ b/lib/theme/models/theme_preference.dart @@ -49,7 +49,7 @@ enum ColorPreference { } @freezed -class ThemePreferences with _$ThemePreferences { +sealed class ThemePreferences with _$ThemePreferences { const factory ThemePreferences({ @Default(BrightnessPreference.system) BrightnessPreference brightnessPreference, diff --git a/lib/theme/models/theme_preference.freezed.dart b/lib/theme/models/theme_preference.freezed.dart index d96ed38..c915bca 100644 --- a/lib/theme/models/theme_preference.freezed.dart +++ b/lib/theme/models/theme_preference.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,176 +10,32 @@ part of 'theme_preference.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -ThemePreferences _$ThemePreferencesFromJson(Map json) { - return _ThemePreferences.fromJson(json); -} - /// @nodoc mixin _$ThemePreferences { - BrightnessPreference get brightnessPreference => - throw _privateConstructorUsedError; - ColorPreference get colorPreference => throw _privateConstructorUsedError; - double get displayScale => throw _privateConstructorUsedError; - bool get enableWallpaper => throw _privateConstructorUsedError; - - /// Serializes this ThemePreferences to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + BrightnessPreference get brightnessPreference; + ColorPreference get colorPreference; + double get displayScale; + bool get enableWallpaper; /// Create a copy of ThemePreferences /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $ThemePreferencesCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$ThemePreferencesCopyWithImpl( + this as ThemePreferences, _$identity); -/// @nodoc -abstract class $ThemePreferencesCopyWith<$Res> { - factory $ThemePreferencesCopyWith( - ThemePreferences value, $Res Function(ThemePreferences) then) = - _$ThemePreferencesCopyWithImpl<$Res, ThemePreferences>; - @useResult - $Res call( - {BrightnessPreference brightnessPreference, - ColorPreference colorPreference, - double displayScale, - bool enableWallpaper}); -} - -/// @nodoc -class _$ThemePreferencesCopyWithImpl<$Res, $Val extends ThemePreferences> - implements $ThemePreferencesCopyWith<$Res> { - _$ThemePreferencesCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of ThemePreferences - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? brightnessPreference = null, - Object? colorPreference = null, - Object? displayScale = null, - Object? enableWallpaper = null, - }) { - return _then(_value.copyWith( - brightnessPreference: null == brightnessPreference - ? _value.brightnessPreference - : brightnessPreference // ignore: cast_nullable_to_non_nullable - as BrightnessPreference, - colorPreference: null == colorPreference - ? _value.colorPreference - : colorPreference // ignore: cast_nullable_to_non_nullable - as ColorPreference, - displayScale: null == displayScale - ? _value.displayScale - : displayScale // ignore: cast_nullable_to_non_nullable - as double, - enableWallpaper: null == enableWallpaper - ? _value.enableWallpaper - : enableWallpaper // ignore: cast_nullable_to_non_nullable - as bool, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$ThemePreferencesImplCopyWith<$Res> - implements $ThemePreferencesCopyWith<$Res> { - factory _$$ThemePreferencesImplCopyWith(_$ThemePreferencesImpl value, - $Res Function(_$ThemePreferencesImpl) then) = - __$$ThemePreferencesImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {BrightnessPreference brightnessPreference, - ColorPreference colorPreference, - double displayScale, - bool enableWallpaper}); -} - -/// @nodoc -class __$$ThemePreferencesImplCopyWithImpl<$Res> - extends _$ThemePreferencesCopyWithImpl<$Res, _$ThemePreferencesImpl> - implements _$$ThemePreferencesImplCopyWith<$Res> { - __$$ThemePreferencesImplCopyWithImpl(_$ThemePreferencesImpl _value, - $Res Function(_$ThemePreferencesImpl) _then) - : super(_value, _then); - - /// Create a copy of ThemePreferences - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? brightnessPreference = null, - Object? colorPreference = null, - Object? displayScale = null, - Object? enableWallpaper = null, - }) { - return _then(_$ThemePreferencesImpl( - brightnessPreference: null == brightnessPreference - ? _value.brightnessPreference - : brightnessPreference // ignore: cast_nullable_to_non_nullable - as BrightnessPreference, - colorPreference: null == colorPreference - ? _value.colorPreference - : colorPreference // ignore: cast_nullable_to_non_nullable - as ColorPreference, - displayScale: null == displayScale - ? _value.displayScale - : displayScale // ignore: cast_nullable_to_non_nullable - as double, - enableWallpaper: null == enableWallpaper - ? _value.enableWallpaper - : enableWallpaper // ignore: cast_nullable_to_non_nullable - as bool, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$ThemePreferencesImpl implements _ThemePreferences { - const _$ThemePreferencesImpl( - {this.brightnessPreference = BrightnessPreference.system, - this.colorPreference = ColorPreference.vapor, - this.displayScale = 1, - this.enableWallpaper = true}); - - factory _$ThemePreferencesImpl.fromJson(Map json) => - _$$ThemePreferencesImplFromJson(json); - - @override - @JsonKey() - final BrightnessPreference brightnessPreference; - @override - @JsonKey() - final ColorPreference colorPreference; - @override - @JsonKey() - final double displayScale; - @override - @JsonKey() - final bool enableWallpaper; - - @override - String toString() { - return 'ThemePreferences(brightnessPreference: $brightnessPreference, colorPreference: $colorPreference, displayScale: $displayScale, enableWallpaper: $enableWallpaper)'; - } + /// Serializes this ThemePreferences to a JSON map. + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$ThemePreferencesImpl && + other is ThemePreferences && (identical(other.brightnessPreference, brightnessPreference) || other.brightnessPreference == brightnessPreference) && (identical(other.colorPreference, colorPreference) || @@ -194,46 +51,181 @@ class _$ThemePreferencesImpl implements _ThemePreferences { int get hashCode => Object.hash(runtimeType, brightnessPreference, colorPreference, displayScale, enableWallpaper); - /// Create a copy of ThemePreferences - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$ThemePreferencesImplCopyWith<_$ThemePreferencesImpl> get copyWith => - __$$ThemePreferencesImplCopyWithImpl<_$ThemePreferencesImpl>( - this, _$identity); - - @override - Map toJson() { - return _$$ThemePreferencesImplToJson( - this, - ); + String toString() { + return 'ThemePreferences(brightnessPreference: $brightnessPreference, colorPreference: $colorPreference, displayScale: $displayScale, enableWallpaper: $enableWallpaper)'; } } -abstract class _ThemePreferences implements ThemePreferences { - const factory _ThemePreferences( - {final BrightnessPreference brightnessPreference, - final ColorPreference colorPreference, - final double displayScale, - final bool enableWallpaper}) = _$ThemePreferencesImpl; +/// @nodoc +abstract mixin class $ThemePreferencesCopyWith<$Res> { + factory $ThemePreferencesCopyWith( + ThemePreferences value, $Res Function(ThemePreferences) _then) = + _$ThemePreferencesCopyWithImpl; + @useResult + $Res call( + {BrightnessPreference brightnessPreference, + ColorPreference colorPreference, + double displayScale, + bool enableWallpaper}); +} - factory _ThemePreferences.fromJson(Map json) = - _$ThemePreferencesImpl.fromJson; +/// @nodoc +class _$ThemePreferencesCopyWithImpl<$Res> + implements $ThemePreferencesCopyWith<$Res> { + _$ThemePreferencesCopyWithImpl(this._self, this._then); + + final ThemePreferences _self; + final $Res Function(ThemePreferences) _then; + + /// Create a copy of ThemePreferences + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? brightnessPreference = null, + Object? colorPreference = null, + Object? displayScale = null, + Object? enableWallpaper = null, + }) { + return _then(_self.copyWith( + brightnessPreference: null == brightnessPreference + ? _self.brightnessPreference + : brightnessPreference // ignore: cast_nullable_to_non_nullable + as BrightnessPreference, + colorPreference: null == colorPreference + ? _self.colorPreference + : colorPreference // ignore: cast_nullable_to_non_nullable + as ColorPreference, + displayScale: null == displayScale + ? _self.displayScale + : displayScale // ignore: cast_nullable_to_non_nullable + as double, + enableWallpaper: null == enableWallpaper + ? _self.enableWallpaper + : enableWallpaper // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _ThemePreferences implements ThemePreferences { + const _ThemePreferences( + {this.brightnessPreference = BrightnessPreference.system, + this.colorPreference = ColorPreference.vapor, + this.displayScale = 1, + this.enableWallpaper = true}); + factory _ThemePreferences.fromJson(Map json) => + _$ThemePreferencesFromJson(json); @override - BrightnessPreference get brightnessPreference; + @JsonKey() + final BrightnessPreference brightnessPreference; @override - ColorPreference get colorPreference; + @JsonKey() + final ColorPreference colorPreference; @override - double get displayScale; + @JsonKey() + final double displayScale; @override - bool get enableWallpaper; + @JsonKey() + final bool enableWallpaper; /// Create a copy of ThemePreferences /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$ThemePreferencesImplCopyWith<_$ThemePreferencesImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$ThemePreferencesCopyWith<_ThemePreferences> get copyWith => + __$ThemePreferencesCopyWithImpl<_ThemePreferences>(this, _$identity); + + @override + Map toJson() { + return _$ThemePreferencesToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _ThemePreferences && + (identical(other.brightnessPreference, brightnessPreference) || + other.brightnessPreference == brightnessPreference) && + (identical(other.colorPreference, colorPreference) || + other.colorPreference == colorPreference) && + (identical(other.displayScale, displayScale) || + other.displayScale == displayScale) && + (identical(other.enableWallpaper, enableWallpaper) || + other.enableWallpaper == enableWallpaper)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, brightnessPreference, + colorPreference, displayScale, enableWallpaper); + + @override + String toString() { + return 'ThemePreferences(brightnessPreference: $brightnessPreference, colorPreference: $colorPreference, displayScale: $displayScale, enableWallpaper: $enableWallpaper)'; + } } + +/// @nodoc +abstract mixin class _$ThemePreferencesCopyWith<$Res> + implements $ThemePreferencesCopyWith<$Res> { + factory _$ThemePreferencesCopyWith( + _ThemePreferences value, $Res Function(_ThemePreferences) _then) = + __$ThemePreferencesCopyWithImpl; + @override + @useResult + $Res call( + {BrightnessPreference brightnessPreference, + ColorPreference colorPreference, + double displayScale, + bool enableWallpaper}); +} + +/// @nodoc +class __$ThemePreferencesCopyWithImpl<$Res> + implements _$ThemePreferencesCopyWith<$Res> { + __$ThemePreferencesCopyWithImpl(this._self, this._then); + + final _ThemePreferences _self; + final $Res Function(_ThemePreferences) _then; + + /// Create a copy of ThemePreferences + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? brightnessPreference = null, + Object? colorPreference = null, + Object? displayScale = null, + Object? enableWallpaper = null, + }) { + return _then(_ThemePreferences( + brightnessPreference: null == brightnessPreference + ? _self.brightnessPreference + : brightnessPreference // ignore: cast_nullable_to_non_nullable + as BrightnessPreference, + colorPreference: null == colorPreference + ? _self.colorPreference + : colorPreference // ignore: cast_nullable_to_non_nullable + as ColorPreference, + displayScale: null == displayScale + ? _self.displayScale + : displayScale // ignore: cast_nullable_to_non_nullable + as double, + enableWallpaper: null == enableWallpaper + ? _self.enableWallpaper + : enableWallpaper // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +// dart format on diff --git a/lib/theme/models/theme_preference.g.dart b/lib/theme/models/theme_preference.g.dart index 23c3d38..f052e2c 100644 --- a/lib/theme/models/theme_preference.g.dart +++ b/lib/theme/models/theme_preference.g.dart @@ -6,9 +6,8 @@ part of 'theme_preference.dart'; // JsonSerializableGenerator // ************************************************************************** -_$ThemePreferencesImpl _$$ThemePreferencesImplFromJson( - Map json) => - _$ThemePreferencesImpl( +_ThemePreferences _$ThemePreferencesFromJson(Map json) => + _ThemePreferences( brightnessPreference: json['brightness_preference'] == null ? BrightnessPreference.system : BrightnessPreference.fromJson(json['brightness_preference']), @@ -19,8 +18,7 @@ _$ThemePreferencesImpl _$$ThemePreferencesImplFromJson( enableWallpaper: json['enable_wallpaper'] as bool? ?? true, ); -Map _$$ThemePreferencesImplToJson( - _$ThemePreferencesImpl instance) => +Map _$ThemePreferencesToJson(_ThemePreferences instance) => { 'brightness_preference': instance.brightnessPreference.toJson(), 'color_preference': instance.colorPreference.toJson(), diff --git a/lib/tools/loggy.dart b/lib/tools/loggy.dart index 2730888..47a1ffd 100644 --- a/lib/tools/loggy.dart +++ b/lib/tools/loggy.dart @@ -8,6 +8,7 @@ import 'package:intl/intl.dart'; import 'package:loggy/loggy.dart'; import 'package:veilid_support/veilid_support.dart'; +import '../proto/proto.dart'; import '../veilid_processor/views/developer.dart'; import 'state_logger.dart'; @@ -121,6 +122,7 @@ class CallbackPrinter extends LoggyPrinter { callback?.call(record); } + // Change callback function // ignore: use_setters_to_change_properties void setCallback(void Function(LogRecord)? cb) { callback = cb; @@ -147,6 +149,7 @@ void initLoggy() { logOptions: getLogOptions(null), ); + // Allow trace logging from the command line // ignore: do_not_use_environment const isTrace = String.fromEnvironment('LOG_TRACE') != ''; LogLevel logLevel; @@ -159,5 +162,8 @@ void initLoggy() { Loggy('').level = getLogOptions(logLevel); // Create state logger + registerVeilidProtoToDebug(); + registerVeilidDHTProtoToDebug(); + registerVeilidchatProtoToDebug(); Bloc.observer = const StateLogger(); } diff --git a/lib/tools/state_logger.dart b/lib/tools/state_logger.dart index 08e32b3..50dec46 100644 --- a/lib/tools/state_logger.dart +++ b/lib/tools/state_logger.dart @@ -1,5 +1,8 @@ +import 'dart:convert'; + import 'package:bloc/bloc.dart'; import 'package:loggy/loggy.dart'; +import 'package:veilid_support/veilid_support.dart'; import 'loggy.dart'; const Map _blocChangeLogLevels = { @@ -38,7 +41,12 @@ class StateLogger extends BlocObserver { void onChange(BlocBase bloc, Change change) { super.onChange(bloc, change); _checkLogLevel(_blocChangeLogLevels, LogLevel.debug, bloc, (logLevel) { - log.log(logLevel, 'Change: ${bloc.runtimeType} $change'); + const encoder = JsonEncoder.withIndent(' ', DynamicDebug.toDebug); + log.log( + logLevel, + 'Change: ${bloc.runtimeType}\n' + 'currentState: ${encoder.convert(change.currentState)}\n' + 'nextState: ${encoder.convert(change.nextState)}\n'); }); } diff --git a/lib/veilid_processor/models/processor_connection_state.dart b/lib/veilid_processor/models/processor_connection_state.dart index e92ebdc..6b68a8e 100644 --- a/lib/veilid_processor/models/processor_connection_state.dart +++ b/lib/veilid_processor/models/processor_connection_state.dart @@ -4,7 +4,7 @@ import 'package:veilid_support/veilid_support.dart'; part 'processor_connection_state.freezed.dart'; @freezed -class ProcessorConnectionState with _$ProcessorConnectionState { +sealed class ProcessorConnectionState with _$ProcessorConnectionState { const factory ProcessorConnectionState({ required VeilidStateAttachment attachment, required VeilidStateNetwork network, diff --git a/lib/veilid_processor/models/processor_connection_state.freezed.dart b/lib/veilid_processor/models/processor_connection_state.freezed.dart index 87ad295..c7c5288 100644 --- a/lib/veilid_processor/models/processor_connection_state.freezed.dart +++ b/lib/veilid_processor/models/processor_connection_state.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,157 +10,27 @@ part of 'processor_connection_state.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - /// @nodoc mixin _$ProcessorConnectionState { - VeilidStateAttachment get attachment => throw _privateConstructorUsedError; - VeilidStateNetwork get network => throw _privateConstructorUsedError; + VeilidStateAttachment get attachment; + VeilidStateNetwork get network; /// Create a copy of ProcessorConnectionState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $ProcessorConnectionStateCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $ProcessorConnectionStateCopyWith<$Res> { - factory $ProcessorConnectionStateCopyWith(ProcessorConnectionState value, - $Res Function(ProcessorConnectionState) then) = - _$ProcessorConnectionStateCopyWithImpl<$Res, ProcessorConnectionState>; - @useResult - $Res call({VeilidStateAttachment attachment, VeilidStateNetwork network}); - - $VeilidStateAttachmentCopyWith<$Res> get attachment; - $VeilidStateNetworkCopyWith<$Res> get network; -} - -/// @nodoc -class _$ProcessorConnectionStateCopyWithImpl<$Res, - $Val extends ProcessorConnectionState> - implements $ProcessorConnectionStateCopyWith<$Res> { - _$ProcessorConnectionStateCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of ProcessorConnectionState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? attachment = null, - Object? network = null, - }) { - return _then(_value.copyWith( - attachment: null == attachment - ? _value.attachment - : attachment // ignore: cast_nullable_to_non_nullable - as VeilidStateAttachment, - network: null == network - ? _value.network - : network // ignore: cast_nullable_to_non_nullable - as VeilidStateNetwork, - ) as $Val); - } - - /// Create a copy of ProcessorConnectionState - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $VeilidStateAttachmentCopyWith<$Res> get attachment { - return $VeilidStateAttachmentCopyWith<$Res>(_value.attachment, (value) { - return _then(_value.copyWith(attachment: value) as $Val); - }); - } - - /// Create a copy of ProcessorConnectionState - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $VeilidStateNetworkCopyWith<$Res> get network { - return $VeilidStateNetworkCopyWith<$Res>(_value.network, (value) { - return _then(_value.copyWith(network: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$ProcessorConnectionStateImplCopyWith<$Res> - implements $ProcessorConnectionStateCopyWith<$Res> { - factory _$$ProcessorConnectionStateImplCopyWith( - _$ProcessorConnectionStateImpl value, - $Res Function(_$ProcessorConnectionStateImpl) then) = - __$$ProcessorConnectionStateImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({VeilidStateAttachment attachment, VeilidStateNetwork network}); - - @override - $VeilidStateAttachmentCopyWith<$Res> get attachment; - @override - $VeilidStateNetworkCopyWith<$Res> get network; -} - -/// @nodoc -class __$$ProcessorConnectionStateImplCopyWithImpl<$Res> - extends _$ProcessorConnectionStateCopyWithImpl<$Res, - _$ProcessorConnectionStateImpl> - implements _$$ProcessorConnectionStateImplCopyWith<$Res> { - __$$ProcessorConnectionStateImplCopyWithImpl( - _$ProcessorConnectionStateImpl _value, - $Res Function(_$ProcessorConnectionStateImpl) _then) - : super(_value, _then); - - /// Create a copy of ProcessorConnectionState - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? attachment = null, - Object? network = null, - }) { - return _then(_$ProcessorConnectionStateImpl( - attachment: null == attachment - ? _value.attachment - : attachment // ignore: cast_nullable_to_non_nullable - as VeilidStateAttachment, - network: null == network - ? _value.network - : network // ignore: cast_nullable_to_non_nullable - as VeilidStateNetwork, - )); - } -} - -/// @nodoc - -class _$ProcessorConnectionStateImpl extends _ProcessorConnectionState { - const _$ProcessorConnectionStateImpl( - {required this.attachment, required this.network}) - : super._(); - - @override - final VeilidStateAttachment attachment; - @override - final VeilidStateNetwork network; - - @override - String toString() { - return 'ProcessorConnectionState(attachment: $attachment, network: $network)'; - } + _$ProcessorConnectionStateCopyWithImpl( + this as ProcessorConnectionState, _$identity); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$ProcessorConnectionStateImpl && + other is ProcessorConnectionState && (identical(other.attachment, attachment) || other.attachment == attachment) && (identical(other.network, network) || other.network == network)); @@ -168,32 +39,176 @@ class _$ProcessorConnectionStateImpl extends _ProcessorConnectionState { @override int get hashCode => Object.hash(runtimeType, attachment, network); + @override + String toString() { + return 'ProcessorConnectionState(attachment: $attachment, network: $network)'; + } +} + +/// @nodoc +abstract mixin class $ProcessorConnectionStateCopyWith<$Res> { + factory $ProcessorConnectionStateCopyWith(ProcessorConnectionState value, + $Res Function(ProcessorConnectionState) _then) = + _$ProcessorConnectionStateCopyWithImpl; + @useResult + $Res call({VeilidStateAttachment attachment, VeilidStateNetwork network}); + + $VeilidStateAttachmentCopyWith<$Res> get attachment; + $VeilidStateNetworkCopyWith<$Res> get network; +} + +/// @nodoc +class _$ProcessorConnectionStateCopyWithImpl<$Res> + implements $ProcessorConnectionStateCopyWith<$Res> { + _$ProcessorConnectionStateCopyWithImpl(this._self, this._then); + + final ProcessorConnectionState _self; + final $Res Function(ProcessorConnectionState) _then; + + /// Create a copy of ProcessorConnectionState + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? attachment = null, + Object? network = null, + }) { + return _then(_self.copyWith( + attachment: null == attachment + ? _self.attachment + : attachment // ignore: cast_nullable_to_non_nullable + as VeilidStateAttachment, + network: null == network + ? _self.network + : network // ignore: cast_nullable_to_non_nullable + as VeilidStateNetwork, + )); + } + /// Create a copy of ProcessorConnectionState /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') - _$$ProcessorConnectionStateImplCopyWith<_$ProcessorConnectionStateImpl> - get copyWith => __$$ProcessorConnectionStateImplCopyWithImpl< - _$ProcessorConnectionStateImpl>(this, _$identity); + $VeilidStateAttachmentCopyWith<$Res> get attachment { + return $VeilidStateAttachmentCopyWith<$Res>(_self.attachment, (value) { + return _then(_self.copyWith(attachment: value)); + }); + } + + /// Create a copy of ProcessorConnectionState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $VeilidStateNetworkCopyWith<$Res> get network { + return $VeilidStateNetworkCopyWith<$Res>(_self.network, (value) { + return _then(_self.copyWith(network: value)); + }); + } } -abstract class _ProcessorConnectionState extends ProcessorConnectionState { - const factory _ProcessorConnectionState( - {required final VeilidStateAttachment attachment, - required final VeilidStateNetwork network}) = - _$ProcessorConnectionStateImpl; - const _ProcessorConnectionState._() : super._(); +/// @nodoc + +class _ProcessorConnectionState extends ProcessorConnectionState { + const _ProcessorConnectionState( + {required this.attachment, required this.network}) + : super._(); @override - VeilidStateAttachment get attachment; + final VeilidStateAttachment attachment; @override - VeilidStateNetwork get network; + final VeilidStateNetwork network; /// Create a copy of ProcessorConnectionState /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$ProcessorConnectionStateImplCopyWith<_$ProcessorConnectionStateImpl> - get copyWith => throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$ProcessorConnectionStateCopyWith<_ProcessorConnectionState> get copyWith => + __$ProcessorConnectionStateCopyWithImpl<_ProcessorConnectionState>( + this, _$identity); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _ProcessorConnectionState && + (identical(other.attachment, attachment) || + other.attachment == attachment) && + (identical(other.network, network) || other.network == network)); + } + + @override + int get hashCode => Object.hash(runtimeType, attachment, network); + + @override + String toString() { + return 'ProcessorConnectionState(attachment: $attachment, network: $network)'; + } } + +/// @nodoc +abstract mixin class _$ProcessorConnectionStateCopyWith<$Res> + implements $ProcessorConnectionStateCopyWith<$Res> { + factory _$ProcessorConnectionStateCopyWith(_ProcessorConnectionState value, + $Res Function(_ProcessorConnectionState) _then) = + __$ProcessorConnectionStateCopyWithImpl; + @override + @useResult + $Res call({VeilidStateAttachment attachment, VeilidStateNetwork network}); + + @override + $VeilidStateAttachmentCopyWith<$Res> get attachment; + @override + $VeilidStateNetworkCopyWith<$Res> get network; +} + +/// @nodoc +class __$ProcessorConnectionStateCopyWithImpl<$Res> + implements _$ProcessorConnectionStateCopyWith<$Res> { + __$ProcessorConnectionStateCopyWithImpl(this._self, this._then); + + final _ProcessorConnectionState _self; + final $Res Function(_ProcessorConnectionState) _then; + + /// Create a copy of ProcessorConnectionState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? attachment = null, + Object? network = null, + }) { + return _then(_ProcessorConnectionState( + attachment: null == attachment + ? _self.attachment + : attachment // ignore: cast_nullable_to_non_nullable + as VeilidStateAttachment, + network: null == network + ? _self.network + : network // ignore: cast_nullable_to_non_nullable + as VeilidStateNetwork, + )); + } + + /// Create a copy of ProcessorConnectionState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $VeilidStateAttachmentCopyWith<$Res> get attachment { + return $VeilidStateAttachmentCopyWith<$Res>(_self.attachment, (value) { + return _then(_self.copyWith(attachment: value)); + }); + } + + /// Create a copy of ProcessorConnectionState + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $VeilidStateNetworkCopyWith<$Res> get network { + return $VeilidStateNetworkCopyWith<$Res>(_self.network, (value) { + return _then(_self.copyWith(network: value)); + }); + } +} + +// dart format on diff --git a/packages/veilid_support/lib/dht_support/proto/proto.dart b/packages/veilid_support/lib/dht_support/proto/proto.dart index 6b36970..ceac3d5 100644 --- a/packages/veilid_support/lib/dht_support/proto/proto.dart +++ b/packages/veilid_support/lib/dht_support/proto/proto.dart @@ -1,5 +1,6 @@ import '../../proto/dht.pb.dart' as dhtproto; import '../../proto/proto.dart' as veilidproto; +import '../../src/dynamic_debug.dart'; import '../dht_support.dart'; export '../../proto/dht.pb.dart'; @@ -23,3 +24,44 @@ extension ProtoOwnedDHTRecordPointer on dhtproto.OwnedDHTRecordPointer { OwnedDHTRecordPointer toVeilid() => OwnedDHTRecordPointer( recordKey: recordKey.toVeilid(), owner: owner.toVeilid()); } + +void registerVeilidDHTProtoToDebug() { + dynamic toDebug(dynamic obj) { + if (obj is dhtproto.OwnedDHTRecordPointer) { + return { + r'$runtimeType': obj.runtimeType, + 'recordKey': obj.recordKey, + 'owner': obj.owner, + }; + } + if (obj is dhtproto.DHTData) { + return { + r'$runtimeType': obj.runtimeType, + 'keys': obj.keys, + 'hash': obj.hash, + 'chunk': obj.chunk, + 'size': obj.size + }; + } + if (obj is dhtproto.DHTLog) { + return { + r'$runtimeType': obj.runtimeType, + 'head': obj.head, + 'tail': obj.tail, + 'stride': obj.stride, + }; + } + if (obj is dhtproto.DHTShortArray) { + return { + r'$runtimeType': obj.runtimeType, + 'keys': obj.keys, + 'index': obj.index, + 'seqs': obj.seqs, + }; + } + + return obj; + } + + DynamicDebug.registerToDebug(toDebug); +} diff --git a/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_cubit.dart b/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_cubit.dart index c299bdc..492312f 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_cubit.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_cubit.dart @@ -31,6 +31,14 @@ class DHTLogStateData extends Equatable { @override List get props => [length, window, windowTail, windowSize, follow]; + + @override + String toString() => 'DHTLogStateData(' + 'length: $length, ' + 'windowTail: $windowTail, ' + 'windowSize: $windowSize, ' + 'follow: $follow, ' + 'window: ${DynamicDebug.toDebug(window)})'; } typedef DHTLogState = AsyncValue>; diff --git a/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_spine.dart b/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_spine.dart index 8eff1b6..bb27e04 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_spine.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_log/dht_log_spine.dart @@ -126,10 +126,7 @@ class _DHTLogSpine { Future delete() async => _spineMutex.protect(_spineRecord.delete); Future operate(Future Function(_DHTLogSpine) closure) async => - // ignore: prefer_expression_function_bodies - _spineMutex.protect(() async { - return closure(this); - }); + _spineMutex.protect(() async => closure(this)); Future operateAppend(Future Function(_DHTLogSpine) closure) async => _spineMutex.protect(() async { diff --git a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record.dart b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record.dart index 0a51ba1..4e632fc 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record.dart @@ -511,7 +511,7 @@ class DHTRecord implements DHTDeleteable { key, subkeys: [ValueSubkeyRange.single(subkey)], ); - return rr.localSeqs.firstOrNull ?? 0xFFFFFFFF; + return rr.localSeqs.firstOrNull ?? emptySeq; } void _addValueChange( @@ -566,4 +566,6 @@ class DHTRecord implements DHTDeleteable { int _openCount; StreamController? _watchController; _WatchState? _watchState; + + static const int emptySeq = 0xFFFFFFFF; } diff --git a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.dart b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.dart index 15c955d..9027799 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.dart @@ -9,6 +9,7 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:protobuf/protobuf.dart'; import '../../../../veilid_support.dart'; +import 'extensions.dart'; export 'package:fast_immutable_collections/fast_immutable_collections.dart' show Output; @@ -32,7 +33,7 @@ typedef DHTRecordPoolLogger = void Function(String message); /// Record pool that managed DHTRecords and allows for tagged deletion /// String versions of keys due to IMap<> json unsupported in key @freezed -class DHTRecordPoolAllocations with _$DHTRecordPoolAllocations { +sealed class DHTRecordPoolAllocations with _$DHTRecordPoolAllocations { const factory DHTRecordPoolAllocations({ @Default(IMapConst>({})) IMap> childrenByParent, @@ -49,7 +50,7 @@ class DHTRecordPoolAllocations with _$DHTRecordPoolAllocations { /// Pointer to an owned record, with key, owner key and owner secret /// Ensure that these are only serialized encrypted @freezed -class OwnedDHTRecordPointer with _$OwnedDHTRecordPointer { +sealed class OwnedDHTRecordPointer with _$OwnedDHTRecordPointer { const factory OwnedDHTRecordPointer({ required TypedKey recordKey, required KeyPair owner, @@ -843,8 +844,12 @@ class DHTRecordPool with TableDBBackedJson { log('Timeout in watch cancel for key=$openedRecordKey'); } on VeilidAPIException catch (e) { // Failed to cancel DHT watch, try again next tick - log('Exception in watch cancel for key=$openedRecordKey: $e'); + log('VeilidAPIException in watch cancel for key=$openedRecordKey: $e'); + } catch (e) { + log('Unhandled exception in watch cancel for key=$openedRecordKey: $e'); + rethrow; } + return; } @@ -887,7 +892,10 @@ class DHTRecordPool with TableDBBackedJson { log('Timeout in watch update for key=$openedRecordKey'); } on VeilidAPIException catch (e) { // Failed to update DHT watch, try again next tick - log('Exception in watch update for key=$openedRecordKey: $e'); + log('VeilidAPIException in watch update for key=$openedRecordKey: $e'); + } catch (e) { + log('Unhandled exception in watch update for key=$openedRecordKey: $e'); + rethrow; } // If we still need a state update after this then do a poll instead @@ -904,28 +912,29 @@ class DHTRecordPool with TableDBBackedJson { singleFuture((this, _sfPollWatch, openedRecordKey), () async { final dhtctx = openedRecordInfo.shared.defaultRoutingContext; - // Get single subkey to poll - // XXX: veilid api limits this for now until everyone supports - // inspectDHTRecord - final pollSubkey = unionWatchState.subkeys?.firstSubkey; - if (pollSubkey == null) { - return; + final currentReport = await dhtctx.inspectDHTRecord(openedRecordKey, + subkeys: unionWatchState.subkeys, scope: DHTReportScope.syncGet); + + final fsc = currentReport.firstSeqChange; + if (fsc == null) { + return null; } - final pollSubkeys = [ValueSubkeyRange.single(pollSubkey)]; + final newerSubkeys = currentReport.newerSubkeys; - final currentReport = - await dhtctx.inspectDHTRecord(openedRecordKey, subkeys: pollSubkeys); - final currentSeq = currentReport.localSeqs.firstOrNull ?? -1; - - final valueData = await dhtctx.getDHTValue(openedRecordKey, pollSubkey, + final valueData = await dhtctx.getDHTValue(openedRecordKey, fsc.subkey, forceRefresh: true); if (valueData == null) { return; } - if (valueData.seq > currentSeq) { + + if (valueData.seq < fsc.newSeq) { + log('inspect returned a newer seq than get: ${valueData.seq} < $fsc'); + } + + if (valueData.seq > fsc.oldSeq && valueData.seq != DHTRecord.emptySeq) { processRemoteValueChange(VeilidUpdateValueChange( key: openedRecordKey, - subkeys: pollSubkeys, + subkeys: newerSubkeys, count: 0xFFFFFFFF, value: valueData)); } diff --git a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.freezed.dart b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.freezed.dart index 9e51ef8..48372bb 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.freezed.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,183 +10,32 @@ part of 'dht_record_pool.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -DHTRecordPoolAllocations _$DHTRecordPoolAllocationsFromJson( - Map json) { - return _DHTRecordPoolAllocations.fromJson(json); -} - /// @nodoc mixin _$DHTRecordPoolAllocations { - IMap>> get childrenByParent => - throw _privateConstructorUsedError; - IMap> get parentByChild => - throw _privateConstructorUsedError; - ISet> get rootRecords => - throw _privateConstructorUsedError; - IMap get debugNames => throw _privateConstructorUsedError; - - /// Serializes this DHTRecordPoolAllocations to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + IMap> get childrenByParent; + IMap get parentByChild; + ISet get rootRecords; + IMap get debugNames; /// Create a copy of DHTRecordPoolAllocations /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $DHTRecordPoolAllocationsCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$DHTRecordPoolAllocationsCopyWithImpl( + this as DHTRecordPoolAllocations, _$identity); -/// @nodoc -abstract class $DHTRecordPoolAllocationsCopyWith<$Res> { - factory $DHTRecordPoolAllocationsCopyWith(DHTRecordPoolAllocations value, - $Res Function(DHTRecordPoolAllocations) then) = - _$DHTRecordPoolAllocationsCopyWithImpl<$Res, DHTRecordPoolAllocations>; - @useResult - $Res call( - {IMap>> childrenByParent, - IMap> parentByChild, - ISet> rootRecords, - IMap debugNames}); -} - -/// @nodoc -class _$DHTRecordPoolAllocationsCopyWithImpl<$Res, - $Val extends DHTRecordPoolAllocations> - implements $DHTRecordPoolAllocationsCopyWith<$Res> { - _$DHTRecordPoolAllocationsCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of DHTRecordPoolAllocations - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? childrenByParent = null, - Object? parentByChild = null, - Object? rootRecords = null, - Object? debugNames = null, - }) { - return _then(_value.copyWith( - childrenByParent: null == childrenByParent - ? _value.childrenByParent - : childrenByParent // ignore: cast_nullable_to_non_nullable - as IMap>>, - parentByChild: null == parentByChild - ? _value.parentByChild - : parentByChild // ignore: cast_nullable_to_non_nullable - as IMap>, - rootRecords: null == rootRecords - ? _value.rootRecords - : rootRecords // ignore: cast_nullable_to_non_nullable - as ISet>, - debugNames: null == debugNames - ? _value.debugNames - : debugNames // ignore: cast_nullable_to_non_nullable - as IMap, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$DHTRecordPoolAllocationsImplCopyWith<$Res> - implements $DHTRecordPoolAllocationsCopyWith<$Res> { - factory _$$DHTRecordPoolAllocationsImplCopyWith( - _$DHTRecordPoolAllocationsImpl value, - $Res Function(_$DHTRecordPoolAllocationsImpl) then) = - __$$DHTRecordPoolAllocationsImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {IMap>> childrenByParent, - IMap> parentByChild, - ISet> rootRecords, - IMap debugNames}); -} - -/// @nodoc -class __$$DHTRecordPoolAllocationsImplCopyWithImpl<$Res> - extends _$DHTRecordPoolAllocationsCopyWithImpl<$Res, - _$DHTRecordPoolAllocationsImpl> - implements _$$DHTRecordPoolAllocationsImplCopyWith<$Res> { - __$$DHTRecordPoolAllocationsImplCopyWithImpl( - _$DHTRecordPoolAllocationsImpl _value, - $Res Function(_$DHTRecordPoolAllocationsImpl) _then) - : super(_value, _then); - - /// Create a copy of DHTRecordPoolAllocations - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? childrenByParent = null, - Object? parentByChild = null, - Object? rootRecords = null, - Object? debugNames = null, - }) { - return _then(_$DHTRecordPoolAllocationsImpl( - childrenByParent: null == childrenByParent - ? _value.childrenByParent - : childrenByParent // ignore: cast_nullable_to_non_nullable - as IMap>>, - parentByChild: null == parentByChild - ? _value.parentByChild - : parentByChild // ignore: cast_nullable_to_non_nullable - as IMap>, - rootRecords: null == rootRecords - ? _value.rootRecords - : rootRecords // ignore: cast_nullable_to_non_nullable - as ISet>, - debugNames: null == debugNames - ? _value.debugNames - : debugNames // ignore: cast_nullable_to_non_nullable - as IMap, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$DHTRecordPoolAllocationsImpl implements _DHTRecordPoolAllocations { - const _$DHTRecordPoolAllocationsImpl( - {this.childrenByParent = const IMapConst>({}), - this.parentByChild = const IMapConst({}), - this.rootRecords = const ISetConst({}), - this.debugNames = const IMapConst({})}); - - factory _$DHTRecordPoolAllocationsImpl.fromJson(Map json) => - _$$DHTRecordPoolAllocationsImplFromJson(json); - - @override - @JsonKey() - final IMap>> childrenByParent; - @override - @JsonKey() - final IMap> parentByChild; - @override - @JsonKey() - final ISet> rootRecords; - @override - @JsonKey() - final IMap debugNames; - - @override - String toString() { - return 'DHTRecordPoolAllocations(childrenByParent: $childrenByParent, parentByChild: $parentByChild, rootRecords: $rootRecords, debugNames: $debugNames)'; - } + /// Serializes this DHTRecordPoolAllocations to a JSON map. + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DHTRecordPoolAllocationsImpl && + other is DHTRecordPoolAllocations && (identical(other.childrenByParent, childrenByParent) || other.childrenByParent == childrenByParent) && (identical(other.parentByChild, parentByChild) || @@ -201,178 +51,205 @@ class _$DHTRecordPoolAllocationsImpl implements _DHTRecordPoolAllocations { int get hashCode => Object.hash(runtimeType, childrenByParent, parentByChild, const DeepCollectionEquality().hash(rootRecords), debugNames); - /// Create a copy of DHTRecordPoolAllocations - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$DHTRecordPoolAllocationsImplCopyWith<_$DHTRecordPoolAllocationsImpl> - get copyWith => __$$DHTRecordPoolAllocationsImplCopyWithImpl< - _$DHTRecordPoolAllocationsImpl>(this, _$identity); - - @override - Map toJson() { - return _$$DHTRecordPoolAllocationsImplToJson( - this, - ); - } -} - -abstract class _DHTRecordPoolAllocations implements DHTRecordPoolAllocations { - const factory _DHTRecordPoolAllocations( - {final IMap>> childrenByParent, - final IMap> parentByChild, - final ISet> rootRecords, - final IMap debugNames}) = _$DHTRecordPoolAllocationsImpl; - - factory _DHTRecordPoolAllocations.fromJson(Map json) = - _$DHTRecordPoolAllocationsImpl.fromJson; - - @override - IMap>> get childrenByParent; - @override - IMap> get parentByChild; - @override - ISet> get rootRecords; - @override - IMap get debugNames; - - /// Create a copy of DHTRecordPoolAllocations - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$DHTRecordPoolAllocationsImplCopyWith<_$DHTRecordPoolAllocationsImpl> - get copyWith => throw _privateConstructorUsedError; -} - -OwnedDHTRecordPointer _$OwnedDHTRecordPointerFromJson( - Map json) { - return _OwnedDHTRecordPointer.fromJson(json); -} - -/// @nodoc -mixin _$OwnedDHTRecordPointer { - Typed get recordKey => - throw _privateConstructorUsedError; - KeyPair get owner => throw _privateConstructorUsedError; - - /// Serializes this OwnedDHTRecordPointer to a JSON map. - Map toJson() => throw _privateConstructorUsedError; - - /// Create a copy of OwnedDHTRecordPointer - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - $OwnedDHTRecordPointerCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $OwnedDHTRecordPointerCopyWith<$Res> { - factory $OwnedDHTRecordPointerCopyWith(OwnedDHTRecordPointer value, - $Res Function(OwnedDHTRecordPointer) then) = - _$OwnedDHTRecordPointerCopyWithImpl<$Res, OwnedDHTRecordPointer>; - @useResult - $Res call({Typed recordKey, KeyPair owner}); -} - -/// @nodoc -class _$OwnedDHTRecordPointerCopyWithImpl<$Res, - $Val extends OwnedDHTRecordPointer> - implements $OwnedDHTRecordPointerCopyWith<$Res> { - _$OwnedDHTRecordPointerCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of OwnedDHTRecordPointer - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? recordKey = null, - Object? owner = null, - }) { - return _then(_value.copyWith( - recordKey: null == recordKey - ? _value.recordKey - : recordKey // ignore: cast_nullable_to_non_nullable - as Typed, - owner: null == owner - ? _value.owner - : owner // ignore: cast_nullable_to_non_nullable - as KeyPair, - ) as $Val); + String toString() { + return 'DHTRecordPoolAllocations(childrenByParent: $childrenByParent, parentByChild: $parentByChild, rootRecords: $rootRecords, debugNames: $debugNames)'; } } /// @nodoc -abstract class _$$OwnedDHTRecordPointerImplCopyWith<$Res> - implements $OwnedDHTRecordPointerCopyWith<$Res> { - factory _$$OwnedDHTRecordPointerImplCopyWith( - _$OwnedDHTRecordPointerImpl value, - $Res Function(_$OwnedDHTRecordPointerImpl) then) = - __$$OwnedDHTRecordPointerImplCopyWithImpl<$Res>; - @override +abstract mixin class $DHTRecordPoolAllocationsCopyWith<$Res> { + factory $DHTRecordPoolAllocationsCopyWith(DHTRecordPoolAllocations value, + $Res Function(DHTRecordPoolAllocations) _then) = + _$DHTRecordPoolAllocationsCopyWithImpl; @useResult - $Res call({Typed recordKey, KeyPair owner}); + $Res call( + {IMap>> childrenByParent, + IMap> parentByChild, + ISet> rootRecords, + IMap debugNames}); } /// @nodoc -class __$$OwnedDHTRecordPointerImplCopyWithImpl<$Res> - extends _$OwnedDHTRecordPointerCopyWithImpl<$Res, - _$OwnedDHTRecordPointerImpl> - implements _$$OwnedDHTRecordPointerImplCopyWith<$Res> { - __$$OwnedDHTRecordPointerImplCopyWithImpl(_$OwnedDHTRecordPointerImpl _value, - $Res Function(_$OwnedDHTRecordPointerImpl) _then) - : super(_value, _then); +class _$DHTRecordPoolAllocationsCopyWithImpl<$Res> + implements $DHTRecordPoolAllocationsCopyWith<$Res> { + _$DHTRecordPoolAllocationsCopyWithImpl(this._self, this._then); - /// Create a copy of OwnedDHTRecordPointer + final DHTRecordPoolAllocations _self; + final $Res Function(DHTRecordPoolAllocations) _then; + + /// Create a copy of DHTRecordPoolAllocations /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') @override $Res call({ - Object? recordKey = null, - Object? owner = null, + Object? childrenByParent = null, + Object? parentByChild = null, + Object? rootRecords = null, + Object? debugNames = null, }) { - return _then(_$OwnedDHTRecordPointerImpl( - recordKey: null == recordKey - ? _value.recordKey - : recordKey // ignore: cast_nullable_to_non_nullable - as Typed, - owner: null == owner - ? _value.owner - : owner // ignore: cast_nullable_to_non_nullable - as KeyPair, + return _then(_self.copyWith( + childrenByParent: null == childrenByParent + ? _self.childrenByParent! + : childrenByParent // ignore: cast_nullable_to_non_nullable + as IMap>>, + parentByChild: null == parentByChild + ? _self.parentByChild! + : parentByChild // ignore: cast_nullable_to_non_nullable + as IMap>, + rootRecords: null == rootRecords + ? _self.rootRecords! + : rootRecords // ignore: cast_nullable_to_non_nullable + as ISet>, + debugNames: null == debugNames + ? _self.debugNames + : debugNames // ignore: cast_nullable_to_non_nullable + as IMap, )); } } /// @nodoc @JsonSerializable() -class _$OwnedDHTRecordPointerImpl implements _OwnedDHTRecordPointer { - const _$OwnedDHTRecordPointerImpl( - {required this.recordKey, required this.owner}); - - factory _$OwnedDHTRecordPointerImpl.fromJson(Map json) => - _$$OwnedDHTRecordPointerImplFromJson(json); +class _DHTRecordPoolAllocations implements DHTRecordPoolAllocations { + const _DHTRecordPoolAllocations( + {this.childrenByParent = const IMapConst>({}), + this.parentByChild = const IMapConst({}), + this.rootRecords = const ISetConst({}), + this.debugNames = const IMapConst({})}); + factory _DHTRecordPoolAllocations.fromJson(Map json) => + _$DHTRecordPoolAllocationsFromJson(json); @override - final Typed recordKey; + @JsonKey() + final IMap>> childrenByParent; @override - final KeyPair owner; + @JsonKey() + final IMap> parentByChild; + @override + @JsonKey() + final ISet> rootRecords; + @override + @JsonKey() + final IMap debugNames; + + /// Create a copy of DHTRecordPoolAllocations + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$DHTRecordPoolAllocationsCopyWith<_DHTRecordPoolAllocations> get copyWith => + __$DHTRecordPoolAllocationsCopyWithImpl<_DHTRecordPoolAllocations>( + this, _$identity); @override - String toString() { - return 'OwnedDHTRecordPointer(recordKey: $recordKey, owner: $owner)'; + Map toJson() { + return _$DHTRecordPoolAllocationsToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$OwnedDHTRecordPointerImpl && + other is _DHTRecordPoolAllocations && + (identical(other.childrenByParent, childrenByParent) || + other.childrenByParent == childrenByParent) && + (identical(other.parentByChild, parentByChild) || + other.parentByChild == parentByChild) && + const DeepCollectionEquality() + .equals(other.rootRecords, rootRecords) && + (identical(other.debugNames, debugNames) || + other.debugNames == debugNames)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, childrenByParent, parentByChild, + const DeepCollectionEquality().hash(rootRecords), debugNames); + + @override + String toString() { + return 'DHTRecordPoolAllocations(childrenByParent: $childrenByParent, parentByChild: $parentByChild, rootRecords: $rootRecords, debugNames: $debugNames)'; + } +} + +/// @nodoc +abstract mixin class _$DHTRecordPoolAllocationsCopyWith<$Res> + implements $DHTRecordPoolAllocationsCopyWith<$Res> { + factory _$DHTRecordPoolAllocationsCopyWith(_DHTRecordPoolAllocations value, + $Res Function(_DHTRecordPoolAllocations) _then) = + __$DHTRecordPoolAllocationsCopyWithImpl; + @override + @useResult + $Res call( + {IMap>> childrenByParent, + IMap> parentByChild, + ISet> rootRecords, + IMap debugNames}); +} + +/// @nodoc +class __$DHTRecordPoolAllocationsCopyWithImpl<$Res> + implements _$DHTRecordPoolAllocationsCopyWith<$Res> { + __$DHTRecordPoolAllocationsCopyWithImpl(this._self, this._then); + + final _DHTRecordPoolAllocations _self; + final $Res Function(_DHTRecordPoolAllocations) _then; + + /// Create a copy of DHTRecordPoolAllocations + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? childrenByParent = null, + Object? parentByChild = null, + Object? rootRecords = null, + Object? debugNames = null, + }) { + return _then(_DHTRecordPoolAllocations( + childrenByParent: null == childrenByParent + ? _self.childrenByParent + : childrenByParent // ignore: cast_nullable_to_non_nullable + as IMap>>, + parentByChild: null == parentByChild + ? _self.parentByChild + : parentByChild // ignore: cast_nullable_to_non_nullable + as IMap>, + rootRecords: null == rootRecords + ? _self.rootRecords + : rootRecords // ignore: cast_nullable_to_non_nullable + as ISet>, + debugNames: null == debugNames + ? _self.debugNames + : debugNames // ignore: cast_nullable_to_non_nullable + as IMap, + )); + } +} + +/// @nodoc +mixin _$OwnedDHTRecordPointer { + TypedKey get recordKey; + KeyPair get owner; + + /// Create a copy of OwnedDHTRecordPointer + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + $OwnedDHTRecordPointerCopyWith get copyWith => + _$OwnedDHTRecordPointerCopyWithImpl( + this as OwnedDHTRecordPointer, _$identity); + + /// Serializes this OwnedDHTRecordPointer to a JSON map. + Map toJson(); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is OwnedDHTRecordPointer && (identical(other.recordKey, recordKey) || other.recordKey == recordKey) && (identical(other.owner, owner) || other.owner == owner)); @@ -382,40 +259,136 @@ class _$OwnedDHTRecordPointerImpl implements _OwnedDHTRecordPointer { @override int get hashCode => Object.hash(runtimeType, recordKey, owner); - /// Create a copy of OwnedDHTRecordPointer - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$OwnedDHTRecordPointerImplCopyWith<_$OwnedDHTRecordPointerImpl> - get copyWith => __$$OwnedDHTRecordPointerImplCopyWithImpl< - _$OwnedDHTRecordPointerImpl>(this, _$identity); - - @override - Map toJson() { - return _$$OwnedDHTRecordPointerImplToJson( - this, - ); + String toString() { + return 'OwnedDHTRecordPointer(recordKey: $recordKey, owner: $owner)'; } } -abstract class _OwnedDHTRecordPointer implements OwnedDHTRecordPointer { - const factory _OwnedDHTRecordPointer( - {required final Typed recordKey, - required final KeyPair owner}) = _$OwnedDHTRecordPointerImpl; +/// @nodoc +abstract mixin class $OwnedDHTRecordPointerCopyWith<$Res> { + factory $OwnedDHTRecordPointerCopyWith(OwnedDHTRecordPointer value, + $Res Function(OwnedDHTRecordPointer) _then) = + _$OwnedDHTRecordPointerCopyWithImpl; + @useResult + $Res call({Typed recordKey, KeyPair owner}); +} - factory _OwnedDHTRecordPointer.fromJson(Map json) = - _$OwnedDHTRecordPointerImpl.fromJson; +/// @nodoc +class _$OwnedDHTRecordPointerCopyWithImpl<$Res> + implements $OwnedDHTRecordPointerCopyWith<$Res> { + _$OwnedDHTRecordPointerCopyWithImpl(this._self, this._then); + + final OwnedDHTRecordPointer _self; + final $Res Function(OwnedDHTRecordPointer) _then; + + /// Create a copy of OwnedDHTRecordPointer + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? recordKey = null, + Object? owner = null, + }) { + return _then(_self.copyWith( + recordKey: null == recordKey + ? _self.recordKey! + : recordKey // ignore: cast_nullable_to_non_nullable + as Typed, + owner: null == owner + ? _self.owner + : owner // ignore: cast_nullable_to_non_nullable + as KeyPair, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _OwnedDHTRecordPointer implements OwnedDHTRecordPointer { + const _OwnedDHTRecordPointer({required this.recordKey, required this.owner}); + factory _OwnedDHTRecordPointer.fromJson(Map json) => + _$OwnedDHTRecordPointerFromJson(json); @override - Typed get recordKey; + final Typed recordKey; @override - KeyPair get owner; + final KeyPair owner; /// Create a copy of OwnedDHTRecordPointer /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$OwnedDHTRecordPointerImplCopyWith<_$OwnedDHTRecordPointerImpl> - get copyWith => throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$OwnedDHTRecordPointerCopyWith<_OwnedDHTRecordPointer> get copyWith => + __$OwnedDHTRecordPointerCopyWithImpl<_OwnedDHTRecordPointer>( + this, _$identity); + + @override + Map toJson() { + return _$OwnedDHTRecordPointerToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _OwnedDHTRecordPointer && + (identical(other.recordKey, recordKey) || + other.recordKey == recordKey) && + (identical(other.owner, owner) || other.owner == owner)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, recordKey, owner); + + @override + String toString() { + return 'OwnedDHTRecordPointer(recordKey: $recordKey, owner: $owner)'; + } } + +/// @nodoc +abstract mixin class _$OwnedDHTRecordPointerCopyWith<$Res> + implements $OwnedDHTRecordPointerCopyWith<$Res> { + factory _$OwnedDHTRecordPointerCopyWith(_OwnedDHTRecordPointer value, + $Res Function(_OwnedDHTRecordPointer) _then) = + __$OwnedDHTRecordPointerCopyWithImpl; + @override + @useResult + $Res call({Typed recordKey, KeyPair owner}); +} + +/// @nodoc +class __$OwnedDHTRecordPointerCopyWithImpl<$Res> + implements _$OwnedDHTRecordPointerCopyWith<$Res> { + __$OwnedDHTRecordPointerCopyWithImpl(this._self, this._then); + + final _OwnedDHTRecordPointer _self; + final $Res Function(_OwnedDHTRecordPointer) _then; + + /// Create a copy of OwnedDHTRecordPointer + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? recordKey = null, + Object? owner = null, + }) { + return _then(_OwnedDHTRecordPointer( + recordKey: null == recordKey + ? _self.recordKey + : recordKey // ignore: cast_nullable_to_non_nullable + as Typed, + owner: null == owner + ? _self.owner + : owner // ignore: cast_nullable_to_non_nullable + as KeyPair, + )); + } +} + +// dart format on diff --git a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.g.dart b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.g.dart index 12b3a1e..c2c031f 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.g.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_record/dht_record_pool.g.dart @@ -6,9 +6,9 @@ part of 'dht_record_pool.dart'; // JsonSerializableGenerator // ************************************************************************** -_$DHTRecordPoolAllocationsImpl _$$DHTRecordPoolAllocationsImplFromJson( +_DHTRecordPoolAllocations _$DHTRecordPoolAllocationsFromJson( Map json) => - _$DHTRecordPoolAllocationsImpl( + _DHTRecordPoolAllocations( childrenByParent: json['children_by_parent'] == null ? const IMapConst>({}) : IMap>>.fromJson( @@ -34,8 +34,8 @@ _$DHTRecordPoolAllocationsImpl _$$DHTRecordPoolAllocationsImplFromJson( (value) => value as String), ); -Map _$$DHTRecordPoolAllocationsImplToJson( - _$DHTRecordPoolAllocationsImpl instance) => +Map _$DHTRecordPoolAllocationsToJson( + _DHTRecordPoolAllocations instance) => { 'children_by_parent': instance.childrenByParent.toJson( (value) => value, @@ -56,15 +56,15 @@ Map _$$DHTRecordPoolAllocationsImplToJson( ), }; -_$OwnedDHTRecordPointerImpl _$$OwnedDHTRecordPointerImplFromJson( +_OwnedDHTRecordPointer _$OwnedDHTRecordPointerFromJson( Map json) => - _$OwnedDHTRecordPointerImpl( + _OwnedDHTRecordPointer( recordKey: Typed.fromJson(json['record_key']), owner: KeyPair.fromJson(json['owner']), ); -Map _$$OwnedDHTRecordPointerImplToJson( - _$OwnedDHTRecordPointerImpl instance) => +Map _$OwnedDHTRecordPointerToJson( + _OwnedDHTRecordPointer instance) => { 'record_key': instance.recordKey.toJson(), 'owner': instance.owner.toJson(), diff --git a/packages/veilid_support/lib/dht_support/src/dht_record/extensions.dart b/packages/veilid_support/lib/dht_support/src/dht_record/extensions.dart new file mode 100644 index 0000000..e62403e --- /dev/null +++ b/packages/veilid_support/lib/dht_support/src/dht_record/extensions.dart @@ -0,0 +1,57 @@ +import 'package:veilid/veilid.dart'; +import 'dht_record_pool.dart'; + +class DHTSeqChange { + const DHTSeqChange(this.subkey, this.oldSeq, this.newSeq); + final int subkey; + final int oldSeq; + final int newSeq; +} + +extension DHTReportReportExt on DHTRecordReport { + List get newerSubkeys { + if (networkSeqs.isEmpty || localSeqs.isEmpty || subkeys.isEmpty) { + return []; + } + + final currentSubkeys = []; + + var i = 0; + for (final skr in subkeys) { + for (var sk = skr.low; sk <= skr.high; sk++) { + if (networkSeqs[i] > localSeqs[i] && + networkSeqs[i] != DHTRecord.emptySeq) { + if (currentSubkeys.isNotEmpty && + currentSubkeys.last.high == (sk - 1)) { + currentSubkeys.add(ValueSubkeyRange( + low: currentSubkeys.removeLast().low, high: sk)); + } else { + currentSubkeys.add(ValueSubkeyRange.single(sk)); + } + } + i++; + } + } + + return currentSubkeys; + } + + DHTSeqChange? get firstSeqChange { + if (networkSeqs.isEmpty || localSeqs.isEmpty || subkeys.isEmpty) { + return null; + } + + var i = 0; + for (final skr in subkeys) { + for (var sk = skr.low; sk <= skr.high; sk++) { + if (networkSeqs[i] > localSeqs[i] && + networkSeqs[i] != DHTRecord.emptySeq) { + return DHTSeqChange(sk, localSeqs[i], networkSeqs[i]); + } + i++; + } + } + + return null; + } +} diff --git a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_cubit.dart b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_cubit.dart index ab56c77..6ff6d95 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_cubit.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_cubit.dart @@ -3,27 +3,14 @@ import 'dart:async'; import 'package:async_tools/async_tools.dart'; import 'package:bloc/bloc.dart'; import 'package:bloc_advanced_tools/bloc_advanced_tools.dart'; -import 'package:equatable/equatable.dart'; import 'package:fast_immutable_collections/fast_immutable_collections.dart'; -import 'package:meta/meta.dart'; import '../../../veilid_support.dart'; -@immutable -class DHTShortArrayElementState extends Equatable { - const DHTShortArrayElementState( - {required this.value, required this.isOffline}); - final T value; - final bool isOffline; +typedef DHTShortArrayState = AsyncValue>>; +typedef DHTShortArrayCubitState = BlocBusyState>; - @override - List get props => [value, isOffline]; -} - -typedef DHTShortArrayState = AsyncValue>>; -typedef DHTShortArrayBusyState = BlocBusyState>; - -class DHTShortArrayCubit extends Cubit> +class DHTShortArrayCubit extends Cubit> with BlocBusyWrapper>, RefreshableCubit { DHTShortArrayCubit({ required Future Function() open, @@ -46,7 +33,7 @@ class DHTShortArrayCubit extends Cubit> } } on Exception catch (e, st) { addError(e, st); - emit(DHTShortArrayBusyState(AsyncValue.error(e, st))); + emit(DHTShortArrayCubitState(AsyncValue.error(e, st))); return; } @@ -83,7 +70,7 @@ class DHTShortArrayCubit extends Cubit> // Get the items final allItems = (await reader.getRange(0, forceRefresh: forceRefresh)) ?.indexed - .map((x) => DHTShortArrayElementState( + .map((x) => OnlineElementState( value: _decodeElement(x.$2), isOffline: offlinePositions?.contains(x.$1) ?? false)) .toIList(); diff --git a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_head.dart b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_head.dart index 0aaed19..49659cd 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_head.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_head.dart @@ -333,7 +333,7 @@ class _DHTShortArrayHead { } Future lookupIndex(int idx, bool allowCreate) async { - final seq = idx < _seqs.length ? _seqs[idx] : 0xFFFFFFFF; + final seq = idx < _seqs.length ? _seqs[idx] : DHTRecord.emptySeq; final recordNumber = idx ~/ _stride; final record = await _getOrCreateLinkedRecord(recordNumber, allowCreate); final recordSubkey = (idx % _stride) + ((recordNumber == 0) ? 1 : 0); @@ -427,14 +427,14 @@ class _DHTShortArrayHead { // If our local sequence number is unknown or hasnt been written yet // then a normal DHT operation is going to pull from the network anyway - if (_localSeqs.length < idx || _localSeqs[idx] == 0xFFFFFFFF) { + if (_localSeqs.length < idx || _localSeqs[idx] == DHTRecord.emptySeq) { return false; } // If the remote sequence number record is unknown or hasnt been written // at this index yet, then we also do not refresh at this time as it // is the first time the index is being written to - if (_seqs.length < idx || _seqs[idx] == 0xFFFFFFFF) { + if (_seqs.length < idx || _seqs[idx] == DHTRecord.emptySeq) { return false; } @@ -448,12 +448,12 @@ class _DHTShortArrayHead { final idx = _index[pos]; while (_localSeqs.length <= idx) { - _localSeqs.add(0xFFFFFFFF); + _localSeqs.add(DHTRecord.emptySeq); } _localSeqs[idx] = newSeq; if (write) { while (_seqs.length <= idx) { - _seqs.add(0xFFFFFFFF); + _seqs.add(DHTRecord.emptySeq); } _seqs[idx] = newSeq; } diff --git a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_write.dart b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_write.dart index f3e1ac3..51950f6 100644 --- a/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_write.dart +++ b/packages/veilid_support/lib/dht_support/src/dht_short_array/dht_short_array_write.dart @@ -122,7 +122,7 @@ class _DHTShortArrayWrite extends _DHTShortArrayRead final outSeqNum = Output(); - final result = lookup.seq == 0xFFFFFFFF + final result = lookup.seq == DHTRecord.emptySeq ? null : await lookup.record.get(subkey: lookup.recordSubkey); @@ -151,7 +151,7 @@ class _DHTShortArrayWrite extends _DHTShortArrayRead final lookup = await _head.lookupPosition(pos, true); final outSeqNumRead = Output(); - final oldValue = lookup.seq == 0xFFFFFFFF + final oldValue = lookup.seq == DHTRecord.emptySeq ? null : await lookup.record .get(subkey: lookup.recordSubkey, outSeqNum: outSeqNumRead); diff --git a/packages/veilid_support/lib/identity_support/account_record_info.dart b/packages/veilid_support/lib/identity_support/account_record_info.dart index 60accf9..c74baac 100644 --- a/packages/veilid_support/lib/identity_support/account_record_info.dart +++ b/packages/veilid_support/lib/identity_support/account_record_info.dart @@ -8,7 +8,7 @@ part 'account_record_info.g.dart'; /// AccountRecordInfo is the key and owner info for the account dht record that /// is stored in the identity instance record @freezed -class AccountRecordInfo with _$AccountRecordInfo { +sealed class AccountRecordInfo with _$AccountRecordInfo { const factory AccountRecordInfo({ // Top level account keys and secrets required OwnedDHTRecordPointer accountRecord, diff --git a/packages/veilid_support/lib/identity_support/account_record_info.freezed.dart b/packages/veilid_support/lib/identity_support/account_record_info.freezed.dart index a266230..b1796f6 100644 --- a/packages/veilid_support/lib/identity_support/account_record_info.freezed.dart +++ b/packages/veilid_support/lib/identity_support/account_record_info.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,137 +10,30 @@ part of 'account_record_info.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -AccountRecordInfo _$AccountRecordInfoFromJson(Map json) { - return _AccountRecordInfo.fromJson(json); -} - /// @nodoc mixin _$AccountRecordInfo { // Top level account keys and secrets - OwnedDHTRecordPointer get accountRecord => throw _privateConstructorUsedError; - - /// Serializes this AccountRecordInfo to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + OwnedDHTRecordPointer get accountRecord; /// Create a copy of AccountRecordInfo /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $AccountRecordInfoCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$AccountRecordInfoCopyWithImpl( + this as AccountRecordInfo, _$identity); -/// @nodoc -abstract class $AccountRecordInfoCopyWith<$Res> { - factory $AccountRecordInfoCopyWith( - AccountRecordInfo value, $Res Function(AccountRecordInfo) then) = - _$AccountRecordInfoCopyWithImpl<$Res, AccountRecordInfo>; - @useResult - $Res call({OwnedDHTRecordPointer accountRecord}); - - $OwnedDHTRecordPointerCopyWith<$Res> get accountRecord; -} - -/// @nodoc -class _$AccountRecordInfoCopyWithImpl<$Res, $Val extends AccountRecordInfo> - implements $AccountRecordInfoCopyWith<$Res> { - _$AccountRecordInfoCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of AccountRecordInfo - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? accountRecord = null, - }) { - return _then(_value.copyWith( - accountRecord: null == accountRecord - ? _value.accountRecord - : accountRecord // ignore: cast_nullable_to_non_nullable - as OwnedDHTRecordPointer, - ) as $Val); - } - - /// Create a copy of AccountRecordInfo - /// with the given fields replaced by the non-null parameter values. - @override - @pragma('vm:prefer-inline') - $OwnedDHTRecordPointerCopyWith<$Res> get accountRecord { - return $OwnedDHTRecordPointerCopyWith<$Res>(_value.accountRecord, (value) { - return _then(_value.copyWith(accountRecord: value) as $Val); - }); - } -} - -/// @nodoc -abstract class _$$AccountRecordInfoImplCopyWith<$Res> - implements $AccountRecordInfoCopyWith<$Res> { - factory _$$AccountRecordInfoImplCopyWith(_$AccountRecordInfoImpl value, - $Res Function(_$AccountRecordInfoImpl) then) = - __$$AccountRecordInfoImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({OwnedDHTRecordPointer accountRecord}); - - @override - $OwnedDHTRecordPointerCopyWith<$Res> get accountRecord; -} - -/// @nodoc -class __$$AccountRecordInfoImplCopyWithImpl<$Res> - extends _$AccountRecordInfoCopyWithImpl<$Res, _$AccountRecordInfoImpl> - implements _$$AccountRecordInfoImplCopyWith<$Res> { - __$$AccountRecordInfoImplCopyWithImpl(_$AccountRecordInfoImpl _value, - $Res Function(_$AccountRecordInfoImpl) _then) - : super(_value, _then); - - /// Create a copy of AccountRecordInfo - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? accountRecord = null, - }) { - return _then(_$AccountRecordInfoImpl( - accountRecord: null == accountRecord - ? _value.accountRecord - : accountRecord // ignore: cast_nullable_to_non_nullable - as OwnedDHTRecordPointer, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$AccountRecordInfoImpl implements _AccountRecordInfo { - const _$AccountRecordInfoImpl({required this.accountRecord}); - - factory _$AccountRecordInfoImpl.fromJson(Map json) => - _$$AccountRecordInfoImplFromJson(json); - -// Top level account keys and secrets - @override - final OwnedDHTRecordPointer accountRecord; - - @override - String toString() { - return 'AccountRecordInfo(accountRecord: $accountRecord)'; - } + /// Serializes this AccountRecordInfo to a JSON map. + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$AccountRecordInfoImpl && + other is AccountRecordInfo && (identical(other.accountRecord, accountRecord) || other.accountRecord == accountRecord)); } @@ -148,39 +42,148 @@ class _$AccountRecordInfoImpl implements _AccountRecordInfo { @override int get hashCode => Object.hash(runtimeType, accountRecord); - /// Create a copy of AccountRecordInfo - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$AccountRecordInfoImplCopyWith<_$AccountRecordInfoImpl> get copyWith => - __$$AccountRecordInfoImplCopyWithImpl<_$AccountRecordInfoImpl>( - this, _$identity); - - @override - Map toJson() { - return _$$AccountRecordInfoImplToJson( - this, - ); + String toString() { + return 'AccountRecordInfo(accountRecord: $accountRecord)'; } } -abstract class _AccountRecordInfo implements AccountRecordInfo { - const factory _AccountRecordInfo( - {required final OwnedDHTRecordPointer accountRecord}) = - _$AccountRecordInfoImpl; +/// @nodoc +abstract mixin class $AccountRecordInfoCopyWith<$Res> { + factory $AccountRecordInfoCopyWith( + AccountRecordInfo value, $Res Function(AccountRecordInfo) _then) = + _$AccountRecordInfoCopyWithImpl; + @useResult + $Res call({OwnedDHTRecordPointer accountRecord}); - factory _AccountRecordInfo.fromJson(Map json) = - _$AccountRecordInfoImpl.fromJson; + $OwnedDHTRecordPointerCopyWith<$Res> get accountRecord; +} + +/// @nodoc +class _$AccountRecordInfoCopyWithImpl<$Res> + implements $AccountRecordInfoCopyWith<$Res> { + _$AccountRecordInfoCopyWithImpl(this._self, this._then); + + final AccountRecordInfo _self; + final $Res Function(AccountRecordInfo) _then; + + /// Create a copy of AccountRecordInfo + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? accountRecord = null, + }) { + return _then(_self.copyWith( + accountRecord: null == accountRecord + ? _self.accountRecord + : accountRecord // ignore: cast_nullable_to_non_nullable + as OwnedDHTRecordPointer, + )); + } + + /// Create a copy of AccountRecordInfo + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $OwnedDHTRecordPointerCopyWith<$Res> get accountRecord { + return $OwnedDHTRecordPointerCopyWith<$Res>(_self.accountRecord, (value) { + return _then(_self.copyWith(accountRecord: value)); + }); + } +} + +/// @nodoc +@JsonSerializable() +class _AccountRecordInfo implements AccountRecordInfo { + const _AccountRecordInfo({required this.accountRecord}); + factory _AccountRecordInfo.fromJson(Map json) => + _$AccountRecordInfoFromJson(json); // Top level account keys and secrets @override - OwnedDHTRecordPointer get accountRecord; + final OwnedDHTRecordPointer accountRecord; /// Create a copy of AccountRecordInfo /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$AccountRecordInfoImplCopyWith<_$AccountRecordInfoImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$AccountRecordInfoCopyWith<_AccountRecordInfo> get copyWith => + __$AccountRecordInfoCopyWithImpl<_AccountRecordInfo>(this, _$identity); + + @override + Map toJson() { + return _$AccountRecordInfoToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _AccountRecordInfo && + (identical(other.accountRecord, accountRecord) || + other.accountRecord == accountRecord)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, accountRecord); + + @override + String toString() { + return 'AccountRecordInfo(accountRecord: $accountRecord)'; + } } + +/// @nodoc +abstract mixin class _$AccountRecordInfoCopyWith<$Res> + implements $AccountRecordInfoCopyWith<$Res> { + factory _$AccountRecordInfoCopyWith( + _AccountRecordInfo value, $Res Function(_AccountRecordInfo) _then) = + __$AccountRecordInfoCopyWithImpl; + @override + @useResult + $Res call({OwnedDHTRecordPointer accountRecord}); + + @override + $OwnedDHTRecordPointerCopyWith<$Res> get accountRecord; +} + +/// @nodoc +class __$AccountRecordInfoCopyWithImpl<$Res> + implements _$AccountRecordInfoCopyWith<$Res> { + __$AccountRecordInfoCopyWithImpl(this._self, this._then); + + final _AccountRecordInfo _self; + final $Res Function(_AccountRecordInfo) _then; + + /// Create a copy of AccountRecordInfo + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? accountRecord = null, + }) { + return _then(_AccountRecordInfo( + accountRecord: null == accountRecord + ? _self.accountRecord + : accountRecord // ignore: cast_nullable_to_non_nullable + as OwnedDHTRecordPointer, + )); + } + + /// Create a copy of AccountRecordInfo + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $OwnedDHTRecordPointerCopyWith<$Res> get accountRecord { + return $OwnedDHTRecordPointerCopyWith<$Res>(_self.accountRecord, (value) { + return _then(_self.copyWith(accountRecord: value)); + }); + } +} + +// dart format on diff --git a/packages/veilid_support/lib/identity_support/account_record_info.g.dart b/packages/veilid_support/lib/identity_support/account_record_info.g.dart index ad9318c..429f9d0 100644 --- a/packages/veilid_support/lib/identity_support/account_record_info.g.dart +++ b/packages/veilid_support/lib/identity_support/account_record_info.g.dart @@ -6,14 +6,12 @@ part of 'account_record_info.dart'; // JsonSerializableGenerator // ************************************************************************** -_$AccountRecordInfoImpl _$$AccountRecordInfoImplFromJson( - Map json) => - _$AccountRecordInfoImpl( +_AccountRecordInfo _$AccountRecordInfoFromJson(Map json) => + _AccountRecordInfo( accountRecord: OwnedDHTRecordPointer.fromJson(json['account_record']), ); -Map _$$AccountRecordInfoImplToJson( - _$AccountRecordInfoImpl instance) => +Map _$AccountRecordInfoToJson(_AccountRecordInfo instance) => { 'account_record': instance.accountRecord.toJson(), }; diff --git a/packages/veilid_support/lib/identity_support/identity.dart b/packages/veilid_support/lib/identity_support/identity.dart index ea9c38c..c1c7113 100644 --- a/packages/veilid_support/lib/identity_support/identity.dart +++ b/packages/veilid_support/lib/identity_support/identity.dart @@ -14,7 +14,7 @@ part 'identity.g.dart'; /// DHT Secret: IdentityInstance Secret Key (stored encrypted with unlock code /// in local table store) @freezed -class Identity with _$Identity { +sealed class Identity with _$Identity { const factory Identity({ // Top level account keys and secrets required IMap> accountRecords, diff --git a/packages/veilid_support/lib/identity_support/identity.freezed.dart b/packages/veilid_support/lib/identity_support/identity.freezed.dart index 3a276b0..d9f08f9 100644 --- a/packages/veilid_support/lib/identity_support/identity.freezed.dart +++ b/packages/veilid_support/lib/identity_support/identity.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,122 +10,29 @@ part of 'identity.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -Identity _$IdentityFromJson(Map json) { - return _Identity.fromJson(json); -} - /// @nodoc mixin _$Identity { // Top level account keys and secrets - IMap> get accountRecords => - throw _privateConstructorUsedError; - - /// Serializes this Identity to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + IMap> get accountRecords; /// Create a copy of Identity /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $IdentityCopyWith get copyWith => - throw _privateConstructorUsedError; -} + _$IdentityCopyWithImpl(this as Identity, _$identity); -/// @nodoc -abstract class $IdentityCopyWith<$Res> { - factory $IdentityCopyWith(Identity value, $Res Function(Identity) then) = - _$IdentityCopyWithImpl<$Res, Identity>; - @useResult - $Res call({IMap> accountRecords}); -} - -/// @nodoc -class _$IdentityCopyWithImpl<$Res, $Val extends Identity> - implements $IdentityCopyWith<$Res> { - _$IdentityCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of Identity - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? accountRecords = null, - }) { - return _then(_value.copyWith( - accountRecords: null == accountRecords - ? _value.accountRecords - : accountRecords // ignore: cast_nullable_to_non_nullable - as IMap>, - ) as $Val); - } -} - -/// @nodoc -abstract class _$$IdentityImplCopyWith<$Res> - implements $IdentityCopyWith<$Res> { - factory _$$IdentityImplCopyWith( - _$IdentityImpl value, $Res Function(_$IdentityImpl) then) = - __$$IdentityImplCopyWithImpl<$Res>; - @override - @useResult - $Res call({IMap> accountRecords}); -} - -/// @nodoc -class __$$IdentityImplCopyWithImpl<$Res> - extends _$IdentityCopyWithImpl<$Res, _$IdentityImpl> - implements _$$IdentityImplCopyWith<$Res> { - __$$IdentityImplCopyWithImpl( - _$IdentityImpl _value, $Res Function(_$IdentityImpl) _then) - : super(_value, _then); - - /// Create a copy of Identity - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? accountRecords = null, - }) { - return _then(_$IdentityImpl( - accountRecords: null == accountRecords - ? _value.accountRecords - : accountRecords // ignore: cast_nullable_to_non_nullable - as IMap>, - )); - } -} - -/// @nodoc -@JsonSerializable() -class _$IdentityImpl implements _Identity { - const _$IdentityImpl({required this.accountRecords}); - - factory _$IdentityImpl.fromJson(Map json) => - _$$IdentityImplFromJson(json); - -// Top level account keys and secrets - @override - final IMap> accountRecords; - - @override - String toString() { - return 'Identity(accountRecords: $accountRecords)'; - } + /// Serializes this Identity to a JSON map. + Map toJson(); @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$IdentityImpl && + other is Identity && (identical(other.accountRecords, accountRecords) || other.accountRecords == accountRecords)); } @@ -133,38 +41,119 @@ class _$IdentityImpl implements _Identity { @override int get hashCode => Object.hash(runtimeType, accountRecords); - /// Create a copy of Identity - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$IdentityImplCopyWith<_$IdentityImpl> get copyWith => - __$$IdentityImplCopyWithImpl<_$IdentityImpl>(this, _$identity); - - @override - Map toJson() { - return _$$IdentityImplToJson( - this, - ); + String toString() { + return 'Identity(accountRecords: $accountRecords)'; } } -abstract class _Identity implements Identity { - const factory _Identity( - {required final IMap> - accountRecords}) = _$IdentityImpl; +/// @nodoc +abstract mixin class $IdentityCopyWith<$Res> { + factory $IdentityCopyWith(Identity value, $Res Function(Identity) _then) = + _$IdentityCopyWithImpl; + @useResult + $Res call({IMap> accountRecords}); +} - factory _Identity.fromJson(Map json) = - _$IdentityImpl.fromJson; +/// @nodoc +class _$IdentityCopyWithImpl<$Res> implements $IdentityCopyWith<$Res> { + _$IdentityCopyWithImpl(this._self, this._then); + + final Identity _self; + final $Res Function(Identity) _then; + + /// Create a copy of Identity + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? accountRecords = null, + }) { + return _then(_self.copyWith( + accountRecords: null == accountRecords + ? _self.accountRecords + : accountRecords // ignore: cast_nullable_to_non_nullable + as IMap>, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _Identity implements Identity { + const _Identity({required this.accountRecords}); + factory _Identity.fromJson(Map json) => + _$IdentityFromJson(json); // Top level account keys and secrets @override - IMap> get accountRecords; + final IMap> accountRecords; /// Create a copy of Identity /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) - _$$IdentityImplCopyWith<_$IdentityImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + _$IdentityCopyWith<_Identity> get copyWith => + __$IdentityCopyWithImpl<_Identity>(this, _$identity); + + @override + Map toJson() { + return _$IdentityToJson( + this, + ); + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _Identity && + (identical(other.accountRecords, accountRecords) || + other.accountRecords == accountRecords)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash(runtimeType, accountRecords); + + @override + String toString() { + return 'Identity(accountRecords: $accountRecords)'; + } } + +/// @nodoc +abstract mixin class _$IdentityCopyWith<$Res> + implements $IdentityCopyWith<$Res> { + factory _$IdentityCopyWith(_Identity value, $Res Function(_Identity) _then) = + __$IdentityCopyWithImpl; + @override + @useResult + $Res call({IMap> accountRecords}); +} + +/// @nodoc +class __$IdentityCopyWithImpl<$Res> implements _$IdentityCopyWith<$Res> { + __$IdentityCopyWithImpl(this._self, this._then); + + final _Identity _self; + final $Res Function(_Identity) _then; + + /// Create a copy of Identity + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $Res call({ + Object? accountRecords = null, + }) { + return _then(_Identity( + accountRecords: null == accountRecords + ? _self.accountRecords + : accountRecords // ignore: cast_nullable_to_non_nullable + as IMap>, + )); + } +} + +// dart format on diff --git a/packages/veilid_support/lib/identity_support/identity.g.dart b/packages/veilid_support/lib/identity_support/identity.g.dart index afc9088..1ee10b8 100644 --- a/packages/veilid_support/lib/identity_support/identity.g.dart +++ b/packages/veilid_support/lib/identity_support/identity.g.dart @@ -6,8 +6,7 @@ part of 'identity.dart'; // JsonSerializableGenerator // ************************************************************************** -_$IdentityImpl _$$IdentityImplFromJson(Map json) => - _$IdentityImpl( +_Identity _$IdentityFromJson(Map json) => _Identity( accountRecords: IMap>.fromJson( json['account_records'] as Map, (value) => value as String, @@ -15,8 +14,7 @@ _$IdentityImpl _$$IdentityImplFromJson(Map json) => value, (value) => AccountRecordInfo.fromJson(value))), ); -Map _$$IdentityImplToJson(_$IdentityImpl instance) => - { +Map _$IdentityToJson(_Identity instance) => { 'account_records': instance.accountRecords.toJson( (value) => value, (value) => value.toJson( diff --git a/packages/veilid_support/lib/identity_support/identity_instance.dart b/packages/veilid_support/lib/identity_support/identity_instance.dart index 1b6bf1f..d2bc323 100644 --- a/packages/veilid_support/lib/identity_support/identity_instance.dart +++ b/packages/veilid_support/lib/identity_support/identity_instance.dart @@ -10,7 +10,7 @@ part 'identity_instance.freezed.dart'; part 'identity_instance.g.dart'; @freezed -class IdentityInstance with _$IdentityInstance { +sealed class IdentityInstance with _$IdentityInstance { const factory IdentityInstance({ // Private DHT record storing identity account mapping required TypedKey recordKey, diff --git a/packages/veilid_support/lib/identity_support/identity_instance.freezed.dart b/packages/veilid_support/lib/identity_support/identity_instance.freezed.dart index 28bbad4..42522d4 100644 --- a/packages/veilid_support/lib/identity_support/identity_instance.freezed.dart +++ b/packages/veilid_support/lib/identity_support/identity_instance.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,112 +10,76 @@ part of 'identity_instance.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -IdentityInstance _$IdentityInstanceFromJson(Map json) { - return _IdentityInstance.fromJson(json); -} - /// @nodoc mixin _$IdentityInstance { // Private DHT record storing identity account mapping - Typed get recordKey => - throw _privateConstructorUsedError; // Public key of identity instance - FixedEncodedString43 get publicKey => - throw _privateConstructorUsedError; // Secret key of identity instance + TypedKey get recordKey; // Public key of identity instance + PublicKey get publicKey; // Secret key of identity instance // Encrypted with appended salt, key is DeriveSharedSecret( // password = SuperIdentity.secret, // salt = publicKey) // Used to recover accounts without generating a new instance @Uint8ListJsonConverter() - Uint8List get encryptedSecretKey => - throw _privateConstructorUsedError; // Signature of SuperInstance recordKey and SuperInstance publicKey + Uint8List + get encryptedSecretKey; // Signature of SuperInstance recordKey and SuperInstance publicKey // by publicKey - FixedEncodedString86 get superSignature => - throw _privateConstructorUsedError; // Signature of recordKey, publicKey, encryptedSecretKey, and superSignature + Signature + get superSignature; // Signature of recordKey, publicKey, encryptedSecretKey, and superSignature // by SuperIdentity publicKey - FixedEncodedString86 get signature => throw _privateConstructorUsedError; - - /// Serializes this IdentityInstance to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + Signature get signature; /// Create a copy of IdentityInstance /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) - $IdentityInstanceCopyWith get copyWith => - throw _privateConstructorUsedError; -} - -/// @nodoc -abstract class $IdentityInstanceCopyWith<$Res> { - factory $IdentityInstanceCopyWith( - IdentityInstance value, $Res Function(IdentityInstance) then) = - _$IdentityInstanceCopyWithImpl<$Res, IdentityInstance>; - @useResult - $Res call( - {Typed recordKey, - FixedEncodedString43 publicKey, - @Uint8ListJsonConverter() Uint8List encryptedSecretKey, - FixedEncodedString86 superSignature, - FixedEncodedString86 signature}); -} - -/// @nodoc -class _$IdentityInstanceCopyWithImpl<$Res, $Val extends IdentityInstance> - implements $IdentityInstanceCopyWith<$Res> { - _$IdentityInstanceCopyWithImpl(this._value, this._then); - - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; - - /// Create a copy of IdentityInstance - /// with the given fields replaced by the non-null parameter values. @pragma('vm:prefer-inline') + $IdentityInstanceCopyWith get copyWith => + _$IdentityInstanceCopyWithImpl( + this as IdentityInstance, _$identity); + + /// Serializes this IdentityInstance to a JSON map. + Map toJson(); + @override - $Res call({ - Object? recordKey = null, - Object? publicKey = null, - Object? encryptedSecretKey = null, - Object? superSignature = null, - Object? signature = null, - }) { - return _then(_value.copyWith( - recordKey: null == recordKey - ? _value.recordKey - : recordKey // ignore: cast_nullable_to_non_nullable - as Typed, - publicKey: null == publicKey - ? _value.publicKey - : publicKey // ignore: cast_nullable_to_non_nullable - as FixedEncodedString43, - encryptedSecretKey: null == encryptedSecretKey - ? _value.encryptedSecretKey - : encryptedSecretKey // ignore: cast_nullable_to_non_nullable - as Uint8List, - superSignature: null == superSignature - ? _value.superSignature - : superSignature // ignore: cast_nullable_to_non_nullable - as FixedEncodedString86, - signature: null == signature - ? _value.signature - : signature // ignore: cast_nullable_to_non_nullable - as FixedEncodedString86, - ) as $Val); + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is IdentityInstance && + (identical(other.recordKey, recordKey) || + other.recordKey == recordKey) && + (identical(other.publicKey, publicKey) || + other.publicKey == publicKey) && + const DeepCollectionEquality() + .equals(other.encryptedSecretKey, encryptedSecretKey) && + (identical(other.superSignature, superSignature) || + other.superSignature == superSignature) && + (identical(other.signature, signature) || + other.signature == signature)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + recordKey, + publicKey, + const DeepCollectionEquality().hash(encryptedSecretKey), + superSignature, + signature); + + @override + String toString() { + return 'IdentityInstance(recordKey: $recordKey, publicKey: $publicKey, encryptedSecretKey: $encryptedSecretKey, superSignature: $superSignature, signature: $signature)'; } } /// @nodoc -abstract class _$$IdentityInstanceImplCopyWith<$Res> - implements $IdentityInstanceCopyWith<$Res> { - factory _$$IdentityInstanceImplCopyWith(_$IdentityInstanceImpl value, - $Res Function(_$IdentityInstanceImpl) then) = - __$$IdentityInstanceImplCopyWithImpl<$Res>; - @override +abstract mixin class $IdentityInstanceCopyWith<$Res> { + factory $IdentityInstanceCopyWith( + IdentityInstance value, $Res Function(IdentityInstance) _then) = + _$IdentityInstanceCopyWithImpl; @useResult $Res call( {Typed recordKey, @@ -125,12 +90,12 @@ abstract class _$$IdentityInstanceImplCopyWith<$Res> } /// @nodoc -class __$$IdentityInstanceImplCopyWithImpl<$Res> - extends _$IdentityInstanceCopyWithImpl<$Res, _$IdentityInstanceImpl> - implements _$$IdentityInstanceImplCopyWith<$Res> { - __$$IdentityInstanceImplCopyWithImpl(_$IdentityInstanceImpl _value, - $Res Function(_$IdentityInstanceImpl) _then) - : super(_value, _then); +class _$IdentityInstanceCopyWithImpl<$Res> + implements $IdentityInstanceCopyWith<$Res> { + _$IdentityInstanceCopyWithImpl(this._self, this._then); + + final IdentityInstance _self; + final $Res Function(IdentityInstance) _then; /// Create a copy of IdentityInstance /// with the given fields replaced by the non-null parameter values. @@ -143,25 +108,25 @@ class __$$IdentityInstanceImplCopyWithImpl<$Res> Object? superSignature = null, Object? signature = null, }) { - return _then(_$IdentityInstanceImpl( + return _then(_self.copyWith( recordKey: null == recordKey - ? _value.recordKey + ? _self.recordKey! : recordKey // ignore: cast_nullable_to_non_nullable as Typed, publicKey: null == publicKey - ? _value.publicKey + ? _self.publicKey! : publicKey // ignore: cast_nullable_to_non_nullable as FixedEncodedString43, encryptedSecretKey: null == encryptedSecretKey - ? _value.encryptedSecretKey + ? _self.encryptedSecretKey : encryptedSecretKey // ignore: cast_nullable_to_non_nullable as Uint8List, superSignature: null == superSignature - ? _value.superSignature + ? _self.superSignature! : superSignature // ignore: cast_nullable_to_non_nullable as FixedEncodedString86, signature: null == signature - ? _value.signature + ? _self.signature! : signature // ignore: cast_nullable_to_non_nullable as FixedEncodedString86, )); @@ -170,17 +135,16 @@ class __$$IdentityInstanceImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$IdentityInstanceImpl extends _IdentityInstance { - const _$IdentityInstanceImpl( +class _IdentityInstance extends IdentityInstance { + const _IdentityInstance( {required this.recordKey, required this.publicKey, @Uint8ListJsonConverter() required this.encryptedSecretKey, required this.superSignature, required this.signature}) : super._(); - - factory _$IdentityInstanceImpl.fromJson(Map json) => - _$$IdentityInstanceImplFromJson(json); + factory _IdentityInstance.fromJson(Map json) => + _$IdentityInstanceFromJson(json); // Private DHT record storing identity account mapping @override @@ -205,16 +169,26 @@ class _$IdentityInstanceImpl extends _IdentityInstance { @override final FixedEncodedString86 signature; + /// Create a copy of IdentityInstance + /// with the given fields replaced by the non-null parameter values. @override - String toString() { - return 'IdentityInstance(recordKey: $recordKey, publicKey: $publicKey, encryptedSecretKey: $encryptedSecretKey, superSignature: $superSignature, signature: $signature)'; + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$IdentityInstanceCopyWith<_IdentityInstance> get copyWith => + __$IdentityInstanceCopyWithImpl<_IdentityInstance>(this, _$identity); + + @override + Map toJson() { + return _$IdentityInstanceToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$IdentityInstanceImpl && + other is _IdentityInstance && (identical(other.recordKey, recordKey) || other.recordKey == recordKey) && (identical(other.publicKey, publicKey) || @@ -237,60 +211,70 @@ class _$IdentityInstanceImpl extends _IdentityInstance { superSignature, signature); - /// Create a copy of IdentityInstance - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$IdentityInstanceImplCopyWith<_$IdentityInstanceImpl> get copyWith => - __$$IdentityInstanceImplCopyWithImpl<_$IdentityInstanceImpl>( - this, _$identity); - - @override - Map toJson() { - return _$$IdentityInstanceImplToJson( - this, - ); + String toString() { + return 'IdentityInstance(recordKey: $recordKey, publicKey: $publicKey, encryptedSecretKey: $encryptedSecretKey, superSignature: $superSignature, signature: $signature)'; } } -abstract class _IdentityInstance extends IdentityInstance { - const factory _IdentityInstance( - {required final Typed recordKey, - required final FixedEncodedString43 publicKey, - @Uint8ListJsonConverter() required final Uint8List encryptedSecretKey, - required final FixedEncodedString86 superSignature, - required final FixedEncodedString86 signature}) = _$IdentityInstanceImpl; - const _IdentityInstance._() : super._(); +/// @nodoc +abstract mixin class _$IdentityInstanceCopyWith<$Res> + implements $IdentityInstanceCopyWith<$Res> { + factory _$IdentityInstanceCopyWith( + _IdentityInstance value, $Res Function(_IdentityInstance) _then) = + __$IdentityInstanceCopyWithImpl; + @override + @useResult + $Res call( + {Typed recordKey, + FixedEncodedString43 publicKey, + @Uint8ListJsonConverter() Uint8List encryptedSecretKey, + FixedEncodedString86 superSignature, + FixedEncodedString86 signature}); +} - factory _IdentityInstance.fromJson(Map json) = - _$IdentityInstanceImpl.fromJson; +/// @nodoc +class __$IdentityInstanceCopyWithImpl<$Res> + implements _$IdentityInstanceCopyWith<$Res> { + __$IdentityInstanceCopyWithImpl(this._self, this._then); -// Private DHT record storing identity account mapping - @override - Typed get recordKey; // Public key of identity instance - @override - FixedEncodedString43 get publicKey; // Secret key of identity instance -// Encrypted with appended salt, key is DeriveSharedSecret( -// password = SuperIdentity.secret, -// salt = publicKey) -// Used to recover accounts without generating a new instance - @override - @Uint8ListJsonConverter() - Uint8List - get encryptedSecretKey; // Signature of SuperInstance recordKey and SuperInstance publicKey -// by publicKey - @override - FixedEncodedString86 - get superSignature; // Signature of recordKey, publicKey, encryptedSecretKey, and superSignature -// by SuperIdentity publicKey - @override - FixedEncodedString86 get signature; + final _IdentityInstance _self; + final $Res Function(_IdentityInstance) _then; /// Create a copy of IdentityInstance /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$IdentityInstanceImplCopyWith<_$IdentityInstanceImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + $Res call({ + Object? recordKey = null, + Object? publicKey = null, + Object? encryptedSecretKey = null, + Object? superSignature = null, + Object? signature = null, + }) { + return _then(_IdentityInstance( + recordKey: null == recordKey + ? _self.recordKey + : recordKey // ignore: cast_nullable_to_non_nullable + as Typed, + publicKey: null == publicKey + ? _self.publicKey + : publicKey // ignore: cast_nullable_to_non_nullable + as FixedEncodedString43, + encryptedSecretKey: null == encryptedSecretKey + ? _self.encryptedSecretKey + : encryptedSecretKey // ignore: cast_nullable_to_non_nullable + as Uint8List, + superSignature: null == superSignature + ? _self.superSignature + : superSignature // ignore: cast_nullable_to_non_nullable + as FixedEncodedString86, + signature: null == signature + ? _self.signature + : signature // ignore: cast_nullable_to_non_nullable + as FixedEncodedString86, + )); + } } + +// dart format on diff --git a/packages/veilid_support/lib/identity_support/identity_instance.g.dart b/packages/veilid_support/lib/identity_support/identity_instance.g.dart index cb228e6..eddbcf6 100644 --- a/packages/veilid_support/lib/identity_support/identity_instance.g.dart +++ b/packages/veilid_support/lib/identity_support/identity_instance.g.dart @@ -6,9 +6,8 @@ part of 'identity_instance.dart'; // JsonSerializableGenerator // ************************************************************************** -_$IdentityInstanceImpl _$$IdentityInstanceImplFromJson( - Map json) => - _$IdentityInstanceImpl( +_IdentityInstance _$IdentityInstanceFromJson(Map json) => + _IdentityInstance( recordKey: Typed.fromJson(json['record_key']), publicKey: FixedEncodedString43.fromJson(json['public_key']), encryptedSecretKey: @@ -17,8 +16,7 @@ _$IdentityInstanceImpl _$$IdentityInstanceImplFromJson( signature: FixedEncodedString86.fromJson(json['signature']), ); -Map _$$IdentityInstanceImplToJson( - _$IdentityInstanceImpl instance) => +Map _$IdentityInstanceToJson(_IdentityInstance instance) => { 'record_key': instance.recordKey.toJson(), 'public_key': instance.publicKey.toJson(), diff --git a/packages/veilid_support/lib/identity_support/super_identity.dart b/packages/veilid_support/lib/identity_support/super_identity.dart index e4ec8fc..5ee8c43 100644 --- a/packages/veilid_support/lib/identity_support/super_identity.dart +++ b/packages/veilid_support/lib/identity_support/super_identity.dart @@ -22,7 +22,7 @@ part 'super_identity.g.dart'; /// DHT Owner Secret: SuperIdentity Secret Key (kept offline) /// Encryption: None @freezed -class SuperIdentity with _$SuperIdentity { +sealed class SuperIdentity with _$SuperIdentity { const factory SuperIdentity({ /// Public DHT record storing this structure for account recovery /// changing this can migrate/forward the SuperIdentity to a new DHT record diff --git a/packages/veilid_support/lib/identity_support/super_identity.freezed.dart b/packages/veilid_support/lib/identity_support/super_identity.freezed.dart index 9c5c6a7..b142373 100644 --- a/packages/veilid_support/lib/identity_support/super_identity.freezed.dart +++ b/packages/veilid_support/lib/identity_support/super_identity.freezed.dart @@ -1,3 +1,4 @@ +// dart format width=80 // coverage:ignore-file // GENERATED CODE - DO NOT MODIFY BY HAND // ignore_for_file: type=lint @@ -9,65 +10,93 @@ part of 'super_identity.dart'; // FreezedGenerator // ************************************************************************** +// dart format off T _$identity(T value) => value; -final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); - -SuperIdentity _$SuperIdentityFromJson(Map json) { - return _SuperIdentity.fromJson(json); -} - /// @nodoc mixin _$SuperIdentity { /// Public DHT record storing this structure for account recovery /// changing this can migrate/forward the SuperIdentity to a new DHT record /// Instances should not hash this recordKey, rather the actual record /// key used to store the superIdentity, as this may change. - Typed get recordKey => - throw _privateConstructorUsedError; + TypedKey get recordKey; /// Public key of the SuperIdentity used to sign identity keys for recovery /// This must match the owner of the superRecord DHT record and can not be /// changed without changing the record - FixedEncodedString43 get publicKey => throw _privateConstructorUsedError; + PublicKey get publicKey; /// Current identity instance /// The most recently generated identity instance for this SuperIdentity - IdentityInstance get currentInstance => throw _privateConstructorUsedError; + IdentityInstance get currentInstance; /// Deprecated identity instances /// These may be compromised and should not be considered valid for /// new signatures, but may be used to validate old signatures - List get deprecatedInstances => - throw _privateConstructorUsedError; + List get deprecatedInstances; /// Deprecated superRecords /// These may be compromised and should not be considered valid for /// new signatures, but may be used to validate old signatures - List> get deprecatedSuperRecordKeys => - throw _privateConstructorUsedError; + List get deprecatedSuperRecordKeys; /// Signature of recordKey, currentInstance signature, /// signatures of deprecatedInstances, and deprecatedSuperRecordKeys /// by publicKey - FixedEncodedString86 get signature => throw _privateConstructorUsedError; - - /// Serializes this SuperIdentity to a JSON map. - Map toJson() => throw _privateConstructorUsedError; + Signature get signature; /// Create a copy of SuperIdentity /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') $SuperIdentityCopyWith get copyWith => - throw _privateConstructorUsedError; + _$SuperIdentityCopyWithImpl( + this as SuperIdentity, _$identity); + + /// Serializes this SuperIdentity to a JSON map. + Map toJson(); + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is SuperIdentity && + (identical(other.recordKey, recordKey) || + other.recordKey == recordKey) && + (identical(other.publicKey, publicKey) || + other.publicKey == publicKey) && + (identical(other.currentInstance, currentInstance) || + other.currentInstance == currentInstance) && + const DeepCollectionEquality() + .equals(other.deprecatedInstances, deprecatedInstances) && + const DeepCollectionEquality().equals( + other.deprecatedSuperRecordKeys, deprecatedSuperRecordKeys) && + (identical(other.signature, signature) || + other.signature == signature)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + recordKey, + publicKey, + currentInstance, + const DeepCollectionEquality().hash(deprecatedInstances), + const DeepCollectionEquality().hash(deprecatedSuperRecordKeys), + signature); + + @override + String toString() { + return 'SuperIdentity(recordKey: $recordKey, publicKey: $publicKey, currentInstance: $currentInstance, deprecatedInstances: $deprecatedInstances, deprecatedSuperRecordKeys: $deprecatedSuperRecordKeys, signature: $signature)'; + } } /// @nodoc -abstract class $SuperIdentityCopyWith<$Res> { +abstract mixin class $SuperIdentityCopyWith<$Res> { factory $SuperIdentityCopyWith( - SuperIdentity value, $Res Function(SuperIdentity) then) = - _$SuperIdentityCopyWithImpl<$Res, SuperIdentity>; + SuperIdentity value, $Res Function(SuperIdentity) _then) = + _$SuperIdentityCopyWithImpl; @useResult $Res call( {Typed recordKey, @@ -81,14 +110,12 @@ abstract class $SuperIdentityCopyWith<$Res> { } /// @nodoc -class _$SuperIdentityCopyWithImpl<$Res, $Val extends SuperIdentity> +class _$SuperIdentityCopyWithImpl<$Res> implements $SuperIdentityCopyWith<$Res> { - _$SuperIdentityCopyWithImpl(this._value, this._then); + _$SuperIdentityCopyWithImpl(this._self, this._then); - // ignore: unused_field - final $Val _value; - // ignore: unused_field - final $Res Function($Val) _then; + final SuperIdentity _self; + final $Res Function(SuperIdentity) _then; /// Create a copy of SuperIdentity /// with the given fields replaced by the non-null parameter values. @@ -102,32 +129,32 @@ class _$SuperIdentityCopyWithImpl<$Res, $Val extends SuperIdentity> Object? deprecatedSuperRecordKeys = null, Object? signature = null, }) { - return _then(_value.copyWith( + return _then(_self.copyWith( recordKey: null == recordKey - ? _value.recordKey + ? _self.recordKey! : recordKey // ignore: cast_nullable_to_non_nullable as Typed, publicKey: null == publicKey - ? _value.publicKey + ? _self.publicKey! : publicKey // ignore: cast_nullable_to_non_nullable as FixedEncodedString43, currentInstance: null == currentInstance - ? _value.currentInstance + ? _self.currentInstance : currentInstance // ignore: cast_nullable_to_non_nullable as IdentityInstance, deprecatedInstances: null == deprecatedInstances - ? _value.deprecatedInstances + ? _self.deprecatedInstances : deprecatedInstances // ignore: cast_nullable_to_non_nullable as List, deprecatedSuperRecordKeys: null == deprecatedSuperRecordKeys - ? _value.deprecatedSuperRecordKeys + ? _self.deprecatedSuperRecordKeys! : deprecatedSuperRecordKeys // ignore: cast_nullable_to_non_nullable as List>, signature: null == signature - ? _value.signature + ? _self.signature! : signature // ignore: cast_nullable_to_non_nullable as FixedEncodedString86, - ) as $Val); + )); } /// Create a copy of SuperIdentity @@ -135,85 +162,16 @@ class _$SuperIdentityCopyWithImpl<$Res, $Val extends SuperIdentity> @override @pragma('vm:prefer-inline') $IdentityInstanceCopyWith<$Res> get currentInstance { - return $IdentityInstanceCopyWith<$Res>(_value.currentInstance, (value) { - return _then(_value.copyWith(currentInstance: value) as $Val); + return $IdentityInstanceCopyWith<$Res>(_self.currentInstance, (value) { + return _then(_self.copyWith(currentInstance: value)); }); } } -/// @nodoc -abstract class _$$SuperIdentityImplCopyWith<$Res> - implements $SuperIdentityCopyWith<$Res> { - factory _$$SuperIdentityImplCopyWith( - _$SuperIdentityImpl value, $Res Function(_$SuperIdentityImpl) then) = - __$$SuperIdentityImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {Typed recordKey, - FixedEncodedString43 publicKey, - IdentityInstance currentInstance, - List deprecatedInstances, - List> deprecatedSuperRecordKeys, - FixedEncodedString86 signature}); - - @override - $IdentityInstanceCopyWith<$Res> get currentInstance; -} - -/// @nodoc -class __$$SuperIdentityImplCopyWithImpl<$Res> - extends _$SuperIdentityCopyWithImpl<$Res, _$SuperIdentityImpl> - implements _$$SuperIdentityImplCopyWith<$Res> { - __$$SuperIdentityImplCopyWithImpl( - _$SuperIdentityImpl _value, $Res Function(_$SuperIdentityImpl) _then) - : super(_value, _then); - - /// Create a copy of SuperIdentity - /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? recordKey = null, - Object? publicKey = null, - Object? currentInstance = null, - Object? deprecatedInstances = null, - Object? deprecatedSuperRecordKeys = null, - Object? signature = null, - }) { - return _then(_$SuperIdentityImpl( - recordKey: null == recordKey - ? _value.recordKey - : recordKey // ignore: cast_nullable_to_non_nullable - as Typed, - publicKey: null == publicKey - ? _value.publicKey - : publicKey // ignore: cast_nullable_to_non_nullable - as FixedEncodedString43, - currentInstance: null == currentInstance - ? _value.currentInstance - : currentInstance // ignore: cast_nullable_to_non_nullable - as IdentityInstance, - deprecatedInstances: null == deprecatedInstances - ? _value._deprecatedInstances - : deprecatedInstances // ignore: cast_nullable_to_non_nullable - as List, - deprecatedSuperRecordKeys: null == deprecatedSuperRecordKeys - ? _value._deprecatedSuperRecordKeys - : deprecatedSuperRecordKeys // ignore: cast_nullable_to_non_nullable - as List>, - signature: null == signature - ? _value.signature - : signature // ignore: cast_nullable_to_non_nullable - as FixedEncodedString86, - )); - } -} - /// @nodoc @JsonSerializable() -class _$SuperIdentityImpl extends _SuperIdentity { - const _$SuperIdentityImpl( +class _SuperIdentity extends SuperIdentity { + const _SuperIdentity( {required this.recordKey, required this.publicKey, required this.currentInstance, @@ -224,9 +182,8 @@ class _$SuperIdentityImpl extends _SuperIdentity { : _deprecatedInstances = deprecatedInstances, _deprecatedSuperRecordKeys = deprecatedSuperRecordKeys, super._(); - - factory _$SuperIdentityImpl.fromJson(Map json) => - _$$SuperIdentityImplFromJson(json); + factory _SuperIdentity.fromJson(Map json) => + _$SuperIdentityFromJson(json); /// Public DHT record storing this structure for account recovery /// changing this can migrate/forward the SuperIdentity to a new DHT record @@ -284,16 +241,26 @@ class _$SuperIdentityImpl extends _SuperIdentity { @override final FixedEncodedString86 signature; + /// Create a copy of SuperIdentity + /// with the given fields replaced by the non-null parameter values. @override - String toString() { - return 'SuperIdentity(recordKey: $recordKey, publicKey: $publicKey, currentInstance: $currentInstance, deprecatedInstances: $deprecatedInstances, deprecatedSuperRecordKeys: $deprecatedSuperRecordKeys, signature: $signature)'; + @JsonKey(includeFromJson: false, includeToJson: false) + @pragma('vm:prefer-inline') + _$SuperIdentityCopyWith<_SuperIdentity> get copyWith => + __$SuperIdentityCopyWithImpl<_SuperIdentity>(this, _$identity); + + @override + Map toJson() { + return _$SuperIdentityToJson( + this, + ); } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$SuperIdentityImpl && + other is _SuperIdentity && (identical(other.recordKey, recordKey) || other.recordKey == recordKey) && (identical(other.publicKey, publicKey) || @@ -319,76 +286,89 @@ class _$SuperIdentityImpl extends _SuperIdentity { const DeepCollectionEquality().hash(_deprecatedSuperRecordKeys), signature); - /// Create a copy of SuperIdentity - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) @override - @pragma('vm:prefer-inline') - _$$SuperIdentityImplCopyWith<_$SuperIdentityImpl> get copyWith => - __$$SuperIdentityImplCopyWithImpl<_$SuperIdentityImpl>(this, _$identity); - - @override - Map toJson() { - return _$$SuperIdentityImplToJson( - this, - ); + String toString() { + return 'SuperIdentity(recordKey: $recordKey, publicKey: $publicKey, currentInstance: $currentInstance, deprecatedInstances: $deprecatedInstances, deprecatedSuperRecordKeys: $deprecatedSuperRecordKeys, signature: $signature)'; } } -abstract class _SuperIdentity extends SuperIdentity { - const factory _SuperIdentity( - {required final Typed recordKey, - required final FixedEncodedString43 publicKey, - required final IdentityInstance currentInstance, - required final List deprecatedInstances, - required final List> - deprecatedSuperRecordKeys, - required final FixedEncodedString86 signature}) = _$SuperIdentityImpl; - const _SuperIdentity._() : super._(); - - factory _SuperIdentity.fromJson(Map json) = - _$SuperIdentityImpl.fromJson; - - /// Public DHT record storing this structure for account recovery - /// changing this can migrate/forward the SuperIdentity to a new DHT record - /// Instances should not hash this recordKey, rather the actual record - /// key used to store the superIdentity, as this may change. +/// @nodoc +abstract mixin class _$SuperIdentityCopyWith<$Res> + implements $SuperIdentityCopyWith<$Res> { + factory _$SuperIdentityCopyWith( + _SuperIdentity value, $Res Function(_SuperIdentity) _then) = + __$SuperIdentityCopyWithImpl; @override - Typed get recordKey; + @useResult + $Res call( + {Typed recordKey, + FixedEncodedString43 publicKey, + IdentityInstance currentInstance, + List deprecatedInstances, + List> deprecatedSuperRecordKeys, + FixedEncodedString86 signature}); - /// Public key of the SuperIdentity used to sign identity keys for recovery - /// This must match the owner of the superRecord DHT record and can not be - /// changed without changing the record @override - FixedEncodedString43 get publicKey; + $IdentityInstanceCopyWith<$Res> get currentInstance; +} - /// Current identity instance - /// The most recently generated identity instance for this SuperIdentity - @override - IdentityInstance get currentInstance; +/// @nodoc +class __$SuperIdentityCopyWithImpl<$Res> + implements _$SuperIdentityCopyWith<$Res> { + __$SuperIdentityCopyWithImpl(this._self, this._then); - /// Deprecated identity instances - /// These may be compromised and should not be considered valid for - /// new signatures, but may be used to validate old signatures - @override - List get deprecatedInstances; - - /// Deprecated superRecords - /// These may be compromised and should not be considered valid for - /// new signatures, but may be used to validate old signatures - @override - List> get deprecatedSuperRecordKeys; - - /// Signature of recordKey, currentInstance signature, - /// signatures of deprecatedInstances, and deprecatedSuperRecordKeys - /// by publicKey - @override - FixedEncodedString86 get signature; + final _SuperIdentity _self; + final $Res Function(_SuperIdentity) _then; /// Create a copy of SuperIdentity /// with the given fields replaced by the non-null parameter values. @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$SuperIdentityImplCopyWith<_$SuperIdentityImpl> get copyWith => - throw _privateConstructorUsedError; + @pragma('vm:prefer-inline') + $Res call({ + Object? recordKey = null, + Object? publicKey = null, + Object? currentInstance = null, + Object? deprecatedInstances = null, + Object? deprecatedSuperRecordKeys = null, + Object? signature = null, + }) { + return _then(_SuperIdentity( + recordKey: null == recordKey + ? _self.recordKey + : recordKey // ignore: cast_nullable_to_non_nullable + as Typed, + publicKey: null == publicKey + ? _self.publicKey + : publicKey // ignore: cast_nullable_to_non_nullable + as FixedEncodedString43, + currentInstance: null == currentInstance + ? _self.currentInstance + : currentInstance // ignore: cast_nullable_to_non_nullable + as IdentityInstance, + deprecatedInstances: null == deprecatedInstances + ? _self._deprecatedInstances + : deprecatedInstances // ignore: cast_nullable_to_non_nullable + as List, + deprecatedSuperRecordKeys: null == deprecatedSuperRecordKeys + ? _self._deprecatedSuperRecordKeys + : deprecatedSuperRecordKeys // ignore: cast_nullable_to_non_nullable + as List>, + signature: null == signature + ? _self.signature + : signature // ignore: cast_nullable_to_non_nullable + as FixedEncodedString86, + )); + } + + /// Create a copy of SuperIdentity + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $IdentityInstanceCopyWith<$Res> get currentInstance { + return $IdentityInstanceCopyWith<$Res>(_self.currentInstance, (value) { + return _then(_self.copyWith(currentInstance: value)); + }); + } } + +// dart format on diff --git a/packages/veilid_support/lib/identity_support/super_identity.g.dart b/packages/veilid_support/lib/identity_support/super_identity.g.dart index 4c4f4f3..1b52492 100644 --- a/packages/veilid_support/lib/identity_support/super_identity.g.dart +++ b/packages/veilid_support/lib/identity_support/super_identity.g.dart @@ -6,8 +6,8 @@ part of 'super_identity.dart'; // JsonSerializableGenerator // ************************************************************************** -_$SuperIdentityImpl _$$SuperIdentityImplFromJson(Map json) => - _$SuperIdentityImpl( +_SuperIdentity _$SuperIdentityFromJson(Map json) => + _SuperIdentity( recordKey: Typed.fromJson(json['record_key']), publicKey: FixedEncodedString43.fromJson(json['public_key']), currentInstance: IdentityInstance.fromJson(json['current_instance']), @@ -21,7 +21,7 @@ _$SuperIdentityImpl _$$SuperIdentityImplFromJson(Map json) => signature: FixedEncodedString86.fromJson(json['signature']), ); -Map _$$SuperIdentityImplToJson(_$SuperIdentityImpl instance) => +Map _$SuperIdentityToJson(_SuperIdentity instance) => { 'record_key': instance.recordKey.toJson(), 'public_key': instance.publicKey.toJson(), diff --git a/packages/veilid_support/lib/proto/proto.dart b/packages/veilid_support/lib/proto/proto.dart index a7a70bb..936bbdf 100644 --- a/packages/veilid_support/lib/proto/proto.dart +++ b/packages/veilid_support/lib/proto/proto.dart @@ -1,5 +1,6 @@ import 'dart:typed_data'; +import '../src/dynamic_debug.dart'; import '../veilid_support.dart' as veilid; import 'veilid.pb.dart' as proto; @@ -150,3 +151,26 @@ extension ProtoKeyPair on proto.KeyPair { veilid.KeyPair toVeilid() => veilid.KeyPair(key: key.toVeilid(), secret: secret.toVeilid()); } + +void registerVeilidProtoToDebug() { + dynamic toDebug(dynamic protoObj) { + if (protoObj is proto.CryptoKey) { + return protoObj.toVeilid(); + } + if (protoObj is proto.Signature) { + return protoObj.toVeilid(); + } + if (protoObj is proto.Nonce) { + return protoObj.toVeilid(); + } + if (protoObj is proto.TypedKey) { + return protoObj.toVeilid(); + } + if (protoObj is proto.KeyPair) { + return protoObj.toVeilid(); + } + return protoObj; + } + + DynamicDebug.registerToDebug(toDebug); +} diff --git a/packages/veilid_support/lib/src/dynamic_debug.dart b/packages/veilid_support/lib/src/dynamic_debug.dart new file mode 100644 index 0000000..1c38d96 --- /dev/null +++ b/packages/veilid_support/lib/src/dynamic_debug.dart @@ -0,0 +1,130 @@ +import 'package:async_tools/async_tools.dart'; +import 'package:bloc_advanced_tools/bloc_advanced_tools.dart'; +import 'package:convert/convert.dart'; +import 'package:fast_immutable_collections/fast_immutable_collections.dart'; + +import 'online_element_state.dart'; + +typedef ToDebugFunction = dynamic Function(dynamic protoObj); + +// This should be implemented to add toDebug capability +// ignore: one_member_abstracts +abstract class ToDebugMap { + Map toDebugMap(); +} + +// We explicitly want this class to avoid having a global function 'toDebug' +// ignore: avoid_classes_with_only_static_members +class DynamicDebug { + /// Add a 'toDebug' handler to the chain + static void registerToDebug(ToDebugFunction toDebugFunction) { + final _oldToDebug = _toDebug; + _toDebug = (obj) => _oldToDebug(toDebugFunction(obj)); + } + + /// Convert a type to a debug version of the same type that + /// has a better `toString` representation and possibly other extra debug + /// information + static dynamic toDebug(dynamic obj) { + try { + return _toDebug(obj); + // In this case we watch to catch everything + // because toDebug need to never fail + // ignore: avoid_catches_without_on_clauses + } catch (e) { + // Ensure this gets printed, but continue + // ignore: avoid_print + print('Exception in toDebug: $e'); + return obj.toString(); + } + } + + ////////////////////////////////////////////////////////////// + static dynamic _baseToDebug(dynamic obj) { + if (obj is AsyncValue) { + if (obj.isLoading) { + return {r'$runtimeType': obj.runtimeType, 'loading': null}; + } + if (obj.isError) { + return { + r'$runtimeType': obj.runtimeType, + 'error': toDebug(obj.asError!.error), + 'stackTrace': toDebug(obj.asError!.stackTrace), + }; + } + if (obj.isData) { + return { + r'$runtimeType': obj.runtimeType, + 'data': toDebug(obj.asData!.value), + }; + } + return obj.toString(); + } + if (obj is IMap) { + // Handled by Map + return _baseToDebug(obj.unlockView); + } + if (obj is IMapOfSets) { + // Handled by Map + return _baseToDebug(obj.unlock); + } + if (obj is ISet) { + // Handled by Iterable + return _baseToDebug(obj.unlockView); + } + if (obj is IList) { + return _baseToDebug(obj.unlockView); + } + if (obj is BlocBusyState) { + return { + r'$runtimeType': obj.runtimeType, + 'busy': obj.busy, + 'state': toDebug(obj.state), + }; + } + if (obj is OnlineElementState) { + return { + r'$runtimeType': obj.runtimeType, + 'isOffline': obj.isOffline, + 'value': toDebug(obj.value), + }; + } + if (obj is List) { + try { + // Do bytes as a hex string for brevity and clarity + return 'List: ${hex.encode(obj)}'; + // One has to be able to catch this + // ignore: avoid_catching_errors + } on RangeError { + // Otherwise directly convert as list of integers + return obj.toString(); + } + } + if (obj is Map) { + return obj.map((k, v) => MapEntry(toDebug(k), toDebug(v))); + } + if (obj is Iterable) { + return obj.map(toDebug).toList(); + } + if (obj is String || obj is bool || obj is num || obj == null) { + return obj; + } + if (obj is ToDebugMap) { + // Handled by Map + return _baseToDebug(obj.toDebugMap()); + } + + try { + // Let's try convering to a json object + // ignore: avoid_dynamic_calls + return obj.toJson(); + + // No matter how this fails, we shouldn't throw + // ignore: avoid_catches_without_on_clauses + } catch (_) {} + + return obj.toString(); + } + + static ToDebugFunction _toDebug = _baseToDebug; +} diff --git a/packages/veilid_support/lib/veilid_support.dart b/packages/veilid_support/lib/veilid_support.dart index f48376f..2f4da90 100644 --- a/packages/veilid_support/lib/veilid_support.dart +++ b/packages/veilid_support/lib/veilid_support.dart @@ -1,13 +1,14 @@ /// Dart Veilid Support Library /// Common functionality for interfacing with Veilid -library veilid_support; +library; export 'package:veilid/veilid.dart'; export 'dht_support/dht_support.dart'; export 'identity_support/identity_support.dart'; export 'src/config.dart'; +export 'src/dynamic_debug.dart'; export 'src/json_tools.dart'; export 'src/memory_tools.dart'; export 'src/online_element_state.dart'; diff --git a/packages/veilid_support/pubspec.lock b/packages/veilid_support/pubspec.lock index e3dfcdd..0c8ca3d 100644 --- a/packages/veilid_support/pubspec.lock +++ b/packages/veilid_support/pubspec.lock @@ -178,7 +178,7 @@ packages: source: hosted version: "1.19.1" convert: - dependency: transitive + dependency: "direct main" description: name: convert sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 diff --git a/packages/veilid_support/pubspec.yaml b/packages/veilid_support/pubspec.yaml index 5aff89e..548c40e 100644 --- a/packages/veilid_support/pubspec.yaml +++ b/packages/veilid_support/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: bloc_advanced_tools: ^0.1.10 charcode: ^1.4.0 collection: ^1.19.1 + convert: ^3.1.2 equatable: ^2.0.7 fast_immutable_collections: ^11.0.3 freezed_annotation: ^3.0.0 From 6830b54ce8e1eecb097b56075deea4834c9d11ba Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sun, 23 Mar 2025 10:41:19 -0400 Subject: [PATCH 5/6] move keyboard shortcuts into own file --- lib/app.dart | 68 +------------------- lib/layout/home/drawer_menu/drawer_menu.dart | 4 +- lib/router/cubits/router_cubit.dart | 13 ++++ lib/router/views/router_shell.dart | 4 +- 4 files changed, 19 insertions(+), 70 deletions(-) diff --git a/lib/app.dart b/lib/app.dart index f8241da..802b0d7 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,15 +1,12 @@ import 'package:animated_theme_switcher/animated_theme_switcher.dart'; -import 'package:async_tools/async_tools.dart'; import 'package:fast_immutable_collections/fast_immutable_collections.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_translate/flutter_translate.dart'; import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:provider/provider.dart'; -import 'package:veilid_support/veilid_support.dart'; import 'account_manager/account_manager.dart'; import 'init.dart'; @@ -19,17 +16,8 @@ import 'router/router.dart'; import 'settings/settings.dart'; import 'theme/theme.dart'; import 'tick.dart'; -import 'tools/loggy.dart'; import 'veilid_processor/veilid_processor.dart'; -class ReloadThemeIntent extends Intent { - const ReloadThemeIntent(); -} - -class AttachDetachIntent extends Intent { - const AttachDetachIntent(); -} - class ScrollBehaviorModified extends ScrollBehavior { const ScrollBehaviorModified(); @override @@ -47,59 +35,6 @@ class VeilidChatApp extends StatelessWidget { final ThemeData initialThemeData; - void reloadTheme(BuildContext context) { - singleFuture(this, () async { - log.info('Reloading theme'); - - await VeilidChatGlobalInit.loadAssetManifest(); - - final theme = - PreferencesRepository.instance.value.themePreference.themeData(); - if (context.mounted) { - ThemeSwitcher.of(context).changeTheme(theme: theme); - - // Hack to reload translations - final localizationDelegate = LocalizedApp.of(context).delegate; - await LocalizationDelegate.create( - fallbackLocale: localizationDelegate.fallbackLocale.toString(), - supportedLocales: localizationDelegate.supportedLocales - .map((x) => x.toString()) - .toList()); - } - }); - } - - void _attachDetach(BuildContext context) { - singleFuture(this, () async { - if (ProcessorRepository.instance.processorConnectionState.isAttached) { - log.info('Detaching'); - await Veilid.instance.detach(); - } else if (ProcessorRepository - .instance.processorConnectionState.isDetached) { - log.info('Attaching'); - await Veilid.instance.attach(); - } - }); - } - - Widget _buildShortcuts({required Widget Function(BuildContext) builder}) => - ThemeSwitcher( - builder: (context) => Shortcuts( - shortcuts: { - LogicalKeySet( - LogicalKeyboardKey.alt, LogicalKeyboardKey.keyR): - const ReloadThemeIntent(), - LogicalKeySet( - LogicalKeyboardKey.alt, LogicalKeyboardKey.keyD): - const AttachDetachIntent(), - }, - child: Actions(actions: >{ - ReloadThemeIntent: CallbackAction( - onInvoke: (intent) => reloadTheme(context)), - AttachDetachIntent: CallbackAction( - onInvoke: (intent) => _attachDetach(context)), - }, child: Focus(autofocus: true, child: builder(context))))); - Widget appBuilder( BuildContext context, LocalizationDelegate localizationDelegate) => ThemeProvider( @@ -138,8 +73,7 @@ class VeilidChatApp extends StatelessWidget { accountRepository: AccountRepository.instance, locator: context.read)), ], - child: - BackgroundTicker(child: _buildShortcuts(builder: (context) { + child: BackgroundTicker(child: Builder(builder: (context) { final scale = theme.extension()!; final scaleConfig = theme.extension()!; diff --git a/lib/layout/home/drawer_menu/drawer_menu.dart b/lib/layout/home/drawer_menu/drawer_menu.dart index 3cf1b79..0863b1f 100644 --- a/lib/layout/home/drawer_menu/drawer_menu.dart +++ b/lib/layout/home/drawer_menu/drawer_menu.dart @@ -9,7 +9,7 @@ import 'package:go_router/go_router.dart'; import 'package:veilid_support/veilid_support.dart'; import '../../../account_manager/account_manager.dart'; -import '../../../app.dart'; +import '../../../keyboard_shortcuts.dart'; import '../../../theme/theme.dart'; import '../../../tools/tools.dart'; import '../../../veilid_processor/veilid_processor.dart'; @@ -366,7 +366,7 @@ class _DrawerMenuState extends State { GestureDetector( onLongPress: () async { context - .findAncestorWidgetOfExactType()! + .findAncestorWidgetOfExactType()! .reloadTheme(context); }, child: SvgPicture.asset( diff --git a/lib/router/cubits/router_cubit.dart b/lib/router/cubits/router_cubit.dart index 1492c51..19af5e0 100644 --- a/lib/router/cubits/router_cubit.dart +++ b/lib/router/cubits/router_cubit.dart @@ -16,6 +16,8 @@ import '../../tools/tools.dart'; import '../../veilid_processor/views/developer.dart'; import '../views/router_shell.dart'; +export 'package:go_router/go_router.dart'; + part 'router_cubit.freezed.dart'; part 'router_cubit.g.dart'; @@ -164,3 +166,14 @@ class RouterCubit extends Cubit { _accountRepositorySubscription; GoRouter? _router; } + +extension GoRouterExtension on GoRouter { + String location() { + final lastMatch = routerDelegate.currentConfiguration.last; + final matchList = lastMatch is ImperativeRouteMatch + ? lastMatch.matches + : routerDelegate.currentConfiguration; + final location = matchList.uri.toString(); + return location; + } +} diff --git a/lib/router/views/router_shell.dart b/lib/router/views/router_shell.dart index f2f035b..8a7130f 100644 --- a/lib/router/views/router_shell.dart +++ b/lib/router/views/router_shell.dart @@ -1,12 +1,14 @@ import 'package:flutter/widgets.dart'; +import '../../keyboard_shortcuts.dart'; import '../../notifications/notifications.dart'; class RouterShell extends StatelessWidget { const RouterShell({required Widget child, super.key}) : _child = child; @override - Widget build(BuildContext context) => NotificationsWidget(child: _child); + Widget build(BuildContext context) => + NotificationsWidget(child: KeyboardShortcuts(child: _child)); final Widget _child; } From 89c6bd5e43934942cfdb3a64a2fc33517524cee3 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 29 Mar 2025 18:06:08 -0400 Subject: [PATCH 6/6] changelog --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7e369f..843cc65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## v0.4.6 ## +- Updated veilid-core to v0.4.4 + - See Veilid changelog for specifics +- UI improvements: Theme fixes, wallpaper option added +- Responsiveness improved +- Contacts workflow more consistent +- Safe-area fixes +- Make layout more mobile-friendly +- Improved contact invitation menus +- Deadlock fixes in veilid_support +- _pollWatch was degenerate and only watched first subkey + ## v0.4.5 ## - Updated veilid-core to v0.4.1 - See Veilid changelog for specifics