android-fix #302

Merged
erinn merged 3 commits from android-fix into trunk 2022-01-13 00:55:20 +00:00
6 changed files with 160 additions and 171 deletions

View File

@ -89,7 +89,8 @@ dependencies {
implementation project(':cwtch')
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.2"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2"
implementation "com.airbnb.android:lottie:3.5.0"
implementation "com.airbnb.android:lottie:4.2.1"
implementation "androidx.localbroadcastmanager:localbroadcastmanager:1.0.0"
implementation "com.android.support.constraint:constraint-layout:2.0.4"
// WorkManager

View File

@ -2,7 +2,8 @@ buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
// jCenter() no longer exists... https://blog.gradle.org/jcenter-shutdown
mavenCentral()
}
dependencies {
@ -15,7 +16,7 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

View File

@ -52,26 +52,22 @@ class _AddContactViewState extends State<AddContactView> {
/// We display a different number of tabs depending on the experiment setup
bool groupsEnabled = Provider.of<Settings>(context).isExperimentEnabled(TapirGroupsExperiment);
return Scrollbar(
isAlwaysShown: true,
child: SingleChildScrollView(
clipBehavior: Clip.antiAlias,
child: Consumer<ErrorHandler>(builder: (context, globalErrorHandler, child) {
return DefaultTabController(
length: groupsEnabled ? 2 : 1,
child: Column(children: [
(groupsEnabled ? getTabBarWithGroups() : getTabBarWithAddPeerOnly()),
Expanded(
child: TabBarView(
children: (groupsEnabled
? [
addPeerTab(),
addGroupTab(),
]
: [addPeerTab()]),
)),
]));
})));
return Consumer<ErrorHandler>(builder: (context, globalErrorHandler, child) {
return DefaultTabController(
length: groupsEnabled ? 2 : 1,
child: Column(children: [
(groupsEnabled ? getTabBarWithGroups() : getTabBarWithAddPeerOnly()),
Expanded(
child: TabBarView(
children: (groupsEnabled
? [
addPeerTab(),
addGroupTab(),
]
: [addPeerTab()]),
)),
]));
});
}
void _copyOnion() {
@ -109,67 +105,70 @@ class _AddContactViewState extends State<AddContactView> {
/// The Add Peer Tab allows a peer to add a specific non-group peer to their contact lists
/// We also provide a convenient way to copy their onion.
Widget addPeerTab() {
return Container(
margin: EdgeInsets.all(30),
padding: EdgeInsets.all(20),
child: Form(
autovalidateMode: AutovalidateMode.always,
key: _formKey,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
CwtchLabel(label: AppLocalizations.of(context)!.profileOnionLabel),
SizedBox(
height: 20,
),
CwtchButtonTextField(
controller: ctrlrOnion,
onPressed: _copyOnion,
readonly: true,
icon: Icon(
CwtchIcons.address_copy_2,
size: 32,
),
tooltip: AppLocalizations.of(context)!.copyBtn,
),
SizedBox(
height: 20,
),
CwtchLabel(label: AppLocalizations.of(context)!.pasteAddressToAddContact),
SizedBox(
height: 20,
),
CwtchTextField(
controller: ctrlrContact,
validator: (value) {
if (value == "") {
return null;
}
if (globalErrorHandler.invalidImportStringError) {
return AppLocalizations.of(context)!.invalidImportString;
} else if (globalErrorHandler.contactAlreadyExistsError) {
return AppLocalizations.of(context)!.contactAlreadyExists;
} else if (globalErrorHandler.explicitAddContactSuccess) {}
return null;
},
onChanged: (String importBundle) async {
var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.ImportBundle(profileOnion, importBundle);
return Scrollbar(
child: SingleChildScrollView(
clipBehavior: Clip.antiAlias,
child: Container(
margin: EdgeInsets.all(30),
padding: EdgeInsets.all(20),
child: Form(
autovalidateMode: AutovalidateMode.always,
key: _formKey,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
CwtchLabel(label: AppLocalizations.of(context)!.profileOnionLabel),
SizedBox(
height: 20,
),
CwtchButtonTextField(
controller: ctrlrOnion,
onPressed: _copyOnion,
readonly: true,
icon: Icon(
CwtchIcons.address_copy_2,
size: 32,
),
tooltip: AppLocalizations.of(context)!.copyBtn,
),
SizedBox(
height: 20,
),
CwtchLabel(label: AppLocalizations.of(context)!.pasteAddressToAddContact),
SizedBox(
height: 20,
),
CwtchTextField(
controller: ctrlrContact,
validator: (value) {
if (value == "") {
return null;
}
if (globalErrorHandler.invalidImportStringError) {
return AppLocalizations.of(context)!.invalidImportString;
} else if (globalErrorHandler.contactAlreadyExistsError) {
return AppLocalizations.of(context)!.contactAlreadyExists;
} else if (globalErrorHandler.explicitAddContactSuccess) {}
return null;
},
onChanged: (String importBundle) async {
var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.ImportBundle(profileOnion, importBundle);
Future.delayed(const Duration(milliseconds: 500), () {
if (globalErrorHandler.importBundleSuccess) {
// TODO: This isn't ideal, but because onChange can be fired during this future check
// and because the context can change after being popped we have this kind of double assertion...
// There is probably a better pattern to handle this...
if (AppLocalizations.of(context) != null) {
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.successfullAddedContact + importBundle));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Navigator.popUntil(context, (route) => route.settings.name == "conversations");
}
}
});
},
hintText: '',
)
])));
Future.delayed(const Duration(milliseconds: 500), () {
if (globalErrorHandler.importBundleSuccess) {
// TODO: This isn't ideal, but because onChange can be fired during this future check
// and because the context can change after being popped we have this kind of double assertion...
// There is probably a better pattern to handle this...
if (AppLocalizations.of(context) != null) {
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.successfullAddedContact + importBundle));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Navigator.popUntil(context, (route) => route.settings.name == "conversations");
}
}
});
},
hintText: '',
)
])))));
}
/// TODO Add Group Pane
@ -179,71 +178,74 @@ class _AddContactViewState extends State<AddContactView> {
return Text(AppLocalizations.of(context)!.addServerFirst);
}
return Container(
margin: EdgeInsets.all(30),
padding: EdgeInsets.all(20),
child: Form(
autovalidateMode: AutovalidateMode.always,
key: _createGroupFormKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CwtchLabel(label: AppLocalizations.of(context)!.server),
SizedBox(
height: 20,
),
DropdownButton(
onChanged: (String? newServer) {
setState(() {
server = newServer!;
});
},
isExpanded: true, // magic property
value: server,
items: Provider.of<ProfileInfoState>(context)
.serverList
.servers
.where((serverInfo) => serverInfo.status == "Synced")
.map<DropdownMenuItem<String>>((RemoteServerInfoState serverInfo) {
return DropdownMenuItem<String>(
value: serverInfo.onion,
child: Text(
serverInfo.description.isNotEmpty ? serverInfo.description : serverInfo.onion,
overflow: TextOverflow.ellipsis,
return Scrollbar(
child: SingleChildScrollView(
clipBehavior: Clip.antiAlias,
child: Container(
margin: EdgeInsets.all(30),
padding: EdgeInsets.all(20),
child: Form(
autovalidateMode: AutovalidateMode.always,
key: _createGroupFormKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CwtchLabel(label: AppLocalizations.of(context)!.server),
SizedBox(
height: 20,
),
);
}).toList()),
SizedBox(
height: 20,
),
CwtchLabel(label: AppLocalizations.of(context)!.groupName),
SizedBox(
height: 20,
),
CwtchTextField(
controller: ctrlrGroupName,
hintText: AppLocalizations.of(context)!.groupNameLabel,
onChanged: (newValue) {},
validator: (value) {},
),
SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.CreateGroup(profileOnion, server, ctrlrGroupName.text);
Future.delayed(const Duration(milliseconds: 500), () {
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.successfullAddedContact + " " + ctrlrGroupName.text));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Navigator.pop(context);
});
},
child: Text(AppLocalizations.of(context)!.createGroupBtn),
),
],
)));
DropdownButton(
onChanged: (String? newServer) {
setState(() {
server = newServer!;
});
},
isExpanded: true, // magic property
value: server,
items: Provider.of<ProfileInfoState>(context)
.serverList
.servers
.where((serverInfo) => serverInfo.status == "Synced")
.map<DropdownMenuItem<String>>((RemoteServerInfoState serverInfo) {
return DropdownMenuItem<String>(
value: serverInfo.onion,
child: Text(
serverInfo.description.isNotEmpty ? serverInfo.description : serverInfo.onion,
overflow: TextOverflow.ellipsis,
),
);
}).toList()),
SizedBox(
height: 20,
),
CwtchLabel(label: AppLocalizations.of(context)!.groupName),
SizedBox(
height: 20,
),
CwtchTextField(
controller: ctrlrGroupName,
hintText: AppLocalizations.of(context)!.groupNameLabel,
onChanged: (newValue) {},
validator: (value) {},
),
SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () {
var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.CreateGroup(profileOnion, server, ctrlrGroupName.text);
Future.delayed(const Duration(milliseconds: 500), () {
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.successfullAddedContact + " " + ctrlrGroupName.text));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Navigator.pop(context);
});
},
child: Text(AppLocalizations.of(context)!.createGroupBtn),
),
],
)))));
}
/// TODO Manage Servers Tab

View File

@ -106,14 +106,10 @@ class _TorStatusView extends State<TorStatusView> {
if (port > 0 && port < 65536) {
return null;
} else {
return AppLocalizations.of(
context)!
.torSettingsErrorSettingPort;
return AppLocalizations.of(context)!.torSettingsErrorSettingPort;
}
}catch (e) {
return AppLocalizations.of(
context)!
.torSettingsErrorSettingPort;
} catch (e) {
return AppLocalizations.of(context)!.torSettingsErrorSettingPort;
}
},
onChanged: (String socksPort) {
@ -141,22 +137,17 @@ class _TorStatusView extends State<TorStatusView> {
if (port > 0 && port < 65536) {
return null;
} else {
return AppLocalizations.of(
context)!
.torSettingsErrorSettingPort;
return AppLocalizations.of(context)!.torSettingsErrorSettingPort;
}
}catch (e) {
return AppLocalizations.of(
context)!
.torSettingsErrorSettingPort;
} catch (e) {
return AppLocalizations.of(context)!.torSettingsErrorSettingPort;
}
},
onChanged: (String controlPort) {
try {
var port = int.parse(controlPort);
if (port > 0 && port < 65536) {
settings.controlPort =
int.parse(controlPort);
settings.controlPort = int.parse(controlPort);
saveSettings(context);
}
} catch (e) {}

View File

@ -51,9 +51,7 @@ class _CwtchTextFieldState extends State<CwtchTextField> {
: widget.number
? TextInputType.number
: TextInputType.text,
inputFormatters: widget.number ? <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
] : null,
inputFormatters: widget.number ? <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly] : null,
maxLines: widget.multiLine ? null : 1,
scrollController: _scrollController,
enableIMEPersonalizedLearning: false,
@ -66,11 +64,7 @@ class _CwtchTextFieldState extends State<CwtchTextField> {
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(15.0), borderSide: BorderSide(color: theme.current().textfieldBorderColor, width: 3.0)),
focusedErrorBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(15.0), borderSide: BorderSide(color: theme.current().textfieldErrorColor, width: 3.0)),
errorBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(15.0), borderSide: BorderSide(color: theme.current().textfieldErrorColor, width: 3.0)),
errorStyle: TextStyle(
color: theme.current().textfieldErrorColor,
fontWeight: FontWeight.bold,
overflow: TextOverflow.visible
),
errorStyle: TextStyle(color: theme.current().textfieldErrorColor, fontWeight: FontWeight.bold, overflow: TextOverflow.visible),
fillColor: theme.current().textfieldBackgroundColor,
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(15.0), borderSide: BorderSide(color: theme.current().textfieldBorderColor, width: 3.0))),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB