mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 21:48:40 +00:00
some small changes
This commit is contained in:
parent
1962c70431
commit
6d67a16840
7 changed files with 149 additions and 78 deletions
|
|
@ -20,7 +20,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||||
|
|
||||||
if let bestAttemptContent = bestAttemptContent {
|
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 {
|
let push_data = bestAttemptContent.userInfo["push_data"] as? String else {
|
||||||
return contentHandler(bestAttemptContent);
|
return contentHandler(bestAttemptContent);
|
||||||
}
|
}
|
||||||
|
|
@ -109,6 +109,8 @@ func getPushNotificationData(pushDataJson: String) -> (title: String, body: Stri
|
||||||
return ("Test Notification", "This is a test notification.")
|
return ("Test Notification", "This is a test notification.")
|
||||||
} else if displayName != nil {
|
} else if displayName != nil {
|
||||||
return (displayName!, getPushNotificationText(pushKind: pushKind))
|
return (displayName!, getPushNotificationText(pushKind: pushKind))
|
||||||
|
} else {
|
||||||
|
return ("", getPushNotificationTextWithoutUserId(pushKind: pushKind))
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -332,3 +334,37 @@ func getPushNotificationText(pushKind: PushKind) -> String {
|
||||||
// Return the corresponding message or an empty string if not found
|
// Return the corresponding message or an empty string if not found
|
||||||
return pushNotificationText[pushKind] ?? ""
|
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] ?? ""
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 77;
|
objectVersion = 54;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
|
|
||||||
Future<List<Contact>> getAllNotBlockedContacts() {
|
Future<List<Contact>> getAllNotBlockedContacts() {
|
||||||
return (select(contacts)
|
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)]))
|
..orderBy([(t) => OrderingTerm.desc(t.lastMessageExchange)]))
|
||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,9 @@ class RetransmitMessage {
|
||||||
messageId: json['messageId'],
|
messageId: json['messageId'],
|
||||||
userId: json['userId'],
|
userId: json['userId'],
|
||||||
bytes: base64Decode(json['bytes']),
|
bytes: base64Decode(json['bytes']),
|
||||||
pushData: json['pushData'],
|
pushData: json['pushData'] == null
|
||||||
|
? null
|
||||||
|
: List<int>.from(json['pushData'].map((item) => item as int)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
final update = ContactsCompanion(accepted: Value(true));
|
final update = ContactsCompanion(accepted: Value(true));
|
||||||
await twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
await twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
||||||
notifyContactsAboutProfileChange();
|
notifyContactsAboutProfileChange();
|
||||||
|
setupNotificationWithUsers();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MessageKind.profileChange:
|
case MessageKind.profileChange:
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,9 @@ Future handlePushData(String pushDataJson) async {
|
||||||
"Test notification", "This is a test notification.");
|
"Test notification", "This is a test notification.");
|
||||||
} else if (fromUserId != null) {
|
} else if (fromUserId != null) {
|
||||||
showLocalPushNotification(fromUserId, pushKind);
|
showLocalPushNotification(fromUserId, pushKind);
|
||||||
|
} else {
|
||||||
|
showLocalPushNotificationWithoutUserId(pushKind);
|
||||||
|
setupNotificationWithUsers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -336,7 +339,6 @@ Future<Map<int, PushUser>> getPushKeys(String storageKey) async {
|
||||||
pushKeys[int.parse(key)] = PushUser.fromJson(value);
|
pushKeys[int.parse(key)] = PushUser.fromJson(value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
print("read: $storageKey: $pushKeys");
|
|
||||||
return pushKeys;
|
return pushKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -348,7 +350,6 @@ Future setPushKeys(String storageKey, Map<int, PushUser> pushKeys) async {
|
||||||
});
|
});
|
||||||
|
|
||||||
String jsonString = jsonEncode(jsonToSend);
|
String jsonString = jsonEncode(jsonToSend);
|
||||||
print("write: $storageKey: $pushKeys");
|
|
||||||
await storage.write(
|
await storage.write(
|
||||||
key: storageKey,
|
key: storageKey,
|
||||||
value: jsonString,
|
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 =
|
final StreamController<NotificationResponse> selectNotificationStream =
|
||||||
StreamController<NotificationResponse>.broadcast();
|
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')
|
@pragma('vm:entry-point')
|
||||||
void notificationTapBackground(NotificationResponse notificationResponse) {
|
void notificationTapBackground(NotificationResponse notificationResponse) {
|
||||||
// ignore: avoid_print
|
// 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(
|
Future showLocalPushNotification(
|
||||||
int fromUserId,
|
int fromUserId,
|
||||||
PushKind pushKind,
|
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 {
|
Future customLocalPushNotification(String title, String msg) async {
|
||||||
const AndroidNotificationDetails androidNotificationDetails =
|
const AndroidNotificationDetails 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 getPushNotificationText(PushKind pushKind) {
|
||||||
String systemLanguage = Platform.localeName;
|
String systemLanguage = Platform.localeName;
|
||||||
|
|
||||||
|
|
@ -575,3 +574,33 @@ String getPushNotificationText(PushKind pushKind) {
|
||||||
}
|
}
|
||||||
return pushNotificationText[pushKind.name] ?? "";
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,15 +51,18 @@ class _SearchUsernameView extends State<SearchUsernameView> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int added =
|
int added = await twonlyDatabase.contactsDao.insertContact(
|
||||||
await twonlyDatabase.contactsDao.insertContact(ContactsCompanion(
|
ContactsCompanion(
|
||||||
username: Value(searchUserName.text),
|
username: Value(searchUserName.text),
|
||||||
userId: Value(res.value.userdata.userId.toInt()),
|
userId: Value(res.value.userdata.userId.toInt()),
|
||||||
requested: Value(false),
|
requested: Value(false),
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if (added > 0) {
|
if (added > 0) {
|
||||||
if (await SignalHelper.addNewContact(res.value.userdata)) {
|
if (await SignalHelper.addNewContact(res.value.userdata)) {
|
||||||
|
// before notifying the other party, add
|
||||||
|
await setupNotificationWithUsers();
|
||||||
encryptAndSendMessage(
|
encryptAndSendMessage(
|
||||||
null,
|
null,
|
||||||
res.value.userdata.userId.toInt(),
|
res.value.userdata.userId.toInt(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue