mirror of
https://github.com/NoCrypt/migu.git
synced 2026-08-18 13:17:59 +00:00
feat: allow changing search parameters for preset values, improve performance on infinite scrolling [a lot]
This commit is contained in:
parent
7355b915ef
commit
a36ee4dbc9
5 changed files with 55 additions and 39 deletions
|
|
@ -6,10 +6,11 @@
|
|||
function viewMedia(media) {
|
||||
$view = media
|
||||
}
|
||||
export let length = 5
|
||||
</script>
|
||||
|
||||
{#await cards}
|
||||
{#each Array(5) as _}
|
||||
{#each Array(length) as _}
|
||||
<div class="card m-0 p-0">
|
||||
<div class="row h-full">
|
||||
<div class="col-4 skeloader" />
|
||||
|
|
|
|||
|
|
@ -6,13 +6,16 @@
|
|||
let loading = true
|
||||
async function update(med) {
|
||||
loading = true
|
||||
await med
|
||||
if (med === media) loading = false
|
||||
const index = med.length - 1
|
||||
await med[index]
|
||||
if (index === med.length - 1) loading = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="gallery browse" class:loading>
|
||||
<Cards cards={media} />
|
||||
{#each media as cards, i (i)}
|
||||
<Cards {cards} length={4} />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
@ -26,17 +29,12 @@
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.loading {
|
||||
height: 30rem !important;
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
|
||||
.loading:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 10rem;
|
||||
height: 40rem;
|
||||
width: 100%;
|
||||
background: linear-gradient(0deg, rgba(37, 40, 44, 1) 0%, rgba(37, 40, 44, 1) 15%, rgba(37, 40, 44, 0.45) 70%, rgba(37, 40, 44, 0) 100%);
|
||||
background: linear-gradient(0deg, rgba(37, 40, 44, 1) 0%, rgba(37, 40, 44, 1) 70%, rgba(37, 40, 44, 1) 75%, rgba(37, 40, 44, 0.45) 90%, rgba(37, 40, 44, 0) 100%);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -8,31 +8,46 @@
|
|||
import { resolveFileMedia } from '@/modules/anime.js'
|
||||
import { getRSSContent, getReleasesRSSurl } from '@/lib/RSSView.svelte'
|
||||
|
||||
let media = null
|
||||
let media = []
|
||||
let search = {}
|
||||
export let current = null
|
||||
let page = 1
|
||||
|
||||
let canScroll = true
|
||||
let hasNext = true
|
||||
let container = null
|
||||
|
||||
function sanitiseObject(object) {
|
||||
const safe = {}
|
||||
for (const [key, value] of Object.entries(object)) {
|
||||
if (value) safe[key] = value
|
||||
}
|
||||
return safe
|
||||
}
|
||||
async function infiniteScroll() {
|
||||
if (current && canScroll && hasNext && this.scrollTop + this.clientHeight > this.scrollHeight - 800) {
|
||||
canScroll = false
|
||||
const res = await sections[current].load(++page)
|
||||
media = media.then(old => {
|
||||
return old.concat(res)
|
||||
})
|
||||
const res = sections[current].load(++page)
|
||||
media.push(res)
|
||||
media = media
|
||||
await res
|
||||
canScroll = hasNext
|
||||
}
|
||||
}
|
||||
|
||||
$: load(current)
|
||||
function load(current) {
|
||||
async function load(current) {
|
||||
console.log(current)
|
||||
if (sections[current]) {
|
||||
page = 1
|
||||
media = sections[current].load(1)
|
||||
canScroll = false
|
||||
const res = sections[current].load(1)
|
||||
media = [res]
|
||||
await res
|
||||
canScroll = hasNext
|
||||
} else {
|
||||
media = null
|
||||
if (container) container.scrollTop = 0
|
||||
media = []
|
||||
canScroll = true
|
||||
lastDate = null
|
||||
search = {
|
||||
|
|
@ -80,6 +95,7 @@
|
|||
continue: {
|
||||
title: 'Continue Watching',
|
||||
load: (page = 1, perPage = 50) => {
|
||||
if (perPage !== 5) search.sort = 'UPDATED_TIME_DESC'
|
||||
return alRequest({ method: 'UserLists', status_in: 'CURRENT', page }).then(res => {
|
||||
hasNext = res?.data?.Page.pageInfo.hasNextPage
|
||||
return res?.data?.Page.mediaList
|
||||
|
|
@ -95,12 +111,14 @@
|
|||
title: 'New Releases',
|
||||
releases: true,
|
||||
load: (page = 1, perPage = 20, force = true) => {
|
||||
if (perPage !== 5) search.sort = 'START_DATE_DESC'
|
||||
return releasesCards(page, perPage, force)
|
||||
}
|
||||
},
|
||||
planning: {
|
||||
title: 'Your List',
|
||||
load: (page = 1, perPage = 50) => {
|
||||
if (perPage !== 5) search.sort = 'UPDATED_TIME_DESC'
|
||||
return alRequest({ method: 'UserLists', page, perPage, status_in: 'PLANNING' }).then(res => {
|
||||
hasNext = res?.data?.Page.pageInfo.hasNextPage
|
||||
return res?.data?.Page.mediaList
|
||||
|
|
@ -111,10 +129,8 @@
|
|||
trending: {
|
||||
title: 'Trending Now',
|
||||
load: (page = 1, perPage = 50) => {
|
||||
if (perPage !== 5) {
|
||||
search.sort = 'TRENDING_DESC'
|
||||
}
|
||||
return alRequest({ method: 'Search', page, perPage, sort: 'TRENDING_DESC' }).then(res => processMedia(res))
|
||||
if (perPage !== 5) search.sort = 'TRENDING_DESC'
|
||||
return alRequest({ method: 'Search', page, perPage, ...sanitiseObject(search) }).then(res => processMedia(res))
|
||||
}
|
||||
},
|
||||
romance: {
|
||||
|
|
@ -124,7 +140,7 @@
|
|||
search.sort = 'TRENDING_DESC'
|
||||
search.genre = 'romance'
|
||||
}
|
||||
return alRequest({ method: 'Search', page, perPage, genre: 'Romance', sort: 'TRENDING_DESC' }).then(res => processMedia(res))
|
||||
return alRequest({ method: 'Search', page, perPage, ...sanitiseObject(search) }).then(res => processMedia(res))
|
||||
}
|
||||
},
|
||||
action: {
|
||||
|
|
@ -134,7 +150,7 @@
|
|||
search.sort = 'TRENDING_DESC'
|
||||
search.genre = 'action'
|
||||
}
|
||||
return alRequest({ method: 'Search', page, perPage, genre: 'Action', sort: 'TRENDING_DESC' }).then(res => processMedia(res))
|
||||
return alRequest({ method: 'Search', page, perPage, ...sanitiseObject(search) }).then(res => processMedia(res))
|
||||
}
|
||||
},
|
||||
adventure: {
|
||||
|
|
@ -144,7 +160,7 @@
|
|||
search.sort = 'TRENDING_DESC'
|
||||
search.genre = 'adventure'
|
||||
}
|
||||
return alRequest({ method: 'Search', page, perPage, genre: 'Adventure', sort: 'TRENDING_DESC' }).then(res => processMedia(res))
|
||||
return alRequest({ method: 'Search', page, perPage, ...sanitiseObject(search) }).then(res => processMedia(res))
|
||||
}
|
||||
},
|
||||
fantasy: {
|
||||
|
|
@ -154,7 +170,7 @@
|
|||
search.sort = 'TRENDING_DESC'
|
||||
search.genre = 'fantasy'
|
||||
}
|
||||
return alRequest({ method: 'Search', page, perPage, genre: 'Fantasy', sort: 'TRENDING_DESC' }).then(res => processMedia(res))
|
||||
return alRequest({ method: 'Search', page, perPage, ...sanitiseObject(search) }).then(res => processMedia(res))
|
||||
}
|
||||
},
|
||||
comedy: {
|
||||
|
|
@ -164,7 +180,7 @@
|
|||
search.sort = 'TRENDING_DESC'
|
||||
search.genre = 'comedy'
|
||||
}
|
||||
return alRequest({ method: 'Search', page, perPage, genre: 'Comedy', sort: 'TRENDING_DESC' }).then(res => processMedia(res))
|
||||
return alRequest({ method: 'Search', page, perPage, ...sanitiseObject(search) }).then(res => processMedia(res))
|
||||
}
|
||||
},
|
||||
schedule: {
|
||||
|
|
@ -200,10 +216,8 @@
|
|||
const opts = {
|
||||
method: 'Search',
|
||||
page,
|
||||
perPage
|
||||
}
|
||||
for (const [key, value] of Object.entries(search)) {
|
||||
if (value) opts[key] = value
|
||||
perPage,
|
||||
...sanitiseObject(search)
|
||||
}
|
||||
return alRequest(opts).then(res => processMedia(res))
|
||||
}
|
||||
|
|
@ -211,10 +225,10 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<div class="d-flex h-full flex-column overflow-y-scroll root" on:scroll={infiniteScroll}>
|
||||
<div class="d-flex h-full flex-column overflow-y-scroll root" on:scroll={infiniteScroll} bind:this={container}>
|
||||
<div class="h-full py-10">
|
||||
<Search bind:media bind:search bind:current />
|
||||
{#if media}
|
||||
{#if media.length}
|
||||
<Gallery {media} />
|
||||
{:else}
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -16,13 +16,14 @@
|
|||
}
|
||||
function input() {
|
||||
if (!searchTimeout) {
|
||||
if (Object.values(search).filter(v => v).length) media = new Promise(() => {})
|
||||
if (Object.values(search).filter(v => v).length) media = [new Promise(() => {})]
|
||||
} else {
|
||||
clearTimeout(searchTimeout)
|
||||
}
|
||||
searchTimeout = setTimeout(() => {
|
||||
const old = current
|
||||
current = null
|
||||
if (Object.values(search).filter(v => v).length) current = 'search'
|
||||
if (Object.values(search).filter(v => v).length) current = old || 'search'
|
||||
searchTimeout = null
|
||||
}, 500)
|
||||
}
|
||||
|
|
@ -135,11 +136,13 @@
|
|||
<option value="SCORE_DESC">Score</option>
|
||||
<option value="POPULARITY_DESC">Popularity</option>
|
||||
<option value="TRENDING_DESC">Trending</option>
|
||||
<option value="UPDATED_TIME_DESC" disabled hidden>Updated Date</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto p-10 d-flex">
|
||||
<button class="btn bg-dark material-icons font-size-18 px-5 align-self-end shadow-lg border-0" type="button" on:click={searchClear} class:text-primary={!!current}
|
||||
>delete</button>
|
||||
<button class="btn bg-dark material-icons font-size-18 px-5 align-self-end shadow-lg border-0" type="button" on:click={searchClear} class:text-primary={!!current}>
|
||||
delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ query ($page: Int, $perPage: Int, $sort: [MediaSort], $type: MediaType, $search:
|
|||
pageInfo {
|
||||
hasNextPage
|
||||
},
|
||||
media(type: $type, search: $search, sort: $sort, status: $status, season: $season, seasonYear: $year, genre: $genre, format: $format, isAdult: false) {
|
||||
media(type: $type, search: $search, sort: $sort, status: $status, season: $season, seasonYear: $year, genre: $genre, format: $format) {
|
||||
${queryObjects}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue