Merge pull request #895 from mpretty-cyro/fix/config-processing-issues

Fixed a couple of config handling bugs
This commit is contained in:
Morgan Pretty 2023-09-04 09:54:28 +10:00 committed by GitHub
commit 1a10049f39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 57 deletions

View File

@ -574,7 +574,7 @@ final class ConversationVC: BaseVC, SessionUtilRespondingViewController, Convers
!SessionUtil.conversationInConfig(
threadId: threadId,
threadVariant: viewModel.threadData.threadVariant,
visibleOnly: true
visibleOnly: false
)
{
Storage.shared.writeAsync { db in

View File

@ -164,7 +164,7 @@ public extension UIContextualAction {
db,
threadId: threadViewModel.threadId,
threadVariant: threadViewModel.threadVariant,
groupLeaveType: .forced,
groupLeaveType: .silent,
calledFromConfigHandling: false
)
}

View File

@ -296,17 +296,18 @@ public extension SessionThread {
calledFromConfigHandling: Bool
) throws {
let currentUserPublicKey: String = getUserHexEncodedPublicKey(db)
let remainingThreadIds: [String] = threadIds.filter { $0 != currentUserPublicKey }
let remainingThreadIds: Set<String> = threadIds.asSet().removing(currentUserPublicKey)
switch (threadVariant, groupLeaveType) {
case (.contact, _):
case (.contact, .standard), (.contact, .silent):
// Clear any interactions for the deleted thread
_ = try Interaction
.filter(threadIds.contains(Interaction.Columns.threadId))
.deleteAll(db)
// We need to custom handle the 'Note to Self' conversation (it should just be
// hidden rather than deleted
// hidden locally rather than deleted)
if threadIds.contains(currentUserPublicKey) {
_ = try Interaction
.filter(Interaction.Columns.threadId == currentUserPublicKey)
.deleteAll(db)
_ = try SessionThread
.filter(id: currentUserPublicKey)
.updateAllAndConfig(
@ -314,17 +315,28 @@ public extension SessionThread {
SessionThread.Columns.pinnedPriority.set(to: 0),
SessionThread.Columns.shouldBeVisible.set(to: false)
)
return
}
// Update any other threads to be hidden (don't want to actually delete the thread
// record in case it's settings get changed while it's not visible)
_ = try SessionThread
.filter(id: remainingThreadIds)
.updateAllAndConfig(
db,
calledFromConfig: calledFromConfig,
SessionThread.Columns.pinnedPriority.set(to: SessionUtil.hiddenPriority),
SessionThread.Columns.shouldBeVisible.set(to: false)
)
case (.contact, .forced):
// If this wasn't called from config handling then we need to hide the conversation
if !calledFromConfigHandling {
try SessionUtil
.hide(db, contactIds: threadIds)
.remove(db, contactIds: remainingThreadIds)
}
_ = try SessionThread
.filter(ids: remainingThreadIds)
.filter(id: remainingThreadIds)
.deleteAll(db)
case (.legacyGroup, .standard), (.group, .standard):

View File

@ -138,46 +138,37 @@ internal extension SessionUtil {
let threadExists: Bool = (threadInfo != nil)
let updatedShouldBeVisible: Bool = SessionUtil.shouldBeVisible(priority: data.priority)
switch (updatedShouldBeVisible, threadExists) {
case (false, true):
SessionUtil.kickFromConversationUIIfNeeded(removedThreadIds: [sessionId])
try SessionThread
.deleteOrLeave(
db,
threadId: sessionId,
threadVariant: .contact,
groupLeaveType: .forced,
calledFromConfigHandling: true
)
case (true, false):
try SessionThread(
id: sessionId,
variant: .contact,
creationDateTimestamp: data.created,
shouldBeVisible: true,
pinnedPriority: data.priority
).save(db)
case (true, true):
let changes: [ConfigColumnAssignment] = [
(threadInfo?.shouldBeVisible == updatedShouldBeVisible ? nil :
SessionThread.Columns.shouldBeVisible.set(to: updatedShouldBeVisible)
),
(threadInfo?.pinnedPriority == data.priority ? nil :
SessionThread.Columns.pinnedPriority.set(to: data.priority)
)
].compactMap { $0 }
try SessionThread
.filter(id: sessionId)
.updateAll( // Handling a config update so don't use `updateAllAndConfig`
db,
changes
)
case (false, false): break
/// If we are hiding the conversation then kick the user from it if it's currently open
if !updatedShouldBeVisible {
SessionUtil.kickFromConversationUIIfNeeded(removedThreadIds: [sessionId])
}
/// Create the thread if it doesn't exist, otherwise just update it's state
if !threadExists {
try SessionThread(
id: sessionId,
variant: .contact,
creationDateTimestamp: data.created,
shouldBeVisible: updatedShouldBeVisible,
pinnedPriority: data.priority
).save(db)
}
else {
let changes: [ConfigColumnAssignment] = [
(threadInfo?.shouldBeVisible == updatedShouldBeVisible ? nil :
SessionThread.Columns.shouldBeVisible.set(to: updatedShouldBeVisible)
),
(threadInfo?.pinnedPriority == data.priority ? nil :
SessionThread.Columns.pinnedPriority.set(to: data.priority)
)
].compactMap { $0 }
try SessionThread
.filter(id: sessionId)
.updateAll( // Handling a config update so don't use `updateAllAndConfig`
db,
changes
)
}
}

View File

@ -113,7 +113,7 @@ internal extension SessionUtil {
db,
threadId: userPublicKey,
threadVariant: .contact,
groupLeaveType: .forced,
groupLeaveType: .silent,
calledFromConfigHandling: true
)
}

View File

@ -52,14 +52,16 @@ public extension QueryInterfaceRequest where RowDecoder: FetchableRecord & Table
@discardableResult
func updateAllAndConfig(
_ db: Database,
calledFromConfig: Bool = false,
_ assignments: ConfigColumnAssignment...
) throws -> Int {
return try updateAllAndConfig(db, assignments)
return try updateAllAndConfig(db, calledFromConfig: calledFromConfig, assignments)
}
@discardableResult
func updateAllAndConfig(
_ db: Database,
calledFromConfig: Bool = false,
_ assignments: [ConfigColumnAssignment]
) throws -> Int {
let targetAssignments: [ColumnAssignment] = assignments.map { $0.assignment }
@ -69,7 +71,7 @@ public extension QueryInterfaceRequest where RowDecoder: FetchableRecord & Table
return try self.updateAll(db, targetAssignments)
}
return try self.updateAndFetchAllAndUpdateConfig(db, assignments).count
return try self.updateAndFetchAllAndUpdateConfig(db, calledFromConfig: calledFromConfig, assignments).count
}
// MARK: -- updateAndFetchAll
@ -77,21 +79,26 @@ public extension QueryInterfaceRequest where RowDecoder: FetchableRecord & Table
@discardableResult
func updateAndFetchAllAndUpdateConfig(
_ db: Database,
calledFromConfig: Bool = false,
_ assignments: ConfigColumnAssignment...
) throws -> [RowDecoder] {
return try updateAndFetchAllAndUpdateConfig(db, assignments)
return try updateAndFetchAllAndUpdateConfig(db, calledFromConfig: calledFromConfig, assignments)
}
@discardableResult
func updateAndFetchAllAndUpdateConfig(
_ db: Database,
calledFromConfig: Bool = false,
_ assignments: [ConfigColumnAssignment]
) throws -> [RowDecoder] {
// First perform the actual updates
let updatedData: [RowDecoder] = try self.updateAndFetchAll(db, assignments.map { $0.assignment })
// Then check if any of the changes could affect the config
guard SessionUtil.assignmentsRequireConfigUpdate(assignments) else { return updatedData }
guard
!calledFromConfig &&
SessionUtil.assignmentsRequireConfigUpdate(assignments)
else { return updatedData }
defer {
// If we changed a column that requires a config update then we may as well automatically

View File

@ -360,6 +360,7 @@ public enum SessionUtil {
guard !publicKey.isEmpty else { throw MessageReceiverError.noThread }
let groupedMessages: [ConfigDump.Variant: [SharedConfigMessage]] = messages
.sorted { lhs, rhs in lhs.seqNo < rhs.seqNo }
.grouped(by: \.kind.configDumpVariant)
let needsPush: Bool = try groupedMessages