ios: update reactions api (#2451)

This commit is contained in:
Evgeny Poberezkin
2023-05-17 10:31:27 +02:00
committed by GitHub
parent 922e95756a
commit 63cb7a75b3
4 changed files with 39 additions and 33 deletions

View File

@@ -345,9 +345,9 @@ func apiUpdateChatItem(type: ChatType, id: Int64, itemId: Int64, msg: MsgContent
throw r
}
func apiChatItemReaction(type: ChatType, id: Int64, itemId: Int64, reaction: MsgReaction, add: Bool) async throws -> ChatItem {
let r = await chatSendCmd(.apiChatItemReaction(type: type, id: id, itemId: itemId, reaction: reaction, add: add), bgDelay: msgDelay)
if case let .chatItemReaction(_, reaction, _) = r { return reaction.chatReaction.chatItem }
func apiChatItemReaction(type: ChatType, id: Int64, itemId: Int64, add: Bool, reaction: MsgReaction) async throws -> ChatItem {
let r = await chatSendCmd(.apiChatItemReaction(type: type, id: id, itemId: itemId, add: add, reaction: reaction), bgDelay: msgDelay)
if case let .chatItemReaction(_, _, reaction) = r { return reaction.chatReaction.chatItem }
throw r
}
@@ -1285,7 +1285,7 @@ func processReceivedMsg(_ res: ChatResponse) async {
}
case let .chatItemUpdated(user, aChatItem):
chatItemSimpleUpdate(user, aChatItem)
case let .chatItemReaction(user, r, _):
case let .chatItemReaction(user, _, r):
if active(user) {
m.updateChatItem(r.chatInfo, r.chatReaction.chatItem)
}

View File

@@ -526,7 +526,7 @@ struct ChatView: View {
if chat.chatInfo.featureEnabled(.reactions) && (ci.allowAddReaction || r.userReacted) {
v.onTapGesture {
setReaction(r.reaction, add: !r.userReacted)
setReaction(add: !r.userReacted, reaction: r.reaction)
}
} else {
v
@@ -606,27 +606,27 @@ struct ChatView: View {
let rs = MsgReaction.values.compactMap { r in
ci.reactions.contains(where: { $0.userReacted && $0.reaction == r })
? nil
: UIAction(title: r.text) { _ in setReaction(r, add: true) }
: UIAction(title: r.text) { _ in setReaction(add: true, reaction: r) }
}
if rs.count > 0 {
return UIMenu(
title: NSLocalizedString("React...", comment: "chat item menu"),
image: UIImage(systemName: "hand.thumbsup"),
image: UIImage(systemName: "face.smiling"),
children: rs
)
}
return nil
}
private func setReaction(_ r: MsgReaction, add: Bool) {
private func setReaction(add: Bool, reaction: MsgReaction) {
Task {
do {
let chatItem = try await apiChatItemReaction(
type: chat.chatInfo.chatType,
id: chat.chatInfo.apiId,
itemId: ci.id,
reaction: r,
add: add
add: add,
reaction: reaction
)
await MainActor.run {
ChatModel.shared.updateChatItem(chat.chatInfo, chatItem)

View File

@@ -41,7 +41,7 @@ public enum ChatCommand {
case apiUpdateChatItem(type: ChatType, id: Int64, itemId: Int64, msg: MsgContent, live: Bool)
case apiDeleteChatItem(type: ChatType, id: Int64, itemId: Int64, mode: CIDeleteMode)
case apiDeleteMemberChatItem(groupId: Int64, groupMemberId: Int64, itemId: Int64)
case apiChatItemReaction(type: ChatType, id: Int64, itemId: Int64, reaction: MsgReaction, add: Bool)
case apiChatItemReaction(type: ChatType, id: Int64, itemId: Int64, add: Bool, reaction: MsgReaction)
case apiGetNtfToken
case apiRegisterToken(token: DeviceToken, notificationMode: NotificationsMode)
case apiVerifyToken(token: DeviceToken, nonce: String, code: String)
@@ -149,7 +149,7 @@ public enum ChatCommand {
case let .apiUpdateChatItem(type, id, itemId, mc, live): return "/_update item \(ref(type, id)) \(itemId) live=\(onOff(live)) \(mc.cmdString)"
case let .apiDeleteChatItem(type, id, itemId, mode): return "/_delete item \(ref(type, id)) \(itemId) \(mode.rawValue)"
case let .apiDeleteMemberChatItem(groupId, groupMemberId, itemId): return "/_delete member item #\(groupId) \(groupMemberId) \(itemId)"
case let .apiChatItemReaction(type, id, itemId, reaction, add): return "/_reaction \(ref(type, id)) \(itemId) \(reaction.cmdString) \(onOff(add))"
case let .apiChatItemReaction(type, id, itemId, add, reaction): return "/_reaction \(ref(type, id)) \(itemId) \(onOff(add)) \(encodeJSON(reaction))"
case .apiGetNtfToken: return "/_ntf get "
case let .apiRegisterToken(token, notificationMode): return "/_ntf register \(token.cmdString) \(notificationMode.rawValue)"
case let .apiVerifyToken(token, nonce, code): return "/_ntf verify \(token.cmdString) \(nonce) \(code)"
@@ -433,7 +433,7 @@ public enum ChatResponse: Decodable, Error {
case newChatItem(user: User, chatItem: AChatItem)
case chatItemStatusUpdated(user: User, chatItem: AChatItem)
case chatItemUpdated(user: User, chatItem: AChatItem)
case chatItemReaction(user: User, reaction: ACIReaction, added: Bool)
case chatItemReaction(user: User, added: Bool, reaction: ACIReaction)
case chatItemDeleted(user: User, deletedChatItem: AChatItem, toChatItem: AChatItem?, byUser: Bool)
case contactsList(user: User, contacts: [Contact])
// group events
@@ -668,7 +668,7 @@ public enum ChatResponse: Decodable, Error {
case let .newChatItem(u, chatItem): return withUser(u, String(describing: chatItem))
case let .chatItemStatusUpdated(u, chatItem): return withUser(u, String(describing: chatItem))
case let .chatItemUpdated(u, chatItem): return withUser(u, String(describing: chatItem))
case let .chatItemReaction(u, reaction, added): return withUser(u, "added: \(added)\n\(String(describing: reaction))")
case let .chatItemReaction(u, added, reaction): return withUser(u, "added: \(added)\n\(String(describing: reaction))")
case let .chatItemDeleted(u, deletedChatItem, toChatItem, byUser): return withUser(u, "deletedChatItem:\n\(String(describing: deletedChatItem))\ntoChatItem:\n\(String(describing: toChatItem))\nbyUser: \(byUser)")
case let .contactsList(u, contacts): return withUser(u, String(describing: contacts))
case let .groupCreated(u, groupInfo): return withUser(u, String(describing: groupInfo))

View File

@@ -561,7 +561,7 @@ public enum ChatFeature: String, Decodable, Feature {
switch self {
case .timedMessages: return "stopwatch"
case .fullDelete: return "trash.slash"
case .reactions: return "hand.thumbsup"
case .reactions: return "face.smiling"
case .voice: return "mic"
case .calls: return "phone"
}
@@ -571,7 +571,7 @@ public enum ChatFeature: String, Decodable, Feature {
switch self {
case .timedMessages: return "stopwatch.fill"
case .fullDelete: return "trash.slash.fill"
case .reactions: return "hand.thumbsup.fill"
case .reactions: return "face.smiling.fill"
case .voice: return "mic.fill"
case .calls: return "phone.fill"
}
@@ -696,7 +696,7 @@ public enum GroupFeature: String, Decodable, Feature {
case .timedMessages: return "stopwatch"
case .directMessages: return "arrow.left.and.right.circle"
case .fullDelete: return "trash.slash"
case .reactions: return "hand.thumbsup"
case .reactions: return "face.smiling"
case .voice: return "mic"
}
}
@@ -706,7 +706,7 @@ public enum GroupFeature: String, Decodable, Feature {
case .timedMessages: return "stopwatch.fill"
case .directMessages: return "arrow.left.and.right.circle.fill"
case .fullDelete: return "trash.slash.fill"
case .reactions: return "hand.thumbsup.fill"
case .reactions: return "face.smiling.fill"
case .voice: return "mic.fill"
}
}
@@ -2469,25 +2469,17 @@ public struct CIReactionCount: Decodable {
}
public enum MsgReaction: Hashable {
case emoji(MREmojiChar)
case unknown
case emoji(emoji: MREmojiChar)
case unknown(type: String)
public var text: String {
switch self {
case let .emoji(emoji): return emoji.rawValue
case .unknown: return ""
case .unknown: return "?"
}
}
public var cmdString: String {
switch self {
case let .emoji(emoji): return emoji.cmdString
case .unknown: return ""
}
}
public static var values: [MsgReaction] =
MREmojiChar.allCases.map { .emoji($0) }
public static var values: [MsgReaction] = MREmojiChar.allCases.map { .emoji(emoji: $0) }
enum CodingKeys: String, CodingKey {
case type
@@ -2527,12 +2519,26 @@ extension MsgReaction: Decodable {
switch type {
case "emoji":
let emoji = try container.decode(MREmojiChar.self, forKey: CodingKeys.emoji)
self = .emoji(emoji)
self = .emoji(emoji: emoji)
default:
self = .unknown
self = .unknown(type: type)
}
} catch {
self = .unknown
self = .unknown(type: "")
}
}
}
extension MsgReaction: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .emoji(emoji):
try container.encode("emoji", forKey: .type)
try container.encode(emoji, forKey: .emoji)
// TODO use original JSON and type
case let .unknown(type):
try container.encode(type, forKey: .type)
}
}
}