use delete action for group that current user is no longer in

pull/799/head
ryanzhao 2 years ago
parent 7f24097343
commit 36748a81c6

@ -764,6 +764,30 @@ final class HomeVC: BaseVC, UITableViewDataSource, UITableViewDelegate, SeedRemi
return UISwipeActionsConfiguration(actions: [ delete, mute, pin ])
case .openGroup, .closedGroup:
if threadViewModel.currentUserIsClosedGroupMember == false {
let delete: UIContextualAction = UIContextualAction(
title: "TXT_DELETE_TITLE".localized(),
icon: UIImage(named: "icon_bin")?.resizedImage(to: CGSize(width: Values.mediumFontSize, height: Values.mediumFontSize)),
iconHeight: Values.mediumFontSize,
themeTintColor: .white,
themeBackgroundColor: .conversationButton_swipeDestructive,
side: .trailing,
actionIndex: 2,
indexPath: indexPath,
tableView: tableView
) { [weak self] _, _, completionHandler in
self?.viewModel.delete(
threadId: threadViewModel.threadId,
threadVariant: threadViewModel.threadVariant,
force: true
)
completionHandler(true)
}
return UISwipeActionsConfiguration(actions: [ delete, mute, pin ])
}
let leave: UIContextualAction = UIContextualAction(
title: "LEAVE_BUTTON_TITLE".localized(),
icon: UIImage(systemName: "rectangle.portrait.and.arrow.right"),

@ -301,23 +301,42 @@ public class HomeViewModel {
// MARK: - Functions
public func delete(threadId: String, threadVariant: SessionThread.Variant) {
public func delete(threadId: String, threadVariant: SessionThread.Variant, force: Bool = false) {
func delete(_ db: Database, threadId: String) throws {
_ = try SessionThread
.filter(id: threadId)
.deleteAll(db)
}
Storage.shared.writeAsync { db in
switch threadVariant {
case .closedGroup:
try MessageSender.leave(
db,
groupPublicKey: threadId,
deleteThread: true
)
if force {
if let thread: SessionThread = try? SessionThread.fetchOne(db, id: threadId),
let closedGroup: ClosedGroup = try? thread.closedGroup.fetchOne(db)
{
try MessageSender.performClosedGroupCleanUp(
db,
for: closedGroup,
in: thread
)
}
try delete(db, threadId: threadId)
} else {
try MessageSender.leave(
db,
groupPublicKey: threadId,
deleteThread: true
)
}
case .openGroup:
OpenGroupManager.shared.delete(db, openGroupId: threadId)
_ = try SessionThread
.filter(id: threadId)
.deleteAll(db)
try delete(db, threadId: threadId)
default: break
default:
try delete(db, threadId: threadId)
}
}
}

@ -50,21 +50,8 @@ public enum GroupLeavingJob: JobExecutor {
)
}
.done(on: queue) { _ in
// Remove the group from the database and unsubscribe from PNs
ClosedGroupPoller.shared.stopPolling(for: details.groupPublicKey)
Storage.shared.writeAsync { db in
let userPublicKey: String = getUserHexEncodedPublicKey(db)
try closedGroup
.keyPairs
.deleteAll(db)
let _ = PushNotificationAPI.performOperation(
.unsubscribe,
for: details.groupPublicKey,
publicKey: userPublicKey
)
try MessageSender.performClosedGroupCleanUp(db, for: closedGroup, in: thread)
try Interaction
.filter(id: interactionId)
@ -76,25 +63,6 @@ public enum GroupLeavingJob: JobExecutor {
]
)
// Update the group (if the admin leaves the group is disbanded)
let wasAdminUser: Bool = try GroupMember
.filter(GroupMember.Columns.groupId == thread.id)
.filter(GroupMember.Columns.profileId == userPublicKey)
.filter(GroupMember.Columns.role == GroupMember.Role.admin)
.isNotEmpty(db)
if wasAdminUser {
try GroupMember
.filter(GroupMember.Columns.groupId == thread.id)
.deleteAll(db)
}
else {
try GroupMember
.filter(GroupMember.Columns.groupId == thread.id)
.filter(GroupMember.Columns.profileId == userPublicKey)
.deleteAll(db)
}
if details.deleteThread {
_ = try SessionThread
.filter(id: thread.id)

@ -582,4 +582,40 @@ extension MessageSender {
}
catch {}
}
/// Remove the group from the database and unsubscribe from PNs
public static func performClosedGroupCleanUp(_ db: Database, for closedGroup: ClosedGroup, in thread: SessionThread) throws {
ClosedGroupPoller.shared.stopPolling(for: closedGroup.publicKey)
let userPublicKey: String = getUserHexEncodedPublicKey(db)
try closedGroup
.keyPairs
.deleteAll(db)
let _ = PushNotificationAPI.performOperation(
.unsubscribe,
for: closedGroup.publicKey,
publicKey: userPublicKey
)
// Update the group (if the admin leaves the group is disbanded)
let wasAdminUser: Bool = try GroupMember
.filter(GroupMember.Columns.groupId == thread.id)
.filter(GroupMember.Columns.profileId == userPublicKey)
.filter(GroupMember.Columns.role == GroupMember.Role.admin)
.isNotEmpty(db)
if wasAdminUser {
try GroupMember
.filter(GroupMember.Columns.groupId == thread.id)
.deleteAll(db)
}
else {
try GroupMember
.filter(GroupMember.Columns.groupId == thread.id)
.filter(GroupMember.Columns.profileId == userPublicKey)
.deleteAll(db)
}
}
}

@ -457,6 +457,9 @@ public extension SessionThreadViewModel {
let interactionAttachmentAttachmentIdColumnLiteral: SQL = SQL(stringLiteral: InteractionAttachment.Columns.attachmentId.name)
let interactionAttachmentInteractionIdColumnLiteral: SQL = SQL(stringLiteral: InteractionAttachment.Columns.interactionId.name)
let interactionAttachmentAlbumIndexColumnLiteral: SQL = SQL(stringLiteral: InteractionAttachment.Columns.albumIndex.name)
let groupMemberProfileIdColumnLiteral: SQL = SQL(stringLiteral: GroupMember.Columns.profileId.name)
let groupMemberRoleColumnLiteral: SQL = SQL(stringLiteral: GroupMember.Columns.role.name)
let groupMemberGroupIdColumnLiteral: SQL = SQL(stringLiteral: GroupMember.Columns.groupId.name)
/// **Note:** The `numColumnsBeforeProfiles` value **MUST** match the number of fields before
/// the `ViewModel.contactProfileKey` entry below otherwise the query will fail to
@ -464,7 +467,7 @@ public extension SessionThreadViewModel {
///
/// Explicitly set default values for the fields ignored for search results
let numColumnsBeforeProfiles: Int = 12
let numColumnsBetweenProfilesAndAttachmentInfo: Int = 11 // The attachment info columns will be combined
let numColumnsBetweenProfilesAndAttachmentInfo: Int = 12 // The attachment info columns will be combined
let request: SQLRequest<ViewModel> = """
SELECT
@ -488,7 +491,8 @@ public extension SessionThreadViewModel {
\(ViewModel.closedGroupProfileBackKey).*,
\(ViewModel.closedGroupProfileBackFallbackKey).*,
\(closedGroup[.name]) AS \(ViewModel.closedGroupNameKey),
(\(groupMember[.profileId]) IS NOT NULL) AS \(ViewModel.currentUserIsClosedGroupAdminKey),
(\(ViewModel.currentUserIsClosedGroupMemberKey).profileId IS NOT NULL) AS \(ViewModel.currentUserIsClosedGroupMemberKey),
(\(ViewModel.currentUserIsClosedGroupAdminKey).profileId IS NOT NULL) AS \(ViewModel.currentUserIsClosedGroupAdminKey),
\(openGroup[.name]) AS \(ViewModel.openGroupNameKey),
\(openGroup[.imageData]) AS \(ViewModel.openGroupProfilePictureDataKey),
@ -563,10 +567,15 @@ public extension SessionThreadViewModel {
LEFT JOIN \(Profile.self) AS \(ViewModel.contactProfileKey) ON \(ViewModel.contactProfileKey).\(profileIdColumnLiteral) = \(thread[.id])
LEFT JOIN \(OpenGroup.self) ON \(openGroup[.threadId]) = \(thread[.id])
LEFT JOIN \(ClosedGroup.self) ON \(closedGroup[.threadId]) = \(thread[.id])
LEFT JOIN \(GroupMember.self) ON (
\(SQL("\(groupMember[.role]) = \(GroupMember.Role.admin)")) AND
\(groupMember[.groupId]) = \(closedGroup[.threadId]) AND
\(SQL("\(groupMember[.profileId]) = \(userPublicKey)"))
LEFT JOIN \(GroupMember.self) AS \(ViewModel.currentUserIsClosedGroupMemberKey) ON (
\(SQL("\(ViewModel.currentUserIsClosedGroupMemberKey).\(groupMemberRoleColumnLiteral) != \(GroupMember.Role.zombie)")) AND
\(ViewModel.currentUserIsClosedGroupMemberKey).\(groupMemberGroupIdColumnLiteral) = \(closedGroup[.threadId]) AND
\(SQL("\(ViewModel.currentUserIsClosedGroupMemberKey).\(groupMemberProfileIdColumnLiteral) = \(userPublicKey)"))
)
LEFT JOIN \(GroupMember.self) AS \(ViewModel.currentUserIsClosedGroupAdminKey) ON (
\(SQL("\(ViewModel.currentUserIsClosedGroupAdminKey).\(groupMemberRoleColumnLiteral) = \(GroupMember.Role.admin)")) AND
\(ViewModel.currentUserIsClosedGroupAdminKey).\(groupMemberGroupIdColumnLiteral) = \(closedGroup[.threadId]) AND
\(SQL("\(ViewModel.currentUserIsClosedGroupAdminKey).\(groupMemberProfileIdColumnLiteral) = \(userPublicKey)"))
)
LEFT JOIN \(Profile.self) AS \(ViewModel.closedGroupProfileFrontKey) ON (

Loading…
Cancel
Save