mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-27 22:34:51 +00:00
ui: fix report archiving (#6239)
* kotlin: fix report archivation * ios wip * surrogate reports scope * refactor
This commit is contained in:
@@ -574,6 +574,8 @@ enum ChatCommand: ChatCmdProtocol {
|
||||
} else {
|
||||
"(_support)"
|
||||
}
|
||||
case .reports:
|
||||
"(reports, prohibited)" // can't use surrogate Reports scope
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -667,20 +667,24 @@ final class ChatModel: ObservableObject {
|
||||
|
||||
func getCIItemsModel(_ cInfo: ChatInfo, _ ci: ChatItem) -> ItemsModel? {
|
||||
let cInfoScope = cInfo.groupChatScope()
|
||||
if let cInfoScope = cInfoScope {
|
||||
switch cInfoScope {
|
||||
case .memberSupport:
|
||||
switch secondaryIM?.secondaryIMFilter {
|
||||
case .none:
|
||||
return nil
|
||||
case let .groupChatScopeContext(groupScopeInfo):
|
||||
return (cInfo.id == chatId && sameChatScope(cInfoScope, groupScopeInfo.toChatScope())) ? secondaryIM : nil
|
||||
case let .msgContentTagContext(contentTag):
|
||||
return (cInfo.id == chatId && ci.isReport && contentTag == .report) ? secondaryIM : nil
|
||||
}
|
||||
return if let cInfoScope = cInfoScope {
|
||||
switch (cInfoScope, secondaryIM?.secondaryIMFilter) {
|
||||
case let (.memberSupport, .some(.groupChatScopeContext(groupScopeInfo))):
|
||||
// Chat with member or Chat with admins opened (secondaryIM has .groupChatScopeContext filter), cInfo has matching scope
|
||||
(cInfo.id == chatId && sameChatScope(cInfoScope, groupScopeInfo.toChatScope())) ? secondaryIM : nil
|
||||
|
||||
case let (.memberSupport, .some(.msgContentTagContext(contentTag))):
|
||||
// Reports view opened (secondaryIM has .msgContentTagContext(.report) filter), we process event (cInfo has proper .memberSupport scope)
|
||||
(cInfo.id == chatId && ci.isReport && contentTag == .report) ? secondaryIM : nil
|
||||
|
||||
case let (.reports, .some(.msgContentTagContext(contentTag))):
|
||||
// Reports view opened (secondaryIM has .msgContentTagContext(.report) filter), we process user action (cInfo has surrogate .reports scope)
|
||||
(cInfo.id == chatId && ci.isReport && contentTag == .report) ? secondaryIM : nil
|
||||
default:
|
||||
nil
|
||||
}
|
||||
} else {
|
||||
return cInfo.id == chatId ? im : nil
|
||||
cInfo.id == chatId ? im : nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -234,13 +234,13 @@ struct ChatView: View {
|
||||
.confirmationDialog(selectedChatItems?.count == 1 ? "Archive report?" : "Archive \((selectedChatItems?.count ?? 0)) reports?", isPresented: $showArchiveSelectedReports, titleVisibility: .visible) {
|
||||
Button("For me", role: .destructive) {
|
||||
if let selected = selectedChatItems {
|
||||
archiveReports(chat.chatInfo, selected.sorted(), false, deletedSelectedMessages)
|
||||
archiveReports(chat, selected.sorted(), false, deletedSelectedMessages)
|
||||
}
|
||||
}
|
||||
if case let ChatInfo.group(groupInfo, _) = chat.chatInfo, groupInfo.membership.memberActive {
|
||||
Button("For all moderators", role: .destructive) {
|
||||
if let selected = selectedChatItems {
|
||||
archiveReports(chat.chatInfo, selected.sorted(), true, deletedSelectedMessages)
|
||||
archiveReports(chat, selected.sorted(), true, deletedSelectedMessages)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -598,6 +598,8 @@ struct ChatView: View {
|
||||
} else {
|
||||
textChatToolbar("Chat with admins")
|
||||
}
|
||||
case .reports:
|
||||
textChatToolbar("Member reports")
|
||||
}
|
||||
case let .msgContentTagContext(contentTag):
|
||||
switch contentTag {
|
||||
@@ -1913,14 +1915,14 @@ struct ChatView: View {
|
||||
.confirmationDialog(archivingReports?.count == 1 ? "Archive report?" : "Archive \(archivingReports?.count ?? 0) reports?", isPresented: $showArchivingReports, titleVisibility: .visible) {
|
||||
Button("For me", role: .destructive) {
|
||||
if let reports = self.archivingReports {
|
||||
archiveReports(chat.chatInfo, reports.sorted(), false)
|
||||
archiveReports(chat, reports.sorted(), false)
|
||||
self.archivingReports = []
|
||||
}
|
||||
}
|
||||
if case let ChatInfo.group(groupInfo, _) = chat.chatInfo, groupInfo.membership.memberActive {
|
||||
Button("For all moderators", role: .destructive) {
|
||||
if let reports = self.archivingReports {
|
||||
archiveReports(chat.chatInfo, reports.sorted(), true)
|
||||
archiveReports(chat, reports.sorted(), true)
|
||||
self.archivingReports = []
|
||||
}
|
||||
}
|
||||
@@ -2712,13 +2714,13 @@ private func deleteMessages(_ chat: Chat, _ deletingItems: [Int64], _ mode: CIDe
|
||||
await MainActor.run {
|
||||
for di in deletedItems {
|
||||
if let toItem = di.toChatItem {
|
||||
_ = ChatModel.shared.upsertChatItem(chat.chatInfo, toItem.chatItem)
|
||||
_ = ChatModel.shared.upsertChatItem(chatInfo, toItem.chatItem)
|
||||
} else {
|
||||
ChatModel.shared.removeChatItem(chatInfo, di.deletedChatItem.chatItem)
|
||||
}
|
||||
let deletedItem = di.deletedChatItem.chatItem
|
||||
if deletedItem.isActiveReport {
|
||||
ChatModel.shared.decreaseGroupReportsCounter(chat.chatInfo.id)
|
||||
ChatModel.shared.decreaseGroupReportsCounter(chatInfo.id)
|
||||
}
|
||||
}
|
||||
if let updatedChatInfo = deletedItems.last?.deletedChatItem.chatInfo {
|
||||
@@ -2733,8 +2735,9 @@ private func deleteMessages(_ chat: Chat, _ deletingItems: [Int64], _ mode: CIDe
|
||||
}
|
||||
}
|
||||
|
||||
func archiveReports(_ chatInfo: ChatInfo, _ itemIds: [Int64], _ forAll: Bool, _ onSuccess: @escaping () async -> Void = {}) {
|
||||
func archiveReports(_ chat: Chat, _ itemIds: [Int64], _ forAll: Bool, _ onSuccess: @escaping () async -> Void = {}) {
|
||||
if itemIds.count > 0 {
|
||||
let chatInfo = chat.chatInfo
|
||||
Task {
|
||||
do {
|
||||
let deleted = try await apiDeleteReceivedReports(
|
||||
|
||||
@@ -98,7 +98,7 @@ struct GroupChatInfoView: View {
|
||||
memberSupportButton()
|
||||
}
|
||||
if groupInfo.canModerate {
|
||||
GroupReportsChatNavLink(chat: chat, scrollToItemId: $scrollToItemId)
|
||||
GroupReportsChatNavLink(chat: chat, groupInfo: groupInfo, scrollToItemId: $scrollToItemId)
|
||||
}
|
||||
if groupInfo.membership.memberActive
|
||||
&& (groupInfo.membership.memberRole < .moderator || groupInfo.membership.supportChat != nil) {
|
||||
@@ -612,15 +612,19 @@ struct GroupChatInfoView: View {
|
||||
}
|
||||
|
||||
struct GroupReportsChatNavLink: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@State private var navLinkActive = false
|
||||
@ObservedObject var chat: Chat
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
var groupInfo: GroupInfo
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@Binding var scrollToItemId: ChatItem.ID?
|
||||
@State private var navLinkActive = false
|
||||
|
||||
var body: some View {
|
||||
NavigationLink(isActive: $navLinkActive) {
|
||||
SecondaryChatView(chat: chat, scrollToItemId: $scrollToItemId)
|
||||
SecondaryChatView(
|
||||
chat: Chat(chatInfo: .group(groupInfo: groupInfo, groupChatScope: .reports), chatItems: [], chatStats: ChatStats()),
|
||||
scrollToItemId: $scrollToItemId
|
||||
)
|
||||
} label: {
|
||||
HStack {
|
||||
Label {
|
||||
|
||||
@@ -107,6 +107,8 @@ struct GroupMentionsView: View {
|
||||
} else {
|
||||
return member.memberRole >= .moderator
|
||||
}
|
||||
case .reports:
|
||||
return false
|
||||
}
|
||||
case .msgContentTagContext:
|
||||
return false
|
||||
|
||||
@@ -160,6 +160,8 @@ enum SEChatCommand: ChatCmdProtocol {
|
||||
} else {
|
||||
"(_support)"
|
||||
}
|
||||
case .reports:
|
||||
"(reports, prohibited)" // can't use surrogate Reports scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1584,6 +1584,8 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat, Hashable {
|
||||
return nil
|
||||
case .some(.memberSupport(groupMember_: .none)):
|
||||
return nil
|
||||
case .some(.reports):
|
||||
return ("can't send messages", nil)
|
||||
}
|
||||
} else if groupInfo.nextConnectPrepared {
|
||||
return nil
|
||||
@@ -1895,26 +1897,35 @@ public struct ChatStats: Decodable, Hashable {
|
||||
|
||||
public enum GroupChatScope: Decodable {
|
||||
case memberSupport(groupMemberId_: Int64?)
|
||||
case reports // surrogate scope used for matching new items to opened Reports "chat scope" in UI, this type is not present in backend
|
||||
}
|
||||
|
||||
public func sameChatScope(_ scope1: GroupChatScope, _ scope2: GroupChatScope) -> Bool {
|
||||
switch (scope1, scope2) {
|
||||
return switch (scope1, scope2) {
|
||||
case let (.memberSupport(groupMemberId1_), .memberSupport(groupMemberId2_)):
|
||||
return groupMemberId1_ == groupMemberId2_
|
||||
groupMemberId1_ == groupMemberId2_
|
||||
case (.reports, .reports):
|
||||
true
|
||||
case (.reports, .memberSupport):
|
||||
false
|
||||
case (.memberSupport(groupMemberId_: let groupMemberId_), .reports):
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
public enum GroupChatScopeInfo: Decodable, Hashable {
|
||||
case memberSupport(groupMember_: GroupMember?)
|
||||
case reports // surrogate scope used for matching new items to opened Reports "chat scope" in UI, this type is not present in backend
|
||||
|
||||
public func toChatScope() -> GroupChatScope {
|
||||
switch self {
|
||||
return switch self {
|
||||
case let .memberSupport(groupMember_):
|
||||
if let groupMember = groupMember_ {
|
||||
return .memberSupport(groupMemberId_: groupMember.groupMemberId)
|
||||
.memberSupport(groupMemberId_: groupMember.groupMemberId)
|
||||
} else {
|
||||
return .memberSupport(groupMemberId_: nil)
|
||||
.memberSupport(groupMemberId_: nil)
|
||||
}
|
||||
case .reports: .reports
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-6
@@ -2943,12 +2943,6 @@ private fun archiveReports(chatRh: Long?, chatInfo: ChatInfo, itemIds: List<Long
|
||||
if (deleted != null) {
|
||||
withContext(Dispatchers.Main) {
|
||||
for (di in deleted) {
|
||||
val toChatItem = di.toChatItem?.chatItem
|
||||
if (toChatItem != null) {
|
||||
chatModel.chatsContext.upsertChatItem(chatRh, chatInfo, toChatItem)
|
||||
} else {
|
||||
chatModel.chatsContext.removeChatItem(chatRh, chatInfo, di.deletedChatItem.chatItem)
|
||||
}
|
||||
val deletedItem = di.deletedChatItem.chatItem
|
||||
if (deletedItem.isActiveReport) {
|
||||
chatModel.chatsContext.decreaseGroupReportsCounter(chatRh, chatInfo.id)
|
||||
|
||||
Reference in New Issue
Block a user