Compare commits

...

2 Commits

5 changed files with 99 additions and 20 deletions

View File

@ -18,6 +18,7 @@ export const buttonVariants = cva(
ghost:
'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
link: 'text-primary underline-offset-4 hover:underline',
borderless: 'border-0 cursor-pointer size-20'
},
size: {
default: 'h-9 px-4 py-2 has-[>svg]:px-3',

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue'
interface Props {
type: EpisodeChangeType;
}
const props = defineProps<Props>();
</script>
<script lang="ts">
export enum EpisodeChangeType {
NEXT = "mage:next-fill",
PREVIOUS = "mage:previous-fill",
}
</script>
<template>
<UiButton variant="borderless" size="icon">
<Icon :icon="props.type" class="size-5" />
</UiButton>
</template>

View File

@ -1,10 +1,14 @@
<script setup lang="ts">
import Artplayer from "artplayer";
import Hls from "hls.js";
import { createVueControlSmart } from "~/components/util/player-control";
import { EpisodeChangeType } from "./ChangeEpisodeButton.vue";
import { UiPlayerChangeEpisodeButton } from "#components";
interface Props {
urls: any;
id: string;
episodeButton: boolean;
}
const props = withDefaults(defineProps<Props>(), {
@ -13,6 +17,29 @@ const props = withDefaults(defineProps<Props>(), {
const emit = defineEmits(['get-instance'])
const options = computed(() => {
const controls = []
if (props.episodeButton) {
controls.push(
createVueControlSmart(UiPlayerChangeEpisodeButton, {
name: "next-episode",
index: 50,
tooltip: "Next episode",
type: EpisodeChangeType.NEXT
}, {
click: () => console.log("NEXT")
})
)
controls.push(
createVueControlSmart(UiPlayerChangeEpisodeButton, {
name: "previous-episode",
index: 50,
tooltip: "Previous episode",
type: EpisodeChangeType.PREVIOUS
}, {
click: () => console.log("Previous")
})
)
}
return {
url: props.urls[0].url || '',
type: 'm3u8',
@ -30,6 +57,7 @@ const options = computed(() => {
autoOrientation: true,
autoPlayback: true,
id: props.id,
controls: controls,
}
})
const artplayerRef = ref();

View File

@ -0,0 +1,44 @@
import { createApp, h } from 'vue'
export function createVueControlSmart(component, props = {}, events = {}) {
let vueApp = null
return {
name: props.name || 'vue-control',
index: props.index || 0,
position: props.position || 'left',
html: `<div class="vue-control-wrapper" data-vue-control="${component.name}"></div>`,
tooltip: props.tooltip || '',
mounted: function ($control) {
const container = $control.querySelector('.vue-control-wrapper')
if (container && !vueApp) {
console.log("111")
vueApp = createApp({
render() {
return h(component, {
...props,
...Object.entries(events).reduce((acc, [eventName, handler]) => {
acc[`on${eventName.charAt(0).toUpperCase() + eventName.slice(1)}`] = handler
return acc
}, {})
})
}
})
vueApp.mount(container)
$control._vueApp = vueApp
}
},
destroy: function ($control) {
if ($control._vueApp) {
$control._vueApp.unmount()
$control._vueApp = null
vueApp = null
}
}
}
}

View File

@ -8,7 +8,8 @@
<p>Episode: {{ episode }}</p>
<div v-if="hlsUrls">
<Player :id="mediaId.toString().concat(episode?.toString() || '')" :urls="hlsUrls" />
<Player :id="mediaId.toString().concat(episode?.toString() || '')" :urls="hlsUrls" :episode="episode"
:episodeButton="true" />
</div>
<!-- Loading and Error States -->
@ -24,7 +25,7 @@
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { Player } from '~/components/ui/player'
import { video, type KodikTranslationDTO, type KodikVideoLinks, type VideoParams } from '~/openapi/extractor'
import { video, type KodikVideoLinks } from '~/openapi/extractor'
const route = useRoute()
const mediaType = route.query.mediaType
@ -35,20 +36,8 @@ const episode = route.query.episode
const results = ref<KodikVideoLinks | null>(null)
const isLoading = ref(false)
const error = ref<unknown>(null)
const hlsUrl = ref<string | null>(null)
const hlsUrls = ref<any>(null)
const playerOptions = ref({
autoplay: false,
controls: true,
responsive: true,
fluid: true,
sources: [{
src: hlsUrl.value,
type: 'application/x-mpegURL'
}]
})
watchEffect(async () => {
if (!mediaType || !mediaId || !mediaHash || !episode) return
@ -56,12 +45,6 @@ watchEffect(async () => {
isLoading.value = true
error.value = null
const translationDto: KodikTranslationDTO = {
mediaType: mediaType as string,
mediaId: mediaId as string,
mediaHash: mediaHash as string,
}
const videoParams: any = {
mediaType: mediaType as string,
mediaId: mediaId as string,