@@ -5,8 +5,21 @@ import MessageItem from './Message.vue'
5
5
import { getMessagesAPI , createMessageAPI , upscaleMessageAPI } from ' ./api/midjourney'
6
6
import { sendMessage , createWebsocket } from ' ./utils/websocket'
7
7
import { useDebounceFn } from ' @vueuse/core'
8
+ import Toast from ' ./components/Toast/index'
9
+ import UseModal from ' ./components/Use-Modal/index.vue'
10
+ import SettingsModal from ' ./components/Settings-Modal/index.vue'
11
+ import { showModal } from ' ./components/Modal' ;
12
+ import { drawStyles , randomPrompt , getJointPrompt } from ' ./utils/index'
8
13
9
- const ws = createWebsocket ({
14
+
15
+ const showUseModal = () => {
16
+ showModal (UseModal )
17
+ }
18
+
19
+ const showSettingsModal = () => {
20
+ showModal (SettingsModal )
21
+ }
22
+ createWebsocket ({
10
23
onMessage(data ) {
11
24
// console.log('message event: ', event)
12
25
console .log (' message event: ' , data )
@@ -24,20 +37,16 @@ const ws = createWebsocket({
24
37
}
25
38
})
26
39
const contentWrap = ref <HTMLDivElement >()
27
- const data = reactive <{
28
- messages: Message [],
29
- prompt: string ,
30
- pageNum: number ,
31
- pageSize: number ,
32
- loading: boolean ,
33
- loaded: boolean
34
- }>({
40
+ const data = reactive ({
35
41
prompt: ' ' ,
36
42
messages: [],
37
43
pageNum: 1 ,
38
44
pageSize: 5 ,
39
45
loading: false ,
40
- loaded: false
46
+ loaded: false ,
47
+ useModalVisible: false ,
48
+ styles: [... drawStyles ],
49
+ currentStyle: ' '
41
50
})
42
51
43
52
const findOneAndUpdate = (id : number , msgData : Partial <Message >) => {
@@ -55,38 +64,51 @@ const onClickSend = () => {
55
64
}
56
65
57
66
const onKeyDown = useDebounceFn ((event : Event ) => {
67
+ if (! data .prompt ) {
68
+ Toast ({
69
+ value: ' 描述不能为空'
70
+ })
71
+ return
72
+ }
58
73
event .stopPropagation ()
59
74
event .preventDefault ()
60
75
sendPrompt ()
61
76
})
62
77
63
78
const getList = (params : any ) => {
64
- if (data .loading || data .loaded ) return
65
- getMessagesAPI (params ).then ((resData ) => {
66
- // data.messages = resData as any;
67
- ((resData || [] as any ) as []).reverse ();
68
- data .messages = [... resData as any , ... data .messages ];
69
- data .loaded = ! resData || ! (resData as any ).length
70
- scrollToBottom ()
71
- }).finally (() => {
72
- data .loading = false
79
+ return new Promise ((resolve , reject ) => {
80
+ if (data .loading || data .loaded ) return
81
+ getMessagesAPI (params ).then ((resData ) => {
82
+ // data.messages = resData as any;
83
+ // ((resData || [] as any) as []).reverse();
84
+ // data.messages = [...resData as any, ...data.messages];
85
+
86
+ data .messages = data .messages .concat (resData )
87
+
88
+ data .loaded = ! resData || ! (resData as any ).length
89
+ }).finally (() => {
90
+ data .loading = false
91
+ resolve (undefined )
92
+ })
73
93
})
74
94
}
75
95
76
96
const sendPrompt = async () => {
77
97
data .prompt = data .prompt .trim ()
78
98
if (! data .prompt ) return
79
- const msgId = await createMessageAPI (data .prompt ) as any ;
99
+ const newPmt = getJointPrompt (data .prompt )
100
+ const msgId = await createMessageAPI (newPmt ) as any ;
80
101
console .log (" msgId: " , msgId )
81
102
const msgObj: Message = {
82
- prompt: data . prompt ,
103
+ prompt: newPmt ,
83
104
createTime: Date .now (),
84
105
uri: " " ,
85
106
id: msgId ,
86
107
status: MessageStatus .INIT
87
108
}
88
109
89
- data .messages .push (msgObj )
110
+ // data.messages.push(msgObj)
111
+ data .messages .unshift (msgObj )
90
112
data .prompt = ' '
91
113
scrollToBottom ()
92
114
}
@@ -97,7 +119,6 @@ const onUpscale = async (msg: Message) => {
97
119
if (! msgHash || ! msgId || ! index || ! prompt ) {
98
120
return console .log (' upscale消息体不完整' )
99
121
}
100
-
101
122
const newId = await upscaleMessageAPI ({
102
123
prompt ,
103
124
index ,
@@ -111,7 +132,8 @@ const onUpscale = async (msg: Message) => {
111
132
index ,
112
133
status: MessageStatus .INIT ,
113
134
}
114
- data .messages .push (newMsg )
135
+ // data.messages.push(newMsg)
136
+ data .messages .unshift (newMsg )
115
137
scrollToBottom ()
116
138
}
117
139
@@ -123,19 +145,25 @@ const scrollToBottom = () => {
123
145
})
124
146
}
125
147
126
- const onContentWrapScroll = (event : Event ) => {
148
+ const onContentWrapScroll = useDebounceFn ( (event : Event ) => {
127
149
if (data .loading || data .loaded ) return
128
150
const el = contentWrap .value
129
151
if (el .scrollTop <= 100 ) {
130
152
getList ({ pageNum: ++ data .pageNum , pageSize: data .pageSize })
131
153
}
154
+ }, 500 )
155
+
156
+ const helpThink = () => {
157
+ const p = randomPrompt ()
158
+ data .prompt = p
132
159
}
133
160
134
161
onMounted (() => {
135
- getList ({ pageNum: 1 , pageSize: data .pageSize })
136
- scrollToBottom ()
137
- setTimeout (() => {
138
- contentWrap .value .addEventListener (' scroll' , onContentWrapScroll )
162
+ getList ({ pageNum: 1 , pageSize: data .pageSize }).finally (() => {
163
+ setTimeout (() => {
164
+ contentWrap .value .addEventListener (' scroll' , onContentWrapScroll )
165
+ scrollToBottom ()
166
+ }, 32 )
139
167
})
140
168
141
169
return () => {
@@ -146,27 +174,28 @@ onMounted(() => {
146
174
</script >
147
175
148
176
<template >
149
- <div class =" h-full py-4 max-sm:py-0" >
150
- <div class =" relative h-full max-w-[980px] m-auto bg-gray-600 text-white px-10 py-4 rounded-lg sm:py-0 max-sm:py-2 max-sm:px-4 max-sm: rounded-none" >
151
- <div id =" contentWrap" ref =" contentWrap" class =" h-full pb-[120px] overflow-auto m-auto" >
152
- <div class =" border-b-2 border-purple-400" v-for =" (item, index) in data.messages" :key =" index " >
153
- <MessageItem :message =" item" @on-upscale =" onUpscale" />
177
+ <div class =" h-full w-full max-sm:py-0 bg-gray-600 " >
178
+ <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" >
179
+ <div id =" contentWrap" ref =" contentWrap" class =" h-[calc(100%-150px)] overflow-auto m-auto flex flex-col-reverse " >
180
+ <div class =" border-b-2 border-purple-400" v-for =" (item, index) in data.messages" :key =" item.id " >
181
+ <MessageItem :key = " item.id " : message =" item" @on-upscale =" onUpscale" />
154
182
</div >
155
183
</div >
156
184
<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]" >
157
185
<!-- 快捷/帮助区域 -->
158
- <div class =" flex w-full pb-1 text-sm" >
159
- <p class =" underline text-orange-400 pr-1 cursor-pointer" >垫图</p >
160
- <p class =" underline text-orange-400 pr-1 cursor-pointer" >帮我想一个</p >
186
+ <div class =" flex w-full px-2 pb-2 pt-1 text-md select-none" >
187
+ <p class =" underline text-orange-400 pr-4 cursor-pointer" @click.stop =" helpThink" >帮我想一个</p >
188
+ <p class =" underline text-orange-400 pr-4 cursor-pointer" @click.stop =" showSettingsModal" >设置参数</p >
189
+ <p class =" underline text-orange-400 pr-4 cursor-pointer" @click.stop =" showSettingsModal" >设置风格</p >
161
190
<p class =" flex-1" ></p >
162
- <p class =" underline text-orange-400 pr-1 cursor-pointer" >微信交流群</p >
163
- <p class =" underline text-orange-400 cursor-pointer" >使用说明</p >
164
- </div >
191
+ <p class =" underline text-orange-400 pr-4 cursor-pointer" >微信交流群</p >
192
+ <p class =" underline text-orange-400 cursor-pointer" @click.stop = " showUseModal " >使用说明</p >
193
+ </div >
165
194
<!-- 输入框 -->
166
195
<div class =" w-full bg-white flex items-center" >
167
196
<textarea
168
197
v-model =" data.prompt"
169
- class =" flex-1 px-4 py-2 rounded-[8px] outline-none text-sm text-gray-500"
198
+ class =" flex-1 px-4 py-2 resize-none rounded-[8px] outline-none max-sm: text-sm text-md text-gray-500"
170
199
autofocus
171
200
placeholder =" 输入图片描述,例如'可爱的橘黄色的猫咪, 迪士尼风格'、'海边,机器人,小女孩,吉卜力风格'等"
172
201
type =" textarea"
0 commit comments