Compare commits

4 Commits

Author SHA1 Message Date
ChenZhaoYu
6216d84ecd chore: v2.4.1 2023-02-18 09:59:39 +08:00
Void
ea887ad755 输入框修改为富文本,支持换行 (#53)
* add Dockerfile

* update Readme.md

* Fixed : Docker log file

* Update vite.config.ts

* chore: code merge, update README.md

* chore: update GitHub workflow

* fix: 输入框修改为富文本,支持换行

* chore: 更新.gitignore

* Update index.vue

---------

Co-authored-by: Redon <790348264@qq.com>
2023-02-18 09:56:13 +08:00
Redon
c98a2a3cb8 feat: 移动端样式修复 (#56)
* feat: 移动端优化

* feat: 部份移动端问题修复
2023-02-18 09:25:57 +08:00
ChenZhaoYu
06f41c3758 chore: 更新封面 2023-02-17 11:10:17 +08:00
11 changed files with 75 additions and 34 deletions

View File

@@ -1,3 +1,11 @@
## v2.4.1
`2023-02-18`
### Enhancement
- 调整部份移动端上的样式
- 输入框支持换行
## v2.4.0
`2023-02-17`
@@ -6,6 +14,7 @@
- 响应式支持移动端
### Enhancement
- 修改部份描述错误
## v2.3.3
`2023-02-16`

View File

@@ -2,9 +2,7 @@
使用 express 和 vue3 搭建的 ChartGPT 演示网页
![PC](./docs/c1.png)
![Mobile](./docs/c2.png)
![PC](./docs/cover.png)
> 提示:目前 `OpenAI` 开放的模型最高只有 `GPT-3`,和现在网页所使用的 `GPT-3.5` 或 `GPT-4` 有很大差距,需要等官方开放最新的模型接口。
@@ -80,26 +78,7 @@ pnpm dev
```
## 打包
### 后端服务
> 如果你不需要本项目的 `node` 接口,可以省略如下操作
复制 `service` 文件夹到你有 `node` 服务环境的服务器上。(搜索关键字:`express部署`
```shell
# 安装
pnpm install
# 打包
pnpm build
# 运行
pnpm prod
```
PS: 不进行打包,直接在服务器上运行 `pnpm start` 也可
## Docker build & run
## Docker build
[参考信息](https://github.com/Chanzhaoyu/chatgpt-web/pull/42)
@@ -123,8 +102,25 @@ services:
OPENAI_API_KEY: xxxxxx
```
### 后端服务
> 如果你不需要本项目的 `node` 接口,可以省略如下操作
### 网页
复制 `service` 文件夹到你有 `node` 服务环境的服务器上。(搜索关键字:`express部署`
```shell
# 安装
pnpm install
# 打包
pnpm build
# 运行
pnpm prod
```
PS: 不进行打包,直接在服务器上运行 `pnpm start` 也可
### 前端打包
根目录下运行以下命令,然后将 `dist` 文件夹复制到你的托管服务器上

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

BIN
docs/cover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -1,6 +1,6 @@
{
"name": "chatgpt-web",
"version": "2.4.0",
"version": "2.4.1",
"private": false,
"description": "ChatGPT Web",
"author": "ChenZhaoYu <chenzhaoyu1994@gmail.com>",

View File

@@ -8,6 +8,7 @@ import { useChat } from './hooks/useChat'
import { fetchChatAPI } from '@/api'
import { HoverButton, SvgIcon } from '@/components/common'
import { useHistoryStore } from '@/store'
import { useBasicLayout } from '@/hooks/useBasicLayout'
let controller = new AbortController()
@@ -15,6 +16,8 @@ const ms = useMessage()
const historyStore = useHistoryStore()
const { isMobile } = useBasicLayout()
let messageReactive: MessageReactive | null = null
const scrollRef = ref<HTMLDivElement>()
@@ -30,6 +33,12 @@ const heartbeat = computed(() => historyStore.heartbeat)
const list = computed<Chat.Chat[]>(() => historyStore.getCurrentChat)
const chatList = computed<Chat.Chat[]>(() => list.value.filter(item => (!item.reversal && !item.error)))
const footerMobileStyle = computed(() => {
if (isMobile.value)
return ['pl-2', 'pt-2', 'pb-6', 'fixed', 'bottom-0', 'left-0', 'right-0', 'z-30']
return []
})
async function handleSubmit() {
if (loading.value)
return
@@ -69,8 +78,10 @@ async function handleSubmit() {
}
function handleEnter(event: KeyboardEvent) {
if (event.key === 'Enter')
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault()
handleSubmit()
}
}
function addMessage(
@@ -143,7 +154,11 @@ watch(
<Layout>
<div class="flex flex-col h-full">
<main class="flex-1 overflow-hidden">
<div ref="scrollRef" class="h-full p-4 overflow-hidden overflow-y-auto">
<div
ref="scrollRef"
class="h-full p-4 overflow-hidden overflow-y-auto"
:class="[{ 'p-2': isMobile }]"
>
<template v-if="!list.length">
<div class="flex items-center justify-center mt-4 text-center text-neutral-300">
<SvgIcon icon="ri:bubble-chart-fill" class="mr-2 text-3xl" />
@@ -153,21 +168,34 @@ watch(
<template v-else>
<div>
<Message
v-for="(item, index) of list" :key="index" :date-time="item.dateTime" :message="item.message"
:reversal="item.reversal" :error="item.error"
v-for="(item, index) of list"
:key="index"
:date-time="item.dateTime"
:message="item.message"
:reversal="item.reversal"
:error="item.error"
/>
</div>
</template>
</div>
</main>
<footer class="p-4">
<footer
class="p-4"
:class="footerMobileStyle"
>
<div class="flex items-center justify-between space-x-2">
<HoverButton tooltip="Clear conversations">
<span class="text-xl text-[#4f555e]" @click="handleClear">
<SvgIcon icon="ri:delete-bin-line" />
</span>
</HoverButton>
<NInput v-model:value="prompt" placeholder="Type a message..." @keypress="handleEnter" />
<NInput
v-model:value="prompt"
type="textarea"
:autosize="{ minRows: 1, maxRows: 2 }"
placeholder="Ask me anything..."
@keypress="handleEnter"
/>
<NButton type="primary" :disabled="loading" @click="handleSubmit">
<template #icon>
<SvgIcon icon="ri:send-plane-fill" />

View File

@@ -22,13 +22,14 @@ const getContainerClass = computed(() => {
return [
'h-full',
{ 'pt-14': isMobile.value },
{ 'pb-[70px]': isMobile.value },
{ 'pl-[260px]': !isMobile.value && !collapsed.value },
]
})
</script>
<template>
<div class="h-screen p-4" :class="[{ 'p-0': isMobile }]">
<div class="h-screen" :class="[isMobile ? 'p-0' : 'p-4']">
<div class="h-full overflow-hidden" :class="getMobileClass">
<NLayout class="z-40 transition" :class="getContainerClass" has-sider>
<Sider />

View File

@@ -23,7 +23,7 @@ function handleUpdateCollapsed() {
<template>
<header class="fixed top-0 left-0 right-0 z-50 border-b bg-white/80 backdrop-blur">
<div class="relative flex items-center justify-between px-4 h-14">
<div class="relative flex items-center justify-between h-14">
<button class="flex items-center justify-center w-11 h-11" @click="handleUpdateCollapsed">
<SvgIcon v-if="collapsed" class="text-2xl" icon="ri:align-justify" />
<SvgIcon v-else class="text-2xl" icon="ri:align-right" />

View File

@@ -29,7 +29,10 @@ watch(
(val) => {
appStore.setSiderCollapsed(val)
},
{ flush: 'post' },
{
immediate: true,
flush: 'post',
},
)
</script>
@@ -42,6 +45,7 @@ watch(
collapse-mode="transform"
position="absolute"
bordered
style="z-index: 50;"
@update-collapsed="handleUpdateCollapsed"
>
<div class="flex flex-col h-full" :class="[{ 'pt-14': isMobile }]">
@@ -63,4 +67,7 @@ watch(
</footer>
</div>
</NLayoutSider>
<template v-if="isMobile">
<div v-show="!collapsed" class="absolute inset-0 z-40 bg-black/40" @click="handleUpdateCollapsed" />
</template>
</template>