Skip to content

Commit 470a0e0

Browse files
committed
feat: add intent to generate thumbnails (fixes #298)
1 parent 0acbf09 commit 470a0e0

File tree

4 files changed

+389
-55
lines changed

4 files changed

+389
-55
lines changed

Localizable.xcstrings

Lines changed: 241 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11884,6 +11884,46 @@
1188411884
}
1188511885
}
1188611886
},
11887+
"Folder for which to generate thumbnails" : {
11888+
"localizations" : {
11889+
"de" : {
11890+
"stringUnit" : {
11891+
"state" : "translated",
11892+
"value" : "Ordner, für den Vorschaubilder erstellt werden sollen"
11893+
}
11894+
},
11895+
"es" : {
11896+
"stringUnit" : {
11897+
"state" : "translated",
11898+
"value" : "Carpeta para la que generar miniaturas"
11899+
}
11900+
},
11901+
"it" : {
11902+
"stringUnit" : {
11903+
"state" : "translated",
11904+
"value" : "Cartella per la quale generare le miniature"
11905+
}
11906+
},
11907+
"nl" : {
11908+
"stringUnit" : {
11909+
"state" : "translated",
11910+
"value" : "Map waarvoor miniaturen gegenereerd moeten worden"
11911+
}
11912+
},
11913+
"uk" : {
11914+
"stringUnit" : {
11915+
"state" : "translated",
11916+
"value" : "Папка, для якої потрібно створити ескізи"
11917+
}
11918+
},
11919+
"zh-Hans" : {
11920+
"stringUnit" : {
11921+
"state" : "translated",
11922+
"value" : "生成缩略图的文件夹"
11923+
}
11924+
}
11925+
}
11926+
},
1188711927
"Folder ID" : {
1188811928
"localizations" : {
1188911929
"de" : {
@@ -13856,6 +13896,46 @@
1385613896
}
1385713897
}
1385813898
},
13899+
"How much time to allow for thumbnail generation." : {
13900+
"localizations" : {
13901+
"de" : {
13902+
"stringUnit" : {
13903+
"state" : "translated",
13904+
"value" : "Wie viel Zeit für die Miniaturbildgenerierung einplanen."
13905+
}
13906+
},
13907+
"es" : {
13908+
"stringUnit" : {
13909+
"state" : "translated",
13910+
"value" : "Cuánto tiempo permitir para la generación de miniaturas."
13911+
}
13912+
},
13913+
"it" : {
13914+
"stringUnit" : {
13915+
"state" : "translated",
13916+
"value" : "Quanto tempo dedicare alla generazione delle miniature."
13917+
}
13918+
},
13919+
"nl" : {
13920+
"stringUnit" : {
13921+
"state" : "translated",
13922+
"value" : "Hoeveel tijd te reserveren voor het genereren van miniaturen."
13923+
}
13924+
},
13925+
"uk" : {
13926+
"stringUnit" : {
13927+
"state" : "translated",
13928+
"value" : "Скільки часу виділити на створення ескізів."
13929+
}
13930+
},
13931+
"zh-Hans" : {
13932+
"stringUnit" : {
13933+
"state" : "translated",
13934+
"value" : "生成缩略图需要多长时间。"
13935+
}
13936+
}
13937+
}
13938+
},
1385913939
"HTTP" : {
1386013940
"localizations" : {
1386113941
"de" : {
@@ -27276,6 +27356,86 @@
2727627356
}
2727727357
}
2727827358
},
27359+
"the specified timeout is not valid" : {
27360+
"localizations" : {
27361+
"de" : {
27362+
"stringUnit" : {
27363+
"state" : "translated",
27364+
"value" : "das angegebene Timeout ist ungültig"
27365+
}
27366+
},
27367+
"es" : {
27368+
"stringUnit" : {
27369+
"state" : "translated",
27370+
"value" : "el tiempo de espera especificado no es válido"
27371+
}
27372+
},
27373+
"it" : {
27374+
"stringUnit" : {
27375+
"state" : "translated",
27376+
"value" : "il timeout specificato non è valido"
27377+
}
27378+
},
27379+
"nl" : {
27380+
"stringUnit" : {
27381+
"state" : "translated",
27382+
"value" : "de opgegeven timeout is niet geldig"
27383+
}
27384+
},
27385+
"uk" : {
27386+
"stringUnit" : {
27387+
"state" : "translated",
27388+
"value" : "зазначений тайм-аут недійсний"
27389+
}
27390+
},
27391+
"zh-Hans" : {
27392+
"stringUnit" : {
27393+
"state" : "translated",
27394+
"value" : "指定的超时无效"
27395+
}
27396+
}
27397+
}
27398+
},
27399+
"The subdirectory to generate thumbnails for (empty to rescan the whole folder)" : {
27400+
"localizations" : {
27401+
"de" : {
27402+
"stringUnit" : {
27403+
"state" : "translated",
27404+
"value" : "Das Unterverzeichnis, für das Thumbnails generiert werden sollen (leer lassen, um den gesamten Ordner erneut zu scannen)"
27405+
}
27406+
},
27407+
"es" : {
27408+
"stringUnit" : {
27409+
"state" : "translated",
27410+
"value" : "El subdirectorio para generar miniaturas (déjalo vacío para volver a escanear toda la carpeta)"
27411+
}
27412+
},
27413+
"it" : {
27414+
"stringUnit" : {
27415+
"state" : "translated",
27416+
"value" : "La sottodirectory per cui generare le miniature (lascia vuoto per eseguire una nuova scansione dell'intera cartella)"
27417+
}
27418+
},
27419+
"nl" : {
27420+
"stringUnit" : {
27421+
"state" : "translated",
27422+
"value" : "De submap om miniaturen voor te genereren (leeg laten om de hele map opnieuw te scannen)"
27423+
}
27424+
},
27425+
"uk" : {
27426+
"stringUnit" : {
27427+
"state" : "translated",
27428+
"value" : "Підкаталог для створення ескізів (залиште порожнім, щоб просканувати всю папку)"
27429+
}
27430+
},
27431+
"zh-Hans" : {
27432+
"stringUnit" : {
27433+
"state" : "translated",
27434+
"value" : "生成缩略图的子目录(留空以重新扫描整个文件夹)"
27435+
}
27436+
}
27437+
}
27438+
},
2727927439
"The subdirectory to rescan (empty to rescan the whole folder)" : {
2728027440
"localizations" : {
2728127441
"de" : {
@@ -27596,6 +27756,46 @@
2759627756
}
2759727757
}
2759827758
},
27759+
"there is insufficient disk space free to continue" : {
27760+
"localizations" : {
27761+
"de" : {
27762+
"stringUnit" : {
27763+
"state" : "translated",
27764+
"value" : "es steht nicht genügend freier Speicherplatz zur Verfügung, um fortzufahren"
27765+
}
27766+
},
27767+
"es" : {
27768+
"stringUnit" : {
27769+
"state" : "translated",
27770+
"value" : "no hay suficiente espacio en disco libre para continuar"
27771+
}
27772+
},
27773+
"it" : {
27774+
"stringUnit" : {
27775+
"state" : "translated",
27776+
"value" : "spazio su disco insufficiente per continuare"
27777+
}
27778+
},
27779+
"nl" : {
27780+
"stringUnit" : {
27781+
"state" : "translated",
27782+
"value" : "er is onvoldoende schijfruimte vrij om door te gaan"
27783+
}
27784+
},
27785+
"uk" : {
27786+
"stringUnit" : {
27787+
"state" : "translated",
27788+
"value" : "недостатньо вільного місця на диску для продовження"
27789+
}
27790+
},
27791+
"zh-Hans" : {
27792+
"stringUnit" : {
27793+
"state" : "translated",
27794+
"value" : "磁盘可用空间不足,无法继续"
27795+
}
27796+
}
27797+
}
27798+
},
2759927799
"There is little to no free storage space left on this device." : {
2760027800
"localizations" : {
2760127801
"de" : {
@@ -28808,6 +29008,46 @@
2880829008
}
2880929009
}
2881029010
},
29011+
"thumbnail disk caching is not enabled" : {
29012+
"localizations" : {
29013+
"de" : {
29014+
"stringUnit" : {
29015+
"state" : "translated",
29016+
"value" : "Miniatur-Disk-Cache ist nicht aktiviert"
29017+
}
29018+
},
29019+
"es" : {
29020+
"stringUnit" : {
29021+
"state" : "translated",
29022+
"value" : "la caché de disco en miniatura no está habilitada"
29023+
}
29024+
},
29025+
"it" : {
29026+
"stringUnit" : {
29027+
"state" : "translated",
29028+
"value" : "la memorizzazione nella cache del disco delle miniature non è abilitata"
29029+
}
29030+
},
29031+
"nl" : {
29032+
"stringUnit" : {
29033+
"state" : "translated",
29034+
"value" : "miniatuur-schijfcaching is niet ingeschakeld"
29035+
}
29036+
},
29037+
"uk" : {
29038+
"stringUnit" : {
29039+
"state" : "translated",
29040+
"value" : "кешування мініатюр на диску не ввімкнено"
29041+
}
29042+
},
29043+
"zh-Hans" : {
29044+
"stringUnit" : {
29045+
"state" : "translated",
29046+
"value" : "未启用缩略图磁盘缓存"
29047+
}
29048+
}
29049+
}
29050+
},
2881129051
"Thumbnails" : {
2881229052
"localizations" : {
2881329053
"de" : {
@@ -29191,7 +29431,7 @@
2919129431
"nl" : {
2919229432
"stringUnit" : {
2919329433
"state" : "translated",
29194-
"value" : "Naar subdirectory"
29434+
"value" : "Naar submap"
2919529435
}
2919629436
},
2919729437
"uk" : {

Sushitrain/FolderView.swift

Lines changed: 8 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,62 +1321,16 @@ private struct FolderGenerateThumbnailsView: View {
13211321
private static let thumbnailInterval: TimeInterval = 1.0
13221322

13231323
private func generateFor(prefix: String?) async throws {
1324-
let ic = ImageCache.forFolder(self.folder)
1325-
let tg = FolderSettingsManager.shared.settingsFor(folderID: self.folder.folderID).thumbnailGeneration
1326-
1327-
// If thumbnails are written to a custom folder, also write thumbnails for local images
1328-
let forceCachingLocalFiles: Bool
1329-
switch tg {
1330-
case .global:
1331-
forceCachingLocalFiles = !appState.userSettings.cacheThumbnailsToFolderID.isEmpty
1332-
case .disabled:
1333-
forceCachingLocalFiles = false
1334-
case .deviceLocal:
1335-
forceCachingLocalFiles = false
1336-
case .inside(_):
1337-
forceCachingLocalFiles = true
1338-
}
1339-
1340-
// Iterate over this folder's entries
1341-
let files = try self.folder.list(prefix, directories: false, recurse: false)
1342-
1343-
for idx in 0..<files.count() {
1344-
let filePath = files.item(at: idx)
1345-
if Task.isCancelled {
1346-
Log.info("Thumbnail generate task cancelled")
1347-
return
1348-
}
1349-
1350-
let fullPath = (prefix ?? "") + "/" + filePath
1351-
1352-
if case .inside(path: let insidePath) = tg, fullPath.withoutStartingSlash.starts(with: insidePath) {
1353-
Log.info("Skipping file \(fullPath), inside thumbnail directory")
1354-
continue
1355-
}
1356-
1357-
if let file = try? self.folder.getFileInformation(fullPath) {
1358-
// Recurse into subdirectories (depth-first)
1359-
if file.isDirectory() {
1360-
try await self.generateFor(prefix: file.path())
1361-
}
1362-
1363-
// Generate thumbnail for files that are not locally present (otherwise QuickLook will manage it for us)
1364-
// except when we are writing to a custom thumbnail folder (this device can then generate thumbnails for
1365-
// another from local files)
1366-
if file.canThumbnail && (forceCachingLocalFiles || !file.isLocallyPresent()) {
1367-
let thumb = await ic.getThumbnail(file: file, forceCache: forceCachingLocalFiles)
1368-
1369-
if (-lastThumbnailTime.timeIntervalSinceNow) > Self.thumbnailInterval {
1370-
lastThumbnailTime = Date.now
1371-
self.lastThumbnail = thumb
1372-
}
1324+
let tg = FolderSettingsManager.shared.settingsFor(folderID: folder.folderID).thumbnailGeneration
1325+
try await generateThumbnailsFor(
1326+
folder: self.folder, prefix: prefix, userSettings: appState.userSettings, generation: tg,
1327+
callback: { thumb in
1328+
if (-lastThumbnailTime.timeIntervalSinceNow) > Self.thumbnailInterval {
1329+
lastThumbnailTime = Date.now
1330+
self.lastThumbnail = thumb
13731331
}
13741332
self.processedFiles += 1
1375-
}
1376-
else {
1377-
Log.warn("Could not get file entry for path \(filePath)")
1378-
}
1379-
}
1333+
})
13801334
}
13811335
}
13821336

0 commit comments

Comments
 (0)