139 lines
3.9 KiB
Swift
139 lines
3.9 KiB
Swift
//
|
|
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import PromiseKit
|
|
|
|
@objc
|
|
protocol GroupViewHelperDelegate: class {
|
|
func groupViewHelperDidUpdateGroup()
|
|
|
|
var currentGroupModel: TSGroupModel? { get }
|
|
|
|
var fromViewController: UIViewController? { get }
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
@objc
|
|
class GroupViewHelper: NSObject {
|
|
|
|
// MARK: - Dependencies
|
|
|
|
var tsAccountManager: TSAccountManager {
|
|
return .sharedInstance()
|
|
}
|
|
|
|
var contactsManager: OWSContactsManager {
|
|
return Environment.shared.contactsManager
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
@objc
|
|
weak var delegate: GroupViewHelperDelegate?
|
|
|
|
let threadViewModel: ThreadViewModel
|
|
|
|
var thread: TSThread {
|
|
return threadViewModel.threadRecord
|
|
}
|
|
|
|
var fromViewController: UIViewController? {
|
|
return delegate?.fromViewController
|
|
}
|
|
|
|
@objc
|
|
init(threadViewModel: ThreadViewModel) {
|
|
self.threadViewModel = threadViewModel
|
|
}
|
|
|
|
// MARK: - Accessors
|
|
|
|
// Don't use this method directly;
|
|
// Use canEditConversationAttributes or canEditConversationMembership instead.
|
|
private func canLocalUserEditConversation(v2AccessTypeBlock: (GroupAccess) -> GroupV2Access) -> Bool {
|
|
if threadViewModel.hasPendingMessageRequest {
|
|
return false
|
|
}
|
|
guard isLocalUserInConversation else {
|
|
return false
|
|
}
|
|
guard let groupThread = thread as? TSGroupThread else {
|
|
// Both users can edit contact threads.
|
|
return true
|
|
}
|
|
guard let groupModelV2 = groupThread.groupModel as? TSGroupModelV2 else {
|
|
// All users can edit v1 groups.
|
|
return true
|
|
}
|
|
guard let localAddress = tsAccountManager.localAddress else {
|
|
owsFailDebug("Missing localAddress.")
|
|
return false
|
|
}
|
|
// Use the block to pick the access type: attributes or members?
|
|
let access = v2AccessTypeBlock(groupModelV2.access)
|
|
switch access {
|
|
case .unknown:
|
|
owsFailDebug("Unknown access.")
|
|
return false
|
|
case .any:
|
|
return true
|
|
case .member:
|
|
return groupModelV2.groupMembership.isNonPendingMember(localAddress)
|
|
case .administrator:
|
|
return (groupModelV2.groupMembership.isNonPendingMember(localAddress) && groupModelV2.groupMembership.isAdministrator(localAddress))
|
|
}
|
|
}
|
|
|
|
// Can local user edit conversation attributes:
|
|
//
|
|
// * DM state
|
|
// * Group title (if group)
|
|
// * Group avatar (if group)
|
|
var canEditConversationAttributes: Bool {
|
|
return canLocalUserEditConversation { groupAccess in
|
|
return groupAccess.attributes
|
|
}
|
|
}
|
|
|
|
// Can local user edit group membership.
|
|
var canEditConversationMembership: Bool {
|
|
return canLocalUserEditConversation { groupAccess in
|
|
return groupAccess.members
|
|
}
|
|
}
|
|
|
|
// Can local user edit group access.
|
|
var canEditConversationAccess: Bool {
|
|
if threadViewModel.hasPendingMessageRequest {
|
|
return false
|
|
}
|
|
guard isLocalUserInConversation else {
|
|
return false
|
|
}
|
|
guard let groupThread = thread as? TSGroupThread else {
|
|
// Contact threads don't use access.
|
|
return false
|
|
}
|
|
guard let groupModelV2 = groupThread.groupModel as? TSGroupModelV2 else {
|
|
// v1 groups don't use access.
|
|
return false
|
|
}
|
|
guard let localAddress = tsAccountManager.localAddress else {
|
|
owsFailDebug("Missing localAddress.")
|
|
return false
|
|
}
|
|
return groupModelV2.groupMembership.isAdministrator(localAddress)
|
|
}
|
|
|
|
var isLocalUserInConversation: Bool {
|
|
guard let groupThread = thread as? TSGroupThread else {
|
|
return true
|
|
}
|
|
|
|
return groupThread.isLocalUserInGroup
|
|
}
|
|
}
|