Language Switcher and Package Info / License Viewer

This commit is contained in:
Sarah Jamie Lewis 2021-03-08 17:23:37 -08:00
parent 75a508fe74
commit e383085268
8 changed files with 254 additions and 99 deletions

BIN
assets/cwtch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
assets/knott.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -75,7 +75,7 @@ class CwtchFfi implements Cwtch {
var startCwtchC = library.lookup<NativeFunction<start_cwtch_function>>("c_StartCwtch");
// ignore: non_constant_identifier_names
final StartCwtch = startCwtchC.asFunction<StartCwtchFn>();
StartCwtch(Utf8.toUtf8(cwtchDir), cwtchDir.length, Utf8.toUtf8(""), 0);
StartCwtch(cwtchDir.toNativeUtf8(), cwtchDir.length, "".toNativeUtf8(), 0);
// Spawn an isolate to listen to events from libcwtch-go and then dispatch them when received on main thread to cwtchNotifier
var _receivePort = ReceivePort();
@ -110,7 +110,7 @@ class CwtchFfi implements Cwtch {
while (true) {
Pointer<Utf8> result = GetAppbusEvent();
String event = Utf8.fromUtf8(result);
String event = result.toDartString();
yield event;
}
}
@ -121,7 +121,7 @@ class CwtchFfi implements Cwtch {
// ignore: non_constant_identifier_names
final SelectProfile = selectProfileC.asFunction<GetJsonBlobStringFn>();
SelectProfile(Utf8.toUtf8(onion), onion.length);
SelectProfile(onion.toNativeUtf8(), onion.length);
}
// ignore: non_constant_identifier_names
@ -129,7 +129,7 @@ class CwtchFfi implements Cwtch {
var createProfileC = library.lookup<NativeFunction<void_from_string_string_function>>("c_CreateProfile");
// ignore: non_constant_identifier_names
final CreateProfile = createProfileC.asFunction<VoidFromStringStringFn>();
CreateProfile(Utf8.toUtf8(nick), nick.length, Utf8.toUtf8(pass), pass.length);
CreateProfile(nick.toNativeUtf8(), nick.length, pass.toNativeUtf8(), pass.length);
}
// ignore: non_constant_identifier_names
@ -137,7 +137,7 @@ class CwtchFfi implements Cwtch {
var loadProfileC = library.lookup<NativeFunction<string_to_void_function>>("c_LoadProfiles");
// ignore: non_constant_identifier_names
final LoadProfiles = loadProfileC.asFunction<StringFn>();
LoadProfiles(Utf8.toUtf8(pass), pass.length);
LoadProfiles(pass.toNativeUtf8(), pass.length);
}
Future<String> ACNEvents() async {
@ -147,7 +147,7 @@ class CwtchFfi implements Cwtch {
final ACNEvents = acnEventsC.asFunction<ACNEventsFn>();
Pointer<Utf8> result = ACNEvents();
String event = Utf8.fromUtf8(result);
String event = result.toDartString();
return event;
}
@ -159,7 +159,7 @@ class CwtchFfi implements Cwtch {
final ContactEvents = acnEventsC.asFunction<ACNEventsFn>();
Pointer<Utf8> result = ContactEvents();
String event = Utf8.fromUtf8(result);
String event = result.toDartString();
return event;
}
@ -169,7 +169,7 @@ class CwtchFfi implements Cwtch {
final GetProfiles = getProfilesC.asFunction<GetJsonBlobVoidFn>();
Pointer<Utf8> jsonProfilesBytes = GetProfiles();
String jsonProfiles = Utf8.fromUtf8(jsonProfilesBytes);
String jsonProfiles = jsonProfilesBytes.toDartString();
return jsonProfiles;
}
@ -177,8 +177,8 @@ class CwtchFfi implements Cwtch {
var getContactsC = library.lookup<NativeFunction<get_json_blob_string_function>>("c_GetContacts");
// ignore: non_constant_identifier_names
final GetContacts = getContactsC.asFunction<GetJsonBlobStringFn>();
Pointer<Utf8> jsonContactBytes = GetContacts(Utf8.toUtf8(onion), onion.length);
String jsonContacts = Utf8.fromUtf8(jsonContactBytes);
Pointer<Utf8> jsonContactBytes = GetContacts(onion.toNativeUtf8(), onion.length);
String jsonContacts = jsonContactBytes.toDartString();
return jsonContacts;
}
@ -187,7 +187,7 @@ class CwtchFfi implements Cwtch {
// ignore: non_constant_identifier_names
final NumMessages = numMessagesC.asFunction<GetIntFromStrStrFn>();
int num = NumMessages(Utf8.toUtf8(profile), profile.length, Utf8.toUtf8(handle), handle.length);
int num = NumMessages(profile.toNativeUtf8(), profile.length, handle.toNativeUtf8(), handle.length);
return num;
}
@ -196,8 +196,8 @@ class CwtchFfi implements Cwtch {
// ignore: non_constant_identifier_names
final GetMessage = getMessageC.asFunction<GetJsonBlobFromStrStrIntFn>();
Pointer<Utf8> jsonMessageBytes = GetMessage(Utf8.toUtf8(profile), profile.length, Utf8.toUtf8(handle), handle.length, index);
String jsonMessage = Utf8.fromUtf8(jsonMessageBytes);
Pointer<Utf8> jsonMessageBytes = GetMessage(profile.toNativeUtf8(), profile.length, handle.toNativeUtf8(), handle.length, index);
String jsonMessage = jsonMessageBytes.toDartString();
return jsonMessage;
}
@ -206,8 +206,8 @@ class CwtchFfi implements Cwtch {
// ignore: non_constant_identifier_names
final GetMessages = getMessagesC.asFunction<GetJsonBlobFromStrStrIntIntFn>();
Pointer<Utf8> jsonMessagesBytes = GetMessages(Utf8.toUtf8(profile), profile.length, Utf8.toUtf8(handle), handle.length, start, end);
String jsonMessages = Utf8.fromUtf8(jsonMessagesBytes);
Pointer<Utf8> jsonMessagesBytes = GetMessages(profile.toNativeUtf8(), profile.length, handle.toNativeUtf8(), handle.length, start, end);
String jsonMessages = jsonMessagesBytes.toDartString();
return jsonMessages;
}
@ -216,6 +216,6 @@ class CwtchFfi implements Cwtch {
var sendAppBusEvent = library.lookup<NativeFunction<string_string_to_void_function>>("c_SendProfileEvent");
// ignore: non_constant_identifier_names
final SendAppBusEvent = sendAppBusEvent.asFunction<StringStringFn>();
SendAppBusEvent(Utf8.toUtf8(onion), onion.length, Utf8.toUtf8(json), json.length);
SendAppBusEvent(onion.toNativeUtf8(), onion.length, json.toNativeUtf8(), json.length);
}
}

View File

@ -1,6 +1,7 @@
import 'package:flutter_app/cwtch/ffi.dart';
import 'package:flutter_app/cwtch/gomobile.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/settings.dart';
import 'package:flutter_app/views/triplecolview.dart';
import 'package:provider/provider.dart';
import 'cwtch/cwtch.dart';
@ -36,6 +37,7 @@ class FlwtchState extends State<Flwtch> {
initState() {
super.initState();
cwtchInit = false;
profs = ProfileListState();
var cwtchNotifier = new CwtchNotifier(profs);
@ -54,6 +56,7 @@ class FlwtchState extends State<Flwtch> {
appStatus = AppModel(cwtch: cwtch);
}
ChangeNotifierProvider<Settings> getSettingsProvider() => ChangeNotifierProvider(create: (context) => Settings(Locale("en", '')));
ChangeNotifierProvider<OpaqueTheme> getOpaqueProvider() => ChangeNotifierProvider(create: (context) => OpaqueTheme(Opaque.dark));
Provider<FlwtchState> getFlwtchStateProvider() => Provider<FlwtchState>(create: (_) => this);
ChangeNotifierProvider<ProfileListState> getProfileListProvider() => ChangeNotifierProvider(create: (context) => profs);
@ -62,17 +65,13 @@ class FlwtchState extends State<Flwtch> {
Widget build(BuildContext context) {
appStatus = AppModel(cwtch: cwtch);
final newTextTheme = Theme.of(context).textTheme.apply(
bodyColor: Opaque.current().mainTextColor(),
displayColor: Opaque.current().mainTextColor(),
);
return MultiProvider(
providers: [getFlwtchStateProvider(), getProfileListProvider(), getOpaqueProvider()],
providers: [getFlwtchStateProvider(), getProfileListProvider(), getOpaqueProvider(), getSettingsProvider()],
builder: (context, widget) {
Provider.of<Settings>(context).initPackageInfo();
return Consumer<OpaqueTheme>(
builder: (context, opaque, child) => MaterialApp(
locale: Locale("en",''),
locale: Provider.of<Settings>(context).locale,
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
title: 'Cwtch',
@ -83,7 +82,39 @@ class FlwtchState extends State<Flwtch> {
canvasColor: opaque.current().backgroundPaneColor(),
accentColor: opaque.current().defaultButtonColor(),
buttonColor: opaque.current().defaultButtonColor(),
textTheme: newTextTheme,
backgroundColor: opaque.current().backgroundMainColor(),
iconTheme: IconThemeData (
color: opaque.current().mainTextColor(),
),
cardColor: opaque.current().backgroundMainColor(),
textButtonTheme: TextButtonThemeData (
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(opaque.current().defaultButtonColor()),
foregroundColor: MaterialStateProperty.all(opaque.current().defaultButtonTextColor()),
overlayColor: MaterialStateProperty.all(opaque.current().defaultButtonActiveColor()),
padding: MaterialStateProperty.all(EdgeInsets.all(20))
),
),
dialogTheme: DialogTheme (
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()),
headline3: TextStyle( color: opaque.current().mainTextColor()),
headline4: TextStyle( color: opaque.current().mainTextColor()),
headline5: TextStyle( color: opaque.current().mainTextColor()),
headline6: TextStyle( color: opaque.current().mainTextColor()),
bodyText1: TextStyle( color: opaque.current().mainTextColor()),
bodyText2: TextStyle( color: opaque.current().mainTextColor()),
subtitle1: TextStyle( color: opaque.current().mainTextColor()),
subtitle2: TextStyle( color: opaque.current().mainTextColor()),
caption: TextStyle( color: opaque.current().mainTextColor()),
button: TextStyle( color: opaque.current().mainTextColor()),
overline: TextStyle( color: opaque.current().mainTextColor())
),
),
// from dan: home: cwtchInit == true ? ProfileMgrView(cwtch) : SplashView(),
// from erinn: home: columns.length == 3 ? TripleColumnView() : ProfileMgrView(),

25
lib/settings.dart Normal file
View File

@ -0,0 +1,25 @@
import 'dart:ui';
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
class Settings extends ChangeNotifier {
Locale locale;
PackageInfo packageInfo;
initPackageInfo() {
PackageInfo.fromPlatform().then((PackageInfo newPackageInfo) {
packageInfo = newPackageInfo;
notifyListeners();
});
}
switchLocale(Locale newLocale) {
locale = newLocale;
notifyListeners();
}
Settings(this.locale);
}

View File

@ -1,19 +1,21 @@
import 'dart:io';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/opaque.dart';
import 'package:flutter_app/settings.dart';
import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../main.dart';
class GlobalSettingsView extends StatefulWidget {
@override
_GlobalSettingsViewState createState() => _GlobalSettingsViewState();
}
class _GlobalSettingsViewState extends State<GlobalSettingsView> {
final myController = TextEditingController();
@override
void dispose() {
myController.dispose();
super.dispose();
}
@ -28,40 +30,80 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
}
Widget _buildSettingsList() {
return Consumer<OpaqueTheme>(
builder: (context, theme, child) {
return Center(child: Column(
children: [
Text(AppLocalizations.of(context).settingLanguage),
TextField(
controller: myController,
onChanged: (text) {
print("First text field: $text");
},
),
Text(AppLocalizations.of(context).settingInterfaceZoom),
SwitchListTile(
title: Text('Theme',
style: TextStyle(color: theme.current().mainTextColor())),
value: theme.current() == Opaque.light,
onChanged: (bool value) {
if (value) {
theme.setLight();
} else {
theme.setDark();
}
},
secondary: Icon(Icons.lightbulb_outline,
color: theme.current().mainTextColor()),
),
Text(AppLocalizations.of(context).experimentsEnabled),
Text("Text magnification reference"),//dev
Text("Acknowledgements"),//todo
Text(AppLocalizations.of(context).version),
Text(AppLocalizations.of(context).builddate),
]
));
}
);
return Consumer<OpaqueTheme>(builder: (context, theme, child) {
return Center(
child: Column(children: [
ListTile(
title: Text(AppLocalizations.of(context).settingLanguage, style: TextStyle(color: theme.current().mainTextColor())),
leading: Icon(Icons.language, color: theme.current().mainTextColor()),
trailing: DropdownButton(
value: Provider.of<Settings>(context).locale.languageCode,
onChanged: (String newValue) {
setState(() {
Provider.of<Settings>(context, listen: false).switchLocale(Locale(newValue, ''));
});
},
items: AppLocalizations.supportedLocales.map<DropdownMenuItem<String>>((Locale value) {
return DropdownMenuItem<String>(
value: value.languageCode,
child: Text(getLanguageFull(context, value.languageCode)),
);
}).toList())),
SwitchListTile(
title: Text(AppLocalizations.of(context).settingTheme, style: TextStyle(color: theme.current().mainTextColor())),
value: theme.current() == Opaque.light,
onChanged: (bool value) {
if (value) {
theme.setLight();
} else {
theme.setDark();
}
},
secondary: Icon(Icons.lightbulb_outline, color: theme.current().mainTextColor()),
),
AboutListTile(
icon: Icon(Icons.info, color: theme.current().mainTextColor()),
applicationIcon: Padding(
padding: EdgeInsets.all(20),
child: Image(
image: AssetImage("assets/knott.png"),
width: 128,
height: 128,
)),
applicationName: "Cwtch (Flutter UI)",
applicationVersion: AppLocalizations.of(context).version.replaceAll("%1", constructVersionString(Provider.of<Settings>(context).packageInfo)),
applicationLegalese: '\u{a9} 2021 Open Privacy Research Society',
),
]));
});
}
}
String constructVersionString(PackageInfo pinfo) {
if (pinfo == null) {
return "";
}
return pinfo.version + "." + pinfo.buildNumber;
}
String getLanguageFull(context, String languageCode) {
if (languageCode == "en") {
return AppLocalizations.of(context).localeEn;
}
if (languageCode == "es") {
return AppLocalizations.of(context).localeEs;
}
if (languageCode == "fr") {
return AppLocalizations.of(context).localeFr;
}
if (languageCode == "pt") {
return AppLocalizations.of(context).localePt;
}
if (languageCode == "de") {
return AppLocalizations.of(context).localeDe;
}
if (languageCode == "it") {
return AppLocalizations.of(context).localeIt;
}
return languageCode;
}

View File

@ -21,42 +21,42 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0-nullsafety.3"
version: "2.5.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.3"
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.5"
version: "1.1.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.3"
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0-nullsafety.5"
version: "1.15.0"
convert:
dependency: transitive
description:
@ -84,21 +84,21 @@ packages:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
ffi:
dependency: "direct main"
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
version: "1.0.0"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.0-nullsafety.4"
version: "6.1.0"
flutter:
dependency: "direct main"
description: flutter
@ -115,12 +115,17 @@ packages:
name: flutter_lokalise
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1"
version: "0.1.3"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
freezed_annotation:
dependency: transitive
description:
@ -134,21 +139,28 @@ packages:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.2"
version: "0.13.0"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
version: "4.0.0"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.0-nullsafety.2"
version: "0.17.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
json_annotation:
dependency: transitive
description:
@ -169,14 +181,14 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10-nullsafety.3"
version: "0.12.10"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.6"
version: "1.3.0"
nested:
dependency: transitive
description:
@ -184,48 +196,90 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4"
package_info_plus:
dependency: "direct main"
description:
name: package_info_plus
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
package_info_plus_linux:
dependency: transitive
description:
name: package_info_plus_linux
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
package_info_plus_macos:
dependency: transitive
description:
name: package_info_plus_macos
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
package_info_plus_web:
dependency: transitive
description:
name: package_info_plus_web
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
package_info_plus_windows:
dependency: transitive
description:
name: package_info_plus_windows
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.3"
version: "1.8.0"
path_provider:
dependency: "direct main"
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.27"
version: "2.0.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+2"
version: "2.0.0"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+8"
version: "2.0.0"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
version: "2.0.1"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+3"
version: "2.0.0"
pedantic:
dependency: transitive
description:
@ -246,14 +300,14 @@ packages:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
version: "2.0.0"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0-nullsafety.4"
version: "4.1.0"
provider:
dependency: "direct main"
description:
@ -279,28 +333,28 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.4"
version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0-nullsafety.6"
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.3"
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.3"
version: "1.1.0"
string_unescape:
dependency: transitive
description:
@ -314,42 +368,42 @@ packages:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.3"
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.19-nullsafety.6"
version: "0.2.19"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.5"
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.5"
version: "2.1.0"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.4"
version: "2.0.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
version: "0.2.0"
yaml:
dependency: transitive
description:
@ -358,5 +412,5 @@ packages:
source: hosted
version: "2.2.1"
sdks:
dart: ">=2.12.0-0.0 <3.0.0"
flutter: ">=1.16.0"
dart: ">=2.12.0-259.9.beta <3.0.0"
flutter: ">=1.20.0"

View File

@ -24,6 +24,7 @@ dependencies:
flutter:
sdk: flutter
provider: "4.3.2+3"
package_info_plus: ^1.0.0
#intl_translation: any
flutter_localizations:
sdk: flutter
@ -31,8 +32,9 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.0
ffi: ^0.1.3
path_provider: ^1.6.27
ffi: ^1.0.0
path_provider: ^2.0.0
dev_dependencies:
flutter_test:
@ -75,6 +77,7 @@ flutter:
# https://flutter.dev/assets-and-images/#from-packages
assets:
- assets/
- assets/profiles/
# To add custom fonts to your application, add a fonts section here,