Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c43385484 | ||
|
|
d2d21258d4 | ||
|
|
3847ba1c58 | ||
|
|
3a65a4bb39 | ||
|
|
6ab9b4ad1f | ||
|
|
f5127637ca | ||
|
|
f995fd14a6 | ||
|
|
9296d64571 | ||
|
|
f00556ab51 | ||
|
|
1c88e13a97 |
No files matched your search
@@ -1,5 +1,19 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [3.9.2](https://github.com/Masutayunikon/FanKarr/compare/v3.9.1...v3.9.2) (2026-04-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* le bouton "tous télécharger" ne s'affiche plus si la series de contient que des integrales comme torrent ([d21270a](https://github.com/Masutayunikon/FanKarr/commit/d21270ae802ee43242365331922393b5cbf689fa))
|
||||||
|
|
||||||
|
## [3.9.1](https://github.com/Masutayunikon/FanKarr/compare/v3.9.0...v3.9.1) (2026-04-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* le badge de rename utilise la meme logique que coté serveur et n'apparait plus sur les vue series si il ne devrais pas ([9764d2d](https://github.com/Masutayunikon/FanKarr/commit/9764d2db8ed2531af3feb6ceba947eaf116c1e76))
|
||||||
|
|
||||||
## [3.9.0](https://github.com/Masutayunikon/FanKarr/compare/v3.8.1...v3.9.0) (2026-04-15)
|
## [3.9.0](https://github.com/Masutayunikon/FanKarr/compare/v3.8.1...v3.9.0) (2026-04-15)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ const props = defineProps<{
|
|||||||
organizedByEpisode: Record<string, any>
|
organizedByEpisode: Record<string, any>
|
||||||
epActionLoading : Record<number, boolean>
|
epActionLoading : Record<number, boolean>
|
||||||
downloadingSeason ?: boolean
|
downloadingSeason ?: boolean
|
||||||
|
nfoSupport ?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -253,9 +254,11 @@ function epExpectedName(ep: any): string {
|
|||||||
const entry = props.organizedByEpisode[String(ep.id)]
|
const entry = props.organizedByEpisode[String(ep.id)]
|
||||||
if (!entry) return ''
|
if (!entry) return ''
|
||||||
const srcExt = entry.dest_filename ? '.' + entry.dest_filename.split('.').pop() : '.mkv'
|
const srcExt = entry.dest_filename ? '.' + entry.dest_filename.split('.').pop() : '.mkv'
|
||||||
if (ep.nfo_filename) return ep.nfo_filename.replace(/\.[^.]+$/, '') + srcExt
|
if (props.nfoSupport) {
|
||||||
if (ep.formatted_name?.trim()) return ep.formatted_name.replace(/[<>:"/\\|?*]/g, '').trim() + srcExt
|
return ep.nfo_filename ? ep.nfo_filename.replace(/\.[^.]+$/, '') + srcExt : entry.dest_filename
|
||||||
return entry.dest_filename
|
} else {
|
||||||
|
return ep.formatted_name?.trim() ? ep.formatted_name.replace(/[<>:"/\\|?*]/g, '').trim() + srcExt : entry.dest_filename
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function epNeedsRename(ep: any): boolean {
|
function epNeedsRename(ep: any): boolean {
|
||||||
const entry = props.organizedByEpisode[String(ep.id)]
|
const entry = props.organizedByEpisode[String(ep.id)]
|
||||||
|
|||||||
+22
-2
@@ -19,7 +19,7 @@
|
|||||||
:serie="data.serie"
|
:serie="data.serie"
|
||||||
:torrents-integrale="data.torrents_integrale"
|
:torrents-integrale="data.torrents_integrale"
|
||||||
:organized-by-episode="organizedByEpisode"
|
:organized-by-episode="organizedByEpisode"
|
||||||
:has-downloadable-torrents="hasDownloadableTorrents"
|
:has-downloadable-torrents="hasNonIntegraleDownloadables"
|
||||||
:downloading-all="downloadingAll"
|
:downloading-all="downloadingAll"
|
||||||
:active-torrents="activeTorrents"
|
:active-torrents="activeTorrents"
|
||||||
:downloading="downloading"
|
:downloading="downloading"
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
:organized-by-episode="organizedByEpisode"
|
:organized-by-episode="organizedByEpisode"
|
||||||
:ep-action-loading="epActionLoading"
|
:ep-action-loading="epActionLoading"
|
||||||
:downloading-season="!!downloadingSeason[season.id]"
|
:downloading-season="!!downloadingSeason[season.id]"
|
||||||
|
:nfo-support="nfoSupport"
|
||||||
@toggle="toggleSeason"
|
@toggle="toggleSeason"
|
||||||
@download="(key, url, magnet) => download(key, url, magnet)"
|
@download="(key, url, magnet) => download(key, url, magnet)"
|
||||||
@download-season="downloadSeason"
|
@download-season="downloadSeason"
|
||||||
@@ -87,6 +88,7 @@ const downloaded = ref<string[]>([])
|
|||||||
const manualImportOpen = ref(false)
|
const manualImportOpen = ref(false)
|
||||||
const organizedByEpisode = ref<Record<string, any>>({})
|
const organizedByEpisode = ref<Record<string, any>>({})
|
||||||
const mediaPath = ref('/')
|
const mediaPath = ref('/')
|
||||||
|
const nfoSupport = ref(false)
|
||||||
const epActionLoading = ref<Record<number, boolean>>({})
|
const epActionLoading = ref<Record<number, boolean>>({})
|
||||||
const unimportMenuOpen = ref(false)
|
const unimportMenuOpen = ref(false)
|
||||||
const downloadingAll = ref(false)
|
const downloadingAll = ref(false)
|
||||||
@@ -128,7 +130,7 @@ async function fetchOrganized() {
|
|||||||
async function fetchSettings() {
|
async function fetchSettings() {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/settings', { credentials: 'include' })
|
const res = await fetch('/api/settings', { credentials: 'include' })
|
||||||
if (res.ok) { const s = await res.json(); mediaPath.value = s.mediaPath || '/' }
|
if (res.ok) { const s = await res.json(); mediaPath.value = s.mediaPath || '/'; nfoSupport.value = !!s.nfoSupport }
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,6 +181,24 @@ function collectDownloadables() {
|
|||||||
|
|
||||||
const hasDownloadableTorrents = computed(() => collectDownloadables().length > 0)
|
const hasDownloadableTorrents = computed(() => collectDownloadables().length > 0)
|
||||||
|
|
||||||
|
// "Tout télécharger" ne s'affiche que s'il y a des torrents saison/épisode à lancer
|
||||||
|
// (les intégrales ont déjà leurs propres boutons dédiés dans le hero)
|
||||||
|
const hasNonIntegraleDownloadables = computed(() => {
|
||||||
|
if (!data.value) return false
|
||||||
|
const covered = new Set<number>()
|
||||||
|
data.value.torrents_integrale.forEach((t: any, i: number) => {
|
||||||
|
if (!isAlreadyQueued(t) && !isDownloaded(`integrale-${i}`))
|
||||||
|
for (const season of data.value!.seasons) for (const ep of season.episodes) covered.add(ep.id)
|
||||||
|
})
|
||||||
|
for (const season of data.value.seasons) {
|
||||||
|
if (season.torrent && !isAlreadyQueued(season.torrent) && !isDownloaded(`season-${season.id}`) && season.organized_state !== 'complete') return true
|
||||||
|
for (const ep of season.episodes) {
|
||||||
|
if (ep.torrent && ep.available && !ep.organized && !isAlreadyQueued(ep.torrent) && !isDownloaded(`ep-${ep.id}`) && !covered.has(ep.id)) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
async function downloadAll() {
|
async function downloadAll() {
|
||||||
downloadingAll.value = true
|
downloadingAll.value = true
|
||||||
const torrents = collectDownloadables()
|
const torrents = collectDownloadables()
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
3.9.0
|
3.9.2
|
||||||
Reference in new issue
Block a user