聊天自定义背景实现
This commit is contained in:
@@ -46,6 +46,7 @@ object AppState {
|
|||||||
var enableGoogleLogin: Boolean = false
|
var enableGoogleLogin: Boolean = false
|
||||||
var enableChat = false
|
var enableChat = false
|
||||||
var agentCreatedSuccess by mutableStateOf(false)
|
var agentCreatedSuccess by mutableStateOf(false)
|
||||||
|
var chatBackgroundUrl by mutableStateOf<String?>(null)
|
||||||
suspend fun initWithAccount(scope: CoroutineScope, context: Context) {
|
suspend fun initWithAccount(scope: CoroutineScope, context: Context) {
|
||||||
// 如果是游客模式,使用简化的初始化流程
|
// 如果是游客模式,使用简化的初始化流程
|
||||||
if (AppStore.isGuest) {
|
if (AppStore.isGuest) {
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ object AppStore {
|
|||||||
AppState.appTheme = DarkThemeColors()
|
AppState.appTheme = DarkThemeColors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load chat background
|
||||||
|
val savedBgUrl = sharedPreferences.getString("chatBackgroundUrl", null)
|
||||||
|
if (savedBgUrl != null) {
|
||||||
|
AppState.chatBackgroundUrl = savedBgUrl
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun saveData() {
|
suspend fun saveData() {
|
||||||
@@ -54,5 +60,15 @@ object AppStore {
|
|||||||
}.apply()
|
}.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveChatBackgroundUrl(url: String?) {
|
||||||
|
sharedPreferences.edit().apply {
|
||||||
|
if (url != null) {
|
||||||
|
putString("chatBackgroundUrl", url)
|
||||||
|
} else {
|
||||||
|
remove("chatBackgroundUrl")
|
||||||
|
}
|
||||||
|
}.apply()
|
||||||
|
AppState.chatBackgroundUrl = url
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -83,6 +83,8 @@ import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
|||||||
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||||
import com.aiosman.ravenow.utils.NetworkUtils
|
import com.aiosman.ravenow.utils.NetworkUtils
|
||||||
import com.aiosman.ravenow.ui.NavigationRoute
|
import com.aiosman.ravenow.ui.NavigationRoute
|
||||||
|
import com.aiosman.ravenow.AppState
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import io.openim.android.sdk.enums.MessageType
|
import io.openim.android.sdk.enums.MessageType
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -93,6 +95,7 @@ fun ChatAiScreen(userId: String) {
|
|||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val context = LocalNavController.current.context
|
val context = LocalNavController.current.context
|
||||||
val AppColors = LocalAppTheme.current
|
val AppColors = LocalAppTheme.current
|
||||||
|
val chatBackgroundUrl = AppState.chatBackgroundUrl
|
||||||
var goToNewCount by remember { mutableStateOf(0) }
|
var goToNewCount by remember { mutableStateOf(0) }
|
||||||
val viewModel = viewModel<ChatAiViewModel>(
|
val viewModel = viewModel<ChatAiViewModel>(
|
||||||
key = "ChatAiViewModel_$userId",
|
key = "ChatAiViewModel_$userId",
|
||||||
@@ -156,14 +159,25 @@ fun ChatAiScreen(userId: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
|
if (chatBackgroundUrl != null && chatBackgroundUrl.isNotEmpty()) {
|
||||||
|
CustomAsyncImage(
|
||||||
|
imageUrl = chatBackgroundUrl,
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentDescription = "chat_background",
|
||||||
|
contentScale = ContentScale.Crop
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
|
backgroundColor = Color.Transparent,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.background(AppColors.background)
|
.background(Color.Transparent)
|
||||||
) {
|
) {
|
||||||
StatusBarSpacer()
|
StatusBarSpacer()
|
||||||
Row(
|
Row(
|
||||||
@@ -222,11 +236,13 @@ fun ChatAiScreen(userId: String) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
|
val hasChatBackground = AppState.chatBackgroundUrl != null && AppState.chatBackgroundUrl!!.isNotEmpty()
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.imePadding()
|
.imePadding()
|
||||||
) {
|
) {
|
||||||
|
if (!hasChatBackground) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -234,6 +250,7 @@ fun ChatAiScreen(userId: String) {
|
|||||||
.background(
|
.background(
|
||||||
AppColors.decentBackground)
|
AppColors.decentBackground)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
ChatAiInput(
|
ChatAiInput(
|
||||||
onSendImage = {
|
onSendImage = {
|
||||||
@@ -254,7 +271,7 @@ fun ChatAiScreen(userId: String) {
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(Color.White)
|
.background(Color.Transparent)
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
@@ -317,8 +334,7 @@ fun ChatAiScreen(userId: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +558,8 @@ fun ChatAiInput(
|
|||||||
}
|
}
|
||||||
Box( modifier = Modifier
|
Box( modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp),){
|
.background(Color.Transparent)
|
||||||
|
.padding(start = 16.dp, end = 16.dp, bottom = 45.dp),){
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ import androidx.compose.ui.platform.LocalFocusManager
|
|||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.platform.SoftwareKeyboardController
|
import androidx.compose.ui.platform.SoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
@@ -74,6 +75,7 @@ import androidx.lifecycle.ViewModelProvider
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.aiosman.ravenow.LocalAppTheme
|
import com.aiosman.ravenow.LocalAppTheme
|
||||||
|
import com.aiosman.ravenow.AppState
|
||||||
import com.aiosman.ravenow.LocalNavController
|
import com.aiosman.ravenow.LocalNavController
|
||||||
import com.aiosman.ravenow.R
|
import com.aiosman.ravenow.R
|
||||||
import com.aiosman.ravenow.entity.ChatItem
|
import com.aiosman.ravenow.entity.ChatItem
|
||||||
@@ -158,14 +160,37 @@ fun ChatScreen(userId: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
) {
|
||||||
|
// 背景图层
|
||||||
|
val bgUrl = AppState.chatBackgroundUrl
|
||||||
|
if (bgUrl != null) {
|
||||||
|
CustomAsyncImage(
|
||||||
|
imageUrl = bgUrl,
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentDescription = "chat_background",
|
||||||
|
contentScale = ContentScale.Crop
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// 无背景时使用主题背景色
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(AppColors.background)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
|
backgroundColor = Color.Transparent,
|
||||||
topBar = {
|
topBar = {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.background(AppColors.background)
|
.background(Color.Transparent)
|
||||||
) {
|
) {
|
||||||
StatusBarSpacer()
|
StatusBarSpacer()
|
||||||
Row(
|
Row(
|
||||||
@@ -256,7 +281,7 @@ fun ChatScreen(userId: String) {
|
|||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(AppColors.background)
|
.background(Color.Transparent)
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
@@ -320,6 +345,7 @@ fun ChatScreen(userId: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,7 +571,7 @@ fun ChatInput(
|
|||||||
}
|
}
|
||||||
Box( modifier = Modifier
|
Box( modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp),){
|
.padding(start = 16.dp, end = 16.dp, bottom = 45.dp),){
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ private fun ThemePickerSheet(onClose: () -> Unit) {
|
|||||||
color = appColors.text,
|
color = appColors.text,
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
fontWeight = FontWeight.W600,
|
fontWeight = FontWeight.W600,
|
||||||
modifier = Modifier.weight(1f).padding(start = 100.dp),
|
modifier = Modifier.weight(1f).padding(start = 90.dp),
|
||||||
)
|
)
|
||||||
IconButton(onClick = onClose) {
|
IconButton(onClick = onClose) {
|
||||||
Icon(
|
Icon(
|
||||||
@@ -338,7 +338,13 @@ private fun ThemePickerSheet(onClose: () -> Unit) {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.clickable { }
|
.clickable {
|
||||||
|
previewUrl?.let { url ->
|
||||||
|
com.aiosman.ravenow.AppStore.saveChatBackgroundUrl(url)
|
||||||
|
previewUrl = null
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
.padding(vertical = 12.dp),
|
.padding(vertical = 12.dp),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ fun IndexScreen() {
|
|||||||
bottomBar = {
|
bottomBar = {
|
||||||
NavigationBar(
|
NavigationBar(
|
||||||
modifier = Modifier.height(58.dp + navigationBarHeight),
|
modifier = Modifier.height(58.dp + navigationBarHeight),
|
||||||
containerColor = AppColors.secondaryBackground
|
containerColor = AppColors.tabUnselectedBackground
|
||||||
) {
|
) {
|
||||||
item.forEachIndexed { idx, it ->
|
item.forEachIndexed { idx, it ->
|
||||||
val isSelected = model.tabIndex == idx
|
val isSelected = model.tabIndex == idx
|
||||||
|
|||||||
@@ -891,7 +891,7 @@ fun ChatRoomCard(
|
|||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.size(cardSize)
|
.size(cardSize)
|
||||||
.background(AppColors.secondaryBackground, RoundedCornerShape(12.dp))
|
.background(AppColors.tabUnselectedBackground, RoundedCornerShape(12.dp))
|
||||||
.clickable(enabled = !viewModel.isJoiningRoom) {
|
.clickable(enabled = !viewModel.isJoiningRoom) {
|
||||||
if (!viewModel.isJoiningRoom && DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
if (!viewModel.isJoiningRoom && DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
||||||
// 加入群聊房间
|
// 加入群聊房间
|
||||||
|
|||||||
Reference in New Issue
Block a user