mirror of
https://github.com/ngthanhvu/kr-phim.git
synced 2026-08-10 15:27:46 +00:00
feat: simplify movie link queries by removing unnecessary source parameters
This commit is contained in:
@@ -32,23 +32,8 @@ const isDescriptionExpanded = ref(false);
|
||||
const previewStyle = ref<Record<string, string>>({});
|
||||
let hideTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
const movieSourcesQuery = computed(() =>
|
||||
(
|
||||
props.movie.sources || [
|
||||
{ source: props.movie.source, slug: props.movie.slug },
|
||||
]
|
||||
)
|
||||
.filter((source) => source.source && source.slug)
|
||||
.map((source) => `${source.source}:${source.slug}`)
|
||||
.join(","),
|
||||
);
|
||||
|
||||
const movieLink = computed(() => ({
|
||||
path: `/phim/${props.movie.slug}`,
|
||||
query: {
|
||||
source: props.movie.source,
|
||||
srcs: movieSourcesQuery.value || undefined,
|
||||
},
|
||||
}));
|
||||
|
||||
function showPreview(event: MouseEvent) {
|
||||
|
||||
+3
-25
@@ -188,9 +188,6 @@ function formatCommentContent(content: string, maxLength = 120) {
|
||||
function movieLinkFromSection(movie: any) {
|
||||
return {
|
||||
path: `/phim/${movie?.slug}`,
|
||||
query: {
|
||||
source: movie?.source,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,24 +207,11 @@ function genreTagColor(index: number) {
|
||||
return colors[index % colors.length]
|
||||
}
|
||||
|
||||
function movieSourcesQuery(movie: any) {
|
||||
return (movie?.sources || [{ source: movie?.source, slug: movie?.slug }])
|
||||
.filter((source: any) => source.source && source.slug)
|
||||
.map((source: any) => `${source.source}:${source.slug}`)
|
||||
.join(',')
|
||||
}
|
||||
|
||||
function movieLink(movie: any) {
|
||||
return {
|
||||
path: `/phim/${movie?.slug}`,
|
||||
query: {
|
||||
source: movie?.source,
|
||||
srcs: movieSourcesQuery(movie) || undefined,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function goToSlide(index: number) {
|
||||
heroSliderRef.value?.goTo(index)
|
||||
}
|
||||
@@ -236,7 +220,6 @@ function watchHistoryLink(item: WatchHistoryItem) {
|
||||
return {
|
||||
path: `/xem/${item.slug}`,
|
||||
query: {
|
||||
source: item.source,
|
||||
server: item.serverIndex || 0,
|
||||
ep: (item.episodeIndex || 0) + 1,
|
||||
},
|
||||
@@ -296,7 +279,7 @@ watch(hero, async (currentHero) => {
|
||||
return
|
||||
}
|
||||
|
||||
const cacheKey = `${currentHero.source}:${currentHero.slug}`
|
||||
const cacheKey = currentHero.slug
|
||||
if (heroDetailCache.has(cacheKey)) {
|
||||
heroDetail.value = heroDetailCache.get(cacheKey)
|
||||
return
|
||||
@@ -304,15 +287,10 @@ watch(hero, async (currentHero) => {
|
||||
|
||||
heroDetail.value = null
|
||||
try {
|
||||
const detail = await $fetch(`/api/movies/${currentHero.slug}`, {
|
||||
query: {
|
||||
source: currentHero.source,
|
||||
srcs: movieSourcesQuery(currentHero) || undefined,
|
||||
},
|
||||
})
|
||||
const detail = await $fetch(`/api/movies/${currentHero.slug}`)
|
||||
heroDetailCache.set(cacheKey, detail)
|
||||
|
||||
if (hero.value?.slug === currentHero.slug && hero.value?.source === currentHero.source) {
|
||||
if (hero.value?.slug === currentHero.slug) {
|
||||
heroDetail.value = detail
|
||||
}
|
||||
} catch {
|
||||
|
||||
@@ -190,7 +190,7 @@ useHead({
|
||||
<div v-if="selectedDay?.items?.length" class="schedule-list">
|
||||
<div class="schedule-card-grid">
|
||||
<NuxtLink v-for="movie in selectedDay.items" :key="`${movie.source}-${movie.slug}`"
|
||||
:to="{ path: `/phim/${movie.slug}`, query: { source: movie.source } }"
|
||||
:to="`/phim/${movie.slug}`"
|
||||
class="schedule-card">
|
||||
<img :src="movie.thumb || movie.poster" :alt="movie.name"
|
||||
class="schedule-card-image">
|
||||
|
||||
@@ -15,7 +15,6 @@ function watchHistoryLink(item: WatchHistoryItem) {
|
||||
return {
|
||||
path: `/xem/${item.slug}`,
|
||||
query: {
|
||||
source: item.source,
|
||||
server: item.serverIndex || 0,
|
||||
ep: (item.episodeIndex || 0) + 1,
|
||||
},
|
||||
|
||||
+10
-28
@@ -1,7 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
const requestedSource = computed(() => String(route.query.source || 'nguonc'))
|
||||
const requestedSources = computed(() => typeof route.query.srcs === 'string' ? route.query.srcs : '')
|
||||
const selectedServer = ref(0)
|
||||
const movieInfoOpen = ref(false)
|
||||
const contentExpanded = ref(false)
|
||||
@@ -16,19 +14,9 @@ const {
|
||||
saveWatchLater,
|
||||
} = useMovieLibrary()
|
||||
|
||||
const { data: movie, pending, error } = await useFetch(() => `/api/movies/${route.params.slug}`, {
|
||||
query: computed(() => ({
|
||||
source: requestedSource.value,
|
||||
srcs: requestedSources.value || undefined,
|
||||
})),
|
||||
watch: [requestedSource, requestedSources],
|
||||
})
|
||||
const { data: movie, pending, error } = await useFetch(() => `/api/movies/${route.params.slug}`)
|
||||
|
||||
const servers = computed(() => movie.value?.servers ?? [])
|
||||
const activeServer = computed(() => servers.value[selectedServer.value])
|
||||
const activeSource = computed(() => String(activeServer.value?.source || movie.value?.source || route.query.source || 'nguonc'))
|
||||
const activeSourceSlug = computed(() => String(activeServer.value?.sourceSlug || movie.value?.slug || route.params.slug))
|
||||
const activeSourceServerIndex = computed(() => Number(activeServer.value?.sourceServerIndex ?? 0))
|
||||
const actors = computed(() => movie.value?.actors ?? [])
|
||||
const actorSummary = computed(() => actors.value.map((actor: any) => actor.name).filter(Boolean).slice(0, 6).join(', '))
|
||||
const episodeCount = computed(() => {
|
||||
@@ -38,8 +26,8 @@ const episodeCount = computed(() => {
|
||||
const libraryItem = computed(() => {
|
||||
if (!movie.value) return null
|
||||
return {
|
||||
source: activeSource.value,
|
||||
slug: activeSourceSlug.value,
|
||||
source: movie.value.source,
|
||||
slug: movie.value.slug,
|
||||
name: movie.value.name,
|
||||
originName: movie.value.originName,
|
||||
thumb: movie.value.thumb,
|
||||
@@ -48,23 +36,20 @@ const libraryItem = computed(() => {
|
||||
}
|
||||
})
|
||||
const firstWatchLink = computed(() => ({
|
||||
path: `/xem/${activeSourceSlug.value}`,
|
||||
query: { source: activeSource.value, srcs: requestedSources.value || undefined, server: activeSourceServerIndex.value, ep: 1 },
|
||||
path: `/xem/${movie.value?.slug}`,
|
||||
query: { server: selectedServer.value, ep: 1 },
|
||||
}))
|
||||
|
||||
function actorInitial(name: string) {
|
||||
return name.trim().charAt(0).toUpperCase()
|
||||
}
|
||||
|
||||
const servers = computed(() => movie.value?.servers ?? [])
|
||||
|
||||
function episodeLink(index: number) {
|
||||
return {
|
||||
path: `/xem/${activeSourceSlug.value}`,
|
||||
query: {
|
||||
source: activeSource.value,
|
||||
srcs: requestedSources.value || undefined,
|
||||
server: activeSourceServerIndex.value,
|
||||
ep: index + 1,
|
||||
},
|
||||
path: `/xem/${movie.value?.slug}`,
|
||||
query: { server: selectedServer.value, ep: index + 1 },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,12 +124,9 @@ onMounted(async () => {
|
||||
// await loadComments()
|
||||
await $fetch(`/api/movies/${route.params.slug}/view`, {
|
||||
method: 'POST',
|
||||
query: { source: route.query.source },
|
||||
}).catch(() => { })
|
||||
})
|
||||
|
||||
watch(requestedSource, () => { selectedServer.value = 0 })
|
||||
watch(requestedSources, () => { selectedServer.value = 0 })
|
||||
watch(libraryItem, () => { refreshFavoriteState() })
|
||||
|
||||
useHead(() => ({
|
||||
@@ -491,7 +473,7 @@ useHead(() => ({
|
||||
<!-- Comment Section -->
|
||||
<div class="mt-10">
|
||||
<ClientOnly>
|
||||
<CommentSection :source="activeSource" :slug="String(route.params.slug)" :movie-name="movie?.name" />
|
||||
<CommentSection :source="movie?.source" :slug="String(route.params.slug)" :movie-name="movie?.name" />
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -53,20 +53,9 @@ const filteredMovies = computed(() => {
|
||||
const totalPages = computed(() => Number(data.value?.pagination?.totalPages || data.value?.pagination?.total_pages || 0))
|
||||
const sourceStatus = computed(() => data.value?.sources ?? [])
|
||||
|
||||
function movieSourcesQuery(movie: any) {
|
||||
return (movie.sources || [{ source: movie.source, slug: movie.slug }])
|
||||
.filter((source: any) => source.source && source.slug)
|
||||
.map((source: any) => `${source.source}:${source.slug}`)
|
||||
.join(',')
|
||||
}
|
||||
|
||||
function movieLink(movie: any) {
|
||||
return {
|
||||
path: `/phim/${movie.slug}`,
|
||||
query: {
|
||||
source: movie.source,
|
||||
srcs: movieSourcesQuery(movie),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-11
@@ -45,13 +45,12 @@ const { loadWatchHistory: fetchWatchHistory, saveWatchHistory: persistWatchHisto
|
||||
const { isFavorite, saveFavorite, removeFavorite, saveWatchLater } = useMovieLibrary()
|
||||
|
||||
const { data: movie, pending, error } = useFetch(() => `/api/movies/${route.params.slug}`, {
|
||||
query: computed(() => ({ source: route.query.source, srcs: route.query.srcs })),
|
||||
watch: [() => route.query.source, () => route.query.srcs],
|
||||
lazy: true, default: () => ({}),
|
||||
})
|
||||
|
||||
const currentMovieSource = computed(() => String(route.query.source || movie.value?.source || ''))
|
||||
const currentMovieSource = computed(() => String(movie.value?.source || ''))
|
||||
const libraryItem = computed(() => movie.value ? {
|
||||
source: currentMovieSource.value, slug: String(route.params.slug),
|
||||
source: movie.value.source, slug: String(route.params.slug),
|
||||
name: movie.value.name, originName: movie.value.originName, thumb: movie.value.thumb, poster: movie.value.poster, updatedAt: Date.now(),
|
||||
} : null)
|
||||
|
||||
@@ -98,7 +97,7 @@ function subtitleLabel(server: any, index: number) {
|
||||
}
|
||||
|
||||
function episodeLink(index: number) {
|
||||
return { path: `/xem/${route.params.slug}`, query: { source: route.query.source, srcs: route.query.srcs, server: selectedServer.value, ep: index + 1 } }
|
||||
return { path: `/xem/${route.params.slug}`, query: { server: selectedServer.value, ep: index + 1 } }
|
||||
}
|
||||
|
||||
function episodeIndexForServer(serverIndex: number, subIndex = selectedSubtitle.value, episodeIndex = selectedEpisode.value) {
|
||||
@@ -114,7 +113,7 @@ async function selectServer(index: number) {
|
||||
selectedSubtitle.value = 0
|
||||
selectedEpisode.value = episodeIndexForServer(index, 0)
|
||||
resetProgressTimer(); destroyHlsPlayer()
|
||||
await navigateTo({ path: `/xem/${route.params.slug}`, query: { ...route.query, server: index, ep: selectedEpisode.value + 1 } }, { replace: true })
|
||||
await navigateTo({ path: `/xem/${route.params.slug}`, query: { server: index, ep: selectedEpisode.value + 1 } }, { replace: true })
|
||||
if (shouldAutoplay) nextTick(() => startPlayer())
|
||||
}
|
||||
|
||||
@@ -123,7 +122,7 @@ async function selectSubtitle(index: number) {
|
||||
selectedSubtitle.value = index
|
||||
selectedEpisode.value = episodeIndexForServer(selectedServer.value, index)
|
||||
resetProgressTimer(); destroyHlsPlayer()
|
||||
await navigateTo({ path: `/xem/${route.params.slug}`, query: { ...route.query, server: selectedServer.value, ep: selectedEpisode.value + 1 } }, { replace: true })
|
||||
await navigateTo({ path: `/xem/${route.params.slug}`, query: { server: selectedServer.value, ep: selectedEpisode.value + 1 } }, { replace: true })
|
||||
if (hasStarted.value) nextTick(() => startPlayer())
|
||||
}
|
||||
|
||||
@@ -247,7 +246,7 @@ function handleVideoError() { hlsErrorMessage.value = 'HLS phát lỗi.'; isVide
|
||||
|
||||
async function loadResumeProgress() {
|
||||
if (!import.meta.client || !movie.value) return
|
||||
const source = String(route.query.source || movie.value.source || '')
|
||||
const source = String(movie.value.source || '')
|
||||
const items = await fetchWatchHistory(30)
|
||||
const item = items.find((i) => i.slug === String(route.params.slug) && i.source === source)
|
||||
const saved = Math.floor(item?.progressSeconds || 0)
|
||||
@@ -350,7 +349,7 @@ function handleTouchEnd(event: TouchEvent) {
|
||||
async function saveWatchHistory() {
|
||||
if (!import.meta.client || !movie.value) return
|
||||
await persistWatchHistory({
|
||||
source: String(route.query.source || movie.value.source || ''), slug: String(route.params.slug),
|
||||
source: String(movie.value.source || ''), slug: String(route.params.slug),
|
||||
name: movie.value.name, originName: movie.value.originName, thumb: movie.value.thumb, poster: movie.value.poster,
|
||||
episodeName: activeEpisode.value?.name, episodeIndex: selectedEpisode.value, serverIndex: selectedServer.value,
|
||||
progressSeconds: Math.floor(progressSeconds.value), durationSeconds: Math.floor(durationSeconds.value), updatedAt: Date.now(),
|
||||
@@ -680,7 +679,7 @@ useHead(() => ({
|
||||
</p>
|
||||
|
||||
<NuxtLink
|
||||
:to="{ path: `/phim/${route.params.slug}`, query: { source: route.query.source, srcs: route.query.srcs } }"
|
||||
:to="{ path: `/phim/${route.params.slug}` }"
|
||||
class="mt-1 inline-flex items-center gap-1 text-[13px] text-cinek-500 hover:underline">
|
||||
Thông tin phim
|
||||
<AppIcon name="chevron-right" class="size-4" />
|
||||
@@ -779,7 +778,7 @@ useHead(() => ({
|
||||
|
||||
<div class="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-1">
|
||||
<NuxtLink v-for="rel in relatedMovies" :key="rel.slug"
|
||||
:to="{ path: `/phim/${rel.slug}`, query: { source: rel.source } }"
|
||||
:to="`/phim/${rel.slug}`"
|
||||
class="group flex gap-3 rounded-lg bg-[#1A1A24] p-2 transition hover:bg-white/5">
|
||||
<img :src="rel.thumb || rel.poster" :alt="rel.name" class="h-16 w-12 shrink-0 rounded object-cover">
|
||||
|
||||
|
||||
@@ -14,9 +14,6 @@ async function refreshFavorites() {
|
||||
function movieLink(item: LibraryMovieItem) {
|
||||
return {
|
||||
path: `/phim/${item.slug}`,
|
||||
query: {
|
||||
source: item.source,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user