Prevent Android from Wiping Unsaved Conversations Every Time the Foreground Reloads #857
|
@ -1 +1 @@
|
|||
2024-02-26-09-28-v0.0.13
|
||||
2024-02-26-18-01-v0.0.14
|
|
@ -177,6 +177,9 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
.build()
|
||||
|
||||
notificationManager.notify(getNotificationID(data.getString("ProfileOnion"), channelId), newNotification)
|
||||
if (fh != null) {
|
||||
fh.close()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -577,9 +577,6 @@ class MainActivity: FlutterActivity() {
|
|||
result.success(Cwtch.searchConversations(profile, pattern))
|
||||
return
|
||||
}
|
||||
"ReconnectCwtchForeground" -> {
|
||||
Cwtch.reconnectCwtchForeground()
|
||||
}
|
||||
"Shutdown" -> {
|
||||
Cwtch.shutdownCwtch();
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ abstract class Cwtch {
|
|||
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> Start();
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> ReconnectCwtchForeground();
|
||||
|
||||
Future<String> getCwtchDir();
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:cwtch/cwtch/cwtch.dart';
|
|||
import 'package:cwtch/main.dart';
|
||||
import 'package:cwtch/models/appstate.dart';
|
||||
import 'package:cwtch/models/contact.dart';
|
||||
import 'package:cwtch/models/message.dart';
|
||||
import 'package:cwtch/models/profilelist.dart';
|
||||
import 'package:cwtch/models/remoteserver.dart';
|
||||
import 'package:cwtch/models/servers.dart';
|
||||
|
@ -58,7 +59,14 @@ class CwtchNotifier {
|
|||
// EnvironmentConfig.debugLog("NewEvent $type $data");
|
||||
switch (type) {
|
||||
case "CwtchStarted":
|
||||
if (data["Reload"] == "true" && profileCN.num > 0) {
|
||||
// don't reload...
|
||||
// unless we have loaded no profiles...then there isnt a risk and this
|
||||
// might be a first time (e.g. new apk, existing service)
|
||||
} else {
|
||||
|
||||
flwtchState.cwtch.LoadProfiles(DefaultPassword);
|
||||
}
|
||||
|
||||
appState.SetCwtchInit();
|
||||
break;
|
||||
case "CwtchStartError":
|
||||
|
@ -188,21 +196,9 @@ class CwtchNotifier {
|
|||
var senderImage = data['picture'];
|
||||
var isAuto = data['Auto'] == "true";
|
||||
String contenthash = data['ContentHash'];
|
||||
|
||||
var selectedProfile = appState.selectedProfile == data["ProfileOnion"];
|
||||
var selectedConversation = selectedProfile && appState.selectedConversation == identifier;
|
||||
var notification = data["notification"];
|
||||
|
||||
if (selectedConversation && seenMessageCallback != null) {
|
||||
seenMessageCallback!(data["ProfileOnion"]!, identifier, DateTime.now().toUtc());
|
||||
}
|
||||
|
||||
if (notification == "SimpleEvent") {
|
||||
notificationManager.notify(notificationSimple ?? "New Message", "", 0);
|
||||
} else if (notification == "ContactInfo") {
|
||||
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier);
|
||||
notificationManager.notify((notificationConversationInfo ?? "New Message from %1").replaceFirst("%1", (contact?.nickname ?? senderHandle.toString())), data["ProfileOnion"], identifier);
|
||||
}
|
||||
|
||||
profileCN.getProfile(data["ProfileOnion"])?.newMessage(
|
||||
identifier,
|
||||
messageID,
|
||||
|
@ -215,6 +211,19 @@ class CwtchNotifier {
|
|||
selectedProfile,
|
||||
selectedConversation,
|
||||
);
|
||||
|
||||
// Now perform the notification logic...
|
||||
var notification = data["notification"];
|
||||
if (selectedConversation && seenMessageCallback != null) {
|
||||
seenMessageCallback!(data["ProfileOnion"]!, identifier, DateTime.now().toUtc());
|
||||
}
|
||||
|
||||
if (notification == "SimpleEvent") {
|
||||
notificationManager.notify(notificationSimple ?? "New Message", "", 0);
|
||||
} else if (notification == "ContactInfo") {
|
||||
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier);
|
||||
notificationManager.notify((notificationConversationInfo ?? "New Message from %1").replaceFirst("%1", (contact?.nickname ?? senderHandle.toString())), data["ProfileOnion"], identifier);
|
||||
}
|
||||
appState.notifyProfileUnread();
|
||||
break;
|
||||
case "PeerAcknowledgement":
|
||||
|
|
|
@ -270,14 +270,6 @@ class CwtchFfi implements Cwtch {
|
|||
return _cwtchDir;
|
||||
}
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> ReconnectCwtchForeground() async {
|
||||
var reconnectCwtch = library.lookup<NativeFunction<Void Function()>>("c_ReconnectCwtchForeground");
|
||||
// ignore: non_constant_identifier_names
|
||||
final ReconnectCwtchForeground = reconnectCwtch.asFunction<void Function()>();
|
||||
ReconnectCwtchForeground();
|
||||
}
|
||||
|
||||
// Called on object being disposed to (presumably on app close) to close the isolate that's listening to libcwtch-go events
|
||||
@override
|
||||
void dispose() {
|
||||
|
|
|
@ -86,12 +86,6 @@ class CwtchGomobile implements Cwtch {
|
|||
cwtchPlatform.invokeMethod("Start", {"appDir": _cwtchDir, "torPath": torPath});
|
||||
}
|
||||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<void> ReconnectCwtchForeground() async {
|
||||
cwtchPlatform.invokeMethod("ReconnectCwtchForeground", {});
|
||||
}
|
||||
|
||||
// Handle libcwtch-go events (received via kotlin) and dispatch to the cwtchNotifier
|
||||
Future<void> _handleAppbusEvent(MethodCall call) async {
|
||||
final String json = call.arguments;
|
||||
|
|
|
@ -64,6 +64,7 @@ Message compileOverlay(MessageInfo messageInfo) {
|
|||
|
||||
abstract class CacheHandler {
|
||||
Future<MessageInfo?> get(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache);
|
||||
Future<MessageInfo?> sync(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache);
|
||||
}
|
||||
|
||||
class ByIndex implements CacheHandler {
|
||||
|
@ -128,7 +129,7 @@ class ByIndex implements CacheHandler {
|
|||
List<dynamic> messagesWrapper = jsonDecode(msgs);
|
||||
|
||||
for (; i < messagesWrapper.length; i++) {
|
||||
var messageInfo = messageWrapperToInfo(profileOnion, conversationIdentifier, messagesWrapper[i]);
|
||||
var messageInfo = MessageWrapperToInfo(profileOnion, conversationIdentifier, messagesWrapper[i]);
|
||||
cache.addIndexed(messageInfo, start + i);
|
||||
}
|
||||
} catch (e, stacktrace) {
|
||||
|
@ -143,6 +144,13 @@ class ByIndex implements CacheHandler {
|
|||
void add(MessageCache cache, MessageInfo messageInfo) {
|
||||
cache.addIndexed(messageInfo, index);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MessageInfo?> sync(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache) {
|
||||
EnvironmentConfig.debugLog("performing a resync on message ${index}");
|
||||
fetchAndProcess(index, 1, cwtch, profileOnion, conversationIdentifier, cache);
|
||||
return get(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
}
|
||||
|
||||
class ById implements CacheHandler {
|
||||
|
@ -172,6 +180,11 @@ class ById implements CacheHandler {
|
|||
}
|
||||
return fetch(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MessageInfo?> sync(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache) {
|
||||
return get(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
}
|
||||
|
||||
class ByContentHash implements CacheHandler {
|
||||
|
@ -200,6 +213,11 @@ class ByContentHash implements CacheHandler {
|
|||
}
|
||||
return fetch(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MessageInfo?> sync(Cwtch cwtch, String profileOnion, int conversationIdentifier, MessageCache cache) {
|
||||
return get(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
}
|
||||
|
||||
List<Message> getReplies(MessageCache cache, int messageIdentifier) {
|
||||
|
@ -257,6 +275,16 @@ Future<Message> messageHandler(BuildContext context, String profileOnion, int co
|
|||
|
||||
MessageInfo? messageInfo = await cacheHandler.get(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
|
||||
if (messageInfo != null) {
|
||||
if (messageInfo.metadata.ackd == false) {
|
||||
if (messageInfo.metadata.lastChecked == null || messageInfo.metadata.lastChecked!.difference(DateTime.now()).abs().inSeconds > 30) {
|
||||
messageInfo.metadata.lastChecked = DateTime.now();
|
||||
// NOTE: Only ByIndex lookups will trigger
|
||||
messageInfo = await cacheHandler.sync(cwtch, profileOnion, conversationIdentifier, cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messageInfo != null) {
|
||||
return compileOverlay(messageInfo);
|
||||
} else {
|
||||
|
@ -272,14 +300,14 @@ MessageInfo? messageJsonToInfo(String profileOnion, int conversationIdentifier,
|
|||
return null;
|
||||
}
|
||||
|
||||
return messageWrapperToInfo(profileOnion, conversationIdentifier, messageWrapper);
|
||||
return MessageWrapperToInfo(profileOnion, conversationIdentifier, messageWrapper);
|
||||
} catch (e, stacktrace) {
|
||||
EnvironmentConfig.debugLog("message handler exception on parse message and cache: " + e.toString() + " " + stacktrace.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
MessageInfo messageWrapperToInfo(String profileOnion, int conversationIdentifier, dynamic messageWrapper) {
|
||||
MessageInfo MessageWrapperToInfo(String profileOnion, int conversationIdentifier, dynamic messageWrapper) {
|
||||
// Construct the initial metadata
|
||||
var messageID = messageWrapper['ID'];
|
||||
var timestamp = DateTime.tryParse(messageWrapper['Timestamp'])!;
|
||||
|
@ -312,6 +340,7 @@ class MessageMetadata extends ChangeNotifier {
|
|||
|
||||
final String? signature;
|
||||
final String contenthash;
|
||||
DateTime? lastChecked;
|
||||
|
||||
dynamic get attributes => this._attributes;
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ class MessageCache extends ChangeNotifier {
|
|||
|
||||
void addNew(String profileOnion, int conversation, int messageID, DateTime timestamp, String senderHandle, String senderImage, bool isAuto, String data, String contenthash) {
|
||||
this.cache[messageID] = MessageInfo(MessageMetadata(profileOnion, conversation, messageID, timestamp, senderHandle, senderImage, "", {}, false, false, isAuto, contenthash), data);
|
||||
this.cache[messageID]?.metadata.lastChecked = DateTime.now(); // Don't check straight away...
|
||||
this.cacheByIndex.insert(0, LocalIndexMessage(messageID));
|
||||
if (contenthash != "") {
|
||||
this.cacheByHash[contenthash] = messageID;
|
||||
|
|
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.14.0+40
|
||||
version: 1.14.7+41
|
||||
|
||||
environment:
|
||||
sdk: ">=2.17.0 <4.0.0"
|
||||
|
|
Loading…
Reference in New Issue
not reloading, presumably loading default pw profiles for the first time