mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 14:48:41 +00:00
bug fix
This commit is contained in:
parent
b756682f7c
commit
bf34920350
10 changed files with 207 additions and 139 deletions
|
|
@ -33,7 +33,7 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId = "eu.twonly.testng"
|
applicationId = "eu.twonly.testing"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
|
951DB0F2008EB94699D02555 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F3BB8E3AC9CEA61248BD989 /* libPods-Runner.a */; };
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||||
A8E4DD3B3139A6996AC817E0 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F3BB8E3AC9CEA61248BD989 /* libPods-Runner.a */; };
|
|
||||||
F3C66D726A2EB28484DF0B10 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 16FBC6F5B58E1C6646F5D447 /* GoogleService-Info.plist */; };
|
F3C66D726A2EB28484DF0B10 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 16FBC6F5B58E1C6646F5D447 /* GoogleService-Info.plist */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
|
@ -83,7 +83,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A8E4DD3B3139A6996AC817E0 /* libPods-Runner.a in Frameworks */,
|
951DB0F2008EB94699D02555 /* libPods-Runner.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
arb-dir: lib/src/localization
|
arb-dir: lib/src/localization
|
||||||
template-arb-file: app_en.arb
|
template-arb-file: app_en.arb
|
||||||
output-localization-file: app_localizations.dart
|
output-localization-file: app_localizations.dart
|
||||||
|
untranslated-messages-file: build/l10n.log
|
||||||
|
|
|
||||||
|
|
@ -144,11 +144,14 @@ class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
return (delete(messages)..where((t) => t.messageId.equals(messageId))).go();
|
return (delete(messages)..where((t) => t.messageId.equals(messageId))).go();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> containsOtherMessageId(int messageOtherId) async {
|
Future<bool> containsOtherMessageId(
|
||||||
|
int fromUserId, int messageOtherId) async {
|
||||||
final query = select(messages)
|
final query = select(messages)
|
||||||
..where((t) => t.messageOtherId.equals(messageOtherId));
|
..where((t) =>
|
||||||
final entry = await query.getSingleOrNull();
|
t.messageOtherId.equals(messageOtherId) &
|
||||||
return entry != null;
|
t.contactId.equals(fromUserId));
|
||||||
|
final entry = await query.get();
|
||||||
|
return entry.isNotEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleOrNullSelectable<Message> getMessageByMessageId(int messageId) {
|
SingleOrNullSelectable<Message> getMessageByMessageId(int messageId) {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
"contextMenuVerifyUser": "Kontakt verifizieren",
|
"contextMenuVerifyUser": "Kontakt verifizieren",
|
||||||
"contextMenuOpenChat": "Chat öffnen",
|
"contextMenuOpenChat": "Chat öffnen",
|
||||||
"contextMenuSendImage": "Bild senden",
|
"contextMenuSendImage": "Bild senden",
|
||||||
|
"mediaViewerAuthReason": "Bitte authentifiziere dich, um diesen twonly zu sehen!",
|
||||||
"messageSendState_Received": "Empfangen",
|
"messageSendState_Received": "Empfangen",
|
||||||
"messageSendState_Opened": "Geöffnet",
|
"messageSendState_Opened": "Geöffnet",
|
||||||
"messageSendState_Send": "Gesendet",
|
"messageSendState_Send": "Gesendet",
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,79 @@
|
||||||
{
|
{
|
||||||
"@@locale": "en",
|
"@@locale": "en",
|
||||||
"registerTitle": "Welcome to twonly!",
|
"registerTitle": "Welcome to twonly!",
|
||||||
|
"@registerTitle": {},
|
||||||
"registerSlogan": "twonly, a privacy friendly way to connect with friends through secure, spontaneous image sharing",
|
"registerSlogan": "twonly, a privacy friendly way to connect with friends through secure, spontaneous image sharing",
|
||||||
|
"@registerSlogan": {},
|
||||||
"onboardingWelcomeTitle": "Welcome to twonly!",
|
"onboardingWelcomeTitle": "Welcome to twonly!",
|
||||||
|
"@onboardingWelcomeTitle": {},
|
||||||
"onboardingWelcomeBody": "Experience a private and secure way to stay in touch with friends by sharing instant pictures.",
|
"onboardingWelcomeBody": "Experience a private and secure way to stay in touch with friends by sharing instant pictures.",
|
||||||
|
"@onboardingWelcomeBody": {},
|
||||||
"onboardingE2eTitle": "Carefree sharing",
|
"onboardingE2eTitle": "Carefree sharing",
|
||||||
|
"@onboardingE2eTitle": {},
|
||||||
"onboardingE2eBody": "With end-to-end encryption, enjoy the peace of mind that only you and your friends can see the moments you share.",
|
"onboardingE2eBody": "With end-to-end encryption, enjoy the peace of mind that only you and your friends can see the moments you share.",
|
||||||
|
"@onboardingE2eBody": {},
|
||||||
"onboardingFocusTitle": "Focus on sharing moments",
|
"onboardingFocusTitle": "Focus on sharing moments",
|
||||||
|
"@onboardingFocusTitle": {},
|
||||||
"onboardingFocusBody": "Say goodbye to addictive features! twonly was created for sharing moments, free from useless distractions or ads.",
|
"onboardingFocusBody": "Say goodbye to addictive features! twonly was created for sharing moments, free from useless distractions or ads.",
|
||||||
|
"@onboardingFocusBody": {},
|
||||||
"onboardingSendTwonliesTitle": "Send twonlies",
|
"onboardingSendTwonliesTitle": "Send twonlies",
|
||||||
|
"@onboardingSendTwonliesTitle": {},
|
||||||
"onboardingSendTwonliesBody": "Share moments securely with your partner. twonly ensures that only your partner can open it, keeping your moments with your partner a two(o)nly thing!",
|
"onboardingSendTwonliesBody": "Share moments securely with your partner. twonly ensures that only your partner can open it, keeping your moments with your partner a two(o)nly thing!",
|
||||||
|
"@onboardingSendTwonliesBody": {},
|
||||||
"onboardingNotProductTitle": "You are not the product!",
|
"onboardingNotProductTitle": "You are not the product!",
|
||||||
|
"@onboardingNotProductTitle": {},
|
||||||
"onboardingNotProductBody": "twonly is financed by a small monthly fee and not by selling your data.",
|
"onboardingNotProductBody": "twonly is financed by a small monthly fee and not by selling your data.",
|
||||||
|
"@onboardingNotProductBody": {},
|
||||||
"onboardingBuyOneGetTwoTitle": "Buy one get two",
|
"onboardingBuyOneGetTwoTitle": "Buy one get two",
|
||||||
|
"@onboardingBuyOneGetTwoTitle": {},
|
||||||
"onboardingBuyOneGetTwoBody": "twonly always requires at least two people, which is why you receive a second free license for your twonly partner with your purchase.",
|
"onboardingBuyOneGetTwoBody": "twonly always requires at least two people, which is why you receive a second free license for your twonly partner with your purchase.",
|
||||||
|
"@onboardingBuyOneGetTwoBody": {},
|
||||||
"onboardingGetStartedTitle": "Let's go!",
|
"onboardingGetStartedTitle": "Let's go!",
|
||||||
|
"@onboardingGetStartedTitle": {},
|
||||||
"onboardingGetStartedBody": "You can test twonly free of charge for 14 days, after that it costs either 1€/month or 9€/year.",
|
"onboardingGetStartedBody": "You can test twonly free of charge for 14 days, after that it costs either 1€/month or 9€/year.",
|
||||||
|
"@onboardingGetStartedBody": {},
|
||||||
"onboardingTryForFree": "Try for free",
|
"onboardingTryForFree": "Try for free",
|
||||||
|
"@onboardingTryForFree": {},
|
||||||
"registerUsernameSlogan": "Please select a username so others can find you!",
|
"registerUsernameSlogan": "Please select a username so others can find you!",
|
||||||
|
"@registerUsernameSlogan": {},
|
||||||
"registerUsernameDecoration": "Username",
|
"registerUsernameDecoration": "Username",
|
||||||
|
"@registerUsernameDecoration": {},
|
||||||
"registerUsernameLimits": "Username must be 3 to 12 characters long, consisting only of letters (a-z) and numbers (0-9).",
|
"registerUsernameLimits": "Username must be 3 to 12 characters long, consisting only of letters (a-z) and numbers (0-9).",
|
||||||
|
"@registerUsernameLimits": {},
|
||||||
"registerSubmitButton": "Register now!",
|
"registerSubmitButton": "Register now!",
|
||||||
|
"@registerSubmitButton": {},
|
||||||
"newMessageTitle": "New message",
|
"newMessageTitle": "New message",
|
||||||
|
"@newMessageTitle": {},
|
||||||
"chatsTapToSend": "Click to send your first image",
|
"chatsTapToSend": "Click to send your first image",
|
||||||
|
"@chatsTapToSend": {},
|
||||||
"shareImageTitle": "Share with",
|
"shareImageTitle": "Share with",
|
||||||
|
"@shareImageTitle": {},
|
||||||
"shareImageBestFriends": "Best friends",
|
"shareImageBestFriends": "Best friends",
|
||||||
|
"@shareImageBestFriends": {},
|
||||||
"shareImagedEditorSendImage": "Send",
|
"shareImagedEditorSendImage": "Send",
|
||||||
|
"@shareImagedEditorSendImage": {},
|
||||||
"shareImagedEditorShareWith": "Share with",
|
"shareImagedEditorShareWith": "Share with",
|
||||||
|
"@shareImagedEditorShareWith": {},
|
||||||
"shareImagedEditorSaveImage": "Save",
|
"shareImagedEditorSaveImage": "Save",
|
||||||
|
"@shareImagedEditorSaveImage": {},
|
||||||
"shareImagedEditorSavedImage": "Saved",
|
"shareImagedEditorSavedImage": "Saved",
|
||||||
|
"@shareImagedEditorSavedImage": {},
|
||||||
"shareImageAllUsers": "All contacts",
|
"shareImageAllUsers": "All contacts",
|
||||||
|
"@shareImageAllUsers": {},
|
||||||
"shareImageAllTwonlyWarning": "twonlies can only be send to verified contacts!",
|
"shareImageAllTwonlyWarning": "twonlies can only be send to verified contacts!",
|
||||||
|
"@shareImageAllTwonlyWarning": {},
|
||||||
"searchUsernameInput": "Username",
|
"searchUsernameInput": "Username",
|
||||||
|
"@searchUsernameInput": {},
|
||||||
"searchUsernameTitle": "Search username",
|
"searchUsernameTitle": "Search username",
|
||||||
|
"@searchUsernameTitle": {},
|
||||||
"searchUsernameNotFound": "Username not found",
|
"searchUsernameNotFound": "Username not found",
|
||||||
"searchUsernameNotFoundBody": "There is no user with the username \"{username}\" registered.",
|
"@searchUsernameNotFound": {},
|
||||||
|
"searchUsernameNotFoundBody": "There is no user with the username \"{username}\" registered",
|
||||||
|
"@searchUsernameNotFoundBody": {
|
||||||
|
"placeholders": {
|
||||||
|
"username": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
"searchUsernameNewFollowerTitle": "Follow requests",
|
"searchUsernameNewFollowerTitle": "Follow requests",
|
||||||
"searchUsernameQrCodeBtn": "Scan QR code",
|
"searchUsernameQrCodeBtn": "Scan QR code",
|
||||||
"chatListViewSearchUserNameBtn": "Add your first twonly contact!",
|
"chatListViewSearchUserNameBtn": "Add your first twonly contact!",
|
||||||
|
|
|
||||||
|
|
@ -162,147 +162,145 @@ Future<client.Response> handleDownloadData(DownloadData data) async {
|
||||||
|
|
||||||
Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
MessageJson? message = await SignalHelper.getDecryptedText(fromUserId, body);
|
MessageJson? message = await SignalHelper.getDecryptedText(fromUserId, body);
|
||||||
if (message != null) {
|
if (message == null) {
|
||||||
switch (message.kind) {
|
Logger("server_messages")
|
||||||
case MessageKind.contactRequest:
|
.info("Got invalid cypher text from $fromUserId. Deleting it.");
|
||||||
Result username = await apiProvider.getUsername(fromUserId);
|
// Message is not valid, so server can delete it
|
||||||
if (username.isSuccess) {
|
var ok = client.Response_Ok()..none = true;
|
||||||
Uint8List name = username.value.userdata.username;
|
return client.Response()..ok = ok;
|
||||||
|
}
|
||||||
|
|
||||||
int added =
|
switch (message.kind) {
|
||||||
await twonlyDatabase.contactsDao.insertContact(ContactsCompanion(
|
case MessageKind.contactRequest:
|
||||||
username: Value(utf8.decode(name)),
|
return handleContactRequest(fromUserId, message);
|
||||||
userId: Value(fromUserId),
|
|
||||||
requested: Value(true),
|
case MessageKind.opened:
|
||||||
));
|
final update = MessagesCompanion(openedAt: Value(message.timestamp));
|
||||||
if (added > 0) {
|
await twonlyDatabase.messagesDao.updateMessageByOtherUser(
|
||||||
localPushNotificationNewMessage(
|
fromUserId,
|
||||||
fromUserId.toInt(),
|
message.messageId!,
|
||||||
message,
|
update,
|
||||||
999999,
|
);
|
||||||
);
|
break;
|
||||||
}
|
|
||||||
|
case MessageKind.rejectRequest:
|
||||||
|
await twonlyDatabase.contactsDao.deleteContactByUserId(fromUserId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MessageKind.acceptRequest:
|
||||||
|
final update = ContactsCompanion(accepted: Value(true));
|
||||||
|
await twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
||||||
|
localPushNotificationNewMessage(fromUserId.toInt(), message, 8888888);
|
||||||
|
notifyContactsAboutProfileChange();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MessageKind.profileChange:
|
||||||
|
var content = message.content;
|
||||||
|
if (content is ProfileContent) {
|
||||||
|
final update = ContactsCompanion(
|
||||||
|
avatarSvg: Value(content.avatarSvg),
|
||||||
|
displayName: Value(content.displayName),
|
||||||
|
);
|
||||||
|
twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MessageKind.ack:
|
||||||
|
final update = MessagesCompanion(acknowledgeByUser: Value(true));
|
||||||
|
await twonlyDatabase.messagesDao.updateMessageByOtherUser(
|
||||||
|
fromUserId,
|
||||||
|
message.messageId!,
|
||||||
|
update,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (message.kind != MessageKind.textMessage &&
|
||||||
|
message.kind != MessageKind.media &&
|
||||||
|
message.kind != MessageKind.storedMediaFile) {
|
||||||
|
Logger("handleServerMessages")
|
||||||
|
.shout("Got unknown MessageKind $message");
|
||||||
|
} else if (message.content == null || message.messageId == null) {
|
||||||
|
Logger("handleServerMessages")
|
||||||
|
.shout("Content or messageid not defined $message");
|
||||||
|
} else {
|
||||||
|
// when a message is received doubled ignore it...
|
||||||
|
if ((await twonlyDatabase.messagesDao
|
||||||
|
.containsOtherMessageId(fromUserId, message.messageId!))) {
|
||||||
|
var ok = client.Response_Ok()..none = true;
|
||||||
|
return client.Response()..ok = ok;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case MessageKind.opened:
|
String content = jsonEncode(message.content!.toJson());
|
||||||
final update = MessagesCompanion(openedAt: Value(message.timestamp));
|
|
||||||
await twonlyDatabase.messagesDao.updateMessageByOtherUser(
|
bool acknowledgeByUser = false;
|
||||||
fromUserId,
|
DateTime? openedAt;
|
||||||
message.messageId!,
|
|
||||||
|
if (message.kind == MessageKind.storedMediaFile) {
|
||||||
|
acknowledgeByUser = true;
|
||||||
|
openedAt = DateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
int? responseToMessageId;
|
||||||
|
final textContent = message.content!;
|
||||||
|
if (textContent is TextMessageContent) {
|
||||||
|
responseToMessageId = textContent.responseToMessageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
final update = MessagesCompanion(
|
||||||
|
contactId: Value(fromUserId),
|
||||||
|
kind: Value(message.kind),
|
||||||
|
messageOtherId: Value(message.messageId),
|
||||||
|
contentJson: Value(content),
|
||||||
|
acknowledgeByServer: Value(true),
|
||||||
|
acknowledgeByUser: Value(acknowledgeByUser),
|
||||||
|
responseToMessageId: Value(responseToMessageId),
|
||||||
|
openedAt: Value(openedAt),
|
||||||
|
downloadState: Value(message.kind == MessageKind.media
|
||||||
|
? DownloadState.pending
|
||||||
|
: DownloadState.downloaded),
|
||||||
|
sendAt: Value(message.timestamp),
|
||||||
|
);
|
||||||
|
|
||||||
|
final messageId = await twonlyDatabase.messagesDao.insertMessage(
|
||||||
update,
|
update,
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
case MessageKind.rejectRequest:
|
if (messageId == null) {
|
||||||
await twonlyDatabase.contactsDao.deleteContactByUserId(fromUserId);
|
return client.Response()..error = ErrorCode.InternalError;
|
||||||
break;
|
|
||||||
case MessageKind.acceptRequest:
|
|
||||||
final update = ContactsCompanion(accepted: Value(true));
|
|
||||||
await twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
|
||||||
localPushNotificationNewMessage(fromUserId.toInt(), message, 8888888);
|
|
||||||
notifyContactsAboutProfileChange();
|
|
||||||
break;
|
|
||||||
case MessageKind.profileChange:
|
|
||||||
var content = message.content;
|
|
||||||
if (content is ProfileContent) {
|
|
||||||
final update = ContactsCompanion(
|
|
||||||
avatarSvg: Value(content.avatarSvg),
|
|
||||||
displayName: Value(content.displayName),
|
|
||||||
);
|
|
||||||
twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case MessageKind.ack:
|
encryptAndSendMessage(
|
||||||
final update = MessagesCompanion(acknowledgeByUser: Value(true));
|
|
||||||
await twonlyDatabase.messagesDao.updateMessageByOtherUser(
|
|
||||||
fromUserId,
|
|
||||||
message.messageId!,
|
message.messageId!,
|
||||||
update,
|
fromUserId,
|
||||||
|
MessageJson(
|
||||||
|
kind: MessageKind.ack,
|
||||||
|
messageId: message.messageId!,
|
||||||
|
content: MessageContent(),
|
||||||
|
timestamp: DateTime.now(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (message.kind != MessageKind.textMessage &&
|
|
||||||
message.kind != MessageKind.media &&
|
|
||||||
message.kind != MessageKind.storedMediaFile) {
|
|
||||||
Logger("handleServerMessages")
|
|
||||||
.shout("Got unknown MessageKind $message");
|
|
||||||
} else if (message.content != null && message.messageId != null) {
|
|
||||||
String content = jsonEncode(message.content!.toJson());
|
|
||||||
|
|
||||||
bool acknowledgeByUser = false;
|
if (message.kind == MessageKind.media) {
|
||||||
DateTime? openedAt;
|
twonlyDatabase.contactsDao.incFlameCounter(
|
||||||
if (message.kind == MessageKind.storedMediaFile) {
|
|
||||||
acknowledgeByUser = true;
|
|
||||||
openedAt = DateTime.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
int? responseToMessageId;
|
|
||||||
final textContent = message.content!;
|
|
||||||
if (textContent is TextMessageContent) {
|
|
||||||
responseToMessageId = textContent.responseToMessageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// when a message is received doubled ignore it...
|
|
||||||
if ((await twonlyDatabase.messagesDao
|
|
||||||
.containsOtherMessageId(message.messageId!))) {
|
|
||||||
var ok = client.Response_Ok()..none = true;
|
|
||||||
return client.Response()..ok = ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
final update = MessagesCompanion(
|
|
||||||
contactId: Value(fromUserId),
|
|
||||||
kind: Value(message.kind),
|
|
||||||
messageOtherId: Value(message.messageId),
|
|
||||||
contentJson: Value(content),
|
|
||||||
acknowledgeByServer: Value(true),
|
|
||||||
acknowledgeByUser: Value(acknowledgeByUser),
|
|
||||||
responseToMessageId: Value(responseToMessageId),
|
|
||||||
openedAt: Value(openedAt),
|
|
||||||
downloadState: Value(message.kind == MessageKind.media
|
|
||||||
? DownloadState.pending
|
|
||||||
: DownloadState.downloaded),
|
|
||||||
sendAt: Value(message.timestamp),
|
|
||||||
);
|
|
||||||
|
|
||||||
final messageId = await twonlyDatabase.messagesDao.insertMessage(
|
|
||||||
update,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (messageId == null) {
|
|
||||||
return client.Response()..error = ErrorCode.InternalError;
|
|
||||||
}
|
|
||||||
|
|
||||||
encryptAndSendMessage(
|
|
||||||
message.messageId!,
|
|
||||||
fromUserId,
|
fromUserId,
|
||||||
MessageJson(
|
true,
|
||||||
kind: MessageKind.ack,
|
message.timestamp,
|
||||||
messageId: message.messageId!,
|
|
||||||
content: MessageContent(),
|
|
||||||
timestamp: DateTime.now(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (message.kind == MessageKind.media) {
|
if (!globalIsAppInBackground) {
|
||||||
twonlyDatabase.contactsDao.incFlameCounter(
|
final content = message.content;
|
||||||
fromUserId,
|
if (content is MediaMessageContent) {
|
||||||
true,
|
tryDownloadMedia(
|
||||||
message.timestamp,
|
messageId,
|
||||||
);
|
fromUserId,
|
||||||
|
content,
|
||||||
if (!globalIsAppInBackground) {
|
);
|
||||||
final content = message.content;
|
|
||||||
if (content is MediaMessageContent) {
|
|
||||||
tryDownloadMedia(
|
|
||||||
messageId,
|
|
||||||
fromUserId,
|
|
||||||
content,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
localPushNotificationNewMessage(fromUserId, message, messageId);
|
|
||||||
}
|
}
|
||||||
}
|
localPushNotificationNewMessage(fromUserId, message, messageId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var ok = client.Response_Ok()..none = true;
|
var ok = client.Response_Ok()..none = true;
|
||||||
return client.Response()..ok = ok;
|
return client.Response()..ok = ok;
|
||||||
|
|
@ -321,3 +319,31 @@ Future<client.Response> handleRequestNewPreKey() async {
|
||||||
var ok = client.Response_Ok()..prekeys = prekeys;
|
var ok = client.Response_Ok()..prekeys = prekeys;
|
||||||
return client.Response()..ok = ok;
|
return client.Response()..ok = ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<client.Response> handleContactRequest(
|
||||||
|
int fromUserId, MessageJson message) async {
|
||||||
|
// request the username by the server so an attacker can not
|
||||||
|
// forge the displayed username in the contact request
|
||||||
|
Result username = await apiProvider.getUsername(fromUserId);
|
||||||
|
if (username.isSuccess) {
|
||||||
|
Uint8List name = username.value.userdata.username;
|
||||||
|
|
||||||
|
int added = await twonlyDatabase.contactsDao.insertContact(
|
||||||
|
ContactsCompanion(
|
||||||
|
username: Value(utf8.decode(name)),
|
||||||
|
userId: Value(fromUserId),
|
||||||
|
requested: Value(true),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (added > 0) {
|
||||||
|
localPushNotificationNewMessage(
|
||||||
|
fromUserId,
|
||||||
|
message,
|
||||||
|
999999,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var ok = client.Response_Ok()..none = true;
|
||||||
|
return client.Response()..ok = ok;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -279,9 +279,6 @@ Future<MessageJson?> getDecryptedText(int source, Uint8List msg) async {
|
||||||
if (msgs == null) return null;
|
if (msgs == null) return null;
|
||||||
Uint8List body = msgs[0];
|
Uint8List body = msgs[0];
|
||||||
int type = bytesToInt(msgs[1]);
|
int type = bytesToInt(msgs[1]);
|
||||||
|
|
||||||
// gzip.decode(body);
|
|
||||||
|
|
||||||
Uint8List plaintext;
|
Uint8List plaintext;
|
||||||
if (type == CiphertextMessage.prekeyType) {
|
if (type == CiphertextMessage.prekeyType) {
|
||||||
PreKeySignalMessage pre = PreKeySignalMessage(body);
|
PreKeySignalMessage pre = PreKeySignalMessage(body);
|
||||||
|
|
|
||||||
|
|
@ -426,7 +426,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.10.4"
|
version: "3.10.4"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ dependencies:
|
||||||
avatar_maker: ^0.2.0
|
avatar_maker: ^0.2.0
|
||||||
flutter_svg: ^2.0.17
|
flutter_svg: ^2.0.17
|
||||||
flutter_volume_controller: ^1.3.3
|
flutter_volume_controller: ^1.3.3
|
||||||
|
fixnum: ^1.1.1
|
||||||
# avatar_maker
|
# avatar_maker
|
||||||
# avatar_maker:
|
# avatar_maker:
|
||||||
# path: ./dependencies/avatar_maker/
|
# path: ./dependencies/avatar_maker/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue