From ff59eb9415d3df520df98e14ef66d9a3d9804c5b Mon Sep 17 00:00:00 2001
From: Runt <qingingrunt2010@qq.com>
Date: Sun, 18 May 2025 17:50:11 +0000
Subject: [PATCH] 封装dialog,popup,loading弹框, 优化权限申请 优化文件选择
---
libmvi/src/main/java/com/runt/open/mvi/base/model/BaseViewModel.kt | 48 +++++
libmvi/src/main/java/com/runt/open/mvi/retrofit/utils/RetrofitUtils.java | 13 +
libmvi/src/main/java/com/runt/open/mvi/views/PublicViews.kt | 149 ++++++++++++++++++
/dev/null | 8 -
libmvi/src/main/java/com/runt/open/mvi/CrashHandler.java | 2
libmvi/src/main/java/com/runt/open/mvi/data/MessageState.kt | 21 ++
libmvi/src/main/java/com/runt/open/mvi/OpenApplication.kt | 2
libmvi/build.gradle.kts | 2
libmvi/src/main/java/com/runt/open/mvi/base/LayoutView.kt | 19 ++
libmvi/src/main/java/com/runt/open/mvi/data/PopupMessage.kt | 8 +
libmvi/src/main/java/com/runt/open/mvi/data/LoadingState.kt | 11 +
libmvi/src/main/java/com/runt/open/mvi/base/BaseActivity.kt | 156 +++++++++++++++++++
12 files changed, 423 insertions(+), 16 deletions(-)
diff --git a/libmvi/build.gradle.kts b/libmvi/build.gradle.kts
index 7c42701..a50342d 100644
--- a/libmvi/build.gradle.kts
+++ b/libmvi/build.gradle.kts
@@ -44,6 +44,8 @@
dependencies {
+ api(libs.androidx.material3)
+ api(platform(libs.androidx.compose.bom))
api(libs.androidx.activity.compose)
api(libs.androidx.core.ktx)
api(libs.androidx.lifecycle.runtime.ktx)
diff --git a/libmvi/src/main/java/com/runt/open/mvi/CrashHandler.java b/libmvi/src/main/java/com/runt/open/mvi/CrashHandler.java
index fee8251..4152db7 100644
--- a/libmvi/src/main/java/com/runt/open/mvi/CrashHandler.java
+++ b/libmvi/src/main/java/com/runt/open/mvi/CrashHandler.java
@@ -153,7 +153,7 @@
* @return 返回文件名称,便于将文件传送到服务器
*/
private String saveCatchInfoFile(Throwable ex) {
- //ex.printStackTrace();
+ ex.printStackTrace();
//Log.i(TAG, "saveCatchInfo2File Throwable:"+ex);
StringBuffer sb = new StringBuffer();
diff --git a/libmvi/src/main/java/com/runt/open/mvi/OpenApplication.kt b/libmvi/src/main/java/com/runt/open/mvi/OpenApplication.kt
index 4bc247a..596fdcb 100644
--- a/libmvi/src/main/java/com/runt/open/mvi/OpenApplication.kt
+++ b/libmvi/src/main/java/com/runt/open/mvi/OpenApplication.kt
@@ -11,7 +11,7 @@
* @purpose
* @date 6/2/24
*/
-class OpenApplication :Application(){
+open class OpenApplication :Application(){
val TAG = "MyApplication"
var activities : MutableList<Activity> = ArrayList()
diff --git a/libmvi/src/main/java/com/runt/open/mvi/base/BaseActivity.kt b/libmvi/src/main/java/com/runt/open/mvi/base/BaseActivity.kt
index 20db9c3..91dae29 100644
--- a/libmvi/src/main/java/com/runt/open/mvi/base/BaseActivity.kt
+++ b/libmvi/src/main/java/com/runt/open/mvi/base/BaseActivity.kt
@@ -1,17 +1,24 @@
package com.runt.open.mvi.base
+import android.Manifest
import android.app.ActivityManager
+import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
+import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
+import android.provider.MediaStore
+import android.provider.Settings
+import android.text.TextUtils
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
+import android.webkit.MimeTypeMap
import android.widget.EditText
import android.widget.Toast
import androidx.activity.ComponentActivity
@@ -53,6 +60,11 @@
val PARAMS_TITLE = "title"
+ private var requestFileResult:Observer<List<String>>? = null;
+
+ private var fileLauncher : ActivityResultLauncher<Intent>? = null //选择文件
+ private var filePermissionLauncher : ActivityResultLauncher<Intent>? = null //文件权限
+ private val fileUriList = mutableListOf<Uri>()
override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate(savedInstanceState) // get genericity "B"
@@ -77,7 +89,7 @@
init();
//setContentView(mLayout)
setContent {
- mLayout!!.layout()
+ mLayout!!.layoutFrame()
}
mContext = this
TAG = this.javaClass.simpleName
@@ -85,18 +97,20 @@
mViewModel!!.onCreate(this as BaseActivity<LayoutView<BaseViewModel> , BaseViewModel>)
loadData() //加载数据
}
+
abstract fun init()
abstract fun initViews()
abstract fun loadData()
- fun registerPermissionResult(){
+ protected fun registerPermissionResult(){
permissionsLauncher = this.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
if (result == null || result.size === 0) {
permissionObserver !!.onChanged("")
return@registerForActivityResult
}
+ mViewModel!!.hidePopupWindow()
Log.d(TAG , "result:" + result + " size:" + result.size)
var allGranted = true
for (key in result.keys) {
@@ -112,6 +126,115 @@
permissionObserver !!.onChanged(com.google.gson.Gson().toJson(result.keys).replace("[" , "").replace("]" , "").replace("\"" , ""))
}
}
+ }
+
+ protected fun registerFileResult(){
+
+ filePermissionLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ Log.i(TAG,"filePermission ${result}")
+ onRequestFileResult();
+ }
+ //选择文件
+ fileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult() , object : ActivityResultCallback<ActivityResult?> {
+ override fun onActivityResult(result : ActivityResult?) {
+ Log.i(TAG,"fileLauncher ${result!!.data?.data}")
+ Log.i(TAG,"fileLauncher clipData= ${result!!.data?.clipData}")
+ fileUriList.clear();
+ result!!.data?.data?.let{
+ fileUriList.add(it);
+ }
+ result!!.data?.clipData?.let{
+ val count = it.itemCount
+ for (i in 0 until count) {
+ fileUriList.add(it.getItemAt(i).uri)
+ }
+ }
+ if(fileUriList.size == 0){
+ requestFileResult?.onChanged(ArrayList())
+ }else{
+ onRequestFileResult();
+ }
+ }
+ })
+ }
+
+ private fun onRequestFileResult(){
+
+ val cR : ContentResolver = getContentResolver()
+ val mime = MimeTypeMap.getSingleton()
+ var filePath = mViewModel!!.getFilePathFromUri(fileUriList.get(0)!!);
+ //文件不存在或读写权限受限
+ if(filePath == null){
+ //android 11需要申请权限 //是否有所有问读写权限
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && ! Environment.isExternalStorageManager()) {
+ //跳转到打开权限页面
+ var intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
+
+ intent.setData(Uri.parse("package:" + mContext!!.getPackageName()));
+ filePermissionLauncher!!.launch(intent)
+ return;
+ }
+ requestFileResult?.onChanged(ArrayList())
+ }else{
+ var filePathes = ArrayList<String>()
+ for (i in 0 until fileUriList.size) {
+ var filePath = mViewModel!!.getFilePathFromUri(fileUriList.get(i)!!);
+ filePathes.add(filePath!!)
+ }
+ requestFileResult?.onChanged(filePathes)
+ }
+ }
+
+ fun requestFile(fileType :String,maxCount:Int = 1,fileResult:Observer<List<String>>){
+ requestFileResult = fileResult;
+ var permissions = "";
+ //android 13 权限申请细化类型
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ permissions = fileType ;
+ //android 14 选择文件授权
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ permissions+=","+ Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED;
+ }
+ }else{
+ //读取权限
+ permissions = Manifest.permission.READ_EXTERNAL_STORAGE ;
+ }
+ //申请权限
+ requestPermissions(permissions , object :Observer<String>{
+ override fun onChanged(value : String) {
+ if(!value.isEmpty()){
+ var intent = Intent()
+ // intent.action = Intent.ACTION_PICK
+ // intent.action = Intent.ACTION_GET_CONTENT
+
+ //intent.setType("image/*")
+ when(fileType){
+ Manifest.permission.READ_MEDIA_VIDEO ->{
+ intent.action = MediaStore.ACTION_PICK_IMAGES
+ intent.setType("video/*") // 设置文件类型,可以更具体如"application/pdf"
+ }
+ Manifest.permission.READ_MEDIA_AUDIO ->{
+ intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+ intent.setType("audio/*") // 设置文件类型,可以更具体如"application/pdf"
+ }
+ Manifest.permission.READ_MEDIA_IMAGES ->{
+ intent.action = MediaStore.ACTION_PICK_IMAGES
+ intent.setType("image/*") // 设置文件类型,可以更具体如"application/pdf"
+ }
+ else -> {}
+ }
+ // 设置可多选
+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, maxCount > 1);
+ if(maxCount > 1){
+ //设置最大数量
+ intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxCount);
+ }
+ fileLauncher!!.launch(intent)
+ }else{
+ requestFileResult?.onChanged(ArrayList())
+ }
+ }
+ })
}
fun registerForActivityResult(callback : ActivityResultCallback<ActivityResult>):ActivityResultLauncher<Intent>{
@@ -271,7 +394,33 @@
allGranted = false
if (showPop) {
// TODO:
- //showPermissionPopu(permission)
+ var title = ""
+ var message = "";
+ if(permissions.contains(Manifest.permission.READ_EXTERNAL_STORAGE)){
+ title = "申请文件读取权限";
+ message = "通过文件读取权限后,可无障碍使用图片、音乐、视频并添加到直播的音视频流中"
+ }else if(permissions.contains(Manifest.permission.CAMERA)){
+ title = "申请相机权限";
+ message = "通过相机权限后,可将相机画面添加到直播画面流中"
+ }else if(permissions.contains(Manifest.permission.RECORD_AUDIO)){
+ title = "申请话筒权限";
+ message = "通过话筒权限后,可将话筒声音添加到直播声音流中"
+ }else if(permissions.contains(Manifest.permission.READ_MEDIA_IMAGES)){
+ title = "申请图片和视频文件权限";
+ message = "通过图片和视频文件权限后,可将图片和视频画面添加到直播画面流中"
+ }else if(permissions.contains(Manifest.permission.READ_MEDIA_VIDEO)){
+ title = "申请图片和视频文件权限";
+ message = "通过图片和视频文件权限后,可将图片和视频画面添加到直播画面流中"
+ }else if(permissions.contains(Manifest.permission.READ_MEDIA_AUDIO)){
+ title = "申请音频文件权限";
+ message = "通过音频文件权限后,可将音频文件的声音添加到直播声音流中"
+ }/*else if(permissions.contains(Manifest.permission.POST_NOTIFICATIONS)){
+ title = "申请通知栏权限";
+ message = "通过通知栏权限后,可开启后台服务,保证相机、话筒、截屏、扬声器等功能不被系统终止"
+ }*/
+ if(!TextUtils.isEmpty(title)){
+ mViewModel!!.showPopupWindow(title = title, message = message)
+ }
}
break
}
@@ -281,6 +430,7 @@
var permissionsLauncher : ActivityResultLauncher<Array<String>>? = null //权限
var permissionObserver : Observer<String>? = null //权限和文件请求回调
+
/**
* 统一权限申请
*/
diff --git a/libmvi/src/main/java/com/runt/open/mvi/base/LayoutView.kt b/libmvi/src/main/java/com/runt/open/mvi/base/LayoutView.kt
index 38aa0d7..5a863fc 100644
--- a/libmvi/src/main/java/com/runt/open/mvi/base/LayoutView.kt
+++ b/libmvi/src/main/java/com/runt/open/mvi/base/LayoutView.kt
@@ -1,7 +1,12 @@
package com.runt.open.mvi.base
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
import com.runt.open.mvi.base.model.BaseViewModel
+import com.runt.open.mvi.views.LoadingDialog
+import com.runt.open.mvi.views.MessageDialog
+import com.runt.open.mvi.views.PopupWindow
/**
* @author Runt(qingingrunt2010@qq.com)
@@ -13,5 +18,17 @@
val TAG : String = javaClass.simpleName
@Composable
- abstract fun layout();
+ fun layoutFrame(){
+ val isLoading by mViewModel.isLoading.collectAsState()
+ val messageState by mViewModel.messageState.collectAsState()
+ val popupState by mViewModel.popupState.collectAsState()
+ layout()
+ // 显示 loading 弹窗
+ LoadingDialog(isLoading)
+ MessageDialog(messageState)
+ PopupWindow(popupState)
+ }
+
+ @Composable
+ protected abstract fun layout();
}
\ No newline at end of file
diff --git a/libmvi/src/main/java/com/runt/open/mvi/base/model/BaseViewModel.kt b/libmvi/src/main/java/com/runt/open/mvi/base/model/BaseViewModel.kt
index 8ecb0d2..12fedd1 100644
--- a/libmvi/src/main/java/com/runt/open/mvi/base/model/BaseViewModel.kt
+++ b/libmvi/src/main/java/com/runt/open/mvi/base/model/BaseViewModel.kt
@@ -7,14 +7,18 @@
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.core.content.FileProvider
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.runt.open.mvi.base.BaseActivity
import com.runt.open.mvi.base.LayoutView
+import com.runt.open.mvi.data.LoadingState
+import com.runt.open.mvi.data.MessageState
+import com.runt.open.mvi.data.PopupMessage
import com.runt.open.mvi.retrofit.AndroidScheduler
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.schedulers.Schedulers
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
@@ -35,7 +39,18 @@
var TAG = "";
protected var mActivity : BaseActivity<LayoutView<BaseViewModel> , BaseViewModel>? = null
- var verifyResult = MutableLiveData<Int>()
+
+ private val _isLoading = MutableStateFlow(LoadingState())
+ val isLoading = _isLoading.asStateFlow()
+
+ val messageSetDismiss = {
+ _messageState.value = _messageState.value.copy(isVisible = false);
+ }
+ private val _messageState = MutableStateFlow(MessageState(isVisible = false, setDismiss = { }))
+ val messageState = _messageState.asStateFlow()
+
+ private val _popupState = MutableStateFlow(PopupMessage(isVisible = false,"",""))
+ val popupState = _popupState.asStateFlow()
open fun onCreate(activity : BaseActivity<LayoutView<BaseViewModel> , BaseViewModel>) {
mActivity = activity
@@ -46,6 +61,35 @@
return mActivity!!;
}
+ fun showLoading(message : String = "加载中...") {
+ _isLoading.value = LoadingState(isVisible = true,message = message);
+ }
+
+ fun hideLoading() {
+ _isLoading.value = _isLoading.value.copy(isVisible = false);
+ }
+
+ fun showDialog( title:String = "", message: String = "", confirmText:String = "确定", cancelText:String = "",
+ touchOutside:Boolean = true,//空白和系统返回 是否关闭
+ showClose:Boolean = false,//显示关闭图标(默认不显示)
+ confirmDissmiss:Boolean = true,//点击确定是否关闭
+ cancelDissmiss:Boolean = true,//点击取消是否关闭
+ onDismissRequest : () -> Unit = {},
+ onConfirmRequest : () -> Unit = {}, ){
+
+ _messageState.value = MessageState(title = title, message = message, touchOutside = touchOutside, showClose = showClose, confirmText = confirmText,
+ cancelText = cancelText, confirmDissmiss = confirmDissmiss, cancelDissmiss = cancelDissmiss, onDismissRequest = onDismissRequest,
+ onConfirmRequest = onConfirmRequest, setDismiss = messageSetDismiss);
+ }
+
+ fun showPopupWindow(title : String,message : String){
+ _popupState.value = PopupMessage(isVisible = true,title,message)
+ }
+
+ fun hidePopupWindow(){
+ _popupState.value = _popupState.value.copy(isVisible = false);
+ }
+
/**
* 获取用户信息
*/
diff --git a/libmvi/src/main/java/com/runt/open/mvi/data/LoadingState.kt b/libmvi/src/main/java/com/runt/open/mvi/data/LoadingState.kt
new file mode 100644
index 0000000..0e022d2
--- /dev/null
+++ b/libmvi/src/main/java/com/runt/open/mvi/data/LoadingState.kt
@@ -0,0 +1,11 @@
+package com.runt.open.mvi.data
+
+/**
+ * @author Runt(qingingrunt2010@qq.com)
+ * @purpose
+ * @date 5/18/25
+ */
+data class LoadingState(
+ val isVisible: Boolean = false,
+ val message: String = "加载中...",
+)
diff --git a/libmvi/src/main/java/com/runt/open/mvi/data/MessageState.kt b/libmvi/src/main/java/com/runt/open/mvi/data/MessageState.kt
new file mode 100644
index 0000000..3ff6b7e
--- /dev/null
+++ b/libmvi/src/main/java/com/runt/open/mvi/data/MessageState.kt
@@ -0,0 +1,21 @@
+package com.runt.open.mvi.data
+
+/**
+ * @author Runt(qingingrunt2010@qq.com)
+ * @purpose
+ * @date 5/18/25
+ */
+data class MessageState(
+ val isVisible: Boolean = true,
+ val title:String = "",
+ val message: String = "加载中...",
+ val confirmText:String = "确定",
+ val cancelText:String = "",
+ val touchOutside:Boolean = true,//空白和系统返回 是否关闭
+ val showClose:Boolean = false,//显示关闭图标(默认不显示)
+ val confirmDissmiss:Boolean = true,//点击确定是否关闭
+ val cancelDissmiss:Boolean = true,//点击取消是否关闭
+ val onDismissRequest : () -> Unit = {},
+ val onConfirmRequest : () -> Unit = {},
+ var setDismiss:() -> Unit
+)
\ No newline at end of file
diff --git a/libmvi/src/main/java/com/runt/open/mvi/data/PopupMessage.kt b/libmvi/src/main/java/com/runt/open/mvi/data/PopupMessage.kt
new file mode 100644
index 0000000..58767b5
--- /dev/null
+++ b/libmvi/src/main/java/com/runt/open/mvi/data/PopupMessage.kt
@@ -0,0 +1,8 @@
+package com.runt.open.mvi.data
+
+/**
+ * @author Runt(qingingrunt2010@qq.com)
+ * @purpose
+ * @date 5/19/25
+ */
+data class PopupMessage(var isVisible:Boolean,val title:String,val message:String)
\ No newline at end of file
diff --git a/libmvi/src/main/java/com/runt/open/mvi/interfaces/UIIntent.kt b/libmvi/src/main/java/com/runt/open/mvi/interfaces/UIIntent.kt
deleted file mode 100644
index d6dc2b0..0000000
--- a/libmvi/src/main/java/com/runt/open/mvi/interfaces/UIIntent.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.runt.open.mvi.interfaces
-
-/**
- * @author Runt(qingingrunt2010@qq.com)
- * @purpose
- * @date 6/2/24
- */
-interface UIIntent {}
\ No newline at end of file
diff --git a/libmvi/src/main/java/com/runt/open/mvi/interfaces/UIState.kt b/libmvi/src/main/java/com/runt/open/mvi/interfaces/UIState.kt
deleted file mode 100644
index 99dd6bf..0000000
--- a/libmvi/src/main/java/com/runt/open/mvi/interfaces/UIState.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.runt.open.mvi.interfaces
-
-/**
- * @author Runt(qingingrunt2010@qq.com)
- * @purpose
- * @date 6/2/24
- */
-interface UIState {}
\ No newline at end of file
diff --git a/libmvi/src/main/java/com/runt/open/mvi/retrofit/utils/RetrofitUtils.java b/libmvi/src/main/java/com/runt/open/mvi/retrofit/utils/RetrofitUtils.java
index 39695c3..b5b0988 100644
--- a/libmvi/src/main/java/com/runt/open/mvi/retrofit/utils/RetrofitUtils.java
+++ b/libmvi/src/main/java/com/runt/open/mvi/retrofit/utils/RetrofitUtils.java
@@ -38,6 +38,15 @@
return instance;
}
+ private Retrofit getRetrofit(OkHttpClient client,Retrofit.Builder builder,String url){
+ return builder
+ //设置OKHttpClient
+ .client(client)
+ //设置baseUrl,注意,baseUrl必须后缀"/"
+ .baseUrl(url)
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+ .build();
+ }
/**
* log输出,gson驼峰转换
* @return
@@ -53,6 +62,10 @@
return retrofit.create(clas);
}
+ public <T> T getTempRetrofit(Class<T> clas,String url) {
+ return getRetrofit(getOkHttpClient(new OkHttpClient.Builder().addInterceptor(new HttpLoggingInterceptor(BuildConfig.DEBUG))),
+ new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(true)),url).create(clas);
+ }
/**
* log输出,gson不转换驼峰
* @return
diff --git a/libmvi/src/main/java/com/runt/open/mvi/views/PublicViews.kt b/libmvi/src/main/java/com/runt/open/mvi/views/PublicViews.kt
new file mode 100644
index 0000000..3dd7708
--- /dev/null
+++ b/libmvi/src/main/java/com/runt/open/mvi/views/PublicViews.kt
@@ -0,0 +1,149 @@
+package com.runt.open.mvi.views
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.Card
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.compose.ui.window.Dialog
+import androidx.compose.ui.window.Popup
+import com.runt.open.mvi.data.LoadingState
+import com.runt.open.mvi.data.MessageState
+import com.runt.open.mvi.data.PopupMessage
+
+/**
+ * @author Runt(qingingrunt2010@qq.com)
+ * @purpose
+ * @date 5/18/25
+ */
+
+@Composable
+fun LoadingDialog( loadingState : LoadingState) {
+ if (loadingState.isVisible) {
+ Dialog(onDismissRequest = {}) {
+ Column(
+ modifier = Modifier
+ .size(140.dp)
+ .clip(RoundedCornerShape(16.dp))
+ .background(Color.White),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ CircularProgressIndicator()
+ Spacer(modifier = Modifier.height(12.dp))
+ Text(
+ text = loadingState.message,
+ fontSize = 14.sp,
+ color = Color.Black
+ )
+ }
+ }
+ }
+}
+
+@Composable
+fun MessageDialog(message : MessageState){
+ if(message.isVisible){
+ Dialog(onDismissRequest = {
+ if(message.cancelDissmiss){
+ message.setDismiss.invoke()
+ }
+ message.onDismissRequest
+ }) {
+ Card(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight()
+ .padding(16.dp),
+ shape = RoundedCornerShape(16.dp),
+ ) {
+ Column(modifier = Modifier.wrapContentHeight()){
+ Text(text = message.title, fontSize = 16.sp,
+ modifier = Modifier.fillMaxWidth()
+ .padding(top = 20.dp , start = 20.dp)
+ .wrapContentSize(Alignment.Center),
+ textAlign = TextAlign.Center)
+ Text(
+ text = message.message,
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentSize()
+ .padding(top = 30.dp , bottom = 20.dp, start = 14.dp, end = 15.dp)
+ .wrapContentSize(Alignment.Center),
+ textAlign = TextAlign.Center,
+ )
+ Row (modifier = Modifier.padding(start = 15.dp, end = 15.dp, bottom = 20.dp)){
+ if(!message.cancelText.equals("")){
+ Spacer(modifier = Modifier.weight(1f))
+ Button(onClick = {
+ if(message.cancelDissmiss){
+ message.setDismiss.invoke()
+ }
+ message.onDismissRequest
+ }) {
+ Text(text = message.cancelText)
+ }
+ }
+ Spacer(modifier = Modifier.weight(1f))
+ Button(onClick = {
+ if(message.confirmDissmiss){
+ message.setDismiss.invoke()
+ }
+ message.onConfirmRequest
+ }) {
+ Text(text = message.confirmText)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+@Composable
+fun PopupWindow(popupMessage : PopupMessage){
+ if(popupMessage.isVisible){
+ Popup(
+ alignment = Alignment.TopCenter,
+ ) {
+ Surface(
+ modifier = Modifier.fillMaxWidth()
+ .wrapContentHeight().padding(10.dp),
+ shadowElevation = 2.dp,
+ border = BorderStroke(1.dp, Color.Gray) ,
+ shape = RoundedCornerShape(8.dp)
+ ) {
+ Column(
+ modifier = Modifier.padding(16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Text(popupMessage.title)
+ Spacer(modifier = Modifier.height(16.dp))
+ Text(popupMessage.message)
+ Spacer(modifier = Modifier.height(15.dp))
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--
Gitblit v1.9.1