chore(deps): bump tailwindcss to v4
This commit is contained in:
@@ -1,6 +1,24 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import 'tailwindcss';
|
||||
|
||||
@config '../../../tailwind.config.ts';
|
||||
|
||||
/*
|
||||
The default border color has changed to `currentcolor` in Tailwind CSS v4,
|
||||
so we've added these compatibility styles to make sure everything still
|
||||
looks the same as it did with Tailwind CSS v3.
|
||||
|
||||
If we ever want to remove these styles, we need to add an explicit border
|
||||
color utility to any element that depends on these defaults.
|
||||
*/
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentcolor);
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
html {
|
||||
|
||||
@@ -30,7 +30,7 @@ const props = defineProps({
|
||||
</h1>
|
||||
|
||||
<h1
|
||||
class="text-xl font-bold text-neutral-700 dark:text-neutral-300 leading-none relative z-[1]"
|
||||
class="text-xl font-bold text-neutral-700 dark:text-neutral-300 leading-none relative z-1"
|
||||
>
|
||||
{{ title }}
|
||||
</h1>
|
||||
@@ -43,7 +43,7 @@ const props = defineProps({
|
||||
<div
|
||||
v-if="bubble"
|
||||
:class="`bg-${bubbleColor}/50`"
|
||||
class="absolute -left-1.5 -bottom-1.5 w-4 h-4 rounded-full z-[0]"
|
||||
class="absolute -left-1.5 -bottom-1.5 w-4 h-4 rounded-full z-0"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -477,7 +477,7 @@ const showAuthModal = ref(false)
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon
|
||||
name="i-heroicons-sun"
|
||||
class="h-4 w-4 text-amber-500 mt-0.5 flex-shrink-0"
|
||||
class="h-4 w-4 text-amber-500 mt-0.5 shrink-0"
|
||||
/>
|
||||
<span class="text-xs text-gray-600 dark:text-gray-300">
|
||||
确保光线充足,避免背光
|
||||
@@ -486,7 +486,7 @@ const showAuthModal = ref(false)
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon
|
||||
name="i-heroicons-speaker-wave"
|
||||
class="h-4 w-4 text-green-500 mt-0.5 flex-shrink-0"
|
||||
class="h-4 w-4 text-green-500 mt-0.5 shrink-0"
|
||||
/>
|
||||
<span class="text-xs text-gray-600 dark:text-gray-300">
|
||||
选择安静环境,减少噪音干扰
|
||||
@@ -495,7 +495,7 @@ const showAuthModal = ref(false)
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon
|
||||
name="i-heroicons-viewfinder-circle"
|
||||
class="h-4 w-4 text-blue-500 mt-0.5 flex-shrink-0"
|
||||
class="h-4 w-4 text-blue-500 mt-0.5 shrink-0"
|
||||
/>
|
||||
<span class="text-xs text-gray-600 dark:text-gray-300">
|
||||
人脸占画面比例控制在 1/4 以内
|
||||
@@ -504,7 +504,7 @@ const showAuthModal = ref(false)
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon
|
||||
name="i-heroicons-face-smile"
|
||||
class="h-4 w-4 text-purple-500 mt-0.5 flex-shrink-0"
|
||||
class="h-4 w-4 text-purple-500 mt-0.5 shrink-0"
|
||||
/>
|
||||
<span class="text-xs text-gray-600 dark:text-gray-300">
|
||||
保持自然表情,使用恰当手势
|
||||
|
||||
@@ -18,12 +18,12 @@ const props = defineProps({
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'w-full h-[1px]': !vertical,
|
||||
'w-[1px] h-full': vertical,
|
||||
'w-full h-px': !vertical,
|
||||
'w-px h-full': vertical,
|
||||
[`from-${lineGradientFrom}-500/50`]: true,
|
||||
[`to-${lineGradientTo}-300/50`]: true,
|
||||
}"
|
||||
class="bg-gradient-to-r rounded-full my-4"
|
||||
class="bg-linear-to-r rounded-full my-4"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -36,6 +36,6 @@ const size = computed(() => {
|
||||
<style scoped>
|
||||
.gradient-background {
|
||||
@apply rounded-lg;
|
||||
@apply bg-gradient-to-r from-indigo-800 to-purple-600;
|
||||
@apply bg-linear-to-r from-indigo-800 to-purple-600;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -585,7 +585,7 @@ const onForgetPasswordSubmit = (
|
||||
|
||||
.pin-input {
|
||||
@apply w-full md:w-16 aspect-square rounded text-center shadow caret-transparent;
|
||||
@apply outline-0 ring-indigo-500 focus:ring font-bold;
|
||||
@apply outline-0 ring-indigo-500 focus:ring-3 font-bold;
|
||||
}
|
||||
|
||||
.pin-label {
|
||||
|
||||
@@ -68,7 +68,7 @@ const getShapeSize = (r: { w: number; h: number }, size: number) => {
|
||||
:class="[ratio.value === selected && 'bg-sky-200/50 dark:bg-sky-700/50']"
|
||||
>
|
||||
<div
|
||||
class="bg-neutral-300/50 dark:bg-neutral-600/50 text-neutral-600 dark:text-neutral-300 rounded flex justify-center items-center"
|
||||
class="bg-neutral-300/50 dark:bg-neutral-600/50 text-neutral-600 dark:text-neutral-300 rounded-sm flex justify-center items-center"
|
||||
:class="[
|
||||
ratio.value === selected && 'bg-sky-300/50 dark:bg-sky-600/50',
|
||||
]"
|
||||
|
||||
@@ -58,7 +58,7 @@ const handleFileInput = (event: { target: any }) => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="w-full bg-neutral-200/50 dark:bg-neutral-700/50 rounded-md flex justify-between items-center p-1.5 gap-2 relative hover:bg-neutral-200/80 hover:dark:bg-neutral-700/80 transition border dark:border-neutral-700 cursor-pointer"
|
||||
class="w-full bg-neutral-200/50 dark:bg-neutral-700/50 rounded-md flex justify-between items-center p-1.5 gap-2 relative hover:bg-neutral-200/80 dark:hover:bg-neutral-700/80 transition border dark:border-neutral-700 cursor-pointer"
|
||||
:class="{ 'cursor-pointer': !loading, 'cursor-not-allowed': loading }"
|
||||
@click="() => !loading && fileInput?.click()"
|
||||
>
|
||||
|
||||
@@ -25,7 +25,7 @@ const message_avatar = computed(() => {
|
||||
})
|
||||
const message_background = computed(() => {
|
||||
if (props.message?.interrupted) {
|
||||
return 'bg-red-200/50 dark:bg-red-800/20 border-red-300 dark:!border-red-500/50'
|
||||
return 'bg-red-200/50 dark:bg-red-800/20 border-red-300 dark:border-red-500/50!'
|
||||
}
|
||||
switch (props.message?.role) {
|
||||
case 'user':
|
||||
|
||||
@@ -40,7 +40,7 @@ const { data: assistantTemplates, pending: assistantTemplatesPending } =
|
||||
<Transition name="loading-screen">
|
||||
<div
|
||||
v-if="assistantTemplatesPending"
|
||||
class="absolute inset-0 bg-white dark:bg-neutral-900 flex justify-center items-center z-[1] text-primary"
|
||||
class="absolute inset-0 bg-white dark:bg-neutral-900 flex justify-center items-center z-1 text-primary"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -151,7 +151,7 @@ const { data: assistantTemplates, pending: assistantTemplatesPending } =
|
||||
class="group ring-primary hover:ring-2 transition duration-300"
|
||||
variant="soft"
|
||||
size="lg"
|
||||
:ui="{ rounded: 'rounded-full' }"
|
||||
:ui="{ rounded-sm: 'rounded-full' }"
|
||||
@click="emit('select', null)"
|
||||
>
|
||||
<span class="-mt-0.5">直接开始</span>
|
||||
@@ -202,7 +202,7 @@ const { data: assistantTemplates, pending: assistantTemplatesPending } =
|
||||
}
|
||||
|
||||
.assistant-item {
|
||||
@apply w-full bg-white dark:bg-neutral-800 rounded-lg shadow-sm ring-primary ring-offset-2 dark:ring-offset-0 hover:ring-2 transition;
|
||||
@apply w-full bg-white dark:bg-neutral-800 rounded-lg shadow-xs ring-primary ring-offset-2 dark:ring-offset-0 hover:ring-2 transition;
|
||||
@apply flex items-center gap-4 px-4 py-2 cursor-pointer border dark:border-neutral-700 hover:border-transparent;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -17,7 +17,7 @@ const props = defineProps({
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="bg-neutral-50 dark:bg-neutral-900 px-1.5 py-1 rounded flex flex-col gap-1 shadow"
|
||||
class="bg-neutral-50 dark:bg-neutral-900 px-1.5 py-1 rounded-sm flex flex-col gap-1 shadow-sm"
|
||||
>
|
||||
<div class="flex items-center gap-1 text-sm">
|
||||
<UIcon
|
||||
|
||||
@@ -155,7 +155,7 @@ const copyToClipboard = (text: string) => {
|
||||
:key="`${fid}-${i}`"
|
||||
>
|
||||
<div
|
||||
class="absolute inset-0 bg-gradient-to-t from-neutral-800/40 to-transparent w-full h-full flex items-end scale-105 opacity-0 group-hover:scale-100 group-hover:opacity-100 transition"
|
||||
class="absolute inset-0 bg-linear-to-t from-neutral-800/40 to-transparent w-full h-full flex items-end scale-105 opacity-0 group-hover:scale-100 group-hover:opacity-100 transition"
|
||||
>
|
||||
<div class="w-full flex justify-end gap-1 p-1">
|
||||
<UTooltip text="以此图为参考创作">
|
||||
@@ -189,7 +189,7 @@ const copyToClipboard = (text: string) => {
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="h-64 aspect-[3/4] mb-4 rounded-lg placeholder-gradient flex justify-center items-center"
|
||||
class="h-64 aspect-3/4 mb-4 rounded-lg placeholder-gradient flex justify-center items-center"
|
||||
>
|
||||
<UIcon
|
||||
name="i-svg-spinners-tadpole"
|
||||
@@ -298,6 +298,6 @@ const copyToClipboard = (text: string) => {
|
||||
}
|
||||
|
||||
.placeholder-gradient {
|
||||
@apply animate-pulse bg-gradient-to-br from-neutral-200 to-neutral-300 dark:from-neutral-700 dark:to-neutral-800;
|
||||
@apply animate-pulse bg-linear-to-br from-neutral-200 to-neutral-300 dark:from-neutral-700 dark:to-neutral-800;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -236,7 +236,7 @@ const onRetryClick = (course: resp.gen.CourseGenItem) => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="w-full rounded-xl border border-neutral-200 dark:border-neutral-700 hover:shadow transition overflow-hidden"
|
||||
class="w-full rounded-xl border border-neutral-200 dark:border-neutral-700 hover:shadow-sm transition overflow-hidden"
|
||||
>
|
||||
<div class="relative w-full aspect-video group">
|
||||
<NuxtImg
|
||||
@@ -248,7 +248,7 @@ const onRetryClick = (course: resp.gen.CourseGenItem) => {
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="absolute inset-0 bg-gradient-to-br from-purple-400 to-primary-400 flex justify-center items-center pattern"
|
||||
class="absolute inset-0 bg-linear-to-br from-purple-400 to-primary-400 flex justify-center items-center pattern"
|
||||
>
|
||||
<Icon
|
||||
v-if="isFailed"
|
||||
@@ -269,7 +269,7 @@ const onRetryClick = (course: resp.gen.CourseGenItem) => {
|
||||
<UBadge
|
||||
:color="stateDisplay.color"
|
||||
:variant="isFailed ? 'solid' : 'subtle'"
|
||||
class="shadow"
|
||||
class="shadow-sm"
|
||||
size="sm"
|
||||
>
|
||||
<Icon
|
||||
@@ -462,7 +462,7 @@ const onRetryClick = (course: resp.gen.CourseGenItem) => {
|
||||
</template>
|
||||
|
||||
<video
|
||||
class="w-full rounded shadow"
|
||||
class="w-full rounded-sm shadow-sm"
|
||||
controls
|
||||
autoplay
|
||||
:src="course.video_url"
|
||||
|
||||
@@ -197,10 +197,10 @@ const startDownload = (url: string, filename: string) => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="w-full flex gap-2 rounded-xl border border-neutral-200 dark:border-neutral-700 hover:shadow transition overflow-hidden p-3"
|
||||
class="w-full flex gap-2 rounded-xl border border-neutral-200 dark:border-neutral-700 hover:shadow-sm transition overflow-hidden p-3"
|
||||
>
|
||||
<div
|
||||
class="flex-0 h-48 aspect-[10/16] flex flex-col items-center justify-center rounded-lg shadow overflow-hidden relative group"
|
||||
class="flex-0 h-48 aspect-10/16 flex flex-col items-center justify-center rounded-lg shadow-sm overflow-hidden relative group"
|
||||
>
|
||||
<div
|
||||
v-if="!video.video_cover"
|
||||
@@ -451,7 +451,7 @@ const startDownload = (url: string, filename: string) => {
|
||||
</template>
|
||||
|
||||
<video
|
||||
class="w-full rounded shadow"
|
||||
class="w-full rounded-sm shadow-sm"
|
||||
controls
|
||||
autoplay
|
||||
:src="video.video_url"
|
||||
@@ -570,7 +570,7 @@ const startDownload = (url: string, filename: string) => {
|
||||
视频预览
|
||||
</div>
|
||||
<video
|
||||
class="w-full rounded-lg shadow bg-black"
|
||||
class="w-full rounded-lg shadow-sm bg-black"
|
||||
controls
|
||||
autoplay
|
||||
muted
|
||||
|
||||
@@ -41,7 +41,7 @@ type subtitleStyleSchema = InferType<typeof subtitleStyleSchema>
|
||||
|
||||
const subtitleStyleState = reactive<subtitleStyleSchema>({
|
||||
color: '#fff',
|
||||
effect: 'shadow',
|
||||
effect: 'shadow-sm',
|
||||
fontSize: 24,
|
||||
bottomOffset: 12,
|
||||
})
|
||||
@@ -213,7 +213,7 @@ const exportVideo = async () => {
|
||||
color: subtitleStyleState.color,
|
||||
fontSize: subtitleStyleState.fontSize,
|
||||
textShadow:
|
||||
subtitleStyleState.effect === 'shadow'
|
||||
subtitleStyleState.effect === 'shadow-sm'
|
||||
? {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
@@ -381,7 +381,7 @@ defineExpose({
|
||||
fontSize: subtitleStyleState.fontSize / 1.5 + 'px',
|
||||
bottom: subtitleStyleState.bottomOffset / 1.5 + 'px',
|
||||
textShadow:
|
||||
subtitleStyleState.effect === 'shadow'
|
||||
subtitleStyleState.effect === 'shadow-sm'
|
||||
? '2px 2px 4px rgba(0, 0, 0, 0.25)'
|
||||
: undefined,
|
||||
}"
|
||||
@@ -391,7 +391,7 @@ defineExpose({
|
||||
<video
|
||||
controls
|
||||
ref="videoElement"
|
||||
class="rounded"
|
||||
class="rounded-sm"
|
||||
style="-webkit-user-drag: none"
|
||||
:src="course.video_url"
|
||||
@timeupdate="syncSubtitles"
|
||||
@@ -425,7 +425,7 @@ defineExpose({
|
||||
fontSize: subtitleStyleState.fontSize / 1.5 + 'px',
|
||||
bottom: subtitleStyleState.bottomOffset / 1.5 + 'px',
|
||||
textShadow:
|
||||
subtitleStyleState.effect === 'shadow'
|
||||
subtitleStyleState.effect === 'shadow-sm'
|
||||
? '2px 2px 4px rgba(0, 0, 0, 0.25)'
|
||||
: undefined,
|
||||
}"
|
||||
@@ -475,7 +475,7 @@ defineExpose({
|
||||
:options="[
|
||||
{
|
||||
label: '阴影',
|
||||
value: 'shadow',
|
||||
value: 'shadow-sm',
|
||||
},
|
||||
{
|
||||
label: '描边',
|
||||
@@ -606,7 +606,7 @@ defineExpose({
|
||||
content: '';
|
||||
inset: 80% 0 0;
|
||||
position: absolute;
|
||||
@apply bg-gradient-to-b from-transparent to-white dark:to-neutral-950 pointer-events-none;
|
||||
@apply bg-linear-to-b from-transparent to-white dark:to-neutral-950 pointer-events-none;
|
||||
}
|
||||
|
||||
.subtitle.stroke {
|
||||
|
||||
@@ -38,12 +38,12 @@ const closePreview = () => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="relative w-full flex flex-col rounded-lg border border-neutral-200 dark:border-neutral-700 overflow-hidden shadow-none hover:shadow transition-shadow"
|
||||
class="relative w-full flex flex-col rounded-lg border border-neutral-200 dark:border-neutral-700 overflow-hidden shadow-none hover:shadow-sm transition-shadow"
|
||||
>
|
||||
<div class="relative w-full aspect-[16/9] group">
|
||||
<div class="relative w-full aspect-16/9 group">
|
||||
<NuxtImg
|
||||
placeholder
|
||||
placeholder-class="w-full aspect-[16/9] object-cover bg-neutral-200 dark:bg-neutral-800"
|
||||
placeholder-class="w-full aspect-16/9 object-cover bg-neutral-200 dark:bg-neutral-800"
|
||||
class="object-cover relative"
|
||||
:src="data.opening_url"
|
||||
/>
|
||||
@@ -183,7 +183,7 @@ const closePreview = () => {
|
||||
|
||||
<video
|
||||
v-if="previewVideoUrl"
|
||||
class="w-full rounded shadow"
|
||||
class="w-full rounded-sm shadow-sm"
|
||||
controls
|
||||
autoplay
|
||||
:src="previewVideoUrl"
|
||||
|
||||
@@ -55,7 +55,7 @@ const handleClick = (e: any) => {
|
||||
|
||||
<template>
|
||||
<button
|
||||
class="w-fit flex justify-center items-center rounded-md font-bold border shadow-sm transition focus:ring-4"
|
||||
class="w-fit flex justify-center items-center rounded-md font-bold border shadow-xs transition focus:ring-4"
|
||||
:class="{
|
||||
'w-full': block,
|
||||
'uni-button--disabled': disabled || loading,
|
||||
|
||||
@@ -98,9 +98,9 @@ const handleInput = (e: any) => {
|
||||
</p>
|
||||
<div class="relative">
|
||||
<input
|
||||
class="relative w-full flex items-center gap-2.5 p-2 pr-2 rounded-md overflow-hidden border transition bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-800 focus:border-neutral-400 dark:focus:border-neutral-700 focus:ring-4 focus:ring-opacity-50 focus:ring-neutral-200 dark:focus:ring-neutral-800 outline-none placeholder-neutral-400 dark:placeholder-neutral-500 shadow-sm"
|
||||
class="relative w-full flex items-center gap-2.5 p-2 pr-2 rounded-md overflow-hidden border transition bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-800 focus:border-neutral-400 dark:focus:border-neutral-700 focus:ring-4 focus:ring-opacity-50 focus:ring-neutral-200 dark:focus:ring-neutral-800 outline-hidden placeholder-neutral-400 dark:placeholder-neutral-500 shadow-xs"
|
||||
:class="{
|
||||
'!border-red-500': isError,
|
||||
'border-red-500!': isError,
|
||||
'bg-neutral-100 dark:bg-neutral-900 text-neutral-400 dark:text-neutral-600':
|
||||
disabled,
|
||||
}"
|
||||
|
||||
@@ -83,7 +83,7 @@ nuxtApp.vueApp.provide('uni-message', api)
|
||||
|
||||
<style scoped>
|
||||
#message-provider .message-wrapper {
|
||||
@apply z-[50000] fixed inset-0 flex flex-col items-center pointer-events-none;
|
||||
@apply z-50000 fixed inset-0 flex flex-col items-center pointer-events-none;
|
||||
}
|
||||
|
||||
.message-move,
|
||||
|
||||
@@ -26,12 +26,12 @@ onMounted(() => {
|
||||
<div
|
||||
class="message"
|
||||
:class="{
|
||||
'!text-blue-500 !border-blue-400 !bg-blue-50': message.type === 'info',
|
||||
'!text-emerald-500 !border-emerald-400 !bg-emerald-50':
|
||||
'text-blue-500! border-blue-400! bg-blue-50!': message.type === 'info',
|
||||
'text-emerald-500! border-emerald-400! bg-emerald-50!':
|
||||
message.type === 'success',
|
||||
'!text-orange-500 !border-orange-400 !bg-orange-50':
|
||||
'text-orange-500! border-orange-400! bg-orange-50!':
|
||||
message.type === 'warning',
|
||||
'!text-rose-500 !border-rose-400 !bg-rose-50': message.type === 'error',
|
||||
'text-rose-500! border-rose-400! bg-rose-50!': message.type === 'error',
|
||||
[message.type]: message.type,
|
||||
}"
|
||||
>
|
||||
|
||||
@@ -97,7 +97,7 @@ onMounted(() => {
|
||||
ref="selectWrapperRef"
|
||||
>
|
||||
<button
|
||||
class="relative w-full flex items-center gap-2.5 p-2 pr-6 rounded-md overflow-hidden border transition bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-800 focus:border-neutral-400 dark:focus:border-neutral-700 focus:ring-4 focus:ring-opacity-50 focus:ring-neutral-200 dark:focus:ring-neutral-800 shadow-sm"
|
||||
class="relative w-full flex items-center gap-2.5 p-2 pr-6 rounded-md overflow-hidden border transition bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-800 focus:border-neutral-400 dark:focus:border-neutral-700 focus:ring-4 focus:ring-opacity-50 focus:ring-neutral-200 dark:focus:ring-neutral-800 shadow-xs"
|
||||
:class="{
|
||||
'cursor-not-allowed bg-neutral-100 dark:bg-neutral-900 text-neutral-400 dark:text-neutral-600':
|
||||
disabled,
|
||||
@@ -148,9 +148,9 @@ onMounted(() => {
|
||||
v-for="(option, index) in items"
|
||||
:key="index"
|
||||
:class="{
|
||||
'!bg-neutral-200 dark:!bg-neutral-700 hover:!bg-neutral-200 dark:hover:!bg-neutral-700':
|
||||
'bg-neutral-200! dark:bg-neutral-700! hover:bg-neutral-200! dark:hover:bg-neutral-700!':
|
||||
option.value === selectedItem?.value,
|
||||
'!cursor-not-allowed text-neutral-300 dark:text-neutral-500 hover:bg-white dark:hover:!bg-neutral-800':
|
||||
'cursor-not-allowed! text-neutral-300 dark:text-neutral-500 hover:bg-white dark:hover:bg-neutral-800!':
|
||||
option.disabled,
|
||||
}"
|
||||
@click="!option.disabled ? handleOptionSelect(option) : void 0"
|
||||
|
||||
@@ -116,11 +116,11 @@ onMounted(() => {
|
||||
</p>
|
||||
<div class="relative">
|
||||
<textarea
|
||||
class="relative w-full flex items-center gap-2.5 p-2 pr-6 rounded-md overflow-hidden overflow-y-auto border transition bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-800 focus:border-neutral-400 dark:focus:border-neutral-700 focus:ring-4 focus:ring-opacity-50 focus:ring-neutral-200 dark:focus:ring-neutral-800 outline-none placeholder-neutral-400 dark:placeholder-neutral-500 shadow-sm"
|
||||
class="relative w-full flex items-center gap-2.5 p-2 pr-6 rounded-md overflow-hidden overflow-y-auto border transition bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-800 focus:border-neutral-400 dark:focus:border-neutral-700 focus:ring-4 focus:ring-opacity-50 focus:ring-neutral-200 dark:focus:ring-neutral-800 outline-hidden placeholder-neutral-400 dark:placeholder-neutral-500 shadow-xs"
|
||||
:rows="minRows || rows"
|
||||
ref="textAreaRef"
|
||||
:class="{
|
||||
'!border-red-500': isError,
|
||||
'border-red-500!': isError,
|
||||
'bg-neutral-100 dark:bg-neutral-900 text-neutral-400 dark:text-neutral-600':
|
||||
disabled,
|
||||
}"
|
||||
|
||||
@@ -98,18 +98,18 @@ watch(
|
||||
|
||||
<template>
|
||||
<button
|
||||
class="relative flex items-center rounded-lg bg-neutral-100 dark:bg-neutral-800 shadow-inner transition ease-in-out group outline-none"
|
||||
class="relative flex items-center rounded-lg bg-neutral-100 dark:bg-neutral-800 shadow-inner transition ease-in-out group outline-hidden"
|
||||
:class="{
|
||||
'!bg-green-400 dark:!bg-green-400/50': checked,
|
||||
'bg-green-400! dark:bg-green-400/50!': checked,
|
||||
[buttonSizeClass]: buttonSizeClass,
|
||||
[buttonPaddingClass]: buttonPaddingClass,
|
||||
}"
|
||||
@click="handleCheck"
|
||||
>
|
||||
<span
|
||||
class="aspect-[1/1] translate-x-0 transition ease-in-out bg-white dark:bg-black rounded-md shadow duration-300 group-active:scale-90"
|
||||
class="aspect-1/1 translate-x-0 transition ease-in-out bg-white dark:bg-black rounded-md shadow-sm duration-300 group-active:scale-90"
|
||||
:class="{
|
||||
'!shadow-lg': checked,
|
||||
'shadow-lg!': checked,
|
||||
'group-active:translate-x-3 group-active:duration-500': !checked,
|
||||
[bulletSizeClass]: bulletSizeClass,
|
||||
[bulletTranslateClass]: checked,
|
||||
|
||||
@@ -208,7 +208,7 @@ onMounted(async () => {
|
||||
<span class="truncate">{{ item.label }}</span>
|
||||
<UIcon
|
||||
:name="item.icon"
|
||||
class="ms-auto size-4 flex-shrink-0 text-gray-400 dark:text-gray-500"
|
||||
class="ms-auto size-4 shrink-0 text-gray-400 dark:text-gray-500"
|
||||
/>
|
||||
</template>
|
||||
</UDropdown>
|
||||
|
||||
@@ -488,7 +488,7 @@ onMounted(() => {
|
||||
v-for="(llm, index) in llmModels"
|
||||
:key="index"
|
||||
@click="currentModel = llm.tag"
|
||||
class="flex flex-col gap-2 justify-center items-center w-full aspect-[1/1] border-2 rounded-xl cursor-pointer transition duration-150 select-none"
|
||||
class="flex flex-col gap-2 justify-center items-center w-full aspect-1/1 border-2 rounded-xl cursor-pointer transition duration-150 select-none"
|
||||
:class="
|
||||
llm.tag === currentModel
|
||||
? 'border-primary shadow-xl bg-primary text-white'
|
||||
@@ -501,7 +501,7 @@ onMounted(() => {
|
||||
class="text-4xl opacity-80"
|
||||
/>
|
||||
<div class="flex flex-col gap-0.5 items-center">
|
||||
<h1 class="font-bold drop-shadow opacity-90">
|
||||
<h1 class="font-bold drop-shadow-sm opacity-90">
|
||||
{{ llm.name || 'unknown' }}
|
||||
</h1>
|
||||
<p class="text-xs opacity-60">{{ llm.description }}</p>
|
||||
@@ -548,7 +548,7 @@ onMounted(() => {
|
||||
|
||||
.chat-option-btn {
|
||||
@apply text-lg px-2 py-1.5 flex gap-1 justify-center items-center rounded-lg;
|
||||
@apply bg-white border border-neutral-300 shadow-sm hover:shadow-card;
|
||||
@apply bg-white border border-neutral-300 shadow-xs hover:shadow-card;
|
||||
@apply dark:bg-neutral-800 dark:border-neutral-600;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -333,7 +333,7 @@ const onDefaultFormSubmit = (event: FormSubmitEvent<DefaultFormSchema>) => {
|
||||
@mousedown.prevent="handle_stick_mousedown"
|
||||
>
|
||||
<span
|
||||
class="w-[1px] h-full bg-neutral-300 dark:bg-neutral-700 group-hover:bg-indigo-300 dark:group-hover:bg-indigo-700 group-hover:w-[3px] transition-all group-hover:delay-500 translate-x-1"
|
||||
class="w-px h-full bg-neutral-300 dark:bg-neutral-700 group-hover:bg-indigo-300 dark:group-hover:bg-indigo-700 group-hover:w-[3px] transition-all group-hover:delay-500 translate-x-1"
|
||||
></span>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -200,7 +200,7 @@ const open = (url?: string | URL, target?: string, features?: string) => {
|
||||
>
|
||||
<div class="container max-w-[1280px] mx-auto py-4 space-y-12">
|
||||
<div
|
||||
class="pattern w-full p-10 flex flex-col justify-center gap-3 items-center rounded-lg shadow-sm border border-gray-200 dark:border-neutral-700"
|
||||
class="pattern w-full p-10 flex flex-col justify-center gap-3 items-center rounded-lg shadow-xs border border-gray-200 dark:border-neutral-700"
|
||||
>
|
||||
<h1 class="text-4xl font-bold text-center text-primary">AI 工具导航</h1>
|
||||
<p>常用 AI 工具,一网打尽,常用常新</p>
|
||||
@@ -222,7 +222,7 @@ const open = (url?: string | URL, target?: string, features?: string) => {
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<div
|
||||
v-for="link in cat.links"
|
||||
class="bg-white dark:bg-neutral-800 p-4 rounded-lg shadow-sm border border-gray-200 dark:border-neutral-700 space-y-2 cursor-pointer hover:shadow-md transition-all duration-300"
|
||||
class="bg-white dark:bg-neutral-800 p-4 rounded-lg shadow-xs border border-gray-200 dark:border-neutral-700 space-y-2 cursor-pointer hover:shadow-md transition-all duration-300"
|
||||
:key="link.id"
|
||||
@click="open(link.url)"
|
||||
>
|
||||
|
||||
@@ -323,7 +323,7 @@ const previewVideo = (videoUrl: string, title: string) => {
|
||||
const closeButton = document.createElement('button')
|
||||
closeButton.textContent = '关闭'
|
||||
closeButton.className =
|
||||
'mt-4 px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600'
|
||||
'mt-4 px-4 py-2 bg-gray-500 text-white rounded-sm hover:bg-gray-600'
|
||||
closeButton.onclick = () => {
|
||||
document.body.removeChild(videoModal)
|
||||
}
|
||||
|
||||
@@ -947,7 +947,7 @@ const onCreateSubmit = async (
|
||||
v-if="row.info.opening_url"
|
||||
:src="row.info.opening_url"
|
||||
:alt="row.info.title"
|
||||
class="w-16 h-9 object-cover rounded cursor-pointer hover:opacity-80 transition-opacity"
|
||||
class="w-16 h-9 object-cover rounded-sm cursor-pointer hover:opacity-80 transition-opacity"
|
||||
@click="
|
||||
previewVideo(
|
||||
row.info.opening_file,
|
||||
@@ -989,12 +989,12 @@ const onCreateSubmit = async (
|
||||
v-if="row.opening_url"
|
||||
:src="row.opening_url"
|
||||
alt="片头"
|
||||
class="w-14 h-8 object-cover rounded cursor-pointer hover:opacity-80 transition-opacity ring-1 ring-blue-200 dark:ring-blue-800"
|
||||
class="w-14 h-8 object-cover rounded-sm cursor-pointer hover:opacity-80 transition-opacity ring-1 ring-blue-200 dark:ring-blue-800"
|
||||
@click="previewVideo(row.opening_file, '制作片头预览')"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="w-14 h-8 bg-blue-100 dark:bg-blue-900/30 rounded flex items-center justify-center cursor-pointer hover:opacity-80 transition-opacity"
|
||||
class="w-14 h-8 bg-blue-100 dark:bg-blue-900/30 rounded-sm flex items-center justify-center cursor-pointer hover:opacity-80 transition-opacity"
|
||||
@click="previewVideo(row.opening_file, '制作片头预览')"
|
||||
>
|
||||
<UIcon
|
||||
@@ -1015,12 +1015,12 @@ const onCreateSubmit = async (
|
||||
v-if="row.ending_url"
|
||||
:src="row.ending_url"
|
||||
alt="片尾"
|
||||
class="w-14 h-8 object-cover rounded cursor-pointer hover:opacity-80 transition-opacity ring-1 ring-green-200 dark:ring-green-800"
|
||||
class="w-14 h-8 object-cover rounded-sm cursor-pointer hover:opacity-80 transition-opacity ring-1 ring-green-200 dark:ring-green-800"
|
||||
@click="previewVideo(row.ending_file, '制作片尾预览')"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="w-14 h-8 bg-green-100 dark:bg-green-900/30 rounded flex items-center justify-center cursor-pointer hover:opacity-80 transition-opacity"
|
||||
class="w-14 h-8 bg-green-100 dark:bg-green-900/30 rounded-sm flex items-center justify-center cursor-pointer hover:opacity-80 transition-opacity"
|
||||
@click="previewVideo(row.ending_file, '制作片尾预览')"
|
||||
>
|
||||
<UIcon
|
||||
@@ -1364,7 +1364,7 @@ const onCreateSubmit = async (
|
||||
v-if="previewVideoUrl"
|
||||
:src="previewVideoUrl"
|
||||
controls
|
||||
class="w-full h-full rounded"
|
||||
class="w-full h-full rounded-sm"
|
||||
/>
|
||||
</div>
|
||||
</UCard>
|
||||
@@ -1395,7 +1395,7 @@ const onCreateSubmit = async (
|
||||
v-if="previewImageUrl"
|
||||
:src="previewImageUrl"
|
||||
:alt="previewImageTitle"
|
||||
class="max-w-full max-h-[70vh] rounded object-contain"
|
||||
class="max-w-full max-h-[70vh] rounded-sm object-contain"
|
||||
/>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
@@ -305,14 +305,14 @@ const onAvatarUpload = async (files: FileList) => {
|
||||
? systemAvatarList?.data.items
|
||||
: userAvatarList?.data.items"
|
||||
:key="avatar.model_id || k"
|
||||
class="relative rounded-lg shadow overflow-hidden w-full aspect-[9/16] group"
|
||||
class="relative rounded-lg shadow-sm overflow-hidden w-full aspect-9/16 group"
|
||||
>
|
||||
<NuxtImg
|
||||
:src="avatar.avatar"
|
||||
class="w-full h-full object-cover"
|
||||
/>
|
||||
<div
|
||||
class="absolute inset-x-0 bottom-0 p-2 bg-gradient-to-t from-black/50 to-transparent flex gap-2"
|
||||
class="absolute inset-x-0 bottom-0 p-2 bg-linear-to-t from-black/50 to-transparent flex gap-2"
|
||||
>
|
||||
<UBadge
|
||||
color="white"
|
||||
@@ -334,7 +334,7 @@ const onAvatarUpload = async (files: FileList) => {
|
||||
</template>
|
||||
</div>
|
||||
<div
|
||||
class="absolute inset-0 flex flex-col justify-center items-center bg-white/50 dark:bg-neutral-800/50 backdrop-blur opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
class="absolute inset-0 flex flex-col justify-center items-center bg-white/50 dark:bg-neutral-800/50 backdrop-blur-sm opacity-0 group-hover:opacity-100 transition-opacity"
|
||||
>
|
||||
<UButtonGroup>
|
||||
<UButton
|
||||
@@ -376,7 +376,7 @@ const onAvatarUpload = async (files: FileList) => {
|
||||
<template #avatar-data="{ row }">
|
||||
<NuxtImg
|
||||
:src="row.avatar"
|
||||
class="h-16 aspect-[9/16] rounded-lg"
|
||||
class="h-16 aspect-9/16 rounded-lg"
|
||||
/>
|
||||
</template>
|
||||
<template #type-data="{ row }">
|
||||
|
||||
@@ -327,7 +327,7 @@ const onDeleteCat = (cat: PPTCategory) => {
|
||||
class="w-full aspect-video object-cover"
|
||||
/>
|
||||
<div
|
||||
class="absolute inset-x-0 bottom-0 p-3 pt-6 flex justify-between items-end bg-gradient-to-t from-black/50 to-transparent"
|
||||
class="absolute inset-x-0 bottom-0 p-3 pt-6 flex justify-between items-end bg-linear-to-t from-black/50 to-transparent"
|
||||
>
|
||||
<div class="space-y-0.5">
|
||||
<h3 class="text-base font-bold text-white">{{ ppt.title }}</h3>
|
||||
|
||||
@@ -608,7 +608,7 @@ onMounted(() => {
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
class="!text-gray-500"
|
||||
class="text-gray-500!"
|
||||
@click="
|
||||
() => {
|
||||
router.push('/user/register')
|
||||
|
||||
@@ -157,7 +157,7 @@ const onSubmit = (form: RegisterSchema) => {
|
||||
<UButton
|
||||
color="gray"
|
||||
variant="ghost"
|
||||
class="!text-gray-500"
|
||||
class="text-gray-500!"
|
||||
@click="
|
||||
() => {
|
||||
router.push('/user/authenticate')
|
||||
|
||||
@@ -53,11 +53,11 @@
|
||||
"oxfmt": "^0.28.0",
|
||||
"oxlint": "^1.43.0",
|
||||
"sass": "^1.77.8",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"dayjs": "^1.11.19",
|
||||
"tailwindcss": "^3.4.7"
|
||||
"dayjs": "^1.11.19"
|
||||
},
|
||||
"packageManager": "pnpm@10.22.0"
|
||||
}
|
||||
|
||||
19
pnpm-lock.yaml
generated
19
pnpm-lock.yaml
generated
@@ -74,9 +74,6 @@ importers:
|
||||
radix-vue:
|
||||
specifier: ^1.9.2
|
||||
version: 1.9.17(vue@3.5.28(typescript@5.9.3))
|
||||
tailwindcss:
|
||||
specifier: ^3.4.7
|
||||
version: 3.4.19(yaml@2.8.2)
|
||||
v-calendar:
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2(@popperjs/core@2.11.8)(vue@3.5.28(typescript@5.9.3))
|
||||
@@ -101,7 +98,7 @@ importers:
|
||||
version: 0.11.3(magicast@0.5.2)(pinia@2.3.1(typescript@5.9.3)(vue@3.5.28(typescript@5.9.3)))
|
||||
'@tailwindcss/typography':
|
||||
specifier: ^0.5.13
|
||||
version: 0.5.19(tailwindcss@3.4.19(yaml@2.8.2))
|
||||
version: 0.5.19(tailwindcss@4.1.18)
|
||||
'@types/markdown-it':
|
||||
specifier: ^13.0.9
|
||||
version: 13.0.9
|
||||
@@ -129,6 +126,9 @@ importers:
|
||||
sass:
|
||||
specifier: ^1.77.8
|
||||
version: 1.97.3
|
||||
tailwindcss:
|
||||
specifier: ^4.1.18
|
||||
version: 4.1.18
|
||||
typescript:
|
||||
specifier: ^5.9.3
|
||||
version: 5.9.3
|
||||
@@ -3180,6 +3180,7 @@ packages:
|
||||
glob@11.1.0:
|
||||
resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==}
|
||||
engines: {node: 20 || >=22}
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
hasBin: true
|
||||
|
||||
glob@13.0.1:
|
||||
@@ -4882,6 +4883,9 @@ packages:
|
||||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
tailwindcss@4.1.18:
|
||||
resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==}
|
||||
|
||||
tar-fs@2.1.4:
|
||||
resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==}
|
||||
|
||||
@@ -7544,6 +7548,11 @@ snapshots:
|
||||
postcss-selector-parser: 6.0.10
|
||||
tailwindcss: 3.4.19(yaml@2.8.2)
|
||||
|
||||
'@tailwindcss/typography@0.5.19(tailwindcss@4.1.18)':
|
||||
dependencies:
|
||||
postcss-selector-parser: 6.0.10
|
||||
tailwindcss: 4.1.18
|
||||
|
||||
'@tanstack/virtual-core@3.13.18': {}
|
||||
|
||||
'@tanstack/vue-virtual@3.13.18(vue@3.5.28(typescript@5.9.3))':
|
||||
@@ -11031,6 +11040,8 @@ snapshots:
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
tailwindcss@4.1.18: {}
|
||||
|
||||
tar-fs@2.1.4:
|
||||
dependencies:
|
||||
chownr: 1.1.4
|
||||
|
||||
Reference in New Issue
Block a user