@@ -90,7 +90,7 @@ private fun CustomAIKeySlot(index: Int, context: Context) {
9090 val cardModifier = Modifier .fillMaxWidth()
9191 val cardColors = if (isSet) {
9292 CardDefaults .elevatedCardColors(
93- containerColor = MaterialTheme .colorScheme.surfaceContainer
93+ containerColor = MaterialTheme .colorScheme.surfaceContainerHigh
9494 )
9595 } else {
9696 CardDefaults .outlinedCardColors()
@@ -99,7 +99,7 @@ private fun CustomAIKeySlot(index: Int, context: Context) {
9999 val CardContent = @Composable {
100100 Row (
101101 modifier = Modifier
102- .padding(16 .dp)
102+ .padding(horizontal = 16 .dp, vertical = 12 .dp)
103103 .fillMaxWidth(),
104104 verticalAlignment = Alignment .CenterVertically ,
105105 horizontalArrangement = Arrangement .spacedBy(16 .dp)
@@ -108,7 +108,7 @@ private fun CustomAIKeySlot(index: Int, context: Context) {
108108 painter = painterResource(iconRes),
109109 contentDescription = null ,
110110 modifier = Modifier .size(32 .dp),
111- tint = if (isSet) MaterialTheme .colorScheme.primary else MaterialTheme .colorScheme.onSurfaceVariant
111+ tint = if (isSet) MaterialTheme .colorScheme.primary else MaterialTheme .colorScheme.outline
112112 )
113113
114114 Column (modifier = Modifier .weight(1f )) {
@@ -121,17 +121,25 @@ private fun CustomAIKeySlot(index: Int, context: Context) {
121121 text = if (isSet) currentPrompt else " Not configured" ,
122122 style = MaterialTheme .typography.bodyMedium,
123123 color = if (isSet) MaterialTheme .colorScheme.onSurfaceVariant else MaterialTheme .colorScheme.outline,
124- maxLines = 1 ,
124+ maxLines = 2 ,
125125 overflow = TextOverflow .Ellipsis
126126 )
127127 }
128128
129129 if (isSet) {
130- Icon (
131- painter = painterResource(R .drawable.ic_setup_check),
132- contentDescription = null , // decorative
133- tint = MaterialTheme .colorScheme.primary
134- )
130+ androidx.compose.material3.IconButton (
131+ onClick = {
132+ prefs.edit { remove(prefKey) }
133+ currentPrompt = " "
134+ updateToolbarKeyStatus(context, keyEnum, false )
135+ }
136+ ) {
137+ Icon (
138+ painter = painterResource(R .drawable.ic_close),
139+ contentDescription = " Clear" ,
140+ tint = MaterialTheme .colorScheme.onSurfaceVariant
141+ )
142+ }
135143 }
136144 }
137145 }
@@ -151,34 +159,146 @@ private fun CustomAIKeySlot(index: Int, context: Context) {
151159 }
152160
153161 if (showDialog) {
154- TextInputDialog (
162+ CustomAIKeyDialog (
163+ initialPrompt = currentPrompt,
164+ title = " Configure Key $index " ,
165+ iconRes = iconRes,
155166 onDismissRequest = { showDialog = false },
156167 onConfirmed = { newPrompt ->
157168 val trimmed = newPrompt.trim()
158169 prefs.edit { putString(prefKey, trimmed) }
159170 currentPrompt = trimmed
160171 updateToolbarKeyStatus(context, keyEnum, trimmed.isNotEmpty())
161- },
162- title = { Text (" Configure Key $index " ) },
163- textInputLabel = { Text (" Prompt (e.g. \" rewrite in poetic style\" )" ) },
164- initialText = currentPrompt,
165- neutralButtonText = if (isSet) " Clear" else null ,
166- onNeutral = {
167- prefs.edit { remove(prefKey) }
168- currentPrompt = " "
169- updateToolbarKeyStatus(context, keyEnum, false )
170- },
171- icon = {
172- Icon (
173- painter = painterResource(iconRes),
174- contentDescription = null ,
175- modifier = Modifier .size(24 .dp)
176- )
172+ showDialog = false
177173 }
178174 )
179175 }
180176}
181177
178+ @Composable
179+ private fun CustomAIKeyDialog (
180+ initialPrompt : String ,
181+ title : String ,
182+ iconRes : Int ,
183+ onDismissRequest : () -> Unit ,
184+ onConfirmed : (String ) -> Unit
185+ ) {
186+ var prompt by remember { mutableStateOf(initialPrompt) }
187+
188+ val modes = listOf (
189+ " #editor" to " Edit text" ,
190+ " #proofread" to " Fix grammar" ,
191+ " #paraphrase" to " Rewrite" ,
192+ " #summarize" to " Summarize" ,
193+ " #expand" to " Expand" ,
194+ " #toneshift" to " Adjust tone" ,
195+ " #generate" to " Generate"
196+ )
197+
198+ val modifiersList = listOf (
199+ " #outputonly" to " Result only" ,
200+ " #append" to " Append result" ,
201+ " #showthought" to " Show reasoning"
202+ )
203+
204+ androidx.compose.material3.AlertDialog (
205+ onDismissRequest = onDismissRequest,
206+ icon = {
207+ Icon (
208+ painter = painterResource(iconRes),
209+ contentDescription = null ,
210+ modifier = Modifier .size(24 .dp)
211+ )
212+ },
213+ title = { Text (title) },
214+ text = {
215+ Column (
216+ verticalArrangement = Arrangement .spacedBy(16 .dp),
217+ modifier = Modifier .padding(top = 8 .dp)
218+ ) {
219+ // Modes Section
220+ Column (verticalArrangement = Arrangement .spacedBy(4 .dp)) {
221+ Text (
222+ text = " Modes" ,
223+ style = MaterialTheme .typography.labelMedium,
224+ color = MaterialTheme .colorScheme.primary
225+ )
226+ androidx.compose.foundation.layout.FlowRow (
227+ horizontalArrangement = Arrangement .spacedBy(8 .dp),
228+ verticalArrangement = Arrangement .spacedBy(4 .dp)
229+ ) {
230+ modes.forEach { (keyword, label) ->
231+ val isSelected = prompt.contains(keyword)
232+ androidx.compose.material3.FilterChip (
233+ selected = isSelected,
234+ onClick = {
235+ prompt = if (isSelected) {
236+ prompt.replace(keyword, " " ).replace(" " , " " ).trim()
237+ } else {
238+ if (prompt.isBlank()) keyword else " $prompt $keyword " .trim()
239+ }
240+ },
241+ label = { Text (label) }
242+ )
243+ }
244+ }
245+ }
246+
247+ // Modifiers Section
248+ Column (verticalArrangement = Arrangement .spacedBy(4 .dp)) {
249+ Text (
250+ text = " Modifiers" ,
251+ style = MaterialTheme .typography.labelMedium,
252+ color = MaterialTheme .colorScheme.primary
253+ )
254+ androidx.compose.foundation.layout.FlowRow (
255+ horizontalArrangement = Arrangement .spacedBy(8 .dp),
256+ verticalArrangement = Arrangement .spacedBy(4 .dp)
257+ ) {
258+ modifiersList.forEach { (keyword, label) ->
259+ val isSelected = prompt.contains(keyword)
260+ androidx.compose.material3.FilterChip (
261+ selected = isSelected,
262+ onClick = {
263+ prompt = if (isSelected) {
264+ prompt.replace(keyword, " " ).replace(" " , " " ).trim()
265+ } else {
266+ if (prompt.isBlank()) keyword else " $prompt $keyword " .trim()
267+ }
268+ },
269+ label = { Text (label) }
270+ )
271+ }
272+ }
273+ }
274+
275+ androidx.compose.material3.OutlinedTextField (
276+ value = prompt,
277+ onValueChange = { prompt = it },
278+ label = { Text (" Custom Prompt" ) },
279+ modifier = Modifier .fillMaxWidth(),
280+ minLines = 2 ,
281+ maxLines = 5
282+ )
283+ }
284+ },
285+ confirmButton = {
286+ androidx.compose.material3.TextButton (
287+ onClick = { onConfirmed(prompt) }
288+ ) {
289+ Text (" Save" )
290+ }
291+ },
292+ dismissButton = {
293+ androidx.compose.material3.TextButton (
294+ onClick = onDismissRequest
295+ ) {
296+ Text (stringResource(android.R .string.cancel))
297+ }
298+ }
299+ )
300+ }
301+
182302private val CUSTOM_AI_KEY_ENUMS = arrayOf(
183303 ToolbarKey .CUSTOM_AI_1 , ToolbarKey .CUSTOM_AI_2 , ToolbarKey .CUSTOM_AI_3 ,
184304 ToolbarKey .CUSTOM_AI_4 , ToolbarKey .CUSTOM_AI_5 , ToolbarKey .CUSTOM_AI_6 ,
0 commit comments