some small changes

This commit is contained in:
otsmr 2025-04-07 00:55:34 +02:00
parent 1962c70431
commit 6d67a16840
7 changed files with 149 additions and 78 deletions

View file

@ -20,7 +20,7 @@ class NotificationService: UNNotificationServiceExtension {
if let bestAttemptContent = bestAttemptContent {
guard let _userInfo = bestAttemptContent.userInfo as? [String: Any],
guard let _ = bestAttemptContent.userInfo as? [String: Any],
let push_data = bestAttemptContent.userInfo["push_data"] as? String else {
return contentHandler(bestAttemptContent);
}
@ -109,6 +109,8 @@ func getPushNotificationData(pushDataJson: String) -> (title: String, body: Stri
return ("Test Notification", "This is a test notification.")
} else if displayName != nil {
return (displayName!, getPushNotificationText(pushKind: pushKind))
} else {
return ("", getPushNotificationTextWithoutUserId(pushKind: pushKind))
}
} else {
@ -332,3 +334,37 @@ func getPushNotificationText(pushKind: PushKind) -> String {
// Return the corresponding message or an empty string if not found
return pushNotificationText[pushKind] ?? ""
}
func getPushNotificationTextWithoutUserId(pushKind: PushKind) -> String {
let systemLanguage = Locale.current.languageCode ?? "en" // Get the current system language
var pushNotificationText: [PushKind: String] = [:]
// Define the messages based on the system language
if systemLanguage.contains("de") { // German
pushNotificationText = [
.text: "Du hast eine Nachricht erhalten.",
.twonly: "Du hast ein twonly erhalten.",
.video: "Du hast ein Video erhalten.",
.image: "Du hast ein Bild erhalten.",
.contactRequest: "Du hast eine Kontaktanfrage erhalten.",
.acceptRequest: "Deine Kontaktanfrage wurde angenommen.",
.storedMediaFile: "Dein Bild wurde gespeichert.",
.reaction: "Du hast eine Reaktion auf dein Bild erhalten."
]
} else { // Default to English
pushNotificationText = [
.text: "You got a message.",
.twonly: "You got a twonly.",
.video: "You got a video.",
.image: "You got an image.",
.contactRequest: "You got a contact request.",
.acceptRequest: "Your contact request has been accepted.",
.storedMediaFile: "Your image has been saved.",
.reaction: "You got a reaction to your image."
]
}
// Return the corresponding message or an empty string if not found
return pushNotificationText[pushKind] ?? ""
}

View file

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 77;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */

View file

@ -125,7 +125,7 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
Future<List<Contact>> getAllNotBlockedContacts() {
return (select(contacts)
..where((t) => t.accepted.equals(true) & t.blocked.equals(false))
..where((t) => t.blocked.equals(false))
..orderBy([(t) => OrderingTerm.desc(t.lastMessageExchange)]))
.get();
}

View file

@ -70,7 +70,9 @@ class RetransmitMessage {
messageId: json['messageId'],
userId: json['userId'],
bytes: base64Decode(json['bytes']),
pushData: json['pushData'],
pushData: json['pushData'] == null
? null
: List<int>.from(json['pushData'].map((item) => item as int)),
);
}

View file

@ -201,6 +201,7 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
final update = ContactsCompanion(accepted: Value(true));
await twonlyDatabase.contactsDao.updateContact(fromUserId, update);
notifyContactsAboutProfileChange();
setupNotificationWithUsers();
break;
case MessageKind.profileChange:

View file

@ -313,6 +313,9 @@ Future handlePushData(String pushDataJson) async {
"Test notification", "This is a test notification.");
} else if (fromUserId != null) {
showLocalPushNotification(fromUserId, pushKind);
} else {
showLocalPushNotificationWithoutUserId(pushKind);
setupNotificationWithUsers();
}
}
} catch (e) {
@ -336,7 +339,6 @@ Future<Map<int, PushUser>> getPushKeys(String storageKey) async {
pushKeys[int.parse(key)] = PushUser.fromJson(value);
});
}
print("read: $storageKey: $pushKeys");
return pushKeys;
}
@ -348,7 +350,6 @@ Future setPushKeys(String storageKey, Map<int, PushUser> pushKeys) async {
});
String jsonString = jsonEncode(jsonToSend);
print("write: $storageKey: $pushKeys");
await storage.write(
key: storageKey,
value: jsonString,
@ -357,45 +358,9 @@ Future setPushKeys(String storageKey, Map<int, PushUser> pushKeys) async {
);
}
/// Streams are created so that app can respond to notification-related events
/// since the plugin is initialized in the `main` function
final StreamController<NotificationResponse> selectNotificationStream =
StreamController<NotificationResponse>.broadcast();
const MethodChannel platform = MethodChannel('twonly.eu/notifications');
const String portName = 'notification_send_port';
class ReceivedNotification {
ReceivedNotification({
required this.id,
required this.title,
required this.body,
required this.payload,
this.data,
});
final int id;
final String? title;
final String? body;
final String? payload;
final Map<String, dynamic>? data;
}
String? selectedNotificationPayload;
/// A notification action which triggers a url launch event
const String urlLaunchActionId = 'id_1';
/// A notification action which triggers a App navigation event
const String navigationActionId = 'id_3';
/// Defines a iOS/MacOS notification category for text input actions.
const String darwinNotificationCategoryText = 'textCategory';
/// Defines a iOS/MacOS notification category for plain actions.
const String darwinNotificationCategoryPlain = 'plainCategory';
@pragma('vm:entry-point')
void notificationTapBackground(NotificationResponse notificationResponse) {
// ignore: avoid_print
@ -444,36 +409,6 @@ Future<void> setupPushNotification() async {
);
}
Future<String?> getAvatarIcon(Contact user) async {
if (user.avatarSvg == null) return null;
final PictureInfo pictureInfo =
await vg.loadPicture(SvgStringLoader(user.avatarSvg!), null);
final ui.Image image = await pictureInfo.picture.toImage(300, 300);
final ByteData? byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
final Uint8List pngBytes = byteData!.buffer.asUint8List();
// Get the directory to save the image
final directory = await getApplicationDocumentsDirectory();
final avatarsDirectory = Directory('${directory.path}/avatars');
// Create the avatars directory if it does not exist
if (!await avatarsDirectory.exists()) {
await avatarsDirectory.create(recursive: true);
}
final filePath = '${avatarsDirectory.path}/${user.userId}.png';
final file = File(filePath);
await file.writeAsBytes(pngBytes);
pictureInfo.picture.dispose();
return filePath;
}
Future showLocalPushNotification(
int fromUserId,
PushKind pushKind,
@ -522,6 +457,39 @@ Future showLocalPushNotification(
);
}
Future showLocalPushNotificationWithoutUserId(
PushKind pushKind,
) async {
String? title;
String? body;
body = getPushNotificationTextWithoutUserId(pushKind);
if (body == "") {
Logger("localPushNotificationNewMessage")
.shout("No push notification type defined!");
}
AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('0', 'Messages',
channelDescription: 'Messages from other users.',
importance: Importance.max,
priority: Priority.max,
ticker: 'You got a new message.');
const DarwinNotificationDetails darwinNotificationDetails =
DarwinNotificationDetails();
NotificationDetails notificationDetails = NotificationDetails(
android: androidNotificationDetails, iOS: darwinNotificationDetails);
await flutterLocalNotificationsPlugin.show(
2,
title,
body,
notificationDetails,
payload: pushKind.name,
);
}
Future customLocalPushNotification(String title, String msg) async {
const AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
@ -545,6 +513,37 @@ Future customLocalPushNotification(String title, String msg) async {
);
}
String getPushNotificationTextWithoutUserId(PushKind pushKind) {
Map<String, String> pushNotificationText;
String systemLanguage = Platform.localeName;
if (systemLanguage.contains("de")) {
pushNotificationText = {
PushKind.text.name: "Du hast eine Nachricht erhalten.",
PushKind.twonly.name: "Du hast ein twonly erhalten.",
PushKind.video.name: "Du hast ein Video erhalten.",
PushKind.image.name: "Du hast ein Bild erhalten.",
PushKind.contactRequest.name: "Du hast eine Kontaktanfrage erhalten.",
PushKind.acceptRequest.name: "Deine Kontaktanfrage wurde angenommen.",
PushKind.storedMediaFile.name: "Dein Bild wurde gespeichert.",
PushKind.reaction.name: "Du hast eine Reaktion auf dein Bild erhalten."
};
} else {
pushNotificationText = {
PushKind.text.name: "You got a message.",
PushKind.twonly.name: "You got a twonly.",
PushKind.video.name: "You got a video.",
PushKind.image.name: "You got an image.",
PushKind.contactRequest.name: "You got a contact request.",
PushKind.acceptRequest.name: "Your contact request has been accepted.",
PushKind.storedMediaFile.name: "Your image has been saved.",
PushKind.reaction.name: "You got a reaction to your image."
};
}
return pushNotificationText[pushKind.name] ?? "";
}
String getPushNotificationText(PushKind pushKind) {
String systemLanguage = Platform.localeName;
@ -575,3 +574,33 @@ String getPushNotificationText(PushKind pushKind) {
}
return pushNotificationText[pushKind.name] ?? "";
}
Future<String?> getAvatarIcon(Contact user) async {
if (user.avatarSvg == null) return null;
final PictureInfo pictureInfo =
await vg.loadPicture(SvgStringLoader(user.avatarSvg!), null);
final ui.Image image = await pictureInfo.picture.toImage(300, 300);
final ByteData? byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
final Uint8List pngBytes = byteData!.buffer.asUint8List();
// Get the directory to save the image
final directory = await getApplicationDocumentsDirectory();
final avatarsDirectory = Directory('${directory.path}/avatars');
// Create the avatars directory if it does not exist
if (!await avatarsDirectory.exists()) {
await avatarsDirectory.create(recursive: true);
}
final filePath = '${avatarsDirectory.path}/${user.userId}.png';
final file = File(filePath);
await file.writeAsBytes(pngBytes);
pictureInfo.picture.dispose();
return filePath;
}

View file

@ -51,15 +51,18 @@ class _SearchUsernameView extends State<SearchUsernameView> {
return;
}
int added =
await twonlyDatabase.contactsDao.insertContact(ContactsCompanion(
username: Value(searchUserName.text),
userId: Value(res.value.userdata.userId.toInt()),
requested: Value(false),
));
int added = await twonlyDatabase.contactsDao.insertContact(
ContactsCompanion(
username: Value(searchUserName.text),
userId: Value(res.value.userdata.userId.toInt()),
requested: Value(false),
),
);
if (added > 0) {
if (await SignalHelper.addNewContact(res.value.userdata)) {
// before notifying the other party, add
await setupNotificationWithUsers();
encryptAndSendMessage(
null,
res.value.userdata.userId.toInt(),