Ver código fonte

feat: H5默认全屏(协议,账号删除除外),申请表支持检查是否填入,搜索上报曝光

DoggyZhang 2 meses atrás
pai
commit
ed460e9e94
27 arquivos alterados com 306 adições e 148 exclusões
  1. 9 0
      app/src/main/java/com/adealink/weparty/module/image/data/ImageData.kt
  2. 8 0
      app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData.kt
  3. 2 2
      app/src/main/java/com/adealink/weparty/url/UrlConfig.kt
  4. 1 0
      app/src/main/java/com/adealink/weparty/webview/BaseWebView.kt
  5. 28 1
      app/src/main/java/com/adealink/weparty/webview/WebViewFragment.kt
  6. 2 0
      app/src/main/java/com/adealink/weparty/webview/callback/IWebViewCallback.kt
  7. 5 3
      app/src/main/res/layout/fragment_webview.xml
  8. 2 0
      module/account/src/main/java/com/adealink/weparty/account/login/LoginDialog.kt
  9. 6 0
      module/joinus/src/main/java/com/adealink/weparty/playmatesetting/PlaymateSettingActivity.kt
  10. 2 17
      module/joinus/src/main/java/com/adealink/weparty/playmatesetting/page/PlaymateSettingFormFragment.kt
  11. 17 2
      module/joinus/src/main/java/com/adealink/weparty/playmatesetting/viewmodel/PlaymateSettingViewModel.kt
  12. 5 0
      module/joinus/src/main/java/com/adealink/weparty/widget/form/BaseWidgetView.kt
  13. 27 10
      module/joinus/src/main/java/com/adealink/weparty/widget/form/dialog/ExampleDialog.kt
  14. 8 0
      module/joinus/src/main/java/com/adealink/weparty/widget/form/dialog/MultipleChoiceDialog.kt
  15. 8 0
      module/joinus/src/main/java/com/adealink/weparty/widget/form/dialog/SingleChoiceDialog.kt
  16. 21 1
      module/joinus/src/main/java/com/adealink/weparty/widget/form/field/multiplechoice/MultipleChoiceWidgetView.kt
  17. 30 29
      module/joinus/src/main/java/com/adealink/weparty/widget/form/field/multipletext/MultipleTextWidgetView.kt
  18. 34 35
      module/joinus/src/main/java/com/adealink/weparty/widget/form/field/number/NumberWidgetView.kt
  19. 22 5
      module/joinus/src/main/java/com/adealink/weparty/widget/form/field/picture/PictureWidgetView.kt
  20. 11 2
      module/joinus/src/main/java/com/adealink/weparty/widget/form/field/singlechoice/SingleChoiceWidgetView.kt
  21. 30 29
      module/joinus/src/main/java/com/adealink/weparty/widget/form/field/singletext/SingleTextWidgetView.kt
  22. 10 0
      module/joinus/src/main/java/com/adealink/weparty/widget/form/field/voice/VoiceWidgetView.kt
  23. 13 5
      module/joinus/src/main/res/layout/widget_dialog_example.xml
  24. 1 1
      module/profile/src/main/java/com/adealink/weparty/profile/search/SearchActivity.kt
  25. 1 4
      module/setting/src/main/java/com/adealink/weparty/setting/SettingActivity.kt
  26. 3 0
      module/setting/src/main/java/com/adealink/weparty/setting/about/AboutActivity.kt
  27. 0 2
      module/wallet/src/main/java/com/adealink/weparty/wallet/WalletActivity.kt

+ 9 - 0
app/src/main/java/com/adealink/weparty/module/image/data/ImageData.kt

@@ -26,4 +26,13 @@ data class PhotoData(
     fun isNull(): Boolean {
         return url.isNullOrEmpty() && path.isNullOrEmpty() && uri.isNullOrEmpty()
     }
+}
+
+fun PhotoData?.sameWith(other: PhotoData?): Boolean {
+    if (this == null && other == null) {
+        return true
+    }
+    return this?.url == other?.url
+            && this?.path == other?.path
+            && this?.uri == other?.uri
 }

+ 8 - 0
app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData.kt

@@ -231,6 +231,14 @@ data class VoiceData(
     }
 }
 
+fun VoiceData?.sameWith(other: VoiceData?): Boolean {
+    if (this == null && other == null) {
+        return true
+    }
+    return this?.url == other?.url
+            && this?.path == other?.path
+}
+
 
 data class LanguageData(
     val key: String,

+ 2 - 2
app/src/main/java/com/adealink/weparty/url/UrlConfig.kt

@@ -34,8 +34,8 @@ object UrlConfig {
     }
 
     val rechargeDetail = when {
-        isProdEnv -> "http://web.gami.vip/wallet/record"
-        else -> "http://test-web.gami.vip/wallet/record"
+        isProdEnv -> "https://web.gami.vip/wallet/record"
+        else -> "https://test-web.gami.vip/wallet/record"
     }
 
     val qrCodeShare = when {

+ 1 - 0
app/src/main/java/com/adealink/weparty/webview/BaseWebView.kt

@@ -172,6 +172,7 @@ abstract class BaseWebView : SPWebView, IWebView, NestedScrollingChild3 {
 
     override fun loadUrl(url: String) {
         lUrl = url
+        webViewCallback?.beforeLoadUrl(url)
         super.loadUrl(url)
     }
 

+ 28 - 1
app/src/main/java/com/adealink/weparty/webview/WebViewFragment.kt

@@ -8,6 +8,7 @@ import android.os.Bundle
 import android.view.KeyEvent
 import android.view.View
 import android.view.ViewOutlineProvider
+import android.webkit.CookieManager
 import android.webkit.SslErrorHandler
 import androidx.core.net.toUri
 import androidx.fragment.app.FragmentManager
@@ -57,6 +58,7 @@ import com.adealink.weparty.webview.payermax.SpWebChromeClient
 import com.adealink.weparty.webview.payermax.SpWebViewClient
 import com.ushareit.easysdk.web.util.SPWebHelper
 
+
 class WebViewFragment : BaseFragment(R.layout.fragment_webview),
     IWebViewCallback {
 
@@ -245,6 +247,31 @@ class WebViewFragment : BaseFragment(R.layout.fragment_webview),
         webFragmentCallback?.setTitle(title)
     }
 
+    override fun beforeLoadUrl(url: String) {
+        val cookieManager: CookieManager = CookieManager.getInstance()
+        cookieManager.setAcceptCookie(true)
+        // 设置多个 Cookie
+        val cookies = mutableMapOf<String, String>()
+        cookies.put(
+            "GAMI-web_auth_token",
+            AppPref.token
+        )
+        cookies.put(
+            "GAMI-web_app_locale",
+            languageManager?.getLanguageCode() ?: ""
+        )
+        cookies.put(
+            "GAMI-cookie_safe_area",
+            "${(activity?.statusBarHeightDp() ?: 0)}|${(activity?.naviBarHeightDp() ?: 0)}"
+        )
+        for (entry in cookies) {
+            val cookieString: String = entry.key + "=" + entry.value + "; path=/"
+            cookieManager.setCookie(url, cookieString)
+        }
+        // 同步 Cookie
+        cookieManager.flush()
+    }
+
     /**
      * 详见: https://mimolive.sg.larksuite.com/wiki/ZYliwjteIilW5XkmdhtlysIWgGg
      */
@@ -255,7 +282,7 @@ class WebViewFragment : BaseFragment(R.layout.fragment_webview),
         loadJSUrl(
             "javascript:window.GAMI_BRIDGE={" +
                     "\"requestHeader\":${requestHeader()}," +
-                    "\"safeArea\":\"${(activity?.statusBarHeightDp() ?: 0)} ${(activity?.naviBarHeightDp() ?: 0)}\"" +
+                    "\"safeArea\":\"${(activity?.statusBarHeightDp() ?: 0)}|${(activity?.naviBarHeightDp() ?: 0)}\"" +
                     "}"
         )
     }

+ 2 - 0
app/src/main/java/com/adealink/weparty/webview/callback/IWebViewCallback.kt

@@ -19,6 +19,8 @@ interface IWebViewCallback {
 
     fun setTitle(title: String?)
 
+    fun beforeLoadUrl(url: String)
+
     fun onPageStarted(url: String?, favicon: Bitmap?)
 
     fun onPageFinished(url: String?)

+ 5 - 3
app/src/main/res/layout/fragment_webview.xml

@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/cl_main"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/cl_main"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:background="@color/white">
 
     <com.adealink.weparty.commonui.widget.nestedscrolling.NestedScrollableHost
         android:layout_width="0dp"
@@ -16,7 +17,8 @@
         <com.adealink.weparty.webview.WeNextWebView
             android:id="@+id/web_view"
             android:layout_width="match_parent"
-            android:layout_height="match_parent" />
+            android:layout_height="match_parent"
+            android:background="@color/white" />
 
     </com.adealink.weparty.commonui.widget.nestedscrolling.NestedScrollableHost>
 

+ 2 - 0
module/account/src/main/java/com/adealink/weparty/account/login/LoginDialog.kt

@@ -212,6 +212,7 @@ class LoginDialog : BaseDialogFragment(R.layout.dialog_login) {
                                                 Web.Common.EXTRA_URL,
                                                 UrlConfig.serviceTerms
                                             )
+                                            .putExtra(Web.Common.EXTRA_SHOW_TOPBAR, true)
                                             .start()
                                     }
                                 }
@@ -249,6 +250,7 @@ class LoginDialog : BaseDialogFragment(R.layout.dialog_login) {
                                                 Web.Common.EXTRA_URL,
                                                 UrlConfig.privacyPolicy
                                             )
+                                            .putExtra(Web.Common.EXTRA_SHOW_TOPBAR, true)
                                             .start()
                                     }
                                 }

+ 6 - 0
module/joinus/src/main/java/com/adealink/weparty/playmatesetting/PlaymateSettingActivity.kt

@@ -93,6 +93,12 @@ class PlaymateSettingActivity : BaseActivity() {
                 }
             }
         }
+        settingViewModel.goUnderReviewPageLD.observeWithoutCache(this) {
+            inflateUnderReviewPage()
+        }
+        settingViewModel.submitFinishLD.observeWithoutCache(this) {
+            finish()
+        }
     }
 
     override fun loadData() {

+ 2 - 17
module/joinus/src/main/java/com/adealink/weparty/playmatesetting/page/PlaymateSettingFormFragment.kt

@@ -3,7 +3,6 @@ package com.adealink.weparty.playmatesetting.page
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.updatePadding
 import androidx.fragment.app.activityViewModels
-import com.adealink.frame.base.Rlt
 import com.adealink.frame.base.fastLazy
 import com.adealink.frame.log.Log
 import com.adealink.frame.mvvm.view.viewBinding
@@ -13,11 +12,9 @@ import com.adealink.weparty.commonui.ext.contentView
 import com.adealink.weparty.commonui.ext.fitSystemWindows
 import com.adealink.weparty.commonui.ext.onWindowInsets
 import com.adealink.weparty.commonui.ext.show
-import com.adealink.weparty.commonui.toast.util.showFailedToast
 import com.adealink.weparty.commonui.toast.util.showToast
 import com.adealink.weparty.joinus.R
 import com.adealink.weparty.joinus.databinding.FragmentPlaymateSettingFormBinding
-import com.adealink.weparty.joinus.viewmodel.JoinUsViewModel
 import com.adealink.weparty.joinus.viewmodel.JoinUsViewModelFactory
 import com.adealink.weparty.playmatesetting.viewmodel.PlaymateSettingViewModel
 import com.adealink.weparty.widget.form.BaseWidgetView
@@ -33,8 +30,6 @@ class PlaymateSettingFormFragment : BaseFragment(R.layout.fragment_playmate_sett
 
 
     private val binding by viewBinding(FragmentPlaymateSettingFormBinding::bind)
-
-    private val joinUsViewModel by activityViewModels<JoinUsViewModel> { JoinUsViewModelFactory() }
     private val settingViewModel by activityViewModels<PlaymateSettingViewModel> { JoinUsViewModelFactory() }
 
     private val fieldAdapter by fastLazy { StepWidgetAdapter() }
@@ -98,18 +93,8 @@ class PlaymateSettingFormFragment : BaseFragment(R.layout.fragment_playmate_sett
     private fun clickConfirm() {
         showLoading()
         settingViewModel.submitForm(formWidgetList).observe(viewLifecycleOwner) { rlt ->
-            when (rlt) {
-                is Rlt.Failed -> {
-                    dismissLoading()
-                    showFailedToast(rlt)
-                }
-
-                is Rlt.Success -> {
-                    joinUsViewModel.loadApplyProgress().observe(viewLifecycleOwner) {
-                        dismissLoading()
-                    }
-                }
-            }
+            dismissLoading()
+            showToast(rlt)
         }
     }
 

+ 17 - 2
module/joinus/src/main/java/com/adealink/weparty/playmatesetting/viewmodel/PlaymateSettingViewModel.kt

@@ -8,6 +8,7 @@ import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
 import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.weparty.App
+import com.adealink.weparty.commonui.ext.isSuccess
 import com.adealink.weparty.module.playmate.data.PlaymateDetailData
 import com.adealink.weparty.playmatesetting.data.PlaymateSettingFormData
 import com.adealink.weparty.playmatesetting.data.PlaymateSettingFormReq
@@ -62,6 +63,8 @@ class PlaymateSettingViewModel : BaseViewModel() {
         return liveData
     }
 
+    val goUnderReviewPageLD = ExtMutableLiveData<Unit>()
+    val submitFinishLD = ExtMutableLiveData<Unit>()
     fun submitForm(formList: List<BaseWidgetView<*>>): LiveData<Rlt<Any>> {
         val liveData = OnceMutableLiveData<Rlt<Any>>()
         viewModelScope.launch {
@@ -94,8 +97,12 @@ class PlaymateSettingViewModel : BaseViewModel() {
             for (formItem in formList) {
                 val fieldValue = formItem.getFieldValue() ?: continue
                 formValueList.add(fieldValue)
-                needReview =
-                    needReview or (formItem.widgetData?.fieldData?.isFieldNeedReview() ?: false)
+                if (formItem.widgetData?.fieldData?.isFieldNeedReview() == true) {
+                    //需要审核项目有改动, 要设置为true
+                    if (formItem.hasEditFieldValue()) {
+                        needReview = true
+                    }
+                }
             }
 
             val submitRlt = settingHttpService.submitEdit(
@@ -106,6 +113,14 @@ class PlaymateSettingViewModel : BaseViewModel() {
                 )
             )
             liveData.send(submitRlt)
+            //提交审核成功,跳转审核页面
+            if (submitRlt.isSuccess) {
+                if (needReview) {
+                    goUnderReviewPageLD.send(Unit)
+                } else {
+                    submitFinishLD.send(Unit)
+                }
+            }
         }
         return liveData
     }

+ 5 - 0
module/joinus/src/main/java/com/adealink/weparty/widget/form/BaseWidgetView.kt

@@ -49,6 +49,11 @@ abstract class BaseWidgetView<DATA : IWidgetData> @JvmOverloads constructor(
      */
     abstract fun getFieldValue(): StepFieldValue?
 
+    /**
+     * 是否已经编辑
+     */
+    abstract fun hasEditFieldValue(): Boolean
+
     fun showExampleDialog() {
         val act = context.getActivity() ?: return
         val data = widgetData ?: return

+ 27 - 10
module/joinus/src/main/java/com/adealink/weparty/widget/form/dialog/ExampleDialog.kt

@@ -1,6 +1,7 @@
 package com.adealink.weparty.widget.form.dialog
 
 import android.view.View
+import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.updateLayoutParams
 import com.adealink.frame.ext.isViewBindingValid
@@ -9,7 +10,6 @@ import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.util.DisplayUtil
 import com.adealink.frame.util.onClick
 import com.adealink.frame.util.runOnUiThread
-import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.widget.BottomDialogFragment
 import com.adealink.weparty.joinus.R
@@ -58,10 +58,14 @@ class ExampleDialog : BottomDialogFragment(R.layout.widget_dialog_example) {
                                 if (this@ExampleDialog.isViewBindingValid()) {
                                     updateImageViewLp(
                                         binding.ivImg,
-                                        binding.vImageMask,
                                         imageInfo?.width,
-                                        imageInfo?.height
+                                        imageInfo?.height,
+
+
+                                        binding.clImage,
+                                        binding.vImageMask
                                     )
+
                                 }
                             }
                         }
@@ -84,24 +88,37 @@ class ExampleDialog : BottomDialogFragment(R.layout.widget_dialog_example) {
 
     private fun updateImageViewLp(
         imageView: NetworkImageView,
-        maskView: View,
         imageWidth: Int?,
-        imageHeight: Int?
+        imageHeight: Int?,
+
+        imageViewContainer: ViewGroup,
+        imageMask: View,
     ) {
         val width = imageWidth ?: 1
         val height = imageHeight ?: 1
         val imageWidth = width.coerceIn(1, width)
         val imageHeight = height.coerceIn(1, height)
+        var imageIsBig = false
         imageView.updateLayoutParams<ConstraintLayout.LayoutParams> {
             //宽高比小于1:3(长图,需要固定)
-            if (imageWidth * 1f / imageHeight < 0.33f) {
-                dimensionRatio = "1:3"
-                maskView.show()
+            dimensionRatio = if (imageWidth * 1f / imageHeight < 0.33f) {
+                imageIsBig = true
+                "1:3"
             } else {
-                dimensionRatio = "${imageWidth}:${imageHeight}"
-                maskView.gone()
+                "${imageWidth}:${imageHeight}"
             }
         }
+
+        if (imageIsBig) {
+            imageMask.show()
+            return
+        }
+
+        imageView.post {
+            val parentHeight = imageViewContainer.measuredHeight
+            val imageHeight = imageView.measuredHeight
+            imageMask.show(parentHeight < imageHeight)
+        }
     }
 
     private fun goImgPreview(url: String?) {

+ 8 - 0
module/joinus/src/main/java/com/adealink/weparty/widget/form/dialog/MultipleChoiceDialog.kt

@@ -30,6 +30,14 @@ data class MultipleChooseItem(
 
 }
 
+fun MultipleChooseItem?.sameWith(other: MultipleChooseItem?): Boolean {
+    if (this == null && other == null) {
+        return true
+    }
+    return this?.option?.key == other?.option?.key
+            && this?.option?.value == other?.option?.value
+}
+
 class MultipleChoiceDialog : BottomDialogFragment(R.layout.widget_dialog_choose) {
 
     private val binding by viewBinding(WidgetDialogChooseBinding::bind)

+ 8 - 0
module/joinus/src/main/java/com/adealink/weparty/widget/form/dialog/SingleChoiceDialog.kt

@@ -18,6 +18,14 @@ data class SingleChooseItem(
 
 }
 
+fun SingleChooseItem?.sameWith(other: SingleChooseItem?): Boolean {
+    if (this == null && other == null) {
+        return true
+    }
+    return this?.option?.key == other?.option?.key
+            && this?.option?.value == other?.option?.value
+}
+
 class SingleChoiceDialog : BottomDialogFragment(R.layout.widget_dialog_single_choose) {
 
     private val binding by viewBinding(WidgetDialogSingleChooseBinding::bind)

+ 21 - 1
module/joinus/src/main/java/com/adealink/weparty/widget/form/field/multiplechoice/MultipleChoiceWidgetView.kt

@@ -33,6 +33,7 @@ import com.adealink.weparty.widget.form.data.StringStepField
 import com.adealink.weparty.widget.form.data.StringStepFieldValue
 import com.adealink.weparty.widget.form.dialog.MultipleChoiceDialog
 import com.adealink.weparty.widget.form.dialog.MultipleChooseItem
+import com.adealink.weparty.widget.form.dialog.sameWith
 import com.adealink.weparty.R as APP_R
 
 
@@ -53,6 +54,8 @@ class MultipleChooseWidgetView(
 
     private val binding = WidgetMultipleChooseBinding.inflate(LayoutInflater.from(context), this)
 
+    private var initItemList = listOf<MultipleChooseItem>()
+
     private var chooseItemList = listOf<MultipleChooseItem>()
     private var selectItemList = listOf<MultipleChooseItem>()
 
@@ -141,15 +144,17 @@ class MultipleChooseWidgetView(
 
     private fun initSelectList(inputItems: List<String>?) {
         if (inputItems.isNullOrEmpty()) {
+            this@MultipleChooseWidgetView.initItemList = emptyList()
             this@MultipleChooseWidgetView.selectItemList = emptyList()
             return
         }
         val chooseItems = mutableListOf<MultipleChooseItem>()
         for (item in chooseItemList) {
-            if (inputItems.contains(item.option.value)) {
+            if (inputItems.contains(item.option.key)) {
                 chooseItems.add(item)
             }
         }
+        this@MultipleChooseWidgetView.initItemList = chooseItems
         notifyItemsChanged(chooseItems)
     }
 
@@ -229,6 +234,21 @@ class MultipleChooseWidgetView(
         }
     }
 
+    override fun hasEditFieldValue(): Boolean {
+        val initList = initItemList
+        val currentList = selectItemList
+        if (initList.size != currentList.size) {
+            return true
+        }
+        for ((index, item) in initList.withIndex()) {
+            val currentItem = currentList[index]
+            if (!item.sameWith(currentItem)) {
+                return true
+            }
+        }
+        return false
+    }
+
     private fun showChoice() {
         val widget = widgetData ?: return
         val act = context.getActivity() ?: return

+ 30 - 29
module/joinus/src/main/java/com/adealink/weparty/widget/form/field/multipletext/MultipleTextWidgetView.kt

@@ -64,6 +64,8 @@ class MultipleTextWidgetView(
 
     private val binding = WidgetMultipleTextBinding.inflate(LayoutInflater.from(context), this)
 
+    private var initValue: String? = null
+
     init {
         binding.etInput.addTextChangedListener(object : TextWatcher {
             override fun beforeTextChanged(
@@ -143,60 +145,53 @@ class MultipleTextWidgetView(
                     EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE or EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE
             }
         }
-        when (widgetData?.fieldData) {
+        val inputText = when (widgetData?.fieldData) {
             is DoubleArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as DoubleArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        formatNumberStr(it, false)
-                    }
-                binding.etInput.setText(inputText)
+                (widgetData?.fieldData as DoubleArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    formatNumberStr(it, false)
+                }
             }
 
             is DoubleStepField -> {
-                val inputText = (widgetData?.fieldData as DoubleStepField).fieldValue?.let {
+                (widgetData?.fieldData as DoubleStepField).fieldValue?.let {
                     formatNumberStr(it, false)
                 }
-                binding.etInput.setText(inputText)
             }
 
             is IntegerArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as IntegerArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        formatNumberStr(it, false)
-                    }
-                binding.etInput.setText(inputText)
+                (widgetData?.fieldData as IntegerArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    formatNumberStr(it, false)
+                }
             }
 
             is IntegerStepField -> {
-                val inputText = (widgetData?.fieldData as IntegerStepField).fieldValue?.let {
+                (widgetData?.fieldData as IntegerStepField).fieldValue?.let {
                     formatNumberStr(it, false)
                 }
-                binding.etInput.setText(inputText)
             }
 
             is StringArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as StringArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        it
-                    }
-                binding.etInput.setText(inputText)
+                (widgetData?.fieldData as StringArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    it
+                }
             }
 
             is StringStepField -> {
-                val inputText = (widgetData?.fieldData as StringStepField).fieldValue
-                binding.etInput.setText(inputText)
+                (widgetData?.fieldData as StringStepField).fieldValue
             }
 
             null -> {
-
+                null
             }
         }
+        initValue = inputText
+        binding.etInput.setText(inputText)
     }
 
     override fun validate(): Rlt<Any> {
@@ -372,4 +367,10 @@ class MultipleTextWidgetView(
         }
     }
 
+    override fun hasEditFieldValue(): Boolean {
+        val initValue = initValue
+        val inputValue = binding.etInput.text?.toString()
+        return initValue != inputValue
+    }
+
 }

+ 34 - 35
module/joinus/src/main/java/com/adealink/weparty/widget/form/field/number/NumberWidgetView.kt

@@ -63,6 +63,8 @@ class NumberWidgetView(
 
     private val binding = WidgetNumberBinding.inflate(LayoutInflater.from(context), this)
 
+    private var initInput: String? = null
+
     override fun onViewCreated(lifecycleOwner: LifecycleOwner, widget: NumberWidgetData) {
         super.onViewCreated(lifecycleOwner, widget)
         if (widget.fieldData.fieldName.isEmpty()) {
@@ -106,66 +108,54 @@ class NumberWidgetView(
             }
         }
 
-        when (widgetData?.fieldData) {
+        val inputText = when (widgetData?.fieldData) {
             is DoubleArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as DoubleArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        formatNumberStr(it, false)
-                    }
-                binding.etInput.setText(inputText)
-                binding.tvPriceInput.text = inputText
+                (widgetData?.fieldData as DoubleArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    formatNumberStr(it, false)
+                }
             }
 
             is DoubleStepField -> {
-                val inputText = (widgetData?.fieldData as DoubleStepField).fieldValue?.let {
+                (widgetData?.fieldData as DoubleStepField).fieldValue?.let {
                     formatNumberStr(it, false)
                 }
-                binding.etInput.setText(inputText)
-                binding.tvPriceInput.text = inputText
             }
 
             is IntegerArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as IntegerArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        formatNumberStr(it, false)
-                    }
-                binding.etInput.setText(inputText)
-                binding.tvPriceInput.text = inputText
+                (widgetData?.fieldData as IntegerArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    formatNumberStr(it, false)
+                }
             }
 
             is IntegerStepField -> {
-                val inputText = (widgetData?.fieldData as IntegerStepField).fieldValue?.let {
+                (widgetData?.fieldData as IntegerStepField).fieldValue?.let {
                     formatNumberStr(it, false)
                 }
-                binding.etInput.setText(inputText)
-                binding.tvPriceInput.text = inputText
             }
 
             is StringArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as StringArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        it
-                    }
-                binding.etInput.setText(inputText)
-                binding.tvPriceInput.text = inputText
+                (widgetData?.fieldData as StringArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    it
+                }
             }
 
             is StringStepField -> {
-                val inputText = (widgetData?.fieldData as StringStepField).fieldValue
-                binding.etInput.setText(inputText)
-                binding.tvPriceInput.text = inputText
+                (widgetData?.fieldData as StringStepField).fieldValue
             }
 
             null -> {
-
+                null
             }
         }
+        initInput = inputText
+        binding.etInput.setText(inputText)
+        binding.tvPriceInput.text = inputText
 
         if (widget.fieldData.example?.isValid() == true) {
             binding.btnExample.background = commonSelectedDrawable()
@@ -359,6 +349,15 @@ class NumberWidgetView(
         }
     }
 
+    override fun hasEditFieldValue(): Boolean {
+        val currentValue = if (widgetData?.fieldData?.isPriceField() == true) {
+            binding.tvPriceInput.text?.toString()
+        } else {
+            binding.etInput.text?.toString()
+        }
+        return initInput != currentValue
+    }
+
     private fun showPriceInputDialog() {
         val act = getActivity() ?: return
         PriceInputDialog().apply {

+ 22 - 5
module/joinus/src/main/java/com/adealink/weparty/widget/form/field/picture/PictureWidgetView.kt

@@ -29,6 +29,7 @@ import com.adealink.weparty.image.PHOTO_WALL_IMAGE_MIN_QUALITY
 import com.adealink.weparty.imageselect.comp.TakeFromAlbumComp
 import com.adealink.weparty.joinus.databinding.WidgetSinglePictureBinding
 import com.adealink.weparty.module.image.data.PhotoData
+import com.adealink.weparty.module.image.data.sameWith
 import com.adealink.weparty.util.goImagePreviewActivity
 import com.adealink.weparty.util.uploadPhotos
 import com.adealink.weparty.widget.form.BaseWidgetView
@@ -68,6 +69,7 @@ class PictureWidgetView(
 
     private val binding = WidgetSinglePictureBinding.inflate(LayoutInflater.from(context), this)
 
+    private var initPictureList = listOf<PhotoData>()
 
     private val pictureAdapter by fastLazy { MultiTypeListAdapter<BasePictureItemData>() }
 
@@ -143,12 +145,12 @@ class PictureWidgetView(
             HorizontalItemDecoration(10.dp(), 0, 0)
         )
 
+        initPictureList = ((widgetData?.fieldData as? StringArrayStepField)?.fieldValue?.map {
+            PhotoData(url = it, path = null, uri = null)
+        } ?: emptyList()).take(maxPictureLimit())
+
         pictureList.clear()
-        pictureList.addAll(
-            ((widgetData?.fieldData as? StringArrayStepField)?.fieldValue?.map {
-                PhotoData(url = it, path = null, uri = null)
-            } ?: emptyList()).take(maxPictureLimit())
-        )
+        pictureList.addAll(initPictureList)
         onPictureListChanged()
     }
 
@@ -276,4 +278,19 @@ class PictureWidgetView(
             pictureUrls
         )
     }
+
+    override fun hasEditFieldValue(): Boolean {
+        val initList = initPictureList
+        val currentList = pictureList
+        if (initList.size != currentList.size) {
+            return true
+        }
+        for ((index, data) in initList.withIndex()) {
+            val currentData = currentList[index]
+            if (!data.sameWith(currentData)) {
+                return true
+            }
+        }
+        return false
+    }
 }

+ 11 - 2
module/joinus/src/main/java/com/adealink/weparty/widget/form/field/singlechoice/SingleChoiceWidgetView.kt

@@ -33,6 +33,7 @@ import com.adealink.weparty.widget.form.data.StringStepField
 import com.adealink.weparty.widget.form.data.StringStepFieldValue
 import com.adealink.weparty.widget.form.dialog.SingleChoiceDialog
 import com.adealink.weparty.widget.form.dialog.SingleChooseItem
+import com.adealink.weparty.widget.form.dialog.sameWith
 import com.adealink.weparty.R as APP_R
 
 
@@ -52,6 +53,7 @@ class SingleChoiceWidgetView(
 
     private val binding = WidgetSingleChooseBinding.inflate(LayoutInflater.from(context), this)
 
+    private var initValue: SingleChooseItem? = null
     private var chooseItemList = listOf<SingleChooseItem>()
     private var selectItem: SingleChooseItem? = null
 
@@ -135,9 +137,10 @@ class SingleChoiceWidgetView(
             }
         }
         if (!inputText.isNullOrEmpty()) {
-            chooseItemList.find { it.option.value == inputText }?.let {
+            chooseItemList.find { it.option.key == inputText }?.let {
+                this@SingleChoiceWidgetView.initValue = it
                 this@SingleChoiceWidgetView.selectItem = it
-                binding.tvContent.text = inputText
+                binding.tvContent.text = it.option.value
             }
         }
     }
@@ -237,4 +240,10 @@ class SingleChoiceWidgetView(
         selectItem = item
         binding.tvContent.text = selectItem?.getDisplayName()
     }
+
+    override fun hasEditFieldValue(): Boolean {
+        val initValue = initValue
+        val currentValue = selectItem
+        return !initValue.sameWith(currentValue)
+    }
 }

+ 30 - 29
module/joinus/src/main/java/com/adealink/weparty/widget/form/field/singletext/SingleTextWidgetView.kt

@@ -64,6 +64,8 @@ class SingleTextWidgetView(
 
     private val binding = WidgetSingleTextBinding.inflate(LayoutInflater.from(context), this)
 
+    private var initValue: String? = null
+
     init {
         binding.etInput.addTextChangedListener(object : TextWatcher {
             override fun beforeTextChanged(
@@ -139,60 +141,53 @@ class SingleTextWidgetView(
                 binding.etInput.inputType = EditorInfo.TYPE_CLASS_TEXT
             }
         }
-        when (widgetData?.fieldData) {
+        val inputText = when (widgetData?.fieldData) {
             is DoubleArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as DoubleArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        formatNumberStr(it, false)
-                    }
-                binding.etInput.setText(inputText)
+                (widgetData?.fieldData as DoubleArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    formatNumberStr(it, false)
+                }
             }
 
             is DoubleStepField -> {
-                val inputText = (widgetData?.fieldData as DoubleStepField).fieldValue?.let {
+                (widgetData?.fieldData as DoubleStepField).fieldValue?.let {
                     formatNumberStr(it, false)
                 }
-                binding.etInput.setText(inputText)
             }
 
             is IntegerArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as IntegerArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        formatNumberStr(it, false)
-                    }
-                binding.etInput.setText(inputText)
+                (widgetData?.fieldData as IntegerArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    formatNumberStr(it, false)
+                }
             }
 
             is IntegerStepField -> {
-                val inputText = (widgetData?.fieldData as IntegerStepField).fieldValue?.let {
+                (widgetData?.fieldData as IntegerStepField).fieldValue?.let {
                     formatNumberStr(it, false)
                 }
-                binding.etInput.setText(inputText)
             }
 
             is StringArrayStepField -> {
-                val inputText =
-                    (widgetData?.fieldData as StringArrayStepField).fieldValue?.joinToString(
-                        separator = ","
-                    ) {
-                        it
-                    }
-                binding.etInput.setText(inputText)
+                (widgetData?.fieldData as StringArrayStepField).fieldValue?.joinToString(
+                    separator = ","
+                ) {
+                    it
+                }
             }
 
             is StringStepField -> {
-                val inputText = (widgetData?.fieldData as StringStepField).fieldValue
-                binding.etInput.setText(inputText)
+                (widgetData?.fieldData as StringStepField).fieldValue
             }
 
             null -> {
-
+                null
             }
         }
+        initValue = inputText
+        binding.etInput.setText(inputText)
     }
 
     override fun validate(): Rlt<Any> {
@@ -367,4 +362,10 @@ class SingleTextWidgetView(
             }
         }
     }
+
+    override fun hasEditFieldValue(): Boolean {
+        val initValue = initValue
+        val inputValue = binding.etInput.text?.toString()
+        return initValue != inputValue
+    }
 }

+ 10 - 0
module/joinus/src/main/java/com/adealink/weparty/widget/form/field/voice/VoiceWidgetView.kt

@@ -22,6 +22,7 @@ import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.toast.util.showToast
 import com.adealink.weparty.joinus.databinding.WidgetVoiceBinding
 import com.adealink.weparty.module.profile.data.VoiceData
+import com.adealink.weparty.module.profile.data.sameWith
 import com.adealink.weparty.permission.PermissionUtils
 import com.adealink.weparty.storage.file.FilePath
 import com.adealink.weparty.util.formatMissTime
@@ -66,6 +67,8 @@ class VoiceWidgetView(
 
     private val binding = WidgetVoiceBinding.inflate(LayoutInflater.from(context), this)
 
+    private var initVoiceData: VoiceData? = null
+
     private var mTimer: Timer? = null
     private var times = 0
     private var isRecording: Boolean = false
@@ -122,6 +125,7 @@ class VoiceWidgetView(
         } else {
             VoiceData(url = currentValue, null)
         }
+        initVoiceData = voiceData
         onVoiceDataChanged()
     }
 
@@ -336,4 +340,10 @@ class VoiceWidgetView(
         }
     }
 
+    override fun hasEditFieldValue(): Boolean {
+        val initData = initVoiceData
+        val currentData = voiceData
+        return !initData.sameWith(currentData)
+    }
+
 }

+ 13 - 5
module/joinus/src/main/res/layout/widget_dialog_example.xml

@@ -3,9 +3,9 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="match_parent"
     tools:background="@color/black"
-    tools:layout_height="400dp">
+    tools:layout_height="match_parent">
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/cl_content"
@@ -28,7 +28,11 @@
             android:minHeight="56dp"
             android:paddingHorizontal="16dp"
             android:paddingVertical="10dp"
-            app:layout_constraintTop_toTopOf="parent">
+            app:layout_constraintBottom_toTopOf="@id/cl_image"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed">
 
             <androidx.appcompat.widget.AppCompatTextView
                 android:id="@+id/tv_title"
@@ -66,6 +70,8 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:visibility="gone"
+            app:layout_constrainedHeight="true"
+            app:layout_constraintBottom_toTopOf="@id/cl_sound"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toBottomOf="@id/cl_top"
@@ -76,6 +82,7 @@
                 android:layout_width="0dp"
                 android:layout_height="0dp"
                 app:actualImageScaleType="bottom_crop"
+                app:layout_constraintDimensionRatio="1:1"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toTopOf="parent" />
@@ -83,7 +90,7 @@
             <View
                 android:id="@+id/v_image_mask"
                 android:layout_width="0dp"
-                android:layout_height="20dp"
+                android:layout_height="32dp"
                 android:background="@drawable/widget_example_image_mask_bg"
                 android:visibility="gone"
                 app:layout_constraintBottom_toBottomOf="parent"
@@ -98,10 +105,11 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:visibility="gone"
+            app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toBottomOf="@id/cl_image"
-            tools:visibility="visible">
+            tools:visibility="gone">
 
             <com.adealink.weparty.module.playmate.widget.SoundView
                 android:id="@+id/v_sound"

+ 1 - 1
module/profile/src/main/java/com/adealink/weparty/profile/search/SearchActivity.kt

@@ -78,7 +78,7 @@ class SearchActivity : BaseActivity(),
             position: Int
         ): BaseStatEvent? {
             val item = resultAdapter.getItem(position) ?: return null
-            return PlaymateStatEvent(PlaymateStatEvent.Action.VISIT).apply {
+            return PlaymateStatEvent(PlaymateStatEvent.Action.EXPOSURE).apply {
                 id to item.data.uid
             }
         }

+ 1 - 4
module/setting/src/main/java/com/adealink/weparty/setting/SettingActivity.kt

@@ -153,10 +153,7 @@ class SettingActivity : BaseActivity() {
                 Web.Common.EXTRA_URL,
                 UrlConfig.deleteAccount
             )
-            .putExtra(
-                Web.Common.EXTRA_SAFE_AREA,
-                true
-            )
+            .putExtra(Web.Common.EXTRA_SHOW_TOPBAR, true)
             .start()
     }
 

+ 3 - 0
module/setting/src/main/java/com/adealink/weparty/setting/about/AboutActivity.kt

@@ -65,6 +65,7 @@ class AboutActivity : BaseActivity() {
                 Web.Common.EXTRA_URL,
                 UrlConfig.privacyPolicy
             )
+            .putExtra(Web.Common.EXTRA_SHOW_TOPBAR, true)
             .start()
     }
 
@@ -74,6 +75,7 @@ class AboutActivity : BaseActivity() {
                 Web.Common.EXTRA_URL,
                 UrlConfig.serviceTerms
             )
+            .putExtra(Web.Common.EXTRA_SHOW_TOPBAR, true)
             .start()
     }
 
@@ -83,6 +85,7 @@ class AboutActivity : BaseActivity() {
                 Web.Common.EXTRA_URL,
                 UrlConfig.communityPolicy
             )
+            .putExtra(Web.Common.EXTRA_SHOW_TOPBAR, true)
             .start()
     }
 

+ 0 - 2
module/wallet/src/main/java/com/adealink/weparty/wallet/WalletActivity.kt

@@ -69,8 +69,6 @@ class WalletActivity : BaseActivity() {
     private fun goDetail() {
         Router.build(this, Web.FullScreen.PATH)
             .putExtra(Web.Common.EXTRA_URL, UrlConfig.rechargeDetail)
-            .putExtra(Web.Common.EXTRA_SHOW_TOPBAR, false)
-            .putExtra(Web.Common.EXTRA_SAFE_AREA, true)
             .start()
     }