diff --git a/android/app/src/main/kotlin/com/example/flutter_app/MainActivity.kt b/android/app/src/main/kotlin/com/example/flutter_app/MainActivity.kt index eb5c22b..bf69dd5 100644 --- a/android/app/src/main/kotlin/com/example/flutter_app/MainActivity.kt +++ b/android/app/src/main/kotlin/com/example/flutter_app/MainActivity.kt @@ -132,6 +132,10 @@ class MainActivity: FlutterActivity() { val jsonEvent = (call.argument("jsonEvent") as? String) ?: ""; Cwtch.sendProfileEvent(onion, jsonEvent); } + "SendAppEvent" -> { + val jsonEvent = (call.argument("jsonEvent") as? String) ?: ""; + Cwtch.sendAppEvent(jsonEvent); + } else -> result.notImplemented() } } diff --git a/lib/cwtch/cwtch.dart b/lib/cwtch/cwtch.dart index 661dd90..9430bc0 100644 --- a/lib/cwtch/cwtch.dart +++ b/lib/cwtch/cwtch.dart @@ -5,6 +5,7 @@ abstract class Cwtch { void CreateProfile(String nick, String pass); void LoadProfiles(String pass); void SendProfileEvent(String onion, String jsonEvent); + void SendAppEvent(String jsonEvent); Future ACNEvents(); Future ContactEvents(); @@ -15,4 +16,4 @@ abstract class Cwtch { Future NumMessages(String profile, String handle); Future GetMessage(String profile, String handle, int index); Future GetMessages(String profile, String handle, int start, int end); -} \ No newline at end of file +} diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index d61c1f1..5716366 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -1,18 +1,32 @@ +import 'dart:convert'; + +import 'package:provider/provider.dart'; +import 'package:provider/provider.dart'; + import '../model.dart'; +import '../settings.dart'; // Class that handles libcwtch-go events (received either via ffi with an isolate or gomobile over a method channel from kotlin) // Takes Notifiers and triggers them on appropriate events class CwtchNotifier { ProfileListState profileCN; + Settings settings; - CwtchNotifier(ProfileListState pcn) { + CwtchNotifier(ProfileListState pcn, Settings settingsCN) { profileCN = pcn; + settings = settingsCN; } void handleMessage(String type, dynamic data) { switch (type) { case "NewPeer": - profileCN.add(ProfileInfoState(onion: data["Identity"], nickname: data["name"], imagePath: data["picture"])); + profileCN.add(ProfileInfoState( + onion: data["Identity"], + nickname: data["name"], + imagePath: data["picture"])); + break; + case "UpdateGlobalSettings": + settings.handleUpdate(jsonDecode(data["Data"])); break; default: print("unhandled gomobile appbus event: ${type}"); diff --git a/lib/cwtch/ffi.dart b/lib/cwtch/ffi.dart index 2fba2e3..2e677e8 100644 --- a/lib/cwtch/ffi.dart +++ b/lib/cwtch/ffi.dart @@ -15,41 +15,55 @@ import '../model.dart'; /// Cwtch API /// ///////////////////// -typedef start_cwtch_function = Void Function(Pointer str, Int32 length, Pointer str2, Int32 length2); -typedef StartCwtchFn = void Function(Pointer dir, int len, Pointer tor, int torLen); +typedef start_cwtch_function = Void Function( + Pointer str, Int32 length, Pointer str2, Int32 length2); +typedef StartCwtchFn = void Function( + Pointer dir, int len, Pointer tor, int torLen); -typedef void_from_string_string_function = Void Function(Pointer, Int32, Pointer, Int32); -typedef VoidFromStringStringFn = void Function(Pointer, int, Pointer, int); +typedef void_from_string_string_function = Void Function( + Pointer, Int32, Pointer, Int32); +typedef VoidFromStringStringFn = void Function( + Pointer, int, Pointer, int); typedef access_cwtch_eventbus_function = Void Function(); typedef NextEventFn = void Function(); -typedef string_to_void_function = Void Function(Pointer str, Int32 length); +typedef string_to_void_function = Void Function( + Pointer str, Int32 length); typedef StringFn = void Function(Pointer dir, int); -typedef string_string_to_void_function = Void Function(Pointer str, Int32 length, Pointer str2, Int32 length2); +typedef string_string_to_void_function = Void Function( + Pointer str, Int32 length, Pointer str2, Int32 length2); typedef StringStringFn = void Function(Pointer, int, Pointer, int); typedef get_json_blob_void_function = Pointer Function(); typedef GetJsonBlobVoidFn = Pointer Function(); -typedef get_json_blob_string_function = Pointer Function(Pointer str, Int32 length); -typedef GetJsonBlobStringFn = Pointer Function(Pointer str,int len); +typedef get_json_blob_string_function = Pointer Function( + Pointer str, Int32 length); +typedef GetJsonBlobStringFn = Pointer Function( + Pointer str, int len); //func NumMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int) (n C.int) { -typedef get_int_from_str_str_function = Int32 Function(Pointer, Int32, Pointer, Int32); -typedef GetIntFromStrStrFn = int Function(Pointer, int, Pointer, int); +typedef get_int_from_str_str_function = Int32 Function( + Pointer, Int32, Pointer, Int32); +typedef GetIntFromStrStrFn = int Function( + Pointer, int, Pointer, int); //func GetMessage(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, message_index C.int) *C.char { -typedef get_json_blob_from_str_str_int_function = Pointer Function(Pointer, Int32, Pointer, Int32, Int32); -typedef GetJsonBlobFromStrStrIntFn = Pointer Function(Pointer, int, Pointer, int, int); +typedef get_json_blob_from_str_str_int_function = Pointer Function( + Pointer, Int32, Pointer, Int32, Int32); +typedef GetJsonBlobFromStrStrIntFn = Pointer Function( + Pointer, int, Pointer, int, int); //func GetMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, start C.int, end C.int) *C.char { -typedef get_json_blob_from_str_str_int_int_function = Pointer Function(Pointer, Int32, Pointer, Int32, Int32, Int32); -typedef GetJsonBlobFromStrStrIntIntFn = Pointer Function(Pointer, int, Pointer, int, int, int); +typedef get_json_blob_from_str_str_int_int_function = Pointer Function( + Pointer, Int32, Pointer, Int32, Int32, Int32); +typedef GetJsonBlobFromStrStrIntIntFn = Pointer Function( + Pointer, int, Pointer, int, int, int); typedef acn_events_function = Pointer Function(); -typedef ACNEventsFn = Pointer Function(); +typedef ACNEventsFn = Pointer Function(); class CwtchFfi implements Cwtch { DynamicLibrary library; @@ -72,17 +86,18 @@ class CwtchFfi implements Cwtch { var cwtchDir = path.join(home, ".cwtch/dev/"); print("cwtchDir $cwtchDir"); - var startCwtchC = library.lookup>("c_StartCwtch"); + var startCwtchC = + library.lookup>("c_StartCwtch"); // ignore: non_constant_identifier_names final StartCwtch = startCwtchC.asFunction(); - final ut8CwtchDir = cwtchDir.toNativeUtf8(); - StartCwtch(ut8CwtchDir,ut8CwtchDir.length, "".toNativeUtf8(), 0); + StartCwtch(ut8CwtchDir, ut8CwtchDir.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(); - cwtchIsolate = await Isolate.spawn(_checkAppbusEvents, _receivePort.sendPort); + cwtchIsolate = + await Isolate.spawn(_checkAppbusEvents, _receivePort.sendPort); _receivePort.listen((message) { var env = jsonDecode(message); cwtchNotifier.handleMessage(env["EventType"], env["Data"]); @@ -108,7 +123,8 @@ class CwtchFfi implements Cwtch { // Steam of appbus events. Call blocks in libcwtch-go GetAppbusEvent. Static so the isolate can use it static Stream pollAppbusEvents() async* { var library = DynamicLibrary.open("libCwtch.so"); - var getAppbusEventC = library.lookup>("c_GetAppBusEvent"); + var getAppbusEventC = + library.lookup>("c_GetAppBusEvent"); final GetAppbusEvent = getAppbusEventC.asFunction(); while (true) { @@ -120,7 +136,9 @@ class CwtchFfi implements Cwtch { // ignore: non_constant_identifier_names void SelectProfile(String onion) async { - var selectProfileC = library.lookup>("c_SelectProfile"); + var selectProfileC = + library.lookup>( + "c_SelectProfile"); // ignore: non_constant_identifier_names final SelectProfile = selectProfileC.asFunction(); final ut8Onion = onion.toNativeUtf8(); @@ -129,7 +147,9 @@ class CwtchFfi implements Cwtch { // ignore: non_constant_identifier_names void CreateProfile(String nick, String pass) { - var createProfileC = library.lookup>("c_CreateProfile"); + var createProfileC = + library.lookup>( + "c_CreateProfile"); // ignore: non_constant_identifier_names final CreateProfile = createProfileC.asFunction(); final utf8nick = nick.toNativeUtf8(); @@ -139,7 +159,8 @@ class CwtchFfi implements Cwtch { // ignore: non_constant_identifier_names void LoadProfiles(String pass) { - var loadProfileC = library.lookup>("c_LoadProfiles"); + var loadProfileC = library + .lookup>("c_LoadProfiles"); // ignore: non_constant_identifier_names final LoadProfiles = loadProfileC.asFunction(); final ut8pass = pass.toNativeUtf8(); @@ -147,8 +168,8 @@ class CwtchFfi implements Cwtch { } Future ACNEvents() async { - var acnEventsC = library.lookup>( - "c_ACNEvents"); + var acnEventsC = + library.lookup>("c_ACNEvents"); // ignore: non_constant_identifier_names final ACNEvents = acnEventsC.asFunction(); @@ -157,10 +178,9 @@ class CwtchFfi implements Cwtch { return event; } - Future ContactEvents() async { - var acnEventsC = library.lookup>( - "c_ContactEvents"); + var acnEventsC = + library.lookup>("c_ContactEvents"); // ignore: non_constant_identifier_names final ContactEvents = acnEventsC.asFunction(); @@ -170,7 +190,8 @@ class CwtchFfi implements Cwtch { } Future GetProfiles() async { - var getProfilesC = library.lookup>("c_GetProfiles"); + var getProfilesC = library + .lookup>("c_GetProfiles"); // ignore: non_constant_identifier_names final GetProfiles = getProfilesC.asFunction(); @@ -180,7 +201,8 @@ class CwtchFfi implements Cwtch { } Future GetContacts(String onion) async { - var getContactsC = library.lookup>("c_GetContacts"); + var getContactsC = library + .lookup>("c_GetContacts"); // ignore: non_constant_identifier_names final GetContacts = getContactsC.asFunction(); final utf8onion = onion.toNativeUtf8(); @@ -190,44 +212,66 @@ class CwtchFfi implements Cwtch { } Future NumMessages(String profile, String handle) async { - var numMessagesC = library.lookup>("c_NumMessages"); + var numMessagesC = library + .lookup>("c_NumMessages"); // ignore: non_constant_identifier_names final NumMessages = numMessagesC.asFunction(); final utf8profile = profile.toNativeUtf8(); final utf8handle = handle.toNativeUtf8(); - int num = NumMessages(utf8profile, utf8profile.length, utf8handle, utf8handle.length); + int num = NumMessages( + utf8profile, utf8profile.length, utf8handle, utf8handle.length); return num; } Future GetMessage(String profile, String handle, int index) async { - var getMessageC = library.lookup>("c_GetMessage"); + var getMessageC = + library.lookup>( + "c_GetMessage"); // ignore: non_constant_identifier_names final GetMessage = getMessageC.asFunction(); final utf8profile = profile.toNativeUtf8(); final utf8handle = handle.toNativeUtf8(); - Pointer jsonMessageBytes = GetMessage(utf8profile, utf8profile.length, utf8handle, utf8handle.length, index); + Pointer jsonMessageBytes = GetMessage( + utf8profile, utf8profile.length, utf8handle, utf8handle.length, index); String jsonMessage = jsonMessageBytes.toDartString(); return jsonMessage; } - Future GetMessages(String profile, String handle, int start, int end) async { - var getMessagesC = library.lookup>("c_GetMessages"); + Future GetMessages( + String profile, String handle, int start, int end) async { + var getMessagesC = library + .lookup>( + "c_GetMessages"); // ignore: non_constant_identifier_names - final GetMessages = getMessagesC.asFunction(); + final GetMessages = + getMessagesC.asFunction(); final utf8profile = profile.toNativeUtf8(); final utf8handle = handle.toNativeUtf8(); - Pointer jsonMessagesBytes = GetMessages(utf8profile, utf8profile.length, utf8handle, utf8handle.length, start, end); + Pointer jsonMessagesBytes = GetMessages(utf8profile, + utf8profile.length, utf8handle, utf8handle.length, start, end); String jsonMessages = jsonMessagesBytes.toDartString(); return jsonMessages; } @override void SendProfileEvent(String onion, String json) { - var sendAppBusEvent = library.lookup>("c_SendProfileEvent"); + var sendAppBusEvent = + library.lookup>( + "c_SendProfileEvent"); // ignore: non_constant_identifier_names final SendAppBusEvent = sendAppBusEvent.asFunction(); final utf8onion = onion.toNativeUtf8(); final utf8json = json.toNativeUtf8(); SendAppBusEvent(utf8onion, utf8onion.length, utf8json, utf8json.length); } -} \ No newline at end of file + + @override + void SendAppEvent(String json) { + var sendAppBusEvent = library + .lookup>("c_SendAppEvent"); + // ignore: non_constant_identifier_names + final SendAppBusEvent = sendAppBusEvent.asFunction(); + final utf8json = json.toNativeUtf8(); + SendAppBusEvent(utf8json, utf8json.length); + } +} diff --git a/lib/cwtch/gomobile.dart b/lib/cwtch/gomobile.dart index 1a08032..a0b759e 100644 --- a/lib/cwtch/gomobile.dart +++ b/lib/cwtch/gomobile.dart @@ -22,7 +22,8 @@ Future startCwtch() async { */ class CwtchGomobile implements Cwtch { - static const appInfoPlatform = const MethodChannel('test.flutter.dev/applicationInfo'); + static const appInfoPlatform = + const MethodChannel('test.flutter.dev/applicationInfo'); static const cwtchPlatform = const MethodChannel('cwtch'); final appbusEventChannelName = 'test.flutter.dev/eventBus'; @@ -47,7 +48,8 @@ class CwtchGomobile implements Cwtch { var cwtchDir = path.join((await androidHomeDirectory).path, ".cwtch/dev/"); String torPath = path.join(await androidLibraryDir, "libtor.so"); print("gomobile.dart: Start invokeMethod Start($cwtchDir, $torPath)..."); - cwtchPlatform.invokeMethod("Start", {"appDir": cwtchDir, "torPath": torPath}); + cwtchPlatform + .invokeMethod("Start", {"appDir": cwtchDir, "torPath": torPath}); } // Handle libcwtch-go events (received via kotlin) and dispatch to the cwtchNotifier @@ -59,7 +61,7 @@ class CwtchGomobile implements Cwtch { } void SelectProfile(String onion) { - cwtchPlatform.invokeMethod("SelectProfile", {"profile" : onion}); + cwtchPlatform.invokeMethod("SelectProfile", {"profile": onion}); } void CreateProfile(String nick, String pass) { @@ -84,26 +86,34 @@ class CwtchGomobile implements Cwtch { } Future GetContacts(String onion) { - return cwtchPlatform.invokeMethod("GetContacts", {"profile" : onion}); + return cwtchPlatform.invokeMethod("GetContacts", {"profile": onion}); } Future NumMessages(String profile, String handle) { - return cwtchPlatform.invokeMethod("NumMessages", {"profile" : profile, "contact": handle}); + return cwtchPlatform + .invokeMethod("NumMessages", {"profile": profile, "contact": handle}); } Future GetMessage(String profile, String handle, int index) { print("gomobile.dart GetMessage " + index.toString()); - return cwtchPlatform.invokeMethod("GetMessage", {"profile" : profile, "contact": handle, "index": index}); + return cwtchPlatform.invokeMethod( + "GetMessage", {"profile": profile, "contact": handle, "index": index}); } - Future GetMessages(String profile, String handle, int start, int end) { - return cwtchPlatform.invokeMethod("GetMessage", {"profile" : profile, "contact": handle, "start": start, "end": end}); + Future GetMessages( + String profile, String handle, int start, int end) { + return cwtchPlatform.invokeMethod("GetMessage", + {"profile": profile, "contact": handle, "start": start, "end": end}); } @override void SendProfileEvent(String onion, String jsonEvent) { - cwtchPlatform.invokeMethod("SendProfileEvent", {"onion" : onion, "jsonEvent": jsonEvent}); + cwtchPlatform.invokeMethod( + "SendProfileEvent", {"onion": onion, "jsonEvent": jsonEvent}); } - -} \ No newline at end of file + @override + void SendAppEvent(String jsonEvent) { + cwtchPlatform.invokeMethod("SendAppEvent", {"jsonEvent": jsonEvent}); + } +} diff --git a/lib/main.dart b/lib/main.dart index 90d04e5..b5c3fb4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -13,6 +13,8 @@ import 'dart:io' show Platform; import 'opaque.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +var GlobalSettings = Settings(Locale("en", ''), Opaque.dark); + void main() => runApp(Flwtch()); class Flwtch extends StatefulWidget { @@ -39,7 +41,7 @@ class FlwtchState extends State { cwtchInit = false; profs = ProfileListState(); - var cwtchNotifier = new CwtchNotifier(profs); + var cwtchNotifier = new CwtchNotifier(profs, GlobalSettings); if (Platform.isAndroid) { cwtch = CwtchGomobile(cwtchNotifier); @@ -56,20 +58,26 @@ class FlwtchState extends State { appStatus = AppModel(cwtch: cwtch); } - ChangeNotifierProvider getSettingsProvider() => ChangeNotifierProvider(create: (context) => Settings(Locale("en", ''))); - ChangeNotifierProvider getOpaqueProvider() => ChangeNotifierProvider(create: (context) => OpaqueTheme(Opaque.dark)); - Provider getFlwtchStateProvider() => Provider(create: (_) => this); - ChangeNotifierProvider getProfileListProvider() => ChangeNotifierProvider(create: (context) => profs); + ChangeNotifierProvider getSettingsProvider() => + ChangeNotifierProvider(create: (context) => GlobalSettings); + Provider getFlwtchStateProvider() => + Provider(create: (_) => this); + ChangeNotifierProvider getProfileListProvider() => + ChangeNotifierProvider(create: (context) => profs); @override Widget build(BuildContext context) { appStatus = AppModel(cwtch: cwtch); return MultiProvider( - providers: [getFlwtchStateProvider(), getProfileListProvider(), getOpaqueProvider(), getSettingsProvider()], + providers: [ + getFlwtchStateProvider(), + getProfileListProvider(), + getSettingsProvider() + ], builder: (context, widget) { Provider.of(context).initPackageInfo(); - return Consumer( + return Consumer( builder: (context, opaque, child) => MaterialApp( locale: Provider.of(context).locale, localizationsDelegates: AppLocalizations.localizationsDelegates, @@ -83,42 +91,46 @@ class FlwtchState extends State { accentColor: opaque.current().defaultButtonColor(), buttonColor: opaque.current().defaultButtonColor(), backgroundColor: opaque.current().backgroundMainColor(), - iconTheme: IconThemeData ( + iconTheme: IconThemeData( color: opaque.current().mainTextColor(), ), cardColor: opaque.current().backgroundMainColor(), - textButtonTheme: TextButtonThemeData ( + 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()) + 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()) - ), + 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(), - home: cwtchInit == true ? (columns.length == 3 ? TripleColumnView() : ProfileMgrView()) : SplashView(), + home: cwtchInit == true + ? (columns.length == 3 ? TripleColumnView() : ProfileMgrView()) + : SplashView(), ), ); }, diff --git a/lib/model.dart b/lib/model.dart index aa5162a..4372a20 100644 --- a/lib/model.dart +++ b/lib/model.dart @@ -29,7 +29,13 @@ class ContactModel { String status; String imagePath; - ContactModel({this.onion, this.nickname, this.status, this.isInvitation, this.isBlocked, this.imagePath}); + ContactModel( + {this.onion, + this.nickname, + this.status, + this.isInvitation, + this.isBlocked, + this.imagePath}); } //todo: delete @@ -52,8 +58,7 @@ class ChatMessage { : o = json['o'], d = json['d']; - Map toJson() => - { + Map toJson() => { 'o': o, 'd': d, }; @@ -73,12 +78,13 @@ class ProfileListState extends ChangeNotifier { } void add(ProfileInfoState newOnion) { - print("ProfileListState: adding " + newOnion.onion +" and notifying"); + print("ProfileListState: adding " + newOnion.onion + " and notifying"); _onions.add(newOnion); notifyListeners(); } - List get onions => _onions.sublist(0);//todo: copy?? dont want caller able to bypass changenotifier + List get onions => _onions + .sublist(0); //todo: copy?? dont want caller able to bypass changenotifier } class ContactListState extends ChangeNotifier { @@ -117,13 +123,16 @@ class ContactListState extends ChangeNotifier { } void updateUnreadMessages(String forOnion, int newVal) { - _onions.sort((ContactInfoState a, ContactInfoState b) { return b.unreadMessages - a.unreadMessages; }); + _onions.sort((ContactInfoState a, ContactInfoState b) { + return b.unreadMessages - a.unreadMessages; + }); // if(changed) { notifyListeners(); //} } - List get onions => _onions.sublist(0);//todo: copy?? dont want caller able to bypass changenotifier + List get onions => _onions + .sublist(0); //todo: copy?? dont want caller able to bypass changenotifier } class ProfileInfoState extends ChangeNotifier { @@ -132,7 +141,12 @@ class ProfileInfoState extends ChangeNotifier { String _imagePath = ""; int _unreadMessages = 0; - ProfileInfoState({this.onion, nickname = "", imagePath = "", unreadMessages = 0,}){ + ProfileInfoState({ + this.onion, + nickname = "", + imagePath = "", + unreadMessages = 0, + }) { this._nickname = nickname; this._imagePath = imagePath; this._unreadMessages = unreadMessages; @@ -174,7 +188,16 @@ class ContactInfoState extends ChangeNotifier { String _imagePath; int _unreadMessages = 0; - ContactInfoState({this.profileOnion, this.onion, nickname = "", isGroup = false, isInvitation = false, isBlocked = false, status = "", imagePath = "",}) { + ContactInfoState({ + this.profileOnion, + this.onion, + nickname = "", + isGroup = false, + isInvitation = false, + isBlocked = false, + status = "", + imagePath = "", + }) { this._nickname = nickname; this._isGroup = isGroup; this._isInvitation = isInvitation; @@ -212,8 +235,6 @@ class ContactInfoState extends ChangeNotifier { /// ACN /// ///////////// - - class AppModel { final Cwtch cwtch; AppModel({this.cwtch}); diff --git a/lib/opaque.dart b/lib/opaque.dart index 0282dcd..477c599 100644 --- a/lib/opaque.dart +++ b/lib/opaque.dart @@ -2,525 +2,1340 @@ // TO EDIT THE THEME, SEE https://git.openprivacy.ca/openprivacy/opaque/ // FOR HOW THIS FILE IS GENERATED, SEE ../regenerate_opaque_theme.sh - import 'dart:ui'; import 'dart:core'; import 'package:flutter/material.dart'; + abstract class OpaqueThemeType { - static final Color red = Color(0xFFFF0000); - Color backgroundMainColor(){return red;} - Color backgroundPaneColor(){return red;} - Color backgroundHilightElementColor(){return red;} + static final Color red = Color(0xFFFF0000); + Color backgroundMainColor() { + return red; + } - Color dividerColor(){return red;} + Color backgroundPaneColor() { + return red; + } - Color mainTextColor(){return red;} - Color altTextColor(){return red;} - Color hilightElementTextColor(){return red;} + Color backgroundHilightElementColor() { + return red; + } - Color defaultButtonColor(){return red;} - Color defaultButtonActiveColor(){return red;} - Color defaultButtonTextColor(){return red;} - Color defaultButtonDisabledColor(){return red;} - Color defaultButtonDisabledTextColor(){return red;} - Color altButtonColor(){return red;} - Color altButtonTextColor(){return red;} - Color altButtonDisabledColor(){return red;} - Color altButtonDisabledTextColor(){return red;} + Color dividerColor() { + return red; + } - Color textfieldBackgroundColor(){return red;} - Color textfieldBorderColor(){return red;} - Color textfieldTextColor(){return red;} - Color textfieldErrorColor(){return red;} - Color textfieldButtonColor(){return red;} - Color textfieldButtonTextColor(){return red;} + Color mainTextColor() { + return red; + } - Color scrollbarDefaultColor(){return red;} - Color scrollbarActiveColor(){return red;} + Color altTextColor() { + return red; + } - Color portraitOnlineBorderColor(){return red;} - Color portraitOnlineBackgroundColor(){return red;} - Color portraitOnlineTextColor(){return red;} - Color portraitConnectingBorderColor(){return red;} - Color portraitConnectingBackgroundColor(){return red;} - Color portraitConnectingTextColor(){return red;} - Color portraitOfflineBorderColor(){return red;} - Color portraitOfflineBackgroundColor(){return red;} - Color portraitOfflineTextColor(){return red;} - Color portraitBlockedBorderColor(){return red;} - Color portraitBlockedBackgroundColor(){return red;} - Color portraitBlockedTextColor(){return red;} + Color hilightElementTextColor() { + return red; + } - Color portraitOnlineBadgeColor(){return red;} - Color portraitOfflineBadgeColor(){return red;} + Color defaultButtonColor() { + return red; + } + Color defaultButtonActiveColor() { + return red; + } - Color portraitContactBadgeColor(){return red;} - Color portraitContactBadgeTextColor(){return red;} - Color portraitProfileBadgeColor(){return red;} - Color portraitProfileBadgeTextColor(){return red;} + Color defaultButtonTextColor() { + return red; + } - Color portraitOverlayOfflineColor(){return red;} + Color defaultButtonDisabledColor() { + return red; + } - Color dropShadowColor(){return red;} - Color dropShadowPaneColor(){return red;} - Color toggleColor(){return red;} - Color toggleOnColor(){return red;} - Color toggleOffColor(){return red;} - Color sliderButtonColor(){return red;} - Color sliderBarLeftColor(){return red;} - Color sliderBarRightColor(){return red;} - Color boxCheckedColor(){return red;} + Color defaultButtonDisabledTextColor() { + return red; + } + Color altButtonColor() { + return red; + } - Color toolbarIconColor(){return red;} - Color toolbarMainColor(){return red;} - Color toolbarAltColor(){return red;} + Color altButtonTextColor() { + return red; + } - Color statusbarDisconnectedInternetColor(){return red;} - Color statusbarDisconnectedInternetFontColor(){return red;} - Color statusbarDisconnectedTorFontColor(){return red;} - Color statusbarDisconnectedTorColor(){return red;} - Color statusbarConnectingColor(){return red;} - Color statusbarConnectingFontColor(){return red;} - Color statusbarOnlineColor(){return red;} - Color statusbarOnlineFontColor(){return red;} + Color altButtonDisabledColor() { + return red; + } - Color chatOverlayWarningTextColor(){return red;} - Color messageFromMeBackgroundColor(){return red;} - Color messageFromMeTextColor(){return red;} - Color messageFromOtherBackgroundColor(){return red;} - Color messageFromOtherTextColor(){return red;} + Color altButtonDisabledTextColor() { + return red; + } - Color messageStatusNormalColor(){return red;} - Color messageStatusBlockedColor(){return red;} - Color messageStatusBlockedTextColor(){return red;} - Color messageStatusAlertColor(){return red;} - Color messageStatusAlertTextColor(){return red;} + Color textfieldBackgroundColor() { + return red; + } + Color textfieldBorderColor() { + return red; + } - // ... more to come + Color textfieldTextColor() { + return red; + } + Color textfieldErrorColor() { + return red; + } + + Color textfieldButtonColor() { + return red; + } + + Color textfieldButtonTextColor() { + return red; + } + + Color scrollbarDefaultColor() { + return red; + } + + Color scrollbarActiveColor() { + return red; + } + + Color portraitOnlineBorderColor() { + return red; + } + + Color portraitOnlineBackgroundColor() { + return red; + } + + Color portraitOnlineTextColor() { + return red; + } + + Color portraitConnectingBorderColor() { + return red; + } + + Color portraitConnectingBackgroundColor() { + return red; + } + + Color portraitConnectingTextColor() { + return red; + } + + Color portraitOfflineBorderColor() { + return red; + } + + Color portraitOfflineBackgroundColor() { + return red; + } + + Color portraitOfflineTextColor() { + return red; + } + + Color portraitBlockedBorderColor() { + return red; + } + + Color portraitBlockedBackgroundColor() { + return red; + } + + Color portraitBlockedTextColor() { + return red; + } + + Color portraitOnlineBadgeColor() { + return red; + } + + Color portraitOfflineBadgeColor() { + return red; + } + + Color portraitContactBadgeColor() { + return red; + } + + Color portraitContactBadgeTextColor() { + return red; + } + + Color portraitProfileBadgeColor() { + return red; + } + + Color portraitProfileBadgeTextColor() { + return red; + } + + Color portraitOverlayOfflineColor() { + return red; + } + + Color dropShadowColor() { + return red; + } + + Color dropShadowPaneColor() { + return red; + } + + Color toggleColor() { + return red; + } + + Color toggleOnColor() { + return red; + } + + Color toggleOffColor() { + return red; + } + + Color sliderButtonColor() { + return red; + } + + Color sliderBarLeftColor() { + return red; + } + + Color sliderBarRightColor() { + return red; + } + + Color boxCheckedColor() { + return red; + } + + Color toolbarIconColor() { + return red; + } + + Color toolbarMainColor() { + return red; + } + + Color toolbarAltColor() { + return red; + } + + Color statusbarDisconnectedInternetColor() { + return red; + } + + Color statusbarDisconnectedInternetFontColor() { + return red; + } + + Color statusbarDisconnectedTorFontColor() { + return red; + } + + Color statusbarDisconnectedTorColor() { + return red; + } + + Color statusbarConnectingColor() { + return red; + } + + Color statusbarConnectingFontColor() { + return red; + } + + Color statusbarOnlineColor() { + return red; + } + + Color statusbarOnlineFontColor() { + return red; + } + + Color chatOverlayWarningTextColor() { + return red; + } + + Color messageFromMeBackgroundColor() { + return red; + } + + Color messageFromMeTextColor() { + return red; + } + + Color messageFromOtherBackgroundColor() { + return red; + } + + Color messageFromOtherTextColor() { + return red; + } + + Color messageStatusNormalColor() { + return red; + } + + Color messageStatusBlockedColor() { + return red; + } + + Color messageStatusBlockedTextColor() { + return red; + } + + Color messageStatusAlertColor() { + return red; + } + + Color messageStatusAlertTextColor() { + return red; + } + + // ... more to come } - - - class CwtchDark extends OpaqueThemeType { - static final Color darkGreyPurple = Color(0xFF281831); - static final Color deepPurple = Color(0xFF422850); - static final Color mauvePurple = Color(0xFF8E64A5); - static final Color purple = Color(0xFFDFB9DE); - static final Color whitePurple = Color(0xFFE3DFE4); - static final Color softPurple = Color(0xFFFDF3FC); - static final Color pink = Color(0xFFE85DA1); - static final Color hotPink = Color(0xFFD01972); - static final Color lightGrey = Color(0xFF9E9E9E); - static final Color softGreen = Color(0xFFA0FFB0); - static final Color softRed = Color(0xFFFFA0B0); + static final Color darkGreyPurple = Color(0xFF281831); + static final Color deepPurple = Color(0xFF422850); + static final Color mauvePurple = Color(0xFF8E64A5); + static final Color purple = Color(0xFFDFB9DE); + static final Color whitePurple = Color(0xFFE3DFE4); + static final Color softPurple = Color(0xFFFDF3FC); + static final Color pink = Color(0xFFE85DA1); + static final Color hotPink = Color(0xFFD01972); + static final Color lightGrey = Color(0xFF9E9E9E); + static final Color softGreen = Color(0xFFA0FFB0); + static final Color softRed = Color(0xFFFFA0B0); - Color backgroundMainColor() { return darkGreyPurple; } - Color backgroundPaneColor() { return darkGreyPurple; } - Color backgroundHilightElementColor() { return deepPurple; } + Color backgroundMainColor() { + return darkGreyPurple; + } - Color dividerColor() { return deepPurple; } + Color backgroundPaneColor() { + return darkGreyPurple; + } - Color mainTextColor() { return whitePurple; } - Color altTextColor() { return whitePurple; } - Color hilightElementTextColor() { return purple; } - Color defaultButtonColor() { return hotPink; } - Color defaultButtonActiveColor() { return pink; } - Color defaultButtonTextColor() { return whitePurple; } - Color defaultButtonDisabledColor() { return deepPurple; } - Color defaultButtonDisabledTextColor() { return darkGreyPurple; } - Color altButtonColor() { return darkGreyPurple; } - Color altButtonTextColor() { return purple; } - Color altButtonDisabledColor() { return darkGreyPurple; } - Color altButtonDisabledTextColor() { return purple; } + Color backgroundHilightElementColor() { + return deepPurple; + } - Color textfieldBackgroundColor() { return deepPurple; } - Color textfieldBorderColor() { return deepPurple; } - Color textfieldTextColor() { return purple; } - Color textfieldErrorColor() { return hotPink; } - Color textfieldButtonColor() { return purple; } - Color textfieldButtonTextColor() { return darkGreyPurple; } + Color dividerColor() { + return deepPurple; + } - Color scrollbarDefaultColor() { return purple; } - Color scrollbarActiveColor() { return hotPink; } + Color mainTextColor() { + return whitePurple; + } - Color portraitOnlineBorderColor() { return whitePurple; } - Color portraitOnlineBackgroundColor() { return whitePurple; } - Color portraitOnlineTextColor() { return whitePurple; } - Color portraitConnectingBorderColor() { return purple; } //mauvePurple - Color portraitConnectingBackgroundColor() { return purple; } //darkGreyPurple - Color portraitConnectingTextColor() { return purple; } - Color portraitOfflineBorderColor() { return purple; } - Color portraitOfflineBackgroundColor() { return purple; } - Color portraitOfflineTextColor() { return purple; } - Color portraitBlockedBorderColor() { return lightGrey; } - Color portraitBlockedBackgroundColor() { return lightGrey; } - Color portraitBlockedTextColor() { return lightGrey; } + Color altTextColor() { + return whitePurple; + } - Color portraitOnlineBadgeColor() { return softGreen; } - Color portraitOfflineBadgeColor() { return softRed; } + Color hilightElementTextColor() { + return purple; + } - Color portraitContactBadgeColor() { return hotPink; } - Color portraitContactBadgeTextColor() { return whitePurple; } - Color portraitProfileBadgeColor() { return mauvePurple; } - Color portraitProfileBadgeTextColor() { return darkGreyPurple; } + Color defaultButtonColor() { + return hotPink; + } - Color portraitOverlayOfflineColor() { return mauvePurple; } + Color defaultButtonActiveColor() { + return pink; + } - Color dropShadowColor() { return mauvePurple; } - Color dropShadowPaneColor() { return darkGreyPurple; } + Color defaultButtonTextColor() { + return whitePurple; + } - Color toggleColor() { return darkGreyPurple; } - Color toggleOnColor() { return whitePurple; } - Color toggleOffColor() { return deepPurple; } - Color sliderButtonColor() { return whitePurple; } - Color sliderBarLeftColor() { return mauvePurple; } - Color sliderBarRightColor() { return mauvePurple; } - Color boxCheckedColor() { return hotPink; } + Color defaultButtonDisabledColor() { + return deepPurple; + } - Color toolbarIconColor() { return whitePurple; } - Color toolbarMainColor() { return darkGreyPurple; } - Color toolbarAltColor() { return deepPurple; } + Color defaultButtonDisabledTextColor() { + return darkGreyPurple; + } - Color statusbarDisconnectedInternetColor() { return whitePurple; } - Color statusbarDisconnectedInternetFontColor() { return deepPurple; } - Color statusbarDisconnectedTorColor() { return darkGreyPurple; } - Color statusbarDisconnectedTorFontColor() { return whitePurple; } - Color statusbarConnectingColor() { return deepPurple; } - Color statusbarConnectingFontColor() { return whitePurple; } - Color statusbarOnlineColor() { return mauvePurple; } - Color statusbarOnlineFontColor() { return whitePurple; } + Color altButtonColor() { + return darkGreyPurple; + } - Color chatOverlayWarningTextColor() { return purple; } + Color altButtonTextColor() { + return purple; + } - Color messageFromMeBackgroundColor() { return mauvePurple; } - Color messageFromMeTextColor() { return whitePurple; } - Color messageFromOtherBackgroundColor() { return deepPurple; } - Color messageFromOtherTextColor() { return whitePurple; } + Color altButtonDisabledColor() { + return darkGreyPurple; + } - Color messageStatusNormalColor() { return deepPurple; } - Color messageStatusBlockedColor() { return lightGrey; } - Color messageStatusBlockedTextColor() { return whitePurple; } - Color messageStatusAlertColor() { return mauvePurple; } - Color messageStatusAlertTextColor() { return whitePurple; } + Color altButtonDisabledTextColor() { + return purple; + } + + Color textfieldBackgroundColor() { + return deepPurple; + } + + Color textfieldBorderColor() { + return deepPurple; + } + + Color textfieldTextColor() { + return purple; + } + + Color textfieldErrorColor() { + return hotPink; + } + + Color textfieldButtonColor() { + return purple; + } + + Color textfieldButtonTextColor() { + return darkGreyPurple; + } + + Color scrollbarDefaultColor() { + return purple; + } + + Color scrollbarActiveColor() { + return hotPink; + } + + Color portraitOnlineBorderColor() { + return whitePurple; + } + + Color portraitOnlineBackgroundColor() { + return whitePurple; + } + + Color portraitOnlineTextColor() { + return whitePurple; + } + + Color portraitConnectingBorderColor() { + return purple; + } //mauvePurple + + Color portraitConnectingBackgroundColor() { + return purple; + } //darkGreyPurple + + Color portraitConnectingTextColor() { + return purple; + } + + Color portraitOfflineBorderColor() { + return purple; + } + + Color portraitOfflineBackgroundColor() { + return purple; + } + + Color portraitOfflineTextColor() { + return purple; + } + + Color portraitBlockedBorderColor() { + return lightGrey; + } + + Color portraitBlockedBackgroundColor() { + return lightGrey; + } + + Color portraitBlockedTextColor() { + return lightGrey; + } + + Color portraitOnlineBadgeColor() { + return softGreen; + } + + Color portraitOfflineBadgeColor() { + return softRed; + } + + Color portraitContactBadgeColor() { + return hotPink; + } + + Color portraitContactBadgeTextColor() { + return whitePurple; + } + + Color portraitProfileBadgeColor() { + return mauvePurple; + } + + Color portraitProfileBadgeTextColor() { + return darkGreyPurple; + } + + Color portraitOverlayOfflineColor() { + return mauvePurple; + } + + Color dropShadowColor() { + return mauvePurple; + } + + Color dropShadowPaneColor() { + return darkGreyPurple; + } + + Color toggleColor() { + return darkGreyPurple; + } + + Color toggleOnColor() { + return whitePurple; + } + + Color toggleOffColor() { + return deepPurple; + } + + Color sliderButtonColor() { + return whitePurple; + } + + Color sliderBarLeftColor() { + return mauvePurple; + } + + Color sliderBarRightColor() { + return mauvePurple; + } + + Color boxCheckedColor() { + return hotPink; + } + + Color toolbarIconColor() { + return whitePurple; + } + + Color toolbarMainColor() { + return darkGreyPurple; + } + + Color toolbarAltColor() { + return deepPurple; + } + + Color statusbarDisconnectedInternetColor() { + return whitePurple; + } + + Color statusbarDisconnectedInternetFontColor() { + return deepPurple; + } + + Color statusbarDisconnectedTorColor() { + return darkGreyPurple; + } + + Color statusbarDisconnectedTorFontColor() { + return whitePurple; + } + + Color statusbarConnectingColor() { + return deepPurple; + } + + Color statusbarConnectingFontColor() { + return whitePurple; + } + + Color statusbarOnlineColor() { + return mauvePurple; + } + + Color statusbarOnlineFontColor() { + return whitePurple; + } + + Color chatOverlayWarningTextColor() { + return purple; + } + + Color messageFromMeBackgroundColor() { + return mauvePurple; + } + + Color messageFromMeTextColor() { + return whitePurple; + } + + Color messageFromOtherBackgroundColor() { + return deepPurple; + } + + Color messageFromOtherTextColor() { + return whitePurple; + } + + Color messageStatusNormalColor() { + return deepPurple; + } + + Color messageStatusBlockedColor() { + return lightGrey; + } + + Color messageStatusBlockedTextColor() { + return whitePurple; + } + + Color messageStatusAlertColor() { + return mauvePurple; + } + + Color messageStatusAlertTextColor() { + return whitePurple; + } } - - - class CwtchLight extends OpaqueThemeType { - static final Color whitePurple = Color(0xFFFFFDFF); - static final Color softPurple = Color(0xFFFDF3FC); - static final Color purple = Color(0xFFDFB9DE); - static final Color brightPurple = Color(0xFF760388); - static final Color darkPurple = Color(0xFF350052); - static final Color greyPurple = Color(0xFF775F84); - static final Color pink = Color(0xFFE85DA1); - static final Color hotPink = Color(0xFFD01972); - static final Color lightGrey = Color(0xFFB3B6B3); - static final Color softGreen = Color(0xFFA0FFB0); - static final Color softRed = Color(0xFFFFA0B0); + static final Color whitePurple = Color(0xFFFFFDFF); + static final Color softPurple = Color(0xFFFDF3FC); + static final Color purple = Color(0xFFDFB9DE); + static final Color brightPurple = Color(0xFF760388); + static final Color darkPurple = Color(0xFF350052); + static final Color greyPurple = Color(0xFF775F84); + static final Color pink = Color(0xFFE85DA1); + static final Color hotPink = Color(0xFFD01972); + static final Color lightGrey = Color(0xFFB3B6B3); + static final Color softGreen = Color(0xFFA0FFB0); + static final Color softRed = Color(0xFFFFA0B0); - Color backgroundMainColor() { return whitePurple; } - Color backgroundPaneColor() { return softPurple; } - Color backgroundHilightElementColor() { return softPurple; } + Color backgroundMainColor() { + return whitePurple; + } - Color dividerColor() { return purple; } + Color backgroundPaneColor() { + return softPurple; + } - Color mainTextColor() { return darkPurple; } - Color altTextColor() { return purple; } - Color hilightElementTextColor() { return darkPurple; } + Color backgroundHilightElementColor() { + return softPurple; + } - Color defaultButtonColor() { return hotPink; } - Color defaultButtonActiveColor() { return pink; } - Color defaultButtonTextColor() { return whitePurple; } - Color defaultButtonDisabledColor() { return purple; } - Color defaultButtonDisabledTextColor() { return whitePurple; } - Color altButtonColor() { return whitePurple; } - Color altButtonTextColor() { return purple; } - Color altButtonDisabledColor() { return softPurple; } - Color altButtonDisabledTextColor() { return purple; } + Color dividerColor() { + return purple; + } - Color textfieldBackgroundColor() { return whitePurple; } - Color textfieldBorderColor() { return purple; } - Color textfieldTextColor() { return purple; } - Color textfieldErrorColor() { return hotPink; } - Color textfieldButtonColor() { return hotPink; } - Color textfieldButtonTextColor() { return whitePurple; } + Color mainTextColor() { + return darkPurple; + } - Color scrollbarDefaultColor() { return darkPurple; } - Color scrollbarActiveColor() { return hotPink; } + Color altTextColor() { + return purple; + } - Color portraitOnlineBorderColor() { return darkPurple; } - Color portraitOnlineBackgroundColor() { return darkPurple; } - Color portraitOnlineTextColor() { return darkPurple; } - Color portraitConnectingBorderColor() { return greyPurple; } - Color portraitConnectingBackgroundColor() { return greyPurple; } - Color portraitConnectingTextColor() { return greyPurple; } - Color portraitOfflineBorderColor() { return greyPurple; } //purple - Color portraitOfflineBackgroundColor() { return greyPurple; } //purple - Color portraitOfflineTextColor() { return greyPurple; }//purple - Color portraitBlockedBorderColor() { return lightGrey; } - Color portraitBlockedBackgroundColor() { return lightGrey; } - Color portraitBlockedTextColor() { return lightGrey; } + Color hilightElementTextColor() { + return darkPurple; + } - Color portraitOnlineBadgeColor() { return softGreen; } - Color portraitOfflineBadgeColor() { return softRed; } + Color defaultButtonColor() { + return hotPink; + } - Color portraitContactBadgeColor() { return hotPink; } - Color portraitContactBadgeTextColor() { return whitePurple; } - Color portraitProfileBadgeColor() { return brightPurple; } - Color portraitProfileBadgeTextColor() { return whitePurple; } + Color defaultButtonActiveColor() { + return pink; + } - Color portraitOverlayOfflineColor() { return whitePurple; } + Color defaultButtonTextColor() { + return whitePurple; + } - Color dropShadowColor() { return purple; } - Color dropShadowPaneColor() { return purple; } + Color defaultButtonDisabledColor() { + return purple; + } - Color toggleColor() { return whitePurple; } - Color toggleOnColor() { return hotPink; } - Color toggleOffColor() { return purple; } - Color sliderButtonColor() { return pink; } - Color sliderBarLeftColor() { return purple; } - Color sliderBarRightColor() { return purple; } - Color boxCheckedColor() { return darkPurple; } + Color defaultButtonDisabledTextColor() { + return whitePurple; + } - Color toolbarIconColor() { return darkPurple; } - Color toolbarMainColor() { return whitePurple; } - Color toolbarAltColor() { return softPurple; } + Color altButtonColor() { + return whitePurple; + } - Color statusbarDisconnectedInternetColor() { return softPurple; } - Color statusbarDisconnectedInternetFontColor() { return darkPurple; } - Color statusbarDisconnectedTorColor() { return purple; } - Color statusbarDisconnectedTorFontColor() { return darkPurple; } - Color statusbarConnectingColor() { return greyPurple; } - Color statusbarConnectingFontColor() { return whitePurple; } - Color statusbarOnlineColor() { return darkPurple; } - Color statusbarOnlineFontColor() { return whitePurple; } + Color altButtonTextColor() { + return purple; + } - Color chatOverlayWarningTextColor() { return purple; } + Color altButtonDisabledColor() { + return softPurple; + } - Color messageFromMeBackgroundColor() { return darkPurple; } - Color messageFromMeTextColor() { return whitePurple; } - Color messageFromOtherBackgroundColor() { return purple; } - Color messageFromOtherTextColor() { return darkPurple; } + Color altButtonDisabledTextColor() { + return purple; + } - Color messageStatusNormalColor() { return purple; } - Color messageStatusBlockedColor() { return lightGrey; } - Color messageStatusBlockedTextColor() { return whitePurple; } - Color messageStatusAlertColor() { return hotPink; } - Color messageStatusAlertTextColor() { return whitePurple; } + Color textfieldBackgroundColor() { + return whitePurple; + } + + Color textfieldBorderColor() { + return purple; + } + + Color textfieldTextColor() { + return purple; + } + + Color textfieldErrorColor() { + return hotPink; + } + + Color textfieldButtonColor() { + return hotPink; + } + + Color textfieldButtonTextColor() { + return whitePurple; + } + + Color scrollbarDefaultColor() { + return darkPurple; + } + + Color scrollbarActiveColor() { + return hotPink; + } + + Color portraitOnlineBorderColor() { + return darkPurple; + } + + Color portraitOnlineBackgroundColor() { + return darkPurple; + } + + Color portraitOnlineTextColor() { + return darkPurple; + } + + Color portraitConnectingBorderColor() { + return greyPurple; + } + + Color portraitConnectingBackgroundColor() { + return greyPurple; + } + + Color portraitConnectingTextColor() { + return greyPurple; + } + + Color portraitOfflineBorderColor() { + return greyPurple; + } //purple + + Color portraitOfflineBackgroundColor() { + return greyPurple; + } //purple + + Color portraitOfflineTextColor() { + return greyPurple; + } //purple + + Color portraitBlockedBorderColor() { + return lightGrey; + } + + Color portraitBlockedBackgroundColor() { + return lightGrey; + } + + Color portraitBlockedTextColor() { + return lightGrey; + } + + Color portraitOnlineBadgeColor() { + return softGreen; + } + + Color portraitOfflineBadgeColor() { + return softRed; + } + + Color portraitContactBadgeColor() { + return hotPink; + } + + Color portraitContactBadgeTextColor() { + return whitePurple; + } + + Color portraitProfileBadgeColor() { + return brightPurple; + } + + Color portraitProfileBadgeTextColor() { + return whitePurple; + } + + Color portraitOverlayOfflineColor() { + return whitePurple; + } + + Color dropShadowColor() { + return purple; + } + + Color dropShadowPaneColor() { + return purple; + } + + Color toggleColor() { + return whitePurple; + } + + Color toggleOnColor() { + return hotPink; + } + + Color toggleOffColor() { + return purple; + } + + Color sliderButtonColor() { + return pink; + } + + Color sliderBarLeftColor() { + return purple; + } + + Color sliderBarRightColor() { + return purple; + } + + Color boxCheckedColor() { + return darkPurple; + } + + Color toolbarIconColor() { + return darkPurple; + } + + Color toolbarMainColor() { + return whitePurple; + } + + Color toolbarAltColor() { + return softPurple; + } + + Color statusbarDisconnectedInternetColor() { + return softPurple; + } + + Color statusbarDisconnectedInternetFontColor() { + return darkPurple; + } + + Color statusbarDisconnectedTorColor() { + return purple; + } + + Color statusbarDisconnectedTorFontColor() { + return darkPurple; + } + + Color statusbarConnectingColor() { + return greyPurple; + } + + Color statusbarConnectingFontColor() { + return whitePurple; + } + + Color statusbarOnlineColor() { + return darkPurple; + } + + Color statusbarOnlineFontColor() { + return whitePurple; + } + + Color chatOverlayWarningTextColor() { + return purple; + } + + Color messageFromMeBackgroundColor() { + return darkPurple; + } + + Color messageFromMeTextColor() { + return whitePurple; + } + + Color messageFromOtherBackgroundColor() { + return purple; + } + + Color messageFromOtherTextColor() { + return darkPurple; + } + + Color messageStatusNormalColor() { + return purple; + } + + Color messageStatusBlockedColor() { + return lightGrey; + } + + Color messageStatusBlockedTextColor() { + return whitePurple; + } + + Color messageStatusAlertColor() { + return hotPink; + } + + Color messageStatusAlertTextColor() { + return whitePurple; + } } - - - - - - class Opaque extends OpaqueThemeType { - Color backgroundMainColor() { return current().backgroundMainColor(); } - Color backgroundPaneColor() { return current().backgroundPaneColor(); } - Color backgroundHilightElementColor() { return current().backgroundHilightElementColor(); } + Color backgroundMainColor() { + return current().backgroundMainColor(); + } - Color dividerColor() { return current().dividerColor(); } + Color backgroundPaneColor() { + return current().backgroundPaneColor(); + } - Color mainTextColor() { return current().mainTextColor(); } - Color altTextColor() { return current().altTextColor(); } - Color hilightElementTextColor() { return current().hilightElementTextColor(); } + Color backgroundHilightElementColor() { + return current().backgroundHilightElementColor(); + } - Color defaultButtonColor() { return current().defaultButtonColor(); } - Color defaultButtonActiveColor() { return current().defaultButtonActiveColor(); } - Color defaultButtonTextColor() { return current().defaultButtonTextColor(); } - Color defaultButtonDisabledColor() { return current().defaultButtonDisabledColor(); } - Color defaultButtonDisabledTextColor() { return current().defaultButtonDisabledTextColor(); } - Color altButtonColor() { return current().altButtonColor(); } - Color altButtonTextColor() { return current().altButtonTextColor(); } - Color altButtonDisabledColor() { return current().altButtonDisabledColor(); } - Color altButtonDisabledTextColor() { return current().altButtonDisabledTextColor(); } + Color dividerColor() { + return current().dividerColor(); + } - Color textfieldBackgroundColor() { return current().textfieldBackgroundColor(); } - Color textfieldBorderColor() { return current().textfieldBorderColor(); } - Color textfieldTextColor() { return current().textfieldTextColor(); } - Color textfieldErrorColor() { return current().textfieldErrorColor(); } - Color textfieldButtonColor() { return current().textfieldButtonColor(); } - Color textfieldButtonTextColor() { return current().textfieldButtonTextColor(); } + Color mainTextColor() { + return current().mainTextColor(); + } + Color altTextColor() { + return current().altTextColor(); + } - Color dropShadowColor() { return current().dropShadowColor(); } - Color dropShadowPaneColor() { return current().dropShadowPaneColor(); } + Color hilightElementTextColor() { + return current().hilightElementTextColor(); + } - Color portraitOnlineBorderColor() { return current().portraitOnlineBorderColor(); } - Color portraitOnlineBackgroundColor() { return current().portraitOnlineBackgroundColor(); } - Color portraitOnlineTextColor() { return current().portraitOnlineTextColor(); } - Color portraitConnectingBorderColor() { return current().portraitConnectingBorderColor(); } - Color portraitConnectingBackgroundColor() { return current().portraitConnectingBackgroundColor(); } - Color portraitConnectingTextColor() { return current().portraitConnectingTextColor(); } - Color portraitOfflineBorderColor() { return current().portraitOfflineBorderColor(); } - Color portraitOfflineBackgroundColor() { return current().portraitOfflineBackgroundColor(); } - Color portraitOfflineTextColor() { return current().portraitOfflineTextColor(); } - Color portraitBlockedBorderColor() { return current().portraitBlockedBorderColor(); } - Color portraitBlockedBackgroundColor() { return current().portraitBlockedBackgroundColor(); } - Color portraitBlockedTextColor() { return current().portraitBlockedTextColor(); } + Color defaultButtonColor() { + return current().defaultButtonColor(); + } - Color portraitOnlineBadgeColor() { return current().portraitOnlineBadgeColor(); } - Color portraitOfflineBadgeColor() { return current().portraitOfflineBadgeColor(); } + Color defaultButtonActiveColor() { + return current().defaultButtonActiveColor(); + } - Color portraitContactBadgeColor() { return current().portraitContactBadgeColor(); } - Color portraitContactBadgeTextColor() { return current().portraitContactBadgeTextColor(); } - Color portraitProfileBadgeColor() { return current().portraitProfileBadgeColor(); } - Color portraitProfileBadgeTextColor() { return current().portraitProfileBadgeTextColor(); } + Color defaultButtonTextColor() { + return current().defaultButtonTextColor(); + } - Color portraitOverlayOfflineColor() { return current().portraitOverlayOfflineColor(); } + Color defaultButtonDisabledColor() { + return current().defaultButtonDisabledColor(); + } - Color toggleColor() { return current().toggleColor(); } - Color toggleOffColor() { return current().toggleOffColor(); } - Color toggleOnColor() { return current().toggleOnColor(); } - Color sliderButtonColor() { return current().sliderButtonColor(); } - Color sliderBarLeftColor() { return current().sliderBarLeftColor(); } - Color sliderBarRightColor() { return current().sliderBarRightColor(); } - Color boxCheckedColor() { return current().boxCheckedColor(); } + Color defaultButtonDisabledTextColor() { + return current().defaultButtonDisabledTextColor(); + } + Color altButtonColor() { + return current().altButtonColor(); + } - Color toolbarIconColor() { return current().toolbarIconColor(); } - Color toolbarMainColor() { return current().toolbarMainColor(); } - Color toolbarAltColor() { return current().toolbarAltColor(); } + Color altButtonTextColor() { + return current().altButtonTextColor(); + } - Color statusbarDisconnectedInternetColor() { return current().statusbarDisconnectedInternetColor(); } - Color statusbarDisconnectedInternetFontColor() { return current().statusbarDisconnectedInternetFontColor(); } - Color statusbarDisconnectedTorFontColor() { return current().statusbarDisconnectedTorFontColor(); } - Color statusbarDisconnectedTorColor() { return current().statusbarDisconnectedTorColor(); } - Color statusbarConnectingColor() { return current().statusbarConnectingColor(); } - Color statusbarConnectingFontColor() { return current().statusbarConnectingFontColor(); } - Color statusbarOnlineColor() { return current().statusbarOnlineColor(); } - Color statusbarOnlineFontColor() { return current().statusbarOnlineFontColor(); } + Color altButtonDisabledColor() { + return current().altButtonDisabledColor(); + } - Color chatOverlayWarningTextColor() { return current().chatOverlayWarningTextColor(); } - Color messageFromMeBackgroundColor() { return current().messageFromMeBackgroundColor(); } - Color messageFromMeTextColor() { return current().messageFromMeTextColor(); } - Color messageFromOtherBackgroundColor() { return current().messageFromOtherBackgroundColor(); } - Color messageFromOtherTextColor() { return current().messageFromOtherTextColor(); } + Color altButtonDisabledTextColor() { + return current().altButtonDisabledTextColor(); + } - Color messageStatusNormalColor() { return current().messageStatusNormalColor(); } - Color messageStatusBlockedColor() { return current().messageStatusBlockedColor(); } - Color messageStatusBlockedTextColor() { return current().messageStatusBlockedTextColor(); } - Color messageStatusAlertColor() { return current().messageStatusAlertColor(); } - Color messageStatusAlertTextColor() { return current().messageStatusAlertTextColor(); } + Color textfieldBackgroundColor() { + return current().textfieldBackgroundColor(); + } - Color scrollbarDefaultColor() { return current().scrollbarDefaultColor(); } - Color scrollbarActiveColor() { return current().scrollbarActiveColor(); } + Color textfieldBorderColor() { + return current().textfieldBorderColor(); + } + Color textfieldTextColor() { + return current().textfieldTextColor(); + } - var sidePaneMinSizeBase = [200, 400, 600]; - int sidePaneMinSize() { return sidePaneMinSizeBase[p[scale]]+200/*for debugging*/; } - var chatPaneMinSizeBase = [300, 400, 500]; - int chatPaneMinSize() { return chatPaneMinSizeBase[p[scale]]; } - int doublePaneMinSize() { return sidePaneMinSize() + chatPaneMinSize(); } + Color textfieldErrorColor() { + return current().textfieldErrorColor(); + } - static OpaqueThemeType _current; - static final OpaqueThemeType dark = CwtchDark(); - static final OpaqueThemeType light = CwtchLight(); - static void setDark() { _current = dark; } - static void setLight() { _current = light; } - static OpaqueThemeType current() { if (_current == null) {setDark();} return _current; } + Color textfieldButtonColor() { + return current().textfieldButtonColor(); + } - -int scale = 2; - static final String gcdOS = "linux"; + Color textfieldButtonTextColor() { + return current().textfieldButtonTextColor(); + } - - - - - - - - - - - + Color dropShadowColor() { + return current().dropShadowColor(); + } - var p = [0, 1, 1, 1, 2]; - var t = [0, 0, 1, 2, 2]; + Color dropShadowPaneColor() { + return current().dropShadowPaneColor(); + } - - - + Color portraitOnlineBorderColor() { + return current().portraitOnlineBorderColor(); + } - var paddingMinimalBase = [1, 4, 6]; - int paddingMinimal() { return paddingMinimalBase[p[scale]]; } - var paddingSmallBase = [3, 10, 15]; - int paddingSmall() { return paddingSmallBase[p[scale]]; } - var paddingStandardBase = [8, 20, 30]; - int paddingStandard() { return paddingStandardBase[p[scale]]; } - var paddingLargeBase = [10, 30, 40]; - int paddingLarge() { return paddingLargeBase[p[scale]]; } + Color portraitOnlineBackgroundColor() { + return current().portraitOnlineBackgroundColor(); + } - var paddingClickTargetBase = gcdOS == "android" ? [10, 40, 100] : [3, 10, 15]; - int paddingClickTarget() { return paddingClickTargetBase[p[scale]]; } + Color portraitOnlineTextColor() { + return current().portraitOnlineTextColor(); + } - - - + Color portraitConnectingBorderColor() { + return current().portraitConnectingBorderColor(); + } - var textSmallPtBase = [8, 12, 16]; - int textSmallPt() { return textSmallPtBase[t[scale]]; } - var textMediumPtBase = [10, 16, 24]; - int textMediumPt() { return textMediumPtBase[t[scale]]; } - var textLargePtBase = [16, 24, 32]; - int textLargePt() { return textLargePtBase[t[scale]]; } + Color portraitConnectingBackgroundColor() { + return current().portraitConnectingBackgroundColor(); + } - var textSubHeaderPtBase = [12, 18, 26]; - int textSubHeaderPt() { return textHeaderPtBase[t[scale]]; } - var textHeaderPtBase = [16, 24, 32]; - int textHeaderPt() { return textHeaderPtBase[t[scale]]; } + Color portraitConnectingTextColor() { + return current().portraitConnectingTextColor(); + } - - - + Color portraitOfflineBorderColor() { + return current().portraitOfflineBorderColor(); + } - var uiIconSizeSBase = [8, 16, 24]; - int uiIconSizeS() { return uiIconSizeSBase[p[scale]]; } - var uiIconSizeMBase = [24, 32, 48]; - int uiIconSizeM() { return uiIconSizeMBase[p[scale]]; } - var uiIconSizeLBase = [32, 48, 60]; - int uiIconSizeL() { return uiIconSizeLBase[p[scale]]; } + Color portraitOfflineBackgroundColor() { + return current().portraitOfflineBackgroundColor(); + } - var uiEmojiSizeBase = [24, 32, 48]; - int uiEmojiSize() { return uiEmojiSizeBase[p[scale]]; } - var contactPortraitSizeBase = [60, 72, 84]; - int contactPortraitSize() { return contactPortraitSizeBase[p[scale]]; } + Color portraitOfflineTextColor() { + return current().portraitOfflineTextColor(); + } - - - + Color portraitBlockedBorderColor() { + return current().portraitBlockedBorderColor(); + } - - int badgeTextSize() { return 12; } - int statusTextSize() { return 12; } - - - int chatSize() { return textMediumPt(); } - - int tabSize() { return textMediumPt(); } - - + Color portraitBlockedBackgroundColor() { + return current().portraitBlockedBackgroundColor(); + } + + Color portraitBlockedTextColor() { + return current().portraitBlockedTextColor(); + } + + Color portraitOnlineBadgeColor() { + return current().portraitOnlineBadgeColor(); + } + + Color portraitOfflineBadgeColor() { + return current().portraitOfflineBadgeColor(); + } + + Color portraitContactBadgeColor() { + return current().portraitContactBadgeColor(); + } + + Color portraitContactBadgeTextColor() { + return current().portraitContactBadgeTextColor(); + } + + Color portraitProfileBadgeColor() { + return current().portraitProfileBadgeColor(); + } + + Color portraitProfileBadgeTextColor() { + return current().portraitProfileBadgeTextColor(); + } + + Color portraitOverlayOfflineColor() { + return current().portraitOverlayOfflineColor(); + } + + Color toggleColor() { + return current().toggleColor(); + } + + Color toggleOffColor() { + return current().toggleOffColor(); + } + + Color toggleOnColor() { + return current().toggleOnColor(); + } + + Color sliderButtonColor() { + return current().sliderButtonColor(); + } + + Color sliderBarLeftColor() { + return current().sliderBarLeftColor(); + } + + Color sliderBarRightColor() { + return current().sliderBarRightColor(); + } + + Color boxCheckedColor() { + return current().boxCheckedColor(); + } + + Color toolbarIconColor() { + return current().toolbarIconColor(); + } + + Color toolbarMainColor() { + return current().toolbarMainColor(); + } + + Color toolbarAltColor() { + return current().toolbarAltColor(); + } + + Color statusbarDisconnectedInternetColor() { + return current().statusbarDisconnectedInternetColor(); + } + + Color statusbarDisconnectedInternetFontColor() { + return current().statusbarDisconnectedInternetFontColor(); + } + + Color statusbarDisconnectedTorFontColor() { + return current().statusbarDisconnectedTorFontColor(); + } + + Color statusbarDisconnectedTorColor() { + return current().statusbarDisconnectedTorColor(); + } + + Color statusbarConnectingColor() { + return current().statusbarConnectingColor(); + } + + Color statusbarConnectingFontColor() { + return current().statusbarConnectingFontColor(); + } + + Color statusbarOnlineColor() { + return current().statusbarOnlineColor(); + } + + Color statusbarOnlineFontColor() { + return current().statusbarOnlineFontColor(); + } + + Color chatOverlayWarningTextColor() { + return current().chatOverlayWarningTextColor(); + } + + Color messageFromMeBackgroundColor() { + return current().messageFromMeBackgroundColor(); + } + + Color messageFromMeTextColor() { + return current().messageFromMeTextColor(); + } + + Color messageFromOtherBackgroundColor() { + return current().messageFromOtherBackgroundColor(); + } + + Color messageFromOtherTextColor() { + return current().messageFromOtherTextColor(); + } + + Color messageStatusNormalColor() { + return current().messageStatusNormalColor(); + } + + Color messageStatusBlockedColor() { + return current().messageStatusBlockedColor(); + } + + Color messageStatusBlockedTextColor() { + return current().messageStatusBlockedTextColor(); + } + + Color messageStatusAlertColor() { + return current().messageStatusAlertColor(); + } + + Color messageStatusAlertTextColor() { + return current().messageStatusAlertTextColor(); + } + + Color scrollbarDefaultColor() { + return current().scrollbarDefaultColor(); + } + + Color scrollbarActiveColor() { + return current().scrollbarActiveColor(); + } + + var sidePaneMinSizeBase = [200, 400, 600]; + int sidePaneMinSize() { + return sidePaneMinSizeBase[p[scale]] + 200 /*for debugging*/; + } + + var chatPaneMinSizeBase = [300, 400, 500]; + int chatPaneMinSize() { + return chatPaneMinSizeBase[p[scale]]; + } + + int doublePaneMinSize() { + return sidePaneMinSize() + chatPaneMinSize(); + } + + static OpaqueThemeType _current; + static final OpaqueThemeType dark = CwtchDark(); + static final OpaqueThemeType light = CwtchLight(); + static void setDark() { + _current = dark; + } + + static void setLight() { + _current = light; + } + + static OpaqueThemeType current() { + if (_current == null) { + setDark(); + } + return _current; + } + + int scale = 2; + static final String gcdOS = "linux"; + + var p = [0, 1, 1, 1, 2]; + var t = [0, 0, 1, 2, 2]; + + var paddingMinimalBase = [1, 4, 6]; + int paddingMinimal() { + return paddingMinimalBase[p[scale]]; + } + + var paddingSmallBase = [3, 10, 15]; + int paddingSmall() { + return paddingSmallBase[p[scale]]; + } + + var paddingStandardBase = [8, 20, 30]; + int paddingStandard() { + return paddingStandardBase[p[scale]]; + } + + var paddingLargeBase = [10, 30, 40]; + int paddingLarge() { + return paddingLargeBase[p[scale]]; + } + + var paddingClickTargetBase = gcdOS == "android" ? [10, 40, 100] : [3, 10, 15]; + int paddingClickTarget() { + return paddingClickTargetBase[p[scale]]; + } + + var textSmallPtBase = [8, 12, 16]; + int textSmallPt() { + return textSmallPtBase[t[scale]]; + } + + var textMediumPtBase = [10, 16, 24]; + int textMediumPt() { + return textMediumPtBase[t[scale]]; + } + + var textLargePtBase = [16, 24, 32]; + int textLargePt() { + return textLargePtBase[t[scale]]; + } + + var textSubHeaderPtBase = [12, 18, 26]; + int textSubHeaderPt() { + return textHeaderPtBase[t[scale]]; + } + + var textHeaderPtBase = [16, 24, 32]; + int textHeaderPt() { + return textHeaderPtBase[t[scale]]; + } + + var uiIconSizeSBase = [8, 16, 24]; + int uiIconSizeS() { + return uiIconSizeSBase[p[scale]]; + } + + var uiIconSizeMBase = [24, 32, 48]; + int uiIconSizeM() { + return uiIconSizeMBase[p[scale]]; + } + + var uiIconSizeLBase = [32, 48, 60]; + int uiIconSizeL() { + return uiIconSizeLBase[p[scale]]; + } + + var uiEmojiSizeBase = [24, 32, 48]; + int uiEmojiSize() { + return uiEmojiSizeBase[p[scale]]; + } + + var contactPortraitSizeBase = [60, 72, 84]; + int contactPortraitSize() { + return contactPortraitSizeBase[p[scale]]; + } + + int badgeTextSize() { + return 12; + } + + int statusTextSize() { + return 12; + } + + int chatSize() { + return textMediumPt(); + } + + int tabSize() { + return textMediumPt(); + } } - - - -/// TODO: Wire into libCwtch saveSettings / updateTheme etc... -class OpaqueTheme extends ChangeNotifier { - OpaqueThemeType theme; - void setDark() { theme = Opaque.dark; notifyListeners();} - void setLight() { theme = Opaque.light; notifyListeners();} - OpaqueThemeType current() { return theme; } - - OpaqueTheme(this.theme); -} \ No newline at end of file diff --git a/lib/settings.dart b/lib/settings.dart index fd47200..62e789a 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -4,11 +4,40 @@ import 'dart:core'; import 'package:flutter/material.dart'; import 'package:package_info_plus/package_info_plus.dart'; +import 'opaque.dart'; + class Settings extends ChangeNotifier { Locale locale; PackageInfo packageInfo; + OpaqueThemeType theme; + + void setDark() { + theme = Opaque.dark; + notifyListeners(); + } + + void setLight() { + theme = Opaque.light; + notifyListeners(); + } + + OpaqueThemeType current() { + return theme; + } + + handleUpdate(dynamic settings) { + print("Settings ${settings}"); + switchLocale(Locale(settings["Locale"])); + if (settings["Theme"] == "light") { + this.setLight(); + } else { + this.setDark(); + } + notifyListeners(); + } + initPackageInfo() { PackageInfo.fromPlatform().then((PackageInfo newPackageInfo) { packageInfo = newPackageInfo; @@ -21,5 +50,22 @@ class Settings extends ChangeNotifier { notifyListeners(); } - Settings(this.locale); -} \ No newline at end of file + Settings(this.locale, this.theme); + + dynamic asJson() { + var themeString = "light"; + if (theme == Opaque.dark) { + themeString = "dark"; + } + + return { + "Locale": this.locale.languageCode, + "Theme": themeString, + "PreviousPid": -1, + "ExperimentsEnabled": false, + "Experiments": {}, + "StateRootPane": 0, + "FirstTime": false + }; + } +} diff --git a/lib/views/addcontactview.dart b/lib/views/addcontactview.dart index 48300cf..f15c136 100644 --- a/lib/views/addcontactview.dart +++ b/lib/views/addcontactview.dart @@ -18,13 +18,14 @@ class _AddContactViewState extends State { } Widget _buildForm() { - return Center(child:Wrap( + return Center( + child: Wrap( direction: Axis.vertical, spacing: 20.0, runSpacing: 20.0, children: [ Text(AppLocalizations.of(context).profileName), - Text("peer handle or group invite or server bundle"),//todo + Text("peer handle or group invite or server bundle"), //todo Text(AppLocalizations.of(context).createGroupBtn), ], )); diff --git a/lib/views/addeditprofileview.dart b/lib/views/addeditprofileview.dart index 41652de..eb3af99 100644 --- a/lib/views/addeditprofileview.dart +++ b/lib/views/addeditprofileview.dart @@ -12,6 +12,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../main.dart'; import '../opaque.dart'; +import '../settings.dart'; class AddEditProfileView extends StatefulWidget { const AddEditProfileView({Key key}) : super(key: key); @@ -46,7 +47,9 @@ class _AddEditProfileViewState extends State { ctrlrOnion.text = Provider.of(context).onion; return Scaffold( appBar: AppBar( - title: Text(Provider.of(context).onion.isEmpty ? AppLocalizations.of(context).addProfileTitle : AppLocalizations.of(context).editProfileTitle), + title: Text(Provider.of(context).onion.isEmpty + ? AppLocalizations.of(context).addProfileTitle + : AppLocalizations.of(context).editProfileTitle), ), body: _buildForm(), ); @@ -62,8 +65,9 @@ class _AddEditProfileViewState extends State { // We use Visibility to hide optional structures when they are not requested. // We used SizedBox for inter-widget height padding in columns, otherwise elements can render a little too close together. Widget _buildForm() { - return Consumer(builder: (context, theme, child) { - return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) { + return Consumer(builder: (context, theme, child) { + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints viewportConstraints) { return Scrollbar( isAlwaysShown: true, child: SingleChildScrollView( @@ -77,180 +81,306 @@ class _AddEditProfileViewState extends State { child: Container( margin: EdgeInsets.all(30), padding: EdgeInsets.all(20), - child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Visibility( - visible: Provider.of(context).onion.isNotEmpty, - child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - width: 120, - height: 120, - child: ClipOval( - child: SizedBox( - width: 120, - height: 120, - child: Container( - color: Colors.white, - width: 120, - height: 120, - child: Image( - image: AssetImage("assets/" + Provider.of(context).imagePath), - width: 100, - height: 100, - ))), - ), - ) - ])), - Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - CwtchLabel(label: AppLocalizations.of(context).displayNameLabel), - SizedBox( - height: 20, - ), - CwtchTextField( - controller: ctrlrNick, - labelText: AppLocalizations.of(context).yourDisplayName, - validator: (value) { - if (value.isEmpty) { - return "Please enter a display name"; - } - return null; - }, - ), - ]), - Visibility( - visible: Provider.of(context).onion.isNotEmpty, - child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - height: 20, - ), - CwtchLabel(label: AppLocalizations.of(context).addressLabel), - SizedBox( - height: 20, - ), - CwtchButtonTextField( - controller: ctrlrOnion, - onPressed: _copyOnion, - icon: Icon(Icons.copy), - tooltip: AppLocalizations.of(context).copyBtn, - ) - ])), - // We only allow setting password types on profile creation - Visibility( - visible: Provider.of(context).onion.isEmpty, - child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - Radio( - value: false, - groupValue: usePassword, - onChanged: _handleSwitchPassword, - ), - Text( - AppLocalizations.of(context).radioNoPassword, - style: TextStyle(color: theme.current().mainTextColor()), - ), - Radio( - value: true, - groupValue: usePassword, - onChanged: _handleSwitchPassword, - ), - Text( - AppLocalizations.of(context).radioUsePassword, - style: TextStyle(color: theme.current().mainTextColor()), - ), - ])), - SizedBox( - height: 20, - ), - Visibility( - visible: usePassword, - child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ Visibility( - visible: Provider.of(context, listen: false).onion.isNotEmpty, - child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - CwtchLabel(label: AppLocalizations.of(context).currentPasswordLabel), + visible: + Provider.of(context) + .onion + .isNotEmpty, + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + SizedBox( + width: 120, + height: 120, + child: ClipOval( + child: SizedBox( + width: 120, + height: 120, + child: Container( + color: Colors.white, + width: 120, + height: 120, + child: Image( + image: AssetImage("assets/" + + Provider.of( + context) + .imagePath), + width: 100, + height: 100, + ))), + ), + ) + ])), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + CwtchLabel( + label: AppLocalizations.of(context) + .displayNameLabel), SizedBox( height: 20, ), - CwtchPasswordField( - controller: ctrlrOldPass, + CwtchTextField( + controller: ctrlrNick, + labelText: + AppLocalizations.of(context) + .yourDisplayName, validator: (value) { - // Password field can be empty when just updating the profile, not on creation - if (Provider.of(context, listen: false).onion.isEmpty && value.isEmpty && usePassword) { - return AppLocalizations.of(context).passwordErrorEmpty; + if (value.isEmpty) { + return "Please enter a display name"; } return null; }, ), - SizedBox( - height: 20, - ), - ])), - CwtchLabel(label: AppLocalizations.of(context).password1Label), + ]), + Visibility( + visible: + Provider.of(context) + .onion + .isNotEmpty, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: 20, + ), + CwtchLabel( + label: + AppLocalizations.of(context) + .addressLabel), + SizedBox( + height: 20, + ), + CwtchButtonTextField( + controller: ctrlrOnion, + onPressed: _copyOnion, + icon: Icon(Icons.copy), + tooltip: + AppLocalizations.of(context) + .copyBtn, + ) + ])), + // We only allow setting password types on profile creation + Visibility( + visible: + Provider.of(context) + .onion + .isEmpty, + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Radio( + value: false, + groupValue: usePassword, + onChanged: _handleSwitchPassword, + ), + Text( + AppLocalizations.of(context) + .radioNoPassword, + style: TextStyle( + color: theme + .current() + .mainTextColor()), + ), + Radio( + value: true, + groupValue: usePassword, + onChanged: _handleSwitchPassword, + ), + Text( + AppLocalizations.of(context) + .radioUsePassword, + style: TextStyle( + color: theme + .current() + .mainTextColor()), + ), + ])), SizedBox( height: 20, ), - CwtchPasswordField( - controller: ctrlrPass, - validator: (value) { - // Password field can be empty when just updating the profile, not on creation - if (Provider.of(context, listen: false).onion.isEmpty && value.isEmpty && usePassword) { - return AppLocalizations.of(context).passwordErrorEmpty; - } - if (value != ctrlrPass2.value.text) { - return AppLocalizations.of(context).passwordErrorMatch; - } - return null; - }, + Visibility( + visible: usePassword, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Visibility( + visible: + Provider.of( + context, + listen: false) + .onion + .isNotEmpty, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + CwtchLabel( + label: AppLocalizations + .of(context) + .currentPasswordLabel), + SizedBox( + height: 20, + ), + CwtchPasswordField( + controller: ctrlrOldPass, + validator: (value) { + // Password field can be empty when just updating the profile, not on creation + if (Provider.of( + context, + listen: + false) + .onion + .isEmpty && + value.isEmpty && + usePassword) { + return AppLocalizations + .of(context) + .passwordErrorEmpty; + } + return null; + }, + ), + SizedBox( + height: 20, + ), + ])), + CwtchLabel( + label: + AppLocalizations.of(context) + .password1Label), + SizedBox( + height: 20, + ), + CwtchPasswordField( + controller: ctrlrPass, + validator: (value) { + // Password field can be empty when just updating the profile, not on creation + if (Provider.of( + context, + listen: false) + .onion + .isEmpty && + value.isEmpty && + usePassword) { + return AppLocalizations.of( + context) + .passwordErrorEmpty; + } + if (value != + ctrlrPass2.value.text) { + return AppLocalizations.of( + context) + .passwordErrorMatch; + } + return null; + }, + ), + SizedBox( + height: 20, + ), + CwtchLabel( + label: + AppLocalizations.of(context) + .password2Label), + SizedBox( + height: 20, + ), + CwtchPasswordField( + controller: ctrlrPass2, + validator: (value) { + // Password field can be empty when just updating the profile, not on creation + if (Provider.of( + context, + listen: false) + .onion + .isEmpty && + value.isEmpty && + usePassword) { + return AppLocalizations.of( + context) + .passwordErrorEmpty; + } + if (value != + ctrlrPass.value.text) { + return AppLocalizations.of( + context) + .passwordErrorMatch; + } + return null; + }), + ]), ), SizedBox( height: 20, ), - CwtchLabel(label: AppLocalizations.of(context).password2Label), - SizedBox( - height: 20, + ElevatedButton( + onPressed: _createPressed, + style: ElevatedButton.styleFrom( + primary: theme + .current() + .defaultButtonColor()), + child: Text( + Provider.of(context) + .onion + .isEmpty + ? AppLocalizations.of(context) + .addNewProfileBtn + : AppLocalizations.of(context) + .saveProfileBtn), ), - CwtchPasswordField( - controller: ctrlrPass2, - validator: (value) { - // Password field can be empty when just updating the profile, not on creation - if (Provider.of(context, listen: false).onion.isEmpty && value.isEmpty && usePassword) { - return AppLocalizations.of(context).passwordErrorEmpty; - } - if (value != ctrlrPass.value.text) { - return AppLocalizations.of(context).passwordErrorMatch; - } - return null; - }), - ]), - ), - SizedBox( - height: 20, - ), - ElevatedButton( - onPressed: _createPressed, - style: ElevatedButton.styleFrom(primary: theme.current().defaultButtonColor()), - child: Text(Provider.of(context).onion.isEmpty ? AppLocalizations.of(context).addNewProfileBtn : AppLocalizations.of(context).saveProfileBtn), - ), - Visibility( - visible: Provider.of(context, listen: false).onion.isNotEmpty, - child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ - SizedBox( - height: 20, - ), - ElevatedButton.icon( - onPressed: () { - showAlertDialog(context); - }, - style: ElevatedButton.styleFrom(primary: theme.current().defaultButtonColor()), - icon: Icon(Icons.delete_forever), - label: Text(AppLocalizations.of(context).deleteBtn), - ) - ])) - ])))))); + Visibility( + visible: Provider.of( + context, + listen: false) + .onion + .isNotEmpty, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + SizedBox( + height: 20, + ), + ElevatedButton.icon( + onPressed: () { + showAlertDialog(context); + }, + style: ElevatedButton.styleFrom( + primary: theme + .current() + .defaultButtonColor()), + icon: Icon(Icons.delete_forever), + label: Text( + AppLocalizations.of(context) + .deleteBtn), + ) + ])) + ])))))); }); }); } void _copyOnion() { - Clipboard.setData(new ClipboardData(text: Provider.of(context, listen: false).onion)); + Clipboard.setData(new ClipboardData( + text: Provider.of(context, listen: false).onion)); // TODO Toast } @@ -261,10 +391,14 @@ class _AddEditProfileViewState extends State { if (_formKey.currentState.validate()) { if (Provider.of(context, listen: false).onion.isEmpty) { if (usePassword == true) { - Provider.of(context, listen: false).cwtch.CreateProfile(ctrlrNick.value.text, ctrlrPass.value.text); + Provider.of(context, listen: false) + .cwtch + .CreateProfile(ctrlrNick.value.text, ctrlrPass.value.text); Navigator.of(context).pop(); } else { - Provider.of(context, listen: false).cwtch.CreateProfile(ctrlrNick.value.text, "be gay do crime"); + Provider.of(context, listen: false) + .cwtch + .CreateProfile(ctrlrNick.value.text, "be gay do crime"); Navigator.of(context).pop(); } } else { @@ -277,7 +411,11 @@ class _AddEditProfileViewState extends State { }; final json = jsonEncode(event); - Provider.of(context, listen: false).cwtch.SendProfileEvent(Provider.of(context, listen: false).onion, json); + Provider.of(context, listen: false) + .cwtch + .SendProfileEvent( + Provider.of(context, listen: false).onion, + json); Navigator.of(context).pop(); } else { // At this points passwords have been validated to be the same and not empty @@ -288,15 +426,26 @@ class _AddEditProfileViewState extends State { }; final updateNameEventJson = jsonEncode(updateNameEvent); - Provider.of(context, listen: false).cwtch.SendProfileEvent(Provider.of(context, listen: false).onion, updateNameEventJson); + Provider.of(context, listen: false) + .cwtch + .SendProfileEvent( + Provider.of(context, listen: false).onion, + updateNameEventJson); final updatePasswordEvent = { "EventType": "ChangePassword", - "Data": {"Password": ctrlrOldPass.text, "NewPassword": ctrlrPass.text} + "Data": { + "Password": ctrlrOldPass.text, + "NewPassword": ctrlrPass.text + } }; final updatePasswordEventJson = jsonEncode(updatePasswordEvent); - Provider.of(context, listen: false).cwtch.SendProfileEvent(Provider.of(context, listen: false).onion, updatePasswordEventJson); + Provider.of(context, listen: false) + .cwtch + .SendProfileEvent( + Provider.of(context, listen: false).onion, + updatePasswordEventJson); Navigator.of(context).pop(); } @@ -310,9 +459,12 @@ showAlertDialog(BuildContext context) { Widget cancelButton = TextButton( child: Text("Cancel"), style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Opaque.current().defaultButtonColor()), - foregroundColor: MaterialStateProperty.all(Opaque.current().defaultButtonTextColor()), - overlayColor: MaterialStateProperty.all(Opaque.current().defaultButtonActiveColor()), + backgroundColor: + MaterialStateProperty.all(Opaque.current().defaultButtonColor()), + foregroundColor: MaterialStateProperty.all( + Opaque.current().defaultButtonTextColor()), + overlayColor: MaterialStateProperty.all( + Opaque.current().defaultButtonActiveColor()), padding: MaterialStateProperty.all(EdgeInsets.all(20))), onPressed: () { Navigator.of(context).pop(); // dismiss dialog @@ -320,9 +472,12 @@ showAlertDialog(BuildContext context) { ); Widget continueButton = TextButton( style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Opaque.current().defaultButtonColor()), - foregroundColor: MaterialStateProperty.all(Opaque.current().defaultButtonTextColor()), - overlayColor: MaterialStateProperty.all(Opaque.current().defaultButtonActiveColor()), + backgroundColor: + MaterialStateProperty.all(Opaque.current().defaultButtonColor()), + foregroundColor: MaterialStateProperty.all( + Opaque.current().defaultButtonTextColor()), + overlayColor: MaterialStateProperty.all( + Opaque.current().defaultButtonActiveColor()), padding: MaterialStateProperty.all(EdgeInsets.all(20))), child: Text(AppLocalizations.of(context).deleteProfileConfirmBtn), onPressed: () { @@ -333,14 +488,7 @@ showAlertDialog(BuildContext context) { // set up the AlertDialog AlertDialog alert = AlertDialog( - backgroundColor: Provider.of(context, listen: false).current().backgroundPaneColor(), title: Text(AppLocalizations.of(context).deleteProfileConfirmBtn), - titleTextStyle: TextStyle( - color: Provider.of(context, listen: false).current().mainTextColor(), - ), - contentTextStyle: TextStyle( - color: Provider.of(context, listen: false).current().mainTextColor(), - ), actions: [ cancelButton, continueButton, diff --git a/lib/views/contactsview.dart b/lib/views/contactsview.dart index 41c9706..d054489 100644 --- a/lib/views/contactsview.dart +++ b/lib/views/contactsview.dart @@ -24,24 +24,31 @@ class _ContactsViewState extends State { // Provider.of(context).onions.forEach((contact) { // _contacts.putIfAbsent(contact.onion, () => ContactModel(contact); // }); - // .cwtch.GetContacts(widget.profile.onion).then((jsonContacts) { - // print("got contact: $jsonContacts"); - // setState(() { - // List contacts = jsonDecode(jsonContacts); - // contacts.forEach((onion) { - // _contacts.putIfAbsent(onion['onion'], () => ContactModel(onion: onion['onion'], nickname: onion['name'], status: onion['status'])); - // }); - // }); - // }); + // .cwtch.GetContacts(widget.profile.onion).then((jsonContacts) { + // print("got contact: $jsonContacts"); + // setState(() { + // List contacts = jsonDecode(jsonContacts); + // contacts.forEach((onion) { + // _contacts.putIfAbsent(onion['onion'], () => ContactModel(onion: onion['onion'], nickname: onion['name'], status: onion['status'])); + // }); + // }); + // }); // } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text("%1's contacts".replaceAll("%1", Provider.of(context).nickname ?? Provider.of(context).onion ?? '')),//todo + title: Text("%1's contacts".replaceAll( + "%1", + Provider.of(context).nickname ?? + Provider.of(context).onion ?? + '')), //todo actions: [ - IconButton(icon: Icon(Icons.copy), onPressed: _copyOnion,), + IconButton( + icon: Icon(Icons.copy), + onPressed: _copyOnion, + ), ], ), floatingActionButton: FloatingActionButton( @@ -58,7 +65,7 @@ class _ContactsViewState extends State { stream: Provider.of(context).appStatus.contactEvents(), builder: (BuildContext context, AsyncSnapshot snapshot) { final tiles = Provider.of(context).onions.map( - (ContactInfoState contact) { + (ContactInfoState contact) { return ChangeNotifierProvider( create: (context) => contact, builder: (context, child) => ContactRow(), @@ -77,20 +84,20 @@ class _ContactsViewState extends State { } void _pushAddContact() { - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) { - return Provider ( - create: (_) => Provider.of(context), - child: AddContactView(), - ); - }, - ) - ); + Navigator.of(context).push(MaterialPageRoute( + builder: (BuildContext context) { + return Provider( + create: (_) => Provider.of(context), + child: AddContactView(), + ); + }, + )); } void _copyOnion() { - final snackBar = SnackBar(content: Text(AppLocalizations.of(context).copiedClipboardNotification));//todo + final snackBar = SnackBar( + content: Text( + AppLocalizations.of(context).copiedClipboardNotification)); //todo // Find the Scaffold in the widget tree and use it to show a SnackBar. ScaffoldMessenger.of(context).showSnackBar(snackBar); } diff --git a/lib/views/doublecolview.dart b/lib/views/doublecolview.dart index c84cb4f..1bc340a 100644 --- a/lib/views/doublecolview.dart +++ b/lib/views/doublecolview.dart @@ -15,19 +15,23 @@ class _DoubleColumnViewState extends State { Widget build(BuildContext context) { var flwtch = Provider.of(context); return Flex( - direction: Axis.horizontal, - children: [ - Flexible( - flex: flwtch.columns[0], - child: ContactsView(), - ), - Flexible( - flex: flwtch.columns[1], - child: flwtch.selectedConversation == "" ? - Center(child:Text("pick a contact")) : //dev - Container(child:MessageView(profile:flwtch.selectedProfile, conversationHandle:flwtch.selectedConversation)), - ), - ], + direction: Axis.horizontal, + children: [ + Flexible( + flex: flwtch.columns[0], + child: ContactsView(), + ), + Flexible( + flex: flwtch.columns[1], + child: flwtch.selectedConversation == "" + ? Center(child: Text("pick a contact")) + : //dev + Container( + child: MessageView( + profile: flwtch.selectedProfile, + conversationHandle: flwtch.selectedConversation)), + ), + ], ); } } diff --git a/lib/views/globalsettingsview.dart b/lib/views/globalsettingsview.dart index 8fa91b0..178bbd7 100644 --- a/lib/views/globalsettingsview.dart +++ b/lib/views/globalsettingsview.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:flutter/material.dart'; @@ -30,27 +31,34 @@ class _GlobalSettingsViewState extends State { } Widget _buildSettingsList() { - return Consumer(builder: (context, theme, child) { + return Consumer(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()), + 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(context).locale.languageCode, onChanged: (String newValue) { setState(() { - Provider.of(context, listen: false).switchLocale(Locale(newValue, '')); + var settings = + Provider.of(context, listen: false); + settings.switchLocale(Locale(newValue, '')); + saveSettings(context); }); }, - items: AppLocalizations.supportedLocales.map>((Locale value) { + items: AppLocalizations.supportedLocales + .map>((Locale value) { return DropdownMenuItem( value: value.languageCode, child: Text(getLanguageFull(context, value.languageCode)), ); }).toList())), SwitchListTile( - title: Text(AppLocalizations.of(context).settingTheme, style: TextStyle(color: theme.current().mainTextColor())), + title: Text(AppLocalizations.of(context).settingTheme, + style: TextStyle(color: theme.current().mainTextColor())), value: theme.current() == Opaque.light, onChanged: (bool value) { if (value) { @@ -58,22 +66,29 @@ class _GlobalSettingsViewState extends State { } else { theme.setDark(); } + + // Save Settings... + saveSettings(context); }, - secondary: Icon(Icons.lightbulb_outline, color: theme.current().mainTextColor()), + 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(context).packageInfo)), - applicationLegalese: '\u{a9} 2021 Open Privacy Research Society', - ), + 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(context).packageInfo)), + applicationLegalese: '\u{a9} 2021 Open Privacy Research Society', + ), ])); }); } @@ -107,3 +122,15 @@ String getLanguageFull(context, String languageCode) { } return languageCode; } + +saveSettings(context) { + var settings = Provider.of(context, listen: false); + final updateSettingsEvent = { + "EventType": "UpdateGlobalSettings", + "Data": {"Data": jsonEncode(settings.asJson())}, + }; + final updateSettingsEventJson = jsonEncode(updateSettingsEvent); + Provider.of(context, listen: false) + .cwtch + .SendAppEvent(updateSettingsEventJson); +} diff --git a/lib/views/messageview.dart b/lib/views/messageview.dart index ccc896b..68944ed 100644 --- a/lib/views/messageview.dart +++ b/lib/views/messageview.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import '../model.dart'; @@ -6,7 +5,8 @@ import '../opaque.dart'; import '../widgets/messagelist.dart'; class MessageView extends StatefulWidget { - const MessageView({Key key, this.profile, this.conversationHandle}) : super(key: key); + const MessageView({Key key, this.profile, this.conversationHandle}) + : super(key: key); final ProfileInfoState profile; final String conversationHandle; @@ -25,7 +25,7 @@ class _MessageViewState extends State { @override Widget build(BuildContext context) { - return Scaffold ( + return Scaffold( appBar: AppBar( title: Text(widget.conversationHandle), actions: [ @@ -35,12 +35,14 @@ class _MessageViewState extends State { IconButton(icon: Icon(Icons.settings), onPressed: _pushConvoSettings), ], ), - body: MessageList(profile: widget.profile, conversationHandle: widget.conversationHandle), + body: MessageList( + profile: widget.profile, + conversationHandle: widget.conversationHandle), bottomSheet: _buildComposeBox(), ); } - void _pushConvoSettings(){} + void _pushConvoSettings() {} void _sendMessage() { ChatMessage cm = new ChatMessage(o: 1, d: ctrlrCompose.value.text); @@ -49,37 +51,38 @@ class _MessageViewState extends State { } Widget _buildComposeBox() { - return Container ( + return Container( color: Opaque.current().backgroundMainColor(), height: 100, child: Row( children: [ - Expanded ( - child:TextField(controller:ctrlrCompose) - ), + Expanded(child: TextField(controller: ctrlrCompose)), SizedBox( width: 100, height: 80, - child: Column( - children: [ - ElevatedButton( - child: Icon(Icons.send, color: Opaque.current().mainTextColor()), - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Opaque.current().defaultButtonColor()), - ), onPressed: _sendMessage, + child: Column(children: [ + ElevatedButton( + child: + Icon(Icons.send, color: Opaque.current().mainTextColor()), + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + Opaque.current().defaultButtonColor()), ), - Row ( - children: [ - SizedBox(width:45, child:ElevatedButton( - child: Icon(Icons.emoji_emotions_outlined, color: Opaque.current().mainTextColor()) - )), - SizedBox(width:45, child:ElevatedButton( - child: Icon(Icons.attach_file, color: Opaque.current().mainTextColor()) - )), - ] - ) - ] - ), + onPressed: _sendMessage, + ), + Row(children: [ + SizedBox( + width: 45, + child: ElevatedButton( + child: Icon(Icons.emoji_emotions_outlined, + color: Opaque.current().mainTextColor()))), + SizedBox( + width: 45, + child: ElevatedButton( + child: Icon(Icons.attach_file, + color: Opaque.current().mainTextColor()))), + ]) + ]), ), ], ), diff --git a/lib/views/profilemgrview.dart b/lib/views/profilemgrview.dart index fd5318d..bc2363a 100644 --- a/lib/views/profilemgrview.dart +++ b/lib/views/profilemgrview.dart @@ -25,13 +25,19 @@ class _ProfileMgrViewState extends State { @override Widget build(BuildContext context) { - return Scaffold ( + return Scaffold( appBar: AppBar( title: Text(AppLocalizations.of(context).profileName), actions: [ - IconButton(icon: Icon(Icons.bug_report_outlined), onPressed: _testChangingContactInfo), - IconButton(icon: Icon(Icons.lock_open), onPressed: _modalUnlockProfiles,), - IconButton(icon: Icon(Icons.settings), onPressed: _pushGlobalSettings), + IconButton( + icon: Icon(Icons.bug_report_outlined), + onPressed: _testChangingContactInfo), + IconButton( + icon: Icon(Icons.lock_open), + onPressed: _modalUnlockProfiles, + ), + IconButton( + icon: Icon(Icons.settings), onPressed: _pushGlobalSettings), ], ), floatingActionButton: FloatingActionButton( @@ -39,75 +45,74 @@ class _ProfileMgrViewState extends State { tooltip: AppLocalizations.of(context).addNewProfileBtn, child: const Icon(Icons.add), ), - body: _buildProfileManager(),//_buildSuggestions(), + body: _buildProfileManager(), //_buildSuggestions(), ); } void _testChangingContactInfo() { - Provider.of(context, listen:false).notifyListeners(); + Provider.of(context, listen: false).notifyListeners(); } void _pushGlobalSettings() { - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) { - return Provider ( - create: (_) => Provider.of(context), - child: GlobalSettingsView(), - ); - }, - ) - ); + Navigator.of(context).push(MaterialPageRoute( + builder: (BuildContext context) { + return Provider( + create: (_) => Provider.of(context, listen: false), + child: GlobalSettingsView(), + ); + }, + )); } void _pushAddEditProfile({onion: ""}) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) { - return MultiProvider ( - providers: [ - ChangeNotifierProvider(create: (_) => ProfileInfoState(onion: onion),), - ], - builder: (context, widget) => AddEditProfileView(), - ); - }, - ) - ); + Navigator.of(context).push(MaterialPageRoute( + builder: (BuildContext context) { + return MultiProvider( + providers: [ + ChangeNotifierProvider( + create: (_) => ProfileInfoState(onion: onion), + ), + ], + builder: (context, widget) => AddEditProfileView(), + ); + }, + )); } void _modalUnlockProfiles() { showModalBottomSheet( context: context, builder: (BuildContext context) { - return Container( - height: 200, // bespoke value courtesy of the [TextField] docs - color: Colors.pink[50], - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text(AppLocalizations.of(context).enterProfilePassword), - TextField( - obscureText: true, - controller: ctrlrPassword, - decoration: InputDecoration( - border: OutlineInputBorder(), - labelText: AppLocalizations.of(context).password1Label, + return Container( + height: 200, // bespoke value courtesy of the [TextField] docs + color: Colors.pink[50], + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Text(AppLocalizations.of(context).enterProfilePassword), + TextField( + obscureText: true, + controller: ctrlrPassword, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: AppLocalizations.of(context).password1Label, + ), ), - ), - ElevatedButton( - child: Text(AppLocalizations.of(context).unlock), - onPressed: () { - Provider.of(context, listen: false).cwtch.LoadProfiles(ctrlrPassword.value.text); - Navigator.pop(context); - }, - ), - ], - ) - ), - ); - }); + ElevatedButton( + child: Text(AppLocalizations.of(context).unlock), + onPressed: () { + Provider.of(context, listen: false) + .cwtch + .LoadProfiles(ctrlrPassword.value.text); + Navigator.pop(context); + }, + ), + ], + )), + ); + }); } Widget _buildProfileManager() { @@ -127,4 +132,4 @@ class _ProfileMgrViewState extends State { return ListView(children: divided); } -} \ No newline at end of file +} diff --git a/lib/views/splashView.dart b/lib/views/splashView.dart index 8acaea3..5ec073f 100644 --- a/lib/views/splashView.dart +++ b/lib/views/splashView.dart @@ -6,13 +6,8 @@ class SplashView extends StatelessWidget { Widget build(BuildContext context) { print("SplashView build()"); return Scaffold( - appBar: AppBar( title: Text("Cwtch")), - body: Center( - child: Column( - children: [ - Text("Loading Cwtch...") - ]) - ), + appBar: AppBar(title: Text("Cwtch")), + body: Center(child: Column(children: [Text("Loading Cwtch...")])), ); } } diff --git a/lib/views/triplecolview.dart b/lib/views/triplecolview.dart index 99f22f4..3d3db31 100644 --- a/lib/views/triplecolview.dart +++ b/lib/views/triplecolview.dart @@ -15,24 +15,27 @@ class _TripleColumnViewState extends State { @override Widget build(BuildContext context) { var flwtch = Provider.of(context); - return Flex( - direction: Axis.horizontal, - children: [ - Flexible( - flex: flwtch.columns[0], - child: ProfileMgrView(), - ), - Flexible( - flex: flwtch.columns[1], - child: flwtch.selectedProfile == null ? Center(child:Text("pick a profile")) : ContactsView(),//dev - ), - Flexible( - flex: flwtch.columns[2], - child: flwtch.selectedConversation == "" ? - Center(child:Text("pick a contact")) : //dev - Container(child:MessageView(profile:flwtch.selectedProfile, conversationHandle:flwtch.selectedConversation)), - ), - ] - ); + return Flex(direction: Axis.horizontal, children: [ + Flexible( + flex: flwtch.columns[0], + child: ProfileMgrView(), + ), + Flexible( + flex: flwtch.columns[1], + child: flwtch.selectedProfile == null + ? Center(child: Text("pick a profile")) + : ContactsView(), //dev + ), + Flexible( + flex: flwtch.columns[2], + child: flwtch.selectedConversation == "" + ? Center(child: Text("pick a contact")) + : //dev + Container( + child: MessageView( + profile: flwtch.selectedProfile, + conversationHandle: flwtch.selectedConversation)), + ), + ]); } } diff --git a/lib/widgets/buttontextfield.dart b/lib/widgets/buttontextfield.dart index 110c433..e50fa16 100644 --- a/lib/widgets/buttontextfield.dart +++ b/lib/widgets/buttontextfield.dart @@ -1,11 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:flutter_app/settings.dart'; import 'package:provider/provider.dart'; import '../opaque.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({this.controller, this.onPressed, this.icon, this.tooltip}); + CwtchButtonTextField( + {this.controller, this.onPressed, this.icon, this.tooltip}); final TextEditingController controller; final Function onPressed; final Icon icon; @@ -18,33 +20,50 @@ class CwtchButtonTextField extends StatefulWidget { class _CwtchButtonTextFieldState extends State { @override Widget build(BuildContext context) { - return Consumer(builder: (context, theme, child) { + return Consumer(builder: (context, theme, child) { return TextField( - controller: widget.controller, - readOnly: true, - decoration: InputDecoration( - suffixIcon: IconButton( - onPressed: widget.onPressed, - icon: widget.icon, - tooltip: widget.tooltip, - enableFeedback: true, - color: theme.current().mainTextColor(), - highlightColor: theme.current().defaultButtonColor(), - focusColor: theme.current().defaultButtonActiveColor(), - splashColor: theme.current().defaultButtonActiveColor(), - ), - floatingLabelBehavior: FloatingLabelBehavior.never, - filled: true, - 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,), - 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))), - - style: TextStyle(color: theme.current().mainTextColor(), backgroundColor: theme.current().textfieldBackgroundColor()), - ); + controller: widget.controller, + readOnly: true, + decoration: InputDecoration( + suffixIcon: IconButton( + onPressed: widget.onPressed, + icon: widget.icon, + tooltip: widget.tooltip, + enableFeedback: true, + color: theme.current().mainTextColor(), + highlightColor: theme.current().defaultButtonColor(), + focusColor: theme.current().defaultButtonActiveColor(), + splashColor: theme.current().defaultButtonActiveColor(), + ), + floatingLabelBehavior: FloatingLabelBehavior.never, + filled: true, + 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, + ), + 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))), + style: TextStyle( + color: theme.current().mainTextColor(), + backgroundColor: theme.current().textfieldBackgroundColor()), + ); }); } } diff --git a/lib/widgets/contactrow.dart b/lib/widgets/contactrow.dart index 29fe637..e5b28d1 100644 --- a/lib/widgets/contactrow.dart +++ b/lib/widgets/contactrow.dart @@ -20,11 +20,28 @@ class _ContactRowState extends State { width: 60, height: 60, child: ClipOval( - child: SizedBox(width:60, height:60, child:Container(color:Colors.white, width: 60, height: 60, child: Image(image: AssetImage("assets/profiles/001-centaur.png"), width:50,height:50,))), + child: SizedBox( + width: 60, + height: 60, + child: Container( + color: Colors.white, + width: 60, + height: 60, + child: Image( + image: AssetImage("assets/profiles/001-centaur.png"), + width: 50, + height: 50, + ))), //child: SizedBox(width:60, height:60, child:Container(color:Colors.white, width: 60, height: 60, child: Image(image: AssetImage(contact.imagePath), width:50,height:50,))), ), ), - trailing: contact.isInvitation != null && contact.isInvitation ? Column(children:[Icon(Icons.favorite, color: Opaque.current().mainTextColor()),Icon(Icons.delete, color: Opaque.current().mainTextColor())]) : Text("99+"),//(nb: Icons.create is a pencil and we use it for "edit", not create) + trailing: contact.isInvitation != null && contact.isInvitation + ? Column(children: [ + Icon(Icons.favorite, color: Opaque.current().mainTextColor()), + Icon(Icons.delete, color: Opaque.current().mainTextColor()) + ]) + : Text( + "99+"), //(nb: Icons.create is a pencil and we use it for "edit", not create) title: Text( contact.nickname, style: Provider.of(context).biggerFont, @@ -32,7 +49,7 @@ class _ContactRowState extends State { subtitle: Text(contact.status), onTap: () { setState(() { - var flwtch = Provider.of(context, listen:false); + var flwtch = Provider.of(context, listen: false); flwtch.setState(() => flwtch.selectedConversation = contact.onion); // case 2/3 handled by Double/TripleColumnView respectively @@ -47,7 +64,10 @@ class _ContactRowState extends State { MaterialPageRoute( builder: (BuildContext builderContext) { return MultiProvider( - providers: [ChangeNotifierProvider(create: (_) => Provider.of(context)),], + providers: [ + ChangeNotifierProvider( + create: (_) => Provider.of(context)), + ], child: MessageView(conversationHandle: handle), ); }, diff --git a/lib/widgets/cwtchlabel.dart b/lib/widgets/cwtchlabel.dart index ea5d9f4..6780198 100644 --- a/lib/widgets/cwtchlabel.dart +++ b/lib/widgets/cwtchlabel.dart @@ -2,12 +2,13 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../opaque.dart'; +import '../settings.dart'; // Provides a styled Label // Callers must provide a label text // TODO: Integrate this with a settings "zoom" / accessibility setting class CwtchLabel extends StatefulWidget { - CwtchLabel({ this.label}); + CwtchLabel({this.label}); final String label; @override @@ -15,16 +16,13 @@ class CwtchLabel extends StatefulWidget { } class _CwtchLabelState extends State { - - @override Widget build(BuildContext context) { - return Consumer ( - builder: (context, theme, child) { - return Text( - widget.label, - style: TextStyle(fontSize: 20, color: theme.current().mainTextColor()), - ); - }); + return Consumer(builder: (context, theme, child) { + return Text( + widget.label, + style: TextStyle(fontSize: 20, color: theme.current().mainTextColor()), + ); + }); } } diff --git a/lib/widgets/messagebubble.dart b/lib/widgets/messagebubble.dart index 230184a..56c0b9f 100644 --- a/lib/widgets/messagebubble.dart +++ b/lib/widgets/messagebubble.dart @@ -16,16 +16,23 @@ class MessageBubble extends StatefulWidget { } class _MessageBubbleState extends State { - String d="", ts=""; - bool ack=false; + String d = "", ts = ""; + bool ack = false; @override void didChangeDependencies() { super.didChangeDependencies(); print("requesting message " + widget.messageIndex.toString()); - Provider.of(context).cwtch.GetMessage(widget.profile.onion, widget.contactOnion, widget.messageIndex).then((jsonMessage){ - print("got message: " + widget.messageIndex.toString() + ": " + jsonMessage); + Provider.of(context) + .cwtch + .GetMessage( + widget.profile.onion, widget.contactOnion, widget.messageIndex) + .then((jsonMessage) { + print("got message: " + + widget.messageIndex.toString() + + ": " + + jsonMessage); dynamic messageWrapper = jsonDecode(jsonMessage); dynamic message = jsonDecode(messageWrapper['Message']); setState(() { @@ -57,11 +64,12 @@ class _MessageBubbleState extends State { ), subtitle: Row( children: [ - Text(""+widget.messageIndex.toString()), - ack ? Icon(Icons.check_circle_outline, - color: Opaque.current().mainTextColor()) : Icon( - Icons.hourglass_bottom_outlined, - color: Opaque.current().mainTextColor()) + Text("" + widget.messageIndex.toString()), + ack + ? Icon(Icons.check_circle_outline, + color: Opaque.current().mainTextColor()) + : Icon(Icons.hourglass_bottom_outlined, + color: Opaque.current().mainTextColor()) ], ), ), diff --git a/lib/widgets/messagelist.dart b/lib/widgets/messagelist.dart index b2697a6..0f2612b 100644 --- a/lib/widgets/messagelist.dart +++ b/lib/widgets/messagelist.dart @@ -10,7 +10,8 @@ class MessageList extends StatefulWidget { final ProfileInfoState profile; final String conversationHandle; - const MessageList({Key key, this.profile, this.conversationHandle}) : super(key: key); + const MessageList({Key key, this.profile, this.conversationHandle}) + : super(key: key); @override _MessageListState createState() => _MessageListState(); @@ -30,18 +31,17 @@ class _MessageListState extends State { } return ProxyProvider0( - update: (_, __) => MessageCounter(conversationNumMessages), - child: ListView.builder( - itemCount: conversationNumMessages, - itemBuilder: (context, index) { - return MessageBubble( - profile: Provider.of(context), - contactOnion: widget.conversationHandle, - messageIndex: index, - ); - }, - ) - ); + update: (_, __) => MessageCounter(conversationNumMessages), + child: ListView.builder( + itemCount: conversationNumMessages, + itemBuilder: (context, index) { + return MessageBubble( + profile: Provider.of(context), + contactOnion: widget.conversationHandle, + messageIndex: index, + ); + }, + )); } Future _updateMessageCount(BuildContext context) async { @@ -50,8 +50,14 @@ class _MessageListState extends State { return; } - Provider.of(context, listen: false).cwtch.NumMessages(Provider.of(context, listen: false).onion, widget.conversationHandle).then((n) { - if (n != conversationNumMessages) setState(() => conversationNumMessages = n); + Provider.of(context, listen: false) + .cwtch + .NumMessages( + Provider.of(context, listen: false).onion, + widget.conversationHandle) + .then((n) { + if (n != conversationNumMessages) + setState(() => conversationNumMessages = n); }); } } @@ -59,4 +65,4 @@ class _MessageListState extends State { class MessageCounter { MessageCounter(this.x); int x = 0; -} \ No newline at end of file +} diff --git a/lib/widgets/passwordfield.dart b/lib/widgets/passwordfield.dart index ff025d5..5853d1f 100644 --- a/lib/widgets/passwordfield.dart +++ b/lib/widgets/passwordfield.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../opaque.dart'; +import '../settings.dart'; // Provides a styled Password Input Field for use in Form Widgets. // Callers must provide a text controller, label helper text and a validator. @@ -17,7 +18,7 @@ class CwtchPasswordField extends StatefulWidget { class _CwtchTextFieldState extends State { @override Widget build(BuildContext context) { - return Consumer(builder: (context, theme, child) { + return Consumer(builder: (context, theme, child) { return TextFormField( controller: widget.controller, validator: widget.validator, @@ -25,18 +26,32 @@ class _CwtchTextFieldState extends State { enableSuggestions: false, autocorrect: false, decoration: InputDecoration( - errorStyle: TextStyle( - color: theme.current().textfieldErrorColor(), - fontWeight: FontWeight.bold, - ), - 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)), - filled: true, - fillColor: theme.current().textfieldBackgroundColor(), - enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(15.0), borderSide: BorderSide(color: theme.current().textfieldBorderColor(), width: 3.0)), + errorStyle: TextStyle( + color: theme.current().textfieldErrorColor(), + fontWeight: FontWeight.bold, + ), + 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)), + filled: true, + fillColor: theme.current().textfieldBackgroundColor(), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(15.0), + borderSide: BorderSide( + color: theme.current().textfieldBorderColor(), width: 3.0)), ), - style: TextStyle(color: theme.current().mainTextColor(), backgroundColor: theme.current().textfieldBackgroundColor()), + style: TextStyle( + color: theme.current().mainTextColor(), + backgroundColor: theme.current().textfieldBackgroundColor()), ); }); } diff --git a/lib/widgets/profilerow.dart b/lib/widgets/profilerow.dart index 204bca4..c2b444d 100644 --- a/lib/widgets/profilerow.dart +++ b/lib/widgets/profilerow.dart @@ -7,6 +7,7 @@ import 'package:provider/provider.dart'; import '../main.dart'; import '../model.dart'; import '../opaque.dart'; +import '../settings.dart'; class ProfileRow extends StatefulWidget { @override @@ -22,13 +23,30 @@ class _ProfileRowState extends State { width: 60, height: 60, child: ClipOval( - child: SizedBox(width:60, height:60, child:Container(color:Colors.white, width: 60, height: 60, child: Image(image: AssetImage("assets/" + profile.imagePath), width:50,height:50,))), + child: SizedBox( + width: 60, + height: 60, + child: Container( + color: Colors.white, + width: 60, + height: 60, + child: Image( + image: AssetImage("assets/" + profile.imagePath), + width: 50, + height: 50, + ))), ), - ) , + ), trailing: IconButton( - icon: Icon(Icons.create, color: Provider.of(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) + icon: Icon(Icons.create, + color: Provider.of(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(context).biggerFont, @@ -36,7 +54,7 @@ class _ProfileRowState extends State { subtitle: Text(profile.onion), onTap: () { setState(() { - var flwtch = Provider.of(context, listen:false); + var flwtch = Provider.of(context, listen: false); flwtch.cwtch.SelectProfile(profile.onion); flwtch.setState(() { flwtch.selectedProfile = profile; @@ -44,8 +62,12 @@ class _ProfileRowState extends State { }); switch (flwtch.columns.length) { - case 1: _pushContactList(profile, false); break; - case 2: _pushContactList(profile, true); break; + case 1: + _pushContactList(profile, false); + break; + case 2: + _pushContactList(profile, true); + break; } // case 3: handled by TripleColumnView }); }, @@ -59,28 +81,33 @@ class _ProfileRowState extends State { return MultiProvider( providers: [ ChangeNotifierProvider.value(value: profile), - ChangeNotifierProvider(create: (_) => ContactListState(Provider.of(buildcontext).cwtch, profile.onion),), + ChangeNotifierProvider( + create: (_) => ContactListState( + Provider.of(buildcontext).cwtch, + profile.onion), + ), ], - builder: (context, widget) => includeDoublePane ? DoubleColumnView() : ContactsView(), + builder: (context, widget) => + includeDoublePane ? DoubleColumnView() : ContactsView(), ); }, ), ); } - void _pushAddEditProfile({onion: "", displayName: "", profileImage: ""}) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (BuildContext context) { - return MultiProvider ( - providers: [ - ChangeNotifierProvider(create: (_) => ProfileInfoState(onion: onion, nickname:displayName, imagePath: profileImage),), - ], - builder: (context, widget) => AddEditProfileView(), - ); - }, - ) - ); + Navigator.of(context).push(MaterialPageRoute( + builder: (BuildContext context) { + return MultiProvider( + providers: [ + ChangeNotifierProvider( + create: (_) => ProfileInfoState( + onion: onion, nickname: displayName, imagePath: profileImage), + ), + ], + builder: (context, widget) => AddEditProfileView(), + ); + }, + )); } } diff --git a/lib/widgets/textfield.dart b/lib/widgets/textfield.dart index 83d02a9..f2a31b3 100644 --- a/lib/widgets/textfield.dart +++ b/lib/widgets/textfield.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../opaque.dart'; +import '../settings.dart'; // Provides a styled Text Field for use in Form Widgets. // Callers must provide a text controller, label helper text and a validator. @@ -17,26 +18,44 @@ class CwtchTextField extends StatefulWidget { class _CwtchTextFieldState extends State { @override Widget build(BuildContext context) { - return Consumer(builder: (context, theme, child) { + return Consumer(builder: (context, theme, child) { return TextFormField( - controller: widget.controller, - validator: widget.validator, - decoration: InputDecoration( - - labelText: widget.labelText, - labelStyle: TextStyle(color: theme.current().mainTextColor(), backgroundColor: theme.current().textfieldBackgroundColor()), - floatingLabelBehavior: FloatingLabelBehavior.never, - filled: true, - 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,), - 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))), - - style: TextStyle(color: theme.current().mainTextColor(), backgroundColor: theme.current().textfieldBackgroundColor()), - ); + controller: widget.controller, + validator: widget.validator, + decoration: InputDecoration( + labelText: widget.labelText, + labelStyle: TextStyle( + color: theme.current().mainTextColor(), + backgroundColor: theme.current().textfieldBackgroundColor()), + floatingLabelBehavior: FloatingLabelBehavior.never, + filled: true, + 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, + ), + 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))), + style: TextStyle( + color: theme.current().mainTextColor(), + backgroundColor: theme.current().textfieldBackgroundColor()), + ); }); } } diff --git a/lib/widgets/torstatuslabel.dart b/lib/widgets/torstatuslabel.dart index 67927c7..6453854 100644 --- a/lib/widgets/torstatuslabel.dart +++ b/lib/widgets/torstatuslabel.dart @@ -15,17 +15,15 @@ class _TorStatusState extends State { Widget build(BuildContext context) { return Builder( builder: (context2) => StreamBuilder( - stream: Provider.of(context).appStatus.torStatus(), - builder: (BuildContext context, AsyncSnapshot snapshot) { - return Text( - snapshot.hasData ? - snapshot.data : AppLocalizations.of(context).loadingTor, - style: Theme - .of(context) - .textTheme - .headline4, - ); - }, - )); + stream: Provider.of(context).appStatus.torStatus(), + builder: (BuildContext context, AsyncSnapshot snapshot) { + return Text( + snapshot.hasData + ? snapshot.data + : AppLocalizations.of(context).loadingTor, + style: Theme.of(context).textTheme.headline4, + ); + }, + )); } }