|
|
@@ -12,13 +12,13 @@ import com.adealink.weparty.commonui.ext.dpf
|
|
|
import com.adealink.weparty.commonui.toast.util.showToast
|
|
|
import com.adealink.weparty.im.R
|
|
|
import com.adealink.weparty.im.databinding.LayoutSessionBottomVoiceBarBinding
|
|
|
+import com.adealink.weparty.im.session.comp.input.AudioInputStatus
|
|
|
import com.adealink.weparty.im.session.comp.input.InputAction
|
|
|
import com.adealink.weparty.im.session.comp.input.InputState
|
|
|
+import com.adealink.weparty.im.session.comp.viewmodel.SessionAudioViewModel
|
|
|
import com.adealink.weparty.im.session.comp.viewmodel.SessionInputViewModel
|
|
|
import com.adealink.weparty.module.im.data.TAG_IM_AUDIO
|
|
|
import com.tencent.qcloud.tuicore.TUIConstants
|
|
|
-import com.tencent.qcloud.tuicore.util.ToastUtil
|
|
|
-import com.tencent.qcloud.tuikit.tuichat.TUIChatService
|
|
|
import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo
|
|
|
import com.tencent.qcloud.tuikit.tuichat.component.audio.AudioPlayer
|
|
|
import com.tencent.qcloud.tuikit.tuichat.component.audio.AudioRecorder
|
|
|
@@ -46,6 +46,7 @@ class SessionBottomAudioComp(
|
|
|
private var mTimer: Timer? = null
|
|
|
private var times = 0
|
|
|
private val inputViewModel by activityViewModels<SessionInputViewModel>()
|
|
|
+ private val audioViewModel by activityViewModels<SessionAudioViewModel>()
|
|
|
|
|
|
private var isPause = false
|
|
|
override fun onCreate() {
|
|
|
@@ -56,8 +57,8 @@ class SessionBottomAudioComp(
|
|
|
|
|
|
|
|
|
private fun initView() {
|
|
|
- voiceBar.btnRemove.onClick {
|
|
|
- clickDelete()
|
|
|
+ voiceBar.btnCancel.onClick {
|
|
|
+ clickCancel()
|
|
|
}
|
|
|
voiceBar.btnPause.onClick {
|
|
|
clickPause()
|
|
|
@@ -92,6 +93,23 @@ class SessionBottomAudioComp(
|
|
|
).event.observeWithoutCache(viewLifecycleOwner) {
|
|
|
startAudioRecord()
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ inputViewModel.registerTransaction(
|
|
|
+ currentState = InputState.STATE_AUDIO_INPUT,
|
|
|
+ action = InputAction.CLICK_AUDIO,
|
|
|
+ nextState = InputState.STATE_NONE
|
|
|
+ ).event.observeWithoutCache(viewLifecycleOwner) {
|
|
|
+ stopAudioRecord()
|
|
|
+ }
|
|
|
+ inputViewModel.registerTransaction(
|
|
|
+ currentState = InputState.STATE_AUDIO_INPUT,
|
|
|
+ action = InputAction.CANCEL_AUDIO,
|
|
|
+ nextState = InputState.STATE_NONE
|
|
|
+ ).event.observeWithoutCache(viewLifecycleOwner) {
|
|
|
+ cancelAudioRecord()
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* transition from [InputState.STATE_AUDIO_INPUT]
|
|
|
*/
|
|
|
@@ -102,27 +120,41 @@ class SessionBottomAudioComp(
|
|
|
stopAudioRecord()
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ audioViewModel.audioInputStatusLD.observeWithoutCache(viewLifecycleOwner) { status ->
|
|
|
+// when (status) {
|
|
|
+// AudioInputStatus.RECORD_CONTINUE -> TODO()
|
|
|
+// AudioInputStatus.RECORD_FAILED -> TODO()
|
|
|
+// AudioInputStatus.RECORD_START -> TODO()
|
|
|
+// AudioInputStatus.RECORD_STOP -> TODO()
|
|
|
+// AudioInputStatus.RECORD_READY_TO_CANCEL -> TODO()
|
|
|
+// AudioInputStatus.RECORD_TOO_SHORT -> {
|
|
|
+//
|
|
|
+// }
|
|
|
+// AudioInputStatus.RECORD_CANCEL -> TODO()
|
|
|
+// }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private fun clickDelete() {
|
|
|
+ private fun clickCancel() {
|
|
|
inputViewModel.execute(InputAction.CANCEL_AUDIO)
|
|
|
- stopAudioRecord()
|
|
|
}
|
|
|
|
|
|
private fun clickPause() {
|
|
|
if (isPause) {
|
|
|
isPause = false
|
|
|
- voiceBar.btnPause.setImageResource(R.drawable.im_session_voice_record_resume_ic)
|
|
|
+ voiceBar.btnPause.setImageResource(R.drawable.im_session_voice_record_pause_ic)
|
|
|
resumeAudioRecord()
|
|
|
} else {
|
|
|
isPause = true
|
|
|
- voiceBar.btnPause.setImageResource(R.drawable.im_session_voice_record_pause_ic)
|
|
|
+ voiceBar.btnPause.setImageResource(R.drawable.im_session_voice_record_resume_ic)
|
|
|
pauseAudioRecord()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private fun clickSend() {
|
|
|
- inputViewModel.execute(InputAction.CANCEL_AUDIO)
|
|
|
+ inputViewModel.execute(InputAction.CLICK_AUDIO)
|
|
|
}
|
|
|
|
|
|
private fun startAudioRecord() {
|
|
|
@@ -133,6 +165,7 @@ class SessionBottomAudioComp(
|
|
|
AudioRecorder.startRecord(object : AudioRecorderCallback {
|
|
|
override fun onStarted() {
|
|
|
Log.d(TAG_IM_AUDIO, "startAudioRecord, onStarted")
|
|
|
+ audioViewModel.changeStatus(AudioInputStatus.RECORD_START)
|
|
|
showVoiceLayout()
|
|
|
if (mTimer == null) {
|
|
|
mTimer = Timer()
|
|
|
@@ -151,11 +184,14 @@ class SessionBottomAudioComp(
|
|
|
|
|
|
override fun onFinished(outputPath: String?) {
|
|
|
Log.d(TAG_IM_AUDIO, "startAudioRecord, onFinished:$outputPath")
|
|
|
+ hideVoiceLayout()
|
|
|
val duration = AudioRecorder.getDuration(outputPath)
|
|
|
if (duration < 1000) {
|
|
|
showToast(R.string.im_audio_say_time_short)
|
|
|
+ audioViewModel.changeStatus(AudioInputStatus.RECORD_TOO_SHORT)
|
|
|
return
|
|
|
}
|
|
|
+ audioViewModel.changeStatus(AudioInputStatus.RECORD_STOP)
|
|
|
voiceBar.vVoiceWave.stop()
|
|
|
sendAudioMessage(outputPath, duration)
|
|
|
}
|
|
|
@@ -165,34 +201,32 @@ class SessionBottomAudioComp(
|
|
|
TAG_IM_AUDIO,
|
|
|
"startAudioRecord, onFailed, errorCode:$errorCode, errorMessage:$errorMessage"
|
|
|
)
|
|
|
+ hideVoiceLayout()
|
|
|
if (errorCode == AudioRecorder.ERROR_CODE_MIC_IS_BEING_USED || errorCode == TUIConstants.TUICalling.ERROR_STATUS_IN_CALL) {
|
|
|
- ToastUtil.toastLongMessage(
|
|
|
- TUIChatService.getAppContext()
|
|
|
- .getString(R.string.im_mic_is_being_used_cant_record)
|
|
|
- )
|
|
|
+ showToast(R.string.im_mic_is_being_used_cant_record)
|
|
|
} else {
|
|
|
- ToastUtil.toastLongMessage(
|
|
|
- TUIChatService.getAppContext().getString(R.string.im_record_audio_failed)
|
|
|
- )
|
|
|
+ showToast(R.string.im_record_audio_failed)
|
|
|
}
|
|
|
- hideVoiceLayout()
|
|
|
Log.e(
|
|
|
TAG_IM_AUDIO,
|
|
|
"record audio failed, errorCode $errorCode, errorMessage $errorMessage"
|
|
|
)
|
|
|
+ audioViewModel.changeStatus(AudioInputStatus.RECORD_FAILED)
|
|
|
voiceBar.vVoiceWave.stop()
|
|
|
+ inputViewModel.execute(InputAction.EMPTY_CLICKED)
|
|
|
}
|
|
|
|
|
|
override fun onCanceled() {
|
|
|
Log.d(TAG_IM_AUDIO, "startAudioRecord, onCanceled")
|
|
|
-// if (mChatInputHandler != null) {
|
|
|
-// mChatInputHandler.onRecordStatusChanged(InputView.ChatInputHandler.RECORD_CANCEL)
|
|
|
-// }
|
|
|
- voiceBar.vVoiceWave.stop()
|
|
|
hideVoiceLayout()
|
|
|
+ audioViewModel.changeStatus(AudioInputStatus.RECORD_CANCEL)
|
|
|
+ voiceBar.vVoiceWave.stop()
|
|
|
}
|
|
|
|
|
|
override fun onVoiceDb(db: Double) {
|
|
|
+ if (isPause) {
|
|
|
+ return
|
|
|
+ }
|
|
|
Log.d(TAG_IM_AUDIO, "startAudioRecord, onVoiceDb: $db")
|
|
|
voiceBar.vVoiceWave.updateDecibel(
|
|
|
max(
|
|
|
@@ -205,36 +239,25 @@ class SessionBottomAudioComp(
|
|
|
}
|
|
|
|
|
|
private fun pauseAudioRecord() {
|
|
|
+ Log.d(TAG_IM_AUDIO, "pauseAudioRecord")
|
|
|
voiceBar.vVoiceWave.pause()
|
|
|
- AudioRecorder.stopRecord()
|
|
|
+ AudioRecorder.pauseRecord()
|
|
|
}
|
|
|
|
|
|
private fun resumeAudioRecord() {
|
|
|
+ Log.d(TAG_IM_AUDIO, "resumeAudioRecord")
|
|
|
voiceBar.vVoiceWave.resume()
|
|
|
- mTimer?.cancel()
|
|
|
+ AudioRecorder.resumeRecord()
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private fun hideVoiceLayout() {
|
|
|
Log.d(TAG_IM_AUDIO, "hideVoiceLayout")
|
|
|
resetVoiceView()
|
|
|
-// voiceBtn.setVisibility(View.VISIBLE)
|
|
|
-// mSendAudioButtonLayout.setVisibility(View.GONE)
|
|
|
-// showInputMoreButton()
|
|
|
-// showTextInputLayout()
|
|
|
-// showImageButton()
|
|
|
-// hideVoiceDeleteImage()
|
|
|
}
|
|
|
|
|
|
private fun showVoiceLayout() {
|
|
|
Log.d(TAG_IM_AUDIO, "showVoiceLayout")
|
|
|
initVoiceWaveView()
|
|
|
-// mSendAudioButtonLayout.setVisibility(View.VISIBLE)
|
|
|
-// voiceBtn.setVisibility(View.GONE)
|
|
|
-// hideInputMoreButton()
|
|
|
-// hideTextInputLayout()
|
|
|
-// hideImageButton()
|
|
|
-// showVoiceDeleteImage()
|
|
|
}
|
|
|
|
|
|
private fun initVoiceWaveView() {
|
|
|
@@ -246,18 +269,6 @@ class SessionBottomAudioComp(
|
|
|
voiceBar.vVoiceWave.barSpacing = 2.dpf()
|
|
|
voiceBar.vVoiceWave.showGlow = false
|
|
|
voiceBar.vVoiceWave.clear()
|
|
|
-// voiceBar.vVoiceWave.addHeader(MIN_VOICE_DB)
|
|
|
-// for (i in 0..100) {
|
|
|
-// voiceBar.vVoiceWave.addBody(MIN_VOICE_DB)
|
|
|
-// }
|
|
|
-// voiceBar.vVoiceWave.addFooter(MIN_VOICE_DB)
|
|
|
-// voiceBar.vVoiceWave.addHeader(0)
|
|
|
-// for (i in 0..100) {
|
|
|
-// voiceBar.vVoiceWave.addBody(0)
|
|
|
-// }
|
|
|
-// voiceBar.vVoiceWave.addFooter(0)
|
|
|
-// voiceDeleteImage.setBackgroundResource(R.drawable.minimalist_delete_icon)
|
|
|
-// mSendAudioButton.setBackground(getResources().getDrawable(R.drawable.minimalist_corner_bg_blue))
|
|
|
}
|
|
|
|
|
|
private fun stopAudioRecord() {
|
|
|
@@ -267,9 +278,13 @@ class SessionBottomAudioComp(
|
|
|
voiceBar.vVoiceWave.clear()
|
|
|
}
|
|
|
|
|
|
+ private fun cancelAudioRecord() {
|
|
|
+ Log.d(TAG_IM_AUDIO, "cancelAudioRecord")
|
|
|
+ AudioRecorder.cancelRecord()
|
|
|
+ }
|
|
|
+
|
|
|
private fun resetVoiceView() {
|
|
|
Log.d(TAG_IM_AUDIO, "resetVoiceView")
|
|
|
-// initVoiceWaveView()
|
|
|
mTimer?.cancel()
|
|
|
mTimer = null
|
|
|
voiceBar.tvRecordTime.text = "0:00"
|