Add internal setting to force regeneration of backup thumbnails

This commit is contained in:
Pete Walters 2026-06-02 14:00:50 -05:00 committed by GitHub
parent feba86dbfb
commit 78130adac7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 7 deletions

View File

@ -65,6 +65,17 @@ class InternalBackupSettingsViewController: OWSTableViewController2 {
self?.navigationController?.pushViewController(vc, animated: true)
})
if RemoteConfig.current.isOptimizeStorageEnabled {
section.add(.switch(
withText: "Regenerate backup thumbnails",
subtitle: "Regenerate backup thumbnails on next offloading run",
isOn: { db.read(block: backupSettingsStore.shouldGenerateThumbnailsOnNextOffloading(tx:)) },
actionBlock: { _ in
db.write { tx in
let currentValue = backupSettingsStore.shouldGenerateThumbnailsOnNextOffloading(tx: tx)
backupSettingsStore.setShouldGenerateThumbnailsOnNextOffloading(!currentValue, tx: tx)
}
},
))
section.add(.switch(
withText: "Aggressive optimize media",
subtitle: "Don't keep recent attachments when optimize media is enabled",

View File

@ -124,6 +124,8 @@ public class AttachmentOffloadingManagerImpl: AttachmentOffloadingManager {
throw NeedsListMediaError()
}
let forceThumbnailGeneration = db.read(block: backupSettingsStore.shouldGenerateThumbnailsOnNextOffloading(tx:))
let (candidateAttachments, didHitEnd) = try db.read { tx -> ([Attachment], Bool) in
guard offloadingIsAllowed(tx: tx) else {
return ([], false)
@ -176,7 +178,12 @@ public class AttachmentOffloadingManagerImpl: AttachmentOffloadingManager {
)
{
attachments.append(attachment)
if self.thumbnailableAttachment(attachment) != nil {
if
self.thumbnailableAttachment(
attachment,
ignoreExisting: forceThumbnailGeneration,
) != nil
{
numAttachmentsNeedingThumbnail += 1
}
}
@ -201,10 +208,15 @@ public class AttachmentOffloadingManagerImpl: AttachmentOffloadingManager {
return nil
}
try await downloadExistingThumbnails(candidateAttachments)
if !forceThumbnailGeneration {
try await downloadExistingThumbnails(candidateAttachments)
}
// Generate if we can't download
let pendingThumbnails = try await generateThumbnails(candidateAttachments)
let pendingThumbnails = try await generateThumbnails(
candidateAttachments,
ignoreExisting: forceThumbnailGeneration,
)
await db.awaitableWrite { tx in
guard offloadingIsAllowed(tx: tx) else {
@ -278,6 +290,9 @@ public class AttachmentOffloadingManagerImpl: AttachmentOffloadingManager {
}
if didHitEnd {
await db.awaitableWrite { tx in
backupSettingsStore.setShouldGenerateThumbnailsOnNextOffloading(false, tx: tx)
}
return nil
} else {
return candidateAttachments.last?.id
@ -358,9 +373,12 @@ public class AttachmentOffloadingManagerImpl: AttachmentOffloadingManager {
}
/// Returns nil if the attachment cannot or does not need to be thumbnailed.
private func thumbnailableAttachment(_ attachment: Attachment) -> ThumbnailableAttachment? {
private func thumbnailableAttachment(
_ attachment: Attachment,
ignoreExisting: Bool,
) -> ThumbnailableAttachment? {
guard
attachment.localRelativeFilePathThumbnail == nil,
(ignoreExisting || attachment.localRelativeFilePathThumbnail == nil),
AttachmentBackupThumbnail.canBeThumbnailed(attachment),
let stream = attachment.asStream(),
let mediaName = attachment.mediaName
@ -403,8 +421,13 @@ public class AttachmentOffloadingManagerImpl: AttachmentOffloadingManager {
}
}
private func generateThumbnails(_ attachments: [Attachment]) async throws -> [Attachment.IDType: PendingThumbnail] {
let attachments = attachments.compactMap(self.thumbnailableAttachment(_:))
private func generateThumbnails(
_ attachments: [Attachment],
ignoreExisting: Bool,
) async throws -> [Attachment.IDType: PendingThumbnail] {
let attachments = attachments.compactMap {
self.thumbnailableAttachment($0, ignoreExisting: ignoreExisting)
}
if attachments.isEmpty {
return [:]
}

View File

@ -60,6 +60,7 @@ public struct BackupSettingsStore {
private enum Keys {
static let haveEverBeenEnabled = "haveEverBeenEnabledKey2"
static let shouldOverrideShowBackupsOnboarding = "shouldOverrideShowBackupsOnboarding"
static let shouldGenerateThumbnailsOnNextOffloading = "shouldGenerateThumbnailsOnNextOffloading"
static let plan = "planKey2"
static let firstBackupDate = "firstBackupDate"
static let lastBackupDate = "lastBackupDate"
@ -113,6 +114,20 @@ public struct BackupSettingsStore {
kvStore.setBool(value, key: Keys.shouldOverrideShowBackupsOnboarding, transaction: tx)
}
/// Whether to force generation/upload of new thumbnails during the next offloading of attachment.
///
/// Not intended for production use.
public func shouldGenerateThumbnailsOnNextOffloading(tx: DBReadTransaction) -> Bool {
return kvStore.getBool(Keys.shouldGenerateThumbnailsOnNextOffloading, defaultValue: false, transaction: tx)
}
/// Set an override to force generation/upload of new thumbnails during the next offloading of attachment.
///
/// Not intended for production use.
public func setShouldGenerateThumbnailsOnNextOffloading(_ value: Bool, tx: DBWriteTransaction) {
kvStore.setBool(value, key: Keys.shouldGenerateThumbnailsOnNextOffloading, transaction: tx)
}
// MARK: - BackupPlan
/// This device's view of the user's current Backup plan. A return value of