Accessibility, Tooltips and better Strings
continuous-integration/drone/pr Build is passing
Details
continuous-integration/drone/pr Build is passing
Details
This commit is contained in:
parent
9448529061
commit
e1b9b0b3c1
|
@ -44,6 +44,9 @@
|
|||
"deleteConfirmText": "LÖSCHEN",
|
||||
"deleteProfileBtn": "Profil löschen",
|
||||
"deleteProfileConfirmBtn": "Profil wirklich löschen",
|
||||
"descriptionBlockUnknownConnections": "",
|
||||
"descriptionExperiments": "",
|
||||
"descriptionExperimentsGroups": "",
|
||||
"displayNameLabel": "Angezeigter Name",
|
||||
"dmTooltip": "Klicken, um DM zu senden",
|
||||
"dontSavePeerHistory": "Peer-Verlauf löschen",
|
||||
|
@ -122,8 +125,13 @@
|
|||
"smallTextLabel": "Klein",
|
||||
"themeDark": "Dunkel",
|
||||
"themeLight": "Licht",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titlePlaceholder": "Titel...",
|
||||
"todoPlaceholder": "noch zu erledigen",
|
||||
"tooltipAddContact": "",
|
||||
"tooltipOpenSettings": "",
|
||||
"tooltipUnlockProfiles": "",
|
||||
"unblockBtn": "Peer entblockieren",
|
||||
"unlock": "Entsperren",
|
||||
"update": "",
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
"deleteConfirmText": "DELETE",
|
||||
"deleteProfileBtn": "Delete Profile",
|
||||
"deleteProfileConfirmBtn": "Really Delete Profile",
|
||||
"descriptionBlockUnknownConnections": "If turned on, this option will automatically close connections from Cwtch users that have not been added to your contact list.",
|
||||
"descriptionExperiments": "Cwtch experiments are optional, opt-in features that add additional functionality to Cwtch that may have different privacy considerations than traditional 1:1 metadata resistant chat e.g. group chat, bot integration etc.",
|
||||
"descriptionExperimentsGroups": "The group experiment allows Cwtch to connect with untrusted server infrastructure to facilitate communication with more than one contact.",
|
||||
"displayNameLabel": "Display Name",
|
||||
"dmTooltip": "Click to DM",
|
||||
"dontSavePeerHistory": "Delete Peer History",
|
||||
|
@ -89,7 +92,7 @@
|
|||
"passwordChangeError": "Error changing password: Supplied password rejected",
|
||||
"passwordErrorEmpty": "Password cannot be empty",
|
||||
"passwordErrorMatch": "Passwords do not match",
|
||||
"pasteAddressToAddContact": "... paste an address here to add a contact...",
|
||||
"pasteAddressToAddContact": "Paste a cwtch address here to add a new contact.",
|
||||
"peerAddress": "Address",
|
||||
"peerBlockedMessage": "Peer is blocked",
|
||||
"peerName": "Name",
|
||||
|
@ -122,8 +125,13 @@
|
|||
"smallTextLabel": "Small",
|
||||
"themeDark": "Dark",
|
||||
"themeLight": "Light",
|
||||
"titleManageContacts": "Manage Contacts",
|
||||
"titleManageProfiles": "Manage Cwtch Profiles",
|
||||
"titlePlaceholder": "title...",
|
||||
"todoPlaceholder": "Todo...",
|
||||
"tooltipAddContact": "Add a new contact",
|
||||
"tooltipOpenSettings": "Open the settings pane",
|
||||
"tooltipUnlockProfiles": "Unlock encrypted profiles by entering their password.",
|
||||
"unblockBtn": "Unblock Peer",
|
||||
"unlock": "Unlock",
|
||||
"update": "Update",
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
"deleteConfirmText": "ELIMINAR",
|
||||
"deleteProfileBtn": "Eliminar Perfil",
|
||||
"deleteProfileConfirmBtn": "Confirmar eliminar perfil",
|
||||
"descriptionBlockUnknownConnections": "",
|
||||
"descriptionExperiments": "",
|
||||
"descriptionExperimentsGroups": "",
|
||||
"displayNameLabel": "Nombre de Usuario",
|
||||
"dmTooltip": "Haz clic para enviar mensaje directo",
|
||||
"dontSavePeerHistory": "Eliminar historial de contacto",
|
||||
|
@ -89,7 +92,7 @@
|
|||
"passwordChangeError": "Hubo un error cambiando tu contraseña: la contraseña ingresada fue rechazada",
|
||||
"passwordErrorEmpty": "El campo de contraseña no puede estar vacío",
|
||||
"passwordErrorMatch": "Las contraseñas no coinciden",
|
||||
"pasteAddressToAddContact": "...pegar una dirección aquí para añadir un contacto...",
|
||||
"pasteAddressToAddContact": "...pegar una dirección aquí para añadir contacto...",
|
||||
"peerAddress": "Dirección",
|
||||
"peerBlockedMessage": "Contacto bloqueado",
|
||||
"peerName": "Nombre",
|
||||
|
@ -122,8 +125,13 @@
|
|||
"smallTextLabel": "Pequeño",
|
||||
"themeDark": "Oscuro",
|
||||
"themeLight": "Claro",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titlePlaceholder": "título...",
|
||||
"todoPlaceholder": "Por hacer...",
|
||||
"tooltipAddContact": "",
|
||||
"tooltipOpenSettings": "",
|
||||
"tooltipUnlockProfiles": "",
|
||||
"unblockBtn": "Desbloquear contacto",
|
||||
"unlock": "Desbloquear",
|
||||
"update": "Actualizar",
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
"deleteConfirmText": "",
|
||||
"deleteProfileBtn": "",
|
||||
"deleteProfileConfirmBtn": "",
|
||||
"descriptionBlockUnknownConnections": "",
|
||||
"descriptionExperiments": "",
|
||||
"descriptionExperimentsGroups": "",
|
||||
"displayNameLabel": "Pseudo",
|
||||
"dmTooltip": "Envoyer un message privé",
|
||||
"dontSavePeerHistory": "",
|
||||
|
@ -122,8 +125,13 @@
|
|||
"smallTextLabel": "Petit",
|
||||
"themeDark": "",
|
||||
"themeLight": "",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titlePlaceholder": "titre...",
|
||||
"todoPlaceholder": "A faire...",
|
||||
"tooltipAddContact": "",
|
||||
"tooltipOpenSettings": "",
|
||||
"tooltipUnlockProfiles": "",
|
||||
"unblockBtn": "",
|
||||
"unlock": "",
|
||||
"update": "",
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
"deleteConfirmText": "ELIMINA",
|
||||
"deleteProfileBtn": "Elimina profilo",
|
||||
"deleteProfileConfirmBtn": "Elimina realmente il profilo",
|
||||
"descriptionBlockUnknownConnections": "",
|
||||
"descriptionExperiments": "",
|
||||
"descriptionExperimentsGroups": "",
|
||||
"displayNameLabel": "Nome visualizzato",
|
||||
"dmTooltip": "Clicca per inviare un Messagio Diretto",
|
||||
"dontSavePeerHistory": "Elimina cronologia dei peer",
|
||||
|
@ -89,7 +92,7 @@
|
|||
"passwordChangeError": "Errore durante la modifica della password: password fornita rifiutata",
|
||||
"passwordErrorEmpty": "La password non può essere vuota",
|
||||
"passwordErrorMatch": "Le password non corrispondono",
|
||||
"pasteAddressToAddContact": "... incolla qui un indirizzo per aggiungere un contatto ...",
|
||||
"pasteAddressToAddContact": "... incolla qui un indirizzo per aggiungere un contatto...",
|
||||
"peerAddress": "Indirizzo",
|
||||
"peerBlockedMessage": "Il peer è bloccato",
|
||||
"peerName": "Nome",
|
||||
|
@ -122,8 +125,13 @@
|
|||
"smallTextLabel": "Piccolo",
|
||||
"themeDark": "Scuro",
|
||||
"themeLight": "Chiaro",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titlePlaceholder": "titolo...",
|
||||
"todoPlaceholder": "Da fare...",
|
||||
"tooltipAddContact": "",
|
||||
"tooltipOpenSettings": "",
|
||||
"tooltipUnlockProfiles": "",
|
||||
"unblockBtn": "Sblocca il peer",
|
||||
"unlock": "Sblocca",
|
||||
"update": "Aggiornamento",
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
"deleteConfirmText": "",
|
||||
"deleteProfileBtn": "",
|
||||
"deleteProfileConfirmBtn": "",
|
||||
"descriptionBlockUnknownConnections": "",
|
||||
"descriptionExperiments": "",
|
||||
"descriptionExperimentsGroups": "",
|
||||
"displayNameLabel": "Nome de Exibição",
|
||||
"dmTooltip": "Clique para DM",
|
||||
"dontSavePeerHistory": "",
|
||||
|
@ -122,8 +125,13 @@
|
|||
"smallTextLabel": "Pequeno",
|
||||
"themeDark": "",
|
||||
"themeLight": "",
|
||||
"titleManageContacts": "",
|
||||
"titleManageProfiles": "",
|
||||
"titlePlaceholder": "título…",
|
||||
"todoPlaceholder": "Afazer…",
|
||||
"tooltipAddContact": "",
|
||||
"tooltipOpenSettings": "",
|
||||
"tooltipUnlockProfiles": "",
|
||||
"unblockBtn": "",
|
||||
"unlock": "",
|
||||
"update": "",
|
||||
|
|
|
@ -19,6 +19,8 @@ class Settings extends ChangeNotifier {
|
|||
bool experimentsEnabled;
|
||||
HashMap<String, bool> experiments = HashMap.identity();
|
||||
|
||||
bool blockUnknownConnections;
|
||||
|
||||
/// Set the dark theme.
|
||||
void setDark() {
|
||||
theme = Opaque.dark;
|
||||
|
@ -49,6 +51,9 @@ class Settings extends ChangeNotifier {
|
|||
// Set Locale and notify listeners
|
||||
switchLocale(Locale(settings["Locale"]));
|
||||
|
||||
// Decide whether to enable Experiments
|
||||
blockUnknownConnections = settings["BlockUnknownConnections"];
|
||||
|
||||
// Decide whether to enable Experiments
|
||||
experimentsEnabled = settings["ExperimentsEnabled"];
|
||||
|
||||
|
@ -67,12 +72,28 @@ class Settings extends ChangeNotifier {
|
|||
});
|
||||
}
|
||||
|
||||
// Switch the Locale of the App
|
||||
/// Switch the Locale of the App
|
||||
switchLocale(Locale newLocale) {
|
||||
locale = newLocale;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Block Unknown Connections will autoblock connections if they authenticate with public key not in our contacts list.
|
||||
/// This is one of the best tools we have to combat abuse, while it isn't ideal it does allow a user to curate their contacts
|
||||
/// list without being bothered by spurious requests (either permanently, or as a short term measure).
|
||||
/// Note: This is not an *appear offline* setting which would explicitly close the listen port, rather than simply auto disconnecting unknown attempts.
|
||||
forbidUnknownConnections() {
|
||||
blockUnknownConnections = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Allow Unknown Connections will allow new contact requires from unknown public keys
|
||||
/// See above for more information.
|
||||
allowUnknownConnections() {
|
||||
blockUnknownConnections = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Turn Experiments On, this will also have the side effect of enabling any
|
||||
/// Experiments that have been previously activated.
|
||||
enableExperiments() {
|
||||
|
@ -113,6 +134,7 @@ class Settings extends ChangeNotifier {
|
|||
"Locale": this.locale.languageCode,
|
||||
"Theme": themeString,
|
||||
"PreviousPid": -1,
|
||||
"BlockUnknownConnections": blockUnknownConnections,
|
||||
"ExperimentsEnabled": this.experimentsEnabled,
|
||||
"Experiments": experiments,
|
||||
"StateRootPane": 0,
|
||||
|
|
|
@ -32,7 +32,7 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context).newConnectionPaneTitle),
|
||||
title: Text(AppLocalizations.of(context).titleManageContacts),
|
||||
),
|
||||
body: _buildForm(),
|
||||
);
|
||||
|
@ -40,6 +40,7 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
|
||||
Widget _buildForm() {
|
||||
ctrlrOnion.text = Provider.of<ProfileInfoState>(context).onion;
|
||||
|
||||
/// We display a different number of tabs dependening on the experiment setup
|
||||
bool groupsEnabled = Provider.of<Settings>(context).experimentsEnabled && Provider.of<Settings>(context).experiments[TapirGroupsExperiment];
|
||||
return Consumer<ErrorHandler>(builder: (context, globalErrorHandler, child) {
|
||||
|
@ -116,14 +117,14 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
CwtchTextField(
|
||||
controller: ctrlrContact,
|
||||
validator: (value) {
|
||||
if (value == "") {
|
||||
if (value == "") {
|
||||
return null;
|
||||
} if (globalErrorHandler.invalidImportStringError) {
|
||||
}
|
||||
if (globalErrorHandler.invalidImportStringError) {
|
||||
return AppLocalizations.of(context).invalidImportString;
|
||||
} else if (globalErrorHandler.contactAlreadyExistsError) {
|
||||
return AppLocalizations.of(context).contactAlreadyExists;
|
||||
} else if (globalErrorHandler.explicitAddContactSuccess) {
|
||||
}
|
||||
} else if (globalErrorHandler.explicitAddContactSuccess) {}
|
||||
return null;
|
||||
},
|
||||
onChanged: (String peerAddr) async {
|
||||
|
|
|
@ -29,7 +29,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _pushAddContact,
|
||||
tooltip: AppLocalizations.of(context).newConnectionPaneTitle,
|
||||
tooltip: AppLocalizations.of(context).tooltipAddContact,
|
||||
child: const Icon(Icons.person_add_sharp),
|
||||
),
|
||||
body: _buildContactList(),
|
||||
|
|
|
@ -74,8 +74,25 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
},
|
||||
secondary: Icon(Icons.lightbulb_outline, color: settings.current().mainTextColor()),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context).blockUnknownLabel, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
subtitle: Text(AppLocalizations.of(context).descriptionBlockUnknownConnections),
|
||||
value: settings.blockUnknownConnections,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.forbidUnknownConnections();
|
||||
} else {
|
||||
settings.allowUnknownConnections();
|
||||
}
|
||||
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
secondary: Icon(Icons.app_blocking, color: settings.current().mainTextColor()),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context).experimentsEnabled, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
subtitle: Text(AppLocalizations.of(context).descriptionExperiments),
|
||||
value: settings.experimentsEnabled,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
|
@ -94,6 +111,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
children: [
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context).enableGroups, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
subtitle: Text(AppLocalizations.of(context).descriptionExperimentsGroups),
|
||||
value: settings.experiments.containsKey(TapirGroupsExperiment) && settings.experiments[TapirGroupsExperiment],
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
|
|
|
@ -29,20 +29,24 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context).profileName),
|
||||
title: Text(AppLocalizations.of(context).titleManageProfiles),
|
||||
actions: [
|
||||
IconButton(icon: Icon(Icons.bug_report_outlined), onPressed: _setLoggingLevelDebug),
|
||||
IconButton(
|
||||
icon: Icon(Icons.lock_open),
|
||||
tooltip: AppLocalizations.of(context).tooltipUnlockProfiles,
|
||||
onPressed: _modalUnlockProfiles,
|
||||
),
|
||||
IconButton(icon: Icon(Icons.settings), onPressed: _pushGlobalSettings),
|
||||
IconButton(icon: Icon(Icons.settings), tooltip: AppLocalizations.of(context).tooltipOpenSettings, onPressed: _pushGlobalSettings),
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _pushAddEditProfile,
|
||||
tooltip: AppLocalizations.of(context).addNewProfileBtn,
|
||||
child: const Icon(Icons.add),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
semanticLabel: AppLocalizations.of(context).addNewProfileBtn,
|
||||
),
|
||||
),
|
||||
body: _buildProfileManager(), //_buildSuggestions(),
|
||||
);
|
||||
|
@ -105,7 +109,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
child: Text(AppLocalizations.of(context).unlock),
|
||||
child: Text(AppLocalizations.of(context).unlock, semanticsLabel: AppLocalizations.of(context).unlock),
|
||||
onPressed: () {
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.LoadProfiles(ctrlrPassword.value.text);
|
||||
Navigator.pop(context);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_app/views/addeditprofileview.dart';
|
||||
import 'package:flutter_app/views/contactsview.dart';
|
||||
import 'package:flutter_app/views/doublecolview.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../model.dart';
|
||||
|
@ -30,23 +32,30 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
width: 60,
|
||||
height: 60,
|
||||
child: Image(
|
||||
excludeFromSemantics: true,
|
||||
image: AssetImage("assets/" + profile.imagePath),
|
||||
width: 50,
|
||||
height: 50,
|
||||
))),
|
||||
),
|
||||
),
|
||||
|
||||
title: Text(
|
||||
profile.nickname,
|
||||
semanticsLabel: profile.nickname,
|
||||
style: Provider.of<FlwtchState>(context).biggerFont,
|
||||
),
|
||||
subtitle: ExcludeSemantics(child: Text(profile.onion)),
|
||||
|
||||
trailing: IconButton(
|
||||
enableFeedback: true,
|
||||
tooltip: AppLocalizations.of(context).editProfile + " " + profile.nickname,
|
||||
icon: Icon(Icons.create, color: Provider.of<Settings>(context).current().mainTextColor()),
|
||||
onPressed: () {
|
||||
_pushAddEditProfile(onion: profile.onion, displayName: profile.nickname, profileImage: profile.imagePath);
|
||||
},
|
||||
), //(nb: Icons.create is a pencil and we use it for "edit", not create)
|
||||
title: Text(
|
||||
profile.nickname,
|
||||
style: Provider.of<FlwtchState>(context).biggerFont,
|
||||
),
|
||||
subtitle: Text(profile.onion),
|
||||
|
||||
onTap: () {
|
||||
setState(() {
|
||||
var flwtch = Provider.of<FlwtchState>(context, listen: false);
|
||||
|
|
Loading…
Reference in New Issue