mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 07:48:40 +00:00
add push notifications for groups and add sender name
This commit is contained in:
parent
9356a1fc70
commit
c786bb55f9
18 changed files with 514 additions and 282 deletions
|
|
@ -84,7 +84,7 @@ func getPushNotificationData(pushData: String) -> (
|
|||
pushUser = tryPushUser
|
||||
if isUUIDNewer(pushUser!.lastMessageID, pushNotification!.messageID)
|
||||
{
|
||||
return ("blocked", "blocked", 0)
|
||||
//return ("blocked", "blocked", 0)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
|
@ -109,11 +109,12 @@ func getPushNotificationData(pushData: String) -> (
|
|||
} else if pushUser != nil {
|
||||
return (
|
||||
pushUser!.displayName,
|
||||
getPushNotificationText(pushNotification: pushNotification), pushUser!.userID
|
||||
getPushNotificationText(pushNotification: pushNotification).0, pushUser!.userID
|
||||
)
|
||||
} else {
|
||||
let content = getPushNotificationText(pushNotification: pushNotification)
|
||||
return (
|
||||
"", getPushNotificationTextWithoutUserId(pushKind: pushNotification.kind), 1
|
||||
content.1, content.0, 1
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -204,28 +205,31 @@ func readFromKeychain(key: String) -> String? {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getPushNotificationText(pushNotification: PushNotification) -> String {
|
||||
func getPushNotificationText(pushNotification: PushNotification) -> (String, String) {
|
||||
let systemLanguage = Locale.current.language.languageCode?.identifier ?? "en" // Get the current system language
|
||||
|
||||
var pushNotificationText: [PushKind: String] = [:]
|
||||
var title = "Someone"
|
||||
|
||||
// Define the messages based on the system language
|
||||
if systemLanguage.contains("de") { // German
|
||||
title = "Jemand"
|
||||
pushNotificationText = [
|
||||
.text: "hat dir eine Nachricht gesendet.",
|
||||
.twonly: "hat dir ein twonly gesendet.",
|
||||
.video: "hat dir ein Video gesendet.",
|
||||
.image: "hat dir ein Bild gesendet.",
|
||||
.text: "hat eine Nachricht gesendet.",
|
||||
.twonly: "hat ein twonly gesendet.",
|
||||
.video: "hat ein Video gesendet.",
|
||||
.image: "hat ein Bild gesendet.",
|
||||
.contactRequest: "möchte sich mit dir vernetzen.",
|
||||
.acceptRequest: "ist jetzt mit dir vernetzt.",
|
||||
.storedMediaFile: "hat dein Bild gespeichert.",
|
||||
.reaction: "hat auf dein Bild reagiert.",
|
||||
.testNotification: "Das ist eine Testbenachrichtigung.",
|
||||
.reopenedMedia: "hat dein Bild erneut geöffnet.",
|
||||
.reactionToVideo: "hat mit {{reaction}} auf dein Video reagiert.",
|
||||
.reactionToText: "hat mit {{reaction}} auf deinen Text reagiert.",
|
||||
.reactionToImage: "hat mit {{reaction}} auf dein Bild reagiert.",
|
||||
.reactionToVideo: "hat mit {{content}} auf dein Video reagiert.",
|
||||
.reactionToText: "hat mit {{content}} auf deinen Text reagiert.",
|
||||
.reactionToImage: "hat mit {{content}} auf dein Bild reagiert.",
|
||||
.response: "hat dir geantwortet.",
|
||||
.addedToGroup: "hat dich zu \"{{content}}\" hinzugefügt."
|
||||
]
|
||||
} else { // Default to English
|
||||
pushNotificationText = [
|
||||
|
|
@ -239,65 +243,21 @@ func getPushNotificationText(pushNotification: PushNotification) -> String {
|
|||
.reaction: "has reacted to your image.",
|
||||
.testNotification: "This is a test notification.",
|
||||
.reopenedMedia: "has reopened your image.",
|
||||
.reactionToVideo: "has reacted with {{reaction}} to your video.",
|
||||
.reactionToText: "has reacted with {{reaction}} to your text.",
|
||||
.reactionToImage: "has reacted with {{reaction}} to your image.",
|
||||
.reactionToVideo: "has reacted with {{content}} to your video.",
|
||||
.reactionToText: "has reacted with {{content}} to your text.",
|
||||
.reactionToImage: "has reacted with {{content}} to your image.",
|
||||
.response: "has responded.",
|
||||
.addedToGroup: "has added you to \"{{content}}\""
|
||||
]
|
||||
}
|
||||
|
||||
var content = pushNotificationText[pushNotification.kind] ?? ""
|
||||
|
||||
if pushNotification.hasReactionContent {
|
||||
content.replace("{{reaction}}", with: pushNotification.reactionContent)
|
||||
if pushNotification.hasAdditionalContent {
|
||||
content.replace("{{content}}", with: pushNotification.additionalContent)
|
||||
}
|
||||
|
||||
// Return the corresponding message or an empty string if not found
|
||||
return content
|
||||
return (content, title)
|
||||
}
|
||||
|
||||
func getPushNotificationTextWithoutUserId(pushKind: PushKind) -> String {
|
||||
let systemLanguage = Locale.current.language.languageCode?.identifier ?? "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.",
|
||||
.testNotification: "Das ist eine Testbenachrichtigung.",
|
||||
.reopenedMedia: "hat dein Bild erneut geöffnet.",
|
||||
.reactionToVideo: "Du hast eine Reaktion auf dein Video erhalten.",
|
||||
.reactionToText: "Du hast eine Reaktion auf deinen Text erhalten.",
|
||||
.reactionToImage: "Du hast eine Reaktion auf dein Bild erhalten.",
|
||||
.response: "Du hast eine Antwort 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.",
|
||||
.testNotification: "This is a test notification.",
|
||||
.reopenedMedia: "has reopened your image.",
|
||||
.reactionToVideo: "You got a reaction to your video.",
|
||||
.reactionToText: "You got a reaction to your text.",
|
||||
.reactionToImage: "You got a reaction to your image.",
|
||||
.response: "You got a response.",
|
||||
]
|
||||
}
|
||||
|
||||
// Return the corresponding message or an empty string if not found
|
||||
return pushNotificationText[pushKind] ?? ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ enum PushKind: SwiftProtobuf.Enum, Swift.CaseIterable {
|
|||
case reactionToVideo // = 11
|
||||
case reactionToText // = 12
|
||||
case reactionToImage // = 13
|
||||
case addedToGroup // = 14
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
|
|
@ -59,6 +60,7 @@ enum PushKind: SwiftProtobuf.Enum, Swift.CaseIterable {
|
|||
case 11: self = .reactionToVideo
|
||||
case 12: self = .reactionToText
|
||||
case 13: self = .reactionToImage
|
||||
case 14: self = .addedToGroup
|
||||
default: self = .UNRECOGNIZED(rawValue)
|
||||
}
|
||||
}
|
||||
|
|
@ -79,6 +81,7 @@ enum PushKind: SwiftProtobuf.Enum, Swift.CaseIterable {
|
|||
case .reactionToVideo: return 11
|
||||
case .reactionToText: return 12
|
||||
case .reactionToImage: return 13
|
||||
case .addedToGroup: return 14
|
||||
case .UNRECOGNIZED(let i): return i
|
||||
}
|
||||
}
|
||||
|
|
@ -99,6 +102,7 @@ enum PushKind: SwiftProtobuf.Enum, Swift.CaseIterable {
|
|||
.reactionToVideo,
|
||||
.reactionToText,
|
||||
.reactionToImage,
|
||||
.addedToGroup,
|
||||
]
|
||||
|
||||
}
|
||||
|
|
@ -137,21 +141,21 @@ struct PushNotification: Sendable {
|
|||
/// Clears the value of `messageID`. Subsequent reads from it will return its default value.
|
||||
mutating func clearMessageID() {self._messageID = nil}
|
||||
|
||||
var reactionContent: String {
|
||||
get {return _reactionContent ?? String()}
|
||||
set {_reactionContent = newValue}
|
||||
var additionalContent: String {
|
||||
get {return _additionalContent ?? String()}
|
||||
set {_additionalContent = newValue}
|
||||
}
|
||||
/// Returns true if `reactionContent` has been explicitly set.
|
||||
var hasReactionContent: Bool {return self._reactionContent != nil}
|
||||
/// Clears the value of `reactionContent`. Subsequent reads from it will return its default value.
|
||||
mutating func clearReactionContent() {self._reactionContent = nil}
|
||||
/// Returns true if `additionalContent` has been explicitly set.
|
||||
var hasAdditionalContent: Bool {return self._additionalContent != nil}
|
||||
/// Clears the value of `additionalContent`. Subsequent reads from it will return its default value.
|
||||
mutating func clearAdditionalContent() {self._additionalContent = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _messageID: String? = nil
|
||||
fileprivate var _reactionContent: String? = nil
|
||||
fileprivate var _additionalContent: String? = nil
|
||||
}
|
||||
|
||||
struct PushUsers: Sendable {
|
||||
|
|
@ -214,7 +218,7 @@ struct PushKey: Sendable {
|
|||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
||||
|
||||
extension PushKind: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0reaction\0\u{1}response\0\u{1}text\0\u{1}video\0\u{1}twonly\0\u{1}image\0\u{1}contactRequest\0\u{1}acceptRequest\0\u{1}storedMediaFile\0\u{1}testNotification\0\u{1}reopenedMedia\0\u{1}reactionToVideo\0\u{1}reactionToText\0\u{1}reactionToImage\0")
|
||||
static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0reaction\0\u{1}response\0\u{1}text\0\u{1}video\0\u{1}twonly\0\u{1}image\0\u{1}contactRequest\0\u{1}acceptRequest\0\u{1}storedMediaFile\0\u{1}testNotification\0\u{1}reopenedMedia\0\u{1}reactionToVideo\0\u{1}reactionToText\0\u{1}reactionToImage\0\u{1}addedToGroup\0")
|
||||
}
|
||||
|
||||
extension EncryptedPushNotification: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
|
|
@ -264,7 +268,7 @@ extension EncryptedPushNotification: SwiftProtobuf.Message, SwiftProtobuf._Messa
|
|||
|
||||
extension PushNotification: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = "PushNotification"
|
||||
static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}kind\0\u{1}messageId\0\u{1}reactionContent\0")
|
||||
static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}kind\0\u{1}messageId\0\u{1}additionalContent\0")
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
|
|
@ -274,7 +278,7 @@ extension PushNotification: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme
|
|||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self.kind) }()
|
||||
case 2: try { try decoder.decodeSingularStringField(value: &self._messageID) }()
|
||||
case 3: try { try decoder.decodeSingularStringField(value: &self._reactionContent) }()
|
||||
case 3: try { try decoder.decodeSingularStringField(value: &self._additionalContent) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
|
@ -291,7 +295,7 @@ extension PushNotification: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme
|
|||
try { if let v = self._messageID {
|
||||
try visitor.visitSingularStringField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try { if let v = self._reactionContent {
|
||||
try { if let v = self._additionalContent {
|
||||
try visitor.visitSingularStringField(value: v, fieldNumber: 3)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
|
|
@ -300,7 +304,7 @@ extension PushNotification: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme
|
|||
static func ==(lhs: PushNotification, rhs: PushNotification) -> Bool {
|
||||
if lhs.kind != rhs.kind {return false}
|
||||
if lhs._messageID != rhs._messageID {return false}
|
||||
if lhs._reactionContent != rhs._reactionContent {return false}
|
||||
if lhs._additionalContent != rhs._additionalContent {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -773,5 +773,22 @@
|
|||
"twonlySafeRecoverDesc": "Wenn du ein Backup mit twonly Backup erstellt hast, kannst du es hier wiederherstellen.",
|
||||
"@twonlySafeRecoverDesc": {},
|
||||
"twonlySafeRecoverBtn": "Backup wiederherstellen",
|
||||
"@twonlySafeRecoverBtn": {}
|
||||
}
|
||||
"@twonlySafeRecoverBtn": {},
|
||||
"notificationText": "hat eine Nachricht gesendet.",
|
||||
"notificationTwonly": "hat ein twonly gesendet.",
|
||||
"notificationVideo": "hat ein Video gesendet.",
|
||||
"notificationImage": "hat ein Bild gesendet.",
|
||||
"notificationAddedToGroup": "hat dich zu \"{groupname}\" hinzugefügt.",
|
||||
"notificationContactRequest": "möchte sich mit dir vernetzen.",
|
||||
"notificationAcceptRequest": "ist jetzt mit dir vernetzt.",
|
||||
"notificationStoredMediaFile": "hat dein Bild gespeichert.",
|
||||
"notificationReaction": "hat auf dein Bild reagiert.",
|
||||
"notificationReopenedMedia": "hat dein Bild erneut geöffnet.",
|
||||
"notificationReactionToVideo": "hat mit {reaction} auf dein Video reagiert.",
|
||||
"notificationReactionToText": "hat mit {reaction} auf deine Nachricht reagiert.",
|
||||
"notificationReactionToImage": "hat mit {reaction} auf dein Bild reagiert.",
|
||||
"notificationResponse": "hat dir geantwortet.",
|
||||
"notificationTitleUnknownUser": "Jemand",
|
||||
"notificationCategoryMessageTitle": "Nachrichten",
|
||||
"notificationCategoryMessageDesc": "Nachrichten von anderen Benutzern."
|
||||
}
|
||||
|
|
@ -552,5 +552,22 @@
|
|||
"youLeftGroup": "You have left the group.",
|
||||
"makerLeftGroup": "{maker} has left the group.",
|
||||
"groupActionYou": "you",
|
||||
"groupActionYour": "your"
|
||||
"groupActionYour": "your",
|
||||
"notificationText": "sent a message.",
|
||||
"notificationTwonly": "sent a twonly.",
|
||||
"notificationVideo": "sent a video.",
|
||||
"notificationImage": "sent a image.",
|
||||
"notificationAddedToGroup": "has added you to \"{groupname}\"",
|
||||
"notificationContactRequest": "wants to connect with you.",
|
||||
"notificationAcceptRequest": "is now connected with you.",
|
||||
"notificationStoredMediaFile": "has stored your image.",
|
||||
"notificationReaction": "has reacted to your image.",
|
||||
"notificationReopenedMedia": "has reopened your image.",
|
||||
"notificationReactionToVideo": "has reacted with {reaction} to your video.",
|
||||
"notificationReactionToText": "has reacted with {reaction} to your message.",
|
||||
"notificationReactionToImage": "has reacted with {reaction} to your image.",
|
||||
"notificationResponse": "has responded.",
|
||||
"notificationTitleUnknownUser": "Someone",
|
||||
"notificationCategoryMessageTitle": "Messages",
|
||||
"notificationCategoryMessageDesc": "Messages from other users."
|
||||
}
|
||||
|
|
@ -2327,85 +2327,85 @@ abstract class AppLocalizations {
|
|||
/// No description provided for @youChangedGroupName.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Du hast den Gruppennamen zu „{newGroupName}“ geändert.'**
|
||||
/// **'You have changed the group name to \"{newGroupName}\".'**
|
||||
String youChangedGroupName(Object newGroupName);
|
||||
|
||||
/// No description provided for @makerChangedGroupName.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{maker} hat den Gruppennamen zu „{newGroupName}“ geändert.'**
|
||||
/// **'{maker} has changed the group name to \"{newGroupName}\".'**
|
||||
String makerChangedGroupName(Object maker, Object newGroupName);
|
||||
|
||||
/// No description provided for @youCreatedGroup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Du hast die Gruppe erstellt.'**
|
||||
/// **'You have created the group.'**
|
||||
String get youCreatedGroup;
|
||||
|
||||
/// No description provided for @makerCreatedGroup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{maker} hat die Gruppe erstellt.'**
|
||||
/// **'{maker} has created the group.'**
|
||||
String makerCreatedGroup(Object maker);
|
||||
|
||||
/// No description provided for @youRemovedMember.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Du hast {affected} aus der Gruppe entfernt.'**
|
||||
/// **'You have removed {affected} from the group.'**
|
||||
String youRemovedMember(Object affected);
|
||||
|
||||
/// No description provided for @makerRemovedMember.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{maker} hat {affected} aus der Gruppe entfernt.'**
|
||||
/// **'{maker} has removed {affected} from the group.'**
|
||||
String makerRemovedMember(Object affected, Object maker);
|
||||
|
||||
/// No description provided for @youAddedMember.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Du hast {affected} zur Gruppe hinzugefügt.'**
|
||||
/// **'You have added {affected} to the group.'**
|
||||
String youAddedMember(Object affected);
|
||||
|
||||
/// No description provided for @makerAddedMember.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{maker} hat {affected} zur Gruppe hinzugefügt.'**
|
||||
/// **'{maker} has added {affected} to the group.'**
|
||||
String makerAddedMember(Object affected, Object maker);
|
||||
|
||||
/// No description provided for @youMadeAdmin.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Du hast {affected} zum Administrator gemacht.'**
|
||||
/// **'You made {affected} an admin.'**
|
||||
String youMadeAdmin(Object affected);
|
||||
|
||||
/// No description provided for @makerMadeAdmin.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{maker} hat {affected} zum Administrator gemacht.'**
|
||||
/// **'{maker} made {affected} an admin.'**
|
||||
String makerMadeAdmin(Object affected, Object maker);
|
||||
|
||||
/// No description provided for @youRevokedAdminRights.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Du hast {affectedR} die Administratorrechte entzogen.'**
|
||||
/// **'You revoked {affectedR} admin rights.'**
|
||||
String youRevokedAdminRights(Object affectedR);
|
||||
|
||||
/// No description provided for @makerRevokedAdminRights.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{maker} hat {affectedR} die Administratorrechte entzogen.'**
|
||||
/// **'{maker} revoked {affectedR} admin rights.'**
|
||||
String makerRevokedAdminRights(Object affectedR, Object maker);
|
||||
|
||||
/// No description provided for @youLeftGroup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Du hast die Gruppe verlassen.'**
|
||||
/// **'You have left the group.'**
|
||||
String get youLeftGroup;
|
||||
|
||||
/// No description provided for @makerLeftGroup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{maker} hat die Gruppe verlassen.'**
|
||||
/// **'{maker} has left the group.'**
|
||||
String makerLeftGroup(Object maker);
|
||||
|
||||
/// No description provided for @groupActionYou.
|
||||
|
|
@ -2419,6 +2419,108 @@ abstract class AppLocalizations {
|
|||
/// In en, this message translates to:
|
||||
/// **'your'**
|
||||
String get groupActionYour;
|
||||
|
||||
/// No description provided for @notificationText.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'sent a message.'**
|
||||
String get notificationText;
|
||||
|
||||
/// No description provided for @notificationTwonly.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'sent a twonly.'**
|
||||
String get notificationTwonly;
|
||||
|
||||
/// No description provided for @notificationVideo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'sent a video.'**
|
||||
String get notificationVideo;
|
||||
|
||||
/// No description provided for @notificationImage.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'sent a image.'**
|
||||
String get notificationImage;
|
||||
|
||||
/// No description provided for @notificationAddedToGroup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'has added you to \"{groupname}\"'**
|
||||
String notificationAddedToGroup(Object groupname);
|
||||
|
||||
/// No description provided for @notificationContactRequest.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'wants to connect with you.'**
|
||||
String get notificationContactRequest;
|
||||
|
||||
/// No description provided for @notificationAcceptRequest.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'is now connected with you.'**
|
||||
String get notificationAcceptRequest;
|
||||
|
||||
/// No description provided for @notificationStoredMediaFile.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'has stored your image.'**
|
||||
String get notificationStoredMediaFile;
|
||||
|
||||
/// No description provided for @notificationReaction.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'has reacted to your image.'**
|
||||
String get notificationReaction;
|
||||
|
||||
/// No description provided for @notificationReopenedMedia.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'has reopened your image.'**
|
||||
String get notificationReopenedMedia;
|
||||
|
||||
/// No description provided for @notificationReactionToVideo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'has reacted with {reaction} to your video.'**
|
||||
String notificationReactionToVideo(Object reaction);
|
||||
|
||||
/// No description provided for @notificationReactionToText.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'has reacted with {reaction} to your message.'**
|
||||
String notificationReactionToText(Object reaction);
|
||||
|
||||
/// No description provided for @notificationReactionToImage.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'has reacted with {reaction} to your image.'**
|
||||
String notificationReactionToImage(Object reaction);
|
||||
|
||||
/// No description provided for @notificationResponse.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'has responded.'**
|
||||
String get notificationResponse;
|
||||
|
||||
/// No description provided for @notificationTitleUnknownUser.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Someone'**
|
||||
String get notificationTitleUnknownUser;
|
||||
|
||||
/// No description provided for @notificationCategoryMessageTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Messages'**
|
||||
String get notificationCategoryMessageTitle;
|
||||
|
||||
/// No description provided for @notificationCategoryMessageDesc.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Messages from other users.'**
|
||||
String get notificationCategoryMessageDesc;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
|
|
|||
|
|
@ -1070,10 +1070,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get twonlySafeRecoverDesc =>
|
||||
'If you have created a backup with twonly Backup, you can restore it here.';
|
||||
'Wenn du ein Backup mit twonly Backup erstellt hast, kannst du es hier wiederherstellen.';
|
||||
|
||||
@override
|
||||
String get twonlySafeRecoverBtn => 'Restore backup';
|
||||
String get twonlySafeRecoverBtn => 'Backup wiederherstellen';
|
||||
|
||||
@override
|
||||
String get inviteFriends => 'Freunde einladen';
|
||||
|
|
@ -1308,4 +1308,64 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get groupActionYour => 'deine';
|
||||
|
||||
@override
|
||||
String get notificationText => 'hat eine Nachricht gesendet.';
|
||||
|
||||
@override
|
||||
String get notificationTwonly => 'hat ein twonly gesendet.';
|
||||
|
||||
@override
|
||||
String get notificationVideo => 'hat ein Video gesendet.';
|
||||
|
||||
@override
|
||||
String get notificationImage => 'hat ein Bild gesendet.';
|
||||
|
||||
@override
|
||||
String notificationAddedToGroup(Object groupname) {
|
||||
return 'hat dich zu \"$groupname\" hinzugefügt.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get notificationContactRequest => 'möchte sich mit dir vernetzen.';
|
||||
|
||||
@override
|
||||
String get notificationAcceptRequest => 'ist jetzt mit dir vernetzt.';
|
||||
|
||||
@override
|
||||
String get notificationStoredMediaFile => 'hat dein Bild gespeichert.';
|
||||
|
||||
@override
|
||||
String get notificationReaction => 'hat auf dein Bild reagiert.';
|
||||
|
||||
@override
|
||||
String get notificationReopenedMedia => 'hat dein Bild erneut geöffnet.';
|
||||
|
||||
@override
|
||||
String notificationReactionToVideo(Object reaction) {
|
||||
return 'hat mit $reaction auf dein Video reagiert.';
|
||||
}
|
||||
|
||||
@override
|
||||
String notificationReactionToText(Object reaction) {
|
||||
return 'hat mit $reaction auf deine Nachricht reagiert.';
|
||||
}
|
||||
|
||||
@override
|
||||
String notificationReactionToImage(Object reaction) {
|
||||
return 'hat mit $reaction auf dein Bild reagiert.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get notificationResponse => 'hat dir geantwortet.';
|
||||
|
||||
@override
|
||||
String get notificationTitleUnknownUser => 'Jemand';
|
||||
|
||||
@override
|
||||
String get notificationCategoryMessageTitle => 'Nachrichten';
|
||||
|
||||
@override
|
||||
String get notificationCategoryMessageDesc =>
|
||||
'Nachrichten von anderen Benutzern.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1232,68 +1232,68 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String youChangedGroupName(Object newGroupName) {
|
||||
return 'Du hast den Gruppennamen zu „$newGroupName“ geändert.';
|
||||
return 'You have changed the group name to \"$newGroupName\".';
|
||||
}
|
||||
|
||||
@override
|
||||
String makerChangedGroupName(Object maker, Object newGroupName) {
|
||||
return '$maker hat den Gruppennamen zu „$newGroupName“ geändert.';
|
||||
return '$maker has changed the group name to \"$newGroupName\".';
|
||||
}
|
||||
|
||||
@override
|
||||
String get youCreatedGroup => 'Du hast die Gruppe erstellt.';
|
||||
String get youCreatedGroup => 'You have created the group.';
|
||||
|
||||
@override
|
||||
String makerCreatedGroup(Object maker) {
|
||||
return '$maker hat die Gruppe erstellt.';
|
||||
return '$maker has created the group.';
|
||||
}
|
||||
|
||||
@override
|
||||
String youRemovedMember(Object affected) {
|
||||
return 'Du hast $affected aus der Gruppe entfernt.';
|
||||
return 'You have removed $affected from the group.';
|
||||
}
|
||||
|
||||
@override
|
||||
String makerRemovedMember(Object affected, Object maker) {
|
||||
return '$maker hat $affected aus der Gruppe entfernt.';
|
||||
return '$maker has removed $affected from the group.';
|
||||
}
|
||||
|
||||
@override
|
||||
String youAddedMember(Object affected) {
|
||||
return 'Du hast $affected zur Gruppe hinzugefügt.';
|
||||
return 'You have added $affected to the group.';
|
||||
}
|
||||
|
||||
@override
|
||||
String makerAddedMember(Object affected, Object maker) {
|
||||
return '$maker hat $affected zur Gruppe hinzugefügt.';
|
||||
return '$maker has added $affected to the group.';
|
||||
}
|
||||
|
||||
@override
|
||||
String youMadeAdmin(Object affected) {
|
||||
return 'Du hast $affected zum Administrator gemacht.';
|
||||
return 'You made $affected an admin.';
|
||||
}
|
||||
|
||||
@override
|
||||
String makerMadeAdmin(Object affected, Object maker) {
|
||||
return '$maker hat $affected zum Administrator gemacht.';
|
||||
return '$maker made $affected an admin.';
|
||||
}
|
||||
|
||||
@override
|
||||
String youRevokedAdminRights(Object affectedR) {
|
||||
return 'Du hast $affectedR die Administratorrechte entzogen.';
|
||||
return 'You revoked $affectedR admin rights.';
|
||||
}
|
||||
|
||||
@override
|
||||
String makerRevokedAdminRights(Object affectedR, Object maker) {
|
||||
return '$maker hat $affectedR die Administratorrechte entzogen.';
|
||||
return '$maker revoked $affectedR admin rights.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get youLeftGroup => 'Du hast die Gruppe verlassen.';
|
||||
String get youLeftGroup => 'You have left the group.';
|
||||
|
||||
@override
|
||||
String makerLeftGroup(Object maker) {
|
||||
return '$maker hat die Gruppe verlassen.';
|
||||
return '$maker has left the group.';
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -1301,4 +1301,63 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get groupActionYour => 'your';
|
||||
|
||||
@override
|
||||
String get notificationText => 'sent a message.';
|
||||
|
||||
@override
|
||||
String get notificationTwonly => 'sent a twonly.';
|
||||
|
||||
@override
|
||||
String get notificationVideo => 'sent a video.';
|
||||
|
||||
@override
|
||||
String get notificationImage => 'sent a image.';
|
||||
|
||||
@override
|
||||
String notificationAddedToGroup(Object groupname) {
|
||||
return 'has added you to \"$groupname\"';
|
||||
}
|
||||
|
||||
@override
|
||||
String get notificationContactRequest => 'wants to connect with you.';
|
||||
|
||||
@override
|
||||
String get notificationAcceptRequest => 'is now connected with you.';
|
||||
|
||||
@override
|
||||
String get notificationStoredMediaFile => 'has stored your image.';
|
||||
|
||||
@override
|
||||
String get notificationReaction => 'has reacted to your image.';
|
||||
|
||||
@override
|
||||
String get notificationReopenedMedia => 'has reopened your image.';
|
||||
|
||||
@override
|
||||
String notificationReactionToVideo(Object reaction) {
|
||||
return 'has reacted with $reaction to your video.';
|
||||
}
|
||||
|
||||
@override
|
||||
String notificationReactionToText(Object reaction) {
|
||||
return 'has reacted with $reaction to your message.';
|
||||
}
|
||||
|
||||
@override
|
||||
String notificationReactionToImage(Object reaction) {
|
||||
return 'has reacted with $reaction to your image.';
|
||||
}
|
||||
|
||||
@override
|
||||
String get notificationResponse => 'has responded.';
|
||||
|
||||
@override
|
||||
String get notificationTitleUnknownUser => 'Someone';
|
||||
|
||||
@override
|
||||
String get notificationCategoryMessageTitle => 'Messages';
|
||||
|
||||
@override
|
||||
String get notificationCategoryMessageDesc => 'Messages from other users.';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class PushNotification extends $pb.GeneratedMessage {
|
|||
factory PushNotification({
|
||||
PushKind? kind,
|
||||
$core.String? messageId,
|
||||
$core.String? reactionContent,
|
||||
$core.String? additionalContent,
|
||||
}) {
|
||||
final $result = create();
|
||||
if (kind != null) {
|
||||
|
|
@ -123,8 +123,8 @@ class PushNotification extends $pb.GeneratedMessage {
|
|||
if (messageId != null) {
|
||||
$result.messageId = messageId;
|
||||
}
|
||||
if (reactionContent != null) {
|
||||
$result.reactionContent = reactionContent;
|
||||
if (additionalContent != null) {
|
||||
$result.additionalContent = additionalContent;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ class PushNotification extends $pb.GeneratedMessage {
|
|||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'PushNotification', createEmptyInstance: create)
|
||||
..e<PushKind>(1, _omitFieldNames ? '' : 'kind', $pb.PbFieldType.OE, defaultOrMaker: PushKind.reaction, valueOf: PushKind.valueOf, enumValues: PushKind.values)
|
||||
..aOS(2, _omitFieldNames ? '' : 'messageId', protoName: 'messageId')
|
||||
..aOS(3, _omitFieldNames ? '' : 'reactionContent', protoName: 'reactionContent')
|
||||
..aOS(3, _omitFieldNames ? '' : 'additionalContent', protoName: 'additionalContent')
|
||||
..hasRequiredFields = false
|
||||
;
|
||||
|
||||
|
|
@ -179,13 +179,13 @@ class PushNotification extends $pb.GeneratedMessage {
|
|||
void clearMessageId() => clearField(2);
|
||||
|
||||
@$pb.TagNumber(3)
|
||||
$core.String get reactionContent => $_getSZ(2);
|
||||
$core.String get additionalContent => $_getSZ(2);
|
||||
@$pb.TagNumber(3)
|
||||
set reactionContent($core.String v) { $_setString(2, v); }
|
||||
set additionalContent($core.String v) { $_setString(2, v); }
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasReactionContent() => $_has(2);
|
||||
$core.bool hasAdditionalContent() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearReactionContent() => clearField(3);
|
||||
void clearAdditionalContent() => clearField(3);
|
||||
}
|
||||
|
||||
class PushUsers extends $pb.GeneratedMessage {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class PushKind extends $pb.ProtobufEnum {
|
|||
static const PushKind reactionToVideo = PushKind._(11, _omitEnumNames ? '' : 'reactionToVideo');
|
||||
static const PushKind reactionToText = PushKind._(12, _omitEnumNames ? '' : 'reactionToText');
|
||||
static const PushKind reactionToImage = PushKind._(13, _omitEnumNames ? '' : 'reactionToImage');
|
||||
static const PushKind addedToGroup = PushKind._(14, _omitEnumNames ? '' : 'addedToGroup');
|
||||
|
||||
static const $core.List<PushKind> values = <PushKind> [
|
||||
reaction,
|
||||
|
|
@ -44,6 +45,7 @@ class PushKind extends $pb.ProtobufEnum {
|
|||
reactionToVideo,
|
||||
reactionToText,
|
||||
reactionToImage,
|
||||
addedToGroup,
|
||||
];
|
||||
|
||||
static final $core.Map<$core.int, PushKind> _byValue = $pb.ProtobufEnum.initByValue(values);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ const PushKind$json = {
|
|||
{'1': 'reactionToVideo', '2': 11},
|
||||
{'1': 'reactionToText', '2': 12},
|
||||
{'1': 'reactionToImage', '2': 13},
|
||||
{'1': 'addedToGroup', '2': 14},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ final $typed_data.Uint8List pushKindDescriptor = $convert.base64Decode(
|
|||
'VvEAMSCgoGdHdvbmx5EAQSCQoFaW1hZ2UQBRISCg5jb250YWN0UmVxdWVzdBAGEhEKDWFjY2Vw'
|
||||
'dFJlcXVlc3QQBxITCg9zdG9yZWRNZWRpYUZpbGUQCBIUChB0ZXN0Tm90aWZpY2F0aW9uEAkSEQ'
|
||||
'oNcmVvcGVuZWRNZWRpYRAKEhMKD3JlYWN0aW9uVG9WaWRlbxALEhIKDnJlYWN0aW9uVG9UZXh0'
|
||||
'EAwSEwoPcmVhY3Rpb25Ub0ltYWdlEA0=');
|
||||
'EAwSEwoPcmVhY3Rpb25Ub0ltYWdlEA0SEAoMYWRkZWRUb0dyb3VwEA4=');
|
||||
|
||||
@$core.Deprecated('Use encryptedPushNotificationDescriptor instead')
|
||||
const EncryptedPushNotification$json = {
|
||||
|
|
@ -65,19 +66,20 @@ const PushNotification$json = {
|
|||
'2': [
|
||||
{'1': 'kind', '3': 1, '4': 1, '5': 14, '6': '.PushKind', '10': 'kind'},
|
||||
{'1': 'messageId', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'messageId', '17': true},
|
||||
{'1': 'reactionContent', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'reactionContent', '17': true},
|
||||
{'1': 'additionalContent', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'additionalContent', '17': true},
|
||||
],
|
||||
'8': [
|
||||
{'1': '_messageId'},
|
||||
{'1': '_reactionContent'},
|
||||
{'1': '_additionalContent'},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `PushNotification`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List pushNotificationDescriptor = $convert.base64Decode(
|
||||
'ChBQdXNoTm90aWZpY2F0aW9uEh0KBGtpbmQYASABKA4yCS5QdXNoS2luZFIEa2luZBIhCgltZX'
|
||||
'NzYWdlSWQYAiABKAlIAFIJbWVzc2FnZUlkiAEBEi0KD3JlYWN0aW9uQ29udGVudBgDIAEoCUgB'
|
||||
'Ug9yZWFjdGlvbkNvbnRlbnSIAQFCDAoKX21lc3NhZ2VJZEISChBfcmVhY3Rpb25Db250ZW50');
|
||||
'NzYWdlSWQYAiABKAlIAFIJbWVzc2FnZUlkiAEBEjEKEWFkZGl0aW9uYWxDb250ZW50GAMgASgJ'
|
||||
'SAFSEWFkZGl0aW9uYWxDb250ZW50iAEBQgwKCl9tZXNzYWdlSWRCFAoSX2FkZGl0aW9uYWxDb2'
|
||||
'50ZW50');
|
||||
|
||||
@$core.Deprecated('Use pushUsersDescriptor instead')
|
||||
const PushUsers$json = {
|
||||
|
|
|
|||
|
|
@ -22,12 +22,13 @@ enum PushKind {
|
|||
reactionToVideo = 11;
|
||||
reactionToText = 12;
|
||||
reactionToImage = 13;
|
||||
addedToGroup = 14;
|
||||
};
|
||||
|
||||
message PushNotification {
|
||||
PushKind kind = 1;
|
||||
optional string messageId = 2;
|
||||
optional string reactionContent = 3;
|
||||
optional string additionalContent = 3;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ import 'package:cryptography_plus/cryptography_plus.dart';
|
|||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:twonly/src/constants/secure_storage_keys.dart';
|
||||
import 'package:twonly/src/localization/generated/app_localizations.dart';
|
||||
import 'package:twonly/src/localization/generated/app_localizations_de.dart';
|
||||
import 'package:twonly/src/localization/generated/app_localizations_en.dart';
|
||||
import 'package:twonly/src/model/protobuf/client/generated/push_notification.pb.dart';
|
||||
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
||||
import 'package:twonly/src/utils/log.dart';
|
||||
|
|
@ -148,10 +151,12 @@ Future<void> showLocalPushNotification(
|
|||
styleInformation = FilePathAndroidBitmap(avatarPath);
|
||||
}
|
||||
|
||||
final lang = getLocalizations();
|
||||
|
||||
final androidNotificationDetails = AndroidNotificationDetails(
|
||||
'0',
|
||||
'Messages',
|
||||
channelDescription: 'Messages from other users.',
|
||||
lang.notificationCategoryMessageTitle,
|
||||
channelDescription: lang.notificationCategoryMessageDesc,
|
||||
importance: Importance.max,
|
||||
priority: Priority.max,
|
||||
ticker: 'You got a new message.',
|
||||
|
|
@ -176,25 +181,29 @@ Future<void> showLocalPushNotification(
|
|||
Future<void> showLocalPushNotificationWithoutUserId(
|
||||
PushNotification pushNotification,
|
||||
) async {
|
||||
String? title;
|
||||
String? body;
|
||||
|
||||
body = getPushNotificationTextWithoutUserId(pushNotification.kind);
|
||||
body = getPushNotificationText(pushNotification);
|
||||
|
||||
final lang = getLocalizations();
|
||||
|
||||
final title = lang.notificationTitleUnknownUser;
|
||||
|
||||
if (body == '') {
|
||||
Log.error('No push notification type defined!');
|
||||
}
|
||||
|
||||
const androidNotificationDetails = AndroidNotificationDetails(
|
||||
final androidNotificationDetails = AndroidNotificationDetails(
|
||||
'0',
|
||||
'Messages',
|
||||
channelDescription: 'Messages from other users.',
|
||||
lang.notificationCategoryMessageTitle,
|
||||
channelDescription: lang.notificationCategoryMessageDesc,
|
||||
importance: Importance.max,
|
||||
priority: Priority.max,
|
||||
ticker: 'You got a new message.',
|
||||
);
|
||||
|
||||
const darwinNotificationDetails = DarwinNotificationDetails();
|
||||
const notificationDetails = NotificationDetails(
|
||||
final notificationDetails = NotificationDetails(
|
||||
android: androidNotificationDetails,
|
||||
iOS: darwinNotificationDetails,
|
||||
);
|
||||
|
|
@ -219,104 +228,35 @@ Future<String?> getAvatarIcon(int contactId) async {
|
|||
return null;
|
||||
}
|
||||
|
||||
String getPushNotificationTextWithoutUserId(PushKind pushKind) {
|
||||
Map<String, String> pushNotificationText;
|
||||
|
||||
AppLocalizations getLocalizations() {
|
||||
final systemLanguage = Platform.localeName;
|
||||
|
||||
if (systemLanguage.contains('de')) {
|
||||
pushNotificationText = {
|
||||
PushKind.text.name: 'Du hast eine neue Nachricht erhalten.',
|
||||
PushKind.twonly.name: 'Du hast ein neues twonly erhalten.',
|
||||
PushKind.video.name: 'Du hast ein neues Video erhalten.',
|
||||
PushKind.image.name: 'Du hast ein neues Bild erhalten.',
|
||||
PushKind.contactRequest.name:
|
||||
'Du hast eine neue 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.',
|
||||
PushKind.reopenedMedia.name: 'Dein Bild wurde erneut geöffnet.',
|
||||
PushKind.reactionToVideo.name:
|
||||
'Du hast eine Reaktion auf dein Video erhalten.',
|
||||
PushKind.reactionToText.name:
|
||||
'Du hast eine Reaktion auf deinen Text erhalten.',
|
||||
PushKind.reactionToImage.name:
|
||||
'Du hast eine Reaktion auf dein Bild erhalten.',
|
||||
PushKind.response.name: 'Du hast eine Antwort erhalten.',
|
||||
};
|
||||
} else {
|
||||
pushNotificationText = {
|
||||
PushKind.text.name: 'You have received a new message.',
|
||||
PushKind.twonly.name: 'You have received a new twonly.',
|
||||
PushKind.video.name: 'You have received a new video.',
|
||||
PushKind.image.name: 'You have received a new image.',
|
||||
PushKind.contactRequest.name: 'You have received a new contact request.',
|
||||
PushKind.acceptRequest.name: 'Your contact request has been accepted.',
|
||||
PushKind.storedMediaFile.name: 'Your image has been saved.',
|
||||
PushKind.reaction.name: 'You have received a reaction to your image.',
|
||||
PushKind.reopenedMedia.name: 'Your image has been reopened.',
|
||||
PushKind.reactionToVideo.name:
|
||||
'You have received a reaction to your video.',
|
||||
PushKind.reactionToText.name:
|
||||
'You have received a reaction to your text.',
|
||||
PushKind.reactionToImage.name:
|
||||
'You have received a reaction to your image.',
|
||||
PushKind.response.name: 'You have received a response.',
|
||||
};
|
||||
}
|
||||
return pushNotificationText[pushKind.name] ?? '';
|
||||
if (systemLanguage.contains('de')) return AppLocalizationsDe();
|
||||
return AppLocalizationsEn();
|
||||
}
|
||||
|
||||
String getPushNotificationText(PushNotification pushNotification) {
|
||||
final systemLanguage = Platform.localeName;
|
||||
final lang = getLocalizations();
|
||||
|
||||
Map<String, String> pushNotificationText;
|
||||
final pushNotificationText = {
|
||||
PushKind.text.name: lang.notificationText,
|
||||
PushKind.twonly.name: lang.notificationTwonly,
|
||||
PushKind.video.name: lang.notificationVideo,
|
||||
PushKind.image.name: lang.notificationImage,
|
||||
PushKind.contactRequest.name: lang.notificationContactRequest,
|
||||
PushKind.acceptRequest.name: lang.notificationAcceptRequest,
|
||||
PushKind.storedMediaFile.name: lang.notificationStoredMediaFile,
|
||||
PushKind.reaction.name: lang.notificationReaction,
|
||||
PushKind.reopenedMedia.name: lang.notificationReopenedMedia,
|
||||
PushKind.reactionToVideo.name:
|
||||
lang.notificationReactionToVideo(pushNotification.additionalContent),
|
||||
PushKind.reactionToText.name:
|
||||
lang.notificationReactionToText(pushNotification.additionalContent),
|
||||
PushKind.reactionToImage.name:
|
||||
lang.notificationReactionToImage(pushNotification.additionalContent),
|
||||
PushKind.response.name: lang.notificationResponse,
|
||||
PushKind.addedToGroup.name:
|
||||
lang.notificationAddedToGroup(pushNotification.additionalContent),
|
||||
};
|
||||
|
||||
if (systemLanguage.contains('de')) {
|
||||
pushNotificationText = {
|
||||
PushKind.text.name: 'hat dir eine Nachricht gesendet.',
|
||||
PushKind.twonly.name: 'hat dir ein twonly gesendet.',
|
||||
PushKind.video.name: 'hat dir ein Video gesendet.',
|
||||
PushKind.image.name: 'hat dir ein Bild gesendet.',
|
||||
PushKind.contactRequest.name: 'möchte sich mit dir vernetzen.',
|
||||
PushKind.acceptRequest.name: 'ist jetzt mit dir vernetzt.',
|
||||
PushKind.storedMediaFile.name: 'hat dein Bild gespeichert.',
|
||||
PushKind.reaction.name: 'hat auf dein Bild reagiert.',
|
||||
PushKind.reopenedMedia.name: 'hat dein Bild erneut geöffnet.',
|
||||
PushKind.reactionToVideo.name:
|
||||
'hat mit {{reaction}} auf dein Video reagiert.',
|
||||
PushKind.reactionToText.name:
|
||||
'hat mit {{reaction}} auf deine Nachricht reagiert.',
|
||||
PushKind.reactionToImage.name:
|
||||
'hat mit {{reaction}} auf dein Bild reagiert.',
|
||||
PushKind.response.name: 'hat dir geantwortet.',
|
||||
};
|
||||
} else {
|
||||
pushNotificationText = {
|
||||
PushKind.text.name: 'has sent you a message.',
|
||||
PushKind.twonly.name: 'has sent you a twonly.',
|
||||
PushKind.video.name: 'has sent you a video.',
|
||||
PushKind.image.name: 'has sent you an image.',
|
||||
PushKind.contactRequest.name: 'wants to connect with you.',
|
||||
PushKind.acceptRequest.name: 'is now connected with you.',
|
||||
PushKind.storedMediaFile.name: 'has stored your image.',
|
||||
PushKind.reaction.name: 'has reacted to your image.',
|
||||
PushKind.reopenedMedia.name: 'has reopened your image.',
|
||||
PushKind.reactionToVideo.name:
|
||||
'has reacted with {{reaction}} to your video.',
|
||||
PushKind.reactionToText.name:
|
||||
'has reacted with {{reaction}} to your message.',
|
||||
PushKind.reactionToImage.name:
|
||||
'has reacted with {{reaction}} to your image.',
|
||||
PushKind.response.name: 'has responded.',
|
||||
};
|
||||
}
|
||||
var contentText = pushNotificationText[pushNotification.kind.name] ?? '';
|
||||
if (pushNotification.hasReactionContent()) {
|
||||
contentText = contentText.replaceAll(
|
||||
'{{reaction}}',
|
||||
pushNotification.reactionContent,
|
||||
);
|
||||
}
|
||||
return contentText;
|
||||
return pushNotificationText[pushNotification.kind.name] ?? '';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ Future<PushNotification?> getPushNotificationFromEncryptedContent(
|
|||
EncryptedContent content,
|
||||
) async {
|
||||
PushKind? kind;
|
||||
String? reactionContent;
|
||||
String? additionalContent;
|
||||
|
||||
if (content.hasReaction()) {
|
||||
if (content.reaction.remove) return null;
|
||||
|
|
@ -209,7 +209,9 @@ Future<PushNotification?> getPushNotificationFromEncryptedContent(
|
|||
final msg = await twonlyDB.messagesDao
|
||||
.getMessageById(content.reaction.targetMessageId)
|
||||
.getSingleOrNull();
|
||||
if (msg == null) return null;
|
||||
if (msg == null || msg.senderId == null || msg.senderId != toUserId) {
|
||||
return null;
|
||||
}
|
||||
if (msg.content != null) {
|
||||
kind = PushKind.reactionToText;
|
||||
} else if (msg.mediaId != null) {
|
||||
|
|
@ -224,7 +226,7 @@ Future<PushNotification?> getPushNotificationFromEncryptedContent(
|
|||
kind = PushKind.reaction;
|
||||
}
|
||||
}
|
||||
reactionContent = content.reaction.emoji;
|
||||
additionalContent = content.reaction.emoji;
|
||||
}
|
||||
|
||||
if (content.hasTextMessage()) {
|
||||
|
|
@ -270,11 +272,17 @@ Future<PushNotification?> getPushNotificationFromEncryptedContent(
|
|||
}
|
||||
}
|
||||
|
||||
if (content.hasGroupCreate()) {
|
||||
kind = PushKind.addedToGroup;
|
||||
final group = await twonlyDB.groupsDao.getGroup(content.groupId);
|
||||
additionalContent = group!.groupName;
|
||||
}
|
||||
|
||||
if (kind == null) return null;
|
||||
|
||||
final pushNotification = PushNotification()..kind = kind;
|
||||
if (reactionContent != null) {
|
||||
pushNotification.reactionContent = reactionContent;
|
||||
if (additionalContent != null) {
|
||||
pushNotification.additionalContent = additionalContent;
|
||||
}
|
||||
if (messageId != null) {
|
||||
pushNotification.messageId = messageId;
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
selectedGroupIds.add(widget.sendToGroup!.groupId);
|
||||
}
|
||||
|
||||
if (widget.mediaFileService.mediaFile.type == MediaType.video ||
|
||||
if (widget.mediaFileService.mediaFile.type == MediaType.image ||
|
||||
widget.mediaFileService.mediaFile.type == MediaType.gif) {
|
||||
if (widget.imageBytesFuture != null) {
|
||||
loadImage(widget.imageBytesFuture!);
|
||||
|
|
|
|||
|
|
@ -77,9 +77,12 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
late StreamSubscription<Group?> userSub;
|
||||
late StreamSubscription<List<Message>> messageSub;
|
||||
late StreamSubscription<List<GroupHistory>>? groupActionsSub;
|
||||
late StreamSubscription<List<Contact>>? contactSub;
|
||||
late StreamSubscription<Future<List<(Message, Contact)>>>?
|
||||
lastOpenedMessageByContactSub;
|
||||
|
||||
Map<int, Contact> userIdToContact = {};
|
||||
|
||||
List<ChatItem> messages = [];
|
||||
List<Message> allMessages = [];
|
||||
List<(Message, Contact)> lastOpenedMessageByContact = [];
|
||||
|
|
@ -110,6 +113,7 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
void dispose() {
|
||||
userSub.cancel();
|
||||
messageSub.cancel();
|
||||
contactSub?.cancel();
|
||||
groupActionsSub?.cancel();
|
||||
lastOpenedMessageByContactSub?.cancel();
|
||||
tutorial?.cancel();
|
||||
|
|
@ -143,6 +147,13 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
groupActions = update;
|
||||
await setMessages(allMessages, lastOpenedMessageByContact, update);
|
||||
});
|
||||
|
||||
final contactsStream = twonlyDB.contactsDao.watchAllContacts();
|
||||
contactSub = contactsStream.listen((contacts) {
|
||||
for (final contact in contacts) {
|
||||
userIdToContact[contact.userId] = contact;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final msgStream = twonlyDB.messagesDao.watchByGroupId(group.groupId);
|
||||
|
|
@ -408,6 +419,7 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
: null,
|
||||
group: group,
|
||||
galleryItems: galleryItems,
|
||||
userIdToContact: userIdToContact,
|
||||
scrollToMessage: scrollToMessage,
|
||||
onResponseTriggered: () {
|
||||
setState(() {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import 'package:twonly/src/views/chats/chat_messages_components/message_actions.
|
|||
import 'package:twonly/src/views/chats/chat_messages_components/message_context_menu.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages_components/response_container.dart';
|
||||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||
import 'package:twonly/src/views/contact/contact.view.dart';
|
||||
|
||||
class ChatListEntry extends StatefulWidget {
|
||||
const ChatListEntry({
|
||||
|
|
@ -24,6 +25,7 @@ class ChatListEntry extends StatefulWidget {
|
|||
this.onResponseTriggered,
|
||||
this.prevMessage,
|
||||
this.nextMessage,
|
||||
this.userIdToContact,
|
||||
this.hideReactions = false,
|
||||
super.key,
|
||||
});
|
||||
|
|
@ -31,6 +33,7 @@ class ChatListEntry extends StatefulWidget {
|
|||
final Message? nextMessage;
|
||||
final Message message;
|
||||
final Group group;
|
||||
final Map<int, Contact>? userIdToContact;
|
||||
final bool hideReactions;
|
||||
final List<MemoryItem> galleryItems;
|
||||
final void Function(String)? scrollToMessage;
|
||||
|
|
@ -108,6 +111,8 @@ class _ChatListEntryState extends State<ChatListEntry> {
|
|||
ChatTextEntry(
|
||||
message: widget.message,
|
||||
nextMessage: widget.nextMessage,
|
||||
prevMessage: widget.prevMessage,
|
||||
userIdToContact: widget.userIdToContact,
|
||||
borderRadius: borderRadius,
|
||||
minWidth: reactionsForWidth * 43,
|
||||
)
|
||||
|
|
@ -124,6 +129,8 @@ class _ChatListEntryState extends State<ChatListEntry> {
|
|||
? ChatTextEntry(
|
||||
message: widget.message,
|
||||
nextMessage: widget.nextMessage,
|
||||
prevMessage: widget.prevMessage,
|
||||
userIdToContact: widget.userIdToContact,
|
||||
borderRadius: borderRadius,
|
||||
minWidth: reactionsForWidth * 43,
|
||||
)
|
||||
|
|
@ -182,9 +189,20 @@ class _ChatListEntryState extends State<ChatListEntry> {
|
|||
if (!right && !widget.group.isDirectChat)
|
||||
hideContactAvatar
|
||||
? const SizedBox(width: 24)
|
||||
: AvatarIcon(
|
||||
contactId: widget.message.senderId,
|
||||
fontSize: 12,
|
||||
: GestureDetector(
|
||||
onTap: () async {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
ContactView(widget.message.senderId!),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: AvatarIcon(
|
||||
contactId: widget.message.senderId,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
child,
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:intl/intl.dart' hide TextDirection;
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
import 'package:twonly/src/database/tables/messages.table.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
|
@ -12,13 +13,17 @@ class ChatTextEntry extends StatelessWidget {
|
|||
const ChatTextEntry({
|
||||
required this.message,
|
||||
required this.nextMessage,
|
||||
required this.prevMessage,
|
||||
required this.borderRadius,
|
||||
required this.userIdToContact,
|
||||
required this.minWidth,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final Message message;
|
||||
final Message? nextMessage;
|
||||
final Message? prevMessage;
|
||||
final Map<int, Contact>? userIdToContact;
|
||||
final BorderRadius borderRadius;
|
||||
final double minWidth;
|
||||
|
||||
|
|
@ -41,6 +46,17 @@ class ChatTextEntry extends StatelessWidget {
|
|||
}
|
||||
|
||||
var displayTime = !combineTextMessageWithNext(message, nextMessage);
|
||||
var displayUserName = '';
|
||||
if (message.senderId != null &&
|
||||
prevMessage != null &&
|
||||
userIdToContact != null) {
|
||||
if (!combineTextMessageWithNext(prevMessage!, message)) {
|
||||
if (userIdToContact![message.senderId] != null) {
|
||||
displayUserName =
|
||||
getContactDisplayName(userIdToContact![message.senderId]!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var spacerWidth = minWidth - measureTextWidth(text) - 53;
|
||||
if (spacerWidth < 0) spacerWidth = 0;
|
||||
|
|
@ -75,57 +91,71 @@ class ChatTextEntry extends StatelessWidget {
|
|||
color: color,
|
||||
borderRadius: borderRadius,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (expanded)
|
||||
Expanded(
|
||||
child: BetterText(text: text, textColor: textColor),
|
||||
)
|
||||
else ...[
|
||||
BetterText(text: text, textColor: textColor),
|
||||
SizedBox(
|
||||
width: spacerWidth,
|
||||
),
|
||||
],
|
||||
if (displayTime || message.modifiedAt != null)
|
||||
Align(
|
||||
alignment: AlignmentGeometry.centerRight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: Row(
|
||||
children: [
|
||||
if (message.modifiedAt != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 5),
|
||||
child: SizedBox(
|
||||
height: 10,
|
||||
child: FaIcon(
|
||||
FontAwesomeIcons.pencil,
|
||||
color: Colors.white.withAlpha(150),
|
||||
size: 10,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
friendlyTime(
|
||||
context,
|
||||
(message.modifiedAt != null)
|
||||
? message.modifiedAt!
|
||||
: message.createdAt,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: Colors.white.withAlpha(150),
|
||||
decoration: TextDecoration.none,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (displayUserName != '')
|
||||
Text(
|
||||
displayUserName,
|
||||
textAlign: TextAlign.left,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (expanded)
|
||||
Expanded(
|
||||
child: BetterText(text: text, textColor: textColor),
|
||||
)
|
||||
else ...[
|
||||
BetterText(text: text, textColor: textColor),
|
||||
SizedBox(
|
||||
width: spacerWidth,
|
||||
),
|
||||
],
|
||||
if (displayTime || message.modifiedAt != null)
|
||||
Align(
|
||||
alignment: AlignmentGeometry.centerRight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: Row(
|
||||
children: [
|
||||
if (message.modifiedAt != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 5),
|
||||
child: SizedBox(
|
||||
height: 10,
|
||||
child: FaIcon(
|
||||
FontAwesomeIcons.pencil,
|
||||
color: Colors.white.withAlpha(150),
|
||||
size: 10,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
friendlyTime(
|
||||
context,
|
||||
(message.modifiedAt != null)
|
||||
? message.modifiedAt!
|
||||
: message.createdAt,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: Colors.white.withAlpha(150),
|
||||
decoration: TextDecoration.none,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -80,9 +80,9 @@ class _ResponseContainerState extends State<ResponseContainer> {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
key: _preview,
|
||||
padding: const EdgeInsets.only(top: 4, right: 4, left: 4),
|
||||
child: Container(
|
||||
key: _preview,
|
||||
width: minWidth,
|
||||
decoration: BoxDecoration(
|
||||
color: context.color.surface.withAlpha(150),
|
||||
|
|
|
|||
Loading…
Reference in a new issue