diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 7b6fcfb57..6a7cf6647 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -8109,7 +8109,7 @@ CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 467; + CURRENT_PROJECT_VERSION = 468; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -8187,7 +8187,7 @@ CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution"; - CURRENT_PROJECT_VERSION = 467; + CURRENT_PROJECT_VERSION = 468; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; diff --git a/Session/Shared/Types/ObservableTableSource.swift b/Session/Shared/Types/ObservableTableSource.swift index b4d85d254..7ec6abf90 100644 --- a/Session/Shared/Types/ObservableTableSource.swift +++ b/Session/Shared/Types/ObservableTableSource.swift @@ -186,14 +186,17 @@ public enum ObservationBuilder { return TableObservation { viewModel, dependencies in subject .withPrevious(([], StagedChangeset())) - .filter { prev, next in - /// Suppress events with no changes (these will be sent in order to clear out the `StagedChangeset` value as if we - /// don't do so then resubscribing will result in an attempt to apply an invalid changeset to the `tableView` resulting - /// in a crash) - !next.1.isEmpty - } + .handleEvents( + receiveCancel: { + /// When we unsubscribe we send through the existing data but clear out the `StagedChangeset` value + /// so that resubscribing doesn't result in the UI trying to reapply the same changeset (which would cause a + /// crash due to invalid table view changes) + subject.send((subject.value.0, StagedChangeset())) + } + ) .map { _, current -> ([T], StagedChangeset<[T]>) in current } .setFailureType(to: Error.self) + .shareReplay(1) .eraseToAnyPublisher() } } diff --git a/Session/Shared/Views/SessionCell.swift b/Session/Shared/Views/SessionCell.swift index fc20532cb..e3b8a568c 100644 --- a/Session/Shared/Views/SessionCell.swift +++ b/Session/Shared/Views/SessionCell.swift @@ -203,6 +203,11 @@ public class SessionCell: UITableViewCell { botSeparatorLeftConstraint = botSeparator.pin(.left, to: .left, of: cellBackgroundView) botSeparatorRightConstraint = botSeparator.pin(.right, to: .right, of: cellBackgroundView) botSeparator.pin(.bottom, to: .bottom, of: cellBackgroundView) + + // Explicitly call this to ensure we have initialised the constraints before we initially + // layout (if we don't do this then some constraints get created for the first time when + // updating the cell before the `isActive` value gets set, resulting in breaking constriants) + prepareForReuse() } public override func layoutSubviews() { diff --git a/SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift b/SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift index 746b42738..38abd6480 100644 --- a/SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift +++ b/SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift @@ -226,9 +226,9 @@ internal extension LibSession { let joinedAt: TimeInterval = { guard let value: Int64 = group.joinedAt else { return 0 } - if value > 9_000_000_000_000 { // Microseconds (after May 1973) + if value > 9_000_000_000_000 { // Microseconds return (Double(value) / 1_000_000) - } else if value > 9_000_000_000 { // Milliseconds (after September 2001) + } else if value > 9_000_000_000 { // Milliseconds return (Double(value) / 1000) } diff --git a/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift b/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift index fbbc07333..0856fc338 100644 --- a/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift +++ b/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift @@ -1084,10 +1084,7 @@ public enum PagedData { // No need to do anything if there were no changes guard !changeset.isEmpty else { return } - // Need to send an event with the changes and then a second event to clear out the `StagedChangeset` - // value otherwise resubscribing will result with the changes coming through a second time valueSubject?.send((updatedData, changeset)) - valueSubject?.send((updatedData, StagedChangeset())) } // No need to dispatch to the next run loop if we are already on the main thread