Fixed a couple of config handling bugs
Fixed an bug where config messages could be processed in the wrong order Tweaked the behaviour or removing threads (this would cause issues with future config-based settings changes that live on the thread getting lost)
This commit is contained in:
parent
6d990559b7
commit
7a8941db5c
|
@ -574,7 +574,7 @@ final class ConversationVC: BaseVC, SessionUtilRespondingViewController, Convers
|
||||||
!SessionUtil.conversationInConfig(
|
!SessionUtil.conversationInConfig(
|
||||||
threadId: threadId,
|
threadId: threadId,
|
||||||
threadVariant: viewModel.threadData.threadVariant,
|
threadVariant: viewModel.threadData.threadVariant,
|
||||||
visibleOnly: true
|
visibleOnly: false
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Storage.shared.writeAsync { db in
|
Storage.shared.writeAsync { db in
|
||||||
|
|
|
@ -164,7 +164,7 @@ public extension UIContextualAction {
|
||||||
db,
|
db,
|
||||||
threadId: threadViewModel.threadId,
|
threadId: threadViewModel.threadId,
|
||||||
threadVariant: threadViewModel.threadVariant,
|
threadVariant: threadViewModel.threadVariant,
|
||||||
groupLeaveType: .forced,
|
groupLeaveType: .silent,
|
||||||
calledFromConfigHandling: false
|
calledFromConfigHandling: false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,17 +296,18 @@ public extension SessionThread {
|
||||||
calledFromConfigHandling: Bool
|
calledFromConfigHandling: Bool
|
||||||
) throws {
|
) throws {
|
||||||
let currentUserPublicKey: String = getUserHexEncodedPublicKey(db)
|
let currentUserPublicKey: String = getUserHexEncodedPublicKey(db)
|
||||||
let remainingThreadIds: [String] = threadIds.filter { $0 != currentUserPublicKey }
|
let remainingThreadIds: Set<String> = threadIds.asSet().removing(currentUserPublicKey)
|
||||||
|
|
||||||
switch (threadVariant, groupLeaveType) {
|
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
|
// 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) {
|
if threadIds.contains(currentUserPublicKey) {
|
||||||
_ = try Interaction
|
|
||||||
.filter(Interaction.Columns.threadId == currentUserPublicKey)
|
|
||||||
.deleteAll(db)
|
|
||||||
|
|
||||||
_ = try SessionThread
|
_ = try SessionThread
|
||||||
.filter(id: currentUserPublicKey)
|
.filter(id: currentUserPublicKey)
|
||||||
.updateAllAndConfig(
|
.updateAllAndConfig(
|
||||||
|
@ -314,17 +315,28 @@ public extension SessionThread {
|
||||||
SessionThread.Columns.pinnedPriority.set(to: 0),
|
SessionThread.Columns.pinnedPriority.set(to: 0),
|
||||||
SessionThread.Columns.shouldBeVisible.set(to: false)
|
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 this wasn't called from config handling then we need to hide the conversation
|
||||||
if !calledFromConfigHandling {
|
if !calledFromConfigHandling {
|
||||||
try SessionUtil
|
try SessionUtil
|
||||||
.hide(db, contactIds: threadIds)
|
.remove(db, contactIds: remainingThreadIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = try SessionThread
|
_ = try SessionThread
|
||||||
.filter(ids: remainingThreadIds)
|
.filter(id: remainingThreadIds)
|
||||||
.deleteAll(db)
|
.deleteAll(db)
|
||||||
|
|
||||||
case (.legacyGroup, .standard), (.group, .standard):
|
case (.legacyGroup, .standard), (.group, .standard):
|
||||||
|
|
|
@ -138,46 +138,37 @@ internal extension SessionUtil {
|
||||||
let threadExists: Bool = (threadInfo != nil)
|
let threadExists: Bool = (threadInfo != nil)
|
||||||
let updatedShouldBeVisible: Bool = SessionUtil.shouldBeVisible(priority: data.priority)
|
let updatedShouldBeVisible: Bool = SessionUtil.shouldBeVisible(priority: data.priority)
|
||||||
|
|
||||||
switch (updatedShouldBeVisible, threadExists) {
|
/// If we are hiding the conversation then kick the user from it if it's currently open
|
||||||
case (false, true):
|
if !updatedShouldBeVisible {
|
||||||
SessionUtil.kickFromConversationUIIfNeeded(removedThreadIds: [sessionId])
|
SessionUtil.kickFromConversationUIIfNeeded(removedThreadIds: [sessionId])
|
||||||
|
}
|
||||||
try SessionThread
|
|
||||||
.deleteOrLeave(
|
/// Create the thread if it doesn't exist, otherwise just update it's state
|
||||||
db,
|
if !threadExists {
|
||||||
threadId: sessionId,
|
try SessionThread(
|
||||||
threadVariant: .contact,
|
id: sessionId,
|
||||||
groupLeaveType: .forced,
|
variant: .contact,
|
||||||
calledFromConfigHandling: true
|
creationDateTimestamp: data.created,
|
||||||
)
|
shouldBeVisible: updatedShouldBeVisible,
|
||||||
|
pinnedPriority: data.priority
|
||||||
case (true, false):
|
).save(db)
|
||||||
try SessionThread(
|
}
|
||||||
id: sessionId,
|
else {
|
||||||
variant: .contact,
|
let changes: [ConfigColumnAssignment] = [
|
||||||
creationDateTimestamp: data.created,
|
(threadInfo?.shouldBeVisible == updatedShouldBeVisible ? nil :
|
||||||
shouldBeVisible: true,
|
SessionThread.Columns.shouldBeVisible.set(to: updatedShouldBeVisible)
|
||||||
pinnedPriority: data.priority
|
),
|
||||||
).save(db)
|
(threadInfo?.pinnedPriority == data.priority ? nil :
|
||||||
|
SessionThread.Columns.pinnedPriority.set(to: data.priority)
|
||||||
case (true, true):
|
)
|
||||||
let changes: [ConfigColumnAssignment] = [
|
].compactMap { $0 }
|
||||||
(threadInfo?.shouldBeVisible == updatedShouldBeVisible ? nil :
|
|
||||||
SessionThread.Columns.shouldBeVisible.set(to: updatedShouldBeVisible)
|
try SessionThread
|
||||||
),
|
.filter(id: sessionId)
|
||||||
(threadInfo?.pinnedPriority == data.priority ? nil :
|
.updateAll( // Handling a config update so don't use `updateAllAndConfig`
|
||||||
SessionThread.Columns.pinnedPriority.set(to: data.priority)
|
db,
|
||||||
)
|
changes
|
||||||
].compactMap { $0 }
|
)
|
||||||
|
|
||||||
try SessionThread
|
|
||||||
.filter(id: sessionId)
|
|
||||||
.updateAll( // Handling a config update so don't use `updateAllAndConfig`
|
|
||||||
db,
|
|
||||||
changes
|
|
||||||
)
|
|
||||||
|
|
||||||
case (false, false): break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ internal extension SessionUtil {
|
||||||
db,
|
db,
|
||||||
threadId: userPublicKey,
|
threadId: userPublicKey,
|
||||||
threadVariant: .contact,
|
threadVariant: .contact,
|
||||||
groupLeaveType: .forced,
|
groupLeaveType: .silent,
|
||||||
calledFromConfigHandling: true
|
calledFromConfigHandling: true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,14 +52,16 @@ public extension QueryInterfaceRequest where RowDecoder: FetchableRecord & Table
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func updateAllAndConfig(
|
func updateAllAndConfig(
|
||||||
_ db: Database,
|
_ db: Database,
|
||||||
|
calledFromConfig: Bool = false,
|
||||||
_ assignments: ConfigColumnAssignment...
|
_ assignments: ConfigColumnAssignment...
|
||||||
) throws -> Int {
|
) throws -> Int {
|
||||||
return try updateAllAndConfig(db, assignments)
|
return try updateAllAndConfig(db, calledFromConfig: calledFromConfig, assignments)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func updateAllAndConfig(
|
func updateAllAndConfig(
|
||||||
_ db: Database,
|
_ db: Database,
|
||||||
|
calledFromConfig: Bool = false,
|
||||||
_ assignments: [ConfigColumnAssignment]
|
_ assignments: [ConfigColumnAssignment]
|
||||||
) throws -> Int {
|
) throws -> Int {
|
||||||
let targetAssignments: [ColumnAssignment] = assignments.map { $0.assignment }
|
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.updateAll(db, targetAssignments)
|
||||||
}
|
}
|
||||||
|
|
||||||
return try self.updateAndFetchAllAndUpdateConfig(db, assignments).count
|
return try self.updateAndFetchAllAndUpdateConfig(db, calledFromConfig: calledFromConfig, assignments).count
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: -- updateAndFetchAll
|
// MARK: -- updateAndFetchAll
|
||||||
|
@ -77,21 +79,26 @@ public extension QueryInterfaceRequest where RowDecoder: FetchableRecord & Table
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func updateAndFetchAllAndUpdateConfig(
|
func updateAndFetchAllAndUpdateConfig(
|
||||||
_ db: Database,
|
_ db: Database,
|
||||||
|
calledFromConfig: Bool = false,
|
||||||
_ assignments: ConfigColumnAssignment...
|
_ assignments: ConfigColumnAssignment...
|
||||||
) throws -> [RowDecoder] {
|
) throws -> [RowDecoder] {
|
||||||
return try updateAndFetchAllAndUpdateConfig(db, assignments)
|
return try updateAndFetchAllAndUpdateConfig(db, calledFromConfig: calledFromConfig, assignments)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func updateAndFetchAllAndUpdateConfig(
|
func updateAndFetchAllAndUpdateConfig(
|
||||||
_ db: Database,
|
_ db: Database,
|
||||||
|
calledFromConfig: Bool = false,
|
||||||
_ assignments: [ConfigColumnAssignment]
|
_ assignments: [ConfigColumnAssignment]
|
||||||
) throws -> [RowDecoder] {
|
) throws -> [RowDecoder] {
|
||||||
// First perform the actual updates
|
// First perform the actual updates
|
||||||
let updatedData: [RowDecoder] = try self.updateAndFetchAll(db, assignments.map { $0.assignment })
|
let updatedData: [RowDecoder] = try self.updateAndFetchAll(db, assignments.map { $0.assignment })
|
||||||
|
|
||||||
// Then check if any of the changes could affect the config
|
// 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 {
|
defer {
|
||||||
// If we changed a column that requires a config update then we may as well automatically
|
// If we changed a column that requires a config update then we may as well automatically
|
||||||
|
|
|
@ -360,6 +360,7 @@ public enum SessionUtil {
|
||||||
guard !publicKey.isEmpty else { throw MessageReceiverError.noThread }
|
guard !publicKey.isEmpty else { throw MessageReceiverError.noThread }
|
||||||
|
|
||||||
let groupedMessages: [ConfigDump.Variant: [SharedConfigMessage]] = messages
|
let groupedMessages: [ConfigDump.Variant: [SharedConfigMessage]] = messages
|
||||||
|
.sorted { lhs, rhs in lhs.seqNo < rhs.seqNo }
|
||||||
.grouped(by: \.kind.configDumpVariant)
|
.grouped(by: \.kind.configDumpVariant)
|
||||||
|
|
||||||
let needsPush: Bool = try groupedMessages
|
let needsPush: Bool = try groupedMessages
|
||||||
|
|
Loading…
Reference in New Issue