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