feat: 优化文件结构、组件、布局

This commit is contained in:
ChenZhaoYu 2023-02-13 11:59:00 +08:00
parent 72df35c929
commit 39f718ef16
15 changed files with 192 additions and 76 deletions

View File

@ -31,6 +31,7 @@
"OPENAI",
"pinia",
"rushstack",
"Sider",
"tailwindcss",
"unplugin",
"VITE",

View File

@ -1,13 +1,12 @@
<script setup lang="ts">
import { GithubSite, NaiveProvider } from '@/components'
import { NaiveProvider } from '@/components/common'
import Chat from '@/views/Chat/index.vue'
</script>
<template>
<NaiveProvider>
<div class="h-full overflow-hidden pb-[50px] p-4">
<div class="h-full p-4 overflow-hidden">
<Chat />
<GithubSite />
</div>
</NaiveProvider>
</template>

View File

@ -1,27 +0,0 @@
<script setup lang="ts">
import { defineComponent, h } from 'vue'
import { NConfigProvider, NMessageProvider, useMessage } from 'naive-ui'
function registerNaiveTools() {
window.$message = useMessage()
}
const NaiveProviderContent = defineComponent({
name: 'NaiveProviderContent',
setup() {
registerNaiveTools()
},
render() {
return h('div')
},
})
</script>
<template>
<NConfigProvider class="h-full">
<NMessageProvider>
<slot />
<NaiveProviderContent />
</NMessageProvider>
</NConfigProvider>
</template>

View File

@ -0,0 +1,20 @@
<script setup lang='ts'>
interface Emit {
(e: 'click'): void
}
const emit = defineEmits<Emit>()
function handleClick() {
emit('click')
}
</script>
<template>
<button
class="flex items-center justify-center w-10 h-10 transition rounded-full hover:bg-neutral-100"
@click="handleClick"
>
<slot />
</button>
</template>

View File

@ -0,0 +1,46 @@
<script setup lang='ts'>
import { computed } from 'vue'
import type { PopoverPlacement } from 'naive-ui'
import { NTooltip } from 'naive-ui'
import Button from './Button.vue'
interface Props {
tooltip?: string
placement?: PopoverPlacement
}
interface Emit {
(e: 'click'): void
}
const props = withDefaults(defineProps<Props>(), {
tooltip: '',
placement: 'bottom',
})
const emit = defineEmits<Emit>()
const showTooltip = computed(() => Boolean(props.tooltip))
function handleClick() {
emit('click')
}
</script>
<template>
<div v-if="showTooltip">
<NTooltip :placement="placement" trigger="hover">
<template #trigger>
<Button @click="handleClick">
<slot />
</Button>
</template>
{{ tooltip }}
</NTooltip>
</div>
<div v-else>
<Button @click="handleClick">
<slot />
</Button>
</div>
</template>

View File

@ -0,0 +1,46 @@
<script setup lang="ts">
import { defineComponent, h } from 'vue'
import {
NConfigProvider,
NDialogProvider,
NLoadingBarProvider,
NMessageProvider,
NNotificationProvider,
useDialog,
useLoadingBar,
useMessage,
useNotification,
} from 'naive-ui'
function registerNaiveTools() {
window.$loadingBar = useLoadingBar()
window.$dialog = useDialog()
window.$message = useMessage()
window.$notification = useNotification()
}
const NaiveProviderContent = defineComponent({
name: 'NaiveProviderContent',
setup() {
registerNaiveTools()
},
render() {
return h('div')
},
})
</script>
<template>
<NConfigProvider class="h-full">
<NLoadingBarProvider>
<NDialogProvider>
<NNotificationProvider>
<NMessageProvider>
<slot />
<NaiveProviderContent />
</NMessageProvider>
</NNotificationProvider>
</NDialogProvider>
</NLoadingBarProvider>
</NConfigProvider>
</template>

View File

@ -0,0 +1,5 @@
import HoverButton from './HoverButton/index.vue'
import NaiveProvider from './NaiveProvider.vue'
import SvgIcon from './SvgIcon.vue'
export { HoverButton, NaiveProvider, SvgIcon }

View File

@ -0,0 +1,3 @@
import GithubSite from './GithubSite.vue'
export { GithubSite }

View File

@ -1,5 +0,0 @@
import NaiveProvider from './NaiveProvider.vue'
import Icon from './Icon.vue'
import GithubSite from './GithubSite.vue'
export { NaiveProvider, Icon, GithubSite }

View File

@ -1,3 +1,6 @@
interface Window {
$loadingBar?: import('naive-ui').LoadingBarProviderInst;
$dialog?: import('naive-ui').DialogProviderInst;
$message?: import('naive-ui').MessageProviderInst;
$notification?: import('naive-ui').NotificationProviderInst;
}

View File

@ -1,9 +1,10 @@
<script setup lang='ts'>
import { nextTick, onMounted, ref } from 'vue'
import { NButton, NInput, NPopover, useMessage } from 'naive-ui'
import { NButton, NInput, useMessage } from 'naive-ui'
import { Message } from './components'
import { clearChatContext, fetchChatAPI } from './request'
import { Icon } from '@/components'
import { Layout } from './layout'
import { HoverButton, SvgIcon } from '@/components/common'
interface ListProps {
dateTime: string
@ -75,44 +76,38 @@ function addMessage(message: string, reversal = false) {
</script>
<template>
<div class="flex flex-col h-full overflow-hidden border rounded-md shadow-md">
<header class="flex items-center justify-between p-4">
<h1 class="text-xl font-bold">
ChatGPT Web
</h1>
<div>
<NPopover>
<template #trigger>
<button
class="w-[40px] h-[40px] rounded-full hover:bg-neutral-100 transition flex justify-center items-center"
@click="handleClear"
>
<Icon icon="ri:delete-bin-6-line" />
</button>
</template>
<span>Clear Context</span>
</NPopover>
</div>
</header>
<main class="flex-1 overflow-hidden border-y">
<div ref="scrollRef" class="h-full p-4 overflow-hidden overflow-y-auto">
<div>
<Message
v-for="(item, index) of list" :key="index" :date-time="item.dateTime" :message="item.message"
:reversal="item.reversal"
/>
<Layout>
<div class="flex flex-col h-full">
<header class="flex items-center justify-between p-4">
<h1 class="text-xl font-bold">
ChatGPT Web
</h1>
<div class="flex items-center space-x-4">
<HoverButton tooltip="Clear" @click="handleClear">
<SvgIcon icon="ri:delete-bin-6-line" />
</HoverButton>
</div>
</div>
</main>
<footer class="p-4">
<div class="flex items-center justify-between space-x-2">
<NInput v-model:value="prompt" placeholder="Type a message..." @keypress="handleEnter" />
<NButton type="primary" :loading="loading" @click="handleSubmit">
<template #icon>
<Icon icon="ri:send-plane-fill" />
</template>
</NButton>
</div>
</footer>
</div>
</header>
<main class="flex-1 overflow-hidden border-y">
<div ref="scrollRef" class="h-full p-4 overflow-hidden overflow-y-auto">
<div>
<Message
v-for="(item, index) of list" :key="index" :date-time="item.dateTime" :message="item.message"
:reversal="item.reversal"
/>
</div>
</div>
</main>
<footer class="p-4">
<div class="flex items-center justify-between space-x-2">
<NInput v-model:value="prompt" placeholder="Type a message..." @keypress="handleEnter" />
<NButton type="primary" :loading="loading" @click="handleSubmit">
<template #icon>
<SvgIcon icon="ri:send-plane-fill" />
</template>
</NButton>
</div>
</footer>
</div>
</Layout>
</template>

View File

@ -0,0 +1,27 @@
<script setup lang='ts'>
import { NLayout, NLayoutContent, NLayoutSider } from 'naive-ui'
</script>
<template>
<div class="h-full overflow-hidden border rounded-md shadow-md">
<NLayout class="h-full" has-sider>
<NLayoutSider
collapse-mode="width"
:collapsed-width="120"
:width="240"
show-trigger="arrow-circle"
class="p-4"
bordered
>
<span>Sider</span>
</NLayoutSider>
<NLayoutContent class="h-full">
<slot />
</NLayoutContent>
</NLayout>
</div>
</template>
<style>
</style>

View File

@ -0,0 +1,3 @@
import Layout from './Layout.vue'
export { Layout }