model contact uses authorization now; add tooltips to contact pics in chat; dual action: add or goto #105
|
@ -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
|
||||
- `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
|
||||
|
||||
|
|
|
@ -103,6 +103,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...
|
||||
|
@ -116,6 +124,12 @@ class CwtchNotifier {
|
|||
try {
|
||||
var message = Provider.of<MessageMetadata>(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...
|
||||
|
@ -134,7 +148,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<MessageMetadata>(key.currentContext!, listen: false);
|
||||
|
@ -153,7 +167,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<MessageMetadata>(key!.currentContext!, listen: false);
|
||||
message.error = true;
|
||||
|
|
|
@ -89,7 +89,7 @@ class CwtchFfi implements Cwtch {
|
|||
String bundledTor = "";
|
||||
Map<String, String> 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");
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ class _ContactsViewState extends State<ContactsView> {
|
|||
),
|
||||
Expanded(
|
||||
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: [
|
||||
IconButton(icon: TorIcon(), onPressed: _pushTorStatus),
|
||||
|
|
|
@ -33,7 +33,8 @@ class _DoubleColumnViewState extends State<DoubleColumnView> {
|
|||
: //dev
|
||||
MultiProvider(providers: [
|
||||
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())),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -93,20 +93,31 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
);
|
||||
}).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<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
return DropdownMenuItem<String>(
|
||||
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<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
return DropdownMenuItem<String>(
|
||||
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),
|
||||
|
|
|
@ -173,6 +173,7 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
|
|||
var handle = Provider.of<ContactInfoState>(context, listen: false).onion;
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.LeaveGroup(profileOnion, handle);
|
||||
Future.delayed(Duration(milliseconds: 500), () {
|
||||
Provider.of<AppState>(context, listen: false).selectedConversation = null;
|
||||
Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog
|
||||
});
|
||||
},
|
||||
|
|
|
@ -47,6 +47,11 @@ class _MessageViewState extends State<MessageView> {
|
|||
|
||||
@override
|
||||
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);
|
||||
return WillPopScope(
|
||||
onWillPop: _onWillPop,
|
||||
|
@ -65,7 +70,11 @@ class _MessageViewState extends State<MessageView> {
|
|||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(Provider.of<ContactInfoState>(context).nickname)
|
||||
Expanded(
|
||||
child: Text(
|
||||
Provider.of<ContactInfoState>(context).nickname,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
))
|
||||
]),
|
||||
actions: [
|
||||
//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;
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.LeaveConversation(profileOnion, handle);
|
||||
Future.delayed(Duration(milliseconds: 500), () {
|
||||
Provider.of<AppState>(context, listen: false).selectedConversation = null;
|
||||
Navigator.of(context).popUntil((route) => route.settings.name == "conversations"); // dismiss dialog
|
||||
});
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue