package com.ydl.confide.intro import android.app.Activity import android.net.Uri import android.text.TextUtils import android.util.Log import android.view.View import android.widget.SeekBar import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableField import androidx.databinding.ObservableInt import androidx.databinding.ViewDataBinding import androidx.fragment.app.FragmentActivity import androidx.recyclerview.widget.RecyclerView import com.alibaba.android.arouter.launcher.ARouter import com.dou361.ijkplayer.widget.IjkVideoView import com.facebook.drawee.backends.pipeline.Fresco import com.facebook.drawee.interfaces.DraweeController import com.ydl.audioim.api.IAudioImService import com.ydl.confide.R import com.ydl.confide.api.ConfideRoute import com.ydl.confide.databinding.ItemExpertIntroBinding import com.ydl.confide.home.ConfideBottomSheetDialogFragment import com.ydl.confide.home.bean.ConfideHomeBodyBean import com.ydl.confide.home.modular.service.ConfideWebServiceImpl import com.ydl.confide.router.PhoneCallIn import com.ydl.webview.H5Params import com.ydl.webview.NewH5Activity import com.ydl.ydlcommon.base.config.HttpConfig import com.ydl.ydlcommon.modular.findRouteService import com.ydl.ydlcommon.utils.LogUtil import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils import com.ydl.ydlcommon.view.dialog.YDLShareDialog import com.yidianling.im.api.service.IImService import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers import tv.danmaku.ijk.media.player.IjkMediaPlayer import java.io.UnsupportedEncodingException import java.net.URLDecoder import java.net.URLEncoder import java.util.concurrent.TimeUnit internal class ItemIntroHolder(binding: ItemExpertIntroBinding) : BindingViewHolder<ItemExpertIntroBinding>(binding) { companion object { private const val TAG = "ItemIntroHolder" } private var disposable: Disposable? = null private var video: IjkVideoView? = null private var vm: VideoViewModel? = null @Volatile private var isTouch = false fun onDetach() { stopTiming() video?.release(true) binding.videoView.removeAllViews() } fun onBind(item: VideoViewModel) { vm = item if (vm?.isVideo == true) { binding.ivCover.visibility = View.GONE } else { binding.ivCover.visibility = View.VISIBLE } binding.layoutCall.setOnClickListener { if (!PhoneCallIn.loginByOneKeyLogin(itemView.context, true)) { return@setOnClickListener } ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId.toString(), if (item.isVideo) "1" else "2", "6" ) val status = item.lineStatus.get() when (status) { 5 -> { if (!TextUtils.isEmpty(item.linkedUrl.get())) { val linkUri = Uri.parse(item.linkedUrl.get()) if (linkUri != null) { val host = linkUri.host if (!TextUtils.isEmpty(host) && host == "h5") { //如果是h5,跳转至NewH5Activity try { var params = URLDecoder.decode( linkUri.getQueryParameter("params"), "UTF-8" ) ARouter.getInstance().build("/new_h5/h5") .withSerializable("routerParam", params).navigation() } catch (e: NullPointerException) { com.yidianling.common.tools.LogUtil.e("params参数为空") } catch (e: UnsupportedEncodingException) { com.yidianling.common.tools.LogUtil.e("解码错误") } catch (e: UnsupportedOperationException) { com.yidianling.common.tools.LogUtil.e("这不是一个uri格式的地址") } } } } } 6 -> { if (!item.uid.isNullOrBlank()) { (itemView.context as? Activity)?.let { it1 -> ARouter.getInstance().navigation(IImService::class.java) ?.startChatBySessionId(it1, item.uid!!) } } } 2, 3 -> {//离线,通话中 (itemView.context as? Activity)?.let { aty -> findRouteService(IImService::class.java).startChat(aty, item.uid!!, 0, 0) } } else -> { if (!item.confideId.isNullOrBlank()) { if (!findRouteService(IAudioImService::class.java).getIsOnlineRtm()) { findRouteService(IAudioImService::class.java).loginRtm( PhoneCallIn.getUserService().getUserInfo()?.uid ) { _: Boolean, _ -> showPayOrDetail(item, it) } } else { showPayOrDetail(item, it) } } } } // showDoctorDetail(item) } binding.btnChat.setOnClickListener { val aty = it.context as? Activity if (aty != null && !item.uid.isNullOrEmpty()) { ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId.toString(), if (item.isVideo) "1" else "2", "7" ) findRouteService(IImService::class.java).startChat(aty, item.uid!!, 0, 0) } } binding.btnEvaluate.setOnClickListener { item.doctorId?.let { ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId ?: "", if (item.isVideo) "1" else "2", "8" ) val url = HttpConfig.MH5_URL + ConfideRoute.h5ExpertEval(it, item.confideId ?: "") NewH5Activity.start(itemView.context, H5Params(url, "")) // ConfideBottomSheetDialogFragment() // .showBottomSheetDialog( // itemView.context as FragmentActivity, // HttpConfig.MH5_URL + ConfideRoute.h5ExpertEval(it, item.confideId ?: ""), // it, uid = item.uid // ) } } binding.tvName.setOnClickListener { ActionCountUtils.record( "listen_counselor_popupwindows_page", "popupwindows_page_visit", item.confideId ?: "", "4" ) showDoctorDetail(item, false) } binding.ivAvatar.setOnClickListener { ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId ?: "", if (item.isVideo) "1" else "2", "10" ) ActionCountUtils.record( "listen_counselor_popupwindows_page", "popupwindows_page_visit", item.confideId ?: "", "3" ) showDoctorDetail(item, false) } binding.vDisableClick.setOnClickListener { } binding.btnShare.setOnClickListener { val aty = it.context as? Activity if (aty != null) { ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId ?: "", if (item.isVideo) "1" else "2", "9" ) var shareUrl = "${HttpConfig.MH5_URL}experts/${item.doctorId}" if (!item.confideId.isNullOrBlank()) { shareUrl += "?id=${item.confideId}" } val dialog = YDLShareDialog.style8( aty, "${item.name.get()}_${item.title.get()}", shareUrl, "壹点灵心理服务平台让天下人更快乐", item.avatar.get(), genMinProgramPath(shareUrl), "gh_25b90294ddcc" ) dialog.show(aty.fragmentManager, "share") } } binding.videoView.setOnClickListener { ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId ?: "", if (item.isVideo) "1" else "2", if (item.isVideo) "4" else "2" ) if (video?.canPause() == true) { video?.pause() if (item.isVideo) { binding.ivPlay.visibility = View.VISIBLE } else { binding.voicePlay.stop() } } } binding.ivPlay.setOnClickListener { ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId.toString(), if (item.isVideo) "1" else "2", if (item.isVideo) "3" else "1" ) video?.start() if (item.isVideo) { binding.ivPlay.visibility = View.GONE } else { binding.voicePlay.start() } } binding.voicePlay.setOnClickListener { ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId.toString(), if (item.isVideo) "1" else "2", if (item.isVideo) "3" else "1" ) if (video?.isPlaying == true) { video?.pause() binding.voicePlay.stop() } else if (video?.isPlaying == false) { video?.start() binding.voicePlay.start() } } val controller: DraweeController = Fresco.newDraweeControllerBuilder() .setUri(Uri.parse("res://drawable/" + R.drawable.confide_first_order)) .setOldController(binding.confideFirstFree.controller) .setAutoPlayAnimations(true) // 是否自动播放Gif动画 .build() binding.confideFirstFree.controller = controller val freeController: DraweeController = Fresco.newDraweeControllerBuilder() .setUri(Uri.parse("res://drawable/" + R.drawable.confide_free)) .setOldController(binding.free.controller) .setAutoPlayAnimations(true) // 是否自动播放Gif动画 .build() binding.free.controller = freeController binding.seekbar.progress = 0 binding.seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { } override fun onStartTrackingTouch(seekBar: SeekBar?) { isTouch = true } override fun onStopTrackingTouch(seekBar: SeekBar?) { isTouch = false if (seekBar != null) { video?.seekTo(seekBar.progress) video?.start() binding.ivPlay.visibility = View.GONE } ActionCountUtils.record( "listen_counselor_content_play_page", "listen_counselor_content_play_icon_click", item.confideId.toString(), if (item.isVideo) "1" else "2", "5" ) } }) binding.voicePlay.visibility = if (item.isVideo) View.GONE else if (item.playUrl.isNullOrBlank()) View.GONE else View.VISIBLE } private fun showPayOrDetail(item: VideoViewModel, it: View) { ConfideWebServiceImpl().connectionJava( item.confideId!!.toInt(), 3, it.context as Activity, null ) { showDoctorDetail(item, true) } } fun onAttach(videoView: IjkVideoView) { this.video = videoView binding.videoView.addView(videoView) video?.setOnPreparedListener { player -> Log.d(TAG, "${player.videoHeight},${player.videoWidth},${player.duration}") val duration = player.duration.toInt() if (duration > 0) { binding.seekbar.max = duration } else { binding.seekbar.visibility = View.GONE } } video?.setOnCompletionListener { video?.seekTo(0) video?.start() } video?.setOnErrorListener { player, what, extra -> LogUtil.e(TAG, "onError:$what,$extra") return@setOnErrorListener true } startTiming() if (vm?.isVideo == false && !vm?.playUrl.isNullOrBlank()) { binding.voicePlay.start() } } private fun startTiming() { disposable = Observable.interval(3, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.computation()) .subscribe { val pos = (video?.mMediaPlayer as IjkMediaPlayer?)?.currentPosition ?: 0 if (pos > 0) { // if (vm?.isVideo == true) { // binding.ivCover.visibility = View.GONE // } if (!isTouch) { binding.seekbar.progress = pos.toInt()// video.bufferPercentage } if (video?.isPlaying == true) { when (vm?.isVideo) { true -> { binding.ivPlay.visibility = View.GONE } false -> { binding.voicePlay.start() } } } } } } private fun stopTiming() { disposable?.dispose() } private fun showDoctorDetail(item: VideoViewModel, toPay: Boolean) { item.confideId?.let { val url = HttpConfig.MH5_URL + ConfideRoute.h5ConfideIntro(it) + if (toPay) "&payPage=1" else "" ConfideBottomSheetDialogFragment() .showBottomSheetDialog( itemView.context as FragmentActivity, url, item.doctorId!!, uid = item.uid, listenFree = item.listenFree.get(), expertUrl = item.linkedUrl.get() ?: "" ) } } } class VideoViewModel { val name = ObservableField<String>("") val title = ObservableField<String>("") val avatar = ObservableField<String>("") val count = ObservableField<String>("") val lineStatus = ObservableInt() var remainingTime = ObservableField<String>("") val intro = ObservableField<String>("") val tag = ObservableField<String>("") var playUrl: String? = null val coverUrl = ObservableField<String>("") val showFreeTag = ObservableBoolean(false) var isVideo = false var uid: String? = null var doctorId: String? = null var confideId: String? = null var listenFree = ObservableBoolean(false) var linkedUrl = ObservableField<String>("") } private fun genMinProgramPath(url: String): String { val pathPrefix = "/pages/web/web?load_url=" val encode = URLEncoder.encode(url, "UTF-8") return pathPrefix + encode } internal fun VideoViewModel.mapOf(bean: ConfideHomeBodyBean): VideoViewModel { name.set(bean.confidedName) avatar.set(bean.confidedIcon) linkedUrl.set(bean.linkUrl) val num = bean.confideNum?.replace("人", "") ?: "0" count.set("服务人次 $num") intro.set(bean.confideContent) title.set(bean.title) val sb = StringBuilder() bean.confidedTag?.forEach { sb.append(it).append(" | ") } if (sb.length > 3) { sb.setLength(sb.length - 3) } tag.set(sb.toString()) if (!bean.videoUrl.isNullOrEmpty()) { playUrl = bean.videoUrl isVideo = true coverUrl.set(bean.coverVideoPicture) } else { playUrl = bean.confideVoice isVideo = false coverUrl.set(bean.coverPicture) } uid = bean.uid?.toString() doctorId = bean.doctorId confideId = bean.confidedId if (bean.listenFree == null) { listenFree.set(false) } else { listenFree.set(bean.listenFree!!) } return this } open class BindingViewHolder<T : ViewDataBinding>(val binding: T) : RecyclerView.ViewHolder(binding.root)