mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-27 07:16:19 +09:00
feat: dark mode
This commit is contained in:
@@ -4,17 +4,30 @@ import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuTrigger
|
||||
} from '@memoh/ui'
|
||||
import SvgIcon from '@jamescoyle/vue-icon'
|
||||
import { mdiTranslate } from '@mdi/js'
|
||||
import { mdiTranslate, mdiBrightness6 } from '@mdi/js'
|
||||
import { useColorMode } from '@vueuse/core'
|
||||
|
||||
const mode = useColorMode()
|
||||
const modeToggleMap:Record<'dark'|'light','dark'|'light'> = {
|
||||
dark: 'light',
|
||||
light:'dark'
|
||||
}
|
||||
console.log(mode.value)
|
||||
const toggleMode = () => {
|
||||
if (mode.value !== 'auto') {
|
||||
mode.value = modeToggleMap[mode.value]
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<div
|
||||
class="fixed top-8 right-2 z-9999 [&:is(:has([data-state=open]))_.translate-icon]:opacity-100"
|
||||
class="fixed top-0 flex right-8 z-9999 [&:is(:has([data-state=open]))_.translate-icon]:opacity-100 align h-16 items-center"
|
||||
>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger class="ml-auto mr-4 cursor-pointer">
|
||||
@@ -33,6 +46,13 @@ import { mdiTranslate } from '@mdi/js'
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
<svg-icon
|
||||
type="mdi"
|
||||
:path="mdiBrightness6"
|
||||
class="translate-icon opacity-30 hover:opacity-100 cursor-pointer"
|
||||
@click="toggleMode"
|
||||
/>
|
||||
</div>
|
||||
<RouterView />
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="flex gap-4 items-start">
|
||||
<div class=" p-2 rounded-full bg-[#F9F9F9]">
|
||||
<div class=" p-2 rounded-full bg-[#F9F9F9] dark:bg-[#666] ">
|
||||
<svg-icon
|
||||
type="mdi"
|
||||
:path="mdiRobotOutline"
|
||||
@@ -12,11 +12,59 @@
|
||||
</sup>
|
||||
<p class="leading-7 text-muted-foreground break-all">
|
||||
<template v-if="robotSay.state==='thinking'">
|
||||
<img
|
||||
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48Y2lyY2xlIGN4PSI0IiBjeT0iMTIiIHI9IjMiIGZpbGw9ImN1cnJlbnRDb2xvciI+PGFuaW1hdGUgaWQ9IlNWRzlJZ2JSYnNsIiBhdHRyaWJ1dGVOYW1lPSJyIiBiZWdpbj0iMDtTVkdGVU5wQ1dkRy5lbmQtMC4yNXMiIGR1cj0iMC43NXMiIHZhbHVlcz0iMzsuMjszIi8+PC9jaXJjbGU+PGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iMyIgZmlsbD0iY3VycmVudENvbG9yIj48YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiBiZWdpbj0iU1ZHOUlnYlJic2wuZW5kLTAuNnMiIGR1cj0iMC43NXMiIHZhbHVlcz0iMzsuMjszIi8+PC9jaXJjbGU+PGNpcmNsZSBjeD0iMjAiIGN5PSIxMiIgcj0iMyIgZmlsbD0iY3VycmVudENvbG9yIj48YW5pbWF0ZSBpZD0iU1ZHRlVOcENXZEciIGF0dHJpYnV0ZU5hbWU9InIiIGJlZ2luPSJTVkc5SWdiUmJzbC5lbmQtMC40NXMiIGR1cj0iMC43NXMiIHZhbHVlcz0iMzsuMjszIi8+PC9jaXJjbGU+PC9zdmc+"
|
||||
class="inline"
|
||||
alt="thinking"
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle
|
||||
cx="4"
|
||||
cy="12"
|
||||
r="3"
|
||||
fill="currentColor"
|
||||
>
|
||||
<animate
|
||||
id="SVG7x14Dcom"
|
||||
fill="freeze"
|
||||
attributeName="opacity"
|
||||
begin="0;SVGqSjG0dUp.end-0.25s"
|
||||
dur="0.75s"
|
||||
values="1;0.2"
|
||||
/>
|
||||
</circle>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="3"
|
||||
fill="currentColor"
|
||||
opacity="0.4"
|
||||
>
|
||||
<animate
|
||||
fill="freeze"
|
||||
attributeName="opacity"
|
||||
begin="SVG7x14Dcom.begin+0.15s"
|
||||
dur="0.75s"
|
||||
values="1;0.2"
|
||||
/>
|
||||
</circle>
|
||||
<circle
|
||||
cx="20"
|
||||
cy="12"
|
||||
r="3"
|
||||
fill="currentColor"
|
||||
opacity="0.3"
|
||||
>
|
||||
<animate
|
||||
id="SVGqSjG0dUp"
|
||||
fill="freeze"
|
||||
attributeName="opacity"
|
||||
begin="SVG7x14Dcom.begin+0.3s"
|
||||
dur="0.75s"
|
||||
values="1;0.2"
|
||||
/>
|
||||
</circle>
|
||||
</svg>
|
||||
</template>
|
||||
<template v-else>
|
||||
<MarkdownRender
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<p
|
||||
class="leading-7 not-first:mt-6 max-w-[90%] ml-auto text-muted-foreground bg-[#F9F9F9] p-4 rounded-xl rounded-tr-none break-all
|
||||
class="leading-7 not-first:mt-6 max-w-[90%] ml-auto text-muted-foreground bg-[#F9F9F9] p-4 rounded-xl rounded-tr-none break-all dark:bg-[#1C1917]
|
||||
"
|
||||
>
|
||||
{{ userSay.description }}
|
||||
|
||||
@@ -22,13 +22,14 @@
|
||||
<script setup lang="ts">
|
||||
import UserChat from './UserChat/index.vue'
|
||||
import RobotChat from './RobotChat/index.vue'
|
||||
import { inject, ref, watch } from 'vue'
|
||||
import { inject, nextTick, ref, watch } from 'vue'
|
||||
import { useElementBounding } from '@vueuse/core'
|
||||
import { useChatList } from '@/store/ChatList'
|
||||
import { onBeforeRouteLeave } from 'vue-router'
|
||||
import { storeToRefs } from 'pinia'
|
||||
// 模拟一下数据
|
||||
const {chatList,add} = useChatList()
|
||||
|
||||
const { loading}=storeToRefs(useChatList())
|
||||
const chatSay = inject('chatSay', ref(''))
|
||||
// 模拟一下对话
|
||||
watch(chatSay, () => {
|
||||
@@ -80,13 +81,17 @@ watch(height, (newVal,oldVal) => {
|
||||
}
|
||||
prevScroll = curScroll
|
||||
}
|
||||
|
||||
if (oldVal === 0 && newVal > container.clientHeight) {
|
||||
container.scrollTo({
|
||||
top: cacheScroll,
|
||||
})
|
||||
nextTick(() => {
|
||||
container.scrollTo({
|
||||
top: cacheScroll,
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!(container && (container?.scrollHeight - container.clientHeight - container.scrollTop) < 1)&&autoScroll) {
|
||||
if (!(container && (container?.scrollHeight - container.clientHeight - container.scrollTop) < 1) && autoScroll&&loading.value) {
|
||||
|
||||
container.scrollTo({
|
||||
top: container?.scrollHeight - container.clientHeight,
|
||||
behavior: 'smooth',
|
||||
@@ -94,12 +99,13 @@ watch(height, (newVal,oldVal) => {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
onBeforeRouteLeave(() => {
|
||||
const container = displayContainer.value?.parentElement?.parentElement
|
||||
if (container) {
|
||||
cacheScroll = container.scrollTop
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
@@ -53,15 +53,15 @@ import {
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
Separator,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
// DropdownMenu,
|
||||
// DropdownMenuContent,
|
||||
// DropdownMenuItem,
|
||||
// DropdownMenuTrigger,
|
||||
} from '@memoh/ui'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { computed } from 'vue'
|
||||
import SvgIcon from '@jamescoyle/vue-icon'
|
||||
import { mdiTranslate } from '@mdi/js'
|
||||
// import SvgIcon from '@jamescoyle/vue-icon'
|
||||
// import { mdiTranslate } from '@mdi/js'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
|
||||
@@ -98,11 +98,11 @@ const sidebarInfo = computed(() => [
|
||||
name: 'chat',
|
||||
icon: mdiChatOutline
|
||||
},
|
||||
{
|
||||
title: t('slidebar.home'),
|
||||
name: 'home',
|
||||
icon: mdiHome
|
||||
},
|
||||
// {
|
||||
// title: t('slidebar.home'),
|
||||
// name: 'home',
|
||||
// icon: mdiHome
|
||||
// },
|
||||
{
|
||||
title: t('slidebar.model_setting'),
|
||||
name: 'models',
|
||||
|
||||
Reference in New Issue
Block a user