mirror of
https://github.com/NoCrypt/migu.git
synced 2026-03-11 17:45:32 +00:00
165 lines
5.2 KiB
Svelte
165 lines
5.2 KiB
Svelte
<script>
|
|
import { formatMap } from './anime.js'
|
|
import { click } from '@/modules/click.js'
|
|
export let media
|
|
|
|
let hide = true
|
|
|
|
function getPlayButtonText (media) {
|
|
if (media.mediaListEntry) {
|
|
const { status, progress } = media.mediaListEntry
|
|
if (progress) {
|
|
if (status === 'COMPLETED') {
|
|
return 'Rewatch Now'
|
|
} else {
|
|
return 'Continue Now'
|
|
}
|
|
}
|
|
}
|
|
return 'Watch Now'
|
|
}
|
|
const playButtonText = getPlayButtonText(media)
|
|
|
|
function volume (video) {
|
|
video.volume = 0.1
|
|
}
|
|
let muted = true
|
|
function toggleMute () {
|
|
muted = !muted
|
|
}
|
|
const noop = () => {}
|
|
function play () {
|
|
open('miru://anime/' + media.id)
|
|
}
|
|
function lazyload (video) {
|
|
if ('IntersectionObserver' in window) {
|
|
const lazyVideoObserver = new IntersectionObserver(entries => {
|
|
for (const { target, isIntersecting } of entries) {
|
|
if (isIntersecting) {
|
|
video.src = video.dataset.src
|
|
lazyVideoObserver.unobserve(target)
|
|
}
|
|
}
|
|
})
|
|
lazyVideoObserver.observe(video.parentNode)
|
|
} else {
|
|
video.src = video.dataset.src
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class='position-absolute w-350 h-400 absolute-container top-0 bottom-0 m-auto bg-dark-light z-30 rounded overflow-hidden pointer'>
|
|
<div class='banner position-relative overflow-hidden bg-black'>
|
|
<img src={media.bannerImage || ' '} alt='banner' class='img-cover w-full h-full' loading='lazy' />
|
|
{#if media.trailer?.id}
|
|
<div class='material-symbols-outlined filled position-absolute z-10 top-0 right-0 p-15 font-size-22' class:d-none={hide} use:click={toggleMute}>{muted ? 'volume_off' : 'volume_up'}</div>
|
|
<!-- for now we use some invidious instance, would be nice to somehow get these links outselves, this redirects straight to some google endpoint -->
|
|
<!-- eslint-disable-next-line svelte/valid-compile -->
|
|
<video data-src={`https://yewtu.be/latest_version?id=${media.trailer.id}&itag=18`}
|
|
class='w-full position-absolute left-0'
|
|
class:d-none={hide}
|
|
playsinline
|
|
preload='none'
|
|
loading='lazy'
|
|
use:lazyload
|
|
loop
|
|
use:volume
|
|
bind:muted
|
|
on:loadeddata={() => { hide = false }}
|
|
autoplay />
|
|
{/if}
|
|
</div>
|
|
<div class='w-full px-20'>
|
|
<div class='font-size-24 font-weight-bold text-truncate d-inline-block w-full text-white' title={media.title.userPreferred}>
|
|
{media.title.userPreferred}
|
|
</div>
|
|
<div class='d-flex flex-row pt-5'>
|
|
<button class='btn btn-secondary flex-grow-1 text-dark font-weight-bold shadow-none border-0 d-flex align-items-center justify-content-center'
|
|
use:click={play}
|
|
disabled={media.status === 'NOT_YET_RELEASED'}>
|
|
<span class='material-symbols-outlined font-size-20 filled pr-10'>
|
|
play_arrow
|
|
</span>
|
|
{playButtonText}
|
|
</button>
|
|
<button class='btn btn-square ml-10 material-symbols-outlined font-size-16 shadow-none border-0' class:filled={media.isFavourite} use:click={noop}>
|
|
favorite
|
|
</button>
|
|
<button class='btn btn-square ml-10 material-symbols-outlined font-size-16 shadow-none border-0' class:filled={media.mediaListEntry} use:click={noop}>
|
|
bookmark
|
|
</button>
|
|
</div>
|
|
<div class='details text-white text-capitalize pt-15 pb-10 d-flex'>
|
|
<span class='text-nowrap d-flex align-items-center'>
|
|
{#if media.format}
|
|
{formatMap[media.format]}
|
|
{/if}
|
|
</span>
|
|
{#if media.episodes && media.episodes !== 1}
|
|
<span class='text-nowrap d-flex align-items-center'>
|
|
{#if media.mediaListEntry?.status === 'CURRENT' && media.mediaListEntry?.progress }
|
|
{media.mediaListEntry.progress} / {media.episodes} Episodes
|
|
{:else}
|
|
{media.episodes} Episodes
|
|
{/if}
|
|
</span>
|
|
{:else if media.duration}
|
|
<span class='text-nowrap d-flex align-items-center'>
|
|
{media.duration + ' Minutes'}
|
|
</span>
|
|
{/if}
|
|
{#if media.season || media.seasonYear}
|
|
<span class='text-nowrap d-flex align-items-center'>
|
|
{[media.season?.toLowerCase(), media.seasonYear].filter(s => s).join(' ')}
|
|
</span>
|
|
{/if}
|
|
</div>
|
|
<div class='w-full h-full text-muted description overflow-hidden'>
|
|
{media.description?.replace(/<[^>]*>/g, '')}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.description {
|
|
display: -webkit-box !important;
|
|
-webkit-line-clamp: 4;
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
.details span + span::before {
|
|
content: '•';
|
|
padding: 0 .5rem;
|
|
font-size: .6rem;
|
|
align-self: center;
|
|
white-space: normal;
|
|
color: var(--dm-muted-text-color) !important;
|
|
}
|
|
.banner {
|
|
height: 45%
|
|
}
|
|
.banner::after {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0 ; bottom: 0;
|
|
width: 100%; height: 100% ;
|
|
background: linear-gradient(180deg, #0000 0%, #25292f00 80%, #25292fe3 95%, #25292f 100%);
|
|
}
|
|
@keyframes load-in {
|
|
from {
|
|
bottom: -1.2rem;
|
|
opacity: 0;
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
to {
|
|
bottom: 0;
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
.absolute-container {
|
|
animation: 0.3s ease 0s 1 load-in;
|
|
left: -100%;
|
|
right: -100%;
|
|
}
|
|
</style>
|