Skip to content

Commit

Permalink
feat: gpt搜索支持下拉刷新
Browse files Browse the repository at this point in the history
  • Loading branch information
jing332 committed Jul 24, 2023
1 parent fbab7c2 commit 10c4c5c
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
Expand All @@ -32,6 +34,9 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldColors
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.pullrefresh.PullRefreshIndicator
import androidx.compose.material3.pullrefresh.pullRefresh
import androidx.compose.material3.pullrefresh.rememberPullRefreshState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
Expand Down Expand Up @@ -163,12 +168,16 @@ private fun ChatGPTScreen(
vm.viewModelScope.launch {
try {
vm.requestGpt(
context,
msg = message,
token = token,
model = model,
systemPrompt = systemPrompt,
)
} catch (e: IllegalArgumentException) {
if (e.message?.contains("token") == true) {
vm.errorMessage = context.getString(R.string.error_open_ai_api_key_empty)
} else
vm.errorMessage = e.message ?: e.toString()
} catch (e: Exception) {
vm.errorMessage = e.message ?: e.toString()
}
Expand All @@ -182,163 +191,184 @@ private fun ChatGPTScreen(

var gptAppearanceScreenVisible by remember { mutableStateOf(false) }
val scrollState = rememberScrollState()
Column(modifier.verticalScroll(scrollState)) {
Row {
Column(
modifier
.weight(1f)
.clip(MaterialTheme.shapes.extraSmall)
.clickable(
enabled = true,
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = true),
onClick = { gptAppearanceScreenVisible = !gptAppearanceScreenVisible },
)
) {
Row(Modifier.align(Alignment.CenterHorizontally)) {
Text(
text = stringResource(R.string.appearance_settings),
fontWeight = if (gptAppearanceScreenVisible) FontWeight.Bold else FontWeight.Normal
)
Icon(
modifier = Modifier.size(24.dp),
imageVector = Icons.Filled.ColorLens,
contentDescription = stringResource(R.string.appearance_settings),
)
}
}

var showTtsSettings by remember { mutableStateOf(false) }
if (showTtsSettings) {
var vTts by remember { mutableStateOf(tts) }
var vTestText by remember { mutableStateOf(testText) }

TtsSettingsDialog(
onDismissRequest = { showTtsSettings = false },
tts = vTts,
message = message,
testText = vTestText,
onTestTextChange = {
vTestText = it
onTestTextChange(it)
},
onTtsChange = {
vTts = it
onTtsChange(it)
val refreshState = rememberPullRefreshState(refreshing = vm.isLoading, onRefresh = {
state.requestLoad = true
})
Box(
Modifier
.pullRefresh(refreshState)
) {
Column(modifier.verticalScroll(scrollState)) {
Row {
Column(
modifier
.weight(1f)
.clip(MaterialTheme.shapes.extraSmall)
.clickable(
enabled = true,
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = true),
onClick = { gptAppearanceScreenVisible = !gptAppearanceScreenVisible },
)
) {
Row(Modifier.align(Alignment.CenterHorizontally)) {
Text(
text = stringResource(R.string.appearance_settings),
fontWeight = if (gptAppearanceScreenVisible) FontWeight.Bold else FontWeight.Normal
)
Icon(
modifier = Modifier.size(24.dp),
imageVector = Icons.Filled.ColorLens,
contentDescription = stringResource(R.string.appearance_settings),
)
}
)
}
/*Divider(
Modifier
.fillMaxHeight()
.width(1.dp)
.padding(horizontal = 2.dp)
)*/
Column(
Modifier
.weight(1f)
.clip(MaterialTheme.shapes.extraSmall)
.clickable(
enabled = true,
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = true),
onClick = { showTtsSettings = true },
}

var showTtsSettings by remember { mutableStateOf(false) }
if (showTtsSettings) {
var vTts by remember { mutableStateOf(tts) }
var vTestText by remember { mutableStateOf(testText) }

TtsSettingsDialog(
onDismissRequest = { showTtsSettings = false },
tts = vTts,
message = message,
testText = vTestText,
onTestTextChange = {
vTestText = it
onTestTextChange(it)
},
onTtsChange = {
vTts = it
onTtsChange(it)
}
)
) {
Row(
Modifier.align(Alignment.CenterHorizontally)
}
/*Divider(
Modifier
.fillMaxHeight()
.width(1.dp)
.padding(horizontal = 2.dp)
)*/
Column(
Modifier
.weight(1f)
.clip(MaterialTheme.shapes.extraSmall)
.clickable(
enabled = true,
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = true),
onClick = { showTtsSettings = true },
)
) {
Text(text = stringResource(R.string.tts_settings))
Icon(
modifier = Modifier.size(24.dp),
contentDescription = stringResource(R.string.tts_settings),
painter = painterResource(id = R.drawable.ic_tts)
)
Row(
Modifier.align(Alignment.CenterHorizontally)
) {
Text(text = stringResource(R.string.tts_settings))
Icon(
modifier = Modifier.size(24.dp),
contentDescription = stringResource(R.string.tts_settings),
painter = painterResource(id = R.drawable.ic_tts)
)
}
}
}
}

// GPT外观设置
if (gptAppearanceScreenVisible) GptAppearanceSettingsScreen(
Modifier
.animateContentSize()
.padding(horizontal = 2.dp),
titleAppearance = mTitleAppearance,
onTitleAppearanceChange = {
onTitleAppearanceChange(it)
mTitleAppearance = it
},
contentAppearance = mContentAppearance,
onContentAppearanceChange = {
onContentAppearanceChange(it)
mContentAppearance = it
},
)
val ffResolver = LocalFontFamilyResolver.current
fun fontFamily(uri: Uri): FontFamily {
try {
context.contentResolver.openFileDescriptor(uri, "r")?.use {
return FontFamily(Font(it)).apply {
ffResolver.resolve(this)
// GPT外观设置
if (gptAppearanceScreenVisible) GptAppearanceSettingsScreen(
Modifier
.animateContentSize()
.padding(horizontal = 2.dp),
titleAppearance = mTitleAppearance,
onTitleAppearanceChange = {
onTitleAppearanceChange(it)
mTitleAppearance = it
},
contentAppearance = mContentAppearance,
onContentAppearanceChange = {
onContentAppearanceChange(it)
mContentAppearance = it
},
)
val ffResolver = LocalFontFamilyResolver.current
fun fontFamily(uri: Uri): FontFamily {
try {
context.contentResolver.openFileDescriptor(uri, "r")?.use {
return FontFamily(Font(it)).apply {
ffResolver.resolve(this)
}
}
} catch (_: Exception) {
}
} catch (_: Exception) {

return FontFamily.Default
}

return FontFamily.Default
}
ExpandableText(
modifier = Modifier.padding(
horizontal = mTitleAppearance.horizontalMargin.dp,
vertical = mTitleAppearance.verticalMargin.dp
),
text = message, style = MaterialTheme.typography.titleMedium,
fontFamily = fontFamily(mTitleAppearance.fontUri),
fontSize = mTitleAppearance.fontSize.sp,
lineHeight = mTitleAppearance.fontSize.sp * mTitleAppearance.lineWidthScale,
fontWeight = FontWeight(mTitleAppearance.fontWeight)
)
val refreshState = rememberPullRefreshState(refreshing = vm.isLoading, onRefresh = {
state.requestLoad = true
})

Box {
var text by remember { mutableStateOf(TextFieldValue(vm.errorMessage.ifEmpty { vm.result })) }
val localView = LocalView.current
val textToolbar = remember {
CustomTextToolbar(localView, onTtsRequested = {
val selectedText = text.getSelectedText().text
if (selectedText.isNotEmpty()) {
context.startService(Intent(context, TtsService::class.java).apply {
putExtra(TtsService.KEY_TTS_TEXT, selectedText)
putExtra(TtsService.KEY_TTS_CONFIG, tts)
})
}
})
}

CompositionLocalProvider(LocalTextToolbar provides textToolbar) {
LaunchedEffect(key1 = vm.errorMessage, key2 = vm.result) {
text = text.copy(text = vm.errorMessage.ifEmpty { vm.result })
ExpandableText(
modifier = Modifier.padding(
horizontal = mTitleAppearance.horizontalMargin.dp,
vertical = mTitleAppearance.verticalMargin.dp
),
text = message, style = MaterialTheme.typography.titleMedium,
fontFamily = fontFamily(mTitleAppearance.fontUri),
fontSize = mTitleAppearance.fontSize.sp,
lineHeight = mTitleAppearance.fontSize.sp * mTitleAppearance.lineWidthScale,
fontWeight = FontWeight(mTitleAppearance.fontWeight)
)

Box {
var text by remember { mutableStateOf(TextFieldValue(vm.errorMessage.ifEmpty { vm.result })) }
val localView = LocalView.current
val textToolbar = remember {
CustomTextToolbar(localView, onTtsRequested = {
val selectedText = text.getSelectedText().text
if (selectedText.isNotEmpty()) {
context.startService(Intent(context, TtsService::class.java).apply {
putExtra(TtsService.KEY_TTS_TEXT, selectedText)
putExtra(TtsService.KEY_TTS_CONFIG, tts)
})
}
})
}

TextWithSelectedText(
modifier = Modifier.padding(
horizontal = mContentAppearance.horizontalMargin.dp,
vertical = mContentAppearance.verticalMargin.dp
),
value = text,
onValueChange = {
text = it
},
textStyle = MaterialTheme.typography.bodyMedium.copy(
fontFamily = fontFamily(mContentAppearance.fontUri),
fontSize = mContentAppearance.fontSize.sp,
fontWeight = FontWeight(mContentAppearance.fontWeight),
lineHeight = mContentAppearance.fontSize.sp * mContentAppearance.lineWidthScale,
color = if (vm.errorMessage.isEmpty()) Color.Unspecified else MaterialTheme.colorScheme.error
),
)
CompositionLocalProvider(LocalTextToolbar provides textToolbar) {
LaunchedEffect(key1 = vm.errorMessage, key2 = vm.result) {
text = text.copy(text = vm.errorMessage.ifEmpty { vm.result })
}

TextWithSelectedText(
modifier = Modifier.padding(
horizontal = mContentAppearance.horizontalMargin.dp,
vertical = mContentAppearance.verticalMargin.dp
),
value = text,
onValueChange = { text = it },
textStyle = MaterialTheme.typography.bodyMedium.copy(
fontFamily = fontFamily(mContentAppearance.fontUri),
fontSize = mContentAppearance.fontSize.sp,
fontWeight = FontWeight(mContentAppearance.fontWeight),
lineHeight = mContentAppearance.fontSize.sp * mContentAppearance.lineWidthScale,
color = if (vm.errorMessage.isEmpty()) Color.Unspecified else MaterialTheme.colorScheme.error
),
)
}
}
Spacer(modifier = Modifier.height(8.dp))
}

Column(Modifier.fillMaxWidth()) {
PullRefreshIndicator(
modifier = Modifier.align(Alignment.CenterHorizontally),
refreshing = refreshState.refreshing,
state = refreshState
)
}
Spacer(modifier = Modifier.height(8.dp))
}
}

Expand Down
Loading

0 comments on commit 10c4c5c

Please sign in to comment.