1
1
<script setup lang="ts">
2
- import { reactive , ref , onMounted , defineAsyncComponent } from ' vue' ;
2
+ import { reactive , ref , onMounted , createVNode } from ' vue' ;
3
3
import { Message , MessageStatus } from ' ./interfaces/message'
4
4
import MessageItem from ' ./Message.vue'
5
5
import { getMessagesAPI , createMessageAPI , upscaleMessageAPI } from ' ./api/midjourney'
6
- import { sendMessage , createWebsocket } from ' ./utils/websocket'
7
- import { useDebounceFn } from ' @vueuse/core'
6
+ import { createWebsocket } from ' ./utils/websocket'
7
+ import { useDebounceFn , } from ' @vueuse/core'
8
8
import Toast from ' ./components/Toast/index'
9
9
import UseModal from ' ./components/Use-Modal/index.vue'
10
10
import SettingsModal from ' ./components/Settings-Modal/index.vue'
11
11
import { showModal } from ' ./components/Modal' ;
12
- import { drawStyles , randomPrompt , getJointPrompt , showLoginModal } from ' ./utils/index'
12
+ import { drawStyles , randomPrompt , getJointPrompt } from ' ./utils/index'
13
13
import { useLimitHook } from ' @/hooks/use-limit-hook' ;
14
+ import { userStorage } from ' @/utils/storage' ;
15
+ import { useUser } from ' @/hooks/use-user'
16
+ import GroupModal from ' @/components/Group-Modal/index.vue'
14
17
18
+
19
+ const { isLogin, showLoginModal, userLogout } = useUser ()
15
20
const showUseModal = () => {
16
21
showModal (UseModal , {
17
22
title: " 使用说明"
@@ -20,17 +25,12 @@ const showUseModal = () => {
20
25
21
26
const showSettingsModal = () => {
22
27
showModal (SettingsModal , {
23
- title: " 设置"
28
+ title: " 设置" ,
29
+ closeOnClickModal: true
24
30
})
25
31
}
32
+
26
33
createWebsocket ({
27
- onMessage(data ) {
28
- // console.log('message event: ', event)
29
- console .log (' message event: ' , data )
30
- },
31
- onOnLine(data ) {
32
- console .log (' online data: ' , data )
33
- },
34
34
onTaskUpdate(data : Message ) {
35
35
console .log (' taskupdate data: ' , data )
36
36
const { id } = data
@@ -46,11 +46,13 @@ const data = reactive({
46
46
messages: [],
47
47
pageNum: 1 ,
48
48
pageSize: 5 ,
49
+ initLoading: true ,
49
50
loading: false ,
50
51
loaded: false ,
51
52
useModalVisible: false ,
52
53
styles: [... drawStyles ],
53
- currentStyle: ' '
54
+ currentStyle: ' ' ,
55
+ onlyCurrentUser: false
54
56
})
55
57
56
58
const findOneAndUpdate = (id : number , msgData : Partial <Message >) => {
@@ -80,15 +82,12 @@ const getList = (params: any) => {
80
82
return new Promise ((resolve , reject ) => {
81
83
if (data .loading || data .loaded ) return
82
84
getMessagesAPI (params ).then ((resData ) => {
83
- // data.messages = resData as any;
84
- // ((resData || [] as any) as []).reverse();
85
- // data.messages = [...resData as any, ...data.messages];
86
-
87
85
data .messages = data .messages .concat (resData )
88
86
89
87
data .loaded = ! resData || ! (resData as any ).length
90
88
}).finally (() => {
91
89
data .loading = false
90
+ data .initLoading = false
92
91
resolve (undefined )
93
92
})
94
93
})
@@ -111,6 +110,9 @@ const sendPrompt = async () => {
111
110
}, 2000 )
112
111
return
113
112
}
113
+ if (data .prompt .length > 500 ) {
114
+ return Toast ({ value: " 描述过长,最多500个字符,包括标点符号" })
115
+ }
114
116
const newPmt = getJointPrompt (data .prompt )
115
117
const msgId = await createMessageAPI (newPmt ) as any ;
116
118
console .log (" msgId: " , msgId )
@@ -121,11 +123,11 @@ const sendPrompt = async () => {
121
123
id: msgId ,
122
124
status: MessageStatus .INIT
123
125
}
124
-
126
+
125
127
data .messages .unshift (msgObj )
126
128
data .prompt = ' '
127
129
recordTimeUse ()
128
- scrollToBottom ()
130
+ // scrollToBottom()
129
131
}
130
132
131
133
const onUpscale = async (msg : Message ) => {
@@ -155,7 +157,7 @@ const onUpscale = async (msg: Message) => {
155
157
const scrollToBottom = () => {
156
158
setTimeout (() => {
157
159
if (contentWrap .value ) {
158
- contentWrap .value .scrollTop = contentWrap .value .scrollHeight
160
+ // contentWrap.value.scrollTop = contentWrap.value.scrollHeight
159
161
}
160
162
})
161
163
}
@@ -173,8 +175,42 @@ const helpThink = () => {
173
175
data .prompt = p
174
176
}
175
177
178
+ const onlyForMe = () => {
179
+ setTimeout (() => {
180
+ const user = userStorage .get ();
181
+ const isForUser = data .onlyCurrentUser
182
+ const queries: any = {
183
+ pageNum: 1 ,
184
+ pageSize: data .pageSize ,
185
+ }
186
+ if (isForUser ) {
187
+ if (! user ) {
188
+ data .onlyCurrentUser = false ;
189
+ return showLoginModal ()
190
+ }
191
+ if (user && user .username ) {
192
+ queries .username = user .username
193
+ }
194
+ }
195
+ data .loaded = false
196
+ data .initLoading = true ;
197
+ data .messages = []
198
+ data .pageNum = 1
199
+ getList (queries )
200
+ data .loading = true
201
+ })
202
+ }
203
+
204
+ const showGroupModal = () => {
205
+ showModal (GroupModal , {
206
+ closeOnClickModal: true ,
207
+ closeOnPressEscape: true
208
+ })
209
+ }
210
+
176
211
onMounted (() => {
177
212
getList ({ pageNum: 1 , pageSize: data .pageSize }).finally (() => {
213
+ data .initLoading = false
178
214
setTimeout (() => {
179
215
contentWrap .value .addEventListener (' scroll' , onContentWrapScroll )
180
216
scrollToBottom ()
@@ -191,34 +227,37 @@ onMounted(() => {
191
227
<template >
192
228
<!-- <div class="h-full w-full max-sm:py-0 bg-gray-600" v-loading:[title]="true"> -->
193
229
<div class =" h-full w-full max-sm:py-0 bg-gray-600" >
194
- <div class =" relative h-full max-w-[980px] bg-gray-700 m-auto text-white px-10 py-4 sm:py-0 max-sm:py-2 max-sm:px-4 rounded-none" >
195
- <div id =" contentWrap" ref =" contentWrap" class =" h-[calc(100%-150px)] overflow-auto m-auto flex flex-col-reverse" >
230
+ <div
231
+ class =" relative h-full max-w-[980px] bg-gray-700 m-auto text-white px-10 py-4 sm:py-0 max-sm:py-2 max-sm:px-4 rounded-none" >
232
+ <div v-loading =" data.initLoading" id =" contentWrap" ref =" contentWrap"
233
+ class =" h-[calc(100%-150px)] overflow-auto m-auto flex flex-col-reverse" >
196
234
<div class =" border-b-2 border-purple-400" v-for =" (item, index) in data.messages" :key =" item.id" >
197
235
<MessageItem :key =" item.id" :message =" item" @on-upscale =" onUpscale" />
198
236
</div >
199
237
</div >
200
- <div class =" absolute left-10 right-10 max-sm:left-2 max-sm:right-2 bottom-4 max-sm:bottom-2 flex-row items-center justify-between px-2 py-2 bg-gray-100 border-gray-400 rounded-[4px]" >
238
+ <div
239
+ class =" absolute left-10 right-10 max-sm:left-2 max-sm:right-2 bottom-4 max-sm:bottom-2 flex-row items-center justify-between px-2 py-2 bg-gray-100 border-gray-400 rounded-[4px]" >
201
240
<!-- 快捷/帮助区域 -->
202
- <div class =" flex w-full px-2 pb-2 pt-1 text-md select-none" >
203
- <p class =" underline text-orange-400 pr-4 cursor-pointer" @click.stop =" helpThink" >帮我想一个</p >
204
- <p class =" underline text-orange-400 pr-4 cursor-pointer" @click.stop =" showSettingsModal" >设置参数</p >
205
- <p class =" underline text-orange-400 pr-4 cursor-pointer" @click.stop =" showSettingsModal" >设置风格</p >
241
+ <div class =" flex w-full px-2 pb-2 pt-1 text-md select-none flex-wrap" >
242
+ <p class =" underline text-orange-400 pr-4 cursor-pointer max-sm:text-sm" @click.stop =" helpThink" >想一个</p >
243
+ <p class =" underline text-orange-400 pr-4 cursor-pointer max-sm:text-sm" @click.stop =" showSettingsModal" >设置</p >
244
+ <!-- <p class="underline text-orange-400 pr-4 cursor-pointer" @click.stop="showSettingsModal">设置风格</p> -->
245
+ <p class =" underline text-orange-400 cursor-pointer max-sm:text-sm" @click.stop =" showUseModal" >使用说明</p >
246
+ <p class =" underline text-orange-400 pr-4 ml-4 max-sm:text-sm" @click.stop =" onlyForMe" >
247
+ <input id =" onlyMe" v-model =" data.onlyCurrentUser" type =" checkbox" class =" cursor-pointer" >
248
+ <label for =" onlyMe" class =" cursor-pointer" >只看自己</label >
249
+ </p >
206
250
<p class =" flex-1" ></p >
207
- <p class =" underline text-orange-400 pr-4 cursor-pointer font-bold " @click.stop = " showLoginModal " >登录/注册 </p >
208
- <p class =" underline text-orange-400 pr-4 cursor-pointer" >微信交流群 </p >
209
- <p class =" underline text-orange-400 cursor-pointer" @click.stop =" showUseModal " >使用说明 </p >
210
- </div >
251
+ <p class =" underline text-orange-400 pr-4 cursor-pointer max-sm:text-sm " @click = " showGroupModal " >交流群 </p >
252
+ <p v-if = " !isLogin " class =" underline text-orange-400 pr-4 cursor-pointer font-bold max-sm:text-sm " @click.stop = " showLoginModal " >登录/注册 </p >
253
+ <p v-if = " isLogin " class =" underline text-orange-400 pr-4 cursor-pointer max-sm:text-sm " @click.stop =" userLogout " >退出 </p >
254
+ </div >
211
255
<!-- 输入框 -->
212
256
<div class =" w-full bg-white flex items-center" >
213
- <textarea
214
- v-model =" data.prompt"
215
- class =" flex-1 px-4 py-2 resize-none rounded-[8px] outline-none max-sm:text-sm text-md text-gray-500"
216
- autofocus
217
- placeholder =" 输入图片描述,例如'可爱的橘黄色的猫咪, 迪士尼风格'、'海边,机器人,小女孩,吉卜力风格'等"
218
- type =" textarea"
219
- :rows =" 2"
220
- @keydown.enter.prevent.stop =" onKeyDown"
221
- />
257
+ <textarea v-model =" data.prompt"
258
+ class =" flex-1 px-4 py-2 resize-none rounded-[8px] outline-none max-sm:text-sm text-md text-gray-500" autofocus
259
+ placeholder =" 输入图片描述,例如'可爱的橘黄色的猫咪, 迪士尼风格'、'海边,机器人,小女孩,吉卜力风格'等" type =" textarea" :rows =" 2"
260
+ @keydown.enter.prevent.stop =" onKeyDown" />
222
261
<img @click =" onClickSend" class =" mx-4 w-[36px] h-[36px] cursor-pointer" src =" /src/assets/send.png" alt =" " >
223
262
</div >
224
263
</div >
0 commit comments