diff --git a/integration_test/features/02_global_settings/05_streamer.feature b/integration_test/features/02_global_settings/05_streamer.feature index 83bc153f..e69de29b 100644 --- a/integration_test/features/02_global_settings/05_streamer.feature +++ b/integration_test/features/02_global_settings/05_streamer.feature @@ -1,4 +0,0 @@ -@env:aliceandbob1 -Feature: Streamer mode setting hides onions - Scenario: Turning on streamer mode - Given \ No newline at end of file diff --git a/integration_test/features/04_profile_mgmt/01_create_delete.feature b/integration_test/features/04_profile_mgmt/01_create_delete.feature index c9825ed9..b085848f 100644 --- a/integration_test/features/04_profile_mgmt/01_create_delete.feature +++ b/integration_test/features/04_profile_mgmt/01_create_delete.feature @@ -1,3 +1,4 @@ +@env:persist Feature: Basic Profile Management Scenario: Error on Creating a Profile without a Display Name Given I wait until the widget with type 'ProfileMgrView' is present @@ -18,14 +19,18 @@ Feature: Basic Profile Management Then I tap the "passwordCheckBox" widget And I expect the text 'New Password' to be absent And I take a screenshot - Then I fill the "displayNameFormElement" field with "Alice (

hello

)" + Then I fill the "displayNameFormElement" field with "Alice (Unencrypted)" Then I tap the "button" widget with label "Add new profile" - And I expect a "ProfileRow" widget with text "Alice (

hello

)" + And I expect a "ProfileRow" widget with text "Alice (Unencrypted)" And I take a screenshot - Then I tap the "ProfileRow" widget with label "Alice (

hello

)" - And I expect the text 'Alice (

hello

) » Conversations' to be present + Then I tap the "ProfileRow" widget with label "Alice (Unencrypted)" + And I expect the text "Alice (Unencrypted) » Conversations" to be present And I take a screenshot + Scenario: Load Unencrypted Profile + Given I wait until the widget with type 'ProfileMgrView' is present + Then I expect a "ProfileRow" widget with text "Alice (Unencrypted)" + Scenario: Create Encrypted Profile Given I wait until the widget with type 'ProfileMgrView' is present And I tap the button with tooltip "Add new profile" @@ -41,4 +46,45 @@ Feature: Basic Profile Management And I take a screenshot Then I tap the "ProfileRow" widget with label "Alice (Encrypted)" And I expect the text 'Alice (Encrypted) » Conversations' to be present - And I take a screenshot \ No newline at end of file + And I take a screenshot + + Scenario: Load an Encrypted Profile by Unlocking it with a Password + Given I wait until the widget with type 'ProfileMgrView' is present + Then I expect the text 'Enter a password to view your profiles' to be absent + And I tap the button with tooltip "Unlock encrypted profiles by entering their password." + Then I expect the text 'Enter a password to view your profiles' to be present + When I fill the "unlockPasswordProfileElement" field with "password1" + And I tap the "button" widget with label "Unlock" + Then I expect a "ProfileRow" widget with text "Alice (Encrypted)" + + Scenario: Load an Encrypted Profile by Unlocking it with a Password and Change the Name + Given I wait until the widget with type 'ProfileMgrView' is present + Then I expect the text 'Enter a password to view your profiles' to be absent + And I tap the button with tooltip "Unlock encrypted profiles by entering their password." + Then I expect the text 'Enter a password to view your profiles' to be present + When I fill the "unlockPasswordProfileElement" field with "password1" + And I tap the "button" widget with label "Unlock" + Then I expect a "ProfileRow" widget with text "Alice (Encrypted)" + When I tap the "IconButton" widget with tooltip "Edit Profile Alice (Encrypted)" + Then I expect the text 'Display Name' to be present + Then I fill the "displayNameFormElement" field with "Carol (Encrypted)" + And I tap the "button" widget with label "Save Profile" + And I wait until the widget with type 'ProfileMgrView' is present + Then I expect a "ProfileRow" widget with text "Carol (Encrypted)" + + Scenario: Delete an Encrypted Profile + Given I wait until the widget with type 'ProfileMgrView' is present + Then I expect the text 'Enter a password to view your profiles' to be absent + And I tap the button with tooltip "Unlock encrypted profiles by entering their password." + Then I expect the text 'Enter a password to view your profiles' to be present + When I fill the "unlockPasswordProfileElement" field with "password1" + And I tap the "button" widget with label "Unlock" + Then I expect a "ProfileRow" widget with text "Carol (Encrypted)" + And I take a screenshot + When I tap the "IconButton" widget with tooltip "Edit Profile Carol (Encrypted)" + Then I expect the text 'Display Name' to be present + When I tap the button that contains the text "Delete" + Then I expect the text "Really Delete Profile" to be present + When I tap the "button" widget with label "Really Delete Profile" + And I wait until the widget with type 'ProfileMgrView' is present + Then I expect a "ProfileRow" widget with text "Carol (Encrypted)" to be absent diff --git a/integration_test/gherkin_suite_test.editable.dart b/integration_test/gherkin_suite_test.editable.dart index 6e38f100..6b235f95 100644 --- a/integration_test/gherkin_suite_test.editable.dart +++ b/integration_test/gherkin_suite_test.editable.dart @@ -38,7 +38,9 @@ void main() { // overrides TapWidgetWithType(), TapWidgetWithLabel(), + TapWidgetWithTooltip(), ExpectWidgetWithText(), + AbsentWidgetWithText(), WaitUntilTypeExists(), ExpectTextToBePresent(), ExpectWidgetWithTextWithin(), diff --git a/integration_test/steps/cwtch_profile_steps.dart b/integration_test/steps/cwtch_profile_steps.dart deleted file mode 100644 index e69de29b..00000000 diff --git a/integration_test/steps/overrides.dart b/integration_test/steps/overrides.dart index a9d647f4..48ce16f3 100644 --- a/integration_test/steps/overrides.dart +++ b/integration_test/steps/overrides.dart @@ -37,6 +37,22 @@ StepDefinitionGeneric TapWidgetWithLabel() { firstMatchOnly: true); //Text wdg = await context.world.appDriver.widget(finder, ExpectedWidgetResultType.first); //print(wdg.debugDescribeChildren().first.) + await context.world.appDriver.scrollIntoView(finder); + await context.world.appDriver.tap(finder); + await context.world.appDriver.waitForAppToSettle(); + }, + ); +} + +StepDefinitionGeneric TapWidgetWithTooltip() { + return given2( + RegExp(r'I tap the {string} widget with tooltip {string}$'), + (ofType, text, context) async { + final finder = context.world.appDriver.findByDescendant( + context.world.appDriver.findBy(widgetTypeByName(ofType), FindType.type), + context.world.appDriver.findBy(text, FindType.tooltip), + firstMatchOnly: true); + await context.world.appDriver.scrollIntoView(finder); await context.world.appDriver.tap(finder); await context.world.appDriver.waitForAppToSettle(); }, @@ -59,6 +75,23 @@ StepDefinitionGeneric ExpectWidgetWithText() { ); } +StepDefinitionGeneric AbsentWidgetWithText() { + return given2( + RegExp(r'I expect a {string} widget with text {string} to be absent$'), + (ofType, text, context) async { + final finder = context.world.appDriver.findByDescendant( + context.world.appDriver.findBy(widgetTypeByName(ofType), FindType.type), + context.world.appDriver.findBy(text, FindType.text), + firstMatchOnly: true); + //Text wdg = await context.world.appDriver.widget(finder, ExpectedWidgetResultType.first); + //print(wdg.debugDescribeChildren().first.) + await context.world.appDriver.isAbsent(finder); + await context.world.appDriver.waitForAppToSettle(); + }, + ); +} + + StepDefinitionGeneric TapButtonWithText() { return given1( RegExp(r'I tap the {string} (?:button|element|label|icon|field|text|widget)$'), @@ -67,8 +100,7 @@ StepDefinitionGeneric TapButtonWithText() { context.world.appDriver.findBy(Flwtch, FindType.type), context.world.appDriver.findBy(input1, FindType.key), firstMatchOnly: true); - //Text wdg = await context.world.appDriver.widget(finder, ExpectedWidgetResultType.first); - //print(wdg.debugDescribeChildren().first.) + await context.world.appDriver.scrollIntoView(finder); await context.world.appDriver.tap(finder); await context.world.appDriver.waitForAppToSettle(); }, @@ -229,6 +261,8 @@ Type widgetTypeByName(String input1) { return TorIcon; case "button": return ElevatedButton; + case "IconButton": + return IconButton; case "ProfileRow": return ProfileRow; default: diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb index ff53b0ac..5ac7c7d8 100644 --- a/lib/l10n/intl_de.arb +++ b/lib/l10n/intl_de.arb @@ -1,6 +1,6 @@ { "@@locale": "de", - "@@last_modified": "2022-01-18T00:38:14+01:00", + "@@last_modified": "2022-01-28T19:57:41+01:00", "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", "torSettingsEnableCache": "Cache Tor Consensus", "labelTorNetwork": "Tor Network", diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 0e1cb975..df6497f1 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1,6 +1,7 @@ { "@@locale": "en", - "@@last_modified": "2022-01-18T00:38:14+01:00", + "@@last_modified": "2022-01-28T19:57:41+01:00", + "editProfile": "Edit Profile", "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", "torSettingsEnableCache": "Cache Tor Consensus", "labelTorNetwork": "Tor Network", @@ -239,7 +240,6 @@ "radioNoPassword": "Unencrypted (No password)", "radioUsePassword": "Password", "copiedToClipboardNotification": "Copied to Clipboard", - "editProfile": "Edit Profille", "newProfile": "New Profile", "defaultProfileName": "Alice", "profileName": "Display name", diff --git a/lib/l10n/intl_es.arb b/lib/l10n/intl_es.arb index 81fd56f3..5f418b75 100644 --- a/lib/l10n/intl_es.arb +++ b/lib/l10n/intl_es.arb @@ -1,6 +1,6 @@ { "@@locale": "es", - "@@last_modified": "2022-01-18T00:38:14+01:00", + "@@last_modified": "2022-01-28T19:57:41+01:00", "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", "torSettingsEnableCache": "Cache Tor Consensus", "labelTorNetwork": "Tor Network", diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index 82f8c123..dd2c0544 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -1,22 +1,24 @@ { "@@locale": "fr", - "@@last_modified": "2022-01-18T00:38:14+01:00", - "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", - "torSettingsEnableCache": "Cache Tor Consensus", - "labelTorNetwork": "Tor Network", - "descriptionACNCircuitInfo": "In depth information about the path that the anonymous communication network is using to connect to this conversation.", - "labelACNCircuitInfo": "ACN Circuit Info", - "fileSharingSettingsDownloadFolderTooltip": "Browse to select a different default folder for downloaded files.", - "fileSharingSettingsDownloadFolderDescription": "When files are downloaded automatically (e.g. image files, when image previews are enabled) a default location to download the files to is needed.", - "torSettingsErrorSettingPort": "Port Number must be between 1 and 65535", - "torSettingsUseCustomTorServiceConfigurastionDescription": "Override the default tor configuration. Warning: This could be dangerous. Only turn this on if you know what you are doing.", - "torSettingsUseCustomTorServiceConfiguration": "Use a Custom Tor Service Configuration (torrc)", - "torSettingsCustomControlPortDescription": "Use a custom port for control connections to the Tor proxy", - "torSettingsCustomControlPort": "Custom Control Port", - "torSettingsCustomSocksPortDescription": "Use a custom port for data connections to the Tor proxy", - "torSettingsCustomSocksPort": "Custom SOCKS Port", - "torSettingsEnabledAdvancedDescription": "Use an existing Tor service on your system, or change the parameters of the Cwtch Tor Service", - "torSettingsEnabledAdvanced": "Enable Advanced Tor Configuration", + "@@last_modified": "2022-01-28T19:57:41+01:00", + "editProfile": "Modifier le profil", + "settingTheme": "Utilisez des thèmes clairs", + "torSettingsUseCustomTorServiceConfiguration": "Utiliser une configuration personnalisée du service Tor (torrc)", + "torSettingsUseCustomTorServiceConfigurastionDescription": "Remplacer la configuration par défaut de tor. Avertissement : Cela peut être dangereux. Ne l'activez que si vous savez ce que vous faites.", + "torSettingsErrorSettingPort": "Le numéro de port doit être compris entre 1 et 65535.", + "torSettingsEnableCache": "Cache du Consensus Tor", + "torSettingsEnabledCacheDescription": "Mettre en cache le consensus Tor actuellement téléchargé pour le réutiliser la prochaine fois que Cwtch est ouvert. Cela permettra à Tor de démarrer plus rapidement. Lorsqu'il est désactivé, Cwtch purgera les données mises en cache au démarrage.", + "torSettingsEnabledAdvancedDescription": "Utilisez un service Tor existant sur votre système ou modifiez les paramètres du service Tor de Cwtch.", + "torSettingsEnabledAdvanced": "Activer la configuration avancée de Tor", + "torSettingsCustomSocksPortDescription": "Utiliser un port personnalisé pour les connexions de données au proxy Tor", + "torSettingsCustomSocksPort": "Port SOCKS personnalisé", + "torSettingsCustomControlPortDescription": "Utiliser un port personnalisé pour contrôler les connexions au proxy Tor", + "torSettingsCustomControlPort": "Port de contrôle personnalisé", + "labelTorNetwork": "Réseau Tor", + "labelACNCircuitInfo": "Informations sur le circuit ACN", + "fileSharingSettingsDownloadFolderTooltip": "Parcourir pour sélectionner un autre dossier par défaut pour les fichiers téléchargés.", + "fileSharingSettingsDownloadFolderDescription": "Lorsque les fichiers sont téléchargés automatiquement (par exemple, les fichiers image, lorsque les aperçus d'image sont activés), un emplacement par défaut pour télécharger les fichiers est nécessaire.", + "descriptionACNCircuitInfo": "Informations détaillées sur le chemin que le réseau de communication anonyme utilise pour se connecter à cette conversation.", "msgConfirmSend": "Êtes-vous sûr de vouloir envoyer", "acceptGroupInviteLabel": "Voulez-vous accepter l'invitation au groupe de", "msgFileTooBig": "La taille du fichier ne peut pas dépasser 10 Go", @@ -187,7 +189,6 @@ "deleteConfirmLabel": "Tapez SUPPRIMER pour confirmer", "addNewProfileBtn": "Ajouter un nouveau profil", "enterProfilePassword": "Entrez un mot de passe pour consulter vos profils", - "editProfile": "Modifier le profil", "radioUsePassword": "Mot de passe", "radioNoPassword": "Non chiffré (pas de mot de passe)", "saveProfileBtn": "Sauvegarder le profil", @@ -205,7 +206,6 @@ "localePt": "Portugais", "localeDe": "Allemand", "settingInterfaceZoom": "Niveau de zoom", - "settingTheme": "Thème", "themeLight": "Clair", "themeDark": "Sombre", "experimentsEnabled": "Activer les expériences", diff --git a/lib/l10n/intl_it.arb b/lib/l10n/intl_it.arb index 2a69d62d..b94f3e24 100644 --- a/lib/l10n/intl_it.arb +++ b/lib/l10n/intl_it.arb @@ -1,6 +1,6 @@ { "@@locale": "it", - "@@last_modified": "2022-01-18T00:38:14+01:00", + "@@last_modified": "2022-01-28T19:57:41+01:00", "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", "torSettingsEnableCache": "Cache Tor Consensus", "labelTorNetwork": "Tor Network", diff --git a/lib/l10n/intl_pl.arb b/lib/l10n/intl_pl.arb index 882e91de..3866a59b 100644 --- a/lib/l10n/intl_pl.arb +++ b/lib/l10n/intl_pl.arb @@ -1,6 +1,6 @@ { "@@locale": "pl", - "@@last_modified": "2022-01-18T00:38:14+01:00", + "@@last_modified": "2022-01-28T19:57:41+01:00", "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", "torSettingsEnableCache": "Cache Tor Consensus", "labelTorNetwork": "Tor Network", diff --git a/lib/l10n/intl_pt.arb b/lib/l10n/intl_pt.arb index fa60f581..41142267 100644 --- a/lib/l10n/intl_pt.arb +++ b/lib/l10n/intl_pt.arb @@ -1,6 +1,6 @@ { "@@locale": "pt", - "@@last_modified": "2022-01-18T00:38:14+01:00", + "@@last_modified": "2022-01-28T19:57:41+01:00", "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", "torSettingsEnableCache": "Cache Tor Consensus", "labelTorNetwork": "Tor Network", @@ -227,7 +227,7 @@ "radioNoPassword": "Unencrypted (No password)", "radioUsePassword": "Password", "copiedToClipboardNotification": "Copiado", - "editProfile": "Edit Profille", + "editProfile": "Edit Profile", "newProfile": "New Profile", "defaultProfileName": "Alice", "profileName": "Display name", diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb index 4ea0b04e..5357f2cb 100644 --- a/lib/l10n/intl_ru.arb +++ b/lib/l10n/intl_ru.arb @@ -1,6 +1,6 @@ { "@@locale": "ru", - "@@last_modified": "2022-01-18T00:38:14+01:00", + "@@last_modified": "2022-01-28T19:57:41+01:00", "torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.", "torSettingsEnableCache": "Cache Tor Consensus", "labelTorNetwork": "Tor Network", diff --git a/lib/main.dart b/lib/main.dart index 21b1a01f..f6174247 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -37,7 +37,7 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); print("runApp()"); runApp(Flwtch()); - sleep(Duration(seconds:1)); + sleep(Duration(seconds: 1)); } class Flwtch extends StatefulWidget { diff --git a/lib/models/remoteserver.dart b/lib/models/remoteserver.dart index f9e658dd..2af03cd4 100644 --- a/lib/models/remoteserver.dart +++ b/lib/models/remoteserver.dart @@ -34,7 +34,7 @@ class RemoteServerInfoState extends ChangeNotifier { if (status == "Authenticated") { // syncing, set lastPreSyncMessageTime _groups.forEach((g) { - if(g.lastMessageTime.isAfter(lastPreSyncMessagTime)) { + if (g.lastMessageTime.isAfter(lastPreSyncMessagTime)) { lastPreSyncMessagTime = g.lastMessageTime; } }); @@ -52,4 +52,4 @@ class RemoteServerInfoState extends ChangeNotifier { } List get groups => _groups.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier -} \ No newline at end of file +} diff --git a/lib/themes/opaque.dart b/lib/themes/opaque.dart index ea219674..b71f655e 100644 --- a/lib/themes/opaque.dart +++ b/lib/themes/opaque.dart @@ -183,7 +183,11 @@ ThemeData mkThemeData(Settings opaque) { scrollbarTheme: ScrollbarThemeData(isAlwaysShown: false, thumbColor: MaterialStateProperty.all(opaque.current().scrollbarDefaultColor)), tabBarTheme: TabBarTheme(indicator: UnderlineTabIndicator(borderSide: BorderSide(color: opaque.current().defaultButtonActiveColor))), dialogTheme: DialogTheme( - backgroundColor: opaque.current().backgroundPaneColor, titleTextStyle: TextStyle(color: opaque.current().mainTextColor), contentTextStyle: TextStyle(color: opaque.current().mainTextColor)), + backgroundColor: opaque.current().backgroundPaneColor, + titleTextStyle: TextStyle(color: opaque.current().mainTextColor), + contentTextStyle: TextStyle( + color: opaque.current().mainTextColor, + )), textTheme: TextTheme( headline1: TextStyle(color: opaque.current().mainTextColor), headline2: TextStyle(color: opaque.current().mainTextColor), diff --git a/lib/views/addeditprofileview.dart b/lib/views/addeditprofileview.dart index 01f3b2c0..9841712b 100644 --- a/lib/views/addeditprofileview.dart +++ b/lib/views/addeditprofileview.dart @@ -186,13 +186,13 @@ class _AddEditProfileViewState extends State { autoFillHints: [AutofillHints.newPassword], validator: (value) { // Password field can be empty when just updating the profile, not on creation - if (Provider.of(context).isEncrypted && + if (Provider.of(context, listen: false).isEncrypted && Provider.of(context, listen: false).onion.isEmpty && value.isEmpty && usePassword) { return AppLocalizations.of(context)!.passwordErrorEmpty; } - if (Provider.of(context).deleteProfileError == true) { + if (Provider.of(context, listen: false).deleteProfileError == true) { return AppLocalizations.of(context)!.enterCurrentPasswordForDelete; } return null; diff --git a/lib/views/contactsview.dart b/lib/views/contactsview.dart index 7f6b2236..9bc2f28d 100644 --- a/lib/views/contactsview.dart +++ b/lib/views/contactsview.dart @@ -163,7 +163,7 @@ class _ContactsViewState extends State { builder: (context, child) => RepaintBoundary(child: ContactRow()), ); }); - + final divided = ListTile.divideTiles( context: context, tiles: tiles, diff --git a/lib/views/globalsettingsview.dart b/lib/views/globalsettingsview.dart index f4cec611..5b733587 100644 --- a/lib/views/globalsettingsview.dart +++ b/lib/views/globalsettingsview.dart @@ -107,7 +107,7 @@ class _GlobalSettingsViewState extends State { items: themes.keys.map>((String themeId) { return DropdownMenuItem( value: themeId, - child: Text("ddi_$themeId",key: Key("ddi_$themeId")),//getThemeName(context, themeId)), + child: Text("ddi_$themeId", key: Key("ddi_$themeId")), //getThemeName(context, themeId)), ); }).toList()), leading: Icon(CwtchIcons.change_theme, color: settings.current().mainTextColor), diff --git a/lib/views/profilemgrview.dart b/lib/views/profilemgrview.dart index 1782459c..f22de587 100644 --- a/lib/views/profilemgrview.dart +++ b/lib/views/profilemgrview.dart @@ -108,7 +108,12 @@ class _ProfileMgrViewState extends State { } // Global Settings - actions.add(IconButton(key: Key("OpenSettingsView"), icon: Icon(Icons.settings), tooltip: AppLocalizations.of(context)!.tooltipOpenSettings, splashRadius: Material.defaultSplashRadius / 2, onPressed: _pushGlobalSettings)); + actions.add(IconButton( + key: Key("OpenSettingsView"), + icon: Icon(Icons.settings), + tooltip: AppLocalizations.of(context)!.tooltipOpenSettings, + splashRadius: Material.defaultSplashRadius / 2, + onPressed: _pushGlobalSettings)); // shutdown cwtch actions.add(IconButton(icon: Icon(Icons.close), tooltip: AppLocalizations.of(context)!.shutdownCwtchTooltip, splashRadius: Material.defaultSplashRadius / 2, onPressed: _modalShutdown)); @@ -191,6 +196,7 @@ class _ProfileMgrViewState extends State { height: 20, ), CwtchPasswordField( + key: Key("unlockPasswordProfileElement"), autofocus: true, controller: ctrlrPassword, action: unlock, diff --git a/lib/widgets/buttontextfield.dart b/lib/widgets/buttontextfield.dart index ecd2631f..dd695de2 100644 --- a/lib/widgets/buttontextfield.dart +++ b/lib/widgets/buttontextfield.dart @@ -5,7 +5,16 @@ import 'package:provider/provider.dart'; // Provides a styled Text Field for use in Form Widgets. // Callers must provide a text controller, label helper text and a validator. class CwtchButtonTextField extends StatefulWidget { - CwtchButtonTextField({required this.controller, required this.onPressed, required this.icon, required this.tooltip, this.readonly = true, this.labelText, this.testKey, this.onChanged,}); + CwtchButtonTextField({ + required this.controller, + required this.onPressed, + required this.icon, + required this.tooltip, + this.readonly = true, + this.labelText, + this.testKey, + this.onChanged, + }); final TextEditingController controller; final Function()? onPressed; final Function(String)? onChanged; diff --git a/lib/widgets/messagerow.dart b/lib/widgets/messagerow.dart index 4b109d12..354bb46a 100644 --- a/lib/widgets/messagerow.dart +++ b/lib/widgets/messagerow.dart @@ -80,7 +80,7 @@ class MessageRowState extends State with SingleTickerProviderStateMi Widget wdgIcons = Platform.isAndroid ? SizedBox.shrink() : Visibility( - visible: true,//Provider.of(context).hoveredIndex == Provider.of(context).messageID, + visible: true, //Provider.of(context).hoveredIndex == Provider.of(context).messageID, maintainSize: true, maintainAnimation: true, maintainState: true, diff --git a/lib/widgets/profilerow.dart b/lib/widgets/profilerow.dart index acbdce0a..1ab6e273 100644 --- a/lib/widgets/profilerow.dart +++ b/lib/widgets/profilerow.dart @@ -89,10 +89,7 @@ class _ProfileRowState extends State { builder: (BuildContext buildcontext) { return OrientationBuilder(builder: (orientationBuilderContext, orientation) { return MultiProvider( - providers: [ - ChangeNotifierProvider.value(value: profile), - ChangeNotifierProvider.value(value: profile.contactList) - ], + providers: [ChangeNotifierProvider.value(value: profile), ChangeNotifierProvider.value(value: profile.contactList)], builder: (innercontext, widget) { var appState = Provider.of(context); var settings = Provider.of(context);