mirror of
https://github.com/mmahdium/TBW.git
synced 2026-08-14 16:22:48 +03:30
Added Watch page
This commit is contained in:
@@ -102,7 +102,7 @@ const alreadyAdded = computed(() =>
|
||||
transition"
|
||||
@click="store.removeMovie(props.movie.imdbID)"
|
||||
>
|
||||
Delete
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -17,83 +17,98 @@ const alreadyAdded = computed(() =>
|
||||
<template>
|
||||
<ErrorAlert v-if="props.movie?.Error" :message="props.movie.ErrorMessage" />
|
||||
|
||||
<!-- Loading state -->
|
||||
<div v-if="props.movie === undefined" class="flex justify-center items-center">
|
||||
<span class="loading loading-ring loading-lg text-primary"></span>
|
||||
</div>
|
||||
|
||||
<!-- Loading state -->
|
||||
<div v-if="props.movie === undefined" class="flex justify-center items-center">
|
||||
<span class="loading loading-ring loading-lg text-primary"></span>
|
||||
</div>
|
||||
<!-- Hero content -->
|
||||
<div
|
||||
v-else
|
||||
class="flex flex-col lg:flex-row gap-12 items-center max-w-6xl w-full bg-white/70 backdrop-blur-md border border-gray-200/60 shadow-md rounded-xl p-8 transition"
|
||||
v-motion-fade-visible-once
|
||||
>
|
||||
<!-- Poster -->
|
||||
<figure class="flex-shrink-0">
|
||||
<span v-if="!imageLoaded" class="loading loading-ring loading-lg text-primary"></span>
|
||||
<img
|
||||
v-show="imageLoaded"
|
||||
:src="props.movie.Poster"
|
||||
alt="Poster"
|
||||
class="w-full max-w-sm rounded-lg shadow-lg transform transition-transform duration-500 hover:scale-105"
|
||||
@load="imageLoaded = true"
|
||||
/>
|
||||
</figure>
|
||||
|
||||
<!-- Hero content -->
|
||||
<div
|
||||
v-else
|
||||
class="flex flex-col lg:flex-row gap-12 items-center max-w-6xl w-full
|
||||
bg-white/70 backdrop-blur-md border border-gray-200/60
|
||||
shadow-md rounded-xl p-8 transition"
|
||||
v-motion-fade-visible-once
|
||||
>
|
||||
<!-- Poster -->
|
||||
<figure class="flex-shrink-0">
|
||||
<span v-if="!imageLoaded" class="loading loading-ring loading-lg text-primary"></span>
|
||||
<img
|
||||
v-show="imageLoaded"
|
||||
:src="props.movie.Poster"
|
||||
alt="Poster"
|
||||
class="w-full max-w-sm rounded-lg shadow-lg transform transition-transform duration-500 hover:scale-105"
|
||||
@load="imageLoaded = true"
|
||||
/>
|
||||
</figure>
|
||||
<!-- Text -->
|
||||
<div class="flex-1">
|
||||
<h1 class="text-4xl font-bold text-gray-800 mb-4">
|
||||
{{ props.movie.Title }}
|
||||
<span class="text-gray-400 text-lg font-normal">({{ props.movie.Year }})</span>
|
||||
</h1>
|
||||
|
||||
<!-- Text -->
|
||||
<div class="flex-1">
|
||||
<h1 class="text-4xl font-bold text-gray-800 mb-4">
|
||||
{{ props.movie.Title }}
|
||||
<span class="text-gray-400 text-lg font-normal">({{ props.movie.Year }})</span>
|
||||
</h1>
|
||||
<p class="text-gray-600 leading-relaxed mb-6">{{ props.movie.Plot }}</p>
|
||||
|
||||
<p class="text-gray-600 leading-relaxed mb-6">{{ props.movie.Plot }}</p>
|
||||
<!-- Badges -->
|
||||
<div class="flex flex-wrap gap-2 mb-6">
|
||||
<span
|
||||
class="px-3 py-1 rounded-md text-sm bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700 border border-gray-300"
|
||||
>
|
||||
Language: {{ props.movie.Language }}
|
||||
</span>
|
||||
<span
|
||||
class="px-3 py-1 rounded-md text-sm bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700 border border-gray-300"
|
||||
>
|
||||
Country: {{ props.movie.Country }}
|
||||
</span>
|
||||
<span
|
||||
class="px-3 py-1 rounded-md text-sm bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700 border border-gray-300"
|
||||
>
|
||||
IMDB Rating: {{ props.movie.imdbRating }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Badges -->
|
||||
<div class="flex flex-wrap gap-2 mb-6">
|
||||
<span
|
||||
class="px-3 py-1 rounded-md text-sm
|
||||
bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700 border border-gray-300"
|
||||
>
|
||||
Language: {{ props.movie.Language }}
|
||||
</span>
|
||||
<span
|
||||
class="px-3 py-1 rounded-md text-sm
|
||||
bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700 border border-gray-300"
|
||||
>
|
||||
Country: {{ props.movie.Country }}
|
||||
</span>
|
||||
<span
|
||||
class="px-3 py-1 rounded-md text-sm
|
||||
bg-gradient-to-r from-gray-100 to-gray-200 text-gray-700 border border-gray-300"
|
||||
>
|
||||
IMDB Rating: {{ props.movie.imdbRating }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- Actions -->
|
||||
<div class="card-actions">
|
||||
<button
|
||||
v-if="!alreadyAdded"
|
||||
class="btn px-6 bg-gradient-to-r from-gray-100 to-gray-200 border border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300"
|
||||
@click="store.addMovie(props.movie)"
|
||||
>
|
||||
Add to list
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="btn px-6 bg-gradient-to-r from-red-50 to-red-100 border border-red-200 text-red-600 hover:from-red-100 hover:to-red-200"
|
||||
@click="store.removeMovie(props.movie.imdbID)"
|
||||
>
|
||||
Remove from list
|
||||
</button>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="card-actions">
|
||||
<RouterLink
|
||||
:to="{ name: 'watch', params: { name: props.movie.Title, id: props.movie.imdbID } }"
|
||||
>
|
||||
<button
|
||||
v-if="!alreadyAdded"
|
||||
class="btn px-6 bg-gradient-to-r from-gray-100 to-gray-200
|
||||
border border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300"
|
||||
@click="store.addMovie(props.movie)"
|
||||
class="btn relative flex items-center gap-2 px-6 bg-gradient-to-r from-indigo-500 to-violet-500 text-white border-0 shadow-md hover:opacity-90 transition"
|
||||
>
|
||||
Add to list
|
||||
<!-- Icon -->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M6.5 5.5a1 1 0 0 1 1.52-.85l6 4.5a1 1 0 0 1 0 1.7l-6 4.5A1 1 0 0 1 6.5 14.5v-9z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<span>Watch</span>
|
||||
<span class="badge badge-sm badge-secondary absolute -top-2 -right-2">Beta</span>
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="btn px-6 bg-gradient-to-r from-red-50 to-red-100
|
||||
border border-red-200 text-red-600 hover:from-red-100 hover:to-red-200"
|
||||
@click="store.removeMovie(props.movie.imdbID)"
|
||||
>
|
||||
Remove from list
|
||||
</button>
|
||||
</div>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -4,6 +4,7 @@ import NotFoundView from '@/views/NotFoundView.vue'
|
||||
import ListView from '@/views/ListView.vue'
|
||||
import DetailsView from '@/views/DetailsView.vue'
|
||||
import AddView from '@/views/AddView.vue'
|
||||
import WatchView from '@/views/WatchView.vue'
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFoundView },
|
||||
@@ -27,6 +28,11 @@ const routes: RouteRecordRaw[] = [
|
||||
name: 'add',
|
||||
component: AddView,
|
||||
},
|
||||
{
|
||||
path: '/watch/:name/:id',
|
||||
name: 'watch',
|
||||
component: WatchView,
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const movieId = ref(route.params.id as string)
|
||||
const movieName = ref(route.params.name as string)
|
||||
const isLoaded = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
// You could add extra logic here if needed
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex justify-center min-h-auto px-4 py-12 bg-gradient-to-b from-gray-50 to-white"
|
||||
>
|
||||
<div
|
||||
class="w-full max-w-6xl bg-white/70 backdrop-blur-md border border-gray-200/60
|
||||
shadow-md rounded-xl p-4 lg:p-8 transition flex flex-col items-center"
|
||||
v-motion-fade-visible-once
|
||||
>
|
||||
<!-- Title with Experimental badge -->
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<h1 class="text-3xl font-bold text-gray-700">
|
||||
Watch
|
||||
<span class="bg-gradient-to-r from-indigo-500 to-cyan-400 bg-clip-text text-transparent">
|
||||
{{ movieName }}
|
||||
</span>
|
||||
</h1>
|
||||
<span class="badge badge-warning">Experimental</span>
|
||||
</div>
|
||||
|
||||
<!-- Loading spinner -->
|
||||
<div v-if="!isLoaded" class="flex justify-center items-center h-64 w-full">
|
||||
<span class="loading loading-ring loading-lg text-primary"></span>
|
||||
</div>
|
||||
|
||||
<!-- Responsive iframe -->
|
||||
<div v-show="isLoaded" class="w-full aspect-video rounded-lg overflow-hidden shadow-lg">
|
||||
<iframe
|
||||
:src="'https://vidlink.pro/movie/' + movieId"
|
||||
frameborder="0"
|
||||
allowfullscreen
|
||||
class="w-full h-full"
|
||||
@load="isLoaded = true"
|
||||
></iframe>
|
||||
</div>
|
||||
|
||||
<!-- Disclaimer -->
|
||||
<p class="mt-6 text-sm text-gray-500 text-center max-w-2xl">
|
||||
⚠️ This player is provided by a <span class="font-semibold">third‑party service</span>.
|
||||
Ads and pop‑ups may appear, and I do not control or endorse them.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user