feat: 完成移动端适配
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
export { default as ChevronLeftIcon } from "./svg/heroicons/ChevronLeftIcon.svg?component";
|
||||
export { default as ExclamationTriangleIcon } from "./svg/heroicons/ExclamationTriangleIcon.svg?component";
|
||||
export { default as microphone } from "./svg/heroicons/MicrophoneIcon.svg?component";
|
||||
export { default as PaperAirplaneIcon } from "./svg/heroicons/PaperAirplaneIcon.svg?component";
|
||||
|
||||
3
web/src/assets/Icons/svg/heroicons/ChevronLeftIcon.svg
Normal file
3
web/src/assets/Icons/svg/heroicons/ChevronLeftIcon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 226 B |
@@ -1,15 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
import { NImage } from "naive-ui";
|
||||
import { ChevronLeftIcon } from "@/assets/Icons";
|
||||
import logo from "@/assets/logo.png";
|
||||
import { useChatStore } from "@/stores";
|
||||
import { useChatStore, useLayoutStore } from "@/stores";
|
||||
|
||||
const chatStore = useChatStore();
|
||||
const { onlineCount } = storeToRefs(chatStore);
|
||||
const layoutStore = useLayoutStore();
|
||||
const { hiddenLeftSidebar, simpleMode } = storeToRefs(layoutStore);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-screen flex overflow-hidden">
|
||||
<div class="flex-none w-[200px] h-full flex flex-col">
|
||||
<div class="relative h-screen flex overflow-hidden">
|
||||
<div
|
||||
class="absolute left-0 top-0 bottom-0 z-10 flex-none w-[200px] h-full flex flex-col bg-white transition-all ease-in-out"
|
||||
:class="{
|
||||
'-translate-x-[200px]': hiddenLeftSidebar
|
||||
}"
|
||||
>
|
||||
<div
|
||||
@click="hiddenLeftSidebar = !hiddenLeftSidebar"
|
||||
class="absolute -right-3 translate-y-1/2 top-1/2 z-20 w-[24px] h-[24px] bg-[#0094c526] rounded-full flex items-center justify-center cursor-pointer"
|
||||
:class="{
|
||||
'rotate-180 -right-8': hiddenLeftSidebar
|
||||
}"
|
||||
>
|
||||
<ChevronLeftIcon class="!w-4 !h-4 text-[#777]" />
|
||||
</div>
|
||||
<router-link class="w-full my-6 cursor-pointer" to="/">
|
||||
<NImage
|
||||
class="w-full object-cover"
|
||||
@@ -40,7 +56,10 @@ const { onlineCount } = storeToRefs(chatStore);
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 relative">
|
||||
<div
|
||||
class="flex-1 relative"
|
||||
:class="{ 'ml-[200px]': !hiddenLeftSidebar && !simpleMode }"
|
||||
>
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./asr_store";
|
||||
export * from "./chat_store";
|
||||
export * from "./layout_store";
|
||||
44
web/src/stores/layout_store.ts
Normal file
44
web/src/stores/layout_store.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { matchMedia } from "@/utils";
|
||||
|
||||
export const useLayoutStore = defineStore("layout", () => {
|
||||
// 侧边栏状态
|
||||
const hiddenLeftSidebar = ref(false);
|
||||
// 简洁按钮
|
||||
const simpleMode = ref(false);
|
||||
|
||||
const handleResize = () => {
|
||||
matchMedia(
|
||||
"sm",
|
||||
() => {
|
||||
hiddenLeftSidebar.value = true;
|
||||
},
|
||||
() => {
|
||||
hiddenLeftSidebar.value = false;
|
||||
}
|
||||
);
|
||||
matchMedia(
|
||||
"536",
|
||||
() => {
|
||||
simpleMode.value = true;
|
||||
},
|
||||
() => {
|
||||
simpleMode.value = false;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const toggleLeftSidebar = () => {
|
||||
hiddenLeftSidebar.value = !hiddenLeftSidebar.value;
|
||||
};
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
|
||||
onMounted(() => {
|
||||
handleResize();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener("resize", handleResize);
|
||||
});
|
||||
return { hiddenLeftSidebar, toggleLeftSidebar, simpleMode };
|
||||
});
|
||||
@@ -35,6 +35,7 @@ export const matchMedia = (
|
||||
}
|
||||
};
|
||||
|
||||
/** 获取视窗宽度 */
|
||||
export const useWindowWidth = () => {
|
||||
const width = ref(window.innerWidth);
|
||||
|
||||
|
||||
@@ -10,14 +10,15 @@ import {
|
||||
} from "@/assets/Icons";
|
||||
import UserAvatar from "@/assets/user_avatar.jpg";
|
||||
import markdown from "@/components/markdown.vue";
|
||||
import { useAsrStore, useChatStore } from "@/stores";
|
||||
import { useAsrStore, useChatStore, useLayoutStore } from "@/stores";
|
||||
|
||||
const chatStore = useChatStore();
|
||||
const asrStore = useAsrStore();
|
||||
|
||||
const { historyMessages, completing, modelList, modelInfo } =
|
||||
storeToRefs(chatStore);
|
||||
const asrStore = useAsrStore();
|
||||
const { isRecording } = storeToRefs(asrStore);
|
||||
const layoutStore = useLayoutStore();
|
||||
const { hiddenLeftSidebar, simpleMode } = storeToRefs(layoutStore);
|
||||
|
||||
const inputData = ref("");
|
||||
const scrollbarRef = ref<HTMLElement | null>(null);
|
||||
@@ -93,7 +94,8 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="p-8 !pr-4 h-full w-full flex flex-col gap-4 border-l-[24px] border-l-[#FAFAFA] text-base"
|
||||
class="p-8 !pr-4 h-full w-full flex flex-col gap-4 border-l-[24px] border-l-[#FAFAFA] transition-all ease-in-out text-base"
|
||||
:class="{ '!border-l-0': hiddenLeftSidebar || simpleMode }"
|
||||
>
|
||||
<!-- 历史消息区 -->
|
||||
<NScrollbar ref="scrollbarRef" class="flex-1 pr-4 relative">
|
||||
@@ -182,16 +184,28 @@ onMounted(() => {
|
||||
</template>
|
||||
<template #trigger>
|
||||
<NButton :disabled="isRecording || completing" type="warning">
|
||||
清除历史
|
||||
<TrashIcon class="!w-4 !h-4 ml-1" />
|
||||
<template v-if="!simpleMode">清除历史</template>
|
||||
<TrashIcon
|
||||
class="!w-4 !h-4"
|
||||
:class="{
|
||||
'ml-1': !simpleMode
|
||||
}"
|
||||
/>
|
||||
</NButton>
|
||||
</template>
|
||||
<span>确定要清除历史消息吗?</span>
|
||||
</NPopconfirm>
|
||||
|
||||
<NButton :disabled="completing" @click="toggleRecording">
|
||||
<template v-if="!simpleMode">
|
||||
{{ isRecording ? "停止输入" : "语音输入" }}
|
||||
<microphone class="!w-4 !h-4 ml-1" />
|
||||
</template>
|
||||
<microphone
|
||||
class="!w-4 !h-4"
|
||||
:class="{
|
||||
'ml-1': !simpleMode
|
||||
}"
|
||||
/>
|
||||
</NButton>
|
||||
<NButton
|
||||
:disabled="isRecording"
|
||||
|
||||
Reference in New Issue
Block a user