From cbe49b3a505617bfe501cbd689a655e493c44d82 Mon Sep 17 00:00:00 2001 From: p0psicles Date: Tue, 10 May 2022 16:10:16 +0200 Subject: [PATCH 01/15] Bring back visual indicators for searching, queued and finished. --- .../slim/src/components/display-show.vue | 30 ++++++++++-- .../slim/src/components/helpers/search.vue | 49 +++++++++++++++---- themes/dark/assets/js/medusa-runtime.js | 8 +-- themes/light/assets/js/medusa-runtime.js | 8 +-- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/themes-default/slim/src/components/display-show.vue b/themes-default/slim/src/components/display-show.vue index 0251a42035..aa352174dc 100644 --- a/themes-default/slim/src/components/display-show.vue +++ b/themes-default/slim/src/components/display-show.vue @@ -128,7 +128,7 @@
- search + search subtitles --> + + + + + search subtitles
@@ -277,7 +287,7 @@
- search + search subtitles --> + + + + + search subtitles
@@ -379,7 +399,7 @@ import debounce from 'lodash/debounce'; import Vue from 'vue'; import { mapState, mapGetters, mapActions } from 'vuex'; -import { AppLink, PlotInfo, SceneNumberInput, SceneNumberAnimeInput } from './helpers'; +import { AppLink, PlotInfo, Search, SceneNumberInput, SceneNumberAnimeInput } from './helpers'; import { humanFileSize } from '../utils/core'; import { manageCookieMixin } from '../mixins/manage-cookie'; import { addQTip } from '../utils/jquery'; @@ -396,6 +416,7 @@ export default { Backstretch, PlotInfo, QualityPill, + Search, SceneNumberInput, SceneNumberAnimeInput, ShowHeader, @@ -794,7 +815,7 @@ export default { }; episodes.forEach(episode => { data.episodes.push(episode.slug); - this.$refs[`search-${episode.slug}`].src = 'images/loading16-dark.gif'; + this.$refs[`search-${episode.slug}`].src = 'images/loading16.gif'; }); } @@ -1019,7 +1040,6 @@ export default { this.initializeEpisodes(true); } } - } }; diff --git a/themes-default/slim/src/components/helpers/search.vue b/themes-default/slim/src/components/helpers/search.vue index cacb91171f..7f86c97d05 100644 --- a/themes-default/slim/src/components/helpers/search.vue +++ b/themes-default/slim/src/components/helpers/search.vue @@ -2,10 +2,11 @@
state.config.search + stateSearch: state => state.config.search, + client: state => state.auth.client, + queueitems: state => state.queue.queueitems }) }, methods: { @@ -116,13 +121,13 @@ export default { episodes: [episode.slug], options: {} }; - this.$refs[`search-${episode.slug}`].src = 'images/loading16-dark.gif'; + this.src = 'images/loading16-dark.gif'; this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef .then(_ => { - console.info(`started search for show: ${showSlug} episode: ${episode.slug}`); - this.$refs[`search-${episode.slug}`].src = 'images/queued.png'; - this.$refs[`search-${episode.slug}`].disabled = true; + console.info(`Queued search for show: ${showSlug} episode: ${episode.slug}`); + this.src = 'images/queued.png'; + this.disabled = true; }).catch(error => { console.error(String(error)); this.$refs[`search-${episode.slug}`].src = 'images/no16.png'; @@ -138,9 +143,8 @@ export default { */ queueSearch(episode) { const { $modal, search, retryDownload } = this; - const episodeIdentifier = episode.slug; if (episode) { - if (this.$refs[`search-${episodeIdentifier}`].disabled === true) { + if (this.disabled === true) { return; } @@ -167,7 +171,32 @@ export default { beforeFailedSearchModalClose(event) { this.failedSearchEpisodes = event.params.episodes; } + }, + watch: { + queueitems(queueitems) { + const episode = queueitems.filter( + q => q.name === 'BACKLOG' && + q.show.id.slug === this.showSlug && + q.segment.find(s => s.slug === this.episode.slug) + ); + + if (episode.length === 0) { + return; + } + const lastEp = episode.slice(-1)[0]; + if (lastEp.inProgress && lastEp.success === null) { + // Search is in progress. + console.info(`Search runnning for show: ${this.showSlug} and episode: ${this.episode.slug}`); + this.src = 'images/loading16.gif'; + this.disabled = true; + } else { + // Search finished. + console.log(`Search finished for ${this.episode.slug}`); + this.src = 'images/yes16.png'; + this.disabled = false; + } + } } }; diff --git a/themes/dark/assets/js/medusa-runtime.js b/themes/dark/assets/js/medusa-runtime.js index 938a9ae4fd..8d85cffdc3 100644 --- a/themes/dark/assets/js/medusa-runtime.js +++ b/themes/dark/assets/js/medusa-runtime.js @@ -235,7 +235,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash/debounce */ \"./node_modules/lodash/debounce.js\");\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.js\");\n/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ \"./src/components/helpers/index.js\");\n/* harmony import */ var _utils_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/core */ \"./src/utils/core.js\");\n/* harmony import */ var _mixins_manage_cookie__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mixins/manage-cookie */ \"./src/mixins/manage-cookie.js\");\n/* harmony import */ var _utils_jquery__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/jquery */ \"./src/utils/jquery.js\");\n/* harmony import */ var vue_good_table__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! vue-good-table */ \"./node_modules/vue-good-table/dist/vue-good-table.esm.js\");\n/* harmony import */ var _backstretch_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./backstretch.vue */ \"./src/components/backstretch.vue\");\n/* harmony import */ var _show_header_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./show-header.vue */ \"./src/components/show-header.vue\");\n/* harmony import */ var _subtitle_search_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./subtitle-search.vue */ \"./src/components/subtitle-search.vue\");\n/* harmony import */ var _helpers_quality_pill_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./helpers/quality-pill.vue */ \"./src/components/helpers/quality-pill.vue\");\n/* provided dependency */ var $ = __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'show',\n components: {\n AppLink: _helpers__WEBPACK_IMPORTED_MODULE_1__.AppLink,\n Backstretch: _backstretch_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"],\n PlotInfo: _helpers__WEBPACK_IMPORTED_MODULE_1__.PlotInfo,\n QualityPill: _helpers_quality_pill_vue__WEBPACK_IMPORTED_MODULE_8__[\"default\"],\n SceneNumberInput: _helpers__WEBPACK_IMPORTED_MODULE_1__.SceneNumberInput,\n SceneNumberAnimeInput: _helpers__WEBPACK_IMPORTED_MODULE_1__.SceneNumberAnimeInput,\n ShowHeader: _show_header_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"],\n VueGoodTable: vue_good_table__WEBPACK_IMPORTED_MODULE_9__.VueGoodTable\n },\n mixins: [(0,_mixins_manage_cookie__WEBPACK_IMPORTED_MODULE_3__.manageCookieMixin)('displayShow')],\n\n metaInfo() {\n if (!this.show || !this.show.title) {\n return {\n title: 'Medusa'\n };\n }\n\n const {\n title\n } = this.show;\n return {\n title,\n titleTemplate: '%s | Medusa'\n };\n },\n\n props: {\n /**\n * Show Slug\n */\n slug: {\n type: String\n }\n },\n\n data() {\n const {\n getCookie\n } = this;\n const perPageDropdown = [25, 50, 100, 250, 500];\n\n const getPaginationPerPage = () => {\n const rows = getCookie('pagination-perPage');\n\n if (!rows) {\n return 50;\n }\n\n if (!perPageDropdown.includes(rows)) {\n return 500;\n }\n\n return rows;\n };\n\n return {\n invertTable: true,\n subtitleSearchComponents: [],\n columns: [{\n label: 'NFO',\n field: 'content.hasNfo',\n type: 'boolean',\n sortable: false,\n hidden: getCookie('NFO')\n }, {\n label: 'TBN',\n field: 'content.hasTbn',\n type: 'boolean',\n sortable: false,\n hidden: getCookie('TBN')\n }, {\n label: 'Episode',\n field: 'episode',\n type: 'number',\n hidden: getCookie('Episode')\n }, {\n label: 'Abs. #',\n field: 'absoluteNumber',\n type: 'number',\n hidden: getCookie('Abs. #')\n }, {\n label: 'Scene',\n field: 'scene',\n sortable: false,\n hidden: getCookie('Scene')\n }, {\n label: 'Scene Abs. #',\n field: 'sceneAbsolute',\n type: 'number',\n hidden: getCookie('Scene Abs. #')\n }, {\n label: 'Title',\n field: 'title',\n hidden: getCookie('Title')\n }, {\n label: 'File',\n field: 'file.location',\n hidden: getCookie('File')\n }, {\n label: 'Size',\n field: 'file.size',\n type: 'number',\n formatFn: _utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize,\n hidden: getCookie('Size')\n }, {\n // For now i'm using a custom function the parse it. As the type: date, isn't working for us.\n // But the goal is to have this user formatted (as configured in backend)\n label: 'Air date',\n field: this.parseDateFn,\n tdClass: 'align-center',\n sortable: false,\n hidden: getCookie('Air date')\n }, {\n label: 'Download',\n field: 'download',\n sortable: false,\n hidden: getCookie('Download')\n }, {\n label: 'Subtitles',\n field: 'subtitles',\n sortable: false,\n hidden: getCookie('Subtitles')\n }, {\n label: 'Status',\n field: 'status',\n hidden: getCookie('Status')\n }, {\n label: 'Search',\n field: 'search',\n sortable: false,\n hidden: getCookie('Search')\n }],\n perPageDropdown,\n paginationPerPage: getPaginationPerPage(),\n selectedEpisodes: [],\n // We need to keep track of which episode where trying to search, for the vue-modal\n failedSearchEpisodes: [],\n backlogSearchEpisodes: [],\n filterByOverviewStatus: false,\n selectedSearch: 'search action'\n };\n },\n\n computed: { ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapState)({\n shows: state => state.shows.shows,\n subtitles: state => state.config.subtitles,\n configLoaded: state => state.config.layout.fanartBackground !== null,\n layout: state => state.config.layout,\n stateSearch: state => state.config.search,\n client: state => state.auth.client\n }),\n ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapGetters)({\n show: 'getCurrentShow',\n getOverviewStatus: 'getOverviewStatus',\n fuzzyParseDateTime: 'fuzzyParseDateTime'\n }),\n\n showSlug() {\n const {\n slug\n } = this;\n return slug || this.$route.query.showslug;\n },\n\n theme() {\n const {\n layout\n } = this;\n const {\n themeName\n } = layout;\n return themeName || 'light';\n },\n\n orderedSeasons() {\n const {\n filterByOverviewStatus,\n invertTable,\n show\n } = this;\n\n if (!show.seasons) {\n return [];\n }\n\n const seasons = show.seasons.slice();\n let sortedSeasons = seasons.sort((a, b) => a.season - b.season).filter(season => season.season !== 0); // Use the filterOverviewStatus to filter the data based on what's checked in the show-header.\n\n if (filterByOverviewStatus && filterByOverviewStatus.filter(status => status.checked).length < filterByOverviewStatus.length) {\n const filteredSortedSeasons = [];\n\n for (const season of sortedSeasons) {\n const {\n children,\n ...res\n } = season;\n const filteredEpisodes = children.filter(episode => {\n const episodeOverviewStatus = this.getOverviewStatus(episode.status, episode.quality, show.config.qualities);\n const filteredStatus = filterByOverviewStatus.find(overviewStatus => overviewStatus.name === episodeOverviewStatus);\n return !filteredStatus || filteredStatus.checked;\n });\n filteredSortedSeasons.push(Object.assign({\n children: filteredEpisodes\n }, res));\n }\n\n sortedSeasons = filteredSortedSeasons;\n }\n\n if (invertTable) {\n return sortedSeasons.slice().reverse();\n }\n\n return sortedSeasons;\n },\n\n specials() {\n const {\n show\n } = this;\n\n if (!show.seasons) {\n return [];\n }\n\n return show.seasons.filter(season => season.season === 0);\n }\n\n },\n\n mounted() {\n this.loadShow();\n ['load', 'resize'].map(event => {\n return window.addEventListener(event, () => {\n this.reflowLayout();\n });\n });\n $(document.body).on('click', '.seasonCheck', event => {\n const seasCheck = event.currentTarget;\n const seasNo = $(seasCheck).attr('id');\n $('#collapseSeason-' + seasNo).collapse('show');\n const seasonIdentifier = 's' + seasNo;\n $('.epCheck:visible').each((index, element) => {\n const epParts = $(element).attr('id').split('e');\n\n if (epParts[0] === seasonIdentifier) {\n element.checked = seasCheck.checked;\n }\n });\n });\n },\n\n methods: {\n humanFileSize: _utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize,\n ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapActions)({\n getShow: 'getShow',\n // Map `this.getShow()` to `this.$store.dispatch('getShow')`\n getEpisodes: 'getEpisodes',\n setCurrentShow: 'setCurrentShow',\n setRecentShow: 'setRecentShow'\n }),\n\n async loadShow() {\n const {\n setCurrentShow,\n showSlug,\n initializeEpisodes,\n getShow\n } = this; // We need detailed info for the xem / scene exceptions, so let's get it.\n\n await getShow({\n showSlug,\n detailed: true\n }); // Let's tell the store which show we currently want as current.\n // Run this after getShow(), as it will trigger the initializeEpisodes() method.\n\n setCurrentShow(showSlug); // Load all episodes\n\n initializeEpisodes();\n },\n\n statusQualityUpdate(event) {\n const {\n selectedEpisodes,\n setStatus,\n setQuality\n } = this;\n\n if (event.newQuality !== null && event.newQuality !== 'Change quality to:') {\n setQuality(event.newQuality, selectedEpisodes);\n }\n\n if (event.newStatus !== null && event.newStatus !== 'Change status to:') {\n setStatus(event.newStatus, selectedEpisodes);\n }\n },\n\n setQuality(quality, episodes) {\n const {\n showSlug,\n getEpisodes,\n show\n } = this;\n const patchData = {};\n episodes.forEach(episode => {\n patchData[episode.slug] = {\n quality: Number.parseInt(quality, 10)\n };\n });\n this.client.api.patch(`series/${show.id.slug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched show ${show.id.slug} with quality ${quality}`);\n [...new Set(episodes.map(episode => episode.season))].forEach(season => {\n getEpisodes({\n showSlug,\n season\n });\n });\n }).catch(error => {\n console.error(String(error));\n });\n },\n\n setStatus(status, episodes) {\n const {\n showSlug,\n getEpisodes\n } = this;\n const patchData = {};\n episodes.forEach(episode => {\n patchData[episode.slug] = {\n status\n };\n });\n this.client.api.patch(`series/${showSlug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched show ${showSlug} with status ${status}`);\n [...new Set(episodes.map(episode => episode.season))].forEach(season => {\n getEpisodes({\n showSlug,\n season\n });\n });\n }).catch(error => {\n console.error(String(error));\n }); // New status Wanted\n\n if (status === 3) {\n this.$modal.show('query-start-backlog-search', {\n episodes\n });\n } // New status Failed\n\n\n if (status === 11) {\n this.$modal.show('query-mark-failed-and-search', {\n episodes\n });\n }\n },\n\n parseDateFn(row) {\n const {\n fuzzyParseDateTime\n } = this;\n return fuzzyParseDateTime(row.airDate);\n },\n\n rowStyleClassFn(row) {\n const {\n getOverviewStatus,\n show\n } = this;\n\n if (Object.keys(row).includes('vgt_header_id')) {\n return;\n }\n\n const overview = getOverviewStatus(row.status, row.quality, show.config.qualities).toLowerCase().trim();\n return overview;\n },\n\n /**\n * Add (reduce) the total episodes filesize.\n * @param {object} headerRow header row object.\n * @returns {string} - Human readable file size.\n */\n addFileSize(headerRow) {\n return (0,_utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize)(headerRow.children.reduce((a, b) => a + (b.file.size || 0), 0));\n },\n\n searchSubtitle(event, episode, lang) {\n const {\n showSlug,\n getEpisodes,\n show,\n subtitleSearchComponents\n } = this;\n const SubtitleSearchClass = vue__WEBPACK_IMPORTED_MODULE_11__[\"default\"].extend(_subtitle_search_vue__WEBPACK_IMPORTED_MODULE_7__[\"default\"]); // eslint-disable-line no-undef\n\n const instance = new SubtitleSearchClass({\n propsData: {\n show,\n episode,\n key: episode.originalIndex,\n lang\n },\n parent: this\n }); // Update the show, as we downloaded new subtitle(s)\n\n instance.$on('update', event => {\n // This could be replaced by the generic websocket updates in future.\n if (event.reason === 'new subtitles found') {\n getEpisodes({\n showSlug,\n season: episode.season\n });\n }\n });\n const node = document.createElement('div');\n const tableRef = episode.season === 0 ? 'table-specials' : 'table-seasons';\n this.$refs[tableRef].$refs[`row-${episode.originalIndex}`][0].after(node);\n instance.$mount(node);\n subtitleSearchComponents.push(instance);\n },\n\n /**\n * Attaches IMDB tooltip\n */\n reflowLayout: lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default()(() => {\n console.debug('Reflowing layout');\n (0,_utils_jquery__WEBPACK_IMPORTED_MODULE_4__.addQTip)(); // eslint-disable-line no-undef\n }, 1000),\n\n /**\n * Check if any of the episodes in this season does not have the status \"unaired\".\n * If that's the case we want to manual season search icon.\n * @param {object} season - A season object.\n * @returns {Boolean} - true if one of the seasons episodes has a status 'unaired'.\n */\n anyEpisodeNotUnaired(season) {\n return season.children.filter(ep => ep.status !== 'Unaired').length > 0;\n },\n\n episodesInverse(season) {\n const {\n invertTable\n } = this;\n\n if (!season.children) {\n return [];\n }\n\n if (invertTable) {\n return season.children.slice().reverse();\n }\n\n return season.children;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeBacklogSearchModalClose(event) {\n this.backlogSearchEpisodes = event.params.episodes;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeFailedSearchModalClose(event) {\n this.failedSearchEpisodes = event.params.episodes;\n },\n\n retryDownload(episode) {\n const {\n stateSearch\n } = this;\n return stateSearch.general.failedDownloads.enabled && ['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n search(episodes, searchType) {\n const {\n show\n } = this;\n let data = {};\n\n if (episodes) {\n data = {\n showSlug: show.id.slug,\n episodes: [],\n options: {}\n };\n episodes.forEach(episode => {\n data.episodes.push(episode.slug);\n this.$refs[`search-${episode.slug}`].src = 'images/loading16-dark.gif';\n });\n }\n\n this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef\n .then(_ => {\n if (episodes.length === 1) {\n console.info(`started search for show: ${show.id.slug} episode: ${episodes[0].slug}`);\n this.$refs[`search-${episodes[0].slug}`].src = 'images/queued.png';\n this.$refs[`search-${episodes[0].slug}`].disabled = true;\n } else {\n console.info('started a full backlog search');\n }\n }).catch(error => {\n console.error(String(error));\n episodes.forEach(episode => {\n data.episodes.push(episode.slug);\n this.$refs[`search-${episodes[0].slug}`].src = 'images/no16.png';\n });\n }).finally(() => {\n this.failedSearchEpisodes = [];\n this.backlogSearchEpisodes = [];\n });\n },\n\n /**\n * Start a backlog search or failed search for the specific episode.\n * A failed search is started depending on the current episodes status.\n * @param {Object} episode - Episode object. If no episode object is passed, a backlog search is started.\n */\n queueSearch(episode) {\n const {\n $modal,\n search,\n retryDownload\n } = this;\n const episodeIdentifier = episode.slug;\n\n if (episode) {\n if (this.$refs[`search-${episodeIdentifier}`].disabled === true) {\n return;\n }\n\n if (retryDownload(episode)) {\n $modal.show('query-mark-failed-and-search', {\n episode\n });\n } else {\n search([episode], 'backlog');\n }\n }\n },\n\n showSubtitleButton(episode) {\n const {\n subtitles,\n show\n } = this;\n return episode.season !== 0 && subtitles.enabled && show.config.subtitlesEnabled && !['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n totalSeasonEpisodeSize(season) {\n return season.children.filter(x => x.file && x.file.size > 0).reduce((a, b) => a + b.file.size, 0);\n },\n\n getSeasonExceptions(season) {\n const {\n show\n } = this;\n const {\n config\n } = show;\n const {\n aliases\n } = config;\n let bindData = {\n class: 'display: none'\n }; // Map the indexer season to a xem mapped season.\n // check if the season exception also exists in the xem numbering table\n\n let xemSeasons = [];\n let foundInXem = false;\n\n if (show.xemNumbering.length > 0) {\n const xemResult = show.xemNumbering.filter(x => x.source.season === season); // Create an array with unique seasons\n\n xemSeasons = [...new Set(xemResult.map(item => item.destination.season))];\n foundInXem = Boolean(xemSeasons.length);\n } // Check if there is a season exception for this season\n\n\n if (aliases.find(x => x.season === season)) {\n // If there is not a match on the xem table, display it as a medusa scene exception\n bindData = {\n id: `xem-exception-season-${foundInXem ? xemSeasons[0] : season}`,\n alt: foundInXem ? '[xem]' : '[medusa]',\n src: foundInXem ? 'images/xem.png' : 'images/ico/favicon-16.png',\n title: foundInXem ? xemSeasons.reduce((a, b) => {\n return a.concat(aliases.filter(alias => alias.season === b).map(alias => alias.title));\n }, []).join(', ') : aliases.filter(alias => alias.season === season).map(alias => alias.title).join(', ')\n };\n }\n\n return bindData;\n },\n\n updateEpisodeWatched(episode, watched) {\n const {\n showSlug,\n getEpisodes,\n show\n } = this;\n const patchData = {};\n patchData[episode.slug] = {\n watched\n };\n this.client.api.patch(`series/${show.id.slug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched episode ${episode.slug} with watched set to ${watched}`);\n getEpisodes({\n showSlug,\n season: episode.season\n });\n }).catch(error => {\n console.error(String(error));\n });\n episode.watched = watched;\n },\n\n updatePaginationPerPage(rows) {\n const {\n setCookie\n } = this;\n this.paginationPerPage = rows;\n setCookie('pagination-perPage', rows);\n },\n\n onPageChange(params) {\n if (params.prevPage !== params.currentPage) {\n this.loadEpisodes(params.currentPage);\n }\n },\n\n neededSeasons(page) {\n const {\n layout,\n paginationPerPage,\n show\n } = this;\n const {\n seasonCount\n } = show;\n\n if (!seasonCount || seasonCount.length === 0) {\n return [];\n }\n\n if (!layout.show.pagination.enable) {\n return seasonCount.filter(season => season.season !== 0).map(season => season.season).reverse();\n }\n\n const seasons = show.seasonCount.length - 1;\n let pagesCount = 1;\n let episodeCount = 0;\n const pages = {};\n\n for (let i = seasons; i >= 0; i--) {\n const {\n season\n } = show.seasonCount[i]; // Exclude specials\n\n if (season === 0) {\n break;\n }\n\n if (pagesCount in pages) {\n pages[pagesCount].push(season);\n } else {\n pages[pagesCount] = [season];\n }\n\n episodeCount += show.seasonCount[i].episodeCount;\n\n if (episodeCount / paginationPerPage > pagesCount) {\n pagesCount++;\n pages[pagesCount] = [season];\n }\n\n if (pagesCount > page) {\n break;\n }\n }\n\n return pages[page] || [];\n },\n\n loadEpisodes(page) {\n const {\n showSlug,\n getEpisodes\n } = this; // Wrap getEpisodes into an async/await function, so we can wait for the season to have been committed\n // before going on to the next one.\n\n const _getEpisodes = async showSlug => {\n for (const season of this.neededSeasons(page)) {\n // We're waiting for the results by design, to give vue the chance to update the dom.\n // If we fire all the promises at once for, for example 25 seasons. We'll overload medusa's app\n // and chance is high a number of requests will timeout.\n await getEpisodes({\n showSlug,\n season\n }); // eslint-disable-line no-await-in-loop\n }\n };\n\n _getEpisodes(showSlug);\n },\n\n initializeEpisodes() {\n let force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n const {\n getEpisodes,\n showSlug,\n setRecentShow,\n show\n } = this;\n\n if (force || !show.seasons && show.seasonCount) {\n // Load episodes for the first page.\n this.loadEpisodes(1); // Always get special episodes if available.\n\n if (show.seasonCount.length > 0 && show.seasonCount[0].season === 0) {\n getEpisodes({\n showSlug,\n season: 0\n });\n }\n }\n\n if (show.id.slug) {\n // For now i'm dumping this here\n setRecentShow({\n showSlug: show.id.slug,\n name: show.title\n });\n }\n },\n\n mobileSelectSearch(event, episode) {\n const {\n $snotify,\n $router,\n queueSearch,\n searchSubtitle,\n show\n } = this;\n\n if (event.target.value === 'forced') {\n queueSearch(episode);\n $snotify.success(`Search started for S${episode.season} E${episode.episode}`);\n }\n\n if (event.target.value === 'manual') {\n // Use the router to navigate to snatchSelection.\n $router.push({\n name: 'snatchSelection',\n query: {\n showslug: show.id.slug,\n season: episode.season,\n episode: episode.episode\n }\n });\n }\n\n if (event.target.value === 'subtitle') {\n searchSubtitle(event, episode);\n }\n\n setTimeout(() => {\n event.target.value = 'search action';\n }, 2000);\n }\n\n },\n filters: {\n sceneObjectToString(value) {\n return `${value.season}x${value.episode}`;\n }\n\n },\n watch: {\n $route(to, from) {\n if (to.name === 'show' && from.name === 'testRename') {\n // Load all episodes if we're coming from the testRename page.\n this.initializeEpisodes(true);\n }\n }\n\n }\n});\n\n//# sourceURL=webpack://slim/./src/components/display-show.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-1%5B0%5D.rules%5B0%5D!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash/debounce */ \"./node_modules/lodash/debounce.js\");\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.js\");\n/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ \"./src/components/helpers/index.js\");\n/* harmony import */ var _utils_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/core */ \"./src/utils/core.js\");\n/* harmony import */ var _mixins_manage_cookie__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mixins/manage-cookie */ \"./src/mixins/manage-cookie.js\");\n/* harmony import */ var _utils_jquery__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/jquery */ \"./src/utils/jquery.js\");\n/* harmony import */ var vue_good_table__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! vue-good-table */ \"./node_modules/vue-good-table/dist/vue-good-table.esm.js\");\n/* harmony import */ var _backstretch_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./backstretch.vue */ \"./src/components/backstretch.vue\");\n/* harmony import */ var _show_header_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./show-header.vue */ \"./src/components/show-header.vue\");\n/* harmony import */ var _subtitle_search_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./subtitle-search.vue */ \"./src/components/subtitle-search.vue\");\n/* harmony import */ var _helpers_quality_pill_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./helpers/quality-pill.vue */ \"./src/components/helpers/quality-pill.vue\");\n/* provided dependency */ var $ = __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'show',\n components: {\n AppLink: _helpers__WEBPACK_IMPORTED_MODULE_1__.AppLink,\n Backstretch: _backstretch_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"],\n PlotInfo: _helpers__WEBPACK_IMPORTED_MODULE_1__.PlotInfo,\n QualityPill: _helpers_quality_pill_vue__WEBPACK_IMPORTED_MODULE_8__[\"default\"],\n Search: _helpers__WEBPACK_IMPORTED_MODULE_1__.Search,\n SceneNumberInput: _helpers__WEBPACK_IMPORTED_MODULE_1__.SceneNumberInput,\n SceneNumberAnimeInput: _helpers__WEBPACK_IMPORTED_MODULE_1__.SceneNumberAnimeInput,\n ShowHeader: _show_header_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"],\n VueGoodTable: vue_good_table__WEBPACK_IMPORTED_MODULE_9__.VueGoodTable\n },\n mixins: [(0,_mixins_manage_cookie__WEBPACK_IMPORTED_MODULE_3__.manageCookieMixin)('displayShow')],\n\n metaInfo() {\n if (!this.show || !this.show.title) {\n return {\n title: 'Medusa'\n };\n }\n\n const {\n title\n } = this.show;\n return {\n title,\n titleTemplate: '%s | Medusa'\n };\n },\n\n props: {\n /**\n * Show Slug\n */\n slug: {\n type: String\n }\n },\n\n data() {\n const {\n getCookie\n } = this;\n const perPageDropdown = [25, 50, 100, 250, 500];\n\n const getPaginationPerPage = () => {\n const rows = getCookie('pagination-perPage');\n\n if (!rows) {\n return 50;\n }\n\n if (!perPageDropdown.includes(rows)) {\n return 500;\n }\n\n return rows;\n };\n\n return {\n invertTable: true,\n subtitleSearchComponents: [],\n columns: [{\n label: 'NFO',\n field: 'content.hasNfo',\n type: 'boolean',\n sortable: false,\n hidden: getCookie('NFO')\n }, {\n label: 'TBN',\n field: 'content.hasTbn',\n type: 'boolean',\n sortable: false,\n hidden: getCookie('TBN')\n }, {\n label: 'Episode',\n field: 'episode',\n type: 'number',\n hidden: getCookie('Episode')\n }, {\n label: 'Abs. #',\n field: 'absoluteNumber',\n type: 'number',\n hidden: getCookie('Abs. #')\n }, {\n label: 'Scene',\n field: 'scene',\n sortable: false,\n hidden: getCookie('Scene')\n }, {\n label: 'Scene Abs. #',\n field: 'sceneAbsolute',\n type: 'number',\n hidden: getCookie('Scene Abs. #')\n }, {\n label: 'Title',\n field: 'title',\n hidden: getCookie('Title')\n }, {\n label: 'File',\n field: 'file.location',\n hidden: getCookie('File')\n }, {\n label: 'Size',\n field: 'file.size',\n type: 'number',\n formatFn: _utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize,\n hidden: getCookie('Size')\n }, {\n // For now i'm using a custom function the parse it. As the type: date, isn't working for us.\n // But the goal is to have this user formatted (as configured in backend)\n label: 'Air date',\n field: this.parseDateFn,\n tdClass: 'align-center',\n sortable: false,\n hidden: getCookie('Air date')\n }, {\n label: 'Download',\n field: 'download',\n sortable: false,\n hidden: getCookie('Download')\n }, {\n label: 'Subtitles',\n field: 'subtitles',\n sortable: false,\n hidden: getCookie('Subtitles')\n }, {\n label: 'Status',\n field: 'status',\n hidden: getCookie('Status')\n }, {\n label: 'Search',\n field: 'search',\n sortable: false,\n hidden: getCookie('Search')\n }],\n perPageDropdown,\n paginationPerPage: getPaginationPerPage(),\n selectedEpisodes: [],\n // We need to keep track of which episode where trying to search, for the vue-modal\n failedSearchEpisodes: [],\n backlogSearchEpisodes: [],\n filterByOverviewStatus: false,\n selectedSearch: 'search action'\n };\n },\n\n computed: { ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapState)({\n shows: state => state.shows.shows,\n subtitles: state => state.config.subtitles,\n configLoaded: state => state.config.layout.fanartBackground !== null,\n layout: state => state.config.layout,\n stateSearch: state => state.config.search,\n client: state => state.auth.client\n }),\n ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapGetters)({\n show: 'getCurrentShow',\n getOverviewStatus: 'getOverviewStatus',\n fuzzyParseDateTime: 'fuzzyParseDateTime'\n }),\n\n showSlug() {\n const {\n slug\n } = this;\n return slug || this.$route.query.showslug;\n },\n\n theme() {\n const {\n layout\n } = this;\n const {\n themeName\n } = layout;\n return themeName || 'light';\n },\n\n orderedSeasons() {\n const {\n filterByOverviewStatus,\n invertTable,\n show\n } = this;\n\n if (!show.seasons) {\n return [];\n }\n\n const seasons = show.seasons.slice();\n let sortedSeasons = seasons.sort((a, b) => a.season - b.season).filter(season => season.season !== 0); // Use the filterOverviewStatus to filter the data based on what's checked in the show-header.\n\n if (filterByOverviewStatus && filterByOverviewStatus.filter(status => status.checked).length < filterByOverviewStatus.length) {\n const filteredSortedSeasons = [];\n\n for (const season of sortedSeasons) {\n const {\n children,\n ...res\n } = season;\n const filteredEpisodes = children.filter(episode => {\n const episodeOverviewStatus = this.getOverviewStatus(episode.status, episode.quality, show.config.qualities);\n const filteredStatus = filterByOverviewStatus.find(overviewStatus => overviewStatus.name === episodeOverviewStatus);\n return !filteredStatus || filteredStatus.checked;\n });\n filteredSortedSeasons.push(Object.assign({\n children: filteredEpisodes\n }, res));\n }\n\n sortedSeasons = filteredSortedSeasons;\n }\n\n if (invertTable) {\n return sortedSeasons.slice().reverse();\n }\n\n return sortedSeasons;\n },\n\n specials() {\n const {\n show\n } = this;\n\n if (!show.seasons) {\n return [];\n }\n\n return show.seasons.filter(season => season.season === 0);\n }\n\n },\n\n mounted() {\n this.loadShow();\n ['load', 'resize'].map(event => {\n return window.addEventListener(event, () => {\n this.reflowLayout();\n });\n });\n $(document.body).on('click', '.seasonCheck', event => {\n const seasCheck = event.currentTarget;\n const seasNo = $(seasCheck).attr('id');\n $('#collapseSeason-' + seasNo).collapse('show');\n const seasonIdentifier = 's' + seasNo;\n $('.epCheck:visible').each((index, element) => {\n const epParts = $(element).attr('id').split('e');\n\n if (epParts[0] === seasonIdentifier) {\n element.checked = seasCheck.checked;\n }\n });\n });\n },\n\n methods: {\n humanFileSize: _utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize,\n ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapActions)({\n getShow: 'getShow',\n // Map `this.getShow()` to `this.$store.dispatch('getShow')`\n getEpisodes: 'getEpisodes',\n setCurrentShow: 'setCurrentShow',\n setRecentShow: 'setRecentShow'\n }),\n\n async loadShow() {\n const {\n setCurrentShow,\n showSlug,\n initializeEpisodes,\n getShow\n } = this; // We need detailed info for the xem / scene exceptions, so let's get it.\n\n await getShow({\n showSlug,\n detailed: true\n }); // Let's tell the store which show we currently want as current.\n // Run this after getShow(), as it will trigger the initializeEpisodes() method.\n\n setCurrentShow(showSlug); // Load all episodes\n\n initializeEpisodes();\n },\n\n statusQualityUpdate(event) {\n const {\n selectedEpisodes,\n setStatus,\n setQuality\n } = this;\n\n if (event.newQuality !== null && event.newQuality !== 'Change quality to:') {\n setQuality(event.newQuality, selectedEpisodes);\n }\n\n if (event.newStatus !== null && event.newStatus !== 'Change status to:') {\n setStatus(event.newStatus, selectedEpisodes);\n }\n },\n\n setQuality(quality, episodes) {\n const {\n showSlug,\n getEpisodes,\n show\n } = this;\n const patchData = {};\n episodes.forEach(episode => {\n patchData[episode.slug] = {\n quality: Number.parseInt(quality, 10)\n };\n });\n this.client.api.patch(`series/${show.id.slug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched show ${show.id.slug} with quality ${quality}`);\n [...new Set(episodes.map(episode => episode.season))].forEach(season => {\n getEpisodes({\n showSlug,\n season\n });\n });\n }).catch(error => {\n console.error(String(error));\n });\n },\n\n setStatus(status, episodes) {\n const {\n showSlug,\n getEpisodes\n } = this;\n const patchData = {};\n episodes.forEach(episode => {\n patchData[episode.slug] = {\n status\n };\n });\n this.client.api.patch(`series/${showSlug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched show ${showSlug} with status ${status}`);\n [...new Set(episodes.map(episode => episode.season))].forEach(season => {\n getEpisodes({\n showSlug,\n season\n });\n });\n }).catch(error => {\n console.error(String(error));\n }); // New status Wanted\n\n if (status === 3) {\n this.$modal.show('query-start-backlog-search', {\n episodes\n });\n } // New status Failed\n\n\n if (status === 11) {\n this.$modal.show('query-mark-failed-and-search', {\n episodes\n });\n }\n },\n\n parseDateFn(row) {\n const {\n fuzzyParseDateTime\n } = this;\n return fuzzyParseDateTime(row.airDate);\n },\n\n rowStyleClassFn(row) {\n const {\n getOverviewStatus,\n show\n } = this;\n\n if (Object.keys(row).includes('vgt_header_id')) {\n return;\n }\n\n const overview = getOverviewStatus(row.status, row.quality, show.config.qualities).toLowerCase().trim();\n return overview;\n },\n\n /**\n * Add (reduce) the total episodes filesize.\n * @param {object} headerRow header row object.\n * @returns {string} - Human readable file size.\n */\n addFileSize(headerRow) {\n return (0,_utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize)(headerRow.children.reduce((a, b) => a + (b.file.size || 0), 0));\n },\n\n searchSubtitle(event, episode, lang) {\n const {\n showSlug,\n getEpisodes,\n show,\n subtitleSearchComponents\n } = this;\n const SubtitleSearchClass = vue__WEBPACK_IMPORTED_MODULE_11__[\"default\"].extend(_subtitle_search_vue__WEBPACK_IMPORTED_MODULE_7__[\"default\"]); // eslint-disable-line no-undef\n\n const instance = new SubtitleSearchClass({\n propsData: {\n show,\n episode,\n key: episode.originalIndex,\n lang\n },\n parent: this\n }); // Update the show, as we downloaded new subtitle(s)\n\n instance.$on('update', event => {\n // This could be replaced by the generic websocket updates in future.\n if (event.reason === 'new subtitles found') {\n getEpisodes({\n showSlug,\n season: episode.season\n });\n }\n });\n const node = document.createElement('div');\n const tableRef = episode.season === 0 ? 'table-specials' : 'table-seasons';\n this.$refs[tableRef].$refs[`row-${episode.originalIndex}`][0].after(node);\n instance.$mount(node);\n subtitleSearchComponents.push(instance);\n },\n\n /**\n * Attaches IMDB tooltip\n */\n reflowLayout: lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default()(() => {\n console.debug('Reflowing layout');\n (0,_utils_jquery__WEBPACK_IMPORTED_MODULE_4__.addQTip)(); // eslint-disable-line no-undef\n }, 1000),\n\n /**\n * Check if any of the episodes in this season does not have the status \"unaired\".\n * If that's the case we want to manual season search icon.\n * @param {object} season - A season object.\n * @returns {Boolean} - true if one of the seasons episodes has a status 'unaired'.\n */\n anyEpisodeNotUnaired(season) {\n return season.children.filter(ep => ep.status !== 'Unaired').length > 0;\n },\n\n episodesInverse(season) {\n const {\n invertTable\n } = this;\n\n if (!season.children) {\n return [];\n }\n\n if (invertTable) {\n return season.children.slice().reverse();\n }\n\n return season.children;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeBacklogSearchModalClose(event) {\n this.backlogSearchEpisodes = event.params.episodes;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeFailedSearchModalClose(event) {\n this.failedSearchEpisodes = event.params.episodes;\n },\n\n retryDownload(episode) {\n const {\n stateSearch\n } = this;\n return stateSearch.general.failedDownloads.enabled && ['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n search(episodes, searchType) {\n const {\n show\n } = this;\n let data = {};\n\n if (episodes) {\n data = {\n showSlug: show.id.slug,\n episodes: [],\n options: {}\n };\n episodes.forEach(episode => {\n data.episodes.push(episode.slug);\n this.$refs[`search-${episode.slug}`].src = 'images/loading16.gif';\n });\n }\n\n this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef\n .then(_ => {\n if (episodes.length === 1) {\n console.info(`started search for show: ${show.id.slug} episode: ${episodes[0].slug}`);\n this.$refs[`search-${episodes[0].slug}`].src = 'images/queued.png';\n this.$refs[`search-${episodes[0].slug}`].disabled = true;\n } else {\n console.info('started a full backlog search');\n }\n }).catch(error => {\n console.error(String(error));\n episodes.forEach(episode => {\n data.episodes.push(episode.slug);\n this.$refs[`search-${episodes[0].slug}`].src = 'images/no16.png';\n });\n }).finally(() => {\n this.failedSearchEpisodes = [];\n this.backlogSearchEpisodes = [];\n });\n },\n\n /**\n * Start a backlog search or failed search for the specific episode.\n * A failed search is started depending on the current episodes status.\n * @param {Object} episode - Episode object. If no episode object is passed, a backlog search is started.\n */\n queueSearch(episode) {\n const {\n $modal,\n search,\n retryDownload\n } = this;\n const episodeIdentifier = episode.slug;\n\n if (episode) {\n if (this.$refs[`search-${episodeIdentifier}`].disabled === true) {\n return;\n }\n\n if (retryDownload(episode)) {\n $modal.show('query-mark-failed-and-search', {\n episode\n });\n } else {\n search([episode], 'backlog');\n }\n }\n },\n\n showSubtitleButton(episode) {\n const {\n subtitles,\n show\n } = this;\n return episode.season !== 0 && subtitles.enabled && show.config.subtitlesEnabled && !['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n totalSeasonEpisodeSize(season) {\n return season.children.filter(x => x.file && x.file.size > 0).reduce((a, b) => a + b.file.size, 0);\n },\n\n getSeasonExceptions(season) {\n const {\n show\n } = this;\n const {\n config\n } = show;\n const {\n aliases\n } = config;\n let bindData = {\n class: 'display: none'\n }; // Map the indexer season to a xem mapped season.\n // check if the season exception also exists in the xem numbering table\n\n let xemSeasons = [];\n let foundInXem = false;\n\n if (show.xemNumbering.length > 0) {\n const xemResult = show.xemNumbering.filter(x => x.source.season === season); // Create an array with unique seasons\n\n xemSeasons = [...new Set(xemResult.map(item => item.destination.season))];\n foundInXem = Boolean(xemSeasons.length);\n } // Check if there is a season exception for this season\n\n\n if (aliases.find(x => x.season === season)) {\n // If there is not a match on the xem table, display it as a medusa scene exception\n bindData = {\n id: `xem-exception-season-${foundInXem ? xemSeasons[0] : season}`,\n alt: foundInXem ? '[xem]' : '[medusa]',\n src: foundInXem ? 'images/xem.png' : 'images/ico/favicon-16.png',\n title: foundInXem ? xemSeasons.reduce((a, b) => {\n return a.concat(aliases.filter(alias => alias.season === b).map(alias => alias.title));\n }, []).join(', ') : aliases.filter(alias => alias.season === season).map(alias => alias.title).join(', ')\n };\n }\n\n return bindData;\n },\n\n updateEpisodeWatched(episode, watched) {\n const {\n showSlug,\n getEpisodes,\n show\n } = this;\n const patchData = {};\n patchData[episode.slug] = {\n watched\n };\n this.client.api.patch(`series/${show.id.slug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched episode ${episode.slug} with watched set to ${watched}`);\n getEpisodes({\n showSlug,\n season: episode.season\n });\n }).catch(error => {\n console.error(String(error));\n });\n episode.watched = watched;\n },\n\n updatePaginationPerPage(rows) {\n const {\n setCookie\n } = this;\n this.paginationPerPage = rows;\n setCookie('pagination-perPage', rows);\n },\n\n onPageChange(params) {\n if (params.prevPage !== params.currentPage) {\n this.loadEpisodes(params.currentPage);\n }\n },\n\n neededSeasons(page) {\n const {\n layout,\n paginationPerPage,\n show\n } = this;\n const {\n seasonCount\n } = show;\n\n if (!seasonCount || seasonCount.length === 0) {\n return [];\n }\n\n if (!layout.show.pagination.enable) {\n return seasonCount.filter(season => season.season !== 0).map(season => season.season).reverse();\n }\n\n const seasons = show.seasonCount.length - 1;\n let pagesCount = 1;\n let episodeCount = 0;\n const pages = {};\n\n for (let i = seasons; i >= 0; i--) {\n const {\n season\n } = show.seasonCount[i]; // Exclude specials\n\n if (season === 0) {\n break;\n }\n\n if (pagesCount in pages) {\n pages[pagesCount].push(season);\n } else {\n pages[pagesCount] = [season];\n }\n\n episodeCount += show.seasonCount[i].episodeCount;\n\n if (episodeCount / paginationPerPage > pagesCount) {\n pagesCount++;\n pages[pagesCount] = [season];\n }\n\n if (pagesCount > page) {\n break;\n }\n }\n\n return pages[page] || [];\n },\n\n loadEpisodes(page) {\n const {\n showSlug,\n getEpisodes\n } = this; // Wrap getEpisodes into an async/await function, so we can wait for the season to have been committed\n // before going on to the next one.\n\n const _getEpisodes = async showSlug => {\n for (const season of this.neededSeasons(page)) {\n // We're waiting for the results by design, to give vue the chance to update the dom.\n // If we fire all the promises at once for, for example 25 seasons. We'll overload medusa's app\n // and chance is high a number of requests will timeout.\n await getEpisodes({\n showSlug,\n season\n }); // eslint-disable-line no-await-in-loop\n }\n };\n\n _getEpisodes(showSlug);\n },\n\n initializeEpisodes() {\n let force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n const {\n getEpisodes,\n showSlug,\n setRecentShow,\n show\n } = this;\n\n if (force || !show.seasons && show.seasonCount) {\n // Load episodes for the first page.\n this.loadEpisodes(1); // Always get special episodes if available.\n\n if (show.seasonCount.length > 0 && show.seasonCount[0].season === 0) {\n getEpisodes({\n showSlug,\n season: 0\n });\n }\n }\n\n if (show.id.slug) {\n // For now i'm dumping this here\n setRecentShow({\n showSlug: show.id.slug,\n name: show.title\n });\n }\n },\n\n mobileSelectSearch(event, episode) {\n const {\n $snotify,\n $router,\n queueSearch,\n searchSubtitle,\n show\n } = this;\n\n if (event.target.value === 'forced') {\n queueSearch(episode);\n $snotify.success(`Search started for S${episode.season} E${episode.episode}`);\n }\n\n if (event.target.value === 'manual') {\n // Use the router to navigate to snatchSelection.\n $router.push({\n name: 'snatchSelection',\n query: {\n showslug: show.id.slug,\n season: episode.season,\n episode: episode.episode\n }\n });\n }\n\n if (event.target.value === 'subtitle') {\n searchSubtitle(event, episode);\n }\n\n setTimeout(() => {\n event.target.value = 'search action';\n }, 2000);\n }\n\n },\n filters: {\n sceneObjectToString(value) {\n return `${value.season}x${value.episode}`;\n }\n\n },\n watch: {\n $route(to, from) {\n if (to.name === 'show' && from.name === 'testRename') {\n // Load all episodes if we're coming from the testRename page.\n this.initializeEpisodes(true);\n }\n }\n\n }\n});\n\n//# sourceURL=webpack://slim/./src/components/display-show.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-1%5B0%5D.rules%5B0%5D!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), @@ -620,7 +620,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n/* harmony import */ var _app_link_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./app-link.vue */ \"./src/components/helpers/app-link.vue\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'select-list',\n components: {\n AppLink: _app_link_vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]\n },\n props: {\n searchType: {\n type: String,\n default: 'forced',\n required: true,\n validator: value => ['backlog', 'manual'].includes(value)\n },\n showSlug: {\n type: String,\n required: true\n },\n episode: {\n type: Object,\n required: true\n }\n },\n\n data() {\n return {\n subtitleComponentInstance: null,\n failedSearchEpisodes: [],\n backlogSearchEpisodes: []\n };\n },\n\n computed: { ...(0,vuex__WEBPACK_IMPORTED_MODULE_1__.mapState)({\n stateSearch: state => state.config.search\n })\n },\n methods: {\n retryDownload(episode) {\n const {\n stateSearch\n } = this;\n return stateSearch.general.failedDownloads.enabled && ['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n search(episode, searchType) {\n const {\n showSlug\n } = this;\n let data = {};\n data = {\n showSlug,\n episodes: [episode.slug],\n options: {}\n };\n this.$refs[`search-${episode.slug}`].src = 'images/loading16-dark.gif';\n this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`started search for show: ${showSlug} episode: ${episode.slug}`);\n this.$refs[`search-${episode.slug}`].src = 'images/queued.png';\n this.$refs[`search-${episode.slug}`].disabled = true;\n }).catch(error => {\n console.error(String(error));\n this.$refs[`search-${episode.slug}`].src = 'images/no16.png';\n }).finally(() => {\n this.failedSearchEpisodes = [];\n this.backlogSearchEpisodes = [];\n });\n },\n\n /**\n * Start a backlog search or failed search for the specific episode.\n * A failed search is started depending on the current episodes status.\n * @param {Object} episode - Episode object. If no episode object is passed, a backlog search is started.\n */\n queueSearch(episode) {\n const {\n $modal,\n search,\n retryDownload\n } = this;\n const episodeIdentifier = episode.slug;\n\n if (episode) {\n if (this.$refs[`search-${episodeIdentifier}`].disabled === true) {\n return;\n }\n\n if (retryDownload(episode)) {\n $modal.show('query-mark-failed-and-search', {\n episode\n });\n } else {\n search(episode, 'backlog');\n }\n }\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeBacklogSearchModalClose(event) {\n this.backlogSearchEpisodes = event.params.episodes;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeFailedSearchModalClose(event) {\n this.failedSearchEpisodes = event.params.episodes;\n }\n\n }\n});\n\n//# sourceURL=webpack://slim/./src/components/helpers/search.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-1%5B0%5D.rules%5B0%5D!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n/* harmony import */ var _app_link_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./app-link.vue */ \"./src/components/helpers/app-link.vue\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'search',\n components: {\n AppLink: _app_link_vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]\n },\n props: {\n searchType: {\n type: String,\n default: 'forced',\n required: true,\n validator: value => ['backlog', 'manual'].includes(value)\n },\n showSlug: {\n type: String,\n required: true\n },\n episode: {\n type: Object,\n required: true\n }\n },\n\n data() {\n return {\n subtitleComponentInstance: null,\n failedSearchEpisodes: [],\n backlogSearchEpisodes: [],\n src: 'images/search16.png',\n disabled: false\n };\n },\n\n computed: { ...(0,vuex__WEBPACK_IMPORTED_MODULE_1__.mapState)({\n stateSearch: state => state.config.search,\n client: state => state.auth.client,\n queueitems: state => state.queue.queueitems\n })\n },\n methods: {\n retryDownload(episode) {\n const {\n stateSearch\n } = this;\n return stateSearch.general.failedDownloads.enabled && ['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n search(episode, searchType) {\n const {\n showSlug\n } = this;\n let data = {};\n data = {\n showSlug,\n episodes: [episode.slug],\n options: {}\n };\n this.src = 'images/loading16-dark.gif';\n this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`Queued search for show: ${showSlug} episode: ${episode.slug}`);\n this.src = 'images/queued.png';\n this.disabled = true;\n }).catch(error => {\n console.error(String(error));\n this.$refs[`search-${episode.slug}`].src = 'images/no16.png';\n }).finally(() => {\n this.failedSearchEpisodes = [];\n this.backlogSearchEpisodes = [];\n });\n },\n\n /**\n * Start a backlog search or failed search for the specific episode.\n * A failed search is started depending on the current episodes status.\n * @param {Object} episode - Episode object. If no episode object is passed, a backlog search is started.\n */\n queueSearch(episode) {\n const {\n $modal,\n search,\n retryDownload\n } = this;\n\n if (episode) {\n if (this.disabled === true) {\n return;\n }\n\n if (retryDownload(episode)) {\n $modal.show('query-mark-failed-and-search', {\n episode\n });\n } else {\n search(episode, 'backlog');\n }\n }\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeBacklogSearchModalClose(event) {\n this.backlogSearchEpisodes = event.params.episodes;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeFailedSearchModalClose(event) {\n this.failedSearchEpisodes = event.params.episodes;\n }\n\n },\n watch: {\n queueitems(queueitems) {\n const episode = queueitems.filter(q => q.name === 'BACKLOG' && q.show.id.slug === this.showSlug && q.segment.find(s => s.slug === this.episode.slug));\n\n if (episode.length === 0) {\n return;\n }\n\n const lastEp = episode.slice(-1)[0];\n\n if (lastEp.inProgress && lastEp.success === null) {\n // Search is in progress.\n console.info(`Search runnning for show: ${this.showSlug} and episode: ${this.episode.slug}`);\n this.src = 'images/loading16.gif';\n this.disabled = true;\n } else {\n // Search finished.\n console.log(`Search finished for ${this.episode.slug}`);\n this.src = 'images/yes16.png';\n this.disabled = false;\n }\n }\n\n }\n});\n\n//# sourceURL=webpack://slim/./src/components/helpers/search.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-1%5B0%5D.rules%5B0%5D!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), @@ -7495,7 +7495,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"display-show-template\", class: _vm.theme },\n [\n _c(\"vue-snotify\"),\n _vm._v(\" \"),\n _vm.show.id.slug\n ? _c(\"backstretch\", {\n key: _vm.show.id.slug,\n attrs: { slug: _vm.show.id.slug }\n })\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"series-id\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"indexer-name\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"series-slug\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"show-header\", {\n ref: \"show-header\",\n attrs: { type: \"show\", slug: _vm.showSlug },\n on: {\n reflow: _vm.reflowLayout,\n update: _vm.statusQualityUpdate,\n \"update-overview-status\": function($event) {\n _vm.filterByOverviewStatus = $event\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"div\",\n { staticClass: \"col-md-12 top-15 displayShow horizontal-scroll\" },\n [\n _vm.show.seasons\n ? _c(\"vue-good-table\", {\n ref: \"table-seasons\",\n attrs: {\n columns: _vm.columns,\n rows: _vm.orderedSeasons,\n groupOptions: {\n enabled: true,\n mode: \"span\"\n },\n \"pagination-options\": {\n enabled: _vm.layout.show.pagination.enable,\n perPage: _vm.paginationPerPage,\n perPageDropdown: _vm.perPageDropdown\n },\n \"search-options\": {\n enabled: true,\n trigger: \"enter\",\n skipDiacritics: false,\n placeholder: \"Search episodes\"\n },\n \"sort-options\": {\n enabled: true,\n initialSortBy: _vm.getSortBy(\"episode\", \"desc\")\n },\n selectOptions: {\n enabled: true,\n selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row\n selectionInfoClass: \"select-info\",\n selectionText: \"episodes selected\",\n clearSelectionText: \"clear\",\n selectAllByGroup: true\n },\n \"row-style-class\": _vm.rowStyleClassFn,\n \"column-filter-options\": {\n enabled: true\n }\n },\n on: {\n \"on-selected-rows-change\": function($event) {\n _vm.selectedEpisodes = $event.selectedRows\n },\n \"on-per-page-change\": function($event) {\n return _vm.updatePaginationPerPage($event.currentPerPage)\n },\n \"on-page-change\": _vm.onPageChange\n },\n scopedSlots: _vm._u(\n [\n {\n key: \"table-header-row\",\n fn: function(props) {\n return [\n _c(\n \"h3\",\n { staticClass: \"season-header toggle collapse\" },\n [\n _c(\"app-link\", {\n attrs: { name: \"season-\" + props.row.season }\n }),\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.row.season > 0\n ? \"Season \" + props.row.season\n : \"Specials\"\n ) +\n \"\\n \"\n ),\n _vm._v(\" \"),\n _vm.anyEpisodeNotUnaired(props.row)\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=1&manual_search_type=season\"\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src:\n \"images/manualsearch-white.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", {\n staticClass: \"season-scene-exception\",\n attrs: {\n \"data-season\":\n props.row.season > 0\n ? props.row.season\n : \"Specials\"\n }\n }),\n _vm._v(\" \"),\n _c(\n \"img\",\n _vm._b(\n {},\n \"img\",\n _vm.getSeasonExceptions(props.row.season),\n false\n )\n )\n ],\n 1\n )\n ]\n }\n },\n {\n key: \"table-footer-row\",\n fn: function(ref) {\n var headerRow = ref.headerRow\n return [\n _c(\n \"tr\",\n {\n staticClass: \"seasoncols border-bottom shadow\",\n attrs: {\n colspan: \"9999\",\n id: \"season-\" + headerRow.season + \"-footer\"\n }\n },\n [\n _c(\n \"th\",\n {\n staticClass: \"col-footer\",\n attrs: { colspan: \"15\", align: \"left\" }\n },\n [\n _vm._v(\n \"Season contains \" +\n _vm._s(headerRow.children.length) +\n \" episodes with total filesize: \" +\n _vm._s(_vm.addFileSize(headerRow))\n )\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"spacer\" })\n ]\n }\n },\n {\n key: \"table-row\",\n fn: function(props) {\n return [\n props.column.field == \"content.hasNfo\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasNfo\n ? \"nfo.gif\"\n : \"nfo-no.gif\"),\n alt: props.row.content.hasNfo ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.field == \"content.hasTbn\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasTbn\n ? \"tbn.gif\"\n : \"tbn-no.gif\"),\n alt: props.row.content.hasTbn ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.label == \"Episode\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n class: {\n addQTip: props.row.file.location !== \"\"\n },\n attrs: {\n title:\n props.row.file.location !== \"\"\n ? props.row.file.location\n : \"\"\n }\n },\n [_vm._v(_vm._s(props.row.episode))]\n )\n ])\n : props.column.label == \"Scene\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Scene Abs. #\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-anime-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Title\"\n ? _c(\n \"span\",\n [\n props.row.description !== \"\"\n ? _c(\"plot-info\", {\n attrs: {\n description: props.row.description,\n \"show-slug\": _vm.show.id.slug,\n season: props.row.season,\n episode: props.row.episode\n }\n })\n : _vm._e(),\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.title) +\n \"\\n \"\n )\n ],\n 1\n )\n : props.column.label == \"File\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: { title: props.row.file.location }\n },\n [_vm._v(_vm._s(props.row.file.name))]\n )\n ])\n : props.column.label == \"Subtitles\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n [\n \"Archived\",\n \"Downloaded\",\n \"Ignored\",\n \"Skipped\"\n ].includes(props.row.status)\n ? _c(\n \"div\",\n { staticClass: \"subtitles\" },\n _vm._l(props.row.subtitles, function(\n flag\n ) {\n return _c(\"div\", { key: flag }, [\n flag !== \"und\"\n ? _c(\"img\", {\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: flag,\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row,\n flag\n )\n }\n }\n })\n : _c(\"img\", {\n staticClass: \"subtitle-flag\",\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: flag,\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n }\n })\n ])\n }),\n 0\n )\n : _vm._e()\n ])\n : props.column.label == \"Status\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"pull-left\" },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.status) +\n \"\\n \"\n ),\n props.row.quality !== 0\n ? _c(\"quality-pill\", {\n attrs: {\n quality: props.row.quality\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n props.row.status !== \"Unaired\"\n ? _c(\"img\", {\n staticClass: \"addQTip\",\n staticStyle: {\n \"margin-left\": \"5px\"\n },\n attrs: {\n title: props.row.watched\n ? \"This episode has been flagged as watched\"\n : \"\",\n src:\n \"images/\" +\n (props.row.watched\n ? \"\"\n : \"not\") +\n \"watched.png\",\n width: \"16\",\n height: \"16\"\n },\n on: {\n click: function($event) {\n return _vm.updateEpisodeWatched(\n props.row,\n !props.row.watched\n )\n }\n }\n })\n : _vm._e()\n ],\n 1\n )\n ])\n : props.column.field == \"search\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"full-width\" },\n [\n _c(\"img\", {\n ref: \"search-\" + props.row.slug,\n staticClass: \"epForcedSearch\",\n attrs: {\n id:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n name:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n src: \"images/search16.png\",\n height: \"16\",\n alt: _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\",\n title: _vm.retryDownload(props.row)\n ? \"Retry Download\"\n : \"Forced Seach\"\n },\n on: {\n click: function($event) {\n return _vm.queueSearch(props.row)\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n id:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n name:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=\" +\n props.row.episode\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src: \"images/manualsearch.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n ),\n _vm._v(\" \"),\n _c(\"img\", {\n attrs: {\n src: \"images/closed_captioning.png\",\n height: \"16\",\n alt: \"search subtitles\",\n title: \"Search Subtitles\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row\n )\n }\n }\n })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"mobile\" }, [\n _c(\n \"select\",\n {\n staticClass:\n \"form-control input-sm mobile-select\",\n attrs: { name: \"search-select\" },\n on: {\n change: function($event) {\n return _vm.mobileSelectSearch(\n $event,\n props.row\n )\n }\n }\n },\n [\n _c(\n \"option\",\n {\n attrs: {\n disabled: \"\",\n selected: \"\",\n value: \"search action\"\n }\n },\n [_vm._v(\"search action\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"forced\" } },\n [\n _vm._v(\n _vm._s(\n _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\"\n )\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"manual\" } },\n [_vm._v(\"manual\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"subtitle\" } },\n [_vm._v(\"subtitle\")]\n )\n ]\n )\n ])\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.formattedRow[props.column.field]\n ) +\n \"\\n \"\n )\n ])\n ]\n }\n },\n {\n key: \"table-column\",\n fn: function(props) {\n return [\n props.column.label == \"Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : props.column.label == \"Scene Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Scene Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(props.column.label) +\n \"\\n \"\n )\n ])\n ]\n }\n }\n ],\n null,\n false,\n 920757038\n )\n })\n : _vm._e(),\n _vm._v(\" \"),\n _vm.layout.show.specials && _vm.specials && _vm.specials.length > 0\n ? _c(\"vue-good-table\", {\n ref: \"table-specials\",\n attrs: {\n columns: _vm.columns,\n rows: _vm.specials,\n groupOptions: {\n enabled: true,\n mode: \"span\",\n customChildObject: \"episodes\"\n },\n \"pagination-options\": {\n enabled: false\n },\n \"search-options\": {\n enabled: true,\n trigger: \"enter\",\n skipDiacritics: false,\n placeholder: \"Search specials\"\n },\n \"sort-options\": {\n enabled: true,\n multipleColumns: true,\n initialSortBy: _vm.getSortBy(\"episode\", \"desc\") // From mixin manage-cookie.js\n },\n selectOptions: {\n enabled: true,\n selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row\n selectionInfoClass: \"select-info\",\n selectionText: \"episodes selected\",\n clearSelectionText: \"clear\",\n selectAllByGroup: true\n },\n \"row-style-class\": _vm.rowStyleClassFn,\n \"column-filter-options\": {\n enabled: false\n }\n },\n on: {\n \"on-selected-rows-change\": function($event) {\n _vm.selectedEpisodes = $event.selectedRows\n }\n },\n scopedSlots: _vm._u(\n [\n {\n key: \"table-header-row\",\n fn: function(props) {\n return [\n _c(\n \"h3\",\n { staticClass: \"season-header toggle collapse\" },\n [\n _c(\"app-link\", {\n attrs: { name: \"season-\" + props.row.season }\n }),\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.row.season > 0\n ? \"Season \" + props.row.season\n : \"Specials\"\n ) +\n \"\\n \"\n ),\n _vm._v(\" \"),\n _vm.anyEpisodeNotUnaired(props.row)\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=1&manual_search_type=season\"\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src:\n \"images/manualsearch-white.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", {\n staticClass: \"season-scene-exception\",\n attrs: {\n \"data-season\":\n props.row.season > 0\n ? props.row.season\n : \"Specials\"\n }\n }),\n _vm._v(\" \"),\n _c(\n \"img\",\n _vm._b(\n {},\n \"img\",\n _vm.getSeasonExceptions(props.row.season),\n false\n )\n )\n ],\n 1\n )\n ]\n }\n },\n {\n key: \"table-footer-row\",\n fn: function(ref) {\n var headerRow = ref.headerRow\n return [\n _c(\n \"tr\",\n {\n staticClass: \"seasoncols border-bottom shadow\",\n attrs: {\n colspan: \"9999\",\n id: \"season-\" + headerRow.season + \"-footer\"\n }\n },\n [\n _c(\n \"th\",\n {\n staticClass: \"col-footer\",\n attrs: { colspan: \"15\", align: \"left\" }\n },\n [\n _vm._v(\n \"Season contains \" +\n _vm._s(headerRow.children.length) +\n \" episodes with total filesize: \" +\n _vm._s(_vm.addFileSize(headerRow))\n )\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"spacer\" })\n ]\n }\n },\n {\n key: \"table-row\",\n fn: function(props) {\n return [\n props.column.field == \"content.hasNfo\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasNfo\n ? \"nfo.gif\"\n : \"nfo-no.gif\"),\n alt: props.row.content.hasNfo ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.field == \"content.hasTbn\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasTbn\n ? \"tbn.gif\"\n : \"tbn-no.gif\"),\n alt: props.row.content.hasTbn ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.label == \"Episode\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n class: {\n addQTip: props.row.file.location !== \"\"\n },\n attrs: {\n title:\n props.row.file.location !== \"\"\n ? props.row.file.location\n : \"\"\n }\n },\n [_vm._v(_vm._s(props.row.episode))]\n )\n ])\n : props.column.label == \"Scene\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Scene Abs. #\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-anime-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Title\"\n ? _c(\n \"span\",\n [\n props.row.description !== \"\"\n ? _c(\"plot-info\", {\n attrs: {\n description: props.row.description,\n \"show-slug\": _vm.show.id.slug,\n season: props.row.season,\n episode: props.row.episode\n }\n })\n : _vm._e(),\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.title) +\n \"\\n \"\n )\n ],\n 1\n )\n : props.column.label == \"File\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: { title: props.row.file.location }\n },\n [_vm._v(_vm._s(props.row.file.name))]\n )\n ])\n : props.column.label == \"Subtitles\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n [\n \"Archived\",\n \"Downloaded\",\n \"Ignored\",\n \"Skipped\"\n ].includes(props.row.status)\n ? _c(\n \"div\",\n { staticClass: \"subtitles\" },\n _vm._l(props.row.subtitles, function(\n flag\n ) {\n return _c(\"div\", { key: flag }, [\n flag !== \"und\"\n ? _c(\"img\", {\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: \"{flag}\",\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row,\n flag\n )\n }\n }\n })\n : _c(\"img\", {\n staticClass: \"subtitle-flag\",\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: \"flag\",\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n }\n })\n ])\n }),\n 0\n )\n : _vm._e()\n ])\n : props.column.label == \"Status\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n _c(\n \"div\",\n { staticClass: \"pull-left\" },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.status) +\n \"\\n \"\n ),\n props.row.quality !== 0\n ? _c(\"quality-pill\", {\n staticClass: \"quality-margins\",\n attrs: {\n quality: props.row.quality\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n props.row.status !== \"Unaired\"\n ? _c(\"img\", {\n staticClass: \"addQTip\",\n attrs: {\n title: props.row.watched\n ? \"This episode has been flagged as watched\"\n : \"\",\n src:\n \"images/\" +\n (props.row.watched\n ? \"\"\n : \"not\") +\n \"watched.png\",\n width: \"16\"\n },\n on: {\n click: function($event) {\n return _vm.updateEpisodeWatched(\n props.row,\n !props.row.watched\n )\n }\n }\n })\n : _vm._e()\n ],\n 1\n )\n ])\n : props.column.field == \"search\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"full-width\" },\n [\n _c(\"img\", {\n ref: \"search-\" + props.row.slug,\n staticClass: \"epForcedSearch\",\n attrs: {\n id:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n name:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n src: \"images/search16.png\",\n height: \"16\",\n alt: _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\",\n title: _vm.retryDownload(props.row)\n ? \"Retry Download\"\n : \"Forced Seach\"\n },\n on: {\n click: function($event) {\n return _vm.queueSearch(props.row)\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n id:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n name:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=\" +\n props.row.episode\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src: \"images/manualsearch.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n ),\n _vm._v(\" \"),\n _c(\"img\", {\n attrs: {\n src: \"images/closed_captioning.png\",\n height: \"16\",\n alt: \"search subtitles\",\n title: \"Search Subtitles\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row\n )\n }\n }\n })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"mobile\" }, [\n _c(\n \"select\",\n {\n staticClass:\n \"form-control input-sm mobile-select\",\n attrs: { name: \"search-select\" },\n on: {\n change: function($event) {\n return _vm.mobileSelectSearch(\n $event,\n props.row\n )\n }\n }\n },\n [\n _c(\n \"option\",\n {\n attrs: {\n disabled: \"\",\n selected: \"\",\n value: \"search action\"\n }\n },\n [_vm._v(\"search action\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"forced\" } },\n [\n _vm._v(\n _vm._s(\n _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\"\n )\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"manual\" } },\n [_vm._v(\"manual\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"subtitle\" } },\n [_vm._v(\"subtitle\")]\n )\n ]\n )\n ])\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.formattedRow[props.column.field]\n ) +\n \"\\n \"\n )\n ])\n ]\n }\n },\n {\n key: \"table-column\",\n fn: function(props) {\n return [\n props.column.label == \"Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : props.column.label == \"Scene Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Scene Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(props.column.label) +\n \"\\n \"\n )\n ])\n ]\n }\n }\n ],\n null,\n false,\n 2545500086\n )\n })\n : _vm._e()\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-start-backlog-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeBacklogSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-hidden\": \"true\"\n }\n },\n [_vm._v(\"×\")]\n ),\n _vm._v(\" \"),\n _c(\"h4\", { staticClass: \"modal-title\" }, [\n _vm._v(\"Start search?\")\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [\n _vm._v(\n \"Some episodes have been changed to 'Wanted'. Do you want to trigger a backlog search for these \" +\n _vm._s(_vm.backlogSearchEpisodes.length) +\n \" episode(s)\"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.backlogSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-mark-failed-and-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeFailedSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _vm._v(\n \"\\n Mark episode as failed and search?\\n \"\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [_vm._v(\"Starting to search for the episode\")]),\n _vm._v(\" \"),\n _vm.failedSearchEpisodes &&\n _vm.failedSearchEpisodes.length === 1\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episode \" +\n _vm._s(_vm.failedSearchEpisodes[0].slug) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm.failedSearchEpisodes\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episodes \" +\n _vm._s(\n _vm.failedSearchEpisodes\n .map(function(ep) {\n return ep.slug\n })\n .join(\", \")\n ) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"failed\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\n \"query-mark-failed-and-search\"\n )\n }\n }\n },\n [_vm._v(\"Cancel\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://slim/./src/components/display-show.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"display-show-template\", class: _vm.theme },\n [\n _c(\"vue-snotify\"),\n _vm._v(\" \"),\n _vm.show.id.slug\n ? _c(\"backstretch\", {\n key: _vm.show.id.slug,\n attrs: { slug: _vm.show.id.slug }\n })\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"series-id\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"indexer-name\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"series-slug\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"show-header\", {\n ref: \"show-header\",\n attrs: { type: \"show\", slug: _vm.showSlug },\n on: {\n reflow: _vm.reflowLayout,\n update: _vm.statusQualityUpdate,\n \"update-overview-status\": function($event) {\n _vm.filterByOverviewStatus = $event\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"div\",\n { staticClass: \"col-md-12 top-15 displayShow horizontal-scroll\" },\n [\n _vm.show.seasons\n ? _c(\"vue-good-table\", {\n ref: \"table-seasons\",\n attrs: {\n columns: _vm.columns,\n rows: _vm.orderedSeasons,\n groupOptions: {\n enabled: true,\n mode: \"span\"\n },\n \"pagination-options\": {\n enabled: _vm.layout.show.pagination.enable,\n perPage: _vm.paginationPerPage,\n perPageDropdown: _vm.perPageDropdown\n },\n \"search-options\": {\n enabled: true,\n trigger: \"enter\",\n skipDiacritics: false,\n placeholder: \"Search episodes\"\n },\n \"sort-options\": {\n enabled: true,\n initialSortBy: _vm.getSortBy(\"episode\", \"desc\")\n },\n selectOptions: {\n enabled: true,\n selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row\n selectionInfoClass: \"select-info\",\n selectionText: \"episodes selected\",\n clearSelectionText: \"clear\",\n selectAllByGroup: true\n },\n \"row-style-class\": _vm.rowStyleClassFn,\n \"column-filter-options\": {\n enabled: true\n }\n },\n on: {\n \"on-selected-rows-change\": function($event) {\n _vm.selectedEpisodes = $event.selectedRows\n },\n \"on-per-page-change\": function($event) {\n return _vm.updatePaginationPerPage($event.currentPerPage)\n },\n \"on-page-change\": _vm.onPageChange\n },\n scopedSlots: _vm._u(\n [\n {\n key: \"table-header-row\",\n fn: function(props) {\n return [\n _c(\n \"h3\",\n { staticClass: \"season-header toggle collapse\" },\n [\n _c(\"app-link\", {\n attrs: { name: \"season-\" + props.row.season }\n }),\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.row.season > 0\n ? \"Season \" + props.row.season\n : \"Specials\"\n ) +\n \"\\n \"\n ),\n _vm._v(\" \"),\n _vm.anyEpisodeNotUnaired(props.row)\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=1&manual_search_type=season\"\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src:\n \"images/manualsearch-white.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", {\n staticClass: \"season-scene-exception\",\n attrs: {\n \"data-season\":\n props.row.season > 0\n ? props.row.season\n : \"Specials\"\n }\n }),\n _vm._v(\" \"),\n _c(\n \"img\",\n _vm._b(\n {},\n \"img\",\n _vm.getSeasonExceptions(props.row.season),\n false\n )\n )\n ],\n 1\n )\n ]\n }\n },\n {\n key: \"table-footer-row\",\n fn: function(ref) {\n var headerRow = ref.headerRow\n return [\n _c(\n \"tr\",\n {\n staticClass: \"seasoncols border-bottom shadow\",\n attrs: {\n colspan: \"9999\",\n id: \"season-\" + headerRow.season + \"-footer\"\n }\n },\n [\n _c(\n \"th\",\n {\n staticClass: \"col-footer\",\n attrs: { colspan: \"15\", align: \"left\" }\n },\n [\n _vm._v(\n \"Season contains \" +\n _vm._s(headerRow.children.length) +\n \" episodes with total filesize: \" +\n _vm._s(_vm.addFileSize(headerRow))\n )\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"spacer\" })\n ]\n }\n },\n {\n key: \"table-row\",\n fn: function(props) {\n return [\n props.column.field == \"content.hasNfo\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasNfo\n ? \"nfo.gif\"\n : \"nfo-no.gif\"),\n alt: props.row.content.hasNfo ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.field == \"content.hasTbn\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasTbn\n ? \"tbn.gif\"\n : \"tbn-no.gif\"),\n alt: props.row.content.hasTbn ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.label == \"Episode\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n class: {\n addQTip: props.row.file.location !== \"\"\n },\n attrs: {\n title:\n props.row.file.location !== \"\"\n ? props.row.file.location\n : \"\"\n }\n },\n [_vm._v(_vm._s(props.row.episode))]\n )\n ])\n : props.column.label == \"Scene\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Scene Abs. #\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-anime-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Title\"\n ? _c(\n \"span\",\n [\n props.row.description !== \"\"\n ? _c(\"plot-info\", {\n attrs: {\n description: props.row.description,\n \"show-slug\": _vm.show.id.slug,\n season: props.row.season,\n episode: props.row.episode\n }\n })\n : _vm._e(),\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.title) +\n \"\\n \"\n )\n ],\n 1\n )\n : props.column.label == \"File\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: { title: props.row.file.location }\n },\n [_vm._v(_vm._s(props.row.file.name))]\n )\n ])\n : props.column.label == \"Subtitles\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n [\n \"Archived\",\n \"Downloaded\",\n \"Ignored\",\n \"Skipped\"\n ].includes(props.row.status)\n ? _c(\n \"div\",\n { staticClass: \"subtitles\" },\n _vm._l(props.row.subtitles, function(\n flag\n ) {\n return _c(\"div\", { key: flag }, [\n flag !== \"und\"\n ? _c(\"img\", {\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: flag,\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row,\n flag\n )\n }\n }\n })\n : _c(\"img\", {\n staticClass: \"subtitle-flag\",\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: flag,\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n }\n })\n ])\n }),\n 0\n )\n : _vm._e()\n ])\n : props.column.label == \"Status\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"pull-left\" },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.status) +\n \"\\n \"\n ),\n props.row.quality !== 0\n ? _c(\"quality-pill\", {\n attrs: {\n quality: props.row.quality\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n props.row.status !== \"Unaired\"\n ? _c(\"img\", {\n staticClass: \"addQTip\",\n staticStyle: {\n \"margin-left\": \"5px\"\n },\n attrs: {\n title: props.row.watched\n ? \"This episode has been flagged as watched\"\n : \"\",\n src:\n \"images/\" +\n (props.row.watched\n ? \"\"\n : \"not\") +\n \"watched.png\",\n width: \"16\",\n height: \"16\"\n },\n on: {\n click: function($event) {\n return _vm.updateEpisodeWatched(\n props.row,\n !props.row.watched\n )\n }\n }\n })\n : _vm._e()\n ],\n 1\n )\n ])\n : props.column.field == \"search\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"full-width\" },\n [\n _c(\"search\", {\n ref: \"search-\" + props.row.slug,\n staticStyle: {\n \"margin-right\": \"0.25rem\"\n },\n attrs: {\n searchType: \"backlog\",\n showSlug: _vm.showSlug,\n episode: {\n episode: props.row.episode,\n season: props.row.season,\n slug: props.row.slug\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"search\", {\n staticStyle: {\n \"margin-right\": \"0.25rem\"\n },\n attrs: {\n searchType: \"manual\",\n showSlug: _vm.showSlug,\n episode: {\n episode: props.row.episode,\n season: props.row.season,\n slug: props.row.slug\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"img\", {\n attrs: {\n src: \"images/closed_captioning.png\",\n height: \"16\",\n alt: \"search subtitles\",\n title: \"Search Subtitles\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row\n )\n }\n }\n })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"mobile\" }, [\n _c(\n \"select\",\n {\n staticClass:\n \"form-control input-sm mobile-select\",\n attrs: { name: \"search-select\" },\n on: {\n change: function($event) {\n return _vm.mobileSelectSearch(\n $event,\n props.row\n )\n }\n }\n },\n [\n _c(\n \"option\",\n {\n attrs: {\n disabled: \"\",\n selected: \"\",\n value: \"search action\"\n }\n },\n [_vm._v(\"search action\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"forced\" } },\n [\n _vm._v(\n _vm._s(\n _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\"\n )\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"manual\" } },\n [_vm._v(\"manual\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"subtitle\" } },\n [_vm._v(\"subtitle\")]\n )\n ]\n )\n ])\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.formattedRow[props.column.field]\n ) +\n \"\\n \"\n )\n ])\n ]\n }\n },\n {\n key: \"table-column\",\n fn: function(props) {\n return [\n props.column.label == \"Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : props.column.label == \"Scene Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Scene Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(props.column.label) +\n \"\\n \"\n )\n ])\n ]\n }\n }\n ],\n null,\n false,\n 1718487019\n )\n })\n : _vm._e(),\n _vm._v(\" \"),\n _vm.layout.show.specials && _vm.specials && _vm.specials.length > 0\n ? _c(\"vue-good-table\", {\n ref: \"table-specials\",\n attrs: {\n columns: _vm.columns,\n rows: _vm.specials,\n groupOptions: {\n enabled: true,\n mode: \"span\",\n customChildObject: \"episodes\"\n },\n \"pagination-options\": {\n enabled: false\n },\n \"search-options\": {\n enabled: true,\n trigger: \"enter\",\n skipDiacritics: false,\n placeholder: \"Search specials\"\n },\n \"sort-options\": {\n enabled: true,\n multipleColumns: true,\n initialSortBy: _vm.getSortBy(\"episode\", \"desc\") // From mixin manage-cookie.js\n },\n selectOptions: {\n enabled: true,\n selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row\n selectionInfoClass: \"select-info\",\n selectionText: \"episodes selected\",\n clearSelectionText: \"clear\",\n selectAllByGroup: true\n },\n \"row-style-class\": _vm.rowStyleClassFn,\n \"column-filter-options\": {\n enabled: false\n }\n },\n on: {\n \"on-selected-rows-change\": function($event) {\n _vm.selectedEpisodes = $event.selectedRows\n }\n },\n scopedSlots: _vm._u(\n [\n {\n key: \"table-header-row\",\n fn: function(props) {\n return [\n _c(\n \"h3\",\n { staticClass: \"season-header toggle collapse\" },\n [\n _c(\"app-link\", {\n attrs: { name: \"season-\" + props.row.season }\n }),\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.row.season > 0\n ? \"Season \" + props.row.season\n : \"Specials\"\n ) +\n \"\\n \"\n ),\n _vm._v(\" \"),\n _vm.anyEpisodeNotUnaired(props.row)\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=1&manual_search_type=season\"\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src:\n \"images/manualsearch-white.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", {\n staticClass: \"season-scene-exception\",\n attrs: {\n \"data-season\":\n props.row.season > 0\n ? props.row.season\n : \"Specials\"\n }\n }),\n _vm._v(\" \"),\n _c(\n \"img\",\n _vm._b(\n {},\n \"img\",\n _vm.getSeasonExceptions(props.row.season),\n false\n )\n )\n ],\n 1\n )\n ]\n }\n },\n {\n key: \"table-footer-row\",\n fn: function(ref) {\n var headerRow = ref.headerRow\n return [\n _c(\n \"tr\",\n {\n staticClass: \"seasoncols border-bottom shadow\",\n attrs: {\n colspan: \"9999\",\n id: \"season-\" + headerRow.season + \"-footer\"\n }\n },\n [\n _c(\n \"th\",\n {\n staticClass: \"col-footer\",\n attrs: { colspan: \"15\", align: \"left\" }\n },\n [\n _vm._v(\n \"Season contains \" +\n _vm._s(headerRow.children.length) +\n \" episodes with total filesize: \" +\n _vm._s(_vm.addFileSize(headerRow))\n )\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"spacer\" })\n ]\n }\n },\n {\n key: \"table-row\",\n fn: function(props) {\n return [\n props.column.field == \"content.hasNfo\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasNfo\n ? \"nfo.gif\"\n : \"nfo-no.gif\"),\n alt: props.row.content.hasNfo ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.field == \"content.hasTbn\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasTbn\n ? \"tbn.gif\"\n : \"tbn-no.gif\"),\n alt: props.row.content.hasTbn ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.label == \"Episode\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n class: {\n addQTip: props.row.file.location !== \"\"\n },\n attrs: {\n title:\n props.row.file.location !== \"\"\n ? props.row.file.location\n : \"\"\n }\n },\n [_vm._v(_vm._s(props.row.episode))]\n )\n ])\n : props.column.label == \"Scene\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Scene Abs. #\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-anime-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Title\"\n ? _c(\n \"span\",\n [\n props.row.description !== \"\"\n ? _c(\"plot-info\", {\n attrs: {\n description: props.row.description,\n \"show-slug\": _vm.show.id.slug,\n season: props.row.season,\n episode: props.row.episode\n }\n })\n : _vm._e(),\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.title) +\n \"\\n \"\n )\n ],\n 1\n )\n : props.column.label == \"File\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: { title: props.row.file.location }\n },\n [_vm._v(_vm._s(props.row.file.name))]\n )\n ])\n : props.column.label == \"Subtitles\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n [\n \"Archived\",\n \"Downloaded\",\n \"Ignored\",\n \"Skipped\"\n ].includes(props.row.status)\n ? _c(\n \"div\",\n { staticClass: \"subtitles\" },\n _vm._l(props.row.subtitles, function(\n flag\n ) {\n return _c(\"div\", { key: flag }, [\n flag !== \"und\"\n ? _c(\"img\", {\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: \"{flag}\",\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row,\n flag\n )\n }\n }\n })\n : _c(\"img\", {\n staticClass: \"subtitle-flag\",\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: \"flag\",\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n }\n })\n ])\n }),\n 0\n )\n : _vm._e()\n ])\n : props.column.label == \"Status\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n _c(\n \"div\",\n { staticClass: \"pull-left\" },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.status) +\n \"\\n \"\n ),\n props.row.quality !== 0\n ? _c(\"quality-pill\", {\n staticClass: \"quality-margins\",\n attrs: {\n quality: props.row.quality\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n props.row.status !== \"Unaired\"\n ? _c(\"img\", {\n staticClass: \"addQTip\",\n attrs: {\n title: props.row.watched\n ? \"This episode has been flagged as watched\"\n : \"\",\n src:\n \"images/\" +\n (props.row.watched\n ? \"\"\n : \"not\") +\n \"watched.png\",\n width: \"16\"\n },\n on: {\n click: function($event) {\n return _vm.updateEpisodeWatched(\n props.row,\n !props.row.watched\n )\n }\n }\n })\n : _vm._e()\n ],\n 1\n )\n ])\n : props.column.field == \"search\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"full-width\" },\n [\n _c(\"search\", {\n ref: \"search-\" + props.row.slug,\n staticStyle: {\n \"margin-right\": \"0.25rem\"\n },\n attrs: {\n searchType: \"backlog\",\n showSlug: _vm.showSlug,\n episode: {\n episode: props.row.episode,\n season: props.row.season,\n slug: props.row.slug\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"search\", {\n staticStyle: {\n \"margin-right\": \"0.25rem\"\n },\n attrs: {\n searchType: \"manual\",\n showSlug: _vm.showSlug,\n episode: {\n episode: props.row.episode,\n season: props.row.season,\n slug: props.row.slug\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"img\", {\n attrs: {\n src: \"images/closed_captioning.png\",\n height: \"16\",\n alt: \"search subtitles\",\n title: \"Search Subtitles\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row\n )\n }\n }\n })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"mobile\" }, [\n _c(\n \"select\",\n {\n staticClass:\n \"form-control input-sm mobile-select\",\n attrs: { name: \"search-select\" },\n on: {\n change: function($event) {\n return _vm.mobileSelectSearch(\n $event,\n props.row\n )\n }\n }\n },\n [\n _c(\n \"option\",\n {\n attrs: {\n disabled: \"\",\n selected: \"\",\n value: \"search action\"\n }\n },\n [_vm._v(\"search action\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"forced\" } },\n [\n _vm._v(\n _vm._s(\n _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\"\n )\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"manual\" } },\n [_vm._v(\"manual\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"subtitle\" } },\n [_vm._v(\"subtitle\")]\n )\n ]\n )\n ])\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.formattedRow[props.column.field]\n ) +\n \"\\n \"\n )\n ])\n ]\n }\n },\n {\n key: \"table-column\",\n fn: function(props) {\n return [\n props.column.label == \"Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : props.column.label == \"Scene Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Scene Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(props.column.label) +\n \"\\n \"\n )\n ])\n ]\n }\n }\n ],\n null,\n false,\n 848378579\n )\n })\n : _vm._e()\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-start-backlog-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeBacklogSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-hidden\": \"true\"\n }\n },\n [_vm._v(\"×\")]\n ),\n _vm._v(\" \"),\n _c(\"h4\", { staticClass: \"modal-title\" }, [\n _vm._v(\"Start search?\")\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [\n _vm._v(\n \"Some episodes have been changed to 'Wanted'. Do you want to trigger a backlog search for these \" +\n _vm._s(_vm.backlogSearchEpisodes.length) +\n \" episode(s)\"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.backlogSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-mark-failed-and-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeFailedSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _vm._v(\n \"\\n Mark episode as failed and search?\\n \"\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [_vm._v(\"Starting to search for the episode\")]),\n _vm._v(\" \"),\n _vm.failedSearchEpisodes &&\n _vm.failedSearchEpisodes.length === 1\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episode \" +\n _vm._s(_vm.failedSearchEpisodes[0].slug) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm.failedSearchEpisodes\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episodes \" +\n _vm._s(\n _vm.failedSearchEpisodes\n .map(function(ep) {\n return ep.slug\n })\n .join(\", \")\n ) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"failed\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\n \"query-mark-failed-and-search\"\n )\n }\n }\n },\n [_vm._v(\"Cancel\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://slim/./src/components/display-show.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), @@ -7880,7 +7880,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"search-wrapper\" },\n [\n _vm.searchType === \"backlog\"\n ? _c(\"img\", {\n ref: \"search-\" + _vm.episode.slug,\n staticClass: \"epForcedSearch\",\n attrs: {\n id:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n name:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n src: \"images/search16.png\",\n height: \"16\",\n alt: _vm.retryDownload(_vm.episode) ? \"retry\" : \"search\",\n title: _vm.retryDownload(_vm.episode)\n ? \"Retry Download\"\n : \"Forced Seach\"\n },\n on: {\n click: function($event) {\n return _vm.queueSearch(_vm.episode)\n }\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n _vm.searchType === \"manual\"\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n id: _vm.showSlug + \"x\" + _vm.episode.episode,\n name:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.showSlug +\n \"&season=\" +\n _vm.episode.season +\n \"&episode=\" +\n _vm.episode.episode\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src: \"images/manualsearch.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-start-backlog-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeBacklogSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-hidden\": \"true\"\n }\n },\n [_vm._v(\"×\")]\n ),\n _vm._v(\" \"),\n _c(\"h4\", { staticClass: \"modal-title\" }, [\n _vm._v(\"Start search?\")\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [\n _vm._v(\n \"Some episodes have been changed to 'Wanted'. Do you want to trigger a backlog search for these \" +\n _vm._s(_vm.backlogSearchEpisodes.length) +\n \" episode(s)\"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.backlogSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-mark-failed-and-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeFailedSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _vm._v(\n \"\\n Mark episode as failed and search?\\n \"\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [_vm._v(\"Starting to search for the episode\")]),\n _vm._v(\" \"),\n _vm.failedSearchEpisodes &&\n _vm.failedSearchEpisodes.length === 1\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episode \" +\n _vm._s(_vm.failedSearchEpisodes[0].slug) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm.failedSearchEpisodes\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episodes \" +\n _vm._s(\n _vm.failedSearchEpisodes\n .map(function(ep) {\n return ep.slug\n })\n .join(\", \")\n ) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"failed\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\n \"query-mark-failed-and-search\"\n )\n }\n }\n },\n [_vm._v(\"Cancel\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://slim/./src/components/helpers/search.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"search-wrapper\" },\n [\n _vm.searchType === \"backlog\"\n ? _c(\"img\", {\n ref: \"search-\" + _vm.episode.slug,\n staticClass: \"epForcedSearch\",\n attrs: {\n id:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n name:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n src: _vm.src,\n height: \"16\",\n alt: _vm.retryDownload(_vm.episode) ? \"retry\" : \"search\",\n title: _vm.retryDownload(_vm.episode)\n ? \"Retry Download\"\n : \"Forced Seach\",\n disabled: _vm.disabled\n },\n on: {\n click: function($event) {\n return _vm.queueSearch(_vm.episode)\n }\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n _vm.searchType === \"manual\"\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n id: _vm.showSlug + \"x\" + _vm.episode.episode,\n name:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.showSlug +\n \"&season=\" +\n _vm.episode.season +\n \"&episode=\" +\n _vm.episode.episode\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src: \"images/manualsearch.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-start-backlog-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeBacklogSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-hidden\": \"true\"\n }\n },\n [_vm._v(\"×\")]\n ),\n _vm._v(\" \"),\n _c(\"h4\", { staticClass: \"modal-title\" }, [\n _vm._v(\"Start search?\")\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [\n _vm._v(\n \"Some episodes have been changed to 'Wanted'. Do you want to trigger a backlog search for these \" +\n _vm._s(_vm.backlogSearchEpisodes.length) +\n \" episode(s)\"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.backlogSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-mark-failed-and-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeFailedSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _vm._v(\n \"\\n Mark episode as failed and search?\\n \"\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [_vm._v(\"Starting to search for the episode\")]),\n _vm._v(\" \"),\n _vm.failedSearchEpisodes &&\n _vm.failedSearchEpisodes.length === 1\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episode \" +\n _vm._s(_vm.failedSearchEpisodes[0].slug) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm.failedSearchEpisodes\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episodes \" +\n _vm._s(\n _vm.failedSearchEpisodes\n .map(function(ep) {\n return ep.slug\n })\n .join(\", \")\n ) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"failed\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\n \"query-mark-failed-and-search\"\n )\n }\n }\n },\n [_vm._v(\"Cancel\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://slim/./src/components/helpers/search.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), diff --git a/themes/light/assets/js/medusa-runtime.js b/themes/light/assets/js/medusa-runtime.js index 938a9ae4fd..8d85cffdc3 100644 --- a/themes/light/assets/js/medusa-runtime.js +++ b/themes/light/assets/js/medusa-runtime.js @@ -235,7 +235,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash/debounce */ \"./node_modules/lodash/debounce.js\");\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.js\");\n/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ \"./src/components/helpers/index.js\");\n/* harmony import */ var _utils_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/core */ \"./src/utils/core.js\");\n/* harmony import */ var _mixins_manage_cookie__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mixins/manage-cookie */ \"./src/mixins/manage-cookie.js\");\n/* harmony import */ var _utils_jquery__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/jquery */ \"./src/utils/jquery.js\");\n/* harmony import */ var vue_good_table__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! vue-good-table */ \"./node_modules/vue-good-table/dist/vue-good-table.esm.js\");\n/* harmony import */ var _backstretch_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./backstretch.vue */ \"./src/components/backstretch.vue\");\n/* harmony import */ var _show_header_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./show-header.vue */ \"./src/components/show-header.vue\");\n/* harmony import */ var _subtitle_search_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./subtitle-search.vue */ \"./src/components/subtitle-search.vue\");\n/* harmony import */ var _helpers_quality_pill_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./helpers/quality-pill.vue */ \"./src/components/helpers/quality-pill.vue\");\n/* provided dependency */ var $ = __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'show',\n components: {\n AppLink: _helpers__WEBPACK_IMPORTED_MODULE_1__.AppLink,\n Backstretch: _backstretch_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"],\n PlotInfo: _helpers__WEBPACK_IMPORTED_MODULE_1__.PlotInfo,\n QualityPill: _helpers_quality_pill_vue__WEBPACK_IMPORTED_MODULE_8__[\"default\"],\n SceneNumberInput: _helpers__WEBPACK_IMPORTED_MODULE_1__.SceneNumberInput,\n SceneNumberAnimeInput: _helpers__WEBPACK_IMPORTED_MODULE_1__.SceneNumberAnimeInput,\n ShowHeader: _show_header_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"],\n VueGoodTable: vue_good_table__WEBPACK_IMPORTED_MODULE_9__.VueGoodTable\n },\n mixins: [(0,_mixins_manage_cookie__WEBPACK_IMPORTED_MODULE_3__.manageCookieMixin)('displayShow')],\n\n metaInfo() {\n if (!this.show || !this.show.title) {\n return {\n title: 'Medusa'\n };\n }\n\n const {\n title\n } = this.show;\n return {\n title,\n titleTemplate: '%s | Medusa'\n };\n },\n\n props: {\n /**\n * Show Slug\n */\n slug: {\n type: String\n }\n },\n\n data() {\n const {\n getCookie\n } = this;\n const perPageDropdown = [25, 50, 100, 250, 500];\n\n const getPaginationPerPage = () => {\n const rows = getCookie('pagination-perPage');\n\n if (!rows) {\n return 50;\n }\n\n if (!perPageDropdown.includes(rows)) {\n return 500;\n }\n\n return rows;\n };\n\n return {\n invertTable: true,\n subtitleSearchComponents: [],\n columns: [{\n label: 'NFO',\n field: 'content.hasNfo',\n type: 'boolean',\n sortable: false,\n hidden: getCookie('NFO')\n }, {\n label: 'TBN',\n field: 'content.hasTbn',\n type: 'boolean',\n sortable: false,\n hidden: getCookie('TBN')\n }, {\n label: 'Episode',\n field: 'episode',\n type: 'number',\n hidden: getCookie('Episode')\n }, {\n label: 'Abs. #',\n field: 'absoluteNumber',\n type: 'number',\n hidden: getCookie('Abs. #')\n }, {\n label: 'Scene',\n field: 'scene',\n sortable: false,\n hidden: getCookie('Scene')\n }, {\n label: 'Scene Abs. #',\n field: 'sceneAbsolute',\n type: 'number',\n hidden: getCookie('Scene Abs. #')\n }, {\n label: 'Title',\n field: 'title',\n hidden: getCookie('Title')\n }, {\n label: 'File',\n field: 'file.location',\n hidden: getCookie('File')\n }, {\n label: 'Size',\n field: 'file.size',\n type: 'number',\n formatFn: _utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize,\n hidden: getCookie('Size')\n }, {\n // For now i'm using a custom function the parse it. As the type: date, isn't working for us.\n // But the goal is to have this user formatted (as configured in backend)\n label: 'Air date',\n field: this.parseDateFn,\n tdClass: 'align-center',\n sortable: false,\n hidden: getCookie('Air date')\n }, {\n label: 'Download',\n field: 'download',\n sortable: false,\n hidden: getCookie('Download')\n }, {\n label: 'Subtitles',\n field: 'subtitles',\n sortable: false,\n hidden: getCookie('Subtitles')\n }, {\n label: 'Status',\n field: 'status',\n hidden: getCookie('Status')\n }, {\n label: 'Search',\n field: 'search',\n sortable: false,\n hidden: getCookie('Search')\n }],\n perPageDropdown,\n paginationPerPage: getPaginationPerPage(),\n selectedEpisodes: [],\n // We need to keep track of which episode where trying to search, for the vue-modal\n failedSearchEpisodes: [],\n backlogSearchEpisodes: [],\n filterByOverviewStatus: false,\n selectedSearch: 'search action'\n };\n },\n\n computed: { ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapState)({\n shows: state => state.shows.shows,\n subtitles: state => state.config.subtitles,\n configLoaded: state => state.config.layout.fanartBackground !== null,\n layout: state => state.config.layout,\n stateSearch: state => state.config.search,\n client: state => state.auth.client\n }),\n ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapGetters)({\n show: 'getCurrentShow',\n getOverviewStatus: 'getOverviewStatus',\n fuzzyParseDateTime: 'fuzzyParseDateTime'\n }),\n\n showSlug() {\n const {\n slug\n } = this;\n return slug || this.$route.query.showslug;\n },\n\n theme() {\n const {\n layout\n } = this;\n const {\n themeName\n } = layout;\n return themeName || 'light';\n },\n\n orderedSeasons() {\n const {\n filterByOverviewStatus,\n invertTable,\n show\n } = this;\n\n if (!show.seasons) {\n return [];\n }\n\n const seasons = show.seasons.slice();\n let sortedSeasons = seasons.sort((a, b) => a.season - b.season).filter(season => season.season !== 0); // Use the filterOverviewStatus to filter the data based on what's checked in the show-header.\n\n if (filterByOverviewStatus && filterByOverviewStatus.filter(status => status.checked).length < filterByOverviewStatus.length) {\n const filteredSortedSeasons = [];\n\n for (const season of sortedSeasons) {\n const {\n children,\n ...res\n } = season;\n const filteredEpisodes = children.filter(episode => {\n const episodeOverviewStatus = this.getOverviewStatus(episode.status, episode.quality, show.config.qualities);\n const filteredStatus = filterByOverviewStatus.find(overviewStatus => overviewStatus.name === episodeOverviewStatus);\n return !filteredStatus || filteredStatus.checked;\n });\n filteredSortedSeasons.push(Object.assign({\n children: filteredEpisodes\n }, res));\n }\n\n sortedSeasons = filteredSortedSeasons;\n }\n\n if (invertTable) {\n return sortedSeasons.slice().reverse();\n }\n\n return sortedSeasons;\n },\n\n specials() {\n const {\n show\n } = this;\n\n if (!show.seasons) {\n return [];\n }\n\n return show.seasons.filter(season => season.season === 0);\n }\n\n },\n\n mounted() {\n this.loadShow();\n ['load', 'resize'].map(event => {\n return window.addEventListener(event, () => {\n this.reflowLayout();\n });\n });\n $(document.body).on('click', '.seasonCheck', event => {\n const seasCheck = event.currentTarget;\n const seasNo = $(seasCheck).attr('id');\n $('#collapseSeason-' + seasNo).collapse('show');\n const seasonIdentifier = 's' + seasNo;\n $('.epCheck:visible').each((index, element) => {\n const epParts = $(element).attr('id').split('e');\n\n if (epParts[0] === seasonIdentifier) {\n element.checked = seasCheck.checked;\n }\n });\n });\n },\n\n methods: {\n humanFileSize: _utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize,\n ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapActions)({\n getShow: 'getShow',\n // Map `this.getShow()` to `this.$store.dispatch('getShow')`\n getEpisodes: 'getEpisodes',\n setCurrentShow: 'setCurrentShow',\n setRecentShow: 'setRecentShow'\n }),\n\n async loadShow() {\n const {\n setCurrentShow,\n showSlug,\n initializeEpisodes,\n getShow\n } = this; // We need detailed info for the xem / scene exceptions, so let's get it.\n\n await getShow({\n showSlug,\n detailed: true\n }); // Let's tell the store which show we currently want as current.\n // Run this after getShow(), as it will trigger the initializeEpisodes() method.\n\n setCurrentShow(showSlug); // Load all episodes\n\n initializeEpisodes();\n },\n\n statusQualityUpdate(event) {\n const {\n selectedEpisodes,\n setStatus,\n setQuality\n } = this;\n\n if (event.newQuality !== null && event.newQuality !== 'Change quality to:') {\n setQuality(event.newQuality, selectedEpisodes);\n }\n\n if (event.newStatus !== null && event.newStatus !== 'Change status to:') {\n setStatus(event.newStatus, selectedEpisodes);\n }\n },\n\n setQuality(quality, episodes) {\n const {\n showSlug,\n getEpisodes,\n show\n } = this;\n const patchData = {};\n episodes.forEach(episode => {\n patchData[episode.slug] = {\n quality: Number.parseInt(quality, 10)\n };\n });\n this.client.api.patch(`series/${show.id.slug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched show ${show.id.slug} with quality ${quality}`);\n [...new Set(episodes.map(episode => episode.season))].forEach(season => {\n getEpisodes({\n showSlug,\n season\n });\n });\n }).catch(error => {\n console.error(String(error));\n });\n },\n\n setStatus(status, episodes) {\n const {\n showSlug,\n getEpisodes\n } = this;\n const patchData = {};\n episodes.forEach(episode => {\n patchData[episode.slug] = {\n status\n };\n });\n this.client.api.patch(`series/${showSlug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched show ${showSlug} with status ${status}`);\n [...new Set(episodes.map(episode => episode.season))].forEach(season => {\n getEpisodes({\n showSlug,\n season\n });\n });\n }).catch(error => {\n console.error(String(error));\n }); // New status Wanted\n\n if (status === 3) {\n this.$modal.show('query-start-backlog-search', {\n episodes\n });\n } // New status Failed\n\n\n if (status === 11) {\n this.$modal.show('query-mark-failed-and-search', {\n episodes\n });\n }\n },\n\n parseDateFn(row) {\n const {\n fuzzyParseDateTime\n } = this;\n return fuzzyParseDateTime(row.airDate);\n },\n\n rowStyleClassFn(row) {\n const {\n getOverviewStatus,\n show\n } = this;\n\n if (Object.keys(row).includes('vgt_header_id')) {\n return;\n }\n\n const overview = getOverviewStatus(row.status, row.quality, show.config.qualities).toLowerCase().trim();\n return overview;\n },\n\n /**\n * Add (reduce) the total episodes filesize.\n * @param {object} headerRow header row object.\n * @returns {string} - Human readable file size.\n */\n addFileSize(headerRow) {\n return (0,_utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize)(headerRow.children.reduce((a, b) => a + (b.file.size || 0), 0));\n },\n\n searchSubtitle(event, episode, lang) {\n const {\n showSlug,\n getEpisodes,\n show,\n subtitleSearchComponents\n } = this;\n const SubtitleSearchClass = vue__WEBPACK_IMPORTED_MODULE_11__[\"default\"].extend(_subtitle_search_vue__WEBPACK_IMPORTED_MODULE_7__[\"default\"]); // eslint-disable-line no-undef\n\n const instance = new SubtitleSearchClass({\n propsData: {\n show,\n episode,\n key: episode.originalIndex,\n lang\n },\n parent: this\n }); // Update the show, as we downloaded new subtitle(s)\n\n instance.$on('update', event => {\n // This could be replaced by the generic websocket updates in future.\n if (event.reason === 'new subtitles found') {\n getEpisodes({\n showSlug,\n season: episode.season\n });\n }\n });\n const node = document.createElement('div');\n const tableRef = episode.season === 0 ? 'table-specials' : 'table-seasons';\n this.$refs[tableRef].$refs[`row-${episode.originalIndex}`][0].after(node);\n instance.$mount(node);\n subtitleSearchComponents.push(instance);\n },\n\n /**\n * Attaches IMDB tooltip\n */\n reflowLayout: lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default()(() => {\n console.debug('Reflowing layout');\n (0,_utils_jquery__WEBPACK_IMPORTED_MODULE_4__.addQTip)(); // eslint-disable-line no-undef\n }, 1000),\n\n /**\n * Check if any of the episodes in this season does not have the status \"unaired\".\n * If that's the case we want to manual season search icon.\n * @param {object} season - A season object.\n * @returns {Boolean} - true if one of the seasons episodes has a status 'unaired'.\n */\n anyEpisodeNotUnaired(season) {\n return season.children.filter(ep => ep.status !== 'Unaired').length > 0;\n },\n\n episodesInverse(season) {\n const {\n invertTable\n } = this;\n\n if (!season.children) {\n return [];\n }\n\n if (invertTable) {\n return season.children.slice().reverse();\n }\n\n return season.children;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeBacklogSearchModalClose(event) {\n this.backlogSearchEpisodes = event.params.episodes;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeFailedSearchModalClose(event) {\n this.failedSearchEpisodes = event.params.episodes;\n },\n\n retryDownload(episode) {\n const {\n stateSearch\n } = this;\n return stateSearch.general.failedDownloads.enabled && ['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n search(episodes, searchType) {\n const {\n show\n } = this;\n let data = {};\n\n if (episodes) {\n data = {\n showSlug: show.id.slug,\n episodes: [],\n options: {}\n };\n episodes.forEach(episode => {\n data.episodes.push(episode.slug);\n this.$refs[`search-${episode.slug}`].src = 'images/loading16-dark.gif';\n });\n }\n\n this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef\n .then(_ => {\n if (episodes.length === 1) {\n console.info(`started search for show: ${show.id.slug} episode: ${episodes[0].slug}`);\n this.$refs[`search-${episodes[0].slug}`].src = 'images/queued.png';\n this.$refs[`search-${episodes[0].slug}`].disabled = true;\n } else {\n console.info('started a full backlog search');\n }\n }).catch(error => {\n console.error(String(error));\n episodes.forEach(episode => {\n data.episodes.push(episode.slug);\n this.$refs[`search-${episodes[0].slug}`].src = 'images/no16.png';\n });\n }).finally(() => {\n this.failedSearchEpisodes = [];\n this.backlogSearchEpisodes = [];\n });\n },\n\n /**\n * Start a backlog search or failed search for the specific episode.\n * A failed search is started depending on the current episodes status.\n * @param {Object} episode - Episode object. If no episode object is passed, a backlog search is started.\n */\n queueSearch(episode) {\n const {\n $modal,\n search,\n retryDownload\n } = this;\n const episodeIdentifier = episode.slug;\n\n if (episode) {\n if (this.$refs[`search-${episodeIdentifier}`].disabled === true) {\n return;\n }\n\n if (retryDownload(episode)) {\n $modal.show('query-mark-failed-and-search', {\n episode\n });\n } else {\n search([episode], 'backlog');\n }\n }\n },\n\n showSubtitleButton(episode) {\n const {\n subtitles,\n show\n } = this;\n return episode.season !== 0 && subtitles.enabled && show.config.subtitlesEnabled && !['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n totalSeasonEpisodeSize(season) {\n return season.children.filter(x => x.file && x.file.size > 0).reduce((a, b) => a + b.file.size, 0);\n },\n\n getSeasonExceptions(season) {\n const {\n show\n } = this;\n const {\n config\n } = show;\n const {\n aliases\n } = config;\n let bindData = {\n class: 'display: none'\n }; // Map the indexer season to a xem mapped season.\n // check if the season exception also exists in the xem numbering table\n\n let xemSeasons = [];\n let foundInXem = false;\n\n if (show.xemNumbering.length > 0) {\n const xemResult = show.xemNumbering.filter(x => x.source.season === season); // Create an array with unique seasons\n\n xemSeasons = [...new Set(xemResult.map(item => item.destination.season))];\n foundInXem = Boolean(xemSeasons.length);\n } // Check if there is a season exception for this season\n\n\n if (aliases.find(x => x.season === season)) {\n // If there is not a match on the xem table, display it as a medusa scene exception\n bindData = {\n id: `xem-exception-season-${foundInXem ? xemSeasons[0] : season}`,\n alt: foundInXem ? '[xem]' : '[medusa]',\n src: foundInXem ? 'images/xem.png' : 'images/ico/favicon-16.png',\n title: foundInXem ? xemSeasons.reduce((a, b) => {\n return a.concat(aliases.filter(alias => alias.season === b).map(alias => alias.title));\n }, []).join(', ') : aliases.filter(alias => alias.season === season).map(alias => alias.title).join(', ')\n };\n }\n\n return bindData;\n },\n\n updateEpisodeWatched(episode, watched) {\n const {\n showSlug,\n getEpisodes,\n show\n } = this;\n const patchData = {};\n patchData[episode.slug] = {\n watched\n };\n this.client.api.patch(`series/${show.id.slug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched episode ${episode.slug} with watched set to ${watched}`);\n getEpisodes({\n showSlug,\n season: episode.season\n });\n }).catch(error => {\n console.error(String(error));\n });\n episode.watched = watched;\n },\n\n updatePaginationPerPage(rows) {\n const {\n setCookie\n } = this;\n this.paginationPerPage = rows;\n setCookie('pagination-perPage', rows);\n },\n\n onPageChange(params) {\n if (params.prevPage !== params.currentPage) {\n this.loadEpisodes(params.currentPage);\n }\n },\n\n neededSeasons(page) {\n const {\n layout,\n paginationPerPage,\n show\n } = this;\n const {\n seasonCount\n } = show;\n\n if (!seasonCount || seasonCount.length === 0) {\n return [];\n }\n\n if (!layout.show.pagination.enable) {\n return seasonCount.filter(season => season.season !== 0).map(season => season.season).reverse();\n }\n\n const seasons = show.seasonCount.length - 1;\n let pagesCount = 1;\n let episodeCount = 0;\n const pages = {};\n\n for (let i = seasons; i >= 0; i--) {\n const {\n season\n } = show.seasonCount[i]; // Exclude specials\n\n if (season === 0) {\n break;\n }\n\n if (pagesCount in pages) {\n pages[pagesCount].push(season);\n } else {\n pages[pagesCount] = [season];\n }\n\n episodeCount += show.seasonCount[i].episodeCount;\n\n if (episodeCount / paginationPerPage > pagesCount) {\n pagesCount++;\n pages[pagesCount] = [season];\n }\n\n if (pagesCount > page) {\n break;\n }\n }\n\n return pages[page] || [];\n },\n\n loadEpisodes(page) {\n const {\n showSlug,\n getEpisodes\n } = this; // Wrap getEpisodes into an async/await function, so we can wait for the season to have been committed\n // before going on to the next one.\n\n const _getEpisodes = async showSlug => {\n for (const season of this.neededSeasons(page)) {\n // We're waiting for the results by design, to give vue the chance to update the dom.\n // If we fire all the promises at once for, for example 25 seasons. We'll overload medusa's app\n // and chance is high a number of requests will timeout.\n await getEpisodes({\n showSlug,\n season\n }); // eslint-disable-line no-await-in-loop\n }\n };\n\n _getEpisodes(showSlug);\n },\n\n initializeEpisodes() {\n let force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n const {\n getEpisodes,\n showSlug,\n setRecentShow,\n show\n } = this;\n\n if (force || !show.seasons && show.seasonCount) {\n // Load episodes for the first page.\n this.loadEpisodes(1); // Always get special episodes if available.\n\n if (show.seasonCount.length > 0 && show.seasonCount[0].season === 0) {\n getEpisodes({\n showSlug,\n season: 0\n });\n }\n }\n\n if (show.id.slug) {\n // For now i'm dumping this here\n setRecentShow({\n showSlug: show.id.slug,\n name: show.title\n });\n }\n },\n\n mobileSelectSearch(event, episode) {\n const {\n $snotify,\n $router,\n queueSearch,\n searchSubtitle,\n show\n } = this;\n\n if (event.target.value === 'forced') {\n queueSearch(episode);\n $snotify.success(`Search started for S${episode.season} E${episode.episode}`);\n }\n\n if (event.target.value === 'manual') {\n // Use the router to navigate to snatchSelection.\n $router.push({\n name: 'snatchSelection',\n query: {\n showslug: show.id.slug,\n season: episode.season,\n episode: episode.episode\n }\n });\n }\n\n if (event.target.value === 'subtitle') {\n searchSubtitle(event, episode);\n }\n\n setTimeout(() => {\n event.target.value = 'search action';\n }, 2000);\n }\n\n },\n filters: {\n sceneObjectToString(value) {\n return `${value.season}x${value.episode}`;\n }\n\n },\n watch: {\n $route(to, from) {\n if (to.name === 'show' && from.name === 'testRename') {\n // Load all episodes if we're coming from the testRename page.\n this.initializeEpisodes(true);\n }\n }\n\n }\n});\n\n//# sourceURL=webpack://slim/./src/components/display-show.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-1%5B0%5D.rules%5B0%5D!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash/debounce */ \"./node_modules/lodash/debounce.js\");\n/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.js\");\n/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n/* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ \"./src/components/helpers/index.js\");\n/* harmony import */ var _utils_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/core */ \"./src/utils/core.js\");\n/* harmony import */ var _mixins_manage_cookie__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mixins/manage-cookie */ \"./src/mixins/manage-cookie.js\");\n/* harmony import */ var _utils_jquery__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/jquery */ \"./src/utils/jquery.js\");\n/* harmony import */ var vue_good_table__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! vue-good-table */ \"./node_modules/vue-good-table/dist/vue-good-table.esm.js\");\n/* harmony import */ var _backstretch_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./backstretch.vue */ \"./src/components/backstretch.vue\");\n/* harmony import */ var _show_header_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./show-header.vue */ \"./src/components/show-header.vue\");\n/* harmony import */ var _subtitle_search_vue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./subtitle-search.vue */ \"./src/components/subtitle-search.vue\");\n/* harmony import */ var _helpers_quality_pill_vue__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./helpers/quality-pill.vue */ \"./src/components/helpers/quality-pill.vue\");\n/* provided dependency */ var $ = __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n\n\n\n\n\n\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'show',\n components: {\n AppLink: _helpers__WEBPACK_IMPORTED_MODULE_1__.AppLink,\n Backstretch: _backstretch_vue__WEBPACK_IMPORTED_MODULE_5__[\"default\"],\n PlotInfo: _helpers__WEBPACK_IMPORTED_MODULE_1__.PlotInfo,\n QualityPill: _helpers_quality_pill_vue__WEBPACK_IMPORTED_MODULE_8__[\"default\"],\n Search: _helpers__WEBPACK_IMPORTED_MODULE_1__.Search,\n SceneNumberInput: _helpers__WEBPACK_IMPORTED_MODULE_1__.SceneNumberInput,\n SceneNumberAnimeInput: _helpers__WEBPACK_IMPORTED_MODULE_1__.SceneNumberAnimeInput,\n ShowHeader: _show_header_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"],\n VueGoodTable: vue_good_table__WEBPACK_IMPORTED_MODULE_9__.VueGoodTable\n },\n mixins: [(0,_mixins_manage_cookie__WEBPACK_IMPORTED_MODULE_3__.manageCookieMixin)('displayShow')],\n\n metaInfo() {\n if (!this.show || !this.show.title) {\n return {\n title: 'Medusa'\n };\n }\n\n const {\n title\n } = this.show;\n return {\n title,\n titleTemplate: '%s | Medusa'\n };\n },\n\n props: {\n /**\n * Show Slug\n */\n slug: {\n type: String\n }\n },\n\n data() {\n const {\n getCookie\n } = this;\n const perPageDropdown = [25, 50, 100, 250, 500];\n\n const getPaginationPerPage = () => {\n const rows = getCookie('pagination-perPage');\n\n if (!rows) {\n return 50;\n }\n\n if (!perPageDropdown.includes(rows)) {\n return 500;\n }\n\n return rows;\n };\n\n return {\n invertTable: true,\n subtitleSearchComponents: [],\n columns: [{\n label: 'NFO',\n field: 'content.hasNfo',\n type: 'boolean',\n sortable: false,\n hidden: getCookie('NFO')\n }, {\n label: 'TBN',\n field: 'content.hasTbn',\n type: 'boolean',\n sortable: false,\n hidden: getCookie('TBN')\n }, {\n label: 'Episode',\n field: 'episode',\n type: 'number',\n hidden: getCookie('Episode')\n }, {\n label: 'Abs. #',\n field: 'absoluteNumber',\n type: 'number',\n hidden: getCookie('Abs. #')\n }, {\n label: 'Scene',\n field: 'scene',\n sortable: false,\n hidden: getCookie('Scene')\n }, {\n label: 'Scene Abs. #',\n field: 'sceneAbsolute',\n type: 'number',\n hidden: getCookie('Scene Abs. #')\n }, {\n label: 'Title',\n field: 'title',\n hidden: getCookie('Title')\n }, {\n label: 'File',\n field: 'file.location',\n hidden: getCookie('File')\n }, {\n label: 'Size',\n field: 'file.size',\n type: 'number',\n formatFn: _utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize,\n hidden: getCookie('Size')\n }, {\n // For now i'm using a custom function the parse it. As the type: date, isn't working for us.\n // But the goal is to have this user formatted (as configured in backend)\n label: 'Air date',\n field: this.parseDateFn,\n tdClass: 'align-center',\n sortable: false,\n hidden: getCookie('Air date')\n }, {\n label: 'Download',\n field: 'download',\n sortable: false,\n hidden: getCookie('Download')\n }, {\n label: 'Subtitles',\n field: 'subtitles',\n sortable: false,\n hidden: getCookie('Subtitles')\n }, {\n label: 'Status',\n field: 'status',\n hidden: getCookie('Status')\n }, {\n label: 'Search',\n field: 'search',\n sortable: false,\n hidden: getCookie('Search')\n }],\n perPageDropdown,\n paginationPerPage: getPaginationPerPage(),\n selectedEpisodes: [],\n // We need to keep track of which episode where trying to search, for the vue-modal\n failedSearchEpisodes: [],\n backlogSearchEpisodes: [],\n filterByOverviewStatus: false,\n selectedSearch: 'search action'\n };\n },\n\n computed: { ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapState)({\n shows: state => state.shows.shows,\n subtitles: state => state.config.subtitles,\n configLoaded: state => state.config.layout.fanartBackground !== null,\n layout: state => state.config.layout,\n stateSearch: state => state.config.search,\n client: state => state.auth.client\n }),\n ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapGetters)({\n show: 'getCurrentShow',\n getOverviewStatus: 'getOverviewStatus',\n fuzzyParseDateTime: 'fuzzyParseDateTime'\n }),\n\n showSlug() {\n const {\n slug\n } = this;\n return slug || this.$route.query.showslug;\n },\n\n theme() {\n const {\n layout\n } = this;\n const {\n themeName\n } = layout;\n return themeName || 'light';\n },\n\n orderedSeasons() {\n const {\n filterByOverviewStatus,\n invertTable,\n show\n } = this;\n\n if (!show.seasons) {\n return [];\n }\n\n const seasons = show.seasons.slice();\n let sortedSeasons = seasons.sort((a, b) => a.season - b.season).filter(season => season.season !== 0); // Use the filterOverviewStatus to filter the data based on what's checked in the show-header.\n\n if (filterByOverviewStatus && filterByOverviewStatus.filter(status => status.checked).length < filterByOverviewStatus.length) {\n const filteredSortedSeasons = [];\n\n for (const season of sortedSeasons) {\n const {\n children,\n ...res\n } = season;\n const filteredEpisodes = children.filter(episode => {\n const episodeOverviewStatus = this.getOverviewStatus(episode.status, episode.quality, show.config.qualities);\n const filteredStatus = filterByOverviewStatus.find(overviewStatus => overviewStatus.name === episodeOverviewStatus);\n return !filteredStatus || filteredStatus.checked;\n });\n filteredSortedSeasons.push(Object.assign({\n children: filteredEpisodes\n }, res));\n }\n\n sortedSeasons = filteredSortedSeasons;\n }\n\n if (invertTable) {\n return sortedSeasons.slice().reverse();\n }\n\n return sortedSeasons;\n },\n\n specials() {\n const {\n show\n } = this;\n\n if (!show.seasons) {\n return [];\n }\n\n return show.seasons.filter(season => season.season === 0);\n }\n\n },\n\n mounted() {\n this.loadShow();\n ['load', 'resize'].map(event => {\n return window.addEventListener(event, () => {\n this.reflowLayout();\n });\n });\n $(document.body).on('click', '.seasonCheck', event => {\n const seasCheck = event.currentTarget;\n const seasNo = $(seasCheck).attr('id');\n $('#collapseSeason-' + seasNo).collapse('show');\n const seasonIdentifier = 's' + seasNo;\n $('.epCheck:visible').each((index, element) => {\n const epParts = $(element).attr('id').split('e');\n\n if (epParts[0] === seasonIdentifier) {\n element.checked = seasCheck.checked;\n }\n });\n });\n },\n\n methods: {\n humanFileSize: _utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize,\n ...(0,vuex__WEBPACK_IMPORTED_MODULE_10__.mapActions)({\n getShow: 'getShow',\n // Map `this.getShow()` to `this.$store.dispatch('getShow')`\n getEpisodes: 'getEpisodes',\n setCurrentShow: 'setCurrentShow',\n setRecentShow: 'setRecentShow'\n }),\n\n async loadShow() {\n const {\n setCurrentShow,\n showSlug,\n initializeEpisodes,\n getShow\n } = this; // We need detailed info for the xem / scene exceptions, so let's get it.\n\n await getShow({\n showSlug,\n detailed: true\n }); // Let's tell the store which show we currently want as current.\n // Run this after getShow(), as it will trigger the initializeEpisodes() method.\n\n setCurrentShow(showSlug); // Load all episodes\n\n initializeEpisodes();\n },\n\n statusQualityUpdate(event) {\n const {\n selectedEpisodes,\n setStatus,\n setQuality\n } = this;\n\n if (event.newQuality !== null && event.newQuality !== 'Change quality to:') {\n setQuality(event.newQuality, selectedEpisodes);\n }\n\n if (event.newStatus !== null && event.newStatus !== 'Change status to:') {\n setStatus(event.newStatus, selectedEpisodes);\n }\n },\n\n setQuality(quality, episodes) {\n const {\n showSlug,\n getEpisodes,\n show\n } = this;\n const patchData = {};\n episodes.forEach(episode => {\n patchData[episode.slug] = {\n quality: Number.parseInt(quality, 10)\n };\n });\n this.client.api.patch(`series/${show.id.slug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched show ${show.id.slug} with quality ${quality}`);\n [...new Set(episodes.map(episode => episode.season))].forEach(season => {\n getEpisodes({\n showSlug,\n season\n });\n });\n }).catch(error => {\n console.error(String(error));\n });\n },\n\n setStatus(status, episodes) {\n const {\n showSlug,\n getEpisodes\n } = this;\n const patchData = {};\n episodes.forEach(episode => {\n patchData[episode.slug] = {\n status\n };\n });\n this.client.api.patch(`series/${showSlug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched show ${showSlug} with status ${status}`);\n [...new Set(episodes.map(episode => episode.season))].forEach(season => {\n getEpisodes({\n showSlug,\n season\n });\n });\n }).catch(error => {\n console.error(String(error));\n }); // New status Wanted\n\n if (status === 3) {\n this.$modal.show('query-start-backlog-search', {\n episodes\n });\n } // New status Failed\n\n\n if (status === 11) {\n this.$modal.show('query-mark-failed-and-search', {\n episodes\n });\n }\n },\n\n parseDateFn(row) {\n const {\n fuzzyParseDateTime\n } = this;\n return fuzzyParseDateTime(row.airDate);\n },\n\n rowStyleClassFn(row) {\n const {\n getOverviewStatus,\n show\n } = this;\n\n if (Object.keys(row).includes('vgt_header_id')) {\n return;\n }\n\n const overview = getOverviewStatus(row.status, row.quality, show.config.qualities).toLowerCase().trim();\n return overview;\n },\n\n /**\n * Add (reduce) the total episodes filesize.\n * @param {object} headerRow header row object.\n * @returns {string} - Human readable file size.\n */\n addFileSize(headerRow) {\n return (0,_utils_core__WEBPACK_IMPORTED_MODULE_2__.humanFileSize)(headerRow.children.reduce((a, b) => a + (b.file.size || 0), 0));\n },\n\n searchSubtitle(event, episode, lang) {\n const {\n showSlug,\n getEpisodes,\n show,\n subtitleSearchComponents\n } = this;\n const SubtitleSearchClass = vue__WEBPACK_IMPORTED_MODULE_11__[\"default\"].extend(_subtitle_search_vue__WEBPACK_IMPORTED_MODULE_7__[\"default\"]); // eslint-disable-line no-undef\n\n const instance = new SubtitleSearchClass({\n propsData: {\n show,\n episode,\n key: episode.originalIndex,\n lang\n },\n parent: this\n }); // Update the show, as we downloaded new subtitle(s)\n\n instance.$on('update', event => {\n // This could be replaced by the generic websocket updates in future.\n if (event.reason === 'new subtitles found') {\n getEpisodes({\n showSlug,\n season: episode.season\n });\n }\n });\n const node = document.createElement('div');\n const tableRef = episode.season === 0 ? 'table-specials' : 'table-seasons';\n this.$refs[tableRef].$refs[`row-${episode.originalIndex}`][0].after(node);\n instance.$mount(node);\n subtitleSearchComponents.push(instance);\n },\n\n /**\n * Attaches IMDB tooltip\n */\n reflowLayout: lodash_debounce__WEBPACK_IMPORTED_MODULE_0___default()(() => {\n console.debug('Reflowing layout');\n (0,_utils_jquery__WEBPACK_IMPORTED_MODULE_4__.addQTip)(); // eslint-disable-line no-undef\n }, 1000),\n\n /**\n * Check if any of the episodes in this season does not have the status \"unaired\".\n * If that's the case we want to manual season search icon.\n * @param {object} season - A season object.\n * @returns {Boolean} - true if one of the seasons episodes has a status 'unaired'.\n */\n anyEpisodeNotUnaired(season) {\n return season.children.filter(ep => ep.status !== 'Unaired').length > 0;\n },\n\n episodesInverse(season) {\n const {\n invertTable\n } = this;\n\n if (!season.children) {\n return [];\n }\n\n if (invertTable) {\n return season.children.slice().reverse();\n }\n\n return season.children;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeBacklogSearchModalClose(event) {\n this.backlogSearchEpisodes = event.params.episodes;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeFailedSearchModalClose(event) {\n this.failedSearchEpisodes = event.params.episodes;\n },\n\n retryDownload(episode) {\n const {\n stateSearch\n } = this;\n return stateSearch.general.failedDownloads.enabled && ['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n search(episodes, searchType) {\n const {\n show\n } = this;\n let data = {};\n\n if (episodes) {\n data = {\n showSlug: show.id.slug,\n episodes: [],\n options: {}\n };\n episodes.forEach(episode => {\n data.episodes.push(episode.slug);\n this.$refs[`search-${episode.slug}`].src = 'images/loading16.gif';\n });\n }\n\n this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef\n .then(_ => {\n if (episodes.length === 1) {\n console.info(`started search for show: ${show.id.slug} episode: ${episodes[0].slug}`);\n this.$refs[`search-${episodes[0].slug}`].src = 'images/queued.png';\n this.$refs[`search-${episodes[0].slug}`].disabled = true;\n } else {\n console.info('started a full backlog search');\n }\n }).catch(error => {\n console.error(String(error));\n episodes.forEach(episode => {\n data.episodes.push(episode.slug);\n this.$refs[`search-${episodes[0].slug}`].src = 'images/no16.png';\n });\n }).finally(() => {\n this.failedSearchEpisodes = [];\n this.backlogSearchEpisodes = [];\n });\n },\n\n /**\n * Start a backlog search or failed search for the specific episode.\n * A failed search is started depending on the current episodes status.\n * @param {Object} episode - Episode object. If no episode object is passed, a backlog search is started.\n */\n queueSearch(episode) {\n const {\n $modal,\n search,\n retryDownload\n } = this;\n const episodeIdentifier = episode.slug;\n\n if (episode) {\n if (this.$refs[`search-${episodeIdentifier}`].disabled === true) {\n return;\n }\n\n if (retryDownload(episode)) {\n $modal.show('query-mark-failed-and-search', {\n episode\n });\n } else {\n search([episode], 'backlog');\n }\n }\n },\n\n showSubtitleButton(episode) {\n const {\n subtitles,\n show\n } = this;\n return episode.season !== 0 && subtitles.enabled && show.config.subtitlesEnabled && !['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n totalSeasonEpisodeSize(season) {\n return season.children.filter(x => x.file && x.file.size > 0).reduce((a, b) => a + b.file.size, 0);\n },\n\n getSeasonExceptions(season) {\n const {\n show\n } = this;\n const {\n config\n } = show;\n const {\n aliases\n } = config;\n let bindData = {\n class: 'display: none'\n }; // Map the indexer season to a xem mapped season.\n // check if the season exception also exists in the xem numbering table\n\n let xemSeasons = [];\n let foundInXem = false;\n\n if (show.xemNumbering.length > 0) {\n const xemResult = show.xemNumbering.filter(x => x.source.season === season); // Create an array with unique seasons\n\n xemSeasons = [...new Set(xemResult.map(item => item.destination.season))];\n foundInXem = Boolean(xemSeasons.length);\n } // Check if there is a season exception for this season\n\n\n if (aliases.find(x => x.season === season)) {\n // If there is not a match on the xem table, display it as a medusa scene exception\n bindData = {\n id: `xem-exception-season-${foundInXem ? xemSeasons[0] : season}`,\n alt: foundInXem ? '[xem]' : '[medusa]',\n src: foundInXem ? 'images/xem.png' : 'images/ico/favicon-16.png',\n title: foundInXem ? xemSeasons.reduce((a, b) => {\n return a.concat(aliases.filter(alias => alias.season === b).map(alias => alias.title));\n }, []).join(', ') : aliases.filter(alias => alias.season === season).map(alias => alias.title).join(', ')\n };\n }\n\n return bindData;\n },\n\n updateEpisodeWatched(episode, watched) {\n const {\n showSlug,\n getEpisodes,\n show\n } = this;\n const patchData = {};\n patchData[episode.slug] = {\n watched\n };\n this.client.api.patch(`series/${show.id.slug}/episodes`, patchData) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`patched episode ${episode.slug} with watched set to ${watched}`);\n getEpisodes({\n showSlug,\n season: episode.season\n });\n }).catch(error => {\n console.error(String(error));\n });\n episode.watched = watched;\n },\n\n updatePaginationPerPage(rows) {\n const {\n setCookie\n } = this;\n this.paginationPerPage = rows;\n setCookie('pagination-perPage', rows);\n },\n\n onPageChange(params) {\n if (params.prevPage !== params.currentPage) {\n this.loadEpisodes(params.currentPage);\n }\n },\n\n neededSeasons(page) {\n const {\n layout,\n paginationPerPage,\n show\n } = this;\n const {\n seasonCount\n } = show;\n\n if (!seasonCount || seasonCount.length === 0) {\n return [];\n }\n\n if (!layout.show.pagination.enable) {\n return seasonCount.filter(season => season.season !== 0).map(season => season.season).reverse();\n }\n\n const seasons = show.seasonCount.length - 1;\n let pagesCount = 1;\n let episodeCount = 0;\n const pages = {};\n\n for (let i = seasons; i >= 0; i--) {\n const {\n season\n } = show.seasonCount[i]; // Exclude specials\n\n if (season === 0) {\n break;\n }\n\n if (pagesCount in pages) {\n pages[pagesCount].push(season);\n } else {\n pages[pagesCount] = [season];\n }\n\n episodeCount += show.seasonCount[i].episodeCount;\n\n if (episodeCount / paginationPerPage > pagesCount) {\n pagesCount++;\n pages[pagesCount] = [season];\n }\n\n if (pagesCount > page) {\n break;\n }\n }\n\n return pages[page] || [];\n },\n\n loadEpisodes(page) {\n const {\n showSlug,\n getEpisodes\n } = this; // Wrap getEpisodes into an async/await function, so we can wait for the season to have been committed\n // before going on to the next one.\n\n const _getEpisodes = async showSlug => {\n for (const season of this.neededSeasons(page)) {\n // We're waiting for the results by design, to give vue the chance to update the dom.\n // If we fire all the promises at once for, for example 25 seasons. We'll overload medusa's app\n // and chance is high a number of requests will timeout.\n await getEpisodes({\n showSlug,\n season\n }); // eslint-disable-line no-await-in-loop\n }\n };\n\n _getEpisodes(showSlug);\n },\n\n initializeEpisodes() {\n let force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n const {\n getEpisodes,\n showSlug,\n setRecentShow,\n show\n } = this;\n\n if (force || !show.seasons && show.seasonCount) {\n // Load episodes for the first page.\n this.loadEpisodes(1); // Always get special episodes if available.\n\n if (show.seasonCount.length > 0 && show.seasonCount[0].season === 0) {\n getEpisodes({\n showSlug,\n season: 0\n });\n }\n }\n\n if (show.id.slug) {\n // For now i'm dumping this here\n setRecentShow({\n showSlug: show.id.slug,\n name: show.title\n });\n }\n },\n\n mobileSelectSearch(event, episode) {\n const {\n $snotify,\n $router,\n queueSearch,\n searchSubtitle,\n show\n } = this;\n\n if (event.target.value === 'forced') {\n queueSearch(episode);\n $snotify.success(`Search started for S${episode.season} E${episode.episode}`);\n }\n\n if (event.target.value === 'manual') {\n // Use the router to navigate to snatchSelection.\n $router.push({\n name: 'snatchSelection',\n query: {\n showslug: show.id.slug,\n season: episode.season,\n episode: episode.episode\n }\n });\n }\n\n if (event.target.value === 'subtitle') {\n searchSubtitle(event, episode);\n }\n\n setTimeout(() => {\n event.target.value = 'search action';\n }, 2000);\n }\n\n },\n filters: {\n sceneObjectToString(value) {\n return `${value.season}x${value.episode}`;\n }\n\n },\n watch: {\n $route(to, from) {\n if (to.name === 'show' && from.name === 'testRename') {\n // Load all episodes if we're coming from the testRename page.\n this.initializeEpisodes(true);\n }\n }\n\n }\n});\n\n//# sourceURL=webpack://slim/./src/components/display-show.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-1%5B0%5D.rules%5B0%5D!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), @@ -620,7 +620,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n/* harmony import */ var _app_link_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./app-link.vue */ \"./src/components/helpers/app-link.vue\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'select-list',\n components: {\n AppLink: _app_link_vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]\n },\n props: {\n searchType: {\n type: String,\n default: 'forced',\n required: true,\n validator: value => ['backlog', 'manual'].includes(value)\n },\n showSlug: {\n type: String,\n required: true\n },\n episode: {\n type: Object,\n required: true\n }\n },\n\n data() {\n return {\n subtitleComponentInstance: null,\n failedSearchEpisodes: [],\n backlogSearchEpisodes: []\n };\n },\n\n computed: { ...(0,vuex__WEBPACK_IMPORTED_MODULE_1__.mapState)({\n stateSearch: state => state.config.search\n })\n },\n methods: {\n retryDownload(episode) {\n const {\n stateSearch\n } = this;\n return stateSearch.general.failedDownloads.enabled && ['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n search(episode, searchType) {\n const {\n showSlug\n } = this;\n let data = {};\n data = {\n showSlug,\n episodes: [episode.slug],\n options: {}\n };\n this.$refs[`search-${episode.slug}`].src = 'images/loading16-dark.gif';\n this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`started search for show: ${showSlug} episode: ${episode.slug}`);\n this.$refs[`search-${episode.slug}`].src = 'images/queued.png';\n this.$refs[`search-${episode.slug}`].disabled = true;\n }).catch(error => {\n console.error(String(error));\n this.$refs[`search-${episode.slug}`].src = 'images/no16.png';\n }).finally(() => {\n this.failedSearchEpisodes = [];\n this.backlogSearchEpisodes = [];\n });\n },\n\n /**\n * Start a backlog search or failed search for the specific episode.\n * A failed search is started depending on the current episodes status.\n * @param {Object} episode - Episode object. If no episode object is passed, a backlog search is started.\n */\n queueSearch(episode) {\n const {\n $modal,\n search,\n retryDownload\n } = this;\n const episodeIdentifier = episode.slug;\n\n if (episode) {\n if (this.$refs[`search-${episodeIdentifier}`].disabled === true) {\n return;\n }\n\n if (retryDownload(episode)) {\n $modal.show('query-mark-failed-and-search', {\n episode\n });\n } else {\n search(episode, 'backlog');\n }\n }\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeBacklogSearchModalClose(event) {\n this.backlogSearchEpisodes = event.params.episodes;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeFailedSearchModalClose(event) {\n this.failedSearchEpisodes = event.params.episodes;\n }\n\n }\n});\n\n//# sourceURL=webpack://slim/./src/components/helpers/search.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-1%5B0%5D.rules%5B0%5D!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n/* harmony import */ var _app_link_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./app-link.vue */ \"./src/components/helpers/app-link.vue\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\n name: 'search',\n components: {\n AppLink: _app_link_vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]\n },\n props: {\n searchType: {\n type: String,\n default: 'forced',\n required: true,\n validator: value => ['backlog', 'manual'].includes(value)\n },\n showSlug: {\n type: String,\n required: true\n },\n episode: {\n type: Object,\n required: true\n }\n },\n\n data() {\n return {\n subtitleComponentInstance: null,\n failedSearchEpisodes: [],\n backlogSearchEpisodes: [],\n src: 'images/search16.png',\n disabled: false\n };\n },\n\n computed: { ...(0,vuex__WEBPACK_IMPORTED_MODULE_1__.mapState)({\n stateSearch: state => state.config.search,\n client: state => state.auth.client,\n queueitems: state => state.queue.queueitems\n })\n },\n methods: {\n retryDownload(episode) {\n const {\n stateSearch\n } = this;\n return stateSearch.general.failedDownloads.enabled && ['Snatched', 'Snatched (Proper)', 'Snatched (Best)', 'Downloaded'].includes(episode.status);\n },\n\n search(episode, searchType) {\n const {\n showSlug\n } = this;\n let data = {};\n data = {\n showSlug,\n episodes: [episode.slug],\n options: {}\n };\n this.src = 'images/loading16-dark.gif';\n this.client.api.put(`search/${searchType}`, data) // eslint-disable-line no-undef\n .then(_ => {\n console.info(`Queued search for show: ${showSlug} episode: ${episode.slug}`);\n this.src = 'images/queued.png';\n this.disabled = true;\n }).catch(error => {\n console.error(String(error));\n this.$refs[`search-${episode.slug}`].src = 'images/no16.png';\n }).finally(() => {\n this.failedSearchEpisodes = [];\n this.backlogSearchEpisodes = [];\n });\n },\n\n /**\n * Start a backlog search or failed search for the specific episode.\n * A failed search is started depending on the current episodes status.\n * @param {Object} episode - Episode object. If no episode object is passed, a backlog search is started.\n */\n queueSearch(episode) {\n const {\n $modal,\n search,\n retryDownload\n } = this;\n\n if (episode) {\n if (this.disabled === true) {\n return;\n }\n\n if (retryDownload(episode)) {\n $modal.show('query-mark-failed-and-search', {\n episode\n });\n } else {\n search(episode, 'backlog');\n }\n }\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeBacklogSearchModalClose(event) {\n this.backlogSearchEpisodes = event.params.episodes;\n },\n\n /**\n * Vue-js-modal requires a method, to pass an event to.\n * The event then can be used to assign the value of the episode.\n * @param {Object} event - vue js modal event\n */\n beforeFailedSearchModalClose(event) {\n this.failedSearchEpisodes = event.params.episodes;\n }\n\n },\n watch: {\n queueitems(queueitems) {\n const episode = queueitems.filter(q => q.name === 'BACKLOG' && q.show.id.slug === this.showSlug && q.segment.find(s => s.slug === this.episode.slug));\n\n if (episode.length === 0) {\n return;\n }\n\n const lastEp = episode.slice(-1)[0];\n\n if (lastEp.inProgress && lastEp.success === null) {\n // Search is in progress.\n console.info(`Search runnning for show: ${this.showSlug} and episode: ${this.episode.slug}`);\n this.src = 'images/loading16.gif';\n this.disabled = true;\n } else {\n // Search finished.\n console.log(`Search finished for ${this.episode.slug}`);\n this.src = 'images/yes16.png';\n this.disabled = false;\n }\n }\n\n }\n});\n\n//# sourceURL=webpack://slim/./src/components/helpers/search.vue?./node_modules/babel-loader/lib/index.js??clonedRuleSet-1%5B0%5D.rules%5B0%5D!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), @@ -7495,7 +7495,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"display-show-template\", class: _vm.theme },\n [\n _c(\"vue-snotify\"),\n _vm._v(\" \"),\n _vm.show.id.slug\n ? _c(\"backstretch\", {\n key: _vm.show.id.slug,\n attrs: { slug: _vm.show.id.slug }\n })\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"series-id\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"indexer-name\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"series-slug\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"show-header\", {\n ref: \"show-header\",\n attrs: { type: \"show\", slug: _vm.showSlug },\n on: {\n reflow: _vm.reflowLayout,\n update: _vm.statusQualityUpdate,\n \"update-overview-status\": function($event) {\n _vm.filterByOverviewStatus = $event\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"div\",\n { staticClass: \"col-md-12 top-15 displayShow horizontal-scroll\" },\n [\n _vm.show.seasons\n ? _c(\"vue-good-table\", {\n ref: \"table-seasons\",\n attrs: {\n columns: _vm.columns,\n rows: _vm.orderedSeasons,\n groupOptions: {\n enabled: true,\n mode: \"span\"\n },\n \"pagination-options\": {\n enabled: _vm.layout.show.pagination.enable,\n perPage: _vm.paginationPerPage,\n perPageDropdown: _vm.perPageDropdown\n },\n \"search-options\": {\n enabled: true,\n trigger: \"enter\",\n skipDiacritics: false,\n placeholder: \"Search episodes\"\n },\n \"sort-options\": {\n enabled: true,\n initialSortBy: _vm.getSortBy(\"episode\", \"desc\")\n },\n selectOptions: {\n enabled: true,\n selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row\n selectionInfoClass: \"select-info\",\n selectionText: \"episodes selected\",\n clearSelectionText: \"clear\",\n selectAllByGroup: true\n },\n \"row-style-class\": _vm.rowStyleClassFn,\n \"column-filter-options\": {\n enabled: true\n }\n },\n on: {\n \"on-selected-rows-change\": function($event) {\n _vm.selectedEpisodes = $event.selectedRows\n },\n \"on-per-page-change\": function($event) {\n return _vm.updatePaginationPerPage($event.currentPerPage)\n },\n \"on-page-change\": _vm.onPageChange\n },\n scopedSlots: _vm._u(\n [\n {\n key: \"table-header-row\",\n fn: function(props) {\n return [\n _c(\n \"h3\",\n { staticClass: \"season-header toggle collapse\" },\n [\n _c(\"app-link\", {\n attrs: { name: \"season-\" + props.row.season }\n }),\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.row.season > 0\n ? \"Season \" + props.row.season\n : \"Specials\"\n ) +\n \"\\n \"\n ),\n _vm._v(\" \"),\n _vm.anyEpisodeNotUnaired(props.row)\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=1&manual_search_type=season\"\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src:\n \"images/manualsearch-white.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", {\n staticClass: \"season-scene-exception\",\n attrs: {\n \"data-season\":\n props.row.season > 0\n ? props.row.season\n : \"Specials\"\n }\n }),\n _vm._v(\" \"),\n _c(\n \"img\",\n _vm._b(\n {},\n \"img\",\n _vm.getSeasonExceptions(props.row.season),\n false\n )\n )\n ],\n 1\n )\n ]\n }\n },\n {\n key: \"table-footer-row\",\n fn: function(ref) {\n var headerRow = ref.headerRow\n return [\n _c(\n \"tr\",\n {\n staticClass: \"seasoncols border-bottom shadow\",\n attrs: {\n colspan: \"9999\",\n id: \"season-\" + headerRow.season + \"-footer\"\n }\n },\n [\n _c(\n \"th\",\n {\n staticClass: \"col-footer\",\n attrs: { colspan: \"15\", align: \"left\" }\n },\n [\n _vm._v(\n \"Season contains \" +\n _vm._s(headerRow.children.length) +\n \" episodes with total filesize: \" +\n _vm._s(_vm.addFileSize(headerRow))\n )\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"spacer\" })\n ]\n }\n },\n {\n key: \"table-row\",\n fn: function(props) {\n return [\n props.column.field == \"content.hasNfo\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasNfo\n ? \"nfo.gif\"\n : \"nfo-no.gif\"),\n alt: props.row.content.hasNfo ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.field == \"content.hasTbn\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasTbn\n ? \"tbn.gif\"\n : \"tbn-no.gif\"),\n alt: props.row.content.hasTbn ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.label == \"Episode\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n class: {\n addQTip: props.row.file.location !== \"\"\n },\n attrs: {\n title:\n props.row.file.location !== \"\"\n ? props.row.file.location\n : \"\"\n }\n },\n [_vm._v(_vm._s(props.row.episode))]\n )\n ])\n : props.column.label == \"Scene\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Scene Abs. #\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-anime-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Title\"\n ? _c(\n \"span\",\n [\n props.row.description !== \"\"\n ? _c(\"plot-info\", {\n attrs: {\n description: props.row.description,\n \"show-slug\": _vm.show.id.slug,\n season: props.row.season,\n episode: props.row.episode\n }\n })\n : _vm._e(),\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.title) +\n \"\\n \"\n )\n ],\n 1\n )\n : props.column.label == \"File\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: { title: props.row.file.location }\n },\n [_vm._v(_vm._s(props.row.file.name))]\n )\n ])\n : props.column.label == \"Subtitles\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n [\n \"Archived\",\n \"Downloaded\",\n \"Ignored\",\n \"Skipped\"\n ].includes(props.row.status)\n ? _c(\n \"div\",\n { staticClass: \"subtitles\" },\n _vm._l(props.row.subtitles, function(\n flag\n ) {\n return _c(\"div\", { key: flag }, [\n flag !== \"und\"\n ? _c(\"img\", {\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: flag,\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row,\n flag\n )\n }\n }\n })\n : _c(\"img\", {\n staticClass: \"subtitle-flag\",\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: flag,\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n }\n })\n ])\n }),\n 0\n )\n : _vm._e()\n ])\n : props.column.label == \"Status\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"pull-left\" },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.status) +\n \"\\n \"\n ),\n props.row.quality !== 0\n ? _c(\"quality-pill\", {\n attrs: {\n quality: props.row.quality\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n props.row.status !== \"Unaired\"\n ? _c(\"img\", {\n staticClass: \"addQTip\",\n staticStyle: {\n \"margin-left\": \"5px\"\n },\n attrs: {\n title: props.row.watched\n ? \"This episode has been flagged as watched\"\n : \"\",\n src:\n \"images/\" +\n (props.row.watched\n ? \"\"\n : \"not\") +\n \"watched.png\",\n width: \"16\",\n height: \"16\"\n },\n on: {\n click: function($event) {\n return _vm.updateEpisodeWatched(\n props.row,\n !props.row.watched\n )\n }\n }\n })\n : _vm._e()\n ],\n 1\n )\n ])\n : props.column.field == \"search\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"full-width\" },\n [\n _c(\"img\", {\n ref: \"search-\" + props.row.slug,\n staticClass: \"epForcedSearch\",\n attrs: {\n id:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n name:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n src: \"images/search16.png\",\n height: \"16\",\n alt: _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\",\n title: _vm.retryDownload(props.row)\n ? \"Retry Download\"\n : \"Forced Seach\"\n },\n on: {\n click: function($event) {\n return _vm.queueSearch(props.row)\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n id:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n name:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=\" +\n props.row.episode\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src: \"images/manualsearch.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n ),\n _vm._v(\" \"),\n _c(\"img\", {\n attrs: {\n src: \"images/closed_captioning.png\",\n height: \"16\",\n alt: \"search subtitles\",\n title: \"Search Subtitles\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row\n )\n }\n }\n })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"mobile\" }, [\n _c(\n \"select\",\n {\n staticClass:\n \"form-control input-sm mobile-select\",\n attrs: { name: \"search-select\" },\n on: {\n change: function($event) {\n return _vm.mobileSelectSearch(\n $event,\n props.row\n )\n }\n }\n },\n [\n _c(\n \"option\",\n {\n attrs: {\n disabled: \"\",\n selected: \"\",\n value: \"search action\"\n }\n },\n [_vm._v(\"search action\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"forced\" } },\n [\n _vm._v(\n _vm._s(\n _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\"\n )\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"manual\" } },\n [_vm._v(\"manual\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"subtitle\" } },\n [_vm._v(\"subtitle\")]\n )\n ]\n )\n ])\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.formattedRow[props.column.field]\n ) +\n \"\\n \"\n )\n ])\n ]\n }\n },\n {\n key: \"table-column\",\n fn: function(props) {\n return [\n props.column.label == \"Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : props.column.label == \"Scene Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Scene Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(props.column.label) +\n \"\\n \"\n )\n ])\n ]\n }\n }\n ],\n null,\n false,\n 920757038\n )\n })\n : _vm._e(),\n _vm._v(\" \"),\n _vm.layout.show.specials && _vm.specials && _vm.specials.length > 0\n ? _c(\"vue-good-table\", {\n ref: \"table-specials\",\n attrs: {\n columns: _vm.columns,\n rows: _vm.specials,\n groupOptions: {\n enabled: true,\n mode: \"span\",\n customChildObject: \"episodes\"\n },\n \"pagination-options\": {\n enabled: false\n },\n \"search-options\": {\n enabled: true,\n trigger: \"enter\",\n skipDiacritics: false,\n placeholder: \"Search specials\"\n },\n \"sort-options\": {\n enabled: true,\n multipleColumns: true,\n initialSortBy: _vm.getSortBy(\"episode\", \"desc\") // From mixin manage-cookie.js\n },\n selectOptions: {\n enabled: true,\n selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row\n selectionInfoClass: \"select-info\",\n selectionText: \"episodes selected\",\n clearSelectionText: \"clear\",\n selectAllByGroup: true\n },\n \"row-style-class\": _vm.rowStyleClassFn,\n \"column-filter-options\": {\n enabled: false\n }\n },\n on: {\n \"on-selected-rows-change\": function($event) {\n _vm.selectedEpisodes = $event.selectedRows\n }\n },\n scopedSlots: _vm._u(\n [\n {\n key: \"table-header-row\",\n fn: function(props) {\n return [\n _c(\n \"h3\",\n { staticClass: \"season-header toggle collapse\" },\n [\n _c(\"app-link\", {\n attrs: { name: \"season-\" + props.row.season }\n }),\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.row.season > 0\n ? \"Season \" + props.row.season\n : \"Specials\"\n ) +\n \"\\n \"\n ),\n _vm._v(\" \"),\n _vm.anyEpisodeNotUnaired(props.row)\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=1&manual_search_type=season\"\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src:\n \"images/manualsearch-white.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", {\n staticClass: \"season-scene-exception\",\n attrs: {\n \"data-season\":\n props.row.season > 0\n ? props.row.season\n : \"Specials\"\n }\n }),\n _vm._v(\" \"),\n _c(\n \"img\",\n _vm._b(\n {},\n \"img\",\n _vm.getSeasonExceptions(props.row.season),\n false\n )\n )\n ],\n 1\n )\n ]\n }\n },\n {\n key: \"table-footer-row\",\n fn: function(ref) {\n var headerRow = ref.headerRow\n return [\n _c(\n \"tr\",\n {\n staticClass: \"seasoncols border-bottom shadow\",\n attrs: {\n colspan: \"9999\",\n id: \"season-\" + headerRow.season + \"-footer\"\n }\n },\n [\n _c(\n \"th\",\n {\n staticClass: \"col-footer\",\n attrs: { colspan: \"15\", align: \"left\" }\n },\n [\n _vm._v(\n \"Season contains \" +\n _vm._s(headerRow.children.length) +\n \" episodes with total filesize: \" +\n _vm._s(_vm.addFileSize(headerRow))\n )\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"spacer\" })\n ]\n }\n },\n {\n key: \"table-row\",\n fn: function(props) {\n return [\n props.column.field == \"content.hasNfo\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasNfo\n ? \"nfo.gif\"\n : \"nfo-no.gif\"),\n alt: props.row.content.hasNfo ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.field == \"content.hasTbn\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasTbn\n ? \"tbn.gif\"\n : \"tbn-no.gif\"),\n alt: props.row.content.hasTbn ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.label == \"Episode\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n class: {\n addQTip: props.row.file.location !== \"\"\n },\n attrs: {\n title:\n props.row.file.location !== \"\"\n ? props.row.file.location\n : \"\"\n }\n },\n [_vm._v(_vm._s(props.row.episode))]\n )\n ])\n : props.column.label == \"Scene\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Scene Abs. #\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-anime-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Title\"\n ? _c(\n \"span\",\n [\n props.row.description !== \"\"\n ? _c(\"plot-info\", {\n attrs: {\n description: props.row.description,\n \"show-slug\": _vm.show.id.slug,\n season: props.row.season,\n episode: props.row.episode\n }\n })\n : _vm._e(),\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.title) +\n \"\\n \"\n )\n ],\n 1\n )\n : props.column.label == \"File\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: { title: props.row.file.location }\n },\n [_vm._v(_vm._s(props.row.file.name))]\n )\n ])\n : props.column.label == \"Subtitles\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n [\n \"Archived\",\n \"Downloaded\",\n \"Ignored\",\n \"Skipped\"\n ].includes(props.row.status)\n ? _c(\n \"div\",\n { staticClass: \"subtitles\" },\n _vm._l(props.row.subtitles, function(\n flag\n ) {\n return _c(\"div\", { key: flag }, [\n flag !== \"und\"\n ? _c(\"img\", {\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: \"{flag}\",\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row,\n flag\n )\n }\n }\n })\n : _c(\"img\", {\n staticClass: \"subtitle-flag\",\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: \"flag\",\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n }\n })\n ])\n }),\n 0\n )\n : _vm._e()\n ])\n : props.column.label == \"Status\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n _c(\n \"div\",\n { staticClass: \"pull-left\" },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.status) +\n \"\\n \"\n ),\n props.row.quality !== 0\n ? _c(\"quality-pill\", {\n staticClass: \"quality-margins\",\n attrs: {\n quality: props.row.quality\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n props.row.status !== \"Unaired\"\n ? _c(\"img\", {\n staticClass: \"addQTip\",\n attrs: {\n title: props.row.watched\n ? \"This episode has been flagged as watched\"\n : \"\",\n src:\n \"images/\" +\n (props.row.watched\n ? \"\"\n : \"not\") +\n \"watched.png\",\n width: \"16\"\n },\n on: {\n click: function($event) {\n return _vm.updateEpisodeWatched(\n props.row,\n !props.row.watched\n )\n }\n }\n })\n : _vm._e()\n ],\n 1\n )\n ])\n : props.column.field == \"search\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"full-width\" },\n [\n _c(\"img\", {\n ref: \"search-\" + props.row.slug,\n staticClass: \"epForcedSearch\",\n attrs: {\n id:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n name:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n src: \"images/search16.png\",\n height: \"16\",\n alt: _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\",\n title: _vm.retryDownload(props.row)\n ? \"Retry Download\"\n : \"Forced Seach\"\n },\n on: {\n click: function($event) {\n return _vm.queueSearch(props.row)\n }\n }\n }),\n _vm._v(\" \"),\n _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n id:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n name:\n _vm.show.indexer +\n \"x\" +\n _vm.show.id[_vm.show.indexer] +\n \"x\" +\n props.row.season +\n \"x\" +\n props.row.episode,\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=\" +\n props.row.episode\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src: \"images/manualsearch.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n ),\n _vm._v(\" \"),\n _c(\"img\", {\n attrs: {\n src: \"images/closed_captioning.png\",\n height: \"16\",\n alt: \"search subtitles\",\n title: \"Search Subtitles\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row\n )\n }\n }\n })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"mobile\" }, [\n _c(\n \"select\",\n {\n staticClass:\n \"form-control input-sm mobile-select\",\n attrs: { name: \"search-select\" },\n on: {\n change: function($event) {\n return _vm.mobileSelectSearch(\n $event,\n props.row\n )\n }\n }\n },\n [\n _c(\n \"option\",\n {\n attrs: {\n disabled: \"\",\n selected: \"\",\n value: \"search action\"\n }\n },\n [_vm._v(\"search action\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"forced\" } },\n [\n _vm._v(\n _vm._s(\n _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\"\n )\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"manual\" } },\n [_vm._v(\"manual\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"subtitle\" } },\n [_vm._v(\"subtitle\")]\n )\n ]\n )\n ])\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.formattedRow[props.column.field]\n ) +\n \"\\n \"\n )\n ])\n ]\n }\n },\n {\n key: \"table-column\",\n fn: function(props) {\n return [\n props.column.label == \"Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : props.column.label == \"Scene Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Scene Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(props.column.label) +\n \"\\n \"\n )\n ])\n ]\n }\n }\n ],\n null,\n false,\n 2545500086\n )\n })\n : _vm._e()\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-start-backlog-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeBacklogSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-hidden\": \"true\"\n }\n },\n [_vm._v(\"×\")]\n ),\n _vm._v(\" \"),\n _c(\"h4\", { staticClass: \"modal-title\" }, [\n _vm._v(\"Start search?\")\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [\n _vm._v(\n \"Some episodes have been changed to 'Wanted'. Do you want to trigger a backlog search for these \" +\n _vm._s(_vm.backlogSearchEpisodes.length) +\n \" episode(s)\"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.backlogSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-mark-failed-and-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeFailedSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _vm._v(\n \"\\n Mark episode as failed and search?\\n \"\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [_vm._v(\"Starting to search for the episode\")]),\n _vm._v(\" \"),\n _vm.failedSearchEpisodes &&\n _vm.failedSearchEpisodes.length === 1\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episode \" +\n _vm._s(_vm.failedSearchEpisodes[0].slug) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm.failedSearchEpisodes\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episodes \" +\n _vm._s(\n _vm.failedSearchEpisodes\n .map(function(ep) {\n return ep.slug\n })\n .join(\", \")\n ) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"failed\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\n \"query-mark-failed-and-search\"\n )\n }\n }\n },\n [_vm._v(\"Cancel\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://slim/./src/components/display-show.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"display-show-template\", class: _vm.theme },\n [\n _c(\"vue-snotify\"),\n _vm._v(\" \"),\n _vm.show.id.slug\n ? _c(\"backstretch\", {\n key: _vm.show.id.slug,\n attrs: { slug: _vm.show.id.slug }\n })\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"series-id\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"indexer-name\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"input\", { attrs: { type: \"hidden\", id: \"series-slug\", value: \"\" } }),\n _vm._v(\" \"),\n _c(\"show-header\", {\n ref: \"show-header\",\n attrs: { type: \"show\", slug: _vm.showSlug },\n on: {\n reflow: _vm.reflowLayout,\n update: _vm.statusQualityUpdate,\n \"update-overview-status\": function($event) {\n _vm.filterByOverviewStatus = $event\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"row\" }, [\n _c(\n \"div\",\n { staticClass: \"col-md-12 top-15 displayShow horizontal-scroll\" },\n [\n _vm.show.seasons\n ? _c(\"vue-good-table\", {\n ref: \"table-seasons\",\n attrs: {\n columns: _vm.columns,\n rows: _vm.orderedSeasons,\n groupOptions: {\n enabled: true,\n mode: \"span\"\n },\n \"pagination-options\": {\n enabled: _vm.layout.show.pagination.enable,\n perPage: _vm.paginationPerPage,\n perPageDropdown: _vm.perPageDropdown\n },\n \"search-options\": {\n enabled: true,\n trigger: \"enter\",\n skipDiacritics: false,\n placeholder: \"Search episodes\"\n },\n \"sort-options\": {\n enabled: true,\n initialSortBy: _vm.getSortBy(\"episode\", \"desc\")\n },\n selectOptions: {\n enabled: true,\n selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row\n selectionInfoClass: \"select-info\",\n selectionText: \"episodes selected\",\n clearSelectionText: \"clear\",\n selectAllByGroup: true\n },\n \"row-style-class\": _vm.rowStyleClassFn,\n \"column-filter-options\": {\n enabled: true\n }\n },\n on: {\n \"on-selected-rows-change\": function($event) {\n _vm.selectedEpisodes = $event.selectedRows\n },\n \"on-per-page-change\": function($event) {\n return _vm.updatePaginationPerPage($event.currentPerPage)\n },\n \"on-page-change\": _vm.onPageChange\n },\n scopedSlots: _vm._u(\n [\n {\n key: \"table-header-row\",\n fn: function(props) {\n return [\n _c(\n \"h3\",\n { staticClass: \"season-header toggle collapse\" },\n [\n _c(\"app-link\", {\n attrs: { name: \"season-\" + props.row.season }\n }),\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.row.season > 0\n ? \"Season \" + props.row.season\n : \"Specials\"\n ) +\n \"\\n \"\n ),\n _vm._v(\" \"),\n _vm.anyEpisodeNotUnaired(props.row)\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=1&manual_search_type=season\"\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src:\n \"images/manualsearch-white.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", {\n staticClass: \"season-scene-exception\",\n attrs: {\n \"data-season\":\n props.row.season > 0\n ? props.row.season\n : \"Specials\"\n }\n }),\n _vm._v(\" \"),\n _c(\n \"img\",\n _vm._b(\n {},\n \"img\",\n _vm.getSeasonExceptions(props.row.season),\n false\n )\n )\n ],\n 1\n )\n ]\n }\n },\n {\n key: \"table-footer-row\",\n fn: function(ref) {\n var headerRow = ref.headerRow\n return [\n _c(\n \"tr\",\n {\n staticClass: \"seasoncols border-bottom shadow\",\n attrs: {\n colspan: \"9999\",\n id: \"season-\" + headerRow.season + \"-footer\"\n }\n },\n [\n _c(\n \"th\",\n {\n staticClass: \"col-footer\",\n attrs: { colspan: \"15\", align: \"left\" }\n },\n [\n _vm._v(\n \"Season contains \" +\n _vm._s(headerRow.children.length) +\n \" episodes with total filesize: \" +\n _vm._s(_vm.addFileSize(headerRow))\n )\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"spacer\" })\n ]\n }\n },\n {\n key: \"table-row\",\n fn: function(props) {\n return [\n props.column.field == \"content.hasNfo\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasNfo\n ? \"nfo.gif\"\n : \"nfo-no.gif\"),\n alt: props.row.content.hasNfo ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.field == \"content.hasTbn\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasTbn\n ? \"tbn.gif\"\n : \"tbn-no.gif\"),\n alt: props.row.content.hasTbn ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.label == \"Episode\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n class: {\n addQTip: props.row.file.location !== \"\"\n },\n attrs: {\n title:\n props.row.file.location !== \"\"\n ? props.row.file.location\n : \"\"\n }\n },\n [_vm._v(_vm._s(props.row.episode))]\n )\n ])\n : props.column.label == \"Scene\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Scene Abs. #\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-anime-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Title\"\n ? _c(\n \"span\",\n [\n props.row.description !== \"\"\n ? _c(\"plot-info\", {\n attrs: {\n description: props.row.description,\n \"show-slug\": _vm.show.id.slug,\n season: props.row.season,\n episode: props.row.episode\n }\n })\n : _vm._e(),\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.title) +\n \"\\n \"\n )\n ],\n 1\n )\n : props.column.label == \"File\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: { title: props.row.file.location }\n },\n [_vm._v(_vm._s(props.row.file.name))]\n )\n ])\n : props.column.label == \"Subtitles\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n [\n \"Archived\",\n \"Downloaded\",\n \"Ignored\",\n \"Skipped\"\n ].includes(props.row.status)\n ? _c(\n \"div\",\n { staticClass: \"subtitles\" },\n _vm._l(props.row.subtitles, function(\n flag\n ) {\n return _c(\"div\", { key: flag }, [\n flag !== \"und\"\n ? _c(\"img\", {\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: flag,\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row,\n flag\n )\n }\n }\n })\n : _c(\"img\", {\n staticClass: \"subtitle-flag\",\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: flag,\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n }\n })\n ])\n }),\n 0\n )\n : _vm._e()\n ])\n : props.column.label == \"Status\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"pull-left\" },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.status) +\n \"\\n \"\n ),\n props.row.quality !== 0\n ? _c(\"quality-pill\", {\n attrs: {\n quality: props.row.quality\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n props.row.status !== \"Unaired\"\n ? _c(\"img\", {\n staticClass: \"addQTip\",\n staticStyle: {\n \"margin-left\": \"5px\"\n },\n attrs: {\n title: props.row.watched\n ? \"This episode has been flagged as watched\"\n : \"\",\n src:\n \"images/\" +\n (props.row.watched\n ? \"\"\n : \"not\") +\n \"watched.png\",\n width: \"16\",\n height: \"16\"\n },\n on: {\n click: function($event) {\n return _vm.updateEpisodeWatched(\n props.row,\n !props.row.watched\n )\n }\n }\n })\n : _vm._e()\n ],\n 1\n )\n ])\n : props.column.field == \"search\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"full-width\" },\n [\n _c(\"search\", {\n ref: \"search-\" + props.row.slug,\n staticStyle: {\n \"margin-right\": \"0.25rem\"\n },\n attrs: {\n searchType: \"backlog\",\n showSlug: _vm.showSlug,\n episode: {\n episode: props.row.episode,\n season: props.row.season,\n slug: props.row.slug\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"search\", {\n staticStyle: {\n \"margin-right\": \"0.25rem\"\n },\n attrs: {\n searchType: \"manual\",\n showSlug: _vm.showSlug,\n episode: {\n episode: props.row.episode,\n season: props.row.season,\n slug: props.row.slug\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"img\", {\n attrs: {\n src: \"images/closed_captioning.png\",\n height: \"16\",\n alt: \"search subtitles\",\n title: \"Search Subtitles\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row\n )\n }\n }\n })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"mobile\" }, [\n _c(\n \"select\",\n {\n staticClass:\n \"form-control input-sm mobile-select\",\n attrs: { name: \"search-select\" },\n on: {\n change: function($event) {\n return _vm.mobileSelectSearch(\n $event,\n props.row\n )\n }\n }\n },\n [\n _c(\n \"option\",\n {\n attrs: {\n disabled: \"\",\n selected: \"\",\n value: \"search action\"\n }\n },\n [_vm._v(\"search action\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"forced\" } },\n [\n _vm._v(\n _vm._s(\n _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\"\n )\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"manual\" } },\n [_vm._v(\"manual\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"subtitle\" } },\n [_vm._v(\"subtitle\")]\n )\n ]\n )\n ])\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.formattedRow[props.column.field]\n ) +\n \"\\n \"\n )\n ])\n ]\n }\n },\n {\n key: \"table-column\",\n fn: function(props) {\n return [\n props.column.label == \"Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : props.column.label == \"Scene Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Scene Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(props.column.label) +\n \"\\n \"\n )\n ])\n ]\n }\n }\n ],\n null,\n false,\n 1718487019\n )\n })\n : _vm._e(),\n _vm._v(\" \"),\n _vm.layout.show.specials && _vm.specials && _vm.specials.length > 0\n ? _c(\"vue-good-table\", {\n ref: \"table-specials\",\n attrs: {\n columns: _vm.columns,\n rows: _vm.specials,\n groupOptions: {\n enabled: true,\n mode: \"span\",\n customChildObject: \"episodes\"\n },\n \"pagination-options\": {\n enabled: false\n },\n \"search-options\": {\n enabled: true,\n trigger: \"enter\",\n skipDiacritics: false,\n placeholder: \"Search specials\"\n },\n \"sort-options\": {\n enabled: true,\n multipleColumns: true,\n initialSortBy: _vm.getSortBy(\"episode\", \"desc\") // From mixin manage-cookie.js\n },\n selectOptions: {\n enabled: true,\n selectOnCheckboxOnly: true, // only select when checkbox is clicked instead of the row\n selectionInfoClass: \"select-info\",\n selectionText: \"episodes selected\",\n clearSelectionText: \"clear\",\n selectAllByGroup: true\n },\n \"row-style-class\": _vm.rowStyleClassFn,\n \"column-filter-options\": {\n enabled: false\n }\n },\n on: {\n \"on-selected-rows-change\": function($event) {\n _vm.selectedEpisodes = $event.selectedRows\n }\n },\n scopedSlots: _vm._u(\n [\n {\n key: \"table-header-row\",\n fn: function(props) {\n return [\n _c(\n \"h3\",\n { staticClass: \"season-header toggle collapse\" },\n [\n _c(\"app-link\", {\n attrs: { name: \"season-\" + props.row.season }\n }),\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.row.season > 0\n ? \"Season \" + props.row.season\n : \"Specials\"\n ) +\n \"\\n \"\n ),\n _vm._v(\" \"),\n _vm.anyEpisodeNotUnaired(props.row)\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.show.id.slug +\n \"&season=\" +\n props.row.season +\n \"&episode=1&manual_search_type=season\"\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src:\n \"images/manualsearch-white.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\"div\", {\n staticClass: \"season-scene-exception\",\n attrs: {\n \"data-season\":\n props.row.season > 0\n ? props.row.season\n : \"Specials\"\n }\n }),\n _vm._v(\" \"),\n _c(\n \"img\",\n _vm._b(\n {},\n \"img\",\n _vm.getSeasonExceptions(props.row.season),\n false\n )\n )\n ],\n 1\n )\n ]\n }\n },\n {\n key: \"table-footer-row\",\n fn: function(ref) {\n var headerRow = ref.headerRow\n return [\n _c(\n \"tr\",\n {\n staticClass: \"seasoncols border-bottom shadow\",\n attrs: {\n colspan: \"9999\",\n id: \"season-\" + headerRow.season + \"-footer\"\n }\n },\n [\n _c(\n \"th\",\n {\n staticClass: \"col-footer\",\n attrs: { colspan: \"15\", align: \"left\" }\n },\n [\n _vm._v(\n \"Season contains \" +\n _vm._s(headerRow.children.length) +\n \" episodes with total filesize: \" +\n _vm._s(_vm.addFileSize(headerRow))\n )\n ]\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\"tr\", { staticClass: \"spacer\" })\n ]\n }\n },\n {\n key: \"table-row\",\n fn: function(props) {\n return [\n props.column.field == \"content.hasNfo\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasNfo\n ? \"nfo.gif\"\n : \"nfo-no.gif\"),\n alt: props.row.content.hasNfo ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.field == \"content.hasTbn\"\n ? _c(\"span\", [\n _c(\"img\", {\n attrs: {\n src:\n \"images/\" +\n (props.row.content.hasTbn\n ? \"tbn.gif\"\n : \"tbn-no.gif\"),\n alt: props.row.content.hasTbn ? \"Y\" : \"N\",\n width: \"23\",\n height: \"11\"\n }\n })\n ])\n : props.column.label == \"Episode\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n class: {\n addQTip: props.row.file.location !== \"\"\n },\n attrs: {\n title:\n props.row.file.location !== \"\"\n ? props.row.file.location\n : \"\"\n }\n },\n [_vm._v(_vm._s(props.row.episode))]\n )\n ])\n : props.column.label == \"Scene\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Scene Abs. #\"\n ? _c(\n \"span\",\n { staticClass: \"align-center\" },\n [\n _c(\"scene-number-anime-input\", {\n attrs: {\n show: _vm.show,\n \"initial-episode\": props.row\n }\n })\n ],\n 1\n )\n : props.column.label == \"Title\"\n ? _c(\n \"span\",\n [\n props.row.description !== \"\"\n ? _c(\"plot-info\", {\n attrs: {\n description: props.row.description,\n \"show-slug\": _vm.show.id.slug,\n season: props.row.season,\n episode: props.row.episode\n }\n })\n : _vm._e(),\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.title) +\n \"\\n \"\n )\n ],\n 1\n )\n : props.column.label == \"File\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: { title: props.row.file.location }\n },\n [_vm._v(_vm._s(props.row.file.name))]\n )\n ])\n : props.column.label == \"Subtitles\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n [\n \"Archived\",\n \"Downloaded\",\n \"Ignored\",\n \"Skipped\"\n ].includes(props.row.status)\n ? _c(\n \"div\",\n { staticClass: \"subtitles\" },\n _vm._l(props.row.subtitles, function(\n flag\n ) {\n return _c(\"div\", { key: flag }, [\n flag !== \"und\"\n ? _c(\"img\", {\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: \"{flag}\",\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row,\n flag\n )\n }\n }\n })\n : _c(\"img\", {\n staticClass: \"subtitle-flag\",\n attrs: {\n src:\n \"images/subtitles/flags/\" +\n flag +\n \".png\",\n width: \"16\",\n height: \"11\",\n alt: \"flag\",\n onError:\n \"this.onerror=null;this.src='images/flags/unknown.png';\"\n }\n })\n ])\n }),\n 0\n )\n : _vm._e()\n ])\n : props.column.label == \"Status\"\n ? _c(\"span\", { staticClass: \"align-center\" }, [\n _c(\n \"div\",\n { staticClass: \"pull-left\" },\n [\n _vm._v(\n \"\\n \" +\n _vm._s(props.row.status) +\n \"\\n \"\n ),\n props.row.quality !== 0\n ? _c(\"quality-pill\", {\n staticClass: \"quality-margins\",\n attrs: {\n quality: props.row.quality\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n props.row.status !== \"Unaired\"\n ? _c(\"img\", {\n staticClass: \"addQTip\",\n attrs: {\n title: props.row.watched\n ? \"This episode has been flagged as watched\"\n : \"\",\n src:\n \"images/\" +\n (props.row.watched\n ? \"\"\n : \"not\") +\n \"watched.png\",\n width: \"16\"\n },\n on: {\n click: function($event) {\n return _vm.updateEpisodeWatched(\n props.row,\n !props.row.watched\n )\n }\n }\n })\n : _vm._e()\n ],\n 1\n )\n ])\n : props.column.field == \"search\"\n ? _c(\"span\", [\n _c(\n \"div\",\n { staticClass: \"full-width\" },\n [\n _c(\"search\", {\n ref: \"search-\" + props.row.slug,\n staticStyle: {\n \"margin-right\": \"0.25rem\"\n },\n attrs: {\n searchType: \"backlog\",\n showSlug: _vm.showSlug,\n episode: {\n episode: props.row.episode,\n season: props.row.season,\n slug: props.row.slug\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"search\", {\n staticStyle: {\n \"margin-right\": \"0.25rem\"\n },\n attrs: {\n searchType: \"manual\",\n showSlug: _vm.showSlug,\n episode: {\n episode: props.row.episode,\n season: props.row.season,\n slug: props.row.slug\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"img\", {\n attrs: {\n src: \"images/closed_captioning.png\",\n height: \"16\",\n alt: \"search subtitles\",\n title: \"Search Subtitles\"\n },\n on: {\n click: function($event) {\n return _vm.searchSubtitle(\n $event,\n props.row\n )\n }\n }\n })\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"mobile\" }, [\n _c(\n \"select\",\n {\n staticClass:\n \"form-control input-sm mobile-select\",\n attrs: { name: \"search-select\" },\n on: {\n change: function($event) {\n return _vm.mobileSelectSearch(\n $event,\n props.row\n )\n }\n }\n },\n [\n _c(\n \"option\",\n {\n attrs: {\n disabled: \"\",\n selected: \"\",\n value: \"search action\"\n }\n },\n [_vm._v(\"search action\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"forced\" } },\n [\n _vm._v(\n _vm._s(\n _vm.retryDownload(props.row)\n ? \"retry\"\n : \"search\"\n )\n )\n ]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"manual\" } },\n [_vm._v(\"manual\")]\n ),\n _vm._v(\" \"),\n _c(\n \"option\",\n { attrs: { value: \"subtitle\" } },\n [_vm._v(\"subtitle\")]\n )\n ]\n )\n ])\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(\n props.formattedRow[props.column.field]\n ) +\n \"\\n \"\n )\n ])\n ]\n }\n },\n {\n key: \"table-column\",\n fn: function(props) {\n return [\n props.column.label == \"Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : props.column.label == \"Scene Abs. #\"\n ? _c(\"span\", [\n _c(\n \"span\",\n {\n staticClass: \"addQTip\",\n attrs: {\n title: \"Scene Absolute episode number\"\n }\n },\n [_vm._v(_vm._s(props.column.label))]\n )\n ])\n : _c(\"span\", [\n _vm._v(\n \"\\n \" +\n _vm._s(props.column.label) +\n \"\\n \"\n )\n ])\n ]\n }\n }\n ],\n null,\n false,\n 848378579\n )\n })\n : _vm._e()\n ],\n 1\n )\n ]),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-start-backlog-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeBacklogSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-hidden\": \"true\"\n }\n },\n [_vm._v(\"×\")]\n ),\n _vm._v(\" \"),\n _c(\"h4\", { staticClass: \"modal-title\" }, [\n _vm._v(\"Start search?\")\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [\n _vm._v(\n \"Some episodes have been changed to 'Wanted'. Do you want to trigger a backlog search for these \" +\n _vm._s(_vm.backlogSearchEpisodes.length) +\n \" episode(s)\"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.backlogSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-mark-failed-and-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeFailedSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _vm._v(\n \"\\n Mark episode as failed and search?\\n \"\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [_vm._v(\"Starting to search for the episode\")]),\n _vm._v(\" \"),\n _vm.failedSearchEpisodes &&\n _vm.failedSearchEpisodes.length === 1\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episode \" +\n _vm._s(_vm.failedSearchEpisodes[0].slug) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm.failedSearchEpisodes\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episodes \" +\n _vm._s(\n _vm.failedSearchEpisodes\n .map(function(ep) {\n return ep.slug\n })\n .join(\", \")\n ) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"failed\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\n \"query-mark-failed-and-search\"\n )\n }\n }\n },\n [_vm._v(\"Cancel\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://slim/./src/components/display-show.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), @@ -7880,7 +7880,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"search-wrapper\" },\n [\n _vm.searchType === \"backlog\"\n ? _c(\"img\", {\n ref: \"search-\" + _vm.episode.slug,\n staticClass: \"epForcedSearch\",\n attrs: {\n id:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n name:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n src: \"images/search16.png\",\n height: \"16\",\n alt: _vm.retryDownload(_vm.episode) ? \"retry\" : \"search\",\n title: _vm.retryDownload(_vm.episode)\n ? \"Retry Download\"\n : \"Forced Seach\"\n },\n on: {\n click: function($event) {\n return _vm.queueSearch(_vm.episode)\n }\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n _vm.searchType === \"manual\"\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n id: _vm.showSlug + \"x\" + _vm.episode.episode,\n name:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.showSlug +\n \"&season=\" +\n _vm.episode.season +\n \"&episode=\" +\n _vm.episode.episode\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src: \"images/manualsearch.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-start-backlog-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeBacklogSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-hidden\": \"true\"\n }\n },\n [_vm._v(\"×\")]\n ),\n _vm._v(\" \"),\n _c(\"h4\", { staticClass: \"modal-title\" }, [\n _vm._v(\"Start search?\")\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [\n _vm._v(\n \"Some episodes have been changed to 'Wanted'. Do you want to trigger a backlog search for these \" +\n _vm._s(_vm.backlogSearchEpisodes.length) +\n \" episode(s)\"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.backlogSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-mark-failed-and-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeFailedSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _vm._v(\n \"\\n Mark episode as failed and search?\\n \"\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [_vm._v(\"Starting to search for the episode\")]),\n _vm._v(\" \"),\n _vm.failedSearchEpisodes &&\n _vm.failedSearchEpisodes.length === 1\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episode \" +\n _vm._s(_vm.failedSearchEpisodes[0].slug) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm.failedSearchEpisodes\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episodes \" +\n _vm._s(\n _vm.failedSearchEpisodes\n .map(function(ep) {\n return ep.slug\n })\n .join(\", \")\n ) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"failed\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\n \"query-mark-failed-and-search\"\n )\n }\n }\n },\n [_vm._v(\"Cancel\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://slim/./src/components/helpers/search.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"render\": () => (/* binding */ render),\n/* harmony export */ \"staticRenderFns\": () => (/* binding */ staticRenderFns)\n/* harmony export */ });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n { staticClass: \"search-wrapper\" },\n [\n _vm.searchType === \"backlog\"\n ? _c(\"img\", {\n ref: \"search-\" + _vm.episode.slug,\n staticClass: \"epForcedSearch\",\n attrs: {\n id:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n name:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n src: _vm.src,\n height: \"16\",\n alt: _vm.retryDownload(_vm.episode) ? \"retry\" : \"search\",\n title: _vm.retryDownload(_vm.episode)\n ? \"Retry Download\"\n : \"Forced Seach\",\n disabled: _vm.disabled\n },\n on: {\n click: function($event) {\n return _vm.queueSearch(_vm.episode)\n }\n }\n })\n : _vm._e(),\n _vm._v(\" \"),\n _vm.searchType === \"manual\"\n ? _c(\n \"app-link\",\n {\n staticClass: \"epManualSearch\",\n attrs: {\n id: _vm.showSlug + \"x\" + _vm.episode.episode,\n name:\n _vm.showSlug +\n \"x\" +\n _vm.episode.season +\n \"x\" +\n _vm.episode.episode,\n href:\n \"home/snatchSelection?showslug=\" +\n _vm.showSlug +\n \"&season=\" +\n _vm.episode.season +\n \"&episode=\" +\n _vm.episode.episode\n }\n },\n [\n _c(\"img\", {\n attrs: {\n \"data-ep-manual-search\": \"\",\n src: \"images/manualsearch.png\",\n width: \"16\",\n height: \"16\",\n alt: \"search\",\n title: \"Manual Search\"\n }\n })\n ]\n )\n : _vm._e(),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-start-backlog-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeBacklogSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _c(\n \"button\",\n {\n staticClass: \"close\",\n attrs: {\n type: \"button\",\n \"data-dismiss\": \"modal\",\n \"aria-hidden\": \"true\"\n }\n },\n [_vm._v(\"×\")]\n ),\n _vm._v(\" \"),\n _c(\"h4\", { staticClass: \"modal-title\" }, [\n _vm._v(\"Start search?\")\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [\n _vm._v(\n \"Some episodes have been changed to 'Wanted'. Do you want to trigger a backlog search for these \" +\n _vm._s(_vm.backlogSearchEpisodes.length) +\n \" episode(s)\"\n )\n ])\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.backlogSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-start-backlog-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n ),\n _vm._v(\" \"),\n _c(\n \"modal\",\n {\n attrs: {\n name: \"query-mark-failed-and-search\",\n height: \"auto\",\n width: \"80%\"\n },\n on: { \"before-open\": _vm.beforeFailedSearchModalClose }\n },\n [\n _c(\"transition\", { attrs: { name: \"modal\" } }, [\n _c(\"div\", { staticClass: \"modal-mask\" }, [\n _c(\"div\", { staticClass: \"modal-wrapper\" }, [\n _c(\"div\", { staticClass: \"modal-content\" }, [\n _c(\"div\", { staticClass: \"modal-header\" }, [\n _vm._v(\n \"\\n Mark episode as failed and search?\\n \"\n )\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-body\" }, [\n _c(\"p\", [_vm._v(\"Starting to search for the episode\")]),\n _vm._v(\" \"),\n _vm.failedSearchEpisodes &&\n _vm.failedSearchEpisodes.length === 1\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episode \" +\n _vm._s(_vm.failedSearchEpisodes[0].slug) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm.failedSearchEpisodes\n ? _c(\"p\", [\n _vm._v(\n \"Would you also like to mark episodes \" +\n _vm._s(\n _vm.failedSearchEpisodes\n .map(function(ep) {\n return ep.slug\n })\n .join(\", \")\n ) +\n ' as \"failed\"? This will make sure the episode cannot be downloaded again'\n )\n ])\n : _vm._e()\n ]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"modal-footer\" }, [\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"backlog\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"No\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-success\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n _vm.search(_vm.failedSearchEpisodes, \"failed\")\n _vm.$modal.hide(\"query-mark-failed-and-search\")\n }\n }\n },\n [_vm._v(\"Yes\")]\n ),\n _vm._v(\" \"),\n _c(\n \"button\",\n {\n staticClass: \"btn-medusa btn-danger\",\n attrs: { type: \"button\", \"data-dismiss\": \"modal\" },\n on: {\n click: function($event) {\n return _vm.$modal.hide(\n \"query-mark-failed-and-search\"\n )\n }\n }\n },\n [_vm._v(\"Cancel\")]\n )\n ])\n ])\n ])\n ])\n ])\n ],\n 1\n )\n ],\n 1\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack://slim/./src/components/helpers/search.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), From ff524fca2163619d05c874f1878c5714590d3bf7 Mon Sep 17 00:00:00 2001 From: p0psicles Date: Thu, 12 May 2022 19:55:00 +0200 Subject: [PATCH 02/15] Fixed a runtime error when loading components. --- .../slim/src/components/display-show.vue | 52 ++++--------------- 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/themes-default/slim/src/components/display-show.vue b/themes-default/slim/src/components/display-show.vue index aa352174dc..94e15a46ab 100644 --- a/themes-default/slim/src/components/display-show.vue +++ b/themes-default/slim/src/components/display-show.vue @@ -6,12 +6,13 @@ -
@@ -128,29 +129,13 @@
- - - - - search subtitles
@@ -287,26 +272,11 @@
- - - - From 87fad1e53b7657e08986fbd9f169ab1e583e2062 Mon Sep 17 00:00:00 2001 From: p0psicles Date: Thu, 12 May 2022 19:55:22 +0200 Subject: [PATCH 03/15] Don't render show-header until fully switched to new showSlug. --- themes-default/slim/src/components/show-header.vue | 6 +++--- themes/dark/assets/js/medusa-runtime.js | 6 +++--- themes/light/assets/js/medusa-runtime.js | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/themes-default/slim/src/components/show-header.vue b/themes-default/slim/src/components/show-header.vue index 598c6d8ad2..40a0a21d40 100644 --- a/themes-default/slim/src/components/show-header.vue +++ b/themes-default/slim/src/components/show-header.vue @@ -1,5 +1,5 @@