You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.6 KiB
133 lines
3.6 KiB
<script setup lang="ts">
|
|
import type { FeedItem } from '@/feed'
|
|
import jfapi, { type View } from '@/jfapi'
|
|
import { getImageLink, getDisplayDuration } from '../utils'
|
|
import { onBeforeMount, onMounted, ref } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import ScrollerItemPortrait from './ScrollerItemPortrait.vue'
|
|
|
|
const route = useRoute()
|
|
const viewId = String(route.params.id)
|
|
|
|
let index = 0
|
|
let totalItems = 0
|
|
|
|
console.log(viewId)
|
|
|
|
const Items = async (viewId: string, type: string): Promise<FeedItem[]> => {
|
|
return new Promise(async (resolve) => {
|
|
const feed: FeedItem[] = []
|
|
const userid = localStorage.getItem('jf_userid')
|
|
const data = await jfapi.GetItemsInView(userid ? userid : '', viewId, type, index)
|
|
if (data !== null) {
|
|
index = data.StartIndex + 100
|
|
totalItems = data.TotalRecordCount
|
|
if (index > totalItems) {
|
|
index = totalItems
|
|
}
|
|
console.log('Index =>', index)
|
|
for (const item of data.Items) {
|
|
if (userid === null) {
|
|
window.location.href = '/login'
|
|
}
|
|
feed.push({
|
|
title: item.SeriesName || item.Name,
|
|
subtext: item.SeriesName
|
|
? `S${item.ParentIndexNumber}:E${item.IndexNumber} - ${item.Name}`
|
|
: String(item.ProductionYear),
|
|
image: getImageLink(item),
|
|
summary: item.Overview,
|
|
infoSubtext: item.OriginalTitle == item.Name ? '' : item.OriginalTitle,
|
|
imdbRating: String(item.CommunityRating),
|
|
runtime: getDisplayDuration(item.RunTimeTicks),
|
|
date: String(item.ProductionYear),
|
|
MPAA: item.OfficialRating,
|
|
tag:
|
|
item.UserData?.UnplayedItemCount !== undefined
|
|
? String(item.UserData.UnplayedItemCount)
|
|
: '',
|
|
itemId: item.Id,
|
|
type: item.Type,
|
|
})
|
|
}
|
|
console.log('MediaGrid.vue =>', feed)
|
|
resolve(feed)
|
|
}
|
|
})
|
|
}
|
|
const items = ref<FeedItem[]>()
|
|
const views = ref<View[]>()
|
|
const viewstring = ref<string | null>('')
|
|
const viewType = ref('')
|
|
let loading = false
|
|
views.value = undefined
|
|
onBeforeMount(async () => {
|
|
viewstring.value = localStorage.getItem('jf_views')
|
|
views.value = JSON.parse(viewstring.value || '')
|
|
for (const view of views.value || []) {
|
|
if (view.Id === viewId) {
|
|
if (view.CollectionType.toLowerCase() === 'movies') {
|
|
viewType.value = 'Movie'
|
|
} else if (view.CollectionType.toLowerCase() === 'tvshows') {
|
|
viewType.value = 'Series'
|
|
}
|
|
}
|
|
}
|
|
console.log('ItemType =>', viewType)
|
|
const data = ref<FeedItem[]>()
|
|
console.log(viewType)
|
|
data.value = await Items(viewId, viewType.value)
|
|
items.value = data.value
|
|
})
|
|
const onLoadMore = async () => {
|
|
if (index === totalItems || loading) {
|
|
return
|
|
}
|
|
loading = true
|
|
const more = await Items(viewId, viewType.value)
|
|
items.value?.push(...more)
|
|
loading = false
|
|
}
|
|
|
|
onMounted(() => {
|
|
const observer = new IntersectionObserver((entries) => {
|
|
if (entries[0].isIntersecting) {
|
|
onLoadMore()
|
|
}
|
|
})
|
|
const el = document.querySelector('.loading-trigger')
|
|
if (el) {
|
|
console.log('observing!')
|
|
observer.observe(el)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="media-grid">
|
|
<div class="grid-wrapper">
|
|
<ScrollerItemPortrait
|
|
v-for="item in items"
|
|
:item="item"
|
|
:key="item.itemId"
|
|
class="scroller-item"
|
|
/>
|
|
<div class="loading-trigger"></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.media-grid {
|
|
max-width: 80%;
|
|
margin: auto;
|
|
margin-top: 3em;
|
|
}
|
|
.grid-wrapper {
|
|
display: flex;
|
|
flex-direction: row;
|
|
flex-wrap: wrap;
|
|
gap: 1em;
|
|
}
|
|
</style>
|