parent
5278050b1c
commit
85d03e0390
|
|
@ -4,10 +4,10 @@
|
||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2026-03-09T06:18:00.411600700Z">
|
<DropdownSelection timestamp="2026-03-10T06:53:45.140671700Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=JRBI89BIE6AI5TG6" />
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=d927cac5" />
|
||||||
</handle>
|
</handle>
|
||||||
</Target>
|
</Target>
|
||||||
</DropdownSelection>
|
</DropdownSelection>
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ dependencies {
|
||||||
implementation(libs.androidx.activity)
|
implementation(libs.androidx.activity)
|
||||||
implementation(libs.androidx.constraintlayout)
|
implementation(libs.androidx.constraintlayout)
|
||||||
implementation(libs.androidx.core.splashscreen)
|
implementation(libs.androidx.core.splashscreen)
|
||||||
implementation(libs.multidex)
|
// implementation(libs.multidex)
|
||||||
|
|
||||||
// Compose 依赖
|
// Compose 依赖
|
||||||
implementation(platform(libs.androidx.compose.bom))
|
implementation(platform(libs.androidx.compose.bom))
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,7 @@
|
||||||
package com.img.rabbit
|
package com.img.rabbit
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.ActivityManager
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Intent
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.KeyEvent
|
|
||||||
import android.webkit.WebView
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.OnBackPressedCallback
|
|
||||||
import androidx.multidex.MultiDex
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.img.rabbit.utils.NetworkMonitor
|
import com.img.rabbit.utils.NetworkMonitor
|
||||||
import com.g.gysdk.GYManager
|
import com.g.gysdk.GYManager
|
||||||
|
|
@ -61,7 +50,7 @@ class BaseApplication : Application() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun attachBaseContext(base: android.content.Context?) {
|
override fun attachBaseContext(base: android.content.Context?) {
|
||||||
MultiDex.install(base)
|
// MultiDex.install(base)
|
||||||
super.attachBaseContext(base)
|
super.attachBaseContext(base)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,13 +196,7 @@ class MainActivity : ComponentActivity(), LoadingCallback {
|
||||||
showSplash = true
|
showSplash = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if(showSplash){ //|| globalLogout.value == true){
|
if(showSplash){
|
||||||
// 全局注销,重新登录
|
|
||||||
// if(globalLogout.value == true){
|
|
||||||
// loginViewModel = viewModel()
|
|
||||||
// loginViewModel.requestUserConfig()
|
|
||||||
// }
|
|
||||||
|
|
||||||
val token = PreferenceUtil.getAccessToken()
|
val token = PreferenceUtil.getAccessToken()
|
||||||
// 未登录,显示登录页
|
// 未登录,显示登录页
|
||||||
if (token.isNullOrEmpty() && loginViewModel.userConfigResult.value == null) {
|
if (token.isNullOrEmpty() && loginViewModel.userConfigResult.value == null) {
|
||||||
|
|
@ -368,7 +362,7 @@ class MainActivity : ComponentActivity(), LoadingCallback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模拟加载过程,2秒后关闭启动页
|
// 模拟加载过程,500毫秒后关闭启动页
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
delay(500L)
|
delay(500L)
|
||||||
splashViewModel.setLoading(false)
|
splashViewModel.setLoading(false)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
package com.img.rabbit.bean.local
|
package com.img.rabbit.bean.local
|
||||||
|
|
||||||
|
data class NotifyBean(var code: String,var message: String)
|
||||||
data class ErrorBean(var code: String,var message: String)
|
data class ErrorBean(var code: String,var message: String)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
|
@ -71,6 +72,7 @@ import com.g.gysdk.EloginActivityParam
|
||||||
import com.g.gysdk.GYManager
|
import com.g.gysdk.GYManager
|
||||||
import com.g.gysdk.GYResponse
|
import com.g.gysdk.GYResponse
|
||||||
import com.g.gysdk.GyCallBack
|
import com.g.gysdk.GyCallBack
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.config.Constants.agreementUrl
|
import com.img.rabbit.config.Constants.agreementUrl
|
||||||
import com.img.rabbit.config.Constants.privacyUrl
|
import com.img.rabbit.config.Constants.privacyUrl
|
||||||
import com.img.rabbit.pages.toolbar.TitleBar
|
import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
|
|
@ -87,18 +89,6 @@ import org.json.JSONObject
|
||||||
@Composable
|
@Composable
|
||||||
fun LoginScreen(navController: NavHostController? = null, generalViewModel: GeneralViewModel, loginViewModel: LoginViewModel, isVisibilityBreak: Boolean) {
|
fun LoginScreen(navController: NavHostController? = null, generalViewModel: GeneralViewModel, loginViewModel: LoginViewModel, isVisibilityBreak: Boolean) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
// val networkStatus by generalViewModel.networkStatus.observeAsState(initial = true)
|
|
||||||
// var showNetworkDisconnected by remember { mutableStateOf(false) }
|
|
||||||
//
|
|
||||||
// // 网络状态监听
|
|
||||||
// LaunchedEffect(networkStatus) {
|
|
||||||
// if (!networkStatus) {
|
|
||||||
// // 网络断开时的处理
|
|
||||||
// Log.w("NetworkStatus","网络断开")
|
|
||||||
// }else{
|
|
||||||
// Log.w("NetworkStatus","网络已连接")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
//关于登录的事件监听
|
//关于登录的事件监听
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
|
|
@ -120,20 +110,20 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
|
||||||
if (loginViewModel.loginResult.value?.data?.token?.isNotEmpty() == true) {
|
if (loginViewModel.loginResult.value?.data?.token?.isNotEmpty() == true) {
|
||||||
val loginInfo = loginViewModel.loginResult.value?.data
|
val loginInfo = loginViewModel.loginResult.value?.data
|
||||||
AppEventBus.post( LoginBindEvent.Login(userId = loginInfo?.user_id?:"", loginType = PreferenceUtil.getLoginType(), isLogin = true, data = loginInfo) )
|
AppEventBus.post( LoginBindEvent.Login(userId = loginInfo?.user_id?:"", loginType = PreferenceUtil.getLoginType(), isLogin = true, data = loginInfo) )
|
||||||
Toast.makeText(context, "登录成功", Toast.LENGTH_SHORT).show() //提示登录成功
|
CenterToast.show("登录成功")
|
||||||
if(isVisibilityBreak){
|
if(isVisibilityBreak){
|
||||||
navController?.popBackStack() // 当允许返回上一页时,登录成功后,返回上一页
|
navController?.popBackStack() // 当允许返回上一页时,登录成功后,返回上一页
|
||||||
}
|
}
|
||||||
loginViewModel.loginResult.value = null //清理loginState
|
loginViewModel.loginResult.value = null //清理loginState
|
||||||
}else if(loginViewModel.loginResult.value != null && loginViewModel.loginResult.value?.data?.token == null){
|
}else if(loginViewModel.loginResult.value != null && loginViewModel.loginResult.value?.data?.token == null){
|
||||||
Log.w("LoginScreen","登录失败,无有效的Token")
|
Log.w("LoginScreen","登录失败,无有效的Token")
|
||||||
Toast.makeText(context, "登录失败,请重新登录", Toast.LENGTH_SHORT).show()//提示登录成功
|
CenterToast.show("登录失败,请重新登录")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold{
|
Scaffold{
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.mipmap.ic_main_previous_mask),
|
painter = painterResource(id = R.mipmap.ic_main_previous_mask),
|
||||||
|
|
@ -758,11 +748,7 @@ private fun WxLoginScreen(
|
||||||
//打开微信登录
|
//打开微信登录
|
||||||
viewModel.authorWechat(context, generalViewModel.api)
|
viewModel.authorWechat(context, generalViewModel.api)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
CenterToast.show("请先同意用户协议和隐私政策")
|
||||||
context,
|
|
||||||
"请先同意用户协议和隐私政策",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
|
@ -934,11 +920,7 @@ private fun AliPayLoginScreen(
|
||||||
// 打开支付宝登录
|
// 打开支付宝登录
|
||||||
viewModel.requestAliPayAuthParam(context)
|
viewModel.requestAliPayAuthParam(context)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
CenterToast.show("请先同意用户协议和隐私政策")
|
||||||
context,
|
|
||||||
"请先同意用户协议和隐私政策",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
|
@ -1164,7 +1146,7 @@ private fun OtherLoginBar(viewModel: LoginViewModel) {
|
||||||
*/
|
*/
|
||||||
private fun validatePhoneEmpty(context: Context, viewModel: LoginViewModel, showToast: Boolean = false): Boolean {
|
private fun validatePhoneEmpty(context: Context, viewModel: LoginViewModel, showToast: Boolean = false): Boolean {
|
||||||
if (showToast && viewModel.userName.value.isEmpty()) {
|
if (showToast && viewModel.userName.value.isEmpty()) {
|
||||||
Toast.makeText(context, "请输入手机号", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请输入手机号")
|
||||||
}
|
}
|
||||||
return viewModel.userName.value.isNotEmpty()
|
return viewModel.userName.value.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
@ -1175,11 +1157,11 @@ private fun validatePhoneEmpty(context: Context, viewModel: LoginViewModel, show
|
||||||
private fun validateCaptchaLoginEmpty(context: Context, viewModel: LoginViewModel, showToast: Boolean = false): Boolean {
|
private fun validateCaptchaLoginEmpty(context: Context, viewModel: LoginViewModel, showToast: Boolean = false): Boolean {
|
||||||
if (showToast) {
|
if (showToast) {
|
||||||
if(viewModel.userName.value.isEmpty()){
|
if(viewModel.userName.value.isEmpty()){
|
||||||
Toast.makeText(context, "请输入手机号", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请输入手机号")
|
||||||
}else if(viewModel.captcha.value.isEmpty()){
|
}else if(viewModel.captcha.value.isEmpty()){
|
||||||
Toast.makeText(context, "请输入验证码", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请输入验证码")
|
||||||
}else if(!viewModel.isPolicyAgreement.value){
|
}else if(!viewModel.isPolicyAgreement.value){
|
||||||
Toast.makeText(context, "请同意用户协议和隐私政策", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请同意用户协议和隐私政策")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return viewModel.userName.value.isNotEmpty() && viewModel.captcha.value.isNotEmpty() && viewModel.isPolicyAgreement.value
|
return viewModel.userName.value.isNotEmpty() && viewModel.captcha.value.isNotEmpty() && viewModel.isPolicyAgreement.value
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ package com.img.rabbit.pages
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Gravity
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
|
@ -50,6 +50,7 @@ import com.img.rabbit.pages.screen.mine.setting.AboutScreen
|
||||||
import com.img.rabbit.pages.screen.mine.setting.AccountBindScreen
|
import com.img.rabbit.pages.screen.mine.setting.AccountBindScreen
|
||||||
import com.img.rabbit.pages.screen.mine.setting.AccountManagerScreen
|
import com.img.rabbit.pages.screen.mine.setting.AccountManagerScreen
|
||||||
import com.img.rabbit.pages.screen.mine.setting.BindScreen
|
import com.img.rabbit.pages.screen.mine.setting.BindScreen
|
||||||
|
import com.img.rabbit.pages.screen.mine.setting.DeleteAccountScreen
|
||||||
import com.img.rabbit.pages.screen.other.CameraGuideScreen
|
import com.img.rabbit.pages.screen.other.CameraGuideScreen
|
||||||
import com.img.rabbit.route.ScreenRoute
|
import com.img.rabbit.route.ScreenRoute
|
||||||
import com.img.rabbit.viewmodel.BindViewModel
|
import com.img.rabbit.viewmodel.BindViewModel
|
||||||
|
|
@ -133,14 +134,23 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = iconRes),
|
painter = painterResource(id = iconRes),
|
||||||
contentDescription = item.title,
|
contentDescription = item.title,
|
||||||
tint = Color.Unspecified
|
tint = Color.Unspecified,
|
||||||
|
modifier = Modifier.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null
|
||||||
|
){
|
||||||
|
selectedTab = tabItems[index]
|
||||||
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
label = { Text(item.title, color = if (selectedTab == tabItems[index]) item.selectedColor else item.normalColor) },
|
label = { Text(item.title, color = if (selectedTab == tabItems[index]) item.selectedColor else item.normalColor) },
|
||||||
selected = selectedTab == tabItems[index],
|
selected = selectedTab == tabItems[index],
|
||||||
onClick = { selectedTab = tabItems[index] },
|
onClick = { selectedTab = tabItems[index] },
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
colors = NavigationBarItemDefaults.colors(
|
colors = NavigationBarItemDefaults.colors(
|
||||||
indicatorColor = Color.Transparent
|
indicatorColor = Color.Transparent, // 去掉选中时的椭圆背景
|
||||||
|
selectedIconColor = Color.Unspecified,
|
||||||
|
unselectedIconColor = Color.Unspecified
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -222,6 +232,9 @@ fun MainScreen(generalViewModel: GeneralViewModel, loginViewModel: LoginViewMode
|
||||||
composable(ScreenRoute.AboutMine.route) {
|
composable(ScreenRoute.AboutMine.route) {
|
||||||
AboutScreen(navController = navController)
|
AboutScreen(navController = navController)
|
||||||
}
|
}
|
||||||
|
composable(ScreenRoute.DeleteAccount.route) {
|
||||||
|
DeleteAccountScreen(navController = navController)
|
||||||
|
}
|
||||||
|
|
||||||
// 登录页面(Login)
|
// 登录页面(Login)
|
||||||
composable(ScreenRoute.Login.route) {
|
composable(ScreenRoute.Login.route) {
|
||||||
|
|
|
||||||
|
|
@ -222,13 +222,11 @@ fun UpdateDialog(
|
||||||
) {
|
) {
|
||||||
// 执行下载更新
|
// 执行下载更新
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
// isStartDown.value = true
|
|
||||||
onStatusChange(false, false, url)
|
onStatusChange(false, false, url)
|
||||||
}else{
|
}else{
|
||||||
when {
|
when {
|
||||||
// 情况 A:已获得权限
|
// 情况 A:已获得权限
|
||||||
storagePermissionState.status.isGranted -> {
|
storagePermissionState.status.isGranted -> {
|
||||||
// isStartDown.value = true
|
|
||||||
onStatusChange(false, false, url)
|
onStatusChange(false, false, url)
|
||||||
}
|
}
|
||||||
// 情况 B:需要向用户解释(之前拒绝过,但未勾选“不再询问”)
|
// 情况 B:需要向用户解释(之前拒绝过,但未勾选“不再询问”)
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
import com.img.rabbit.R
|
import com.img.rabbit.R
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.pages.LoadingCallback
|
import com.img.rabbit.pages.LoadingCallback
|
||||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
|
|
@ -90,7 +91,7 @@ fun HomeScreen(
|
||||||
BackHandler(enabled = (currentRoute == ScreenRoute.Home.route)) {
|
BackHandler(enabled = (currentRoute == ScreenRoute.Home.route)) {
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
if (currentTime - lastClickTime > 2000) {
|
if (currentTime - lastClickTime > 2000) {
|
||||||
Toast.makeText(context, "再按一次退出应用", Toast.LENGTH_SHORT).show()
|
CenterToast.show("再按一次退出应用")
|
||||||
lastClickTime = currentTime
|
lastClickTime = currentTime
|
||||||
} else {
|
} else {
|
||||||
(context as? Activity)?.finish()
|
(context as? Activity)?.finish()
|
||||||
|
|
@ -470,7 +471,7 @@ fun HomeScreen(
|
||||||
val uniVersion =
|
val uniVersion =
|
||||||
PreferenceUtil.getUserConfig()?.config?.uniVersionEntity?.firstOrNull { it.unimp_type == item.type }
|
PreferenceUtil.getUserConfig()?.config?.uniVersionEntity?.firstOrNull { it.unimp_type == item.type }
|
||||||
if(uniVersion == null){
|
if(uniVersion == null){
|
||||||
Toast.makeText(context, "无可用资源...", Toast.LENGTH_SHORT).show()
|
CenterToast.show("无可用资源...")
|
||||||
return@clickable
|
return@clickable
|
||||||
}
|
}
|
||||||
val uniMpId = uniVersion.unimp_id
|
val uniMpId = uniVersion.unimp_id
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ import androidx.navigation.compose.rememberNavController
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
import com.img.rabbit.BuildConfig
|
import com.img.rabbit.BuildConfig
|
||||||
import com.img.rabbit.R
|
import com.img.rabbit.R
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
import com.img.rabbit.route.ScreenRoute
|
import com.img.rabbit.route.ScreenRoute
|
||||||
|
|
@ -81,7 +82,7 @@ fun MineScreen(
|
||||||
BackHandler(enabled = (currentRoute == ScreenRoute.Mine.route)) {
|
BackHandler(enabled = (currentRoute == ScreenRoute.Mine.route)) {
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
if (currentTime - lastClickTime > 2000) {
|
if (currentTime - lastClickTime > 2000) {
|
||||||
Toast.makeText(context, "再按一次退出应用", Toast.LENGTH_SHORT).show()
|
CenterToast.show("再按一次退出应用")
|
||||||
lastClickTime = currentTime
|
lastClickTime = currentTime
|
||||||
} else {
|
} else {
|
||||||
(context as? Activity)?.finish()
|
(context as? Activity)?.finish()
|
||||||
|
|
@ -194,8 +195,7 @@ fun MineScreen(
|
||||||
userInfo?.user_id
|
userInfo?.user_id
|
||||||
)
|
)
|
||||||
clipboard.setPrimaryClip(clip)
|
clipboard.setPrimaryClip(clip)
|
||||||
Toast.makeText(context, "已复制到剪贴板", Toast.LENGTH_SHORT)
|
CenterToast.show("已复制到剪贴板")
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
){
|
){
|
||||||
|
|
@ -388,7 +388,7 @@ fun MineScreen(
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
) {
|
) {
|
||||||
if (!generalViewModel.api.isWXAppInstalled) {
|
if (!generalViewModel.api.isWXAppInstalled) {
|
||||||
Toast.makeText(context, "未安装微信客户端", Toast.LENGTH_SHORT).show()
|
CenterToast.show("未安装微信客户端")
|
||||||
}else if(userInfo != null){
|
}else if(userInfo != null){
|
||||||
viewModel.requestServiceLink(context, generalViewModel.api)
|
viewModel.requestServiceLink(context, generalViewModel.api)
|
||||||
}
|
}
|
||||||
|
|
@ -455,7 +455,7 @@ fun MineScreen(
|
||||||
GlobalStateManager(context).storeGlobalUpdateNotify(true)
|
GlobalStateManager(context).storeGlobalUpdateNotify(true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(context, tips, Toast.LENGTH_SHORT).show()
|
CenterToast.show(tips)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
|
@file:OptIn(ExperimentalPermissionsApi::class)
|
||||||
|
|
||||||
package com.img.rabbit.pages.screen.make
|
package com.img.rabbit.pages.screen.make
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
|
|
@ -24,6 +26,7 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
|
@ -63,10 +66,15 @@ import androidx.compose.ui.unit.toSize
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
|
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||||
|
import com.google.accompanist.permissions.isGranted
|
||||||
|
import com.google.accompanist.permissions.rememberPermissionState
|
||||||
|
import com.google.accompanist.permissions.shouldShowRationale
|
||||||
import com.img.rabbit.R
|
import com.img.rabbit.R
|
||||||
import com.img.rabbit.bean.local.ClothingBean
|
import com.img.rabbit.bean.local.ClothingBean
|
||||||
import com.img.rabbit.bean.local.HairstyleBean
|
import com.img.rabbit.bean.local.HairstyleBean
|
||||||
import com.img.rabbit.components.AppearanceType
|
import com.img.rabbit.components.AppearanceType
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.components.DrawingBoardPicker
|
import com.img.rabbit.components.DrawingBoardPicker
|
||||||
import com.img.rabbit.config.CommonData.clothingForFemales
|
import com.img.rabbit.config.CommonData.clothingForFemales
|
||||||
import com.img.rabbit.config.CommonData.clothingForMans
|
import com.img.rabbit.config.CommonData.clothingForMans
|
||||||
|
|
@ -170,6 +178,14 @@ fun CutoutScreen(navController: NavController) {
|
||||||
val selectedSize = remember { mutableStateOf(resizes.first { it.width == widthParam && it.height == heightParam }) }
|
val selectedSize = remember { mutableStateOf(resizes.first { it.width == widthParam && it.height == heightParam }) }
|
||||||
|
|
||||||
|
|
||||||
|
val storagePermissionState = rememberPermissionState(
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
Manifest.permission.READ_MEDIA_IMAGES // Android 13+ 使用具体媒体权限
|
||||||
|
} else {
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE // 旧版本使用常规存储权限
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// 图片选择启动器
|
// 图片选择启动器
|
||||||
val imagePickerLauncher = rememberLauncherForActivityResult(
|
val imagePickerLauncher = rememberLauncherForActivityResult(
|
||||||
contract = ActivityResultContracts.GetContent()
|
contract = ActivityResultContracts.GetContent()
|
||||||
|
|
@ -200,7 +216,7 @@ fun CutoutScreen(navController: NavController) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
context.mainExecutor.execute {
|
context.mainExecutor.execute {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
Toast.makeText(context, "抠图失败,请重试", Toast.LENGTH_SHORT).show()
|
CenterToast.show("抠图失败,请重试")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -245,21 +261,18 @@ fun CutoutScreen(navController: NavController) {
|
||||||
imagePickerLauncher.launch("image/*")
|
imagePickerLauncher.launch("image/*")
|
||||||
}
|
}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4))
|
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4)).navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
TitleBar(navController = navController, paddingValues = it, title = "", showSave = true){
|
TitleBar(navController = navController, paddingValues = it, title = "", showSave = true){
|
||||||
// 保存图片
|
// 保存图片
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
// 从 Layer 捕获 Bitmap
|
// 从 Layer 捕获 Bitmap
|
||||||
val bitmap = graphicsLayer.toImageBitmap().asAndroidBitmap()
|
val bitmap = graphicsLayer.toImageBitmap().asAndroidBitmap()
|
||||||
// 保存图片到系统相册(图片已按比例裁剪)
|
// // 保存图片到系统相册(图片已按比例裁剪)
|
||||||
saveCanvasToGallery(context, bitmap, ExportFormat.JPG){fileName, isSuccess ->
|
// saveCanvasToGallery(context, bitmap, ExportFormat.JPG){fileName, isSuccess ->
|
||||||
if(isSuccess){
|
// val tips = if(isSuccess){ "已保存为: $fileName" }else{ "保存失败" }
|
||||||
Toast.makeText(context, "已保存为: $fileName", Toast.LENGTH_SHORT).show()
|
// CenterToast.show(tips)
|
||||||
}else{
|
// }
|
||||||
Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// 保存图片到系统相册(指定尺寸,如果targetWidth与targetHeight比原始值小太多会导致图片模糊)
|
// 保存图片到系统相册(指定尺寸,如果targetWidth与targetHeight比原始值小太多会导致图片模糊)
|
||||||
|
|
@ -271,6 +284,33 @@ fun CutoutScreen(navController: NavController) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
// 保存图片到系统相册(图片已按比例裁剪)
|
||||||
|
saveCanvasToGallery(context, bitmap, ExportFormat.JPG){fileName, isSuccess ->
|
||||||
|
val tips = if(isSuccess){ "已保存为: $fileName" }else{ "保存失败" }
|
||||||
|
CenterToast.show(tips)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
when {
|
||||||
|
// 情况 A:已获得权限
|
||||||
|
storagePermissionState.status.isGranted -> {
|
||||||
|
// 保存图片到系统相册(图片已按比例裁剪)
|
||||||
|
saveCanvasToGallery(context, bitmap, ExportFormat.JPG){fileName, isSuccess ->
|
||||||
|
val tips = if(isSuccess){ "已保存为: $fileName" }else{ "保存失败" }
|
||||||
|
CenterToast.show(tips)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 情况 B:需要向用户解释(之前拒绝过,但未勾选“不再询问”)
|
||||||
|
storagePermissionState.status.shouldShowRationale -> {
|
||||||
|
storagePermissionState.launchPermissionRequest()
|
||||||
|
}
|
||||||
|
// 情况 C:从未请求过权限或已被彻底拒绝
|
||||||
|
else -> {
|
||||||
|
storagePermissionState.launchPermissionRequest()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.img.rabbit.pages.screen.make
|
package com.img.rabbit.pages.screen.make
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
|
|
@ -13,6 +12,7 @@ import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
|
@ -33,6 +33,7 @@ import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
import com.img.rabbit.R
|
import com.img.rabbit.R
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.components.DrawingBoardFormatPicker
|
import com.img.rabbit.components.DrawingBoardFormatPicker
|
||||||
import com.img.rabbit.config.CommonData.formats
|
import com.img.rabbit.config.CommonData.formats
|
||||||
import com.img.rabbit.pages.toolbar.TitleBar
|
import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
|
|
@ -66,7 +67,7 @@ fun FormatScreen(navController: NavController) {
|
||||||
imagePickerLauncher.launch("image/*")
|
imagePickerLauncher.launch("image/*")
|
||||||
}
|
}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4))
|
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4)).navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
TitleBar(navController = navController, paddingValues = it, title = "", showSave = true) {
|
TitleBar(navController = navController, paddingValues = it, title = "", showSave = true) {
|
||||||
val bitmap = selectedImageUri.value?.let {uri->
|
val bitmap = selectedImageUri.value?.let {uri->
|
||||||
|
|
@ -87,11 +88,8 @@ fun FormatScreen(navController: NavController) {
|
||||||
sourceBitmap = bitmap,
|
sourceBitmap = bitmap,
|
||||||
format = format,
|
format = format,
|
||||||
onSubmitResult = { fileName, isSuccess ->
|
onSubmitResult = { fileName, isSuccess ->
|
||||||
if (isSuccess) {
|
val tips = if (isSuccess) { "已保存至 $fileName" } else { "保存失败" }
|
||||||
Toast.makeText(context, "已保存至 $fileName", Toast.LENGTH_SHORT).show()
|
CenterToast.show(tips)
|
||||||
} else {
|
|
||||||
Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
|
@ -56,6 +57,7 @@ import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.asAndroidBitmap
|
import androidx.compose.ui.graphics.asAndroidBitmap
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import io.moyuru.cropify.Cropify
|
import io.moyuru.cropify.Cropify
|
||||||
import io.moyuru.cropify.CropifyOption
|
import io.moyuru.cropify.CropifyOption
|
||||||
import io.moyuru.cropify.rememberCropifyState
|
import io.moyuru.cropify.rememberCropifyState
|
||||||
|
|
@ -97,7 +99,7 @@ fun LongImageScreen(navController: NavController) {
|
||||||
mediaPickerLauncher.launch(matisse)
|
mediaPickerLauncher.launch(matisse)
|
||||||
}
|
}
|
||||||
Column (
|
Column (
|
||||||
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4))
|
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4)).navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
TitleBar(
|
TitleBar(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
|
|
@ -107,11 +109,8 @@ fun LongImageScreen(navController: NavController) {
|
||||||
){
|
){
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
saveLongToGallery(context = context, items = imageItems, format = ExportFormat.JPG){ fileName, isSuccess ->
|
saveLongToGallery(context = context, items = imageItems, format = ExportFormat.JPG){ fileName, isSuccess ->
|
||||||
if (isSuccess) {
|
val tips = if (isSuccess) { "已保存至 $fileName" } else { "保存失败" }
|
||||||
Toast.makeText(context, "已保存至 $fileName", Toast.LENGTH_SHORT).show()
|
CenterToast.show(tips)
|
||||||
} else {
|
|
||||||
Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
|
@ -53,6 +54,7 @@ import androidx.compose.ui.unit.sp
|
||||||
import androidx.compose.ui.unit.toSize
|
import androidx.compose.ui.unit.toSize
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.img.rabbit.R
|
import com.img.rabbit.R
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.components.DrawingBoardCertificatePicker
|
import com.img.rabbit.components.DrawingBoardCertificatePicker
|
||||||
import com.img.rabbit.config.CommonData.resizes
|
import com.img.rabbit.config.CommonData.resizes
|
||||||
import com.img.rabbit.pages.toolbar.TitleBar
|
import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
|
|
@ -117,7 +119,7 @@ fun ResizeScreen(navController: NavController) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
context.mainExecutor.execute {
|
context.mainExecutor.execute {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
Toast.makeText(context, "加载失败,请重试", Toast.LENGTH_SHORT).show()
|
CenterToast.show("加载失败,请重试")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +143,7 @@ fun ResizeScreen(navController: NavController) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4))
|
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4)).navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
TitleBar(navController = navController, paddingValues = it, title = "", showSave = true){
|
TitleBar(navController = navController, paddingValues = it, title = "", showSave = true){
|
||||||
// 保存图片
|
// 保存图片
|
||||||
|
|
@ -150,11 +152,8 @@ fun ResizeScreen(navController: NavController) {
|
||||||
val bitmap = graphicsLayer.toImageBitmap().asAndroidBitmap()
|
val bitmap = graphicsLayer.toImageBitmap().asAndroidBitmap()
|
||||||
// 保存图片到系统相册(图片已按比例裁剪)
|
// 保存图片到系统相册(图片已按比例裁剪)
|
||||||
saveCanvasToGallery(context, bitmap, ExportFormat.JPG){fileName, isSuccess ->
|
saveCanvasToGallery(context, bitmap, ExportFormat.JPG){fileName, isSuccess ->
|
||||||
if(isSuccess){
|
val tips = if(isSuccess){ "已保存为: $fileName" }else{ "保存失败" }
|
||||||
Toast.makeText(context, "已保存为: $fileName", Toast.LENGTH_SHORT).show()
|
CenterToast.show(tips)
|
||||||
}else{
|
|
||||||
Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,16 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.layout.wrapContentSize
|
import androidx.compose.foundation.layout.wrapContentSize
|
||||||
import androidx.compose.foundation.layout.wrapContentWidth
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
@ -38,6 +41,7 @@ import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.components.ImagePicker
|
import com.img.rabbit.components.ImagePicker
|
||||||
import com.img.rabbit.pages.toolbar.TitleBar
|
import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
import com.img.rabbit.viewmodel.FeedbackViewModel
|
import com.img.rabbit.viewmodel.FeedbackViewModel
|
||||||
|
|
@ -46,17 +50,18 @@ import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
@Composable
|
@Composable
|
||||||
fun FeedbackScreen(navController: NavHostController, viewModel: FeedbackViewModel = viewModel()) {
|
fun FeedbackScreen(navController: NavHostController, viewModel: FeedbackViewModel = viewModel()) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val scrollState = rememberScrollState()
|
||||||
|
|
||||||
LaunchedEffect(viewModel.errorState.value) {
|
LaunchedEffect(viewModel.errorState.value) {
|
||||||
if(viewModel.errorState.value != null){
|
if(viewModel.errorState.value != null){
|
||||||
Toast.makeText(context, viewModel.errorState.value?.message, Toast.LENGTH_SHORT).show()
|
viewModel.errorState.value?.message?.let { CenterToast.show(it) }
|
||||||
}
|
}
|
||||||
viewModel.errorState.value = null
|
viewModel.errorState.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold{
|
Scaffold{
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
TitleBar(navController = navController, paddingValues = it, title = "意见反馈")
|
TitleBar(navController = navController, paddingValues = it, title = "意见反馈")
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -67,7 +72,7 @@ fun FeedbackScreen(navController: NavHostController, viewModel: FeedbackViewMode
|
||||||
){
|
){
|
||||||
// 意见反馈内容
|
// 意见反馈内容
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().verticalScroll(scrollState)
|
||||||
) {
|
) {
|
||||||
// 意见反馈类型
|
// 意见反馈类型
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -421,6 +426,7 @@ fun FeedbackScreen(navController: NavHostController, viewModel: FeedbackViewMode
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Box(modifier = Modifier.fillMaxWidth().height(98.dp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -439,7 +445,7 @@ fun FeedbackScreen(navController: NavHostController, viewModel: FeedbackViewMode
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
) {
|
) {
|
||||||
if (viewModel.feedbackMore.isEmpty()) {
|
if (viewModel.feedbackMore.isEmpty()) {
|
||||||
Toast.makeText(context, "请填写详细问题或意见...", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请填写详细问题或意见...")
|
||||||
return@clickable
|
return@clickable
|
||||||
}
|
}
|
||||||
// 提交反馈
|
// 提交反馈
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
|
@ -29,7 +30,7 @@ import com.img.rabbit.R
|
||||||
fun OnlineServiceScreen(navController: NavHostController) {
|
fun OnlineServiceScreen(navController: NavHostController) {
|
||||||
Scaffold{
|
Scaffold{
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize().padding(it)
|
modifier = Modifier.fillMaxSize().padding(it).navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
// 顶部栏
|
// 顶部栏
|
||||||
Row(
|
Row(
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.layout.wrapContentSize
|
import androidx.compose.foundation.layout.wrapContentSize
|
||||||
|
|
@ -66,7 +67,7 @@ fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewMod
|
||||||
|
|
||||||
Scaffold{
|
Scaffold{
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
TitleBar(navController = navController, paddingValues = it, title = "设置")
|
TitleBar(navController = navController, paddingValues = it, title = "设置")
|
||||||
|
|
||||||
|
|
@ -257,6 +258,48 @@ fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewMod
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.mipmap.ic_arrow_right),
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentSize()
|
||||||
|
.padding(end = 12.dp)
|
||||||
|
.align(Alignment.CenterVertically)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxWidth().height(0.5.dp).padding(horizontal = 12.dp).background(
|
||||||
|
Color(0x4DBBBBBB)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(52.dp)
|
||||||
|
.clickable(
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
) {
|
||||||
|
// 跳转注销账号页面
|
||||||
|
navController.navigate("deleteAccount")
|
||||||
|
},
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
){
|
||||||
|
Text(
|
||||||
|
text = "注销账号",
|
||||||
|
fontSize = 14.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color(0xFF1A1A1A),
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentSize()
|
||||||
|
.padding(start = 8.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.mipmap.ic_arrow_right),
|
painter = painterResource(id = R.mipmap.ic_arrow_right),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentSize
|
import androidx.compose.foundation.layout.wrapContentSize
|
||||||
|
|
@ -43,14 +44,14 @@ fun AboutScreen(navController: NavHostController) {
|
||||||
Scaffold{
|
Scaffold{
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
TitleBar(navController = navController, paddingValues = it, title = "关于我们")
|
TitleBar(navController = navController, paddingValues = it, title = "关于我们")
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxSize().padding(start = 17.dp, end = 17.dp)
|
modifier = Modifier.fillMaxSize().padding(start = 17.dp, end = 17.dp)
|
||||||
){
|
){
|
||||||
//TODO 设置内容
|
// 设置内容
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
|
@ -45,6 +46,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.img.rabbit.R
|
import com.img.rabbit.R
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.pages.toolbar.TitleBar
|
import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
import com.img.rabbit.utils.AppEventBus
|
import com.img.rabbit.utils.AppEventBus
|
||||||
|
|
@ -66,7 +68,7 @@ fun AccountBindScreen(navController: NavHostController, viewModel: AccountBindVi
|
||||||
LaunchedEffect(viewModel.unBindState.value) {
|
LaunchedEffect(viewModel.unBindState.value) {
|
||||||
if(viewModel.unBindState.value != null){
|
if(viewModel.unBindState.value != null){
|
||||||
val loginInfo = viewModel.unBindState.value?.data
|
val loginInfo = viewModel.unBindState.value?.data
|
||||||
Toast.makeText(context, "解绑成功!", Toast.LENGTH_SHORT).show()
|
CenterToast.show("解绑成功!")
|
||||||
AppEventBus.post( LoginBindEvent.Bind(userId = loginInfo?.user_id?:"", loginType = null, isBind = false, data = loginInfo) )
|
AppEventBus.post( LoginBindEvent.Bind(userId = loginInfo?.user_id?:"", loginType = null, isBind = false, data = loginInfo) )
|
||||||
|
|
||||||
val popped = navController.popBackStack(route = "home", inclusive = true)
|
val popped = navController.popBackStack(route = "home", inclusive = true)
|
||||||
|
|
@ -80,14 +82,14 @@ fun AccountBindScreen(navController: NavHostController, viewModel: AccountBindVi
|
||||||
}
|
}
|
||||||
LaunchedEffect(viewModel.errorState.value) {
|
LaunchedEffect(viewModel.errorState.value) {
|
||||||
if(viewModel.errorState.value != null){
|
if(viewModel.errorState.value != null){
|
||||||
Toast.makeText(context, "解绑失败...", Toast.LENGTH_SHORT).show()
|
CenterToast.show("解绑失败...")
|
||||||
viewModel.errorState.value = null
|
viewModel.errorState.value = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold{
|
Scaffold{
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().navigationBarsPadding()
|
||||||
){
|
){
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
|
@ -47,6 +48,7 @@ import androidx.navigation.compose.rememberNavController
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
import com.img.rabbit.R
|
import com.img.rabbit.R
|
||||||
import com.img.rabbit.bean.response.UserInfoEntity
|
import com.img.rabbit.bean.response.UserInfoEntity
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.pages.dialog.TipsDialog
|
import com.img.rabbit.pages.dialog.TipsDialog
|
||||||
import com.img.rabbit.pages.toolbar.TitleBar
|
import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
import com.img.rabbit.provider.storage.PreferenceUtil
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
|
|
@ -76,7 +78,7 @@ fun AccountManagerScreen(navController: NavHostController, viewModel: AccountMan
|
||||||
loginInfo?.let { PreferenceUtil.saveLoginInfo(it) }
|
loginInfo?.let { PreferenceUtil.saveLoginInfo(it) }
|
||||||
PreferenceUtil.saveAccessToken(viewModel.switchState.value?.data?.token)
|
PreferenceUtil.saveAccessToken(viewModel.switchState.value?.data?.token)
|
||||||
AppEventBus.post( LoginBindEvent.Login(userId = loginInfo?.user_id?:"", loginType = null, isLogin = true, data = loginInfo) )
|
AppEventBus.post( LoginBindEvent.Login(userId = loginInfo?.user_id?:"", loginType = null, isLogin = true, data = loginInfo) )
|
||||||
Toast.makeText(context, "切换账号成功!", Toast.LENGTH_SHORT).show()
|
CenterToast.show("切换账号成功!")
|
||||||
|
|
||||||
//延迟执行,确保返回时,接口已经拿到最新的用户信息
|
//延迟执行,确保返回时,接口已经拿到最新的用户信息
|
||||||
delay(500)
|
delay(500)
|
||||||
|
|
@ -86,14 +88,14 @@ fun AccountManagerScreen(navController: NavHostController, viewModel: AccountMan
|
||||||
}
|
}
|
||||||
LaunchedEffect(viewModel.errorState.value) {
|
LaunchedEffect(viewModel.errorState.value) {
|
||||||
if(viewModel.errorState.value != null){
|
if(viewModel.errorState.value != null){
|
||||||
Toast.makeText(context, "切换账号失败...", Toast.LENGTH_SHORT).show()
|
CenterToast.show("切换账号失败...")
|
||||||
viewModel.errorState.value = null
|
viewModel.errorState.value = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold{
|
Scaffold{
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().navigationBarsPadding()
|
||||||
){
|
){
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.mipmap.ic_account_switch_top_mask),
|
painter = painterResource(id = R.mipmap.ic_account_switch_top_mask),
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
|
@ -65,6 +66,7 @@ import com.g.gysdk.GYManager
|
||||||
import com.g.gysdk.GYResponse
|
import com.g.gysdk.GYResponse
|
||||||
import com.g.gysdk.GyCallBack
|
import com.g.gysdk.GyCallBack
|
||||||
import com.img.rabbit.R
|
import com.img.rabbit.R
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.config.Constants.agreementUrl
|
import com.img.rabbit.config.Constants.agreementUrl
|
||||||
import com.img.rabbit.config.Constants.privacyUrl
|
import com.img.rabbit.config.Constants.privacyUrl
|
||||||
import com.img.rabbit.pages.toolbar.TitleBar
|
import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
|
|
@ -102,12 +104,12 @@ fun BindScreen(navController: NavHostController, viewModel: BindViewModel = view
|
||||||
LaunchedEffect(viewModel.bindState.value) {
|
LaunchedEffect(viewModel.bindState.value) {
|
||||||
if (viewModel.bindState.value != null && viewModel.bindState.value?.data?.token != null) {
|
if (viewModel.bindState.value != null && viewModel.bindState.value?.data?.token != null) {
|
||||||
val loginInfo = viewModel.bindState.value?.data
|
val loginInfo = viewModel.bindState.value?.data
|
||||||
Toast.makeText(context, "绑定成功!", Toast.LENGTH_SHORT).show()
|
CenterToast.show("绑定成功!")
|
||||||
AppEventBus.post( LoginBindEvent.Bind(userId = loginInfo?.user_id?:"", loginType = null, isBind = true, data = loginInfo) )
|
AppEventBus.post( LoginBindEvent.Bind(userId = loginInfo?.user_id?:"", loginType = null, isBind = true, data = loginInfo) )
|
||||||
|
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}else if (viewModel.bindState.value != null){
|
}else if (viewModel.bindState.value != null){
|
||||||
Toast.makeText(context, "绑定失败!", Toast.LENGTH_SHORT).show()
|
CenterToast.show("绑定失败...")
|
||||||
}
|
}
|
||||||
viewModel.bindState.value = null
|
viewModel.bindState.value = null
|
||||||
}
|
}
|
||||||
|
|
@ -116,9 +118,9 @@ fun BindScreen(navController: NavHostController, viewModel: BindViewModel = view
|
||||||
// 登录成功后,保存 token
|
// 登录成功后,保存 token
|
||||||
LaunchedEffect(viewModel.errorState.value) {
|
LaunchedEffect(viewModel.errorState.value) {
|
||||||
if (viewModel.errorState.value != null) {
|
if (viewModel.errorState.value != null) {
|
||||||
Toast.makeText(context, viewModel.errorState.value?.message?: "绑定失败!", Toast.LENGTH_SHORT).show()
|
CenterToast.show(viewModel.errorState.value?.message?: "绑定失败...")
|
||||||
}else if (viewModel.bindState.value != null){
|
}else if (viewModel.bindState.value != null){
|
||||||
Toast.makeText(context, "绑定失败!", Toast.LENGTH_SHORT).show()
|
CenterToast.show("绑定失败...")
|
||||||
}
|
}
|
||||||
viewModel.errorState.value = null
|
viewModel.errorState.value = null
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +143,7 @@ fun BindScreen(navController: NavHostController, viewModel: BindViewModel = view
|
||||||
|
|
||||||
Scaffold{
|
Scaffold{
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize().navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.mipmap.ic_main_previous_mask),
|
painter = painterResource(id = R.mipmap.ic_main_previous_mask),
|
||||||
|
|
@ -742,7 +744,7 @@ private fun CaptchaBindScreen(context: Context, viewModel: BindViewModel) {
|
||||||
*/
|
*/
|
||||||
private fun validatePhoneEmpty(context: Context, viewModel: BindViewModel, showToast: Boolean = false): Boolean {
|
private fun validatePhoneEmpty(context: Context, viewModel: BindViewModel, showToast: Boolean = false): Boolean {
|
||||||
if (showToast && viewModel.userName.value.isEmpty()) {
|
if (showToast && viewModel.userName.value.isEmpty()) {
|
||||||
Toast.makeText(context, "请输入手机号", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请输入手机号")
|
||||||
}
|
}
|
||||||
return viewModel.userName.value.isNotEmpty()
|
return viewModel.userName.value.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
@ -753,11 +755,11 @@ private fun validatePhoneEmpty(context: Context, viewModel: BindViewModel, showT
|
||||||
private fun validateCaptchaLoginEmpty(context: Context, viewModel: BindViewModel, showToast: Boolean = false): Boolean {
|
private fun validateCaptchaLoginEmpty(context: Context, viewModel: BindViewModel, showToast: Boolean = false): Boolean {
|
||||||
if (showToast) {
|
if (showToast) {
|
||||||
if(viewModel.userName.value.isEmpty()){
|
if(viewModel.userName.value.isEmpty()){
|
||||||
Toast.makeText(context, "请输入手机号", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请输入手机号")
|
||||||
}else if(viewModel.captcha.value.isEmpty()){
|
}else if(viewModel.captcha.value.isEmpty()){
|
||||||
Toast.makeText(context, "请输入验证码", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请输入验证码")
|
||||||
}else if(!viewModel.isPolicyAgreement.value){
|
}else if(!viewModel.isPolicyAgreement.value){
|
||||||
Toast.makeText(context, "请同意用户协议和隐私政策", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请同意用户协议和隐私政策")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return viewModel.userName.value.isNotEmpty() && viewModel.captcha.value.isNotEmpty() && viewModel.isPolicyAgreement.value
|
return viewModel.userName.value.isNotEmpty() && viewModel.captcha.value.isNotEmpty() && viewModel.isPolicyAgreement.value
|
||||||
|
|
@ -819,11 +821,7 @@ private fun WxBindScreen(
|
||||||
// 打开微信登录
|
// 打开微信登录
|
||||||
viewModel.requestWithWechatAuth(context, generalViewModel.api)
|
viewModel.requestWithWechatAuth(context, generalViewModel.api)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
CenterToast.show("请先同意用户协议和隐私政策")
|
||||||
context,
|
|
||||||
"请先同意用户协议和隐私政策",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,446 @@
|
||||||
|
package com.img.rabbit.pages.screen.mine.setting
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.Checkbox
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.scale
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.img.rabbit.R
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
|
import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
|
import com.img.rabbit.viewmodel.DeleteAccountViewModel
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DeleteAccountScreen(navController: NavHostController,viewModel: DeleteAccountViewModel = viewModel()) {
|
||||||
|
val inputTextValue = "我自愿注销本账号"
|
||||||
|
var isRights by remember { mutableStateOf(false) }//权益
|
||||||
|
var isDispute by remember { mutableStateOf(false) }//纠纷
|
||||||
|
var isDuty by remember { mutableStateOf(false) }//责任
|
||||||
|
var isIrrecoverable by remember { mutableStateOf(false) }//不可恢复
|
||||||
|
var inputText by remember { mutableStateOf("") }//文字
|
||||||
|
|
||||||
|
LaunchedEffect(viewModel.resultState.value) {
|
||||||
|
if (viewModel.resultState.value != null) {
|
||||||
|
CenterToast.show("注销成功!")
|
||||||
|
|
||||||
|
navController.popBackStack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LaunchedEffect(viewModel.errorState.value) {
|
||||||
|
if (viewModel.errorState.value != null) {
|
||||||
|
CenterToast.show("注销失败...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Scaffold{
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize().navigationBarsPadding().background(Color(0xFFF9F9F9))
|
||||||
|
) {
|
||||||
|
TitleBar(navController = navController, paddingValues = it, title = "注销账号")
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize().padding(start = 17.dp, end = 17.dp)
|
||||||
|
){
|
||||||
|
// 设置内容
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(top = 16.dp)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
){
|
||||||
|
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.mipmap.ic_warning),
|
||||||
|
contentDescription = null,
|
||||||
|
contentScale = ContentScale.FillWidth,
|
||||||
|
modifier = Modifier.size(86.dp).align(Alignment.CenterHorizontally)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "为保证你的账号安全,在你提交的注销申请生效前,需要同时满足以下条件:",
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterHorizontally),
|
||||||
|
color = Color(0xFF3D3D3D)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(top = 16.dp, bottom = 16.dp)
|
||||||
|
.align(Alignment.CenterHorizontally)
|
||||||
|
.background(Color(0xFFFFFFFF), shape = RoundedCornerShape(12.dp))
|
||||||
|
) {
|
||||||
|
//权益
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "1.放弃当前的VIP权益",
|
||||||
|
fontSize = 15.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
color = Color(0xFF1A1A1A)
|
||||||
|
)
|
||||||
|
|
||||||
|
Checkbox(
|
||||||
|
checked = isRights,
|
||||||
|
onCheckedChange = { isChecked ->
|
||||||
|
isRights = isChecked
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterVertically)
|
||||||
|
.size(16.dp)
|
||||||
|
.scale(0.35f)
|
||||||
|
.padding(start = 6.dp)
|
||||||
|
.background(
|
||||||
|
if (isRights) Color(0xFF252525)
|
||||||
|
else Color.Transparent,
|
||||||
|
shape = RoundedCornerShape(36.dp)
|
||||||
|
)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = if (isRights) Color(0xFF252525)
|
||||||
|
else Color(0xFFCCCCCC),
|
||||||
|
shape = RoundedCornerShape(36.dp)
|
||||||
|
)
|
||||||
|
.align(Alignment.CenterVertically),
|
||||||
|
colors = androidx.compose.material3.CheckboxDefaults.colors(
|
||||||
|
checkedColor = Color.Transparent, // 隐藏默认背景
|
||||||
|
uncheckedColor = Color.Transparent, // 隐藏默认背景
|
||||||
|
checkmarkColor = Color.White
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "当前充值的VIP我们不会退款,请解除你的自动续费(如果有),同意请打勾",
|
||||||
|
fontSize = 13.sp,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 4.dp, start = 30.dp, end = 57.dp),
|
||||||
|
color = Color(0xFF767676)
|
||||||
|
)
|
||||||
|
//纠纷
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "2.当前账号没有违规及其他的法律纠纷",
|
||||||
|
fontSize = 15.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
color = Color(0xFF1A1A1A)
|
||||||
|
)
|
||||||
|
|
||||||
|
Checkbox(
|
||||||
|
checked = isDispute,
|
||||||
|
onCheckedChange = { isChecked ->
|
||||||
|
isDispute = isChecked
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterVertically)
|
||||||
|
.size(16.dp)
|
||||||
|
.scale(0.35f)
|
||||||
|
.padding(start = 6.dp)
|
||||||
|
.background(
|
||||||
|
if (isDispute) Color(0xFF252525)
|
||||||
|
else Color.Transparent,
|
||||||
|
shape = RoundedCornerShape(36.dp)
|
||||||
|
)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = if (isDispute) Color(0xFF252525)
|
||||||
|
else Color(0xFFCCCCCC),
|
||||||
|
shape = RoundedCornerShape(36.dp)
|
||||||
|
)
|
||||||
|
.align(Alignment.CenterVertically),
|
||||||
|
colors = androidx.compose.material3.CheckboxDefaults.colors(
|
||||||
|
checkedColor = Color.Transparent, // 隐藏默认背景
|
||||||
|
uncheckedColor = Color.Transparent, // 隐藏默认背景
|
||||||
|
checkmarkColor = Color.White
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "同意请打勾",
|
||||||
|
fontSize = 13.sp,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 4.dp, start = 30.dp, end = 57.dp),
|
||||||
|
color = Color(0xFF767676)
|
||||||
|
)
|
||||||
|
//责任
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "3.确认是账号本人进行注销操作,自愿承担后果",
|
||||||
|
fontSize = 15.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
color = Color(0xFF1A1A1A)
|
||||||
|
)
|
||||||
|
|
||||||
|
Checkbox(
|
||||||
|
checked = isDuty,
|
||||||
|
onCheckedChange = { isChecked ->
|
||||||
|
isDuty = isChecked
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterVertically)
|
||||||
|
.size(16.dp)
|
||||||
|
.scale(0.35f)
|
||||||
|
.padding(start = 6.dp)
|
||||||
|
.background(
|
||||||
|
if (isDuty) Color(0xFF252525)
|
||||||
|
else Color.Transparent,
|
||||||
|
shape = RoundedCornerShape(36.dp)
|
||||||
|
)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = if (isDuty) Color(0xFF252525)
|
||||||
|
else Color(0xFFCCCCCC),
|
||||||
|
shape = RoundedCornerShape(36.dp)
|
||||||
|
)
|
||||||
|
.align(Alignment.CenterVertically),
|
||||||
|
colors = androidx.compose.material3.CheckboxDefaults.colors(
|
||||||
|
checkedColor = Color.Transparent, // 隐藏默认背景
|
||||||
|
uncheckedColor = Color.Transparent, // 隐藏默认背景
|
||||||
|
checkmarkColor = Color.White
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "同意请打勾",
|
||||||
|
fontSize = 13.sp,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 4.dp, start = 30.dp, end = 57.dp),
|
||||||
|
color = Color(0xFF767676)
|
||||||
|
)
|
||||||
|
//不可恢复
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "4.账号注销后账号不可登录,不可恢复",
|
||||||
|
fontSize = 15.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
color = Color(0xFF1A1A1A)
|
||||||
|
)
|
||||||
|
|
||||||
|
Checkbox(
|
||||||
|
checked = isIrrecoverable,
|
||||||
|
onCheckedChange = { isChecked ->
|
||||||
|
isIrrecoverable = isChecked
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterVertically)
|
||||||
|
.size(16.dp)
|
||||||
|
.scale(0.35f)
|
||||||
|
.padding(start = 6.dp)
|
||||||
|
.background(
|
||||||
|
if (isIrrecoverable) Color(0xFF252525)
|
||||||
|
else Color.Transparent,
|
||||||
|
shape = RoundedCornerShape(36.dp)
|
||||||
|
)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = if (isIrrecoverable) Color(0xFF252525)
|
||||||
|
else Color(0xFFCCCCCC),
|
||||||
|
shape = RoundedCornerShape(36.dp)
|
||||||
|
)
|
||||||
|
.align(Alignment.CenterVertically),
|
||||||
|
colors = androidx.compose.material3.CheckboxDefaults.colors(
|
||||||
|
checkedColor = Color.Transparent, // 隐藏默认背景
|
||||||
|
uncheckedColor = Color.Transparent, // 隐藏默认背景
|
||||||
|
checkmarkColor = Color.White
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = "同意请打勾",
|
||||||
|
fontSize = 13.sp,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 4.dp, start = 30.dp, end = 57.dp),
|
||||||
|
color = Color(0xFF767676)
|
||||||
|
)
|
||||||
|
//文字前面意愿
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "5.请在输入框中输入以下文字",
|
||||||
|
fontSize = 15.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f),
|
||||||
|
color = Color(0xFF1A1A1A)
|
||||||
|
)
|
||||||
|
|
||||||
|
Box(modifier = Modifier.size(16.dp))
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = inputTextValue,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(top = 4.dp, start = 30.dp, end = 57.dp),
|
||||||
|
color = Color(0xFFF64545)
|
||||||
|
)
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp)
|
||||||
|
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
|
||||||
|
.background(Color(0xFFF6F6F6), RoundedCornerShape(8.dp)).border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = Color(0xFFDEDEDE),
|
||||||
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
){
|
||||||
|
CustomTextField(value = inputText, onValueChange = {input-> inputText = input })
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(modifier = Modifier.height(14.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp)
|
||||||
|
.background(Color(0xFFFF4F4F).copy(
|
||||||
|
alpha = if(isValid(isRights, isDispute, isDuty, isIrrecoverable, inputText, inputTextValue))1f else 0.5f
|
||||||
|
), shape = RoundedCornerShape(197.dp))
|
||||||
|
.clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) {
|
||||||
|
if(isValid(isRights, isDispute, isDuty, isIrrecoverable, inputText, inputTextValue)){
|
||||||
|
// 处理确认注销逻辑
|
||||||
|
viewModel.deleteAccount()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
){
|
||||||
|
Text(
|
||||||
|
text = "确认注销",
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color(0xFFFFFFFF),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.Center)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(modifier = Modifier.height(56.dp))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CustomTextField(
|
||||||
|
value: String,
|
||||||
|
onValueChange: (String) -> Unit,
|
||||||
|
placeholder: String = ""
|
||||||
|
) {
|
||||||
|
BasicTextField(
|
||||||
|
value = value,
|
||||||
|
onValueChange = onValueChange,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp)
|
||||||
|
.background(Color(0xFFF6F6F6), RoundedCornerShape(8.dp))
|
||||||
|
.padding(horizontal = 16.dp),
|
||||||
|
// 核心:处理占位符和对齐
|
||||||
|
decorationBox = { innerTextField ->
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.CenterStart, // 垂直居中
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) {
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
Text(text = placeholder, color = Color.Gray, fontSize = 14.sp)
|
||||||
|
}
|
||||||
|
innerTextField() // 实际的文本输入区域
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cursorBrush = SolidColor(Color.Blue), // 自定义光标颜色
|
||||||
|
textStyle = TextStyle(color = Color.Black, fontSize = 16.sp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isValid(isRights: Boolean, isDispute: Boolean, isDuty: Boolean, isIrrecoverable: Boolean, input: String, @Suppress(
|
||||||
|
"SameParameterValue"
|
||||||
|
) inputValue: String): Boolean {
|
||||||
|
return isRights && isDispute && isDuty && isIrrecoverable && input == inputValue
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun PreviewDeleteAccountScreen(){
|
||||||
|
DeleteAccountScreen(navController = rememberNavController())
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
|
@ -34,7 +35,7 @@ import com.img.rabbit.pages.toolbar.TitleBar
|
||||||
fun CameraGuideScreen(navController: NavController) {
|
fun CameraGuideScreen(navController: NavController) {
|
||||||
Scaffold {
|
Scaffold {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4))
|
modifier = Modifier.fillMaxSize().background(Color(0xFFF4F4F4)).navigationBarsPadding()
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import com.img.rabbit.route.ScreenRoute
|
||||||
@Composable
|
@Composable
|
||||||
fun TitleBar(navController: NavController?, paddingValues: PaddingValues, title: String? = "", showSave: Boolean = false, showBreak: Boolean = true, onSubmit: (() -> Unit)? = null) {
|
fun TitleBar(navController: NavController?, paddingValues: PaddingValues, title: String? = "", showSave: Boolean = false, showBreak: Boolean = true, onSubmit: (() -> Unit)? = null) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.fillMaxWidth().padding(paddingValues)
|
modifier = Modifier.fillMaxWidth().padding(top = paddingValues.calculateTopPadding())
|
||||||
){
|
){
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,6 @@ sealed class ScreenRoute(val route: String) {
|
||||||
object BindAccount : ScreenRoute("bindAccount")
|
object BindAccount : ScreenRoute("bindAccount")
|
||||||
object ManagerAccount : ScreenRoute("managerAccount")
|
object ManagerAccount : ScreenRoute("managerAccount")
|
||||||
object AboutMine : ScreenRoute("aboutMine")
|
object AboutMine : ScreenRoute("aboutMine")
|
||||||
|
object DeleteAccount : ScreenRoute("deleteAccount")
|
||||||
object NetError : ScreenRoute("netError")
|
object NetError : ScreenRoute("netError")
|
||||||
}
|
}
|
||||||
|
|
@ -1,15 +1,8 @@
|
||||||
package com.img.rabbit.utils
|
package com.img.rabbit.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import com.dcloud.android.downloader.domain.DownloadInfo
|
|
||||||
import com.github.gzuliyujiang.oaid.DeviceIdentifier
|
import com.github.gzuliyujiang.oaid.DeviceIdentifier
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.img.rabbit.BuildConfig
|
import com.img.rabbit.BuildConfig
|
||||||
import com.img.rabbit.bean.response.UniVersionEntity
|
import com.img.rabbit.bean.response.UniVersionEntity
|
||||||
import com.img.rabbit.components.CenterToast
|
import com.img.rabbit.components.CenterToast
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import com.google.gson.JsonObject
|
||||||
import com.img.rabbit.bean.local.ErrorBean
|
import com.img.rabbit.bean.local.ErrorBean
|
||||||
import com.img.rabbit.bean.local.OnekeyPreLogin
|
import com.img.rabbit.bean.local.OnekeyPreLogin
|
||||||
import com.img.rabbit.bean.response.LoginInfoEntity
|
import com.img.rabbit.bean.response.LoginInfoEntity
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.pages.screen.mine.setting.BindScreenType
|
import com.img.rabbit.pages.screen.mine.setting.BindScreenType
|
||||||
import com.img.rabbit.provider.api.ApiManager
|
import com.img.rabbit.provider.api.ApiManager
|
||||||
import com.img.rabbit.provider.api.ResultVo
|
import com.img.rabbit.provider.api.ResultVo
|
||||||
|
|
@ -207,14 +208,14 @@ class BindViewModel : BaseViewModel() {
|
||||||
if (isPolicyAgreement.value) {
|
if (isPolicyAgreement.value) {
|
||||||
doWechatAuth(context, wxApi)
|
doWechatAuth(context, wxApi)
|
||||||
}else{
|
}else{
|
||||||
Toast.makeText(context, "请先同意用户协议和隐私政策", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请先同意用户协议和隐私政策")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取微信授权
|
//获取微信授权
|
||||||
private fun doWechatAuth(context: Context, wxApi: IWXAPI) {
|
private fun doWechatAuth(context: Context, wxApi: IWXAPI) {
|
||||||
if (!wxApi.isWXAppInstalled) {
|
if (!wxApi.isWXAppInstalled) {
|
||||||
Toast.makeText(context, "您没有安装微信客户端,请先下载安装", Toast.LENGTH_SHORT).show()
|
CenterToast.show("您没有安装微信客户端,请先下载安装")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isBindWxAuthor = true
|
isBindWxAuthor = true
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.img.rabbit.viewmodel
|
||||||
|
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import com.img.rabbit.bean.local.ErrorBean
|
||||||
|
import com.img.rabbit.bean.local.NotifyBean
|
||||||
|
import com.img.rabbit.provider.api.ApiManager
|
||||||
|
import com.img.rabbit.provider.storage.PreferenceUtil
|
||||||
|
import com.img.rabbit.utils.AppEventBus
|
||||||
|
import com.img.rabbit.utils.LoginBindEvent
|
||||||
|
|
||||||
|
class DeleteAccountViewModel : BaseViewModel() {
|
||||||
|
// 结果状态
|
||||||
|
val resultState = mutableStateOf<NotifyBean?>(null)
|
||||||
|
// 错误状态
|
||||||
|
val errorState = mutableStateOf<ErrorBean?>(null)
|
||||||
|
|
||||||
|
fun deleteAccount() {
|
||||||
|
isLoading.value = true // 开始加载
|
||||||
|
mLaunch {
|
||||||
|
val response = ApiManager.serviceVo.userDestroy()
|
||||||
|
if (response.status) {
|
||||||
|
resultState.value = NotifyBean(response.code.toString(), response.message.ifEmpty { "已注销!" })
|
||||||
|
|
||||||
|
PreferenceUtil.clearLogin()
|
||||||
|
AppEventBus.post( LoginBindEvent.Login(userId = null, loginType = PreferenceUtil.getLoginType(), isLogin = false, data = null) )
|
||||||
|
}else{
|
||||||
|
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "注销失败..." })
|
||||||
|
}
|
||||||
|
isLoading.value = false // 开始加载
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,6 @@ import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
|
|
@ -21,6 +20,7 @@ import com.img.rabbit.bean.local.OnekeyPreLogin
|
||||||
import com.img.rabbit.bean.local.toAlipayResult
|
import com.img.rabbit.bean.local.toAlipayResult
|
||||||
import com.img.rabbit.bean.response.LoginInfoEntity
|
import com.img.rabbit.bean.response.LoginInfoEntity
|
||||||
import com.img.rabbit.bean.response.UserConfigEntity
|
import com.img.rabbit.bean.response.UserConfigEntity
|
||||||
|
import com.img.rabbit.components.CenterToast
|
||||||
import com.img.rabbit.provider.api.ApiManager
|
import com.img.rabbit.provider.api.ApiManager
|
||||||
import com.img.rabbit.provider.api.ResultVo
|
import com.img.rabbit.provider.api.ResultVo
|
||||||
import com.img.rabbit.provider.storage.GlobalStateManager
|
import com.img.rabbit.provider.storage.GlobalStateManager
|
||||||
|
|
@ -270,7 +270,7 @@ class LoginViewModel : BaseViewModel() {
|
||||||
fun authorWechat(context: Context, wxApi:IWXAPI) {
|
fun authorWechat(context: Context, wxApi:IWXAPI) {
|
||||||
if (isPolicyAgreement.value) {
|
if (isPolicyAgreement.value) {
|
||||||
if (!wxApi.isWXAppInstalled) {
|
if (!wxApi.isWXAppInstalled) {
|
||||||
Toast.makeText(context, "您没有安装微信客户端,请先下载安装", Toast.LENGTH_SHORT).show()
|
CenterToast.show("您没有安装微信客户端,请先下载安装")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isLoginWxAuthor = true
|
isLoginWxAuthor = true
|
||||||
|
|
@ -279,7 +279,7 @@ class LoginViewModel : BaseViewModel() {
|
||||||
req.state = context.packageName + Math.random() * 1000 + "_phone"
|
req.state = context.packageName + Math.random() * 1000 + "_phone"
|
||||||
wxApi.sendReq(req)
|
wxApi.sendReq(req)
|
||||||
}else{
|
}else{
|
||||||
Toast.makeText(context, "请先同意用户协议和隐私政策", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请先同意用户协议和隐私政策")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -331,7 +331,7 @@ class LoginViewModel : BaseViewModel() {
|
||||||
|
|
||||||
private fun authorAlipay(context: Context, authParam: String){
|
private fun authorAlipay(context: Context, authParam: String){
|
||||||
if(authParam.isEmpty()){
|
if(authParam.isEmpty()){
|
||||||
Toast.makeText(context, "请先获取支付宝登录授权码", Toast.LENGTH_SHORT).show()
|
CenterToast.show("请先获取支付宝登录授权码")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 发送请求获取支付宝登录授权码
|
// 发送请求获取支付宝登录授权码
|
||||||
|
|
@ -436,13 +436,7 @@ class LoginViewModel : BaseViewModel() {
|
||||||
mLaunch {
|
mLaunch {
|
||||||
val response = ApiManager.serviceVo.logout()
|
val response = ApiManager.serviceVo.logout()
|
||||||
if (response.status) {
|
if (response.status) {
|
||||||
//logoutState.value = response
|
|
||||||
PreferenceUtil.clearLogin()
|
PreferenceUtil.clearLogin()
|
||||||
// setLogin(false)
|
|
||||||
// 跳转登录页面
|
|
||||||
// GlobalScope.launch {
|
|
||||||
// GlobalStateManager(context).storeGlobalLogoutNotify(true)
|
|
||||||
// }
|
|
||||||
AppEventBus.post( LoginBindEvent.Login(userId = null, loginType = PreferenceUtil.getLoginType(), isLogin = false, data = null) )
|
AppEventBus.post( LoginBindEvent.Login(userId = null, loginType = PreferenceUtil.getLoginType(), isLogin = false, data = null) )
|
||||||
} else {
|
} else {
|
||||||
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "退出登录失败" })
|
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "退出登录失败" })
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
|
|
@ -13,7 +13,7 @@ constraintlayout = "2.1.4"
|
||||||
splashscreen = "1.0.1"
|
splashscreen = "1.0.1"
|
||||||
datastoreCore = "1.2.0"
|
datastoreCore = "1.2.0"
|
||||||
datastorePreferences = "1.1.1"
|
datastorePreferences = "1.1.1"
|
||||||
multidex = "2.0.1"
|
#multidex = "2.0.1"
|
||||||
|
|
||||||
# Compose Version
|
# Compose Version
|
||||||
composeBom = "2024.05.00"
|
composeBom = "2024.05.00"
|
||||||
|
|
@ -80,7 +80,7 @@ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serializa
|
||||||
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
||||||
androidx-datastore-core = { group = "androidx.datastore", name = "datastore-core", version.ref = "datastoreCore" }
|
androidx-datastore-core = { group = "androidx.datastore", name = "datastore-core", version.ref = "datastoreCore" }
|
||||||
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
|
androidx-datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastorePreferences" }
|
||||||
multidex = { module = "androidx.multidex:multidex", version.ref = "multidex" }
|
#multidex = { module = "androidx.multidex:multidex", version.ref = "multidex" }
|
||||||
|
|
||||||
# Compose dependencies
|
# Compose dependencies
|
||||||
androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
|
androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue