From 3acd207de629ebf65f799ff5d0270f78afcc0c59 Mon Sep 17 00:00:00 2001 From: otsmr Date: Mon, 4 May 2026 23:35:15 +0200 Subject: [PATCH] improved layout and fixed add logging --- CHANGELOG.md | 4 + .../callbacks/user_discovery.callbacks.dart | 7 +- .../generated/app_localizations.dart | 84 ++++ .../generated/app_localizations_de.dart | 42 ++ .../generated/app_localizations_en.dart | 42 ++ lib/src/localization/translations | 2 +- lib/src/services/user_discovery.service.dart | 14 +- lib/src/visual/themes/dark.dart | 4 +- .../visual/views/onboarding/setup.view.dart | 68 ++- .../setup/add_new_contacts.setup.dart | 2 +- .../mock_contact_request_actions.comp.dart | 160 +++---- .../setup/components/next_button.comp.dart | 2 +- .../let_your_friends_find_you.setup.dart | 15 +- .../components/user_discovery_setup.comp.dart | 405 ++++++++++-------- pubspec.yaml | 2 +- rust/src/bridge/wrapper/user_discovery.rs | 14 +- .../protocols/src/user_discovery.rs | 6 + 17 files changed, 577 insertions(+), 296 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c0239aa..c5c3bb0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.2.9 + +- Fix: Messages occasionally not received until app restart + ## 0.2.8 - Fix: App did not launch sometimes on Android diff --git a/lib/src/callbacks/user_discovery.callbacks.dart b/lib/src/callbacks/user_discovery.callbacks.dart index 8542616b..3b72cc66 100644 --- a/lib/src/callbacks/user_discovery.callbacks.dart +++ b/lib/src/callbacks/user_discovery.callbacks.dart @@ -16,8 +16,12 @@ class UserDiscoveryCallbacks { static Future signData( Uint8List inputData, ) async { + Log.info('UserDiscoveryCallbacks: signData started'); var privKey = (await getSignalIdentityKeyPair())?.getPrivateKey(); - if (privKey == null) return null; + if (privKey == null) { + Log.error('UserDiscoveryCallbacks: signData failed, privKey is null'); + return null; + } final random = getRandomUint8List(32); final signature = sign( privKey.serialize(), @@ -25,6 +29,7 @@ class UserDiscoveryCallbacks { random, ); privKey = null; + Log.info('UserDiscoveryCallbacks: signData finished'); return signature; } diff --git a/lib/src/localization/generated/app_localizations.dart b/lib/src/localization/generated/app_localizations.dart index 47f5438e..0e3312d5 100644 --- a/lib/src/localization/generated/app_localizations.dart +++ b/lib/src/localization/generated/app_localizations.dart @@ -2965,6 +2965,90 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Approve'** String get contactUserDiscoveryManualApprovalApprove; + + /// No description provided for @exampleUserName1. + /// + /// In en, this message translates to: + /// **'james'** + String get exampleUserName1; + + /// No description provided for @exampleUserName2. + /// + /// In en, this message translates to: + /// **'mary'** + String get exampleUserName2; + + /// No description provided for @exampleUserName3. + /// + /// In en, this message translates to: + /// **'john'** + String get exampleUserName3; + + /// No description provided for @exampleUserName4. + /// + /// In en, this message translates to: + /// **'patricia'** + String get exampleUserName4; + + /// No description provided for @exampleUserName5. + /// + /// In en, this message translates to: + /// **'robert'** + String get exampleUserName5; + + /// No description provided for @exampleUserName6. + /// + /// In en, this message translates to: + /// **'jennifer'** + String get exampleUserName6; + + /// No description provided for @exampleUserName7. + /// + /// In en, this message translates to: + /// **'michael'** + String get exampleUserName7; + + /// No description provided for @exampleUserName8. + /// + /// In en, this message translates to: + /// **'linda'** + String get exampleUserName8; + + /// No description provided for @exampleUserName9. + /// + /// In en, this message translates to: + /// **'william'** + String get exampleUserName9; + + /// No description provided for @exampleUserName10. + /// + /// In en, this message translates to: + /// **'lena'** + String get exampleUserName10; + + /// No description provided for @exampleUserName11. + /// + /// In en, this message translates to: + /// **'david'** + String get exampleUserName11; + + /// No description provided for @exampleJane. + /// + /// In en, this message translates to: + /// **'jane'** + String get exampleJane; + + /// No description provided for @back. + /// + /// In en, this message translates to: + /// **'Back'** + String get back; + + /// No description provided for @onboardingExampleLabel. + /// + /// In en, this message translates to: + /// **'Example'** + String get onboardingExampleLabel; } class _AppLocalizationsDelegate diff --git a/lib/src/localization/generated/app_localizations_de.dart b/lib/src/localization/generated/app_localizations_de.dart index 4e247819..91796dd8 100644 --- a/lib/src/localization/generated/app_localizations_de.dart +++ b/lib/src/localization/generated/app_localizations_de.dart @@ -1669,4 +1669,46 @@ class AppLocalizationsDe extends AppLocalizations { @override String get contactUserDiscoveryManualApprovalApprove => 'Freigeben'; + + @override + String get exampleUserName1 => 'max_mustermann'; + + @override + String get exampleUserName2 => 'erika_musterfrau'; + + @override + String get exampleUserName3 => 'hans'; + + @override + String get exampleUserName4 => 'petra'; + + @override + String get exampleUserName5 => 'klaus'; + + @override + String get exampleUserName6 => 'sabine'; + + @override + String get exampleUserName7 => 'stefan'; + + @override + String get exampleUserName8 => 'monika'; + + @override + String get exampleUserName9 => 'christian'; + + @override + String get exampleUserName10 => 'lena'; + + @override + String get exampleUserName11 => 'david'; + + @override + String get exampleJane => 'erika'; + + @override + String get back => 'Zurück'; + + @override + String get onboardingExampleLabel => 'Beispiel'; } diff --git a/lib/src/localization/generated/app_localizations_en.dart b/lib/src/localization/generated/app_localizations_en.dart index 0f4bf7fa..6b9adbd7 100644 --- a/lib/src/localization/generated/app_localizations_en.dart +++ b/lib/src/localization/generated/app_localizations_en.dart @@ -1654,4 +1654,46 @@ class AppLocalizationsEn extends AppLocalizations { @override String get contactUserDiscoveryManualApprovalApprove => 'Approve'; + + @override + String get exampleUserName1 => 'james'; + + @override + String get exampleUserName2 => 'mary'; + + @override + String get exampleUserName3 => 'john'; + + @override + String get exampleUserName4 => 'patricia'; + + @override + String get exampleUserName5 => 'robert'; + + @override + String get exampleUserName6 => 'jennifer'; + + @override + String get exampleUserName7 => 'michael'; + + @override + String get exampleUserName8 => 'linda'; + + @override + String get exampleUserName9 => 'william'; + + @override + String get exampleUserName10 => 'lena'; + + @override + String get exampleUserName11 => 'david'; + + @override + String get exampleJane => 'jane'; + + @override + String get back => 'Back'; + + @override + String get onboardingExampleLabel => 'Example'; } diff --git a/lib/src/localization/translations b/lib/src/localization/translations index 03bf2204..73d1af8c 160000 --- a/lib/src/localization/translations +++ b/lib/src/localization/translations @@ -1 +1 @@ -Subproject commit 03bf220400bf35002c77e153768bd0f963a97d89 +Subproject commit 73d1af8ca42b10abf6204acf3720d40f9ab6d4a8 diff --git a/lib/src/services/user_discovery.service.dart b/lib/src/services/user_discovery.service.dart index a9d0015b..d7d61504 100644 --- a/lib/src/services/user_discovery.service.dart +++ b/lib/src/services/user_discovery.service.dart @@ -76,20 +76,28 @@ class UserDiscoveryService { required bool sharePromotion, }) async { try { + Log.info('UserDiscoveryService: initializeOrUpdate started'); + final userId = userService.currentUser.userId; + final publicKey = await getUserPublicKey(); + Log.info('UserDiscoveryService: initializing Rust bridge'); await FlutterUserDiscovery.initializeOrUpdate( threshold: threshold, - userId: userService.currentUser.userId, - publicKey: await getUserPublicKey(), + userId: userId, + publicKey: publicKey, sharePromotion: sharePromotion, ); + Log.info( + 'UserDiscoveryService: Rust bridge initialized, updating UserService', + ); await UserService.update( (u) => u ..isUserDiscoveryEnabled = true ..userDiscoverySharePromotion = sharePromotion ..userDiscoveryThreshold = threshold, ); + Log.info('UserDiscoveryService: initializeOrUpdate finished'); } catch (e) { - Log.error(e); + Log.error('UserDiscoveryService: initializeOrUpdate error: $e'); } } diff --git a/lib/src/visual/themes/dark.dart b/lib/src/visual/themes/dark.dart index 621e0b68..ec302fab 100644 --- a/lib/src/visual/themes/dark.dart +++ b/lib/src/visual/themes/dark.dart @@ -5,7 +5,9 @@ final ThemeData darkTheme = ThemeData.dark().copyWith( brightness: Brightness.dark, seedColor: const Color(0xFF57CC99), surface: const Color.fromARGB(255, 20, 18, 23), - surfaceContainer: const Color.fromARGB(255, 33, 30, 39), + surfaceContainer: const Color.fromARGB(255, 45, 41, 54), + surfaceContainerLow: const Color.fromARGB(255, 38, 34, 45), + surfaceContainerHigh: const Color.fromARGB(255, 52, 48, 62), ), inputDecorationTheme: const InputDecorationTheme( border: OutlineInputBorder(), diff --git a/lib/src/visual/views/onboarding/setup.view.dart b/lib/src/visual/views/onboarding/setup.view.dart index 048f8b23..847cdc50 100644 --- a/lib/src/visual/views/onboarding/setup.view.dart +++ b/lib/src/visual/views/onboarding/setup.view.dart @@ -43,6 +43,14 @@ extension SetupPagesExtension on SetupPages { } return null; } + + SetupPages? previous() { + final prevIndex = index - 1; + if (prevIndex >= 0) { + return SetupPages.values[prevIndex]; + } + return null; + } } class SetupView extends StatefulWidget { @@ -119,31 +127,51 @@ class _SetupViewState extends State { ), body: ListView( key: ValueKey(currentPage.name), - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30), + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20), children: [ _buildPage(currentPage, state), - if (!currentPage.isLast) - SizedBox( - height: 50, - child: Center( - child: TextButton( - onPressed: () async { - await UserService.update( - (u) => u.skipSetupPages = true, - ); - widget.onUpdate?.call(); - }, - child: Text( - context.lang.onboardingFinishLater, - style: TextStyle( - color: context.color.primary, - fontWeight: FontWeight.bold, + if (currentPage.index > 0 || !currentPage.isLast) + Padding( + padding: const EdgeInsets.only(top: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (currentPage.index > 0) + TextButton( + onPressed: () async { + await UserService.update((u) { + u.currentSetupPage = currentPage.previous()?.name; + }); + }, + child: Text( + context.lang.back, + style: TextStyle( + color: context.color.primary, + fontWeight: FontWeight.bold, + ), + ), ), - ), - ), + if (currentPage.index > 0 && !currentPage.isLast) + const SizedBox(width: 24), + if (!currentPage.isLast) + TextButton( + onPressed: () async { + await UserService.update( + (u) => u.skipSetupPages = true, + ); + widget.onUpdate?.call(); + }, + child: Text( + context.lang.onboardingFinishLater, + style: TextStyle( + color: context.color.primary, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), ), - const SizedBox(height: 60), ], ), ); diff --git a/lib/src/visual/views/onboarding/setup/add_new_contacts.setup.dart b/lib/src/visual/views/onboarding/setup/add_new_contacts.setup.dart index f50687d4..b28da67f 100644 --- a/lib/src/visual/views/onboarding/setup/add_new_contacts.setup.dart +++ b/lib/src/visual/views/onboarding/setup/add_new_contacts.setup.dart @@ -65,7 +65,7 @@ class AddNewContactsPage extends StatelessWidget { const SizedBox(height: 20), Padding( - padding: const EdgeInsets.symmetric(horizontal: 40), + padding: const EdgeInsets.symmetric(horizontal: 35), child: Column( children: [ diff --git a/lib/src/visual/views/onboarding/setup/components/mock_contact_request_actions.comp.dart b/lib/src/visual/views/onboarding/setup/components/mock_contact_request_actions.comp.dart index 5599da39..155fbf54 100644 --- a/lib/src/visual/views/onboarding/setup/components/mock_contact_request_actions.comp.dart +++ b/lib/src/visual/views/onboarding/setup/components/mock_contact_request_actions.comp.dart @@ -8,53 +8,101 @@ class MockContactRequestActionsComp extends StatelessWidget { @override Widget build(BuildContext context) { - return SizedBox( - // width: 125, + return IgnorePointer( + child: SizedBox( + // width: 125, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(width: 4), + SizedBox( + height: 20, + // width: 45, + child: FilledButton( + style: FilledButton.styleFrom( + padding: const EdgeInsets.only(right: 2, left: 4), + backgroundColor: context.color.surfaceContainerHigh, + foregroundColor: context.color.onSurface, + ), + onPressed: () {}, + child: Row( + children: [ + const Icon( + Icons.person_off_rounded, + color: Color.fromARGB(164, 244, 67, 54), + size: 12, + ), + Text( + context.lang.contactActionBlock, + style: const TextStyle(fontSize: 8), + ), + ], + ), + ), + ), + const SizedBox(width: 6), + SizedBox( + height: 20, + // width: 50, + child: FilledButton( + style: FilledButton.styleFrom( + padding: const EdgeInsets.only(right: 2, left: 4), + backgroundColor: context.color.surfaceContainerHigh, + foregroundColor: context.color.onSurface, + ), + onPressed: () {}, + child: Row( + children: [ + const Icon(Icons.check, color: Colors.green, size: 12), + Text( + context.lang.contactActionAccept, + style: const TextStyle(fontSize: 8), + ), + ], + ), + ), + ), + IconButton( + style: IconButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 2), + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + constraints: const BoxConstraints(), + icon: const Icon(Icons.close, size: 12), + onPressed: () {}, + ), + ], + ), + ), + ); + } +} + +class MockContactSuggestedActionsComp extends StatelessWidget { + const MockContactSuggestedActionsComp({super.key}); + + @override + Widget build(BuildContext context) { + return IgnorePointer( child: Row( mainAxisSize: MainAxisSize.min, children: [ const SizedBox(width: 4), SizedBox( height: 20, - // width: 45, child: FilledButton( style: FilledButton.styleFrom( - padding: const EdgeInsets.only(right: 2, left: 4), - backgroundColor: context.color.surfaceContainerHigh, - foregroundColor: context.color.onSurface, - ), + padding: const EdgeInsets.only(right: 8, left: 4), + ).merge(secondaryGreyButtonStyle(context)), onPressed: () {}, child: Row( children: [ - const Icon( - Icons.person_off_rounded, - color: Color.fromARGB(164, 244, 67, 54), - size: 12, + const Padding( + padding: EdgeInsets.symmetric(horizontal: 6), + child: FaIcon(FontAwesomeIcons.userPlus, size: 10), ), Text( - context.lang.contactActionBlock, - style: const TextStyle(fontSize: 8), - ), - ], - ), - ), - ), - const SizedBox(width: 6), - SizedBox( - height: 20, - // width: 50, - child: FilledButton( - style: FilledButton.styleFrom( - padding: const EdgeInsets.only(right: 2, left: 4), - backgroundColor: context.color.surfaceContainerHigh, - foregroundColor: context.color.onSurface, - ), - onPressed: () {}, - child: Row( - children: [ - const Icon(Icons.check, color: Colors.green, size: 12), - Text( - context.lang.contactActionAccept, + context.lang.friendSuggestionsRequest, style: const TextStyle(fontSize: 8), ), ], @@ -75,47 +123,3 @@ class MockContactRequestActionsComp extends StatelessWidget { ); } } - -class MockContactSuggestedActionsComp extends StatelessWidget { - const MockContactSuggestedActionsComp({super.key}); - - @override - Widget build(BuildContext context) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox(width: 4), - SizedBox( - height: 20, - child: FilledButton( - style: FilledButton.styleFrom( - padding: const EdgeInsets.only(right: 8, left: 4), - ).merge(secondaryGreyButtonStyle(context)), - onPressed: () {}, - child: Row( - children: [ - const Padding( - padding: EdgeInsets.symmetric(horizontal: 6), - child: FaIcon(FontAwesomeIcons.userPlus, size: 10), - ), - Text( - context.lang.friendSuggestionsRequest, - style: const TextStyle(fontSize: 8), - ), - ], - ), - ), - ), - IconButton( - style: IconButton.styleFrom( - padding: const EdgeInsets.symmetric(horizontal: 2), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - ), - constraints: const BoxConstraints(), - icon: const Icon(Icons.close, size: 12), - onPressed: () {}, - ), - ], - ); - } -} diff --git a/lib/src/visual/views/onboarding/setup/components/next_button.comp.dart b/lib/src/visual/views/onboarding/setup/components/next_button.comp.dart index 40f22be4..fbf9eb80 100644 --- a/lib/src/visual/views/onboarding/setup/components/next_button.comp.dart +++ b/lib/src/visual/views/onboarding/setup/components/next_button.comp.dart @@ -22,7 +22,7 @@ class NextButtonComp extends StatelessWidget { userService.currentUser.currentSetupPage, ); return ElevatedButton( - onPressed: canSubmit + onPressed: (canSubmit && !isLoading) ? () async { if (onPressed != null) { final error = await onPressed?.call(); diff --git a/lib/src/visual/views/onboarding/setup/let_your_friends_find_you.setup.dart b/lib/src/visual/views/onboarding/setup/let_your_friends_find_you.setup.dart index 3f7275ef..ed65698b 100644 --- a/lib/src/visual/views/onboarding/setup/let_your_friends_find_you.setup.dart +++ b/lib/src/visual/views/onboarding/setup/let_your_friends_find_you.setup.dart @@ -17,6 +17,8 @@ class LetYourFriendsFindYou extends StatefulWidget { } class _LetYourFriendsFindYouState extends State { + bool _isLoading = false; + @override void initState() { super.initState(); @@ -77,8 +79,19 @@ class _LetYourFriendsFindYouState extends State { ), const SizedBox(height: 50), NextButtonComp( + isLoading: _isLoading, onPressed: () async { - return !(await widget.state.initializeOrUpdate()); + setState(() { + _isLoading = true; + }); + try { + final result = await widget.state.initializeOrUpdate(); + return !result; + } finally { + setState(() { + _isLoading = false; + }); + } }, ), ], diff --git a/lib/src/visual/views/settings/privacy/user_discovery/components/user_discovery_setup.comp.dart b/lib/src/visual/views/settings/privacy/user_discovery/components/user_discovery_setup.comp.dart index 17c7f8c7..d32d9c30 100644 --- a/lib/src/visual/views/settings/privacy/user_discovery/components/user_discovery_setup.comp.dart +++ b/lib/src/visual/views/settings/privacy/user_discovery/components/user_discovery_setup.comp.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:twonly/locator.dart'; import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/services/user_discovery.service.dart'; +import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/visual/components/avatar_icon.comp.dart'; import 'package:twonly/src/visual/components/verification_badge.comp.dart'; @@ -9,18 +10,18 @@ import 'package:twonly/src/visual/views/contact/add_new_contact_components/frien import 'package:twonly/src/visual/views/onboarding/setup/components/mock_contact_request_actions.comp.dart'; import 'package:twonly/src/visual/views/onboarding/setup/components/setup_switch_card.comp.dart'; -const exampleUsers = [ - 'james', - 'mary', - 'john', - 'patricia', - 'robert', - 'jennifer', - 'michael', - 'linda', - 'william', - 'lena', - 'david', +List getExampleUsers(BuildContext context) => [ + context.lang.exampleUserName1, + context.lang.exampleUserName2, + context.lang.exampleUserName3, + context.lang.exampleUserName4, + context.lang.exampleUserName5, + context.lang.exampleUserName6, + context.lang.exampleUserName7, + context.lang.exampleUserName8, + context.lang.exampleUserName9, + context.lang.exampleUserName10, + context.lang.exampleUserName11, ]; class UserDiscoverySetupState { @@ -52,21 +53,30 @@ class UserDiscoverySetupState { } Future initializeOrUpdate() async { - if (isUserDiscoveryEnabled) { - await UserDiscoveryService.initializeOrUpdate( - threshold: threshold, - sharePromotion: sharePromotion, - ); + try { + Log.info('UserDiscoverySetupState: initializeOrUpdate started'); + if (isUserDiscoveryEnabled) { + Log.info('UserDiscoverySetupState: initializing UserDiscoveryService'); + await UserDiscoveryService.initializeOrUpdate( + threshold: threshold, + sharePromotion: sharePromotion, + ); + } + + Log.info('UserDiscoverySetupState: updating UserService'); + await UserService.update((u) { + u + ..isUserDiscoveryEnabled = isUserDiscoveryEnabled + ..requiredSendImages = requiredSendImages + ..userDiscoveryRequiresManualApproval = isManualApprovalEnabled; + }); + + Log.info('UserDiscoverySetupState: initializeOrUpdate finished'); + return true; + } catch (e) { + Log.error('UserDiscoverySetupState: initializeOrUpdate failed: $e'); + return false; } - - await UserService.update((u) { - u - ..isUserDiscoveryEnabled = isUserDiscoveryEnabled - ..requiredSendImages = requiredSendImages - ..userDiscoveryRequiresManualApproval = isManualApprovalEnabled; - }); - - return true; } } @@ -107,15 +117,12 @@ class UserDiscoverySetupComp extends StatelessWidget { textAlign: TextAlign.center, ), - const SizedBox(height: 32), + const SizedBox(height: 24), SetupSwitchCard( value: state.isUserDiscoveryEnabled, onChanged: (val) => state.update(() { state.isUserDiscoveryEnabled = val; - if (!val) { - state.sharePromotion = false; - } }), title: context.lang.onboardingUserDiscoveryShareFriends, expandedChild: Column( @@ -143,48 +150,10 @@ class UserDiscoverySetupComp extends StatelessWidget { ), ), const Padding( - padding: EdgeInsets.symmetric(vertical: 8), + padding: EdgeInsets.only(bottom: 8), child: Divider(), ), - Text( - context.lang.onboardingUserDiscoveryContactsVerifiedBadge, - style: TextStyle( - color: context.color.onSurfaceVariant, - fontSize: 12, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 16), - Center( - child: Container( - width: 100, - height: 40, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey, width: 0.5), - borderRadius: BorderRadius.circular(12), - ), - child: const Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - AvatarIcon(fontSize: 12), - SizedBox(width: 5), - Text( - 'jane', - style: TextStyle( - fontWeight: FontWeight.bold, - ), - ), - SizedBox(width: 5), - VerificationBadgeComp( - isVerifiedByTransferredTrust: true, - size: 14, - clickable: false, - ), - ], - ), - ), - ), - const SizedBox(height: 24), + const _ExampleLabel(), Text( context.lang.onboardingUserDiscoveryWhoIsRequesting, style: TextStyle( @@ -214,9 +183,9 @@ class UserDiscoverySetupComp extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( - 'jane', - style: TextStyle( + Text( + context.lang.exampleJane, + style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 13, ), @@ -226,8 +195,8 @@ class UserDiscoverySetupComp extends StatelessWidget { children: buildFriendsListTextString( context, [ - 'mary', - 'james', + context.lang.exampleUserName2, + context.lang.exampleUserName1, ], ), style: const TextStyle(fontSize: 10), @@ -241,6 +210,47 @@ class UserDiscoverySetupComp extends StatelessWidget { ), ), ), + + const SizedBox(height: 24), + Text( + context.lang.onboardingUserDiscoveryContactsVerifiedBadge, + style: TextStyle( + color: context.color.onSurfaceVariant, + fontSize: 12, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 16), + Center( + child: Container( + width: 100, + height: 40, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey, width: 0.5), + borderRadius: BorderRadius.circular(12), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const AvatarIcon(fontSize: 12), + const SizedBox(width: 5), + Text( + context.lang.exampleJane, + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(width: 5), + const VerificationBadgeComp( + isVerifiedByTransferredTrust: true, + size: 14, + clickable: false, + ), + ], + ), + ), + ), + const SizedBox(height: 16), ], ), @@ -275,18 +285,15 @@ class UserDiscoverySetupComp extends StatelessWidget { SetupSwitchCard( value: state.sharePromotion, onChanged: (val) => state.update(() { - if (val) { - state.isUserDiscoveryEnabled = true; - } state.sharePromotion = val; }), title: context.lang.onboardingUserDiscoveryBeRecommended, - expandedChild: Padding( - padding: const EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Row( + expandedChild: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( children: [ Expanded( child: Text( @@ -319,121 +326,128 @@ class UserDiscoverySetupComp extends StatelessWidget { ), ], ), - const SizedBox(height: 16), - Text( - context.lang.onboardingUserDiscoveryWhatOthersSee, - style: TextStyle( - color: context.color.onSurfaceVariant, - fontSize: 12, - ), - textAlign: TextAlign.center, + ), + const Padding( + padding: EdgeInsets.only(bottom: 8, top: 8), + child: Divider(), + ), + const _ExampleLabel(), + Text( + context.lang.onboardingUserDiscoveryWhatOthersSee, + style: TextStyle( + color: context.color.onSurfaceVariant, + fontSize: 12, ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 6, - vertical: 3, - ), - decoration: BoxDecoration( - border: Border.all(color: Colors.grey, width: 0.5), - borderRadius: BorderRadius.circular(12), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const AvatarIcon(fontSize: 14), - const SizedBox(width: 5), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - userService.currentUser.username, - style: const TextStyle( - fontWeight: FontWeight.bold, - ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 3, + ), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey, width: 0.5), + borderRadius: BorderRadius.circular(12), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const AvatarIcon(fontSize: 14), + const SizedBox(width: 5), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + userService.currentUser.username, + style: const TextStyle( + fontWeight: FontWeight.bold, ), - RichText( - text: TextSpan( - children: buildFriendsListTextString( - context, - exampleUsers.sublist( - 0, - state.threshold, - ), + ), + RichText( + text: TextSpan( + children: buildFriendsListTextString( + context, + getExampleUsers(context).sublist( + 0, + state.threshold, ), - style: const TextStyle(fontSize: 11), ), + style: const TextStyle(fontSize: 11), ), - ], - ), + ), + ], ), - const MockContactSuggestedActionsComp(), - ], - ), + ), + const MockContactSuggestedActionsComp(), + ], ), ), - const SizedBox(height: 16), - Text( - context.lang.onboardingUserDiscoveryWhatYouSee, - style: TextStyle( - color: context.color.onSurfaceVariant, - fontSize: 12, - ), - textAlign: TextAlign.center, + ), + const SizedBox(height: 16), + Text( + context.lang.onboardingUserDiscoveryWhatYouSee, + style: TextStyle( + color: context.color.onSurfaceVariant, + fontSize: 12, ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 6, - vertical: 3, - ), - decoration: BoxDecoration( - border: Border.all(color: Colors.grey, width: 0.5), - borderRadius: BorderRadius.circular(12), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const AvatarIcon(fontSize: 14), - const SizedBox(width: 5), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text( - 'jane', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 13, - ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + ), + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 3, + ), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey, width: 0.5), + borderRadius: BorderRadius.circular(12), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const AvatarIcon(fontSize: 14), + const SizedBox(width: 5), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + context.lang.exampleJane, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 13, ), - RichText( - text: TextSpan( - children: buildFriendsListTextString( - context, - exampleUsers.sublist( - 0, - state.threshold, - ), + ), + RichText( + text: TextSpan( + children: buildFriendsListTextString( + context, + getExampleUsers(context).sublist( + 0, + state.threshold, ), - style: const TextStyle(fontSize: 10), ), + style: const TextStyle(fontSize: 10), ), - ], - ), + ), + ], ), - const MockContactRequestActionsComp(), - ], - ), + ), + const MockContactRequestActionsComp(), + ], ), ), - ], - ), + ), + const SizedBox(height: 16), + ], ), ), ], @@ -442,3 +456,28 @@ class UserDiscoverySetupComp extends StatelessWidget { ); } } + +class _ExampleLabel extends StatelessWidget { + const _ExampleLabel(); + + @override + Widget build(BuildContext context) { + return Align( + alignment: Alignment.centerRight, + child: Padding( + padding: const EdgeInsets.only(right: 12, bottom: 0), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey, width: 0.5), + borderRadius: BorderRadius.circular(12), + ), + child: Text( + context.lang.onboardingExampleLabel, + style: const TextStyle(fontSize: 10, color: Colors.white), + ), + ), + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index d43bc94a..378fba9a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: "twonly, a privacy-friendly way to connect with friends through sec publish_to: 'none' -version: 0.2.8+117 +version: 0.2.9+118 environment: sdk: ^3.11.0 diff --git a/rust/src/bridge/wrapper/user_discovery.rs b/rust/src/bridge/wrapper/user_discovery.rs index 175184dd..6c50a7f8 100644 --- a/rust/src/bridge/wrapper/user_discovery.rs +++ b/rust/src/bridge/wrapper/user_discovery.rs @@ -10,12 +10,16 @@ impl FlutterUserDiscovery { public_key: Vec, share_promotion: bool, ) -> Result<()> { - Ok(get_twonly_flutter()? - .user_discovery - .get() - .await + tracing::info!("Rust bridge: initialize_or_update started"); + let twonly = get_twonly_flutter()?; + tracing::info!("Rust bridge: getting user_discovery lock"); + let user_discovery = twonly.user_discovery.get().await; + tracing::info!("Rust bridge: calling initialize_or_update on protocols"); + let res = user_discovery .initialize_or_update(threshold, user_id, public_key, share_promotion) - .await?) + .await; + tracing::info!("Rust bridge: initialize_or_update on protocols finished"); + Ok(res?) } pub async fn get_current_version() -> Result> { diff --git a/rust_dependencies/protocols/src/user_discovery.rs b/rust_dependencies/protocols/src/user_discovery.rs index a7df228c..30675e55 100644 --- a/rust_dependencies/protocols/src/user_discovery.rs +++ b/rust_dependencies/protocols/src/user_discovery.rs @@ -91,7 +91,9 @@ impl UserDiscovery, share_promotion: bool, ) -> Result<()> { + tracing::info!("Protocols: initialize_or_update started, getting config_lock"); let config_lock = self.config_lock.lock().await; + tracing::info!("Protocols: got config_lock, getting config from store"); let mut config = match self.store.get_config().await { Ok(config) => { let mut config: UserDiscoveryConfig = serde_json::from_str(&config)?; @@ -113,10 +115,12 @@ impl UserDiscovery UserDiscovery