session-ios/Session/Conversations/Context Menu/ContextMenuVC+Action.swift

157 lines
6.3 KiB
Swift

// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import UIKit
import SessionMessagingKit
extension ContextMenuVC {
struct Action {
let icon: UIImage?
let title: String
let isDismissAction: Bool
let work: () -> Void
static func reply(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action {
return Action(
icon: UIImage(named: "ic_reply"),
title: "context_menu_reply".localized(),
isDismissAction: false
) { delegate?.reply(cellViewModel) }
}
static func copy(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action {
return Action(
icon: UIImage(named: "ic_copy"),
title: "copy".localized(),
isDismissAction: false
) { delegate?.copy(cellViewModel) }
}
static func copySessionID(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action {
return Action(
icon: UIImage(named: "ic_copy"),
title: "vc_conversation_settings_copy_session_id_button_title".localized(),
isDismissAction: false
) { delegate?.copySessionID(cellViewModel) }
}
static func delete(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action {
return Action(
icon: UIImage(named: "ic_trash"),
title: "TXT_DELETE_TITLE".localized(),
isDismissAction: false
) { delegate?.delete(cellViewModel) }
}
static func save(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action {
return Action(
icon: UIImage(named: "ic_download"),
title: "context_menu_save".localized(),
isDismissAction: false
) { delegate?.save(cellViewModel) }
}
static func ban(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action {
return Action(
icon: UIImage(named: "ic_block"),
title: "context_menu_ban_user".localized(),
isDismissAction: false
) { delegate?.ban(cellViewModel) }
}
static func banAndDeleteAllMessages(_ cellViewModel: MessageViewModel, _ delegate: ContextMenuActionDelegate?) -> Action {
return Action(
icon: UIImage(named: "ic_block"),
title: "context_menu_ban_and_delete_all".localized(),
isDismissAction: false
) { delegate?.banAndDeleteAllMessages(cellViewModel) }
}
static func dismiss(_ delegate: ContextMenuActionDelegate?) -> Action {
return Action(
icon: nil,
title: "",
isDismissAction: true
) { delegate?.contextMenuDismissed() }
}
}
static func actions(for cellViewModel: MessageViewModel, currentUserIsOpenGroupModerator: Bool, delegate: ContextMenuActionDelegate?) -> [Action]? {
// No context items for info messages
guard cellViewModel.variant == .standardOutgoing || cellViewModel.variant == .standardIncoming else {
return nil
}
let canReply: Bool = (
cellViewModel.variant != .standardOutgoing || (
cellViewModel.state != .failed &&
cellViewModel.state != .sending
)
)
let canCopy: Bool = (
cellViewModel.cellType == .textOnlyMessage || (
(
cellViewModel.cellType == .genericAttachment ||
cellViewModel.cellType == .mediaMessage
) &&
(cellViewModel.attachments ?? []).count == 1 &&
(cellViewModel.attachments ?? []).first?.isVisualMedia == true &&
(cellViewModel.attachments ?? []).first?.isValid == true && (
(cellViewModel.attachments ?? []).first?.state == .downloaded ||
(cellViewModel.attachments ?? []).first?.state == .uploaded
)
)
)
let canSave: Bool = (
cellViewModel.cellType == .mediaMessage &&
(cellViewModel.attachments ?? [])
.filter { attachment in
attachment.isValid &&
attachment.isVisualMedia && (
attachment.state == .downloaded ||
attachment.state == .uploaded
)
}.isEmpty == false
)
let canCopySessionId: Bool = (
cellViewModel.variant == .standardIncoming &&
cellViewModel.threadVariant != .openGroup
)
let canDelete: Bool = (
cellViewModel.threadVariant != .openGroup ||
currentUserIsOpenGroupModerator
)
let canBan: Bool = (
cellViewModel.threadVariant == .openGroup &&
currentUserIsOpenGroupModerator
)
let generatedActions: [Action] = [
(canReply ? Action.reply(cellViewModel, delegate) : nil),
(canCopy ? Action.copy(cellViewModel, delegate) : nil),
(canSave ? Action.save(cellViewModel, delegate) : nil),
(canCopySessionId ? Action.copySessionID(cellViewModel, delegate) : nil),
(canDelete ? Action.delete(cellViewModel, delegate) : nil),
(canBan ? Action.ban(cellViewModel, delegate) : nil),
(canBan ? Action.banAndDeleteAllMessages(cellViewModel, delegate) : nil)
]
.compactMap { $0 }
guard !generatedActions.isEmpty else { return [] }
return generatedActions.appending(Action.dismiss(delegate))
}
}
// MARK: - Delegate
protocol ContextMenuActionDelegate {
func reply(_ cellViewModel: MessageViewModel)
func copy(_ cellViewModel: MessageViewModel)
func copySessionID(_ cellViewModel: MessageViewModel)
func delete(_ cellViewModel: MessageViewModel)
func save(_ cellViewModel: MessageViewModel)
func ban(_ cellViewModel: MessageViewModel)
func banAndDeleteAllMessages(_ cellViewModel: MessageViewModel)
func contextMenuDismissed()
}