소스 검색

feat: 用户音频录制编辑

DoggyZhang 2 달 전
부모
커밋
6a2ea27adc
22개의 변경된 파일330개의 추가작업 그리고 87개의 파일을 삭제
  1. 36 7
      app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData.kt
  2. 4 0
      app/src/main/java/com/adealink/weparty/module/profile/viewmodel/IProfileViewModel.kt
  3. 2 2
      module/account/src/main/java/com/adealink/weparty/account/register/RegisterProfileActivity.kt
  4. 6 4
      module/profile/src/main/java/com/adealink/weparty/profile/data/ProfileData.kt
  5. 11 4
      module/profile/src/main/java/com/adealink/weparty/profile/datasource/remote/ProfileHttpService.kt
  6. 10 4
      module/profile/src/main/java/com/adealink/weparty/profile/edit/EditProfileActivity.kt
  7. 12 8
      module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditTalentComp.kt
  8. 29 12
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditTalentVoiceDialog.kt
  9. 28 4
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/VoiceEditFragment.kt
  10. 13 9
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/VoiceFragment.kt
  11. 21 0
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/VoiceUnderReviewFragment.kt
  12. 74 5
      module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/viewmodel/EditVoiceViewModel.kt
  13. 0 6
      module/profile/src/main/java/com/adealink/weparty/profile/edit/viewmodel/EditProfileViewModel.kt
  14. 2 1
      module/profile/src/main/java/com/adealink/weparty/profile/manager/IProfileManager.kt
  15. 3 2
      module/profile/src/main/java/com/adealink/weparty/profile/manager/ProfileManager.kt
  16. 20 18
      module/profile/src/main/java/com/adealink/weparty/profile/viewmodel/ProfileViewModel.kt
  17. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_voice_under_review_ic.png
  18. 52 0
      module/profile/src/main/res/layout/fragment_talent_voice_under_review.xml
  19. 2 0
      module/profile/src/main/res/values-in/strings.xml
  20. 2 0
      module/profile/src/main/res/values-zh/strings.xml
  21. 2 0
      module/profile/src/main/res/values/strings.xml
  22. 1 1
      module/wallet/src/main/java/com/adealink/weparty/wallet/comp/MyIncomeComp.kt

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

@@ -167,11 +167,6 @@ open class EditUserInfo() {
             isEdited = true
         }
 
-    var voice: VoiceData? = null
-        set(value) {
-            field = value
-        }
-
     open fun resetBy(userInfo: UserInfo?) {
         avatar = PhotoData(url = userInfo?.avatar, null, null)
         nickname = userInfo?.nickName
@@ -182,7 +177,6 @@ open class EditUserInfo() {
         intro = userInfo?.intro
         birthday = userInfo?.birthday
         interest = userInfo?.interests
-        voice = VoiceData(url = userInfo?.voiceBar, null)
         isEdited = false
     }
 
@@ -241,4 +235,39 @@ data class VoiceData(
 data class LanguageData(
     val key: String,
     val language: String
-)
+)
+
+data class MyUserInfoData(
+    @SerializedName("userProfile") val userInfo: UserInfo,
+    @GsonNullable
+    @SerializedName("userVoice") val userVoiceEdit: UserVoiceEditData? = null, //用户编辑语音
+)
+
+@Parcelize
+data class UserVoiceEditData(
+    @GsonNullable
+    @SerializedName("voiceBar") val voiceBar: String?, //语音条
+    @SerializedName("voiceBarDuration") val voiceBarDuration: Int, //时长:秒
+    @SerializedName("status") val status: Int, //0:待上传,1:待审核,2:审核通过展示中
+    @GsonNullable
+    @SerializedName("applyingVoiceBar") val applyingVoiceBar: String?, //申请中的语音条
+    @GsonNullable
+    @SerializedName("applyingVoiceBarDuration") val applyingVoiceBarDuration: Int?, //请中的语音条-时长(秒)
+) : Parcelable {
+
+    fun isDisplay(): Boolean {
+        return !voiceBar.isNullOrEmpty() && status == 2
+    }
+
+    fun isUnderReview(): Boolean {
+        return status == 1
+    }
+
+    fun getVoiceIfPass(): String? {
+        return if (status == 2) {
+            voiceBar
+        } else {
+            null
+        }
+    }
+}

+ 4 - 0
app/src/main/java/com/adealink/weparty/module/profile/viewmodel/IProfileViewModel.kt

@@ -3,12 +3,16 @@ package com.adealink.weparty.module.profile.viewmodel
 import androidx.lifecycle.LiveData
 import com.adealink.frame.base.Rlt
 import com.adealink.weparty.module.profile.data.EditUserInfo
+import com.adealink.weparty.module.profile.data.MyUserInfoData
 import com.adealink.weparty.module.profile.data.UserInfo
 
 interface IProfileViewModel {
 
     val userInfoLD: LiveData<UserInfo?>
 
+    val myUserInfoLD: LiveData<MyUserInfoData?>
+    fun pullMyUserInfo(): LiveData<Rlt<MyUserInfoData?>>
+
     fun pullUserInfoBy(uid: String, cache: Boolean): LiveData<Rlt<UserInfo>>
 
     fun pullUserInoBy(uids: List<String>, cache: Boolean): LiveData<Rlt<Map<String, UserInfo>>>

+ 2 - 2
module/account/src/main/java/com/adealink/weparty/account/register/RegisterProfileActivity.kt

@@ -95,7 +95,7 @@ class RegisterProfileActivity : BaseActivity() {
 
     private fun inflateSelectGenderFragment() {
         val fragment = supportFragmentManager.findFragmentByTag(TAG_SELECT_GENDER_FRAGMENT)
-        if (fragment?.isDetached == true) {
+        if (fragment?.isAdded == true) {
             return
         }
         supportFragmentManager.beginTransaction()
@@ -115,7 +115,7 @@ class RegisterProfileActivity : BaseActivity() {
 
     private fun inflateSelectCategoryFragment() {
         val fragment = supportFragmentManager.findFragmentByTag(TAG_SELECT_CATEGORY_FRAGMENT)
-        if (fragment?.isDetached == true) {
+        if (fragment?.isAdded == true) {
             return
         }
         supportFragmentManager.beginTransaction()

+ 6 - 4
module/profile/src/main/java/com/adealink/weparty/profile/data/ProfileData.kt

@@ -3,10 +3,6 @@ package com.adealink.weparty.profile.data
 import com.adealink.weparty.module.profile.data.UserInfo
 import com.google.gson.annotations.SerializedName
 
-data class MyUserInfoRes(
-    @SerializedName("userProfile") val userInfo: UserInfo
-)
-
 data class GetUserinfoReq(
     @SerializedName("userNos") val uids: List<String>
 )
@@ -42,4 +38,10 @@ data class UserOnlineRes(
 data class UserOnlineData(
     @SerializedName("userNo") val userNo: String,
     @SerializedName("online") val online: Boolean,
+)
+
+
+data class UserVoiceApplyReq(
+    @SerializedName("voiceBar") val voiceBar: String,
+    @SerializedName("voiceBarDuration") val duration: Int //单位:秒
 )

+ 11 - 4
module/profile/src/main/java/com/adealink/weparty/profile/datasource/remote/ProfileHttpService.kt

@@ -2,13 +2,14 @@ package com.adealink.weparty.profile.datasource.remote
 
 import com.adealink.frame.base.Rlt
 import com.adealink.frame.network.data.Res
+import com.adealink.weparty.module.profile.data.MyUserInfoData
 import com.adealink.weparty.profile.data.GetUserInfosRes
 import com.adealink.weparty.profile.data.GetUserinfoReq
-import com.adealink.weparty.profile.data.UserOnlineReq
-import com.adealink.weparty.profile.data.UserOnlineRes
-import com.adealink.weparty.profile.data.MyUserInfoRes
 import com.adealink.weparty.profile.data.PlaymateCharmStarReq
 import com.adealink.weparty.profile.data.UpdateMyUserInfoReq
+import com.adealink.weparty.profile.data.UserOnlineReq
+import com.adealink.weparty.profile.data.UserOnlineRes
+import com.adealink.weparty.profile.data.UserVoiceApplyReq
 import retrofit2.http.Body
 import retrofit2.http.Core
 import retrofit2.http.POST
@@ -17,7 +18,7 @@ interface ProfileHttpService {
 
     @Core
     @POST("user/my/info")
-    suspend fun getMyUserInfo(): Rlt<Res<MyUserInfoRes>>
+    suspend fun getMyUserInfo(): Rlt<Res<MyUserInfoData>>
 
     @POST("user/my/info/edit")
     suspend fun updateUserInfo(
@@ -41,4 +42,10 @@ interface ProfileHttpService {
     suspend fun isUserOnline(
         @Body req: UserOnlineReq
     ): Rlt<Res<UserOnlineRes>>
+
+    @POST("user/my/voiceBarApply")
+    suspend fun userVoiceApply(
+        @Body req: UserVoiceApplyReq
+    ): Rlt<Res<Any>>
+
 }

+ 10 - 4
module/profile/src/main/java/com/adealink/weparty/profile/edit/EditProfileActivity.kt

@@ -18,7 +18,6 @@ import com.adealink.weparty.commonui.toast.util.showFailedToast
 import com.adealink.weparty.commonui.toast.util.showToast
 import com.adealink.weparty.commonui.widget.CommonDialog
 import com.adealink.weparty.module.profile.Profile
-import com.adealink.weparty.module.profile.ProfileModule
 import com.adealink.weparty.profile.R
 import com.adealink.weparty.profile.databinding.ActivityEditProfileBinding
 import com.adealink.weparty.profile.edit.comp.EditAvatarComp
@@ -73,14 +72,21 @@ class EditProfileActivity : BaseActivity() {
         EditTalentComp(this, binding.vTalent).attach()
     }
 
-    override fun loadData() {
-        super.loadData()
-        editViewModel.setUserInfo(ProfileModule.getMyUserInfo())
+    override fun observeViewModel() {
+        super.observeViewModel()
+        profileViewModel.myUserInfoLD.observe(this) {
+            editViewModel.setUserInfo(it?.userInfo)
+        }
         editViewModel.editUserInfoLD.observe(this) { edit ->
             binding.btnSave.isEnabled = edit.isEdited
         }
     }
 
+    override fun loadData() {
+        super.loadData()
+        profileViewModel.pullMyUserInfo()
+    }
+
     private fun clickClose() {
         val editUserInfo = editViewModel.getEditUserInfo()
         if (editUserInfo.isEdited) {

+ 12 - 8
module/profile/src/main/java/com/adealink/weparty/profile/edit/comp/EditTalentComp.kt

@@ -9,8 +9,9 @@ import com.adealink.weparty.module.profile.data.VoiceData
 import com.adealink.weparty.profile.R
 import com.adealink.weparty.profile.databinding.LayoutEditProfilePersonTalentBinding
 import com.adealink.weparty.profile.edit.dialog.EditTalentVoiceDialog
-import com.adealink.weparty.profile.edit.viewmodel.EditProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
+import com.adealink.weparty.R as APP_R
 
 class EditTalentComp(
     lifecycleOwner: LifecycleOwner,
@@ -21,7 +22,7 @@ class EditTalentComp(
         private const val SOURCE_TAG = "EditTalentComp"
     }
 
-    private val editViewModel by activityViewModels<EditProfileViewModel> { ProfileViewModelFactory() }
+    private val profileViewModel by activityViewModels<ProfileViewModel> { ProfileViewModelFactory() }
 
     override fun onCreate() {
         super.onCreate()
@@ -36,21 +37,24 @@ class EditTalentComp(
     }
 
     private fun observeViewModel() {
-        editViewModel.editUserInfoLD.observe(viewLifecycleOwner) { userInfo ->
-            if (userInfo.voice == null || userInfo.voice?.isNull() == null) {
-                binging.tvVoice.text = null
-            } else {
+        profileViewModel.myUserInfoLD.observe(viewLifecycleOwner) { userInfo ->
+            val userVoice = userInfo?.userVoiceEdit
+            if (userVoice != null && userVoice.isDisplay()) {
                 binging.tvVoice.text = getCompatString(R.string.profile_edit_voice_not_empty)
+            } else if (userVoice != null && userVoice.isUnderReview()) {
+                binging.tvVoice.text = getCompatString(APP_R.string.common_under_review)
+            } else {
+                binging.tvVoice.text = null
             }
         }
     }
 
     private fun editIntro() {
         EditTalentVoiceDialog().apply {
-            setVoice(editViewModel.editUserInfoLD.value?.voice)
+            setVoice(profileViewModel.myUserInfoLD.value?.userVoiceEdit)
             setCallback(object : EditTalentVoiceDialog.ITalentVoiceCallback {
                 override fun onEditVoice(voice: VoiceData?) {
-                    editViewModel.setVoice(voice)
+
                 }
             })
         }.show(fragmentManager, "EditVoice")

+ 29 - 12
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/EditTalentVoiceDialog.kt

@@ -6,11 +6,13 @@ import androidx.fragment.app.viewModels
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.util.naviBarHeight
 import com.adealink.weparty.commonui.widget.BottomDialogFragment
+import com.adealink.weparty.module.profile.data.UserVoiceEditData
 import com.adealink.weparty.module.profile.data.VoiceData
 import com.adealink.weparty.profile.R
 import com.adealink.weparty.profile.databinding.DialogEditTalentVoiceBinding
 import com.adealink.weparty.profile.edit.dialog.fragment.VoiceEditFragment
 import com.adealink.weparty.profile.edit.dialog.fragment.VoiceFragment
+import com.adealink.weparty.profile.edit.dialog.fragment.VoiceUnderReviewFragment
 import com.adealink.weparty.profile.edit.dialog.viewmodel.EditVoicePage
 import com.adealink.weparty.profile.edit.dialog.viewmodel.EditVoiceViewModel
 
@@ -19,6 +21,8 @@ class EditTalentVoiceDialog : BottomDialogFragment(R.layout.dialog_edit_talent_v
     companion object {
         private const val TAG_VOICE = "TAG_TALENT_VOICE"
         private const val TAG_VOICE_EDIT = "TAG_TALENT_VOICE_EDIT"
+
+        private const val TAG_VOICE_REVIEW = "TAG_TALENT_VOICE_REVIEW"
     }
 
     private val binding by viewBinding(DialogEditTalentVoiceBinding::bind)
@@ -26,10 +30,12 @@ class EditTalentVoiceDialog : BottomDialogFragment(R.layout.dialog_edit_talent_v
     private val viewModel by viewModels<EditVoiceViewModel>()
     private var callback: ITalentVoiceCallback? = null
 
+    private var editVoice: UserVoiceEditData? = null
     private var voice: VoiceData? = null
 
-    fun setVoice(voice: VoiceData?) {
-        this.voice = voice
+    fun setVoice(voice: UserVoiceEditData?) {
+        this.editVoice = voice
+        this.voice = VoiceData(url = voice?.voiceBar, null, null)
     }
 
     fun setCallback(callback: ITalentVoiceCallback?) {
@@ -54,25 +60,22 @@ class EditTalentVoiceDialog : BottomDialogFragment(R.layout.dialog_edit_talent_v
                 EditVoicePage.EDIT -> {
                     inflateVoiceEditFragment()
                 }
+
+                EditVoicePage.REVIEW -> {
+                    inflateUnderReviewFragment()
+                }
             }
         }
     }
 
     override fun loadData() {
         super.loadData()
-        viewModel.showPage(EditVoicePage.EDIT)
-        // TODO: zhangfei 先做录音部分, 审核后续再加
-//        if (voice == null || voice?.isNull() == true) {
-//            //未上传声音
-//            viewModel.showPage(EditVoicePage.EDIT)
-//        } else {
-//            viewModel.showPage(EditVoicePage.VOICE)
-//        }
+        viewModel.setEditVoice(editVoice)
     }
 
     private fun inflateVoiceFragment() {
         val fragment = childFragmentManager.findFragmentByTag(TAG_VOICE)
-        if (fragment?.isDetached == true) {
+        if (fragment?.isAdded == true) {
             return
         }
         childFragmentManager.beginTransaction()
@@ -86,7 +89,7 @@ class EditTalentVoiceDialog : BottomDialogFragment(R.layout.dialog_edit_talent_v
 
     private fun inflateVoiceEditFragment() {
         val fragment = childFragmentManager.findFragmentByTag(TAG_VOICE_EDIT)
-        if (fragment?.isDetached == true) {
+        if (fragment?.isAdded == true) {
             return
         }
         childFragmentManager.beginTransaction()
@@ -98,6 +101,20 @@ class EditTalentVoiceDialog : BottomDialogFragment(R.layout.dialog_edit_talent_v
             .commitAllowingStateLoss()
     }
 
+    private fun inflateUnderReviewFragment() {
+        val fragment = childFragmentManager.findFragmentByTag(TAG_VOICE_REVIEW)
+        if (fragment?.isAdded == true) {
+            return
+        }
+        childFragmentManager.beginTransaction()
+            .replace(
+                R.id.fl_content,
+                VoiceUnderReviewFragment(),
+                TAG_VOICE_REVIEW
+            )
+            .commitAllowingStateLoss()
+    }
+
 
     interface ITalentVoiceCallback {
         fun onEditVoice(voice: VoiceData?)

+ 28 - 4
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/VoiceEditFragment.kt

@@ -3,8 +3,10 @@ package com.adealink.weparty.profile.edit.dialog.fragment
 import android.Manifest
 import android.annotation.SuppressLint
 import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.lifecycleScope
 import com.adealink.frame.aab.util.getCompatString
+import com.adealink.frame.base.Rlt
 import com.adealink.frame.ext.isViewBindingValid
 import com.adealink.frame.log.Log
 import com.adealink.frame.mvvm.view.viewBinding
@@ -13,13 +15,15 @@ import com.adealink.frame.util.runOnUiThread
 import com.adealink.weparty.commonui.BaseFragment
 import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
-import com.adealink.weparty.commonui.toast.util.debugToast
 import com.adealink.weparty.commonui.toast.util.showToast
 import com.adealink.weparty.permission.PermissionUtils
 import com.adealink.weparty.profile.R
 import com.adealink.weparty.profile.databinding.FragmentTalentVoiceEditBinding
 import com.adealink.weparty.profile.edit.dialog.EditTalentVoiceDialog
+import com.adealink.weparty.profile.edit.dialog.viewmodel.EditVoicePage
 import com.adealink.weparty.profile.edit.dialog.viewmodel.EditVoiceViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
 import com.adealink.weparty.storage.file.FilePath
 import com.adealink.weparty.util.formatMissTime
 import com.adealink.weparty.viewmodel.parentFragmentViewModels
@@ -46,6 +50,8 @@ class VoiceEditFragment : BaseFragment(R.layout.fragment_talent_voice_edit) {
         EditTalentVoiceDialog::class.java
     )
 
+    private val profileViewModel by activityViewModels<ProfileViewModel> { ProfileViewModelFactory() }
+
     private var mTimer: Timer? = null
     private var times = 0
 
@@ -63,7 +69,7 @@ class VoiceEditFragment : BaseFragment(R.layout.fragment_talent_voice_edit) {
             audioPreview()
         }
         binding.btnSubmit.onClick {
-            debugToast("录音审核功能未实现,目前仅支持录音过程")
+            submit()
         }
     }
 
@@ -146,10 +152,10 @@ class VoiceEditFragment : BaseFragment(R.layout.fragment_talent_voice_edit) {
                 val duration = AudioRecorder.getDuration(outputPath)
                 if (duration < 3000) {
                     showToast(APP_R.string.profile_record_voice_less_than_3_seconds)
-                    editViewModel.setVoiceData(null)
+                    editViewModel.setVoiceData(null, null)
                     return
                 }
-                editViewModel.setVoiceData(outputPath)
+                editViewModel.setVoiceData(outputPath, duration)
             }
 
             override fun onFailed(errorCode: Int, errorMessage: String?) {
@@ -235,6 +241,24 @@ class VoiceEditFragment : BaseFragment(R.layout.fragment_talent_voice_edit) {
         }
     }
 
+    private fun submit() {
+        showLoading()
+        editViewModel.submit().observe(viewLifecycleOwner) { rlt ->
+            dismissLoading()
+            showToast(rlt)
+            when (rlt) {
+                is Rlt.Failed -> {
+                    //Ntd.
+                }
+
+                is Rlt.Success -> {
+                    profileViewModel.pullMyUserInfo()
+                    editViewModel.showPage(EditVoicePage.REVIEW)
+                }
+            }
+        }
+    }
+
     override fun onDestroyView() {
         super.onDestroyView()
         AudioPlayer.getInstance().stopPlay()

+ 13 - 9
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/VoiceFragment.kt

@@ -1,15 +1,13 @@
 package com.adealink.weparty.profile.edit.dialog.fragment
 
-import androidx.fragment.app.activityViewModels
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.util.onClick
 import com.adealink.weparty.commonui.BaseFragment
 import com.adealink.weparty.profile.R
 import com.adealink.weparty.profile.databinding.FragmentTalentVoiceBinding
 import com.adealink.weparty.profile.edit.dialog.EditTalentVoiceDialog
+import com.adealink.weparty.profile.edit.dialog.viewmodel.EditVoicePage
 import com.adealink.weparty.profile.edit.dialog.viewmodel.EditVoiceViewModel
-import com.adealink.weparty.profile.edit.viewmodel.EditProfileViewModel
-import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
 import com.adealink.weparty.viewmodel.parentFragmentViewModels
 
 class VoiceFragment : BaseFragment(R.layout.fragment_talent_voice) {
@@ -20,19 +18,25 @@ class VoiceFragment : BaseFragment(R.layout.fragment_talent_voice) {
         EditTalentVoiceDialog::class.java
     )
 
-    private val editViewModel by activityViewModels<EditProfileViewModel> { ProfileViewModelFactory() }
-
     override fun initViews() {
         super.initViews()
-        val voice = editViewModel.getEditUserInfo().voice
-        binding.vSound.setSound(voice)
+        val voiceData = viewModel.voiceDataLD.value
+        binding.vSound.setSound(voiceData)
         binding.btnRecord.onClick {
+            clearAndRecode()
+        }
+    }
 
+    override fun observeViewModel() {
+        super.observeViewModel()
+        viewModel.voiceDataLD.observe(viewLifecycleOwner) {
+            binding.vSound.setSound(it)
         }
     }
 
-    override fun loadData() {
-        super.loadData()
+    private fun clearAndRecode() {
+        viewModel.setVoiceData(null)
+        viewModel.showPage(EditVoicePage.EDIT)
     }
 
 }

+ 21 - 0
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/fragment/VoiceUnderReviewFragment.kt

@@ -0,0 +1,21 @@
+package com.adealink.weparty.profile.edit.dialog.fragment
+
+import com.adealink.frame.mvvm.view.viewBinding
+import com.adealink.weparty.commonui.BaseFragment
+import com.adealink.weparty.profile.R
+import com.adealink.weparty.profile.databinding.FragmentTalentVoiceUnderReviewBinding
+
+class VoiceUnderReviewFragment : BaseFragment(R.layout.fragment_talent_voice_under_review) {
+
+    companion object {
+        private const val TAG = "VoiceUnderReviewFragment"
+    }
+
+    private val binding by viewBinding(FragmentTalentVoiceUnderReviewBinding::bind)
+
+    override fun initViews() {
+        super.initViews()
+    }
+
+
+}

+ 74 - 5
module/profile/src/main/java/com/adealink/weparty/profile/edit/dialog/viewmodel/EditVoiceViewModel.kt

@@ -1,34 +1,103 @@
 package com.adealink.weparty.profile.edit.dialog.viewmodel
 
+import androidx.lifecycle.LiveData
+import com.adealink.frame.base.CommonDataNullError
+import com.adealink.frame.base.Rlt
 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.isFailure
+import com.adealink.weparty.module.profile.data.UserVoiceEditData
 import com.adealink.weparty.module.profile.data.VoiceData
+import com.adealink.weparty.profile.data.UserVoiceApplyReq
+import com.adealink.weparty.profile.datasource.remote.ProfileHttpService
+import com.adealink.weparty.util.uploadVoice
+import kotlinx.coroutines.launch
 
 enum class EditVoicePage {
-    VOICE,
-    EDIT
+    VOICE, //展示当前语音
+    EDIT, //编辑语音
+    REVIEW, //审核
 }
 
 class EditVoiceViewModel : BaseViewModel() {
 
+    private val profileHttpService by lazy {
+        App.instance.networkService.getHttpService(ProfileHttpService::class.java)
+    }
+
     val pageLD = ExtMutableLiveData<EditVoicePage>()
 
     fun showPage(page: EditVoicePage) {
         pageLD.send(page)
     }
 
+    private var editVoice: UserVoiceEditData? = null
+    val editVoiceLD = ExtMutableLiveData<UserVoiceEditData?>()
+    fun setEditVoice(editVoice: UserVoiceEditData?) {
+        this.editVoice = editVoice
+        editVoiceLD.send(editVoice)
+        setVoiceData(editVoice?.voiceBar)
+        if (editVoice == null) {
+            showPage(EditVoicePage.EDIT)
+        } else if (editVoice.isDisplay()) {
+            showPage(EditVoicePage.VOICE)
+        } else if (editVoice.isUnderReview()) {
+            showPage(EditVoicePage.REVIEW)
+        } else {
+            showPage(EditVoicePage.EDIT)
+        }
+    }
+
 
     /**
      * 录制声音
      */
-
     private var voiceData: VoiceData? = null
     val voiceDataLD = ExtMutableLiveData<VoiceData>()
 
-    fun setVoiceData(path: String?) {
-        val data = VoiceData(url = null, path = path)
+    fun setVoiceData(url: String?) {
+        val data = VoiceData(url = url, null, null)
+        voiceData = data
+        voiceDataLD.send(data)
+    }
+
+    fun setVoiceData(path: String?, duration: Int?) {
+        val data = VoiceData(url = null, path = path, duration = duration)
         voiceData = data
         voiceDataLD.send(data)
     }
 
+    fun submit(): LiveData<Rlt<Any>> {
+        val liveData = OnceMutableLiveData<Rlt<Any>>()
+        viewModelScope.launch {
+            val voiceData = voiceData
+            if (voiceData == null || voiceData.isNull()) {
+                liveData.send(Rlt.Failed(CommonDataNullError()))
+                return@launch
+            }
+
+            val uploadRlt = uploadVoice(voiceData)
+            if (uploadRlt.isFailure) {
+                liveData.send(uploadRlt)
+                return@launch
+            }
+
+            val voiceUrl = voiceData.url
+            if (voiceUrl.isNullOrEmpty()) {
+                liveData.send(Rlt.Failed(CommonDataNullError()))
+                return@launch
+            }
+
+            val applyRlt = profileHttpService.userVoiceApply(
+                UserVoiceApplyReq(
+                    voiceUrl, voiceData.duration ?: 0
+                )
+            )
+            liveData.send(applyRlt)
+        }
+        return liveData
+    }
+
 }

+ 0 - 6
module/profile/src/main/java/com/adealink/weparty/profile/edit/viewmodel/EditProfileViewModel.kt

@@ -8,7 +8,6 @@ import com.adealink.weparty.module.profile.data.EditUserInfo
 import com.adealink.weparty.module.profile.data.Gender
 import com.adealink.weparty.module.profile.data.UserInfo
 import com.adealink.weparty.module.profile.data.UserInterest
-import com.adealink.weparty.module.profile.data.VoiceData
 import com.adealink.weparty.profile.edit.data.AddPhotoItemData
 import com.adealink.weparty.profile.edit.data.BasePhotoItemData
 import com.adealink.weparty.profile.edit.data.PhotoItemData
@@ -139,9 +138,4 @@ class EditProfileViewModel : BaseViewModel() {
         editUserInfo.interest = interest
         editUserInfoLD.send(editUserInfo)
     }
-
-    fun setVoice(voice: VoiceData?) {
-        editUserInfo.voice = voice
-        editUserInfoLD.send(editUserInfo)
-    }
 }

+ 2 - 1
module/profile/src/main/java/com/adealink/weparty/profile/manager/IProfileManager.kt

@@ -2,6 +2,7 @@ package com.adealink.weparty.profile.manager
 
 import com.adealink.frame.base.Rlt
 import com.adealink.frame.frame.IBaseFrame
+import com.adealink.weparty.module.profile.data.MyUserInfoData
 import com.adealink.weparty.module.profile.data.UserConfigType
 import com.adealink.weparty.module.profile.data.UserInfo
 import com.adealink.weparty.module.profile.listener.IProfileListener
@@ -11,7 +12,7 @@ interface IProfileManager : IBaseFrame<IProfileListener> {
 
     fun getMyUserInfo(): UserInfo?
 
-    suspend fun pullMyUserInfo(): Rlt<UserInfo?>
+    suspend fun pullMyUserInfo(): Rlt<MyUserInfoData?>
 
     fun setMyUserInfo(userInfo: UserInfo, attrSet: Set<UserConfigType>?)
 

+ 3 - 2
module/profile/src/main/java/com/adealink/weparty/profile/manager/ProfileManager.kt

@@ -12,6 +12,7 @@ import com.adealink.frame.log.Log
 import com.adealink.frame.storage.cache.TimeoutLruCache
 import com.adealink.weparty.App
 import com.adealink.weparty.module.account.AccountModule
+import com.adealink.weparty.module.profile.data.MyUserInfoData
 import com.adealink.weparty.module.profile.data.UserConfigType
 import com.adealink.weparty.module.profile.data.UserConfigType.Companion.NECESSARY_USER_ATTR_SET
 import com.adealink.weparty.module.profile.data.UserInfo
@@ -55,7 +56,7 @@ class ProfileManager : BaseFrame<IProfileListener>(), IProfileManager, ILanguage
         return userInfoCache[AccountModule.uid] ?: getMyUserInfoFromCache()
     }
 
-    override suspend fun pullMyUserInfo(): Rlt<UserInfo?> {
+    override suspend fun pullMyUserInfo(): Rlt<MyUserInfoData?> {
         val rlt = profileHttpService.getMyUserInfo()
         return when (rlt) {
             is Rlt.Failed -> {
@@ -63,7 +64,7 @@ class ProfileManager : BaseFrame<IProfileListener>(), IProfileManager, ILanguage
             }
 
             is Rlt.Success -> {
-                Rlt.Success(rlt.data.data?.userInfo)
+                Rlt.Success(rlt.data.data)
             }
         }
     }

+ 20 - 18
module/profile/src/main/java/com/adealink/weparty/profile/viewmodel/ProfileViewModel.kt

@@ -19,20 +19,38 @@ import com.adealink.weparty.image.PHOTO_WALL_IMAGE_MIN_QUALITY
 import com.adealink.weparty.module.image.data.PhotoData
 import com.adealink.weparty.module.profile.ProfileModule
 import com.adealink.weparty.module.profile.data.EditUserInfo
+import com.adealink.weparty.module.profile.data.MyUserInfoData
 import com.adealink.weparty.module.profile.data.UserInfo
-import com.adealink.weparty.module.profile.data.VoiceData
 import com.adealink.weparty.module.profile.listener.IProfileListener
 import com.adealink.weparty.module.profile.viewmodel.IProfileViewModel
 import com.adealink.weparty.profile.data.UpdateMyUserInfoReq
 import com.adealink.weparty.profile.datasource.remote.ProfileHttpService
 import com.adealink.weparty.profile.manager.profileManager
 import com.adealink.weparty.util.uploadPhotos
-import com.adealink.weparty.util.uploadVoice
 import kotlinx.coroutines.launch
 
 class ProfileViewModel : BaseViewModel(), IProfileViewModel, IProfileListener {
 
     override val userInfoLD: LiveData<UserInfo?> = MutableLiveData<UserInfo?>()
+    override val myUserInfoLD: LiveData<MyUserInfoData?> = MutableLiveData<MyUserInfoData?>()
+
+    override fun pullMyUserInfo(): LiveData<Rlt<MyUserInfoData?>> {
+        val liveData = OnceMutableLiveData<Rlt<MyUserInfoData?>>()
+        viewModelScope.launch {
+            val rlt = profileManager.pullMyUserInfo()
+            when (rlt) {
+                is Rlt.Failed -> {
+                    myUserInfoLD.send(null)
+                }
+
+                is Rlt.Success -> {
+                    myUserInfoLD.send(rlt.data)
+                }
+            }
+            liveData.send(rlt)
+        }
+        return liveData
+    }
 
     private val profileHttpService by lazy {
         App.instance.networkService.getHttpService(ProfileHttpService::class.java)
@@ -120,22 +138,6 @@ class ProfileViewModel : BaseViewModel(), IProfileViewModel, IProfileListener {
                     }
                 }
             }
-            //音频自我介绍
-            editUserInfo.voice?.let { voice ->
-                val rlt = uploadVoice(
-                    voice
-                )
-                when (rlt) {
-                    is Rlt.Failed -> {
-                        liveData.send(rlt)
-                        return@launch
-                    }
-
-                    is Rlt.Success<VoiceData> -> {
-                        editUserInfo.voice = rlt.data
-                    }
-                }
-            }
 
             val rlt = profileHttpService.updateUserInfo(
                 UpdateMyUserInfoReq(

BIN
module/profile/src/main/res/drawable-xhdpi/profile_voice_under_review_ic.png


+ 52 - 0
module/profile/src/main/res/layout/fragment_talent_voice_under_review.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/edit_talent_voice_height">
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_review"
+        android:layout_width="35dp"
+        android:layout_height="35dp"
+        app:layout_constraintBottom_toTopOf="@id/tv_review_title"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintVertical_bias="0.32"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:srcCompat="@drawable/profile_voice_under_review_ic" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_review_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="12dp"
+        android:fontFamily="@font/poppins_semibold"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:maxLines="2"
+        android:text="@string/profile_voice_under_review_title"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toBottomOf="@id/tv_review_desc"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/iv_review" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_review_desc"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:maxLines="2"
+        android:text="@string/profile_voice_under_review_desc"
+        android:textColor="@color/color_FF1D2129"
+        android:textSize="14sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/tv_review_title" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 2 - 0
module/profile/src/main/res/values-in/strings.xml

@@ -77,4 +77,6 @@
     <string name="profile_edit_avatar">Profile Photo</string>
     <string name="profile_visitor_title">Pengunjung Terbaru</string>
     <string name="profile_visitor_desc">Mengunjungi Anda</string>
+    <string name="profile_voice_under_review_title">Suara Sedang Ditinjau</string>
+    <string name="profile_voice_under_review_desc">Harap menunggu dengan sabar</string>
 </resources>

+ 2 - 0
module/profile/src/main/res/values-zh/strings.xml

@@ -73,4 +73,6 @@
     <string name="profile_edit_avatar">个人照片</string>
     <string name="profile_visitor_title">最近访客</string>
     <string name="profile_visitor_desc">访问了你</string>
+    <string name="profile_voice_under_review_title">音频审核中</string>
+    <string name="profile_voice_under_review_desc">请耐心等待</string>
 </resources>

+ 2 - 0
module/profile/src/main/res/values/strings.xml

@@ -77,4 +77,6 @@
     <string name="profile_edit_voice_not_empty">On display</string>
     <string name="profile_visitor_title">Recent Visitors</string>
     <string name="profile_visitor_desc">Visited you</string>
+    <string name="profile_voice_under_review_title">Voice Under Review</string>
+    <string name="profile_voice_under_review_desc">Please wait patiently</string>
 </resources>

+ 1 - 1
module/wallet/src/main/java/com/adealink/weparty/wallet/comp/MyIncomeComp.kt

@@ -40,7 +40,7 @@ class MyIncomeComp(
     }
 
     private fun observeViewModel() {
-        viewModel.beanLD.observe(viewLifecycleOwner) {
+        viewModel.availableBeanLD.observe(viewLifecycleOwner) {
             binding.tvBean.text = formatNumberStr(it)
         }
     }