Fixed a few bugs

• Updated to the latest libSession
• Fixed some warnings
• Fixed a compilation issue on non-debug builds
• Fixed an issue with the dev settings data importer when ignoring hidden files from old exports (wouldn't move the inputStream forward correctly resulting in a crash)
• Fixed an issue where the swarm poller wasn't included synchronously processed messages in it's publisher output
pull/894/head
Morgan Pretty 2 months ago
parent 811528bfd5
commit d91af1b5b6

@ -1 +1 @@
Subproject commit 4651fe174e79f10a58d07f748fcabfd145ccb0bd
Subproject commit 1ce161d98ada8f154cb8fd0e14458d65d85bc944

@ -386,7 +386,7 @@ final class ConversationVC: BaseVC, LibSessionRespondingViewController, Conversa
private lazy var legacyGroupsFooterButton: SessionButton = {
let result: SessionButton = SessionButton(style: .bordered, size: .large)
result.translatesAutoresizingMaskIntoConstraints = false
result.setTitle("Recreate Group", for: .normal)
result.setTitle("recreateGroup".localized(), for: .normal)
result.addTarget(self, action: #selector(recreateLegacyGroupTapped), for: .touchUpInside)
result.accessibilityIdentifier = "Legacy Groups Recreate Button"
@ -823,7 +823,7 @@ final class ConversationVC: BaseVC, LibSessionRespondingViewController, Conversa
let messageRequestsViewWasVisible: Bool = (self.messageRequestFooterView.isHidden == false)
UIView.animate(withDuration: 0.3) { [weak self, dependencies = viewModel.dependencies] in
UIView.animate(withDuration: 0.3) { [weak self] in
self?.messageRequestFooterView.update(
threadVariant: updatedThreadData.threadVariant,
canWrite: (updatedThreadData.threadCanWrite == true),
@ -1585,16 +1585,14 @@ final class ConversationVC: BaseVC, LibSessionRespondingViewController, Conversa
return
}
self.outdatedClientBanner.update(
message: "disappearingMessagesLegacy"
.put(
key: "name",
value: Profile.displayName(
let profileDispalyName: String = Profile.displayName(
id: outdatedMemberId,
threadVariant: self.viewModel.threadData.threadVariant,
using: viewModel.dependencies
)
)
self.outdatedClientBanner.update(
message: "disappearingMessagesLegacy"
.put(key: "name", value: profileDispalyName)
.localizedFormatted(baseFont: self.outdatedClientBanner.font),
onTap: { [weak self] in self?.removeOutdatedClientBanner() }
)

@ -76,7 +76,7 @@ public class ConversationViewModel: OWSAudioPlayerDelegate, NavigatableStateHold
}
// FIXME: Strings should be updated in Crowdin to include the {icon}
return localizationKey
return LocalizationHelper(template: localizationKey)
.put(key: "date", value: Features.legacyGroupDepricationDate.formattedForBanner)
.localizedFormatted(baseFont: legacyGroupsBannerFont)
.appending(string: " ") // Designs have a space before the icon

@ -58,12 +58,12 @@ public extension LibSession {
var count: Int {
switch self {
case .userProfile(let conf): return 1
case .userProfile: return 1
case .contacts(let conf): return contacts_size(conf)
case .convoInfoVolatile(let conf): return convo_info_volatile_size(conf)
case .userGroups(let conf): return user_groups_size(conf)
case .groupInfo(let conf): return 1
case .groupInfo: return 1
case .groupMembers(let conf): return groups_members_size(conf)
case .groupKeys(let conf, _, _): return groups_keys_size(conf)
}

@ -150,7 +150,7 @@ public class SwarmPoller: SwarmPollerType & PollerType {
.compactMap { $0.value.data?.messages.map { $0.info.hash } }
.reduce([], +)
var messageCount: Int = 0
var processedMessages: [ProcessedMessage] = []
var finalProcessedMessages: [ProcessedMessage] = []
var hadValidHashUpdate: Bool = false
return dependencies[singleton: .storage].writePublisher { db -> (configMessageJobs: [Job], standardMessageJobs: [Job], pollResult: PollResult) in
@ -258,6 +258,9 @@ public class SwarmPoller: SwarmPollerType & PollerType {
}
}
/// Make sure to add any synchronously processed messages to the `finalProcessedMessages`
/// as otherwise they wouldn't be emitted by the `receivedPollResponseSubject`
finalProcessedMessages += processedMessages
return nil
}
.flatMap { $0 }
@ -266,8 +269,8 @@ public class SwarmPoller: SwarmPollerType & PollerType {
// to create message receive jobs or mess with cached hashes)
guard shouldStoreMessages else {
messageCount += allProcessedMessages.count
processedMessages += allProcessedMessages
return ([], [], (processedMessages, rawMessageCount, messageCount, hadValidHashUpdate))
finalProcessedMessages += allProcessedMessages
return ([], [], (finalProcessedMessages, rawMessageCount, messageCount, hadValidHashUpdate))
}
// Add a job to process the config messages first
@ -276,7 +279,7 @@ public class SwarmPoller: SwarmPollerType & PollerType {
.grouped { $0.threadId }
.compactMap { threadId, threadMessages in
messageCount += threadMessages.count
processedMessages += threadMessages
finalProcessedMessages += threadMessages
let job: Job? = Job(
variant: .configMessageReceive,
@ -306,7 +309,7 @@ public class SwarmPoller: SwarmPollerType & PollerType {
.grouped { $0.threadId }
.compactMap { threadId, threadMessages in
messageCount += threadMessages.count
processedMessages += threadMessages
finalProcessedMessages += threadMessages
let job: Job? = Job(
variant: .messageReceive,
@ -360,7 +363,7 @@ public class SwarmPoller: SwarmPollerType & PollerType {
otherKnownValidHashes: otherKnownHashes
)
return (configMessageJobs, standardMessageJobs, (processedMessages, rawMessageCount, messageCount, hadValidHashUpdate))
return (configMessageJobs, standardMessageJobs, (finalProcessedMessages, rawMessageCount, messageCount, hadValidHashUpdate))
}
}
.flatMap { [dependencies] (configMessageJobs: [Job], standardMessageJobs: [Job], pollResult: PollResult) -> AnyPublisher<PollResult, Error> in

@ -717,7 +717,7 @@ open class Storage {
semaphoreResult = semaphore.wait(timeout: .now() + .seconds(Storage.transactionDeadlockTimeoutSeconds))
}
#else
semaphoreResult = semaphore?.wait(timeout: .now() + .seconds(Storage.transactionDeadlockTimeoutSeconds))
semaphoreResult = semaphore.wait(timeout: .now() + .seconds(Storage.transactionDeadlockTimeoutSeconds))
#endif
/// If the query timed out then we should interrupt the query (don't want the query thread to remain blocked when we've

@ -284,32 +284,36 @@ public class DirectoryArchiver {
encryptedFileSize
)
// Read and decrypt file content
let outputStream: OutputStream?
let isHiddenFile: Bool = URL(fileURLWithPath: relativePath).lastPathComponent.starts(with: ".")
defer { outputStream?.close() }
switch isHiddenFile {
case true:
// If the file is a hidden file (shouldn't be possible anymore but old backups had this
// issue) then just skip the file - any hidden files are from Apple and seem to fail to
// decrypt causing the entire import to fail
guard !URL(fileURLWithPath: relativePath).lastPathComponent.starts(with: ".") else {
//
// Note: We still need to process the file in order to ensure the inputStream is moved
// the correct amount, otherwise out byte alignment could be off which will result in
// at best a failed import, but more likely a crash due to invalid size data
Log.warn(.cat, "Skipping hidden file to avoid breaking the import: \(relativePath)")
skippedFilePaths.append(fullPath)
outputStream = nil
// Update the progress
fileAmountProcessed += fileSize
progressChanged?(
(filePaths.count + skippedFilePaths.count + additionalFilePaths.count),
Int(expectedFileCount + expectedAdditionalFileCount),
fileAmountProcessed,
encryptedFileSize
)
continue
}
case false:
// It's a valid file so ensure the OutputStream was opened successfully
outputStream = OutputStream(toFileAtPath: fullPath, append: false)
outputStream?.open()
// Read and decrypt file content
guard let outputStream: OutputStream = OutputStream(toFileAtPath: fullPath, append: false) else {
guard outputStream != nil else {
Log.error(.cat, "Failed to create output stream")
throw ArchiveError.unarchiveFailed
}
outputStream.open()
defer { outputStream.close() }
}
// Process the file chunk by chunk
var remainingFileSize: Int = Int(fileSize)
while remainingFileSize > 0 {
let (chunk, chunkSizeBytesRead, encryptedSize): ([UInt8], Int, UInt32) = try read(
@ -318,7 +322,7 @@ public class DirectoryArchiver {
)
// Write to the output
outputStream.write(chunk, maxLength: chunk.count)
outputStream?.write(chunk, maxLength: chunk.count)
remainingFileSize -= chunk.count
// Update the progress
@ -332,9 +336,10 @@ public class DirectoryArchiver {
}
// Store the file path info and update the progress
switch isExtraFile {
case false: filePaths.append(fullPath)
case true: additionalFilePaths.append(fullPath)
switch (isExtraFile, isHiddenFile) {
case (_, true): break
case (false, false): filePaths.append(fullPath)
case (true, false): additionalFilePaths.append(fullPath)
}
progressChanged?(
(filePaths.count + skippedFilePaths.count + additionalFilePaths.count),

@ -165,7 +165,7 @@ class TypeConversionUtilitiesSpec: QuickSpec {
// MARK: ---- returns an empty string when null and not set to return null
it("returns an empty string when null and not set to return null") {
var test: TestClass = TestClass()
let test: TestClass = TestClass()
let result: String? = test.get(\.testString, nullIfEmpty: false)
expect(result).to(equal(""))
@ -173,7 +173,7 @@ class TypeConversionUtilitiesSpec: QuickSpec {
// MARK: ---- returns null when specified and empty
it("returns null when specified and empty") {
var test: TestClass = TestClass()
let test: TestClass = TestClass()
let result: String? = test.get(\.testString, nullIfEmpty: true)
expect(result).to(beNil())
@ -181,7 +181,7 @@ class TypeConversionUtilitiesSpec: QuickSpec {
// MARK: ---- defaults the null if empty flag to false
it("defaults the null if empty flag to false") {
var test: TestClass = TestClass()
let test: TestClass = TestClass()
let result: String? = test.get(\.testString)
expect(result).to(equal(""))

Loading…
Cancel
Save