diff --git a/client/components/app/Appbar.vue b/client/components/app/Appbar.vue index 92599c7a..c281f821 100644 --- a/client/components/app/Appbar.vue +++ b/client/components/app/Appbar.vue @@ -320,9 +320,11 @@ export default { checkboxLabel: this.$strings.LabelDeleteFromFileSystemCheckbox, yesButtonText: this.$strings.ButtonDelete, yesButtonColor: 'error', - checkboxDefaultValue: true, + checkboxDefaultValue: !Number(localStorage.getItem('softDeleteDefault') || 0), callback: (confirmed, hardDelete) => { if (confirmed) { + localStorage.setItem('softDeleteDefault', hardDelete ? 0 : 1) + this.$store.commit('setProcessingBatch', true) this.$axios diff --git a/client/components/cards/AuthorCard.vue b/client/components/cards/AuthorCard.vue index db4e7e9a..fc3bc4b2 100644 --- a/client/components/cards/AuthorCard.vue +++ b/client/components/cards/AuthorCard.vue @@ -8,7 +8,7 @@

{{ name }}

-

{{ numBooks }} Book{{ numBooks === 1 ? '' : 's' }}

+

{{ numBooks }} {{ $strings.LabelBooks }}

diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index 1b87df0f..c4d1345d 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -848,9 +848,11 @@ export default { checkboxLabel: this.$strings.LabelDeleteFromFileSystemCheckbox, yesButtonText: this.$strings.ButtonDelete, yesButtonColor: 'error', - checkboxDefaultValue: true, + checkboxDefaultValue: !Number(localStorage.getItem('softDeleteDefault') || 0), callback: (confirmed, hardDelete) => { if (confirmed) { + localStorage.setItem('softDeleteDefault', hardDelete ? 0 : 1) + this.processing = true const axios = this.$axios || this.$nuxt.$axios axios diff --git a/client/components/modals/item/tabs/Files.vue b/client/components/modals/item/tabs/Files.vue index 4081f98c..7be286fe 100644 --- a/client/components/modals/item/tabs/Files.vue +++ b/client/components/modals/item/tabs/Files.vue @@ -14,8 +14,7 @@ export default { }, data() { return { - tracks: [], - showFullPath: false + tracks: [] } }, watch: { diff --git a/client/components/tables/EbookFilesTable.vue b/client/components/tables/EbookFilesTable.vue index 0c85774c..3532c2a7 100644 --- a/client/components/tables/EbookFilesTable.vue +++ b/client/components/tables/EbookFilesTable.vue @@ -6,7 +6,7 @@ {{ ebookFiles.length }}
- +
expand_more
@@ -75,6 +75,10 @@ export default { } }, methods: { + toggleFullPath() { + this.showFullPath = !this.showFullPath + localStorage.setItem('showFullPath', this.showFullPath ? 1 : 0) + }, readEbook(fileIno) { this.$store.commit('showEReader', { libraryItem: this.libraryItem, keepProgress: false, fileId: fileIno }) }, @@ -82,6 +86,10 @@ export default { this.showFiles = !this.showFiles } }, - mounted() {} + mounted() { + if (this.userIsAdmin) { + this.showFullPath = !!Number(localStorage.getItem('showFullPath') || 0) + } + } } \ No newline at end of file diff --git a/client/components/tables/LibraryFilesTable.vue b/client/components/tables/LibraryFilesTable.vue index c6c8c777..fef1ae5a 100644 --- a/client/components/tables/LibraryFilesTable.vue +++ b/client/components/tables/LibraryFilesTable.vue @@ -6,7 +6,7 @@ {{ files.length }}
- +
expand_more
@@ -84,6 +84,10 @@ export default { } }, methods: { + toggleFullPath() { + this.showFullPath = !this.showFullPath + localStorage.setItem('showFullPath', this.showFullPath ? 1 : 0) + }, clickBar() { this.showFiles = !this.showFiles }, @@ -93,6 +97,9 @@ export default { } }, mounted() { + if (this.userIsAdmin) { + this.showFullPath = !!Number(localStorage.getItem('showFullPath') || 0) + } this.showFiles = this.expanded } } diff --git a/client/components/tables/TracksTable.vue b/client/components/tables/TracksTable.vue index 2554fff1..5730ee36 100644 --- a/client/components/tables/TracksTable.vue +++ b/client/components/tables/TracksTable.vue @@ -6,7 +6,7 @@ {{ tracks.length }}
- + {{ $strings.ButtonManageTracks }} @@ -74,6 +74,10 @@ export default { } }, methods: { + toggleFullPath() { + this.showFullPath = !this.showFullPath + localStorage.setItem('showFullPath', this.showFullPath ? 1 : 0) + }, clickBar() { this.showTracks = !this.showTracks }, @@ -82,6 +86,10 @@ export default { this.showAudioFileDataModal = true } }, - mounted() {} + mounted() { + if (this.userIsAdmin) { + this.showFullPath = !!Number(localStorage.getItem('showFullPath') || 0) + } + } } \ No newline at end of file diff --git a/client/components/tables/collection/BookTableRow.vue b/client/components/tables/collection/BookTableRow.vue index 399c429a..110edcb9 100644 --- a/client/components/tables/collection/BookTableRow.vue +++ b/client/components/tables/collection/BookTableRow.vue @@ -30,7 +30,7 @@ >
-

{{ bookDuration }}

+

{{ bookDuration }}

diff --git a/client/pages/item/_id/index.vue b/client/pages/item/_id/index.vue index 657d564d..8658a6e4 100644 --- a/client/pages/item/_id/index.vue +++ b/client/pages/item/_id/index.vue @@ -686,9 +686,11 @@ export default { checkboxLabel: this.$strings.LabelDeleteFromFileSystemCheckbox, yesButtonText: this.$strings.ButtonDelete, yesButtonColor: 'error', - checkboxDefaultValue: true, + checkboxDefaultValue: !Number(localStorage.getItem('softDeleteDefault') || 0), callback: (confirmed, hardDelete) => { if (confirmed) { + localStorage.setItem('softDeleteDefault', hardDelete ? 0 : 1) + this.$axios .$delete(`/api/items/${this.libraryItemId}?hard=${hardDelete ? 1 : 0}`) .then(() => { diff --git a/client/strings/it.json b/client/strings/it.json index 747d7420..c893212e 100644 --- a/client/strings/it.json +++ b/client/strings/it.json @@ -1,10 +1,10 @@ { "ButtonAdd": "Aggiungi", "ButtonAddChapters": "Aggiungi Capitoli", - "ButtonAddDevice": "Add Device", - "ButtonAddLibrary": "Add Library", + "ButtonAddDevice": "Aggiungi Dispositivo", + "ButtonAddLibrary": "Aggiungi Libreria", "ButtonAddPodcasts": "Aggiungi Podcast", - "ButtonAddUser": "Add User", + "ButtonAddUser": "Aggiungi User", "ButtonAddYourFirstLibrary": "Aggiungi la tua prima libreria", "ButtonApply": "Applica", "ButtonApplyChapters": "Applica", @@ -62,7 +62,7 @@ "ButtonRemoveSeriesFromContinueSeries": "Rimuovi la Serie per Continuarla", "ButtonReScan": "Ri-scansiona", "ButtonReset": "Reset", - "ButtonResetToDefault": "Reset to default", + "ButtonResetToDefault": "Ripristino di default", "ButtonRestore": "Ripristina", "ButtonSave": "Salva", "ButtonSaveAndClose": "Salva & Chiudi", @@ -75,7 +75,7 @@ "ButtonSetChaptersFromTracks": "Impostare i capitoli dalle tracce", "ButtonShiftTimes": "Ricerca veloce", "ButtonShow": "Mostra", - "ButtonStartM4BEncode": "Inizia L'Encoda del M4B", + "ButtonStartM4BEncode": "Inizia L'Encode del M4B", "ButtonStartMetadataEmbed": "Inizia Incorporo Metadata", "ButtonSubmit": "Invia", "ButtonTest": "Test", @@ -102,7 +102,7 @@ "HeaderCurrentDownloads": "Download Correnti", "HeaderDetails": "Dettagli", "HeaderDownloadQueue": "Download Queue", - "HeaderEbookFiles": "Ebook Files", + "HeaderEbookFiles": "Ebook File", "HeaderEmail": "Email", "HeaderEmailSettings": "Email Settings", "HeaderEpisodes": "Episodi", @@ -161,7 +161,7 @@ "HeaderStatsRecentSessions": "Sessioni Recenti", "HeaderStatsTop10Authors": "Top 10 Autori", "HeaderStatsTop5Genres": "Top 5 Generi", - "HeaderTableOfContents": "Tabellla dei Contenuti", + "HeaderTableOfContents": "Tabella dei Contenuti", "HeaderTools": "Strumenti", "HeaderUpdateAccount": "Aggiorna Account", "HeaderUpdateAuthor": "Aggiorna Autore", @@ -181,11 +181,11 @@ "LabelAddToCollectionBatch": "Aggiungi {0} Libri alla Raccolta", "LabelAddToPlaylist": "aggiungi alla Playlist", "LabelAddToPlaylistBatch": "Aggiungi {0} file alla Playlist", - "LabelAdminUsersOnly": "Admin users only", + "LabelAdminUsersOnly": "Solo utenti Amministratori", "LabelAll": "Tutti", "LabelAllUsers": "Tutti gli Utenti", - "LabelAllUsersExcludingGuests": "All users excluding guests", - "LabelAllUsersIncludingGuests": "All users including guests", + "LabelAllUsersExcludingGuests": "Tutti gli Utenti Esclusi gli ospiti", + "LabelAllUsersIncludingGuests": "Tutti gli Utenti Inclusi gli ospiti", "LabelAlreadyInYourLibrary": "Già esistente nella libreria", "LabelAppend": "Appese", "LabelAuthor": "Autore", @@ -194,7 +194,7 @@ "LabelAuthors": "Autori", "LabelAutoDownloadEpisodes": "Auto Download Episodi", "LabelBackToUser": "Torna a Utenti", - "LabelBackupLocation": "Backup Location", + "LabelBackupLocation": "Percorso del Backup", "LabelBackupsEnableAutomaticBackups": "Abilita backup Automatico", "LabelBackupsEnableAutomaticBackupsHelp": "I Backup saranno salvati in /metadata/backups", "LabelBackupsMaxBackupSize": "Dimensione massima backup (in GB)", @@ -208,11 +208,11 @@ "LabelChapters": "Capitoli", "LabelChaptersFound": "Capitoli Trovati", "LabelChapterTitle": "Titoli dei Capitoli", - "LabelClickForMoreInfo": "Click for more info", + "LabelClickForMoreInfo": "Click per altre Info", "LabelClosePlayer": "Chiudi player", "LabelCodec": "Codec", "LabelCollapseSeries": "Comprimi Serie", - "LabelCollection": "Collection", + "LabelCollection": "Raccolta", "LabelCollections": "Raccolte", "LabelComplete": "Completo", "LabelConfirmPassword": "Conferma Password", @@ -220,23 +220,23 @@ "LabelContinueReading": "Continua la Lettura", "LabelContinueSeries": "Continua Serie", "LabelCover": "Cover", - "LabelCoverImageURL": "Cover Image URL", + "LabelCoverImageURL": "Indirizzo della cover URL", "LabelCreatedAt": "Creato A", "LabelCronExpression": "Espressione Cron", "LabelCurrent": "Attuale", "LabelCurrently": "Attualmente:", - "LabelCustomCronExpression": "Custom Cron Expression:", + "LabelCustomCronExpression": "Espressione Cron personalizzata:", "LabelDatetime": "Data & Ora", - "LabelDeleteFromFileSystemCheckbox": "Delete from file system (uncheck to only remove from database)", + "LabelDeleteFromFileSystemCheckbox": "Elimina dal file system (togli la spunta per eliminarla solo dal DB)", "LabelDescription": "Descrizione", "LabelDeselectAll": "Deseleziona Tutto", "LabelDevice": "Dispositivo", "LabelDeviceInfo": "Info Dispositivo", - "LabelDeviceIsAvailableTo": "Device is available to...", + "LabelDeviceIsAvailableTo": "Il dispositivo e disponibile su...", "LabelDirectory": "Elenco", "LabelDiscFromFilename": "Disco dal nome file", "LabelDiscFromMetadata": "Disco dal Metadata", - "LabelDiscover": "Discover", + "LabelDiscover": "Scopri", "LabelDownload": "Download", "LabelDownloadNEpisodes": "Download {0} episodes", "LabelDuration": "Durata", @@ -278,7 +278,7 @@ "LabelHost": "Host", "LabelHour": "Ora", "LabelIcon": "Icona", - "LabelImageURLFromTheWeb": "Image URL from the web", + "LabelImageURLFromTheWeb": "Immagine URL da internet", "LabelIncludeInTracklist": "Includi nella Tracklist", "LabelIncomplete": "Incompleta", "LabelInProgress": "In Corso", @@ -303,14 +303,14 @@ "LabelLastUpdate": "Ultimo Aggiornamento", "LabelLayout": "Layout", "LabelLayoutSinglePage": "Pagina Singola", - "LabelLayoutSplitPage": "DIvidi Pagina", + "LabelLayoutSplitPage": "Dividi Pagina", "LabelLess": "Poco", "LabelLibrariesAccessibleToUser": "Librerie Accessibili agli Utenti", "LabelLibrary": "Libreria", "LabelLibraryItem": "Elementi della Library", "LabelLibraryName": "Nome Libreria", "LabelLimit": "Limiti", - "LabelLineSpacing": "Line spacing", + "LabelLineSpacing": "Interlinea", "LabelListenAgain": "Ri-ascolta", "LabelLogLevelDebug": "Debug", "LabelLogLevelInfo": "Info", @@ -318,7 +318,7 @@ "LabelLookForNewEpisodesAfterDate": "Cerca nuovi episodi dopo questa data", "LabelMediaPlayer": "Media Player", "LabelMediaType": "Tipo Media", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "1 e bassa priorità, 5 è alta priorità", "LabelMetadataProvider": "Metadata Provider", "LabelMetaTag": "Meta Tag", "LabelMetaTags": "Meta Tags", @@ -398,7 +398,7 @@ "LabelSeason": "Stagione", "LabelSelectAllEpisodes": "Seleziona tutti gli Episodi", "LabelSelectEpisodesShowing": "Episodi {0} selezionati ", - "LabelSelectUsers": "Select users", + "LabelSelectUsers": "Selezione Utenti", "LabelSendEbookToDevice": "Invia ebook a...", "LabelSequence": "Sequenza", "LabelSeries": "Serie", @@ -414,9 +414,9 @@ "LabelSettingsDisableWatcher": "Disattiva Watcher", "LabelSettingsDisableWatcherForLibrary": "Disattiva Watcher per le librerie", "LabelSettingsDisableWatcherHelp": "Disattiva il controllo automatico libri nelle cartelle delle librerie. *Richiede il Riavvio del Server", - "LabelSettingsEnableWatcher": "Enable Watcher", - "LabelSettingsEnableWatcherForLibrary": "Enable folder watcher for library", - "LabelSettingsEnableWatcherHelp": "Enables the automatic adding/updating of items when file changes are detected. *Requires server restart", + "LabelSettingsEnableWatcher": "Abilita Watcher", + "LabelSettingsEnableWatcherForLibrary": "Abilita il controllo cartelle per la libreria", + "LabelSettingsEnableWatcherHelp": "Abilita l'aggiunta/aggiornamento automatico degli elementi quando vengono rilevate modifiche ai file. *Richiede il riavvio del Server", "LabelSettingsExperimentalFeatures": "Opzioni Sperimentali", "LabelSettingsExperimentalFeaturesHelp": "Funzionalità in fase di sviluppo che potrebbero utilizzare i tuoi feedback e aiutare i test. Fare clic per aprire la discussione github.", "LabelSettingsFindCovers": "Trova covers", @@ -471,8 +471,8 @@ "LabelTagsNotAccessibleToUser": "Tags non accessibile agli Utenti", "LabelTasks": "Processi in esecuzione", "LabelTheme": "Tema", - "LabelThemeDark": "Dark", - "LabelThemeLight": "Light", + "LabelThemeDark": "Scuro", + "LabelThemeLight": "Chiaro", "LabelTimeBase": "Time Base", "LabelTimeListened": "Tempo di Ascolto", "LabelTimeListenedToday": "Tempo di Ascolto Oggi", @@ -532,21 +532,21 @@ "MessageChapterErrorStartLtPrev": "L'ora di inizio non valida deve essere maggiore o uguale all'ora di inizio del capitolo precedente", "MessageChapterStartIsAfter": "L'inizio del capitolo è dopo la fine del tuo audiolibro", "MessageCheckingCron": "Controllo cron...", - "MessageConfirmCloseFeed": "Are you sure you want to close this feed?", + "MessageConfirmCloseFeed": "Sei sicuro di voler chiudere questo feed?", "MessageConfirmDeleteBackup": "Sei sicuro di voler eliminare il backup {0}?", "MessageConfirmDeleteFile": "Questo eliminerà il file dal tuo file system. Sei sicuro?", "MessageConfirmDeleteLibrary": "Sei sicuro di voler eliminare definitivamente la libreria \"{0}\"?", - "MessageConfirmDeleteLibraryItem": "This will delete the library item from the database and your file system. Are you sure?", - "MessageConfirmDeleteLibraryItems": "This will delete {0} library items from the database and your file system. Are you sure?", + "MessageConfirmDeleteLibraryItem": " l'elemento della libreria dal database e dal file system. Sei sicuro?", + "MessageConfirmDeleteLibraryItems": "Ciò eliminerà {0} elementi della libreria dal database e dal file system. Sei sicuro?", "MessageConfirmDeleteSession": "Sei sicuro di voler eliminare questa sessione?", "MessageConfirmForceReScan": "Sei sicuro di voler forzare una nuova scansione?", "MessageConfirmMarkAllEpisodesFinished": "Sei sicuro di voler contrassegnare tutti gli episodi come finiti?", - "MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?", + "MessageConfirmMarkAllEpisodesNotFinished": "Sei sicuro di voler contrassegnare tutti gli episodi come non completati?", "MessageConfirmMarkSeriesFinished": "Sei sicuro di voler contrassegnare tutti i libri di questa serie come completati?", "MessageConfirmMarkSeriesNotFinished": "Sei sicuro di voler contrassegnare tutti i libri di questa serie come non completati?", - "MessageConfirmQuickEmbed": "Warning! Quick embed will not backup your audio files. Make sure that you have a backup of your audio files.

Would you like to continue?", + "MessageConfirmQuickEmbed": "Attenzione! L'incorporamento rapido non eseguirà il backup dei file audio. Assicurati di avere un backup dei tuoi file audio.

Vuoi Continuare?", "MessageConfirmRemoveAllChapters": "Sei sicuro di voler rimuovere tutti i capitoli?", - "MessageConfirmRemoveAuthor": "Are you sure you want to remove author \"{0}\"?", + "MessageConfirmRemoveAuthor": "Sei sicuro di voler rimuovere l'autore? \"{0}\"?", "MessageConfirmRemoveCollection": "Sei sicuro di voler rimuovere la Raccolta \"{0}\"?", "MessageConfirmRemoveEpisode": "Sei sicuro di voler rimuovere l'episodio \"{0}\"?", "MessageConfirmRemoveEpisodes": "Sei sicuro di voler rimuovere {0} episodi?", @@ -558,7 +558,7 @@ "MessageConfirmRenameTag": "Sei sicuro di voler rinominare il tag \"{0}\" in \"{1}\" per tutti gli oggetti?", "MessageConfirmRenameTagMergeNote": "Nota: Questo tag esiste già e verrà unito nel vecchio.", "MessageConfirmRenameTagWarning": "Avvertimento! Esiste già un tag simile con un nome simile \"{0}\".", - "MessageConfirmReScanLibraryItems": "Are you sure you want to re-scan {0} items?", + "MessageConfirmReScanLibraryItems": "Sei sicuro di voler ripetere la scansione? {0} oggetti?", "MessageConfirmSendEbookToDevice": "Sei sicuro di voler inviare {0} ebook \"{1}\" al Device \"{2}\"?", "MessageDownloadingEpisode": "Download episodio in corso", "MessageDragFilesIntoTrackOrder": "Trascina i file nell'ordine di traccia corretto", @@ -608,7 +608,7 @@ "MessageNoResults": "Nessun Risultato", "MessageNoSearchResultsFor": "Nessun risultato per \"{0}\"", "MessageNoSeries": "Nessuna Serie", - "MessageNoTags": "No Tags", + "MessageNoTags": "Nessun Tags", "MessageNoTasksRunning": "Nessun processo in esecuzione", "MessageNotYetImplemented": "Non Ancora Implementato", "MessageNoUpdateNecessary": "Nessun aggiornamento necessario", @@ -637,7 +637,7 @@ "MessageUploaderItemSuccess": "Caricato con successo!", "MessageUploading": "Caricamento...", "MessageValidCronExpression": "Espressione Cron Valida", - "MessageWatcherIsDisabledGlobally": "Watcher è disabilitato a livello globale nelle impostazioni del server", + "MessageWatcherIsDisabledGlobally": "Controllo file automatico è disabilitato a livello globale nelle impostazioni del server", "MessageXLibraryIsEmpty": "{0} libreria vuota!", "MessageYourAudiobookDurationIsLonger": "La durata dell'audiolibro è più lunga della durata trovata", "MessageYourAudiobookDurationIsShorter": "La durata dell'audiolibro è inferiore alla durata trovata", @@ -651,7 +651,7 @@ "NoteUploaderOnlyAudioFiles": "Se carichi solo file audio, ogni file audio verrà gestito come un audiolibro separato.", "NoteUploaderUnsupportedFiles": "I file non supportati vengono ignorati. Quando si sceglie o si elimina una cartella, gli altri file che non si trovano in una cartella di elementi vengono ignorati.", "PlaceholderNewCollection": "Nome Nuova Raccolta", - "PlaceholderNewFolderPath": "Nuovo percorso Cartella", + "PlaceholderNewFolderPath": "Nuovo Percorso Cartella", "PlaceholderNewPlaylist": "Nome nuova playlist", "PlaceholderSearch": "Cerca..", "PlaceholderSearchEpisode": "Cerca Episodio..", @@ -717,7 +717,7 @@ "ToastRSSFeedCloseSuccess": "RSS feed chiuso", "ToastSendEbookToDeviceFailed": "Impossibile inviare l'ebook al dispositivo", "ToastSendEbookToDeviceSuccess": "Ebook inviato al dispositivo \"{0}\"", - "ToastSeriesUpdateFailed": "Aggiornaento Serie Fallito", + "ToastSeriesUpdateFailed": "Aggiornamento Serie Fallito", "ToastSeriesUpdateSuccess": "Serie Aggornate", "ToastSessionDeleteFailed": "Errore eliminazione sessione", "ToastSessionDeleteSuccess": "Sessione cancellata", @@ -726,4 +726,4 @@ "ToastSocketFailedToConnect": "Socket non riesce a connettersi", "ToastUserDeleteFailed": "Errore eliminazione utente", "ToastUserDeleteSuccess": "Utente eliminato" -} \ No newline at end of file +} diff --git a/server/scanner/LibraryScanner.js b/server/scanner/LibraryScanner.js index 11a88bd4..27c507bd 100644 --- a/server/scanner/LibraryScanner.js +++ b/server/scanner/LibraryScanner.js @@ -463,7 +463,7 @@ class LibraryScanner { // Test Case: Moving audio files from library item folder to author folder should trigger a re-scan of the item const updateGroup = { ...fileUpdateGroup } for (const itemDir in updateGroup) { - if (itemDir == fileUpdateGroup[itemDir]) continue // Media in root path + if (isSingleMediaFile(fileUpdateGroup, itemDir)) continue // Media in root path const itemDirNestedFiles = fileUpdateGroup[itemDir].filter(b => b.includes('/')) if (!itemDirNestedFiles.length) continue @@ -559,7 +559,7 @@ class LibraryScanner { Logger.debug(`[LibraryScanner] Folder update for relative path "${itemDir}" is in library item "${existingLibraryItem.media.metadata.title}" - scan for updates`) itemGroupingResults[itemDir] = await LibraryItemScanner.scanLibraryItem(existingLibraryItem.id, renamedPaths) continue - } else if (library.settings.audiobooksOnly && !fileUpdateGroup[itemDir].some?.(scanUtils.checkFilepathIsAudioFile)) { + } else if (library.settings.audiobooksOnly && !hasAudioFiles(fileUpdateGroup, itemDir)) { Logger.debug(`[LibraryScanner] Folder update for relative path "${itemDir}" has no audio files`) continue } @@ -580,7 +580,7 @@ class LibraryScanner { } Logger.debug(`[LibraryScanner] Folder update group must be a new item "${itemDir}" in library "${library.name}"`) - const isSingleMediaItem = itemDir === fileUpdateGroup[itemDir] + const isSingleMediaItem = isSingleMediaFile(fileUpdateGroup, itemDir) const newLibraryItem = await LibraryItemScanner.scanPotentialNewLibraryItem(fullPath, library, folder, isSingleMediaItem) if (newLibraryItem) { const oldNewLibraryItem = Database.libraryItemModel.getOldLibraryItem(newLibraryItem) @@ -592,4 +592,14 @@ class LibraryScanner { return itemGroupingResults } } -module.exports = new LibraryScanner() \ No newline at end of file +module.exports = new LibraryScanner() + +function hasAudioFiles(fileUpdateGroup, itemDir) { + return isSingleMediaFile(fileUpdateGroup, itemDir) ? + scanUtils.checkFilepathIsAudioFile(fileUpdateGroup[itemDir]) : + fileUpdateGroup[itemDir].some(scanUtils.checkFilepathIsAudioFile) +} + +function isSingleMediaFile(fileUpdateGroup, itemDir) { + return itemDir === fileUpdateGroup[itemDir] +}