@@ -3,10 +3,12 @@ import { useState, useEffect, useMemo, HTMLProps, useRef } from "react";
3
3
import styles from "./settings.module.scss" ;
4
4
5
5
import ResetIcon from "../icons/reload.svg" ;
6
+ import AddIcon from "../icons/add.svg" ;
6
7
import CloseIcon from "../icons/close.svg" ;
7
8
import CopyIcon from "../icons/copy.svg" ;
8
9
import ClearIcon from "../icons/clear.svg" ;
9
10
import EditIcon from "../icons/edit.svg" ;
11
+ import EyeIcon from "../icons/eye.svg" ;
10
12
import { Input , List , ListItem , Modal , PasswordInput , Popover } from "./ui-lib" ;
11
13
import { ModelConfigList } from "./model-config" ;
12
14
@@ -30,6 +32,55 @@ import { InputRange } from "./input-range";
30
32
import { useNavigate } from "react-router-dom" ;
31
33
import { Avatar , AvatarPicker } from "./emoji" ;
32
34
35
+ function EditPromptModal ( props : { id : number ; onClose : ( ) => void } ) {
36
+ const promptStore = usePromptStore ( ) ;
37
+ const prompt = promptStore . get ( props . id ) ;
38
+
39
+ return prompt ? (
40
+ < div className = "modal-mask" >
41
+ < Modal
42
+ title = { Locale . Settings . Prompt . EditModal . Title }
43
+ onClose = { props . onClose }
44
+ actions = { [
45
+ < IconButton
46
+ key = ""
47
+ onClick = { props . onClose }
48
+ text = { Locale . UI . Confirm }
49
+ bordered
50
+ /> ,
51
+ ] }
52
+ >
53
+ < div className = { styles [ "edit-prompt-modal" ] } >
54
+ < input
55
+ type = "text"
56
+ value = { prompt . title }
57
+ readOnly = { ! prompt . isUser }
58
+ className = { styles [ "edit-prompt-title" ] }
59
+ onInput = { ( e ) =>
60
+ promptStore . update (
61
+ props . id ,
62
+ ( prompt ) => ( prompt . title = e . currentTarget . value ) ,
63
+ )
64
+ }
65
+ > </ input >
66
+ < Input
67
+ value = { prompt . content }
68
+ readOnly = { ! prompt . isUser }
69
+ className = { styles [ "edit-prompt-content" ] }
70
+ rows = { 10 }
71
+ onInput = { ( e ) =>
72
+ promptStore . update (
73
+ props . id ,
74
+ ( prompt ) => ( prompt . content = e . currentTarget . value ) ,
75
+ )
76
+ }
77
+ > </ Input >
78
+ </ div >
79
+ </ Modal >
80
+ </ div >
81
+ ) : null ;
82
+ }
83
+
33
84
function UserPromptModal ( props : { onClose ?: ( ) => void } ) {
34
85
const promptStore = usePromptStore ( ) ;
35
86
const userPrompts = promptStore . getUserPrompts ( ) ;
@@ -39,6 +90,8 @@ function UserPromptModal(props: { onClose?: () => void }) {
39
90
const [ searchPrompts , setSearchPrompts ] = useState < Prompt [ ] > ( [ ] ) ;
40
91
const prompts = searchInput . length > 0 ? searchPrompts : allPrompts ;
41
92
93
+ const [ editingPromptId , setEditingPromptId ] = useState < number > ( ) ;
94
+
42
95
useEffect ( ( ) => {
43
96
if ( searchInput . length > 0 ) {
44
97
const searchResult = SearchService . search ( searchInput ) ;
@@ -56,8 +109,13 @@ function UserPromptModal(props: { onClose?: () => void }) {
56
109
actions = { [
57
110
< IconButton
58
111
key = "add"
59
- onClick = { ( ) => promptStore . add ( { title : "" , content : "" } ) }
60
- icon = { < ClearIcon /> }
112
+ onClick = { ( ) =>
113
+ promptStore . add ( {
114
+ title : "Empty Prompt" ,
115
+ content : "Empty Prompt Content" ,
116
+ } )
117
+ }
118
+ icon = { < AddIcon /> }
61
119
bordered
62
120
text = { Locale . Settings . Prompt . Modal . Add }
63
121
/> ,
@@ -76,57 +134,51 @@ function UserPromptModal(props: { onClose?: () => void }) {
76
134
{ prompts . map ( ( v , _ ) => (
77
135
< div className = { styles [ "user-prompt-item" ] } key = { v . id ?? v . title } >
78
136
< div className = { styles [ "user-prompt-header" ] } >
79
- < input
80
- type = "text"
81
- className = { styles [ "user-prompt-title" ] }
82
- value = { v . title }
83
- readOnly = { ! v . isUser }
84
- onChange = { ( e ) => {
85
- if ( v . isUser ) {
86
- promptStore . updateUserPrompts (
87
- v . id ! ,
88
- ( prompt ) => ( prompt . title = e . currentTarget . value ) ,
89
- ) ;
90
- }
91
- } }
92
- > </ input >
93
-
94
- < div className = { styles [ "user-prompt-buttons" ] } >
95
- { v . isUser && (
96
- < IconButton
97
- icon = { < ClearIcon /> }
98
- bordered
99
- className = { styles [ "user-prompt-button" ] }
100
- onClick = { ( ) => promptStore . remove ( v . id ! ) }
101
- />
102
- ) }
137
+ < div className = { styles [ "user-prompt-title" ] } > { v . title } </ div >
138
+ < div className = { styles [ "user-prompt-content" ] + " one-line" } >
139
+ { v . content }
140
+ </ div >
141
+ </ div >
142
+
143
+ < div className = { styles [ "user-prompt-buttons" ] } >
144
+ { v . isUser && (
103
145
< IconButton
104
- icon = { < CopyIcon /> }
105
- bordered
146
+ icon = { < ClearIcon /> }
106
147
className = { styles [ "user-prompt-button" ] }
107
- onClick = { ( ) => copyToClipboard ( v . content ) }
148
+ onClick = { ( ) => promptStore . remove ( v . id ! ) }
108
149
/>
109
- </ div >
150
+ ) }
151
+ { v . isUser ? (
152
+ < IconButton
153
+ icon = { < EditIcon /> }
154
+ className = { styles [ "user-prompt-button" ] }
155
+ onClick = { ( ) => setEditingPromptId ( v . id ) }
156
+ />
157
+ ) : (
158
+ < IconButton
159
+ icon = { < EyeIcon /> }
160
+ className = { styles [ "user-prompt-button" ] }
161
+ onClick = { ( ) => setEditingPromptId ( v . id ) }
162
+ />
163
+ ) }
164
+ < IconButton
165
+ icon = { < CopyIcon /> }
166
+ className = { styles [ "user-prompt-button" ] }
167
+ onClick = { ( ) => copyToClipboard ( v . content ) }
168
+ />
110
169
</ div >
111
- < Input
112
- rows = { 2 }
113
- value = { v . content }
114
- className = { styles [ "user-prompt-content" ] }
115
- readOnly = { ! v . isUser }
116
- onChange = { ( e ) => {
117
- if ( v . isUser ) {
118
- promptStore . updateUserPrompts (
119
- v . id ! ,
120
- ( prompt ) => ( prompt . content = e . currentTarget . value ) ,
121
- ) ;
122
- }
123
- } }
124
- />
125
170
</ div >
126
171
) ) }
127
172
</ div >
128
173
</ div >
129
174
</ Modal >
175
+
176
+ { editingPromptId !== undefined && (
177
+ < EditPromptModal
178
+ id = { editingPromptId ! }
179
+ onClose = { ( ) => setEditingPromptId ( undefined ) }
180
+ />
181
+ ) }
130
182
</ div >
131
183
) ;
132
184
}
0 commit comments