Merge pull request 'Formatting' (#19) from splash into trunk
Reviewed-on: #19
This commit is contained in:
commit
827873b68b
|
@ -21,31 +21,32 @@ class CwtchNotifier {
|
|||
switch (type) {
|
||||
case "NewPeer":
|
||||
profileCN.add(ProfileInfoState(
|
||||
onion: data["Identity"],
|
||||
nickname: data["name"],
|
||||
imagePath: data["picture"],
|
||||
contactsJson: data["ContactsJson"],
|
||||
onion: data["Identity"],
|
||||
nickname: data["name"],
|
||||
imagePath: data["picture"],
|
||||
contactsJson: data["ContactsJson"],
|
||||
));
|
||||
break;
|
||||
case "PeerCreated":
|
||||
print("xx peercreated");
|
||||
profileCN.getProfile(data["ProfileOnion"]).contactList.add(ContactInfoState(
|
||||
profileOnion: data["ProfileOnion"],
|
||||
onion: data["RemotePeer"],
|
||||
nickname: data["nick"],
|
||||
status: data["status"],
|
||||
));
|
||||
profileOnion: data["ProfileOnion"],
|
||||
onion: data["RemotePeer"],
|
||||
nickname: data["nick"],
|
||||
status: data["status"],
|
||||
));
|
||||
break;
|
||||
case "PeerStateChange":
|
||||
ContactInfoState contact = profileCN.getProfile(data["ProfileOnion"]).contactList.getContact(data["RemotePeer"]);
|
||||
if (contact == null) {//todo: stopgap, as lc-g is supposed to handle this
|
||||
print("PSC -> adding "+data["ProfileOnion"]+" :: " + data["RemotePeer"]);
|
||||
if (contact == null) {
|
||||
//todo: stopgap, as lc-g is supposed to handle this
|
||||
print("PSC -> adding " + data["ProfileOnion"] + " :: " + data["RemotePeer"]);
|
||||
profileCN.getProfile(data["ProfileOnion"]).contactList.add(ContactInfoState(
|
||||
profileOnion: data["ProfileOnion"],
|
||||
onion: data["RemotePeer"],
|
||||
nickname: data["nick"],
|
||||
status: data["ConnectionState"],
|
||||
));
|
||||
profileOnion: data["ProfileOnion"],
|
||||
onion: data["RemotePeer"],
|
||||
nickname: data["nick"],
|
||||
status: data["ConnectionState"],
|
||||
));
|
||||
} else {
|
||||
contact.status = data["ConnectionState"];
|
||||
}
|
||||
|
|
|
@ -15,52 +15,38 @@ import '../model.dart';
|
|||
/// Cwtch API ///
|
||||
/////////////////////
|
||||
|
||||
typedef start_cwtch_function = Void Function(
|
||||
Pointer<Utf8> str, Int32 length, Pointer<Utf8> str2, Int32 length2);
|
||||
typedef StartCwtchFn = void Function(
|
||||
Pointer<Utf8> dir, int len, Pointer<Utf8> tor, int torLen);
|
||||
typedef start_cwtch_function = Void Function(Pointer<Utf8> str, Int32 length, Pointer<Utf8> str2, Int32 length2);
|
||||
typedef StartCwtchFn = void Function(Pointer<Utf8> dir, int len, Pointer<Utf8> tor, int torLen);
|
||||
|
||||
typedef void_from_string_string_function = Void Function(
|
||||
Pointer<Utf8>, Int32, Pointer<Utf8>, Int32);
|
||||
typedef VoidFromStringStringFn = void Function(
|
||||
Pointer<Utf8>, int, Pointer<Utf8>, int);
|
||||
typedef void_from_string_string_function = Void Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32);
|
||||
typedef VoidFromStringStringFn = void Function(Pointer<Utf8>, int, Pointer<Utf8>, int);
|
||||
|
||||
typedef access_cwtch_eventbus_function = Void Function();
|
||||
typedef NextEventFn = void Function();
|
||||
|
||||
typedef string_to_void_function = Void Function(
|
||||
Pointer<Utf8> str, Int32 length);
|
||||
typedef string_to_void_function = Void Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef StringFn = void Function(Pointer<Utf8> dir, int);
|
||||
|
||||
typedef string_string_to_void_function = Void Function(
|
||||
Pointer<Utf8> str, Int32 length, Pointer<Utf8> str2, Int32 length2);
|
||||
typedef string_string_to_void_function = Void Function(Pointer<Utf8> str, Int32 length, Pointer<Utf8> str2, Int32 length2);
|
||||
typedef StringStringFn = void Function(Pointer<Utf8>, int, Pointer<Utf8>, int);
|
||||
|
||||
typedef get_json_blob_void_function = Pointer<Utf8> Function();
|
||||
typedef GetJsonBlobVoidFn = Pointer<Utf8> Function();
|
||||
|
||||
typedef get_json_blob_string_function = Pointer<Utf8> Function(
|
||||
Pointer<Utf8> str, Int32 length);
|
||||
typedef GetJsonBlobStringFn = Pointer<Utf8> Function(
|
||||
Pointer<Utf8> str, int len);
|
||||
typedef get_json_blob_string_function = Pointer<Utf8> Function(Pointer<Utf8> str, Int32 length);
|
||||
typedef GetJsonBlobStringFn = Pointer<Utf8> Function(Pointer<Utf8> 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<Utf8>, Int32, Pointer<Utf8>, Int32);
|
||||
typedef GetIntFromStrStrFn = int Function(
|
||||
Pointer<Utf8>, int, Pointer<Utf8>, int);
|
||||
typedef get_int_from_str_str_function = Int32 Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32);
|
||||
typedef GetIntFromStrStrFn = int Function(Pointer<Utf8>, int, Pointer<Utf8>, 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<Utf8> Function(
|
||||
Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int32);
|
||||
typedef GetJsonBlobFromStrStrIntFn = Pointer<Utf8> Function(
|
||||
Pointer<Utf8>, int, Pointer<Utf8>, int, int);
|
||||
typedef get_json_blob_from_str_str_int_function = Pointer<Utf8> Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int32);
|
||||
typedef GetJsonBlobFromStrStrIntFn = Pointer<Utf8> Function(Pointer<Utf8>, int, Pointer<Utf8>, 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<Utf8> Function(
|
||||
Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int32, Int32);
|
||||
typedef GetJsonBlobFromStrStrIntIntFn = Pointer<Utf8> Function(
|
||||
Pointer<Utf8>, int, Pointer<Utf8>, int, int, int);
|
||||
typedef get_json_blob_from_str_str_int_int_function = Pointer<Utf8> Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int32, Int32);
|
||||
typedef GetJsonBlobFromStrStrIntIntFn = Pointer<Utf8> Function(Pointer<Utf8>, int, Pointer<Utf8>, int, int, int);
|
||||
|
||||
typedef acn_events_function = Pointer<Utf8> Function();
|
||||
typedef ACNEventsFn = Pointer<Utf8> Function();
|
||||
|
@ -86,8 +72,7 @@ class CwtchFfi implements Cwtch {
|
|||
var cwtchDir = path.join(home, ".cwtch/dev/");
|
||||
print("cwtchDir $cwtchDir");
|
||||
|
||||
var startCwtchC =
|
||||
library.lookup<NativeFunction<start_cwtch_function>>("c_StartCwtch");
|
||||
var startCwtchC = library.lookup<NativeFunction<start_cwtch_function>>("c_StartCwtch");
|
||||
// ignore: non_constant_identifier_names
|
||||
final StartCwtch = startCwtchC.asFunction<StartCwtchFn>();
|
||||
|
||||
|
@ -96,8 +81,7 @@ class CwtchFfi implements Cwtch {
|
|||
|
||||
// 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"]);
|
||||
|
@ -123,8 +107,7 @@ class CwtchFfi implements Cwtch {
|
|||
// Steam of appbus events. Call blocks in libcwtch-go GetAppbusEvent. Static so the isolate can use it
|
||||
static Stream<String> pollAppbusEvents() async* {
|
||||
var library = DynamicLibrary.open("libCwtch.so");
|
||||
var getAppbusEventC =
|
||||
library.lookup<NativeFunction<acn_events_function>>("c_GetAppBusEvent");
|
||||
var getAppbusEventC = library.lookup<NativeFunction<acn_events_function>>("c_GetAppBusEvent");
|
||||
final GetAppbusEvent = getAppbusEventC.asFunction<ACNEventsFn>();
|
||||
|
||||
while (true) {
|
||||
|
@ -136,9 +119,7 @@ class CwtchFfi implements Cwtch {
|
|||
|
||||
// ignore: non_constant_identifier_names
|
||||
void SelectProfile(String onion) async {
|
||||
var selectProfileC =
|
||||
library.lookup<NativeFunction<get_json_blob_string_function>>(
|
||||
"c_SelectProfile");
|
||||
var selectProfileC = library.lookup<NativeFunction<get_json_blob_string_function>>("c_SelectProfile");
|
||||
// ignore: non_constant_identifier_names
|
||||
final SelectProfile = selectProfileC.asFunction<GetJsonBlobStringFn>();
|
||||
final ut8Onion = onion.toNativeUtf8();
|
||||
|
@ -147,9 +128,7 @@ class CwtchFfi implements Cwtch {
|
|||
|
||||
// ignore: non_constant_identifier_names
|
||||
void CreateProfile(String nick, String pass) {
|
||||
var createProfileC =
|
||||
library.lookup<NativeFunction<void_from_string_string_function>>(
|
||||
"c_CreateProfile");
|
||||
var createProfileC = library.lookup<NativeFunction<void_from_string_string_function>>("c_CreateProfile");
|
||||
// ignore: non_constant_identifier_names
|
||||
final CreateProfile = createProfileC.asFunction<VoidFromStringStringFn>();
|
||||
final utf8nick = nick.toNativeUtf8();
|
||||
|
@ -159,8 +138,7 @@ class CwtchFfi implements Cwtch {
|
|||
|
||||
// ignore: non_constant_identifier_names
|
||||
void LoadProfiles(String pass) {
|
||||
var loadProfileC = library
|
||||
.lookup<NativeFunction<string_to_void_function>>("c_LoadProfiles");
|
||||
var loadProfileC = library.lookup<NativeFunction<string_to_void_function>>("c_LoadProfiles");
|
||||
// ignore: non_constant_identifier_names
|
||||
final LoadProfiles = loadProfileC.asFunction<StringFn>();
|
||||
final ut8pass = pass.toNativeUtf8();
|
||||
|
@ -168,8 +146,7 @@ class CwtchFfi implements Cwtch {
|
|||
}
|
||||
|
||||
Future<String> ACNEvents() async {
|
||||
var acnEventsC =
|
||||
library.lookup<NativeFunction<acn_events_function>>("c_ACNEvents");
|
||||
var acnEventsC = library.lookup<NativeFunction<acn_events_function>>("c_ACNEvents");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ACNEvents = acnEventsC.asFunction<ACNEventsFn>();
|
||||
|
||||
|
@ -179,8 +156,7 @@ class CwtchFfi implements Cwtch {
|
|||
}
|
||||
|
||||
Future<String> ContactEvents() async {
|
||||
var acnEventsC =
|
||||
library.lookup<NativeFunction<acn_events_function>>("c_ContactEvents");
|
||||
var acnEventsC = library.lookup<NativeFunction<acn_events_function>>("c_ContactEvents");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ContactEvents = acnEventsC.asFunction<ACNEventsFn>();
|
||||
|
||||
|
@ -190,8 +166,7 @@ class CwtchFfi implements Cwtch {
|
|||
}
|
||||
|
||||
Future<String> GetProfiles() async {
|
||||
var getProfilesC = library
|
||||
.lookup<NativeFunction<get_json_blob_void_function>>("c_GetProfiles");
|
||||
var getProfilesC = library.lookup<NativeFunction<get_json_blob_void_function>>("c_GetProfiles");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetProfiles = getProfilesC.asFunction<GetJsonBlobVoidFn>();
|
||||
|
||||
|
@ -201,8 +176,7 @@ class CwtchFfi implements Cwtch {
|
|||
}
|
||||
|
||||
Future<String> GetContacts(String onion) async {
|
||||
var getContactsC = library
|
||||
.lookup<NativeFunction<get_json_blob_string_function>>("c_GetContacts");
|
||||
var getContactsC = library.lookup<NativeFunction<get_json_blob_string_function>>("c_GetContacts");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetContacts = getContactsC.asFunction<GetJsonBlobStringFn>();
|
||||
final utf8onion = onion.toNativeUtf8();
|
||||
|
@ -212,52 +186,40 @@ class CwtchFfi implements Cwtch {
|
|||
}
|
||||
|
||||
Future<int> NumMessages(String profile, String handle) async {
|
||||
var numMessagesC = library
|
||||
.lookup<NativeFunction<get_int_from_str_str_function>>("c_NumMessages");
|
||||
var numMessagesC = library.lookup<NativeFunction<get_int_from_str_str_function>>("c_NumMessages");
|
||||
// ignore: non_constant_identifier_names
|
||||
final NumMessages = numMessagesC.asFunction<GetIntFromStrStrFn>();
|
||||
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<String> GetMessage(String profile, String handle, int index) async {
|
||||
var getMessageC =
|
||||
library.lookup<NativeFunction<get_json_blob_from_str_str_int_function>>(
|
||||
"c_GetMessage");
|
||||
var getMessageC = library.lookup<NativeFunction<get_json_blob_from_str_str_int_function>>("c_GetMessage");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetMessage = getMessageC.asFunction<GetJsonBlobFromStrStrIntFn>();
|
||||
final utf8profile = profile.toNativeUtf8();
|
||||
final utf8handle = handle.toNativeUtf8();
|
||||
Pointer<Utf8> jsonMessageBytes = GetMessage(
|
||||
utf8profile, utf8profile.length, utf8handle, utf8handle.length, index);
|
||||
Pointer<Utf8> jsonMessageBytes = GetMessage(utf8profile, utf8profile.length, utf8handle, utf8handle.length, index);
|
||||
String jsonMessage = jsonMessageBytes.toDartString();
|
||||
return jsonMessage;
|
||||
}
|
||||
|
||||
Future<String> GetMessages(
|
||||
String profile, String handle, int start, int end) async {
|
||||
var getMessagesC = library
|
||||
.lookup<NativeFunction<get_json_blob_from_str_str_int_int_function>>(
|
||||
"c_GetMessages");
|
||||
Future<String> GetMessages(String profile, String handle, int start, int end) async {
|
||||
var getMessagesC = library.lookup<NativeFunction<get_json_blob_from_str_str_int_int_function>>("c_GetMessages");
|
||||
// ignore: non_constant_identifier_names
|
||||
final GetMessages =
|
||||
getMessagesC.asFunction<GetJsonBlobFromStrStrIntIntFn>();
|
||||
final GetMessages = getMessagesC.asFunction<GetJsonBlobFromStrStrIntIntFn>();
|
||||
final utf8profile = profile.toNativeUtf8();
|
||||
final utf8handle = handle.toNativeUtf8();
|
||||
Pointer<Utf8> jsonMessagesBytes = GetMessages(utf8profile,
|
||||
utf8profile.length, utf8handle, utf8handle.length, start, end);
|
||||
Pointer<Utf8> 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<NativeFunction<string_string_to_void_function>>(
|
||||
"c_SendProfileEvent");
|
||||
var sendAppBusEvent = library.lookup<NativeFunction<string_string_to_void_function>>("c_SendProfileEvent");
|
||||
// ignore: non_constant_identifier_names
|
||||
final SendAppBusEvent = sendAppBusEvent.asFunction<StringStringFn>();
|
||||
final utf8onion = onion.toNativeUtf8();
|
||||
|
@ -267,8 +229,7 @@ class CwtchFfi implements Cwtch {
|
|||
|
||||
@override
|
||||
void SendAppEvent(String json) {
|
||||
var sendAppBusEvent = library
|
||||
.lookup<NativeFunction<string_to_void_function>>("c_SendAppEvent");
|
||||
var sendAppBusEvent = library.lookup<NativeFunction<string_to_void_function>>("c_SendAppEvent");
|
||||
// ignore: non_constant_identifier_names
|
||||
final SendAppBusEvent = sendAppBusEvent.asFunction<StringFn>();
|
||||
final utf8json = json.toNativeUtf8();
|
||||
|
|
|
@ -22,8 +22,7 @@ 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';
|
||||
|
@ -48,8 +47,7 @@ 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
|
||||
|
@ -89,26 +87,21 @@ class CwtchGomobile implements Cwtch {
|
|||
}
|
||||
|
||||
Future<int> NumMessages(String profile, String handle) {
|
||||
return cwtchPlatform
|
||||
.invokeMethod("NumMessages", {"profile": profile, "contact": handle});
|
||||
return cwtchPlatform.invokeMethod("NumMessages", {"profile": profile, "contact": handle});
|
||||
}
|
||||
|
||||
Future<String> 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<String> GetMessages(
|
||||
String profile, String handle, int start, int end) {
|
||||
return cwtchPlatform.invokeMethod("GetMessage",
|
||||
{"profile": profile, "contact": handle, "start": start, "end": end});
|
||||
Future<String> 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});
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -86,7 +86,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.''');
|
||||
|
||||
|
||||
/// Go Standard Lib
|
||||
yield LicenseEntryWithLineBreaks(["crypto, net"], '''Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|||
|
||||
var globalSettings = Settings(Locale("en", ''), Opaque.dark);
|
||||
|
||||
|
||||
void main() {
|
||||
LicenseRegistry.addLicense(() => licenses());
|
||||
runApp(Flwtch());
|
||||
|
@ -64,23 +63,16 @@ class FlwtchState extends State<Flwtch> {
|
|||
appStatus = AppModel(cwtch: cwtch);
|
||||
}
|
||||
|
||||
ChangeNotifierProvider<Settings> getSettingsProvider() =>
|
||||
ChangeNotifierProvider(create: (context) => globalSettings);
|
||||
Provider<FlwtchState> getFlwtchStateProvider() =>
|
||||
Provider<FlwtchState>(create: (_) => this);
|
||||
ChangeNotifierProvider<ProfileListState> getProfileListProvider() =>
|
||||
ChangeNotifierProvider(create: (context) => profs);
|
||||
ChangeNotifierProvider<Settings> getSettingsProvider() => ChangeNotifierProvider(create: (context) => globalSettings);
|
||||
Provider<FlwtchState> getFlwtchStateProvider() => Provider<FlwtchState>(create: (_) => this);
|
||||
ChangeNotifierProvider<ProfileListState> getProfileListProvider() => ChangeNotifierProvider(create: (context) => profs);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
appStatus = AppModel(cwtch: cwtch);
|
||||
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
getFlwtchStateProvider(),
|
||||
getProfileListProvider(),
|
||||
getSettingsProvider()
|
||||
],
|
||||
providers: [getFlwtchStateProvider(), getProfileListProvider(), getSettingsProvider()],
|
||||
builder: (context, widget) {
|
||||
Provider.of<Settings>(context).initPackageInfo();
|
||||
return Consumer<Settings>(
|
||||
|
@ -103,20 +95,15 @@ class FlwtchState extends State<Flwtch> {
|
|||
cardColor: opaque.current().backgroundMainColor(),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all(
|
||||
opaque.current().defaultButtonColor()),
|
||||
foregroundColor: MaterialStateProperty.all(
|
||||
opaque.current().defaultButtonTextColor()),
|
||||
overlayColor: MaterialStateProperty.all(
|
||||
opaque.current().defaultButtonActiveColor()),
|
||||
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())),
|
||||
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()),
|
||||
|
@ -134,9 +121,7 @@ class FlwtchState extends State<Flwtch> {
|
|||
),
|
||||
// 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(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -29,13 +29,7 @@ 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
|
||||
|
@ -78,12 +72,12 @@ class ProfileListState extends ChangeNotifier {
|
|||
}
|
||||
|
||||
void add(ProfileInfoState newProfile) {
|
||||
print("ProfileListState: adding " + newProfile.onion +" and notifying");
|
||||
print("ProfileListState: adding " + newProfile.onion + " and notifying");
|
||||
_profiles.add(newProfile);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<ProfileInfoState> get profiles => _profiles.sublist(0);//todo: copy?? dont want caller able to bypass changenotifier
|
||||
List<ProfileInfoState> get profiles => _profiles.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
|
||||
|
||||
ProfileInfoState getProfile(String onion) {
|
||||
int idx = _profiles.indexWhere((element) => element.onion == onion);
|
||||
|
@ -106,13 +100,15 @@ class ContactListState extends ChangeNotifier {
|
|||
}
|
||||
|
||||
void updateUnreadMessages(String forOnion, int newVal) {
|
||||
_contacts.sort((ContactInfoState a, ContactInfoState b) { return b.unreadMessages - a.unreadMessages; });
|
||||
_contacts.sort((ContactInfoState a, ContactInfoState b) {
|
||||
return b.unreadMessages - a.unreadMessages;
|
||||
});
|
||||
//<todo> if(changed) {
|
||||
notifyListeners();
|
||||
//} </todo>
|
||||
}
|
||||
|
||||
List<ContactInfoState> get contacts => _contacts.sublist(0);//todo: copy?? dont want caller able to bypass changenotifier
|
||||
List<ContactInfoState> get contacts => _contacts.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
|
||||
|
||||
ContactInfoState getContact(String onion) {
|
||||
int idx = _contacts.indexWhere((element) => element.onion == onion);
|
||||
|
@ -127,7 +123,13 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
String _imagePath = "";
|
||||
int _unreadMessages = 0;
|
||||
|
||||
ProfileInfoState({this.onion, nickname = "", imagePath = "", unreadMessages = 0, contactsJson = "",}){
|
||||
ProfileInfoState({
|
||||
this.onion,
|
||||
nickname = "",
|
||||
imagePath = "",
|
||||
unreadMessages = 0,
|
||||
contactsJson = "",
|
||||
}) {
|
||||
this._nickname = nickname;
|
||||
this._imagePath = imagePath;
|
||||
this._unreadMessages = unreadMessages;
|
||||
|
@ -135,17 +137,15 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
if (contactsJson != null && contactsJson != "" && contactsJson != "null") {
|
||||
print("decoding " + contactsJson);
|
||||
List<dynamic> contacts = jsonDecode(contactsJson);
|
||||
this._contacts.addAll(
|
||||
contacts.map((contact){
|
||||
return ContactInfoState(
|
||||
profileOnion: this.onion,
|
||||
onion: contact["onion"],
|
||||
nickname: contact["name"],
|
||||
status: contact["status"],
|
||||
imagePath: contact["picture"],
|
||||
);
|
||||
})
|
||||
);
|
||||
this._contacts.addAll(contacts.map((contact) {
|
||||
return ContactInfoState(
|
||||
profileOnion: this.onion,
|
||||
onion: contact["onion"],
|
||||
nickname: contact["name"],
|
||||
status: contact["status"],
|
||||
imagePath: contact["picture"],
|
||||
);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,509 +0,0 @@
|
|||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND AS CHANGES WILL BE OVERRIDDEN.
|
||||
// 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';
|
||||
abstract class OpaqueThemeType {
|
||||
static final Color red = Color(0xFFFF0000);
|
||||
Color backgroundMainColor(){return red;}
|
||||
Color backgroundPaneColor(){return red;}
|
||||
Color backgroundHilightElementColor(){return red;}
|
||||
|
||||
Color dividerColor(){return red;}
|
||||
|
||||
Color mainTextColor(){return red;}
|
||||
Color altTextColor(){return red;}
|
||||
Color hilightElementTextColor(){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 textfieldBackgroundColor(){return red;}
|
||||
Color textfieldBorderColor(){return red;}
|
||||
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);
|
||||
|
||||
Color backgroundMainColor() { return darkGreyPurple; }
|
||||
Color backgroundPaneColor() { return darkGreyPurple; }
|
||||
Color backgroundHilightElementColor() { return deepPurple; }
|
||||
|
||||
Color dividerColor() { return deepPurple; }
|
||||
|
||||
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 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);
|
||||
|
||||
Color backgroundMainColor() { return whitePurple; }
|
||||
Color backgroundPaneColor() { return softPurple; }
|
||||
Color backgroundHilightElementColor() { return softPurple; }
|
||||
|
||||
Color dividerColor() { return purple; }
|
||||
|
||||
Color mainTextColor() { return darkPurple; }
|
||||
Color altTextColor() { return purple; }
|
||||
Color hilightElementTextColor() { return darkPurple; }
|
||||
|
||||
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 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 dividerColor() { return current().dividerColor(); }
|
||||
|
||||
Color mainTextColor() { return current().mainTextColor(); }
|
||||
Color altTextColor() { return current().altTextColor(); }
|
||||
Color hilightElementTextColor() { return current().hilightElementTextColor(); }
|
||||
|
||||
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 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 dropShadowColor() { return current().dropShadowColor(); }
|
||||
Color dropShadowPaneColor() { return current().dropShadowPaneColor(); }
|
||||
|
||||
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 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 final OpaqueThemeType dark = CwtchDark();
|
||||
static final OpaqueThemeType light = CwtchLight();
|
||||
static static Opaque current() { return dark; }
|
||||
|
||||
|
||||
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(); }
|
||||
|
||||
|
||||
}
|
|
@ -47,9 +47,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
ctrlrOnion.text = Provider.of<ProfileInfoState>(context).onion;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(Provider.of<ProfileInfoState>(context).onion.isEmpty
|
||||
? AppLocalizations.of(context).addProfileTitle
|
||||
: AppLocalizations.of(context).editProfileTitle),
|
||||
title: Text(Provider.of<ProfileInfoState>(context).onion.isEmpty ? AppLocalizations.of(context).addProfileTitle : AppLocalizations.of(context).editProfileTitle),
|
||||
),
|
||||
body: _buildForm(),
|
||||
);
|
||||
|
@ -66,8 +64,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
// We used SizedBox for inter-widget height padding in columns, otherwise elements can render a little too close together.
|
||||
Widget _buildForm() {
|
||||
return Consumer<Settings>(builder: (context, theme, child) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||
return Scrollbar(
|
||||
isAlwaysShown: true,
|
||||
child: SingleChildScrollView(
|
||||
|
@ -81,308 +78,184 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
child: Container(
|
||||
margin: EdgeInsets.all(30),
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
||||
Visibility(
|
||||
visible: Provider.of<ProfileInfoState>(context).onion.isNotEmpty,
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
|
||||
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<ProfileInfoState>(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<ProfileInfoState>(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<ProfileInfoState>(context).onion.isEmpty,
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
|
||||
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: <Widget>[
|
||||
Visibility(
|
||||
visible:
|
||||
Provider.of<ProfileInfoState>(context)
|
||||
.onion
|
||||
.isNotEmpty,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
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<ProfileInfoState>(
|
||||
context)
|
||||
.imagePath),
|
||||
width: 100,
|
||||
height: 100,
|
||||
))),
|
||||
),
|
||||
)
|
||||
])),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
CwtchLabel(
|
||||
label: AppLocalizations.of(context)
|
||||
.displayNameLabel),
|
||||
visible: Provider.of<ProfileInfoState>(context, listen: false).onion.isNotEmpty,
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
CwtchLabel(label: AppLocalizations.of(context).currentPasswordLabel),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
CwtchTextField(
|
||||
controller: ctrlrNick,
|
||||
labelText:
|
||||
AppLocalizations.of(context)
|
||||
.yourDisplayName,
|
||||
CwtchPasswordField(
|
||||
controller: ctrlrOldPass,
|
||||
validator: (value) {
|
||||
if (value.isEmpty) {
|
||||
return "Please enter a display name";
|
||||
// Password field can be empty when just updating the profile, not on creation
|
||||
if (Provider.of<ProfileInfoState>(context, listen: false).onion.isEmpty && value.isEmpty && usePassword) {
|
||||
return AppLocalizations.of(context).passwordErrorEmpty;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
]),
|
||||
Visibility(
|
||||
visible:
|
||||
Provider.of<ProfileInfoState>(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<ProfileInfoState>(context)
|
||||
.onion
|
||||
.isEmpty,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
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,
|
||||
),
|
||||
])),
|
||||
CwtchLabel(label: AppLocalizations.of(context).password1Label),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Visibility(
|
||||
visible: usePassword,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Visibility(
|
||||
visible:
|
||||
Provider.of<ProfileInfoState>(
|
||||
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<ProfileInfoState>(
|
||||
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<ProfileInfoState>(
|
||||
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<ProfileInfoState>(
|
||||
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;
|
||||
}),
|
||||
]),
|
||||
CwtchPasswordField(
|
||||
controller: ctrlrPass,
|
||||
validator: (value) {
|
||||
// Password field can be empty when just updating the profile, not on creation
|
||||
if (Provider.of<ProfileInfoState>(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,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: _createPressed,
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: theme
|
||||
.current()
|
||||
.defaultButtonColor()),
|
||||
child: Text(
|
||||
Provider.of<ProfileInfoState>(context)
|
||||
.onion
|
||||
.isEmpty
|
||||
? AppLocalizations.of(context)
|
||||
.addNewProfileBtn
|
||||
: AppLocalizations.of(context)
|
||||
.saveProfileBtn),
|
||||
CwtchLabel(label: AppLocalizations.of(context).password2Label),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Visibility(
|
||||
visible: Provider.of<ProfileInfoState>(
|
||||
context,
|
||||
listen: false)
|
||||
.onion
|
||||
.isNotEmpty,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Tooltip(message: AppLocalizations.of(context).enterCurrentPasswordForDelete, child:
|
||||
ElevatedButton.icon(
|
||||
onPressed: checkCurrentPassword() ? null : () {
|
||||
showAlertDialog(context);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: theme
|
||||
.current()
|
||||
.defaultButtonColor()),
|
||||
icon: Icon(Icons.delete_forever),
|
||||
|
||||
label: Text(
|
||||
AppLocalizations.of(context)
|
||||
.deleteBtn),
|
||||
))
|
||||
]))
|
||||
]))))));
|
||||
CwtchPasswordField(
|
||||
controller: ctrlrPass2,
|
||||
validator: (value) {
|
||||
// Password field can be empty when just updating the profile, not on creation
|
||||
if (Provider.of<ProfileInfoState>(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<ProfileInfoState>(context).onion.isEmpty ? AppLocalizations.of(context).addNewProfileBtn : AppLocalizations.of(context).saveProfileBtn),
|
||||
),
|
||||
Visibility(
|
||||
visible: Provider.of<ProfileInfoState>(context, listen: false).onion.isNotEmpty,
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Tooltip(
|
||||
message: AppLocalizations.of(context).enterCurrentPasswordForDelete,
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: checkCurrentPassword()
|
||||
? null
|
||||
: () {
|
||||
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<ProfileInfoState>(context, listen: false).onion));
|
||||
Clipboard.setData(new ClipboardData(text: Provider.of<ProfileInfoState>(context, listen: false).onion));
|
||||
// TODO Toast
|
||||
}
|
||||
|
||||
|
@ -393,14 +266,10 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
if (_formKey.currentState.validate()) {
|
||||
if (Provider.of<ProfileInfoState>(context, listen: false).onion.isEmpty) {
|
||||
if (usePassword == true) {
|
||||
Provider.of<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.CreateProfile(ctrlrNick.value.text, ctrlrPass.value.text);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.CreateProfile(ctrlrNick.value.text, ctrlrPass.value.text);
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
Provider.of<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.CreateProfile(ctrlrNick.value.text, "be gay do crime");
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.CreateProfile(ctrlrNick.value.text, "be gay do crime");
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
} else {
|
||||
|
@ -413,11 +282,7 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
};
|
||||
final json = jsonEncode(event);
|
||||
|
||||
Provider.of<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.SendProfileEvent(
|
||||
Provider.of<ProfileInfoState>(context, listen: false).onion,
|
||||
json);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SendProfileEvent(Provider.of<ProfileInfoState>(context, listen: false).onion, json);
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
// At this points passwords have been validated to be the same and not empty
|
||||
|
@ -428,26 +293,15 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
};
|
||||
final updateNameEventJson = jsonEncode(updateNameEvent);
|
||||
|
||||
Provider.of<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.SendProfileEvent(
|
||||
Provider.of<ProfileInfoState>(context, listen: false).onion,
|
||||
updateNameEventJson);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SendProfileEvent(Provider.of<ProfileInfoState>(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<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.SendProfileEvent(
|
||||
Provider.of<ProfileInfoState>(context, listen: false).onion,
|
||||
updatePasswordEventJson);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SendProfileEvent(Provider.of<ProfileInfoState>(context, listen: false).onion, updatePasswordEventJson);
|
||||
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
@ -459,7 +313,6 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
bool checkCurrentPassword() {
|
||||
return ctrlrOldPass.value.text.isEmpty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
showAlertDialog(BuildContext context) {
|
||||
|
@ -467,12 +320,9 @@ 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
|
||||
|
@ -480,12 +330,9 @@ 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: () {
|
||||
|
@ -511,4 +358,3 @@ showAlertDialog(BuildContext context) {
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("%1's contacts".replaceAll(
|
||||
"%1",
|
||||
Provider.of<ProfileInfoState>(context).nickname ??
|
||||
Provider.of<ProfileInfoState>(context).onion ??
|
||||
'')), //todo
|
||||
title: Text("%1's contacts".replaceAll("%1", Provider.of<ProfileInfoState>(context).nickname ?? Provider.of<ProfileInfoState>(context).onion ?? '')), //todo
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.copy),
|
||||
|
@ -41,9 +37,12 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
|
||||
Widget _buildContactList() {
|
||||
final tiles = Provider.of<ContactListState>(context).contacts.map((ContactInfoState contact) {
|
||||
return ChangeNotifierProvider<ContactInfoState>.value(value: contact, child: ContactRow());
|
||||
return ChangeNotifierProvider<ContactInfoState>.value(value: contact, child: ContactRow());
|
||||
});
|
||||
final divided = ListTile.divideTiles(context: context, tiles: tiles, ).toList();
|
||||
final divided = ListTile.divideTiles(
|
||||
context: context,
|
||||
tiles: tiles,
|
||||
).toList();
|
||||
return ListView(children: divided);
|
||||
}
|
||||
|
||||
|
@ -59,9 +58,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -26,10 +26,7 @@ class _DoubleColumnViewState extends State<DoubleColumnView> {
|
|||
child: flwtch.selectedConversation == ""
|
||||
? Center(child: Text("pick a contact"))
|
||||
: //dev
|
||||
Container(
|
||||
child: MessageView(
|
||||
profile: flwtch.selectedProfile,
|
||||
conversationHandle: flwtch.selectedConversation)),
|
||||
Container(child: MessageView(profile: flwtch.selectedProfile, conversationHandle: flwtch.selectedConversation)),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -25,9 +25,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations
|
||||
.of(context)
|
||||
.cwtchSettingsTitle),
|
||||
title: Text(AppLocalizations.of(context).cwtchSettingsTitle),
|
||||
),
|
||||
body: _buildSettingsList(),
|
||||
);
|
||||
|
@ -35,122 +33,97 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
|
||||
Widget _buildSettingsList() {
|
||||
return Consumer<Settings>(builder: (context, settings, child) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||
return Scrollbar(
|
||||
isAlwaysShown: true,
|
||||
child: SingleChildScrollView(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Column(children: [
|
||||
ListTile(
|
||||
title: Text(AppLocalizations
|
||||
.of(context)
|
||||
.settingLanguage,
|
||||
style: TextStyle(color: settings.current().mainTextColor())),
|
||||
leading:
|
||||
Icon(Icons.language, color: settings.current().mainTextColor()),
|
||||
trailing: DropdownButton(
|
||||
value: Provider
|
||||
.of<Settings>(context)
|
||||
.locale
|
||||
.languageCode,
|
||||
onChanged: (String newValue) {
|
||||
setState(() {
|
||||
settings.switchLocale(Locale(newValue, ''));
|
||||
saveSettings(context);
|
||||
});
|
||||
},
|
||||
items: AppLocalizations.supportedLocales
|
||||
.map<DropdownMenuItem<String>>((Locale value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.languageCode,
|
||||
child: Text(getLanguageFull(context, value.languageCode)),
|
||||
);
|
||||
}).toList())),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations
|
||||
.of(context)
|
||||
.settingTheme,
|
||||
style: TextStyle(color: settings.current().mainTextColor())),
|
||||
value: settings.current() == Opaque.light,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.setLight();
|
||||
} else {
|
||||
settings.setDark();
|
||||
}
|
||||
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
secondary: Icon(Icons.lightbulb_outline,
|
||||
color: settings.current().mainTextColor()),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations
|
||||
.of(context)
|
||||
.experimentsEnabled,
|
||||
style: TextStyle(color: settings.current().mainTextColor())),
|
||||
value: settings.experimentsEnabled,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiments();
|
||||
} else {
|
||||
settings.disableExperiments();
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
secondary: Icon(Icons.science,
|
||||
color: settings.current().mainTextColor()),
|
||||
),
|
||||
Visibility(visible: settings.experimentsEnabled, child: Column(children: [
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations
|
||||
.of(context)
|
||||
.enableGroups,
|
||||
style: TextStyle(color: settings.current().mainTextColor())),
|
||||
value: settings.experiments.containsKey("tapir-groups-experiment") && settings.experiments["tapir-groups-experiment"],
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment("tapir-groups-experiment");
|
||||
} else {
|
||||
settings.disableExperiment("tapir-groups-experiment");
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
|
||||
return Scrollbar(
|
||||
isAlwaysShown: true,
|
||||
child: SingleChildScrollView(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Column(children: [
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context).settingLanguage, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
leading: Icon(Icons.language, color: settings.current().mainTextColor()),
|
||||
trailing: DropdownButton(
|
||||
value: Provider.of<Settings>(context).locale.languageCode,
|
||||
onChanged: (String newValue) {
|
||||
setState(() {
|
||||
settings.switchLocale(Locale(newValue, ''));
|
||||
saveSettings(context);
|
||||
});
|
||||
},
|
||||
secondary: Icon(Icons.group_sharp,
|
||||
color: settings.current().mainTextColor()),
|
||||
),
|
||||
],)),
|
||||
AboutListTile(
|
||||
icon: Icon(Icons.info, color: settings.current().mainTextColor()),
|
||||
applicationIcon: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Image(
|
||||
image: AssetImage("assets/knott.png"),
|
||||
width: 128,
|
||||
height: 128,
|
||||
)),
|
||||
applicationName: "Cwtch (Flutter UI)",
|
||||
applicationVersion: AppLocalizations
|
||||
.of(context)
|
||||
.version
|
||||
.replaceAll(
|
||||
"%1",
|
||||
constructVersionString(
|
||||
Provider
|
||||
.of<Settings>(context)
|
||||
.packageInfo)),
|
||||
applicationLegalese: '\u{a9} 2021 Open Privacy Research Society',
|
||||
),
|
||||
]))));
|
||||
});
|
||||
items: AppLocalizations.supportedLocales.map<DropdownMenuItem<String>>((Locale value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.languageCode,
|
||||
child: Text(getLanguageFull(context, value.languageCode)),
|
||||
);
|
||||
}).toList())),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context).settingTheme, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
value: settings.current() == Opaque.light,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.setLight();
|
||||
} else {
|
||||
settings.setDark();
|
||||
}
|
||||
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
secondary: Icon(Icons.lightbulb_outline, color: settings.current().mainTextColor()),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context).experimentsEnabled, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
value: settings.experimentsEnabled,
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiments();
|
||||
} else {
|
||||
settings.disableExperiments();
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
secondary: Icon(Icons.science, color: settings.current().mainTextColor()),
|
||||
),
|
||||
Visibility(
|
||||
visible: settings.experimentsEnabled,
|
||||
child: Column(
|
||||
children: [
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context).enableGroups, style: TextStyle(color: settings.current().mainTextColor())),
|
||||
value: settings.experiments.containsKey("tapir-groups-experiment") && settings.experiments["tapir-groups-experiment"],
|
||||
onChanged: (bool value) {
|
||||
if (value) {
|
||||
settings.enableExperiment("tapir-groups-experiment");
|
||||
} else {
|
||||
settings.disableExperiment("tapir-groups-experiment");
|
||||
}
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
secondary: Icon(Icons.group_sharp, color: settings.current().mainTextColor()),
|
||||
),
|
||||
],
|
||||
)),
|
||||
AboutListTile(
|
||||
icon: Icon(Icons.info, color: settings.current().mainTextColor()),
|
||||
applicationIcon: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Image(
|
||||
image: AssetImage("assets/knott.png"),
|
||||
width: 128,
|
||||
height: 128,
|
||||
)),
|
||||
applicationName: "Cwtch (Flutter UI)",
|
||||
applicationVersion: AppLocalizations.of(context).version.replaceAll("%1", constructVersionString(Provider.of<Settings>(context).packageInfo)),
|
||||
applicationLegalese: '\u{a9} 2021 Open Privacy Research Society',
|
||||
),
|
||||
]))));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +168,5 @@ saveSettings(context) {
|
|||
"Data": {"Data": jsonEncode(settings.asJson())},
|
||||
};
|
||||
final updateSettingsEventJson = jsonEncode(updateSettingsEvent);
|
||||
Provider.of<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.SendAppEvent(updateSettingsEventJson);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SendAppEvent(updateSettingsEventJson);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ 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;
|
||||
|
||||
|
@ -35,9 +34,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
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(),
|
||||
);
|
||||
}
|
||||
|
@ -62,25 +59,15 @@ class _MessageViewState extends State<MessageView> {
|
|||
height: 80,
|
||||
child: Column(children: <Widget>[
|
||||
ElevatedButton(
|
||||
child:
|
||||
Icon(Icons.send, color: Opaque.current().mainTextColor()),
|
||||
child: Icon(Icons.send, color: Opaque.current().mainTextColor()),
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all(
|
||||
Opaque.current().defaultButtonColor()),
|
||||
backgroundColor: MaterialStateProperty.all(Opaque.current().defaultButtonColor()),
|
||||
),
|
||||
onPressed: _sendMessage,
|
||||
),
|
||||
Row(children: <Widget>[
|
||||
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()))),
|
||||
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()))),
|
||||
])
|
||||
]),
|
||||
),
|
||||
|
|
|
@ -29,15 +29,12 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context).profileName),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.bug_report_outlined),
|
||||
onPressed: _testChangingContactInfo),
|
||||
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.settings), onPressed: _pushGlobalSettings),
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
|
@ -50,7 +47,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
}
|
||||
|
||||
void _testChangingContactInfo() {
|
||||
Provider.of<ProfileListState>(context, listen:false).profiles.first.nickname = "yay!";
|
||||
Provider.of<ProfileListState>(context, listen: false).profiles.first.nickname = "yay!";
|
||||
}
|
||||
|
||||
void _pushGlobalSettings() {
|
||||
|
@ -103,9 +100,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
|
|||
ElevatedButton(
|
||||
child: Text(AppLocalizations.of(context).unlock),
|
||||
onPressed: () {
|
||||
Provider.of<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.LoadProfiles(ctrlrPassword.value.text);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.LoadProfiles(ctrlrPassword.value.text);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
|
|
|
@ -22,19 +22,14 @@ class _TripleColumnViewState extends State<TripleColumnView> {
|
|||
),
|
||||
Flexible(
|
||||
flex: flwtch.columns[1],
|
||||
child: flwtch.selectedProfile == null
|
||||
? Center(child: Text("pick a profile"))
|
||||
: ContactsView(), //dev
|
||||
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)),
|
||||
Container(child: MessageView(profile: flwtch.selectedProfile, conversationHandle: flwtch.selectedConversation)),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,10 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_app/settings.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
||||
// Provides a styled Text Field for use in Form Widgets.
|
||||
// Callers must provide a text controller, label helper text and a validator.
|
||||
class CwtchButtonTextField extends StatefulWidget {
|
||||
CwtchButtonTextField(
|
||||
{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;
|
||||
|
@ -37,32 +35,17 @@ class _CwtchButtonTextFieldState extends State<CwtchButtonTextField> {
|
|||
),
|
||||
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)),
|
||||
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()),
|
||||
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()),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,16 +20,23 @@ class _ContactRowState extends State<ContactRow> {
|
|||
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/"+contact.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/" + contact.imagePath),
|
||||
width: 50,
|
||||
height: 50,
|
||||
))),
|
||||
),
|
||||
),
|
||||
trailing: contact.isInvitation != null && contact.isInvitation
|
||||
? Column(children: <Widget>[
|
||||
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)
|
||||
? Column(children: <Widget>[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<FlwtchState>(context).biggerFont,
|
||||
|
@ -53,8 +60,7 @@ class _ContactRowState extends State<ContactRow> {
|
|||
builder: (BuildContext builderContext) {
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider<ProfileInfoState>(
|
||||
create: (_) => Provider.of<ProfileInfoState>(context)),
|
||||
ChangeNotifierProvider<ProfileInfoState>(create: (_) => Provider.of<ProfileInfoState>(context)),
|
||||
],
|
||||
child: MessageView(conversationHandle: handle),
|
||||
);
|
||||
|
|
|
@ -24,15 +24,8 @@ class _MessageBubbleState extends State<MessageBubble> {
|
|||
super.didChangeDependencies();
|
||||
|
||||
print("requesting message " + widget.messageIndex.toString());
|
||||
Provider.of<FlwtchState>(context)
|
||||
.cwtch
|
||||
.GetMessage(
|
||||
widget.profile.onion, widget.contactOnion, widget.messageIndex)
|
||||
.then((jsonMessage) {
|
||||
print("got message: " +
|
||||
widget.messageIndex.toString() +
|
||||
": " +
|
||||
jsonMessage);
|
||||
Provider.of<FlwtchState>(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(() {
|
||||
|
@ -50,9 +43,7 @@ class _MessageBubbleState extends State<MessageBubble> {
|
|||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Opaque.current().messageFromOtherBackgroundColor(),
|
||||
border: Border.all(
|
||||
color: Opaque.current().messageFromOtherBackgroundColor(),
|
||||
width: 1),
|
||||
border: Border.all(color: Opaque.current().messageFromOtherBackgroundColor(), width: 1),
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(15.0),
|
||||
),
|
||||
|
@ -65,11 +56,7 @@ class _MessageBubbleState extends State<MessageBubble> {
|
|||
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())
|
||||
ack ? Icon(Icons.check_circle_outline, color: Opaque.current().mainTextColor()) : Icon(Icons.hourglass_bottom_outlined, color: Opaque.current().mainTextColor())
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -10,8 +10,7 @@ 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();
|
||||
|
@ -50,14 +49,8 @@ class _MessageListState extends State<MessageList> {
|
|||
return;
|
||||
}
|
||||
|
||||
Provider.of<FlwtchState>(context, listen: false)
|
||||
.cwtch
|
||||
.NumMessages(
|
||||
Provider.of<ProfileInfoState>(context, listen: false).onion,
|
||||
widget.conversationHandle)
|
||||
.then((n) {
|
||||
if (n != conversationNumMessages)
|
||||
setState(() => conversationNumMessages = n);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.NumMessages(Provider.of<ProfileInfoState>(context, listen: false).onion, widget.conversationHandle).then((n) {
|
||||
if (n != conversationNumMessages) setState(() => conversationNumMessages = n);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,28 +28,14 @@ class _CwtchTextFieldState extends State<CwtchPasswordField> {
|
|||
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)),
|
||||
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)),
|
||||
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()),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -37,13 +37,9 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.create,
|
||||
color: Provider.of<Settings>(context).current().mainTextColor()),
|
||||
icon: Icon(Icons.create, color: Provider.of<Settings>(context).current().mainTextColor()),
|
||||
onPressed: () {
|
||||
_pushAddEditProfile(
|
||||
onion: profile.onion,
|
||||
displayName: profile.nickname,
|
||||
profileImage: profile.imagePath);
|
||||
_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(
|
||||
|
@ -82,8 +78,7 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
ChangeNotifierProvider<ProfileInfoState>.value(value: profile),
|
||||
ChangeNotifierProvider<ContactListState>.value(value: profile.contactList),
|
||||
],
|
||||
builder: (context, widget) =>
|
||||
includeDoublePane ? DoubleColumnView() : ContactsView(),
|
||||
builder: (context, widget) => includeDoublePane ? DoubleColumnView() : ContactsView(),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
@ -96,8 +91,7 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
return MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider<ProfileInfoState>(
|
||||
create: (_) => ProfileInfoState(
|
||||
onion: onion, nickname: displayName, imagePath: profileImage),
|
||||
create: (_) => ProfileInfoState(onion: onion, nickname: displayName, imagePath: profileImage),
|
||||
),
|
||||
],
|
||||
builder: (context, widget) => AddEditProfileView(),
|
||||
|
|
|
@ -23,37 +23,20 @@ class _CwtchTextFieldState extends State<CwtchTextField> {
|
|||
validator: widget.validator,
|
||||
decoration: InputDecoration(
|
||||
labelText: widget.labelText,
|
||||
labelStyle: TextStyle(
|
||||
color: theme.current().mainTextColor(),
|
||||
backgroundColor: theme.current().textfieldBackgroundColor()),
|
||||
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)),
|
||||
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()),
|
||||
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()),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,9 +18,7 @@ class _TorStatusState extends State<TorStatusLabel> {
|
|||
stream: Provider.of<FlwtchState>(context).appStatus.torStatus(),
|
||||
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
|
||||
return Text(
|
||||
snapshot.hasData
|
||||
? snapshot.data
|
||||
: AppLocalizations.of(context).loadingTor,
|
||||
snapshot.hasData ? snapshot.data : AppLocalizations.of(context).loadingTor,
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
);
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue