fix: preview card trailers

feat: preview card trailer volume toggle
fix: dont resolve trusted media
fix: episode list air dates and numbers
This commit is contained in:
ThaUnknown 2023-07-25 19:03:11 +02:00
parent 665d4a3748
commit 36e2672a13
9 changed files with 59 additions and 23 deletions

View file

@ -1,6 +1,6 @@
{
"name": "Miru",
"version": "4.2.7",
"version": "4.2.8",
"author": "ThaUnknown_ <ThaUnknown@users.noreply.github.com>",
"description": "Stream anime torrents, real-time with no waiting for downloads.",
"main": "build/main.js",

View file

@ -97,7 +97,7 @@
position: absolute;
left: 0 ; bottom: 0;
width: 100%; height: 100%;
background: linear-gradient(180deg, #0000 0%, #0000 76%, #25292fdd 97%, #25292f);
background: linear-gradient(180deg, #0000 0%, #25292f00 80%, #25292f 95%, #25292f 100%);
}
.list-status-circle {
background: var(--statusColor);

View file

@ -45,9 +45,13 @@
if (media.status === 'NOT_YET_RELEASED') return
playMedia(media)
}
// TODO: add a volume toggle icon for trailer
function volume (video) {
video.volume = 0.05
video.volume = 0.1
}
let muted = true
function toggleMute () {
muted = !muted
}
</script>
@ -55,16 +59,17 @@
<div class='banner position-relative overflow-hidden bg-black'>
<img src={media.bannerImage || ' '} alt='banner' class='img-cover w-full h-full' />
{#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 -->
<!-- `https://yewtu.be/latest_version?id=${media.trailer.id}&itag=18` -->
<!-- eslint-disable-next-line svelte/valid-compile -->
<video src={`https://proxy2.vnxservers.com/youtube/${media.trailer.id}`}
<video 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'
loop
muted
use:volume
bind:muted
on:loadeddata={() => { hide = false }}
autoplay />
<!-- <iframe
@ -150,7 +155,7 @@
position: absolute;
left: 0 ; bottom: 0;
width: 100%; height: 100% ;
background: linear-gradient(180deg, #0000 0%, #25292faa 76%, #25292f 97%, #25292f 100%);
background: linear-gradient(180deg, #0000 0%, #25292f00 80%, #25292fe3 95%, #25292f 100%);
}
@keyframes load-in {
from {

View file

@ -413,6 +413,17 @@ query($page: Int, $perPage: Int, $from: Int, $to: Int){
}
}
}
}`
break
} case 'Episodes': {
query = /* js */`
query($id: Int){
Page(page: 1, perPage: 1000){
airingSchedules(mediaId: $id){
airingAt,
episode
}
}
}`
break
} case 'Search': {

View file

@ -29,8 +29,8 @@ window.addEventListener('paste', ({ clipboardData }) => { // WAIT image lookup o
if (!type.startsWith('text')) return
item.getAsString(text => {
if (torrentRx.exec(text)) {
add(text)
media.set(null)
add(text)
} else {
let src = null
if (type === 'text/html') {

View file

@ -89,6 +89,10 @@ async function getAniDBEpisodeFromAL ({ media, episode }, { episodes, episodeCou
const res = await alRequest({ method: 'EpisodeDate', id: media.id, ep: episode })
const alDate = new Date((res.data.AiringSchedule?.airingAt || 0) * 1000)
return getEpisodeNumberByAirDate(alDate, episodes, episode)
}
export function getEpisodeNumberByAirDate (alDate, episodes, episode) {
if (!+alDate) return episodes[Number(episode)] || episodes[1] // what the fuck, are you braindead anilist?, the source episode number to play is from an array created from AL ep count, so how come it's missing?
// find closest episodes by air date, multiple episodes can have the same air date distance

View file

@ -82,6 +82,8 @@
otherFiles.push(file)
}
}
let nowPlaying = get(media)
const resolved = await resolveFileMedia(videoFiles.map(file => file.name))
videoFiles.map(file => {
@ -91,9 +93,13 @@
videoFiles = videoFiles.filter(file => !TYPE_EXCLUSIONS.includes(file.media.parseObject.anime_type))
console.info('MediaHandler: resolved video files', { videoFiles })
if (nowPlaying?.verified && videoFiles.length === 1) {
console.info('Media was verified, skipping verification')
videoFiles[0].media.media = nowPlaying.media
if (nowPlaying.episode) videoFiles[0].media.episode = nowPlaying.episode
}
let nowPlaying = get(media)
console.info('MediaHandler: resolved video files', { videoFiles })
if (!nowPlaying) {
const max = highestOccurence(videoFiles, file => file.media.media?.id).media

View file

@ -93,7 +93,7 @@
entries.sort((a, b) => b.seeders - a.seeders)
if (settings.rssAutoplay) {
const best = entries.find(entry => entry.best)
if (best?.seeders > 20) { // only play best if it actually has a lot of seeders, 20 might be too little for those overkill blurays
if (best?.seeders >= 15) { // only play best if it actually has a lot of seeders, 20 might be too little for those overkill blurays
play(best)
} else {
play(entries[0])
@ -110,7 +110,8 @@
}
function play (entry) {
$media = $rss
if (entry.seeders !== '?' && entry.seeders <= 15) {
$media.verified = entry.verified
if (entry.seeders !== '?' && entry.seeders < 15) {
toast('Availability Warning', {
description: 'This release is poorly seeded and likely will have playback issues such as buffering!'
})

View file

@ -1,6 +1,9 @@
<script>
import { since } from '@/modules/util'
import { click } from '@/modules/click.js'
import { getEpisodeNumberByAirDate } from '@/modules/providers/tosho.js'
import { alRequest } from '@/modules/anilist'
import { media } from '../Player/MediaHandler.svelte'
export let id
@ -14,15 +17,18 @@
const episodeList = Array.from({ length: episodeCount }, (_, i) => ({ episode: i + 1 }))
async function load () {
const episodesPromise = alRequest({ method: 'Episodes', id })
const res = await fetch('https://api.ani.zip/mappings?anilist_id=' + id)
const { episodes } = await res.json()
for (const { episode, image, summary, rating, title, length, airdate } of Object.values(episodes)) {
const episodeNumber = Number(episode)
if (!episodeNumber) continue
const { episodes, specialCount, episodeCount } = await res.json()
const settled = (await episodesPromise).data.Page?.airingSchedules
const alEpisodes = settled?.length ? settled : episodeList
for (const { episode, airingAt } of alEpisodes) {
const airdate = new Date((airingAt || 0) * 1000)
// TODO: AL airing times
const needsValidation = !(!specialCount || (media.episodes && media.episodes === episodeCount && episodes[Number(episode)]))
const { image, summary, rating, title, length } = needsValidation ? getEpisodeNumberByAirDate(airdate, episodes, episode) : (episodes[Number(episode)] || {})
episodeList[episodeNumber - 1] = { episode: episodeNumber, image, summary, rating, title, length: length || duration, airdate }
episodeList[episode - 1] = { episode, image, summary, rating, title, length: length || duration, airdate }
}
}
load()
@ -31,11 +37,11 @@
{#each episodeList as { episode, image, summary, rating, title, length, airdate }}
{@const completed = userProgress >= episode}
{@const target = userProgress + 1 === episode}
<div class='w-full my-20 content-visibility-auto scale' class:px-20={!target} class:h-150={image || summary} use:click={() => play(episode)}>
<div class='rounded w-full h-full overflow-hidden d-flex flex-row pointer' class:bg-dark-light={completed} class:bg-dark={!completed}>
<div class='w-full my-20 content-visibility-auto scale' class:opacity-half={completed} class:px-20={!target} class:h-150={image || summary} use:click={() => play(episode)}>
<div class='rounded w-full h-full overflow-hidden d-flex flex-row pointer' class:border={target} class:bg-black={completed} class:bg-dark={!completed}>
{#if image}
<div class='w-450 h-full'>
<img alt='thumbnail' src={image} class='img-cover h-full w-full' class:opacity-half={completed} />
<img alt='thumbnail' src={image} class='img-cover h-full w-full' />
</div>
{/if}
<div class='h-full w-full px-20 py-15 d-flex flex-column'>
@ -69,7 +75,7 @@
<style>
.opacity-half {
opacity: 50%;
opacity: 30%;
}
.title {
display: -webkit-box !important;
@ -82,4 +88,7 @@
.scale:hover{
transform: scale(1.05);
}
.border {
--dm-border-color: white
}
</style>