From 057732c445b30ea39fb169795ce8be2824e8faeb Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Wed, 7 Jul 2021 16:12:20 -0700 Subject: [PATCH 1/4] Add support for CWTCH_DIR env var --- LIBCWTCH-GO.version | 2 +- README.md | 4 +++- lib/cwtch/ffi.dart | 7 ++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index 080fef9f..534536d7 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -v1.0.0-25-g801a805-2021-07-07-16-10 \ No newline at end of file +v1.0.0-27-g4d218df-2021-07-07-23-27 diff --git a/README.md b/README.md index 25c80b52..f95318aa 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,12 @@ This README covers build instructions, for information on Cwtch itself please go - Linux: Available from [https://cwtch.im/download/](https://cwtch.im/download/) as a .tar.gz - `install.home.sh` installs the app into your home directory - `install.sys.sh` as root to install system wide + - or run out of the unziped directory ## Running -Cwtch logging is controlable with the following environment variables: +Cwtch processes the following environment variables: +- `CWTCH_HOME=` overrides the default storage path of `~/.cwtch` with what ever you choose - `LOG_FILE=` will reroute all of libcwtch-go's logging to the specified file instead of the console - `LOG_LEVEL=debug` will set the log level to debug instead of info diff --git a/lib/cwtch/ffi.dart b/lib/cwtch/ffi.dart index a1b4bda7..f0957f08 100644 --- a/lib/cwtch/ffi.dart +++ b/lib/cwtch/ffi.dart @@ -89,7 +89,7 @@ class CwtchFfi implements Cwtch { String bundledTor = ""; Map envVars = Platform.environment; if (Platform.isLinux) { - home = (envVars['HOME'])!; + home = envVars['HOME']!; if (await File("linux/tor").exists()) { bundledTor = "linux/tor"; } else if (await File("lib/tor").exists()) { @@ -102,10 +102,11 @@ class CwtchFfi implements Cwtch { bundledTor = "tor"; } } else if (Platform.isWindows) { - home = (envVars['UserProfile'])!; + home = envVars['UserProfile']!; bundledTor = "Tor\\Tor\\tor.exe"; } - var cwtchDir = path.join(home, ".cwtch"); + + var cwtchDir = envVars['CWTCH_HOME'] ?? path.join(home, ".cwtch"); if (EnvironmentConfig.BUILD_VER == dev_version) { cwtchDir = path.join(cwtchDir, "dev"); } From 9029386344334589232287c4badc08df87cc1ceb Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Thu, 8 Jul 2021 13:28:30 -0700 Subject: [PATCH 2/4] UI state fixes Fix #89 Fix #75 --- LIBCWTCH-GO.version | 2 +- lib/cwtch/cwtchNotifier.dart | 18 ++++++++++++++++-- lib/views/contactsview.dart | 2 +- lib/views/doublecolview.dart | 3 ++- lib/views/messageview.dart | 11 ++++++++++- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index 534536d7..b70bed05 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -v1.0.0-27-g4d218df-2021-07-07-23-27 +v1.0.0-29-g41ae09d-2021-07-08-20-22 diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index 4ecc0ec5..2d905c59 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -105,6 +105,14 @@ class CwtchNotifier { } profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.totalMessages++; profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(data["RemotePeer"], DateTime.now()); + + // We only ever see messages from authenticated peers. + // If the contact is marked as offline then override this - can happen when the contact is removed from the front + // end during syncing. + if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.isOnline() == false) { + profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.status = "Authenticated"; + } + break; case "PeerAcknowledgement": // We don't use these anymore, IndexedAcknowledgement is more suited to the UI front end... @@ -118,6 +126,12 @@ class CwtchNotifier { try { var message = Provider.of(key.currentContext!, listen: false); if (message == null) break; + // We only ever see acks from authenticated peers. + // If the contact is marked as offline then override this - can happen when the contact is removed from the front + // end during syncing. + if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.isOnline() == false) { + profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.status = "Authenticated"; + } message.ackd = true; } catch (e) { // ignore, we received an ack for a message that hasn't loaded onto the screen yet... @@ -136,7 +150,7 @@ class CwtchNotifier { } else { // from me (already displayed - do not update counter) var idx = data["Signature"]; - var key = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.getMessageKey(idx); + var key = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])?.getMessageKey(idx); if (key == null) break; try { var message = Provider.of(key.currentContext!, listen: false); @@ -155,7 +169,7 @@ class CwtchNotifier { case "IndexedFailure": EnvironmentConfig.debugLog("IndexedFailure"); var idx = data["Index"]; - var key = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.getMessageKey(idx); + var key = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])?.getMessageKey(idx); try { var message = Provider.of(key!.currentContext!, listen: false); message.error = true; diff --git a/lib/views/contactsview.dart b/lib/views/contactsview.dart index d52709be..d116977f 100644 --- a/lib/views/contactsview.dart +++ b/lib/views/contactsview.dart @@ -49,7 +49,7 @@ class _ContactsViewState extends State { ), Expanded( child: Text("%1 ยป %2".replaceAll("%1", Provider.of(context).nickname).replaceAll("%2", AppLocalizations.of(context)!.titleManageContacts), - overflow: TextOverflow.ellipsis, style: TextStyle(color: Provider.of(context).current().mainTextColor()))), //todo + overflow: TextOverflow.ellipsis, style: TextStyle(color: Provider.of(context).current().mainTextColor()))), ])), actions: [ IconButton(icon: TorIcon(), onPressed: _pushTorStatus), diff --git a/lib/views/doublecolview.dart b/lib/views/doublecolview.dart index e7d3a260..ebd7ffff 100644 --- a/lib/views/doublecolview.dart +++ b/lib/views/doublecolview.dart @@ -33,7 +33,8 @@ class _DoubleColumnViewState extends State { : //dev MultiProvider(providers: [ ChangeNotifierProvider.value(value: Provider.of(context)), - ChangeNotifierProvider.value(value: Provider.of(context).contactList.getContact(flwtch.selectedConversation!)!), + ChangeNotifierProvider.value( + value: flwtch.selectedConversation != null ? Provider.of(context).contactList.getContact(flwtch.selectedConversation!)! : ContactInfoState("", "")), ], child: Container(child: MessageView())), ), ], diff --git a/lib/views/messageview.dart b/lib/views/messageview.dart index d295e379..b327fc09 100644 --- a/lib/views/messageview.dart +++ b/lib/views/messageview.dart @@ -47,6 +47,11 @@ class _MessageViewState extends State { @override Widget build(BuildContext context) { + // After leaving a conversation the selected conversation is set to null... + if (Provider.of(context).profileOnion == "") { + return Card(child: Center(child: Text(AppLocalizations.of(context)!.addContactFirst))); + } + var appState = Provider.of(context); return WillPopScope( onWillPop: _onWillPop, @@ -65,7 +70,11 @@ class _MessageViewState extends State { SizedBox( width: 10, ), - Text(Provider.of(context).nickname) + Expanded( + child: Text( + Provider.of(context).nickname, + overflow: TextOverflow.ellipsis, + )) ]), actions: [ //IconButton(icon: Icon(Icons.chat), onPressed: _pushContactSettings), From d4ab6585ea608580cc26d9c0739aeec7b28b2e80 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Thu, 8 Jul 2021 13:28:30 -0700 Subject: [PATCH 3/4] UI state fixes Fix #89 Fix #75 --- lib/views/groupsettingsview.dart | 1 + lib/views/peersettingsview.dart | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/views/groupsettingsview.dart b/lib/views/groupsettingsview.dart index f1e50b95..a0149122 100644 --- a/lib/views/groupsettingsview.dart +++ b/lib/views/groupsettingsview.dart @@ -173,6 +173,7 @@ class _GroupSettingsViewState extends State { var handle = Provider.of(context, listen: false).onion; Provider.of(context, listen: false).cwtch.LeaveGroup(profileOnion, handle); Future.delayed(Duration(milliseconds: 500), () { + Provider.of(context, listen: false).selectedConversation = null; Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog }); }, diff --git a/lib/views/peersettingsview.dart b/lib/views/peersettingsview.dart index cdcfc707..44de9d79 100644 --- a/lib/views/peersettingsview.dart +++ b/lib/views/peersettingsview.dart @@ -230,6 +230,7 @@ class _PeerSettingsViewState extends State { var handle = Provider.of(context, listen: false).onion; Provider.of(context, listen: false).cwtch.LeaveConversation(profileOnion, handle); Future.delayed(Duration(milliseconds: 500), () { + Provider.of(context, listen: false).selectedConversation = null; Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog }); }, From 992b26e1ab7aa83a6c42e5a9ed627c482c3fd58e Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Thu, 8 Jul 2021 14:43:01 -0700 Subject: [PATCH 4/4] Max width on UI Landscape Setting Fix #16 --- lib/views/globalsettingsview.dart | 37 ++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/views/globalsettingsview.dart b/lib/views/globalsettingsview.dart index 01f37db2..aa782034 100644 --- a/lib/views/globalsettingsview.dart +++ b/lib/views/globalsettingsview.dart @@ -93,20 +93,31 @@ class _GlobalSettingsViewState extends State { ); }).toList())), ListTile( - title: Text(AppLocalizations.of(context)!.settingUIColumnLandscape, style: TextStyle(color: settings.current().mainTextColor())), + title: Text( + AppLocalizations.of(context)!.settingUIColumnLandscape, + textWidthBasis: TextWidthBasis.longestLine, + softWrap: true, + style: TextStyle(color: settings.current().mainTextColor()), + ), leading: Icon(Icons.table_chart, color: settings.current().mainTextColor()), - trailing: DropdownButton( - value: settings.uiColumnModeLandscape.toString(), - onChanged: (String? newValue) { - settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!); - saveSettings(context); - }, - items: Settings.uiColumnModeOptions(true).map>((DualpaneMode value) { - return DropdownMenuItem( - value: value.toString(), - child: Text(Settings.uiColumnModeToString(value, context)), - ); - }).toList())), + trailing: Container( + width: 200.0, + child: DropdownButton( + isExpanded: true, + value: settings.uiColumnModeLandscape.toString(), + onChanged: (String? newValue) { + settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!); + saveSettings(context); + }, + items: Settings.uiColumnModeOptions(true).map>((DualpaneMode value) { + return DropdownMenuItem( + value: value.toString(), + child: Text( + Settings.uiColumnModeToString(value, context), + overflow: TextOverflow.ellipsis, + ), + ); + }).toList()))), SwitchListTile( title: Text(AppLocalizations.of(context)!.blockUnknownLabel, style: TextStyle(color: settings.current().mainTextColor())), subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections),