From 8bbeae4873dcedccffe986d8a07d52ad292ebd2f Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 14 Apr 2022 10:15:42 -0500 Subject: [PATCH 1/4] Fix check podcast episodes cronjob --- server/managers/PodcastManager.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/server/managers/PodcastManager.js b/server/managers/PodcastManager.js index 2ddc9d06..67391c5a 100644 --- a/server/managers/PodcastManager.js +++ b/server/managers/PodcastManager.js @@ -139,31 +139,30 @@ class PodcastManager { } async checkForNewEpisodes() { - var podcastsWithAutoDownload = this.db.libraryItems.find(li => li.mediaType === 'podcast' && li.media.autoDownloadEpisodes) + var podcastsWithAutoDownload = this.db.libraryItems.filter(li => li.mediaType === 'podcast' && li.media.autoDownloadEpisodes) if (!podcastsWithAutoDownload.length) { this.cancelCron() return } for (const libraryItem of podcastsWithAutoDownload) { - Logger.info(`[PodcastManager] checkForNewEpisodes Cron for "${libraryItem.media.metadata.title}"`) + const lastEpisodeCheckDate = new Date(libraryItem.media.lastEpisodeCheck || 0) + Logger.info(`[PodcastManager] checkForNewEpisodes Cron for "${libraryItem.media.metadata.title}" - Last episode check: ${lastEpisodeCheckDate}`) var newEpisodes = await this.checkPodcastForNewEpisodes(libraryItem) - var hasUpdates = false + if (!newEpisodes) { // Failed libraryItem.media.autoDownloadEpisodes = false - hasUpdates = true } else if (newEpisodes.length) { Logger.info(`[PodcastManager] Found ${newEpisodes.length} new episodes for podcast "${libraryItem.media.metadata.title}" - starting download`) this.downloadPodcastEpisodes(libraryItem, newEpisodes) - hasUpdates = true + } else { + Logger.debug(`[PodcastManager] No new episodes for "${libraryItem.media.metadata.title}"`) } - if (hasUpdates) { - libraryItem.media.lastEpisodeCheck = Date.now() - libraryItem.updatedAt = Date.now() - await this.db.updateLibraryItem(libraryItem) - this.emitter('item_updated', libraryItem.toJSONExpanded()) - } + libraryItem.media.lastEpisodeCheck = Date.now() + libraryItem.updatedAt = Date.now() + await this.db.updateLibraryItem(libraryItem) + this.emitter('item_updated', libraryItem.toJSONExpanded()) } } From cbde451120227bc84d5cba8fe9606e3e736b0128 Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 14 Apr 2022 12:57:34 -0500 Subject: [PATCH 2/4] Add redirects for media types on unsupported pages --- client/pages/collection/_id.vue | 1 + client/pages/library/_library/authors/index.vue | 9 +++++++-- client/pages/library/_library/bookshelf/_id.vue | 11 +++++++++-- client/pages/library/_library/podcast/search.vue | 11 +++++++++-- client/pages/library/_library/series/_id.vue | 10 ++++++++-- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/client/pages/collection/_id.vue b/client/pages/collection/_id.vue index 37c9f609..02be207c 100644 --- a/client/pages/collection/_id.vue +++ b/client/pages/collection/_id.vue @@ -51,6 +51,7 @@ export default { if (!collection) { return redirect('/') } + store.commit('user/addUpdateCollection', collection) return { collectionId: collection.id diff --git a/client/pages/library/_library/authors/index.vue b/client/pages/library/_library/authors/index.vue index 686702e1..34e819c1 100644 --- a/client/pages/library/_library/authors/index.vue +++ b/client/pages/library/_library/authors/index.vue @@ -23,11 +23,16 @@ export default { async asyncData({ store, params, redirect, query, app }) { var libraryId = params.library - var library = await store.dispatch('libraries/fetch', libraryId) - if (!library) { + var libraryData = await store.dispatch('libraries/fetch', libraryId) + if (!libraryData) { return redirect('/oops?message=Library not found') } + const library = libraryData.library + if (library.mediaType === 'podcast') { + return redirect(`/library/${libraryId}`) + } + return { libraryId } diff --git a/client/pages/library/_library/bookshelf/_id.vue b/client/pages/library/_library/bookshelf/_id.vue index 30f8b551..8b94747a 100644 --- a/client/pages/library/_library/bookshelf/_id.vue +++ b/client/pages/library/_library/bookshelf/_id.vue @@ -14,8 +14,8 @@ export default { async asyncData({ params, query, store, app, redirect }) { var libraryId = params.library - var library = await store.dispatch('libraries/fetch', libraryId) - if (!library) { + var libraryData = await store.dispatch('libraries/fetch', libraryId) + if (!libraryData) { return redirect('/oops?message=Library not found') } @@ -23,6 +23,13 @@ export default { if (query.filter) { store.dispatch('user/updateUserSettings', { filterBy: query.filter }) } + + // Redirect podcast libraries + const library = libraryData.library + if (library.mediaType === 'podcast' && (params.id === 'collections' || params.id === 'series')) { + return redirect(`/library/${libraryId}`) + } + return { id: params.id || '', libraryId diff --git a/client/pages/library/_library/podcast/search.vue b/client/pages/library/_library/podcast/search.vue index 03b25497..5433b81f 100644 --- a/client/pages/library/_library/podcast/search.vue +++ b/client/pages/library/_library/podcast/search.vue @@ -44,10 +44,17 @@ export default { async asyncData({ params, query, store, app, redirect }) { var libraryId = params.library - var library = await store.dispatch('libraries/fetch', libraryId) - if (!library) { + var libraryData = await store.dispatch('libraries/fetch', libraryId) + if (!libraryData) { return redirect('/oops?message=Library not found') } + + // Redirect book libraries + const library = libraryData.library + if (library.mediaType === 'book') { + return redirect(`/library/${libraryId}`) + } + return { libraryId } diff --git a/client/pages/library/_library/series/_id.vue b/client/pages/library/_library/series/_id.vue index 054f19cf..754b332e 100644 --- a/client/pages/library/_library/series/_id.vue +++ b/client/pages/library/_library/series/_id.vue @@ -14,10 +14,16 @@ export default { async asyncData({ store, params, redirect, query, app }) { var libraryId = params.library - var library = await store.dispatch('libraries/fetch', libraryId) - if (!library) { + var libraryData = await store.dispatch('libraries/fetch', libraryId) + if (!libraryData) { return redirect('/oops?message=Library not found') } + + const library = libraryData.library + if (library.mediaType === 'podcast') { + return redirect(`/library/${libraryId}`) + } + var series = await app.$axios.$get(`/api/series/${params.id}`).catch((error) => { console.error('Failed', error) return false From 5a26b01ffb1a5ecdbf09f82d14a71f9f1e177e57 Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 14 Apr 2022 17:15:52 -0500 Subject: [PATCH 3/4] Add LibrarySettings and update edit library modal to include settings tab --- client/components/modals/item/EditModal.vue | 4 +- .../modals/libraries/EditLibrary.vue | 171 ++++------------- .../components/modals/libraries/EditModal.vue | 181 +++++++++++++++++- .../modals/libraries/FolderChooser.vue | 23 ++- .../modals/libraries/LibrarySettings.vue | 63 ++++++ client/components/ui/MediaIconPicker.vue | 8 +- client/components/ui/TextInputWithLabel.vue | 5 +- server/Db.js | 2 +- server/Watcher.js | 6 +- server/objects/Library.js | 17 +- server/objects/settings/LibrarySettings.js | 34 ++++ .../objects/{ => settings}/ServerSettings.js | 4 +- 12 files changed, 356 insertions(+), 162 deletions(-) create mode 100644 client/components/modals/libraries/LibrarySettings.vue create mode 100644 server/objects/settings/LibrarySettings.js rename server/objects/{ => settings}/ServerSettings.js (97%) diff --git a/client/components/modals/item/EditModal.vue b/client/components/modals/item/EditModal.vue index 2840898e..094ef9bd 100644 --- a/client/components/modals/item/EditModal.vue +++ b/client/components/modals/item/EditModal.vue @@ -5,7 +5,7 @@

{{ title }}

-
+
@@ -252,7 +252,7 @@ export default { } - \ No newline at end of file diff --git a/client/components/modals/libraries/FolderChooser.vue b/client/components/modals/libraries/FolderChooser.vue index d41d16e9..a54cdfe6 100644 --- a/client/components/modals/libraries/FolderChooser.vue +++ b/client/components/modals/libraries/FolderChooser.vue @@ -1,10 +1,14 @@ @@ -161,4 +161,9 @@ export default { .dir-item.dir-used { background-color: rgba(255, 25, 0, 0.1); } +.folder-container { + max-height: calc(100% - 130px); + height: calc(100% - 130px); + min-height: calc(100% - 130px); +} \ No newline at end of file diff --git a/client/components/modals/libraries/LibrarySettings.vue b/client/components/modals/libraries/LibrarySettings.vue new file mode 100644 index 00000000..c27f4838 --- /dev/null +++ b/client/components/modals/libraries/LibrarySettings.vue @@ -0,0 +1,63 @@ + + + \ No newline at end of file diff --git a/client/components/ui/MediaIconPicker.vue b/client/components/ui/MediaIconPicker.vue index 50280904..efb0b9a0 100644 --- a/client/components/ui/MediaIconPicker.vue +++ b/client/components/ui/MediaIconPicker.vue @@ -40,8 +40,8 @@ export default { showMenu: false, types: [ { - id: 'default', - name: 'Default' + id: 'database', + name: 'Database' }, { id: 'audiobook', @@ -65,7 +65,7 @@ export default { computed: { selected: { get() { - return this.value || 'default' + return this.value || 'database' }, set(val) { this.$emit('input', val) @@ -75,7 +75,7 @@ export default { return this.types.find((t) => t.id === this.selected) }, selectedName() { - return this.selectedItem ? this.selectedItem.name : 'Default' + return this.selectedItem ? this.selectedItem.name : 'Database' } }, methods: { diff --git a/client/components/ui/TextInputWithLabel.vue b/client/components/ui/TextInputWithLabel.vue index f5cbd1e4..0dab6109 100644 --- a/client/components/ui/TextInputWithLabel.vue +++ b/client/components/ui/TextInputWithLabel.vue @@ -3,7 +3,7 @@

{{ label }}{{ note }}

- +
@@ -38,6 +38,9 @@ export default { if (this.$refs.input && this.$refs.input.blur) { this.$refs.input.blur() } + }, + inputBlurred() { + this.$emit('blur') } }, mounted() {} diff --git a/server/Db.js b/server/Db.js index 62e1bb0f..e3700d7e 100644 --- a/server/Db.js +++ b/server/Db.js @@ -9,7 +9,7 @@ const UserCollection = require('./objects/UserCollection') const Library = require('./objects/Library') const Author = require('./objects/entities/Author') const Series = require('./objects/entities/Series') -const ServerSettings = require('./objects/ServerSettings') +const ServerSettings = require('./objects/settings/ServerSettings') const PlaybackSession = require('./objects/PlaybackSession') class Db { diff --git a/server/Watcher.js b/server/Watcher.js index aa3c68f6..ea9e46e0 100644 --- a/server/Watcher.js +++ b/server/Watcher.js @@ -69,19 +69,19 @@ class FolderWatcher extends EventEmitter { initWatcher(libraries) { libraries.forEach((lib) => { - if (!lib.disableWatcher) { + if (!lib.settings.disableWatcher) { this.buildLibraryWatcher(lib) } }) } addLibrary(library) { - if (this.disabled || library.disableWatcher) return + if (this.disabled || library.settings.disableWatcher) return this.buildLibraryWatcher(library) } updateLibrary(library) { - if (this.disabled || library.disableWatcher) return + if (this.disabled || library.settings.disableWatcher) return var libwatcher = this.libraryWatchers.find(lib => lib.id === library.id) if (libwatcher) { libwatcher.name = library.name diff --git a/server/objects/Library.js b/server/objects/Library.js index 1219d8f0..aef80702 100644 --- a/server/objects/Library.js +++ b/server/objects/Library.js @@ -1,4 +1,5 @@ const Folder = require('./Folder') +const LibrarySettings = require('./settings/LibrarySettings') const { getId } = require('../utils/index') class Library { @@ -10,9 +11,9 @@ class Library { this.icon = 'database' // database, podcast, book, audiobook, comic this.mediaType = 'book' // book, podcast this.provider = 'google' - this.disableWatcher = false this.lastScan = 0 + this.settings = null this.createdAt = null this.lastUpdate = null @@ -34,7 +35,11 @@ class Library { this.icon = library.icon || 'database' this.mediaType = library.mediaType this.provider = library.provider || 'google' - this.disableWatcher = !!library.disableWatcher + + this.settings = new LibrarySettings(library.settings) + if (library.settings === undefined) { // LibrarySettings added in v2, migrate settings + this.settings.disableWatcher = !!library.disableWatcher + } this.createdAt = library.createdAt this.lastUpdate = library.lastUpdate @@ -62,7 +67,7 @@ class Library { icon: this.icon, mediaType: this.mediaType, provider: this.provider, - disableWatcher: this.disableWatcher, + settings: this.settings.toJSON(), createdAt: this.createdAt, lastUpdate: this.lastUpdate } @@ -89,7 +94,7 @@ class Library { this.icon = data.icon || 'database' this.mediaType = data.mediaType || 'book' this.provider = data.provider || 'google' - this.disableWatcher = !!data.disableWatcher + this.settings = new LibrarySettings(data.settings) this.createdAt = Date.now() this.lastUpdate = Date.now() } @@ -105,10 +110,10 @@ class Library { } }) - if (payload.disableWatcher !== this.disableWatcher) { - this.disableWatcher = !!payload.disableWatcher + if (payload.settings && this.settings.update(payload.settings)) { hasUpdates = true } + if (!isNaN(payload.displayOrder) && payload.displayOrder !== this.displayOrder) { this.displayOrder = Number(payload.displayOrder) hasUpdates = true diff --git a/server/objects/settings/LibrarySettings.js b/server/objects/settings/LibrarySettings.js new file mode 100644 index 00000000..853962ad --- /dev/null +++ b/server/objects/settings/LibrarySettings.js @@ -0,0 +1,34 @@ +const { BookCoverAspectRatio } = require('../../utils/constants') +const Logger = require('../../Logger') + +class LibrarySettings { + constructor(settings) { + this.disableWatcher = false + + if (settings) { + this.construct(settings) + } + } + + construct(settings) { + this.disableWatcher = !!settings.disableWatcher + } + + toJSON() { + return { + disableWatcher: this.disableWatcher + } + } + + update(payload) { + var hasUpdates = false + for (const key in payload) { + if (this[key] !== payload[key]) { + this[key] = payload[key] + hasUpdates = true + } + } + return hasUpdates + } +} +module.exports = LibrarySettings \ No newline at end of file diff --git a/server/objects/ServerSettings.js b/server/objects/settings/ServerSettings.js similarity index 97% rename from server/objects/ServerSettings.js rename to server/objects/settings/ServerSettings.js index 43e777e7..86cb33fb 100644 --- a/server/objects/ServerSettings.js +++ b/server/objects/settings/ServerSettings.js @@ -1,5 +1,5 @@ -const { BookCoverAspectRatio, BookshelfView } = require('../utils/constants') -const Logger = require('../Logger') +const { BookCoverAspectRatio, BookshelfView } = require('../../utils/constants') +const Logger = require('../../Logger') class ServerSettings { constructor(settings) { From a62f7a4861e3a6569159b912e13642706d9d5dc0 Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 14 Apr 2022 18:24:24 -0500 Subject: [PATCH 4/4] Update uploader to support podcast folder structure --- ...{BookUploadCard.vue => ItemUploadCard.vue} | 58 +++++--- client/mixins/uploadHelpers.js | 101 +++++++------ client/pages/upload/index.vue | 139 ++++++++++-------- client/plugins/constants.js | 2 +- server/controllers/MiscController.js | 21 ++- server/objects/Library.js | 3 + 6 files changed, 186 insertions(+), 138 deletions(-) rename client/components/cards/{BookUploadCard.vue => ItemUploadCard.vue} (61%) diff --git a/client/components/cards/BookUploadCard.vue b/client/components/cards/ItemUploadCard.vue similarity index 61% rename from client/components/cards/BookUploadCard.vue rename to client/components/cards/ItemUploadCard.vue index 08d66e2f..16f789b3 100644 --- a/client/components/cards/BookUploadCard.vue +++ b/client/components/cards/ItemUploadCard.vue @@ -1,7 +1,7 @@

Successfully Uploaded!

@@ -55,15 +59,16 @@ import Path from 'path' export default { props: { - book: { + item: { type: Object, default: () => {} }, + mediaType: String, processing: Boolean }, data() { return { - bookData: { + itemData: { title: '', author: '', series: '' @@ -75,14 +80,19 @@ export default { } }, computed: { + isPodcast() { + return this.mediaType === 'podcast' + }, directory() { - if (!this.bookData.title) return '' - if (this.bookData.series && this.bookData.author) { - return Path.join(this.bookData.author, this.bookData.series, this.bookData.title) - } else if (this.bookData.author) { - return Path.join(this.bookData.author, this.bookData.title) + if (!this.itemData.title) return '' + if (this.isPodcast) return this.itemData.title + + if (this.itemData.series && this.itemData.author) { + return Path.join(this.itemData.author, this.itemData.series, this.itemData.title) + } else if (this.itemData.author) { + return Path.join(this.itemData.author, this.itemData.title) } else { - return this.bookData.title + return this.itemData.title } } }, @@ -96,24 +106,24 @@ export default { this.error = '' }, getData() { - if (!this.bookData.title) { + if (!this.itemData.title) { this.error = 'Must have a title' return null } this.error = '' - var files = this.book.bookFiles.concat(this.book.otherFiles) + var files = this.item.itemFiles.concat(this.item.otherFiles) return { - index: this.book.index, - ...this.bookData, + index: this.item.index, + ...this.itemData, files } } }, mounted() { - if (this.book) { - this.bookData.title = this.book.title - this.bookData.author = this.book.author - this.bookData.series = this.book.series + if (this.item) { + this.itemData.title = this.item.title + this.itemData.author = this.item.author + this.itemData.series = this.item.series } } } diff --git a/client/mixins/uploadHelpers.js b/client/mixins/uploadHelpers.js index caa06edc..a54453e5 100644 --- a/client/mixins/uploadHelpers.js +++ b/client/mixins/uploadHelpers.js @@ -4,8 +4,8 @@ export default { data() { return { uploadHelpers: { - getBooksFromDrop: this.getBooksFromDataTransferItems, - getBooksFromPicker: this.getBooksFromFileList + getItemsFromDrop: this.getItemsFromDataTransferItems, + getItemsFromPicker: this.getItemsFromFilelist } } }, @@ -23,8 +23,8 @@ export default { } return false }, - filterAudiobookFiles(files) { - var validBookFiles = [] + filterItemFiles(files, mediaType) { + var validItemFiles = [] var validOtherFiles = [] var ignoredFiles = [] files.forEach((file) => { @@ -32,60 +32,60 @@ export default { if (!filetype) ignoredFiles.push(file) else { file.filetype = filetype - if (filetype === 'audio' || filetype === 'ebook') validBookFiles.push(file) + if (filetype === 'audio' || (filetype === 'ebook' && mediaType === 'book')) validItemFiles.push(file) else validOtherFiles.push(file) } }) return { - bookFiles: validBookFiles, + itemFiles: validItemFiles, otherFiles: validOtherFiles, ignoredFiles } }, - audiobookFromItems(items) { - var { bookFiles, otherFiles, ignoredFiles } = this.filterAudiobookFiles(items) - if (!bookFiles.length) { + itemFromTreeItems(items, mediaType) { + var { itemFiles, otherFiles, ignoredFiles } = this.filterItemFiles(items, mediaType) + if (!itemFiles.length) { ignoredFiles = ignoredFiles.concat(otherFiles) otherFiles = [] } return [ { - bookFiles, + itemFiles, otherFiles, ignoredFiles } ] }, - traverseForAudiobook(folder, depth = 1) { + traverseForItem(folder, mediaType, depth = 1) { if (folder.items.some((f) => f.isDirectory)) { - var audiobooks = [] + var items = [] folder.items.forEach((file) => { if (file.isDirectory) { - var audiobookResults = this.traverseForAudiobook(file, ++depth) - audiobooks = audiobooks.concat(audiobookResults) + var itemResults = this.traverseForItem(file, mediaType, ++depth) + items = items.concat(itemResults) } }) - return audiobooks + return items } else { - return this.audiobookFromItems(folder.items) + return this.itemFromTreeItems(folder.items, mediaType) } }, - fileTreeToAudiobooks(filetree) { + fileTreeToItems(filetree, mediaType) { // Has directores - Is Multi Book Drop if (filetree.some((f) => f.isDirectory)) { var ignoredFilesInRoot = filetree.filter((f) => !f.isDirectory) if (ignoredFilesInRoot.length) filetree = filetree.filter((f) => f.isDirectory) - var audiobookResults = this.traverseForAudiobook({ items: filetree }) + var itemResults = this.traverseForItem({ items: filetree }, mediaType) return { - audiobooks: audiobookResults, + items: itemResults, ignoredFiles: ignoredFilesInRoot } } else { // Single Book drop return { - audiobooks: this.audiobookFromItems(filetree), + items: this.itemFromTreeItems(filetree, mediaType), ignoredFiles: [] } } @@ -140,7 +140,7 @@ export default { series: '', ...book } - var firstBookFile = book.bookFiles[0] + var firstBookFile = book.itemFiles[0] if (!firstBookFile.filepath) return audiobook // No path var firstBookPath = Path.dirname(firstBookFile.filepath) @@ -157,32 +157,49 @@ export default { } return audiobook }, - async getBooksFromDataTransferItems(items) { + cleanPodcast(item, index) { + var podcast = { + index, + title: '', + ...item + } + var firstAudioFile = podcast.itemFiles[0] + if (!firstAudioFile.filepath) return podcast // No path + var firstPath = Path.dirname(firstAudioFile.filepath) + var dirs = firstPath.split('/').filter(d => !!d && d !== '.') + podcast.title = dirs.length > 1 ? dirs[1] : dirs[0] + return podcast + }, + cleanItem(item, mediaType, index) { + if (mediaType === 'podcast') return this.cleanPodcast(item, index) + return this.cleanBook(item, index) + }, + async getItemsFromDataTransferItems(items, mediaType) { var files = await this.getFilesDropped(items) if (!files || !files.length) return { error: 'No files found ' } - var audiobooksData = this.fileTreeToAudiobooks(files) - if (!audiobooksData.audiobooks.length && !audiobooksData.ignoredFiles.length) { + var itemData = this.fileTreeToItems(files, mediaType) + if (!itemData.items.length && !itemData.ignoredFiles.length) { return { error: 'Invalid file drop' } } - var ignoredFiles = audiobooksData.ignoredFiles + var ignoredFiles = itemData.ignoredFiles var index = 1 - var books = audiobooksData.audiobooks.filter((ab) => { - if (!ab.bookFiles.length) { + var items = itemData.items.filter((ab) => { + if (!ab.itemFiles.length) { if (ab.otherFiles.length) ignoredFiles = ignoredFiles.concat(ab.otherFiles) if (ab.ignoredFiles.length) ignoredFiles = ignoredFiles.concat(ab.ignoredFiles) } - return ab.bookFiles.length - }).map(ab => this.cleanBook(ab, index++)) + return ab.itemFiles.length + }).map(ab => this.cleanItem(ab, index++)) return { - books, + items, ignoredFiles } }, - getBooksFromFileList(filelist) { + getItemsFromFilelist(filelist, mediaType) { var ignoredFiles = [] var otherFiles = [] - var bookMap = {} + var itemMap = {} filelist.forEach((file) => { var filetype = this.checkFileType(file.name) @@ -191,17 +208,17 @@ export default { file.filetype = filetype if (file.webkitRelativePath) file.filepath = file.webkitRelativePath - if (filetype === 'audio' || filetype === 'ebook') { + if (filetype === 'audio' || (filetype === 'ebook' && mediaType === 'book')) { var dir = file.filepath ? Path.dirname(file.filepath) : '' - if (!bookMap[dir]) { - bookMap[dir] = { + if (!itemMap[dir]) { + itemMap[dir] = { path: dir, ignoredFiles: [], - bookFiles: [], + itemFiles: [], otherFiles: [] } } - bookMap[dir].bookFiles.push(file) + itemMap[dir].itemFiles.push(file) } else { otherFiles.push(file) } @@ -210,18 +227,18 @@ export default { otherFiles.forEach((file) => { var dir = Path.dirname(file.filepath) - var findBook = Object.values(bookMap).find(b => dir.startsWith(b.path)) - if (findBook) { - bookMap[dir].otherFiles.push(file) + var findItem = Object.values(itemMap).find(b => dir.startsWith(b.path)) + if (findItem) { + findItem.otherFiles.push(file) } else { ignoredFiles.push(file) } }) var index = 1 - var books = Object.values(bookMap).map(ab => this.cleanBook(ab, index++)) + var items = Object.values(itemMap).map(i => this.cleanItem(i, mediaType, index++)) return { - books, + items, ignoredFiles: ignoredFiles } }, diff --git a/client/pages/upload/index.vue b/client/pages/upload/index.vue index cc9a0b09..b225ad0d 100644 --- a/client/pages/upload/index.vue +++ b/client/pages/upload/index.vue @@ -3,11 +3,14 @@
-
- +
+
-
- +
+ +
+
+
@@ -16,7 +19,7 @@ -
+

{{ isDragging ? 'Drop files' : "Drag n' drop files or folders" }}

or

@@ -29,33 +32,33 @@

Supported File Types: {{ inputAccept.join(', ') }}

- +
-

{{ books.length }} book{{ books.length === 1 ? '' : 's' }}

+

{{ items.length }} item{{ items.length === 1 ? '' : 's' }}

 | {{ ignoredFiles.length }} file{{ ignoredFiles.length === 1 ? '' : 's' }} ignored

Reset
- -

No books found

+ +

No items found

-

Unsupported files are ignored. When choosing or dropping a folder, other files that are not in a book folder are ignored.

+

Unsupported files are ignored. When choosing or dropping a folder, other files that are not in an item folder are ignored.

Supported File Types: {{ inputAccept.join(', ') }}

- -