Merge branch 'trunk' into authTooltip
continuous-integration/drone/pr Build is passing
Details
continuous-integration/drone/pr Build is passing
Details
This commit is contained in:
commit
80f9ed6a6c
|
@ -1 +1 @@
|
||||||
v1.0.0-25-g801a805-2021-07-07-16-10
|
v1.0.0-29-g41ae09d-2021-07-08-20-22
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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())),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue