Merge branch 'trunk' into authTooltip
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
Sarah Jamie Lewis 2021-07-12 14:44:07 -07:00
commit 80f9ed6a6c
10 changed files with 63 additions and 23 deletions

View File

@ -1 +1 @@
v1.0.0-25-g801a805-2021-07-07-16-10 v1.0.0-29-g41ae09d-2021-07-08-20-22

View File

@ -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 - 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.home.sh` installs the app into your home directory
- `install.sys.sh` as root to install system wide - `install.sys.sh` as root to install system wide
- or run out of the unziped directory
## Running ## 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_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 - `LOG_LEVEL=debug` will set the log level to debug instead of info

View File

@ -103,6 +103,14 @@ class CwtchNotifier {
} }
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.totalMessages++; profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.totalMessages++;
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(data["RemotePeer"], DateTime.now()); 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; break;
case "PeerAcknowledgement": case "PeerAcknowledgement":
// We don't use these anymore, IndexedAcknowledgement is more suited to the UI front end... // We don't use these anymore, IndexedAcknowledgement is more suited to the UI front end...
@ -116,6 +124,12 @@ class CwtchNotifier {
try { try {
var message = Provider.of<MessageMetadata>(key.currentContext!, listen: false); var message = Provider.of<MessageMetadata>(key.currentContext!, listen: false);
if (message == null) break; 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; message.ackd = true;
} catch (e) { } catch (e) {
// ignore, we received an ack for a message that hasn't loaded onto the screen yet... // ignore, we received an ack for a message that hasn't loaded onto the screen yet...
@ -134,7 +148,7 @@ class CwtchNotifier {
} else { } else {
// from me (already displayed - do not update counter) // from me (already displayed - do not update counter)
var idx = data["Signature"]; 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; if (key == null) break;
try { try {
var message = Provider.of<MessageMetadata>(key.currentContext!, listen: false); var message = Provider.of<MessageMetadata>(key.currentContext!, listen: false);
@ -153,7 +167,7 @@ class CwtchNotifier {
case "IndexedFailure": case "IndexedFailure":
EnvironmentConfig.debugLog("IndexedFailure"); EnvironmentConfig.debugLog("IndexedFailure");
var idx = data["Index"]; 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 { try {
var message = Provider.of<MessageMetadata>(key!.currentContext!, listen: false); var message = Provider.of<MessageMetadata>(key!.currentContext!, listen: false);
message.error = true; message.error = true;

View File

@ -89,7 +89,7 @@ class CwtchFfi implements Cwtch {
String bundledTor = ""; String bundledTor = "";
Map<String, String> envVars = Platform.environment; Map<String, String> envVars = Platform.environment;
if (Platform.isLinux) { if (Platform.isLinux) {
home = (envVars['HOME'])!; home = envVars['HOME']!;
if (await File("linux/tor").exists()) { if (await File("linux/tor").exists()) {
bundledTor = "linux/tor"; bundledTor = "linux/tor";
} else if (await File("lib/tor").exists()) { } else if (await File("lib/tor").exists()) {
@ -102,10 +102,11 @@ class CwtchFfi implements Cwtch {
bundledTor = "tor"; bundledTor = "tor";
} }
} else if (Platform.isWindows) { } else if (Platform.isWindows) {
home = (envVars['UserProfile'])!; home = envVars['UserProfile']!;
bundledTor = "Tor\\Tor\\tor.exe"; 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) { if (EnvironmentConfig.BUILD_VER == dev_version) {
cwtchDir = path.join(cwtchDir, "dev"); cwtchDir = path.join(cwtchDir, "dev");
} }

View File

@ -83,7 +83,7 @@ class _ContactsViewState extends State<ContactsView> {
), ),
Expanded( Expanded(
child: Text("%1 » %2".replaceAll("%1", Provider.of<ProfileInfoState>(context).nickname).replaceAll("%2", AppLocalizations.of(context)!.titleManageContacts), child: Text("%1 » %2".replaceAll("%1", Provider.of<ProfileInfoState>(context).nickname).replaceAll("%2", AppLocalizations.of(context)!.titleManageContacts),
overflow: TextOverflow.ellipsis, style: TextStyle(color: Provider.of<Settings>(context).current().mainTextColor()))), //todo overflow: TextOverflow.ellipsis, style: TextStyle(color: Provider.of<Settings>(context).current().mainTextColor()))),
])), ])),
actions: [ actions: [
IconButton(icon: TorIcon(), onPressed: _pushTorStatus), IconButton(icon: TorIcon(), onPressed: _pushTorStatus),

View File

@ -33,7 +33,8 @@ class _DoubleColumnViewState extends State<DoubleColumnView> {
: //dev : //dev
MultiProvider(providers: [ MultiProvider(providers: [
ChangeNotifierProvider.value(value: Provider.of<ProfileInfoState>(context)), ChangeNotifierProvider.value(value: Provider.of<ProfileInfoState>(context)),
ChangeNotifierProvider.value(value: Provider.of<ProfileInfoState>(context).contactList.getContact(flwtch.selectedConversation!)!), ChangeNotifierProvider.value(
value: flwtch.selectedConversation != null ? Provider.of<ProfileInfoState>(context).contactList.getContact(flwtch.selectedConversation!)! : ContactInfoState("", "")),
], child: Container(child: MessageView())), ], child: Container(child: MessageView())),
), ),
], ],

View File

@ -93,20 +93,31 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
); );
}).toList())), }).toList())),
ListTile( 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()), leading: Icon(Icons.table_chart, color: settings.current().mainTextColor()),
trailing: DropdownButton( trailing: Container(
value: settings.uiColumnModeLandscape.toString(), width: 200.0,
onChanged: (String? newValue) { child: DropdownButton(
settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!); isExpanded: true,
saveSettings(context); value: settings.uiColumnModeLandscape.toString(),
}, onChanged: (String? newValue) {
items: Settings.uiColumnModeOptions(true).map<DropdownMenuItem<String>>((DualpaneMode value) { settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!);
return DropdownMenuItem<String>( saveSettings(context);
value: value.toString(), },
child: Text(Settings.uiColumnModeToString(value, context)), items: Settings.uiColumnModeOptions(true).map<DropdownMenuItem<String>>((DualpaneMode value) {
); return DropdownMenuItem<String>(
}).toList())), value: value.toString(),
child: Text(
Settings.uiColumnModeToString(value, context),
overflow: TextOverflow.ellipsis,
),
);
}).toList()))),
SwitchListTile( SwitchListTile(
title: Text(AppLocalizations.of(context)!.blockUnknownLabel, style: TextStyle(color: settings.current().mainTextColor())), title: Text(AppLocalizations.of(context)!.blockUnknownLabel, style: TextStyle(color: settings.current().mainTextColor())),
subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections), subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections),

View File

@ -173,6 +173,7 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
var handle = Provider.of<ContactInfoState>(context, listen: false).onion; var handle = Provider.of<ContactInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.LeaveGroup(profileOnion, handle); Provider.of<FlwtchState>(context, listen: false).cwtch.LeaveGroup(profileOnion, handle);
Future.delayed(Duration(milliseconds: 500), () { Future.delayed(Duration(milliseconds: 500), () {
Provider.of<AppState>(context, listen: false).selectedConversation = null;
Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog
}); });
}, },

View File

@ -47,6 +47,11 @@ class _MessageViewState extends State<MessageView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// After leaving a conversation the selected conversation is set to null...
if (Provider.of<ContactInfoState>(context).profileOnion == "") {
return Card(child: Center(child: Text(AppLocalizations.of(context)!.addContactFirst)));
}
var appState = Provider.of<AppState>(context); var appState = Provider.of<AppState>(context);
return WillPopScope( return WillPopScope(
onWillPop: _onWillPop, onWillPop: _onWillPop,
@ -65,7 +70,11 @@ class _MessageViewState extends State<MessageView> {
SizedBox( SizedBox(
width: 10, width: 10,
), ),
Text(Provider.of<ContactInfoState>(context).nickname) Expanded(
child: Text(
Provider.of<ContactInfoState>(context).nickname,
overflow: TextOverflow.ellipsis,
))
]), ]),
actions: [ actions: [
//IconButton(icon: Icon(Icons.chat), onPressed: _pushContactSettings), //IconButton(icon: Icon(Icons.chat), onPressed: _pushContactSettings),

View File

@ -230,6 +230,7 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
var handle = Provider.of<ContactInfoState>(context, listen: false).onion; var handle = Provider.of<ContactInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.LeaveConversation(profileOnion, handle); Provider.of<FlwtchState>(context, listen: false).cwtch.LeaveConversation(profileOnion, handle);
Future.delayed(Duration(milliseconds: 500), () { Future.delayed(Duration(milliseconds: 500), () {
Provider.of<AppState>(context, listen: false).selectedConversation = null;
Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog
}); });
}, },