Merge remote-tracking branch 'origin/main'

# Conflicts:
#	layouts/default.vue
#	nuxt.config.ts
#	package.json
#	yarn.lock
This commit is contained in:
2024-06-22 01:50:23 +08:00
12 changed files with 363 additions and 17 deletions

View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
const props = defineProps({
title: {
type: String,
required: true,
},
subtitle: {
type: String,
required: false,
},
bubble: {
type: Boolean,
default: true,
},
})
</script>
<template>
<div class="relative font-sans select-none">
<h1
v-if="subtitle"
class="text-base text-neutral-300 italic tracking-wide font-black leading-none"
>{{ subtitle }}</h1>
<h1 class="text-xl font-bold text-neutral-700 leading-none relative z-[1]">
{{ title }}
</h1>
<div
v-if="bubble"
class="absolute -left-1.5 -bottom-1.5 w-4 h-4 rounded-full bg-primary-500/50 z-[0]"
></div>
</div>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,19 @@
<script setup lang="ts">
const props = defineProps({
vertical: {
type: Boolean,
default: false,
},
})
</script>
<template>
<div
class="bg-gradient-to-r from-primary-500/50 to-primary-300/50 rounded-full my-4"
:class="{'w-full h-[1px]': !vertical, 'w-[1px] h-full': vertical}"
></div>
</template>
<style scoped>
</style>

View File

@@ -1,24 +1,38 @@
<script setup lang="ts">
<script setup lang="tsx">
import ModalAuthentication from '~/components/ModalAuthentication.vue'
const loginState = useLoginState()
defineProps({
contentClass: {
type: String,
default: ''
}
default: '',
},
})
const modal = useModal()
</script>
<template>
<div v-if="!loginState.is_logged_in"
class="w-full flex flex-col justify-center items-center gap-2 bg-neutral-100 dark:bg-neutral-900">
<Icon name="i-tabler-user-circle" class="text-7xl text-neutral-300 dark:text-neutral-700"/>
<p class="text-sm text-neutral-500 dark:text-neutral-400">请登录后使用</p>
<UButton class="mt-2 font-bold" to="/login" color="black" variant="solid" size="xs">登录</UButton>
</div>
<div :class="contentClass" v-else>
<slot/>
</div>
<ClientOnly>
<div v-if="!loginState.is_logged_in"
class="w-full flex flex-col justify-center items-center gap-2 bg-neutral-100 dark:bg-neutral-900">
<Icon name="i-tabler-user-circle" class="text-7xl text-neutral-300 dark:text-neutral-700"/>
<p class="text-sm text-neutral-500 dark:text-neutral-400">登录后使用</p>
<UButton
class="mt-2 font-bold"
color="black"
variant="solid"
size="xs"
@click="modal.open(ModalAuthentication)"
>
登录
</UButton>
</div>
<div :class="contentClass" v-else>
<slot/>
</div>
</ClientOnly>
</template>
<style scoped>

View File

@@ -0,0 +1,37 @@
<script setup lang="ts">
const props = defineProps({
icon: {
type: String,
default: 'i-tabler-photo-filled',
},
label: {
type: String,
required: true,
},
to: {
type: String,
required: true,
},
})
const route = useRoute()
const active = computed(() => {
return route.path === props.to
})
</script>
<template>
<NuxtLink
class="px-4 py-3 flex items-center gap-2 rounded-lg transition cursor-pointer"
:class="active ? 'bg-primary text-white' : 'hover:bg-neutral-200'"
:to="to"
>
<Icon :name="icon" class="text-xl inline"/>
<h1 class="text-[14px] font-medium">{{ label }}</h1>
</NuxtLink>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,93 @@
<script setup lang="ts">
const props = defineProps({
record: {
type: Object,
required: true,
},
})
const dayjs = useDayjs()
</script>
<template>
<div
class="relative w-full aspect-video rounded-lg overflow-hidden shadow"
>
<NuxtImg :src="record.video_cover"></NuxtImg>
<div class="absolute inset-0 flex flex-col justify-between bg-black/10 bg-gradient-to-t from-black/20">
<div class="flex justify-between items-start p-2.5 gap-2">
<div>
<UButton icon="i-solar-play-circle-bold-duotone">预览</UButton>
</div>
<div class="flex flex-col items-end gap-1">
<UTooltip :text="record.task_id" :close-delay="300">
<h1 class="text-white text-xs font-bold font-sans">
ID: {{ record.task_id.slice(0, 6) }}
</h1>
</UTooltip>
<UTooltip :text="dayjs(record.create_time * 1000).format('YYYY-MM-DD HH:mm:ss')">
<h1 class="text-white text-xs font-bold font-sans">
{{ dayjs(record.create_time * 1000).fromNow() }}
</h1>
</UTooltip>
</div>
<!-- <UProgress-->
<!-- size="md"-->
<!-- indicator-->
<!-- :ui="{-->
<!-- wrapper: 'flex-col-reverse',-->
<!-- progress: {-->
<!-- base: '!bg-opacity-50'-->
<!-- }-->
<!-- }"-->
<!-- :value="10"-->
<!-- :max="100"-->
<!-- :animation="'carousel'"-->
<!-- />-->
</div>
<div class="flex justify-between items-center p-2.5 gap-2">
<div class="overflow-hidden whitespace-nowrap">
<UTooltip
:text="record.title"
:popper="{
placement: 'bottom-start'
}"
:open-delay="300"
:close-delay="300"
class="w-full"
>
<h1 class="text-white text-base font-bold font-sans drop-shadow overflow-hidden text-ellipsis leading-none">
{{ record.title }}
</h1>
</UTooltip>
</div>
<div class="flex-1 whitespace-nowrap flex gap-1.5">
<UButton
size="xs"
color="red"
variant="soft"
icon="i-tabler-trash"
/>
<UButton
size="xs"
color="primary"
variant="soft"
icon="i-solar-subtitles-linear"
>
字幕
</UButton>
<UButton
size="xs"
icon="i-tabler-download"
>
下载
</UButton>
</div>
</div>
</div>
</div>
</template>
<style scoped>
</style>