mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 11:36:36 +08:00
04fc50a4b0
* Add favourite buttons to library list and series detail pages Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix favourites list for remote Emby mounted media Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Route favourites to library series detail when appropriate Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix favourites link to library series for remote anime paths Co-authored-by: truewhile <truewhile@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: truewhile <truewhile@users.noreply.github.com>
48 lines
1.9 KiB
TypeScript
48 lines
1.9 KiB
TypeScript
import type { Media } from '../types'
|
|
import { isRemoteEmbyID } from './remoteEmby'
|
|
import { getSeriesKey, isEpisodeLike, pathLooksEpisodic } from './groupSeries'
|
|
|
|
function pathLooksLikeMovie(media: Media): boolean {
|
|
const path = (media.path || media.display_library_path || media.library_path || '').toLowerCase()
|
|
return /[\\/](?:movie|movies|film|films|电影)[\\/]/i.test(path)
|
|
}
|
|
|
|
function isRemoteEmbyLibrarySeries(media: Media): boolean {
|
|
if (!isRemoteEmbyID(media.id) || isEpisodeLike(media)) return false
|
|
const libraryID = media.display_library_id || media.library_id
|
|
if (!libraryID) return false
|
|
return !pathLooksLikeMovie(media)
|
|
}
|
|
|
|
/** Whether opening the library series detail view is a better target than /media/:id. */
|
|
export function prefersLibrarySeriesView(media: Media): boolean {
|
|
if (isEpisodeLike(media)) return true
|
|
if (pathLooksEpisodic(media)) return true
|
|
if (media.series_id) return true
|
|
if (isRemoteEmbyLibrarySeries(media)) return true
|
|
return false
|
|
}
|
|
|
|
/** Series key used by /library/:id?series=... for both local and remote libraries. */
|
|
export function resolveLibrarySeriesKey(media: Media): string {
|
|
if (isRemoteEmbyID(media.id) && !isEpisodeLike(media)) {
|
|
return media.id
|
|
}
|
|
return getSeriesKey(media)
|
|
}
|
|
|
|
/** Best library URL for a media item, or null when /media/:id is preferred. */
|
|
export function mediaLibraryTarget(media: Media): string | null {
|
|
const libraryID = media.display_library_id || media.library_id
|
|
if (!libraryID || !prefersLibrarySeriesView(media)) return null
|
|
|
|
const seriesKey = resolveLibrarySeriesKey(media)
|
|
const base = `/library/${encodeURIComponent(libraryID)}`
|
|
return seriesKey ? `${base}?series=${encodeURIComponent(seriesKey)}` : base
|
|
}
|
|
|
|
/** Link target for favourites / cards that should open the library series view when possible. */
|
|
export function favouriteMediaLink(media: Media): string {
|
|
return mediaLibraryTarget(media) ?? `/media/${media.id}`
|
|
}
|