Commit 55a87036 authored by wanglei's avatar wanglei

...

parent f152a0f0
...@@ -20,7 +20,7 @@ abstract class BaseFragment<VB : ViewBinding>( ...@@ -20,7 +20,7 @@ abstract class BaseFragment<VB : ViewBinding>(
private val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> VB private val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> VB
) : Fragment() { ) : Fragment() {
private var _binding: VB? = null private var _binding: VB? = null
private var fragmentInit = false var fragmentInit = false
open val TAG = javaClass.simpleName open val TAG = javaClass.simpleName
//重写binding get()方法不直接暴露真实的可空_binding数据 //重写binding get()方法不直接暴露真实的可空_binding数据
......
...@@ -81,7 +81,9 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl ...@@ -81,7 +81,9 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
bannerAdapter = BannerAdapter() bannerAdapter = BannerAdapter()
bannerAdapter?.let { bannerAdapter?.let {
it.paletteAction = { it.paletteAction = {
binding.root.setBackgroundColor(it) if (isVisible && fragmentInit) {
binding.root.setBackgroundColor(it)
}
} }
it.playAction = { shortPlay -> it.playAction = { shortPlay ->
startActivity(Intent(activity, PlayFullActivity::class.java).apply { startActivity(Intent(activity, PlayFullActivity::class.java).apply {
...@@ -105,6 +107,8 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl ...@@ -105,6 +107,8 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>(FragmentHomeBinding::infl
super.onResumeOneShoot() super.onResumeOneShoot()
val activity = requireActivity() as MainActivity? val activity = requireActivity() as MainActivity?
activity?.viewModel?.getPopularDrama()
activity?.viewModel?.getNewDrama()
activity?.viewModel?.getCategoryListFlow(true) activity?.viewModel?.getCategoryListFlow(true)
} }
......
...@@ -5,8 +5,8 @@ import android.view.LayoutInflater ...@@ -5,8 +5,8 @@ import android.view.LayoutInflater
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.navigation.fragment.NavHostFragment import androidx.viewpager2.widget.ViewPager2
import com.base.appzxhy.R import com.base.appzxhy.R
import com.base.appzxhy.base.BaseActivity import com.base.appzxhy.base.BaseActivity
import com.base.appzxhy.bean.HomeTabUIBean import com.base.appzxhy.bean.HomeTabUIBean
...@@ -20,7 +20,6 @@ import com.gyf.immersionbar.ktx.immersionBar ...@@ -20,7 +20,6 @@ import com.gyf.immersionbar.ktx.immersionBar
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate) { class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate) {
private lateinit var navController: NavController
private val homeTabs by lazy { private val homeTabs by lazy {
arrayOf( arrayOf(
HomeTabUIBean(R.drawable.bg_selector_home, getString(R.string.home)), HomeTabUIBean(R.drawable.bg_selector_home, getString(R.string.home)),
...@@ -34,24 +33,57 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl ...@@ -34,24 +33,57 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
ViewModelProvider(this)[ShortPlayViewModel::class.java] ViewModelProvider(this)[ShortPlayViewModel::class.java]
} }
private val homeFragment by lazy(LazyThreadSafetyMode.NONE) {
HomeFragment()
}
private val slideFragment by lazy(LazyThreadSafetyMode.NONE) {
PlaySlideFragment()
}
private val myListFragment by lazy(LazyThreadSafetyMode.NONE) {
MyListFragment()
}
private val rewardsFragment by lazy(LazyThreadSafetyMode.NONE) {
RewardsFragment()
}
private val profileFragment by lazy(LazyThreadSafetyMode.NONE) {
ProfileFragment()
}
private val fragments = arrayOf(homeFragment, slideFragment, myListFragment, rewardsFragment, profileFragment)
private var pageAdapter: FragmentStateAdapter? = null
override fun initView() { override fun initView() {
super.initView() super.initView()
navController = (supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment).navController initViewPager2()
initTab()
}
navController.addOnDestinationChangedListener { controller, destination, arguments -> private fun initViewPager2() {
LogEx.logDebug(TAG, "addOnDestinationChangedListener") pageAdapter = object : FragmentStateAdapter(this) {
override fun getItemCount(): Int {
return fragments.size
}
if (destination.id == R.id.homeFragment) { override fun createFragment(position: Int): Fragment {
LogEx.logDebug(TAG, "addOnDestinationChangedListener homeFragment") return fragments[position]
} }
} }
binding.viewPager2.run {
isUserInputEnabled = false
//https://www.jianshu.com/p/f69bd30cf5b0
//FragmentStateAdapter 这里必须传人fragment
adapter = pageAdapter
}
binding.viewPager2.registerOnPageChangeCallback(object :
ViewPager2.OnPageChangeCallback() {
initTab() override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
}
viewModel.getPopularDrama() override fun onPageSelected(position: Int) {
viewModel.getNewDrama() }
})
} }
private fun initTab() { private fun initTab() {
...@@ -85,42 +117,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl ...@@ -85,42 +117,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
defaultTab?.setSelected() defaultTab?.setSelected()
} }
private fun naviFragment(id: Int) {
when (id) {
0 -> {
if (navController.currentDestination?.id != R.id.homeFragment) {
navController.navigate(R.id.homeFragment)
}
}
1 -> {
navController.navigate(R.id.playSlideFragment)
}
2 -> {
navController.navigate(R.id.myListFragment)
}
3 -> {
navController.navigate(R.id.rewardsFragment)
}
4 -> {
navController.navigate(R.id.profileFragment)
}
}
}
private fun showFragment(targetFragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
// 隐藏所有Fragment
for (fragment in supportFragmentManager.fragments) {
transaction.hide(fragment)
}
// 显示当前需要显示的Fragment
transaction.show(targetFragment)
transaction.commit()
}
fun TabLayout.Tab.setUnselected() { fun TabLayout.Tab.setUnselected() {
val textView = customView?.findViewById<TextView>(R.id.tv_tab) val textView = customView?.findViewById<TextView>(R.id.tv_tab)
...@@ -132,7 +128,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl ...@@ -132,7 +128,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
val textView = customView?.findViewById<TextView>(R.id.tv_tab) val textView = customView?.findViewById<TextView>(R.id.tv_tab)
LogEx.logDebug(TAG, "setSelected ${textView?.text}") LogEx.logDebug(TAG, "setSelected ${textView?.text}")
textView?.setTextColor(Color.parseColor("#FFFFFF")) textView?.setTextColor(Color.parseColor("#FFFFFF"))
naviFragment(this.id) binding.viewPager2.setCurrentItem(this.id, false)
} }
override fun configSystemBar() { override fun configSystemBar() {
......
package com.base.appzxhy.ui.main package com.base.appzxhy.ui.main
import android.view.View
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.base.appzxhy.base.BaseFragment import com.base.appzxhy.base.BaseFragment
import com.base.appzxhy.databinding.FragmentPlaySlideBinding import com.base.appzxhy.databinding.FragmentPlaySlideBinding
import com.bytedance.sdk.shortplay.api.PSSDK
import com.bytedance.sdk.shortplay.api.PSSDK.DetailPageConfig
import com.bytedance.sdk.shortplay.api.PSSDK.FeedListLoadResult
import com.bytedance.sdk.shortplay.api.PSSDK.FeedListResultListener
import com.bytedance.sdk.shortplay.api.ShortPlay
import com.bytedance.sdk.shortplay.api.ShortPlayFragment
class PlaySlideFragment : BaseFragment<FragmentPlaySlideBinding>(FragmentPlaySlideBinding::inflate) { class PlaySlideFragment : BaseFragment<FragmentPlaySlideBinding>(FragmentPlaySlideBinding::inflate) {
private var feedListAdapter: FeedListAdapter? = null
private var currentShortPlayFragment: ShortPlayFragment? = null
override fun initView() { override fun initView() {
super.initView() super.initView()
feedListAdapter = FeedListAdapter(this)
binding.vpShortFeed.adapter = feedListAdapter
binding.vpShortFeed.setOrientation(ViewPager2.ORIENTATION_VERTICAL)
binding.vpShortFeed.offscreenPageLimit = 1
binding.vpShortFeed.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
//当前fragment
val currentFragment = feedListAdapter?.getItem(position)
if (currentFragment is ShortPlayFragment) {
currentShortPlayFragment = currentFragment
}
//预加载下个fragment
val nextPos = position + 1
val nextPlayFragment = feedListAdapter?.getItem(nextPos)
if (nextPlayFragment is ShortPlayFragment) {
nextPlayFragment.preLoadVideo(object : PSSDK.ActionResultListener {
override fun onSuccess() {
}
override fun onFail(p0: PSSDK.ErrorInfo?) {
}
})
}
}
})
PSSDK.requestPopularDrama(1, 20, object : FeedListResultListener {
override fun onFail(errorInfo: PSSDK.ErrorInfo?) {
}
override fun onSuccess(result: FeedListLoadResult<ShortPlay>?) {
val activity = requireActivity() as MainActivity?
result?.dataList?.let {
activity?.runOnUiThread {
setShortData(it)
}
}
}
})
}
private fun setShortData(dataList: List<ShortPlay>) {
val fragments: ArrayList<Fragment> = ArrayList()
dataList.forEach { shortPlay ->
val shortPlayFragment = createShortPlayFragment(shortPlay)
shortPlayFragment?.let { fragments.add(it) }
}
feedListAdapter?.appendData(fragments)
}
private fun createShortPlayFragment(shortPlay: ShortPlay): ShortPlayFragment? {
val builder = DetailPageConfig.Builder()
builder.hideLeftTopCloseAndTitle(true, null)
.displayBottomExtraView(false)
.displayProgressBar(false)
.displayTextVisibility(DetailPageConfig.TEXT_POS_BOTTOM_TITLE, false)
.displayTextVisibility(DetailPageConfig.TEXT_POS_BOTTOM_DESC, false)
.playSingleItem(true)
val config = builder.build()
val shortPlayFragment = PSSDK.createDetailFragment(shortPlay, config, object : PSSDK.ShortPlayDetailPageListener {
override fun onProgressChange(shortPlay: ShortPlay, index: Int, currentPlayTime: Int, duration: Int) = Unit
override fun onPlayFailed(errorInfo: PSSDK.ErrorInfo?): Boolean = false
override fun onShortPlayPlayed(shortPlay: ShortPlay?, index: Int) = Unit
override fun onItemSelected(position: Int, type: PSSDK.ShortPlayDetailPageListener.ItemType, index: Int) = Unit
override fun onVideoPlayStateChanged(shortPlay: ShortPlay?, index: Int, playbackState: Int) = Unit
override fun onVideoPlayCompleted(shortPlay: ShortPlay?, index: Int) = Unit
override fun onEnterImmersiveMode() = Unit
override fun onExitImmersiveMode() = Unit
override fun isNeedBlock(shortPlay: ShortPlay?, index: Int): Boolean = false
override fun showAdIfNeed(shortPlay: ShortPlay?, index: Int, listener: PSSDK.ShortPlayBlockResultListener?) = Unit
override fun onVideoInfoFetched(shortPlay: ShortPlay?, index: Int, videoPlayInfo: PSSDK.VideoPlayInfo?) = Unit
override fun onObtainPlayerControlViews(): MutableList<View> {
val views = ArrayList<View>()
return views
}
})
return shortPlayFragment
} }
override fun initListener() { override fun initListener() {
super.initListener() super.initListener()
} }
inner class FeedListAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
private val fragments: ArrayList<Fragment> = ArrayList()
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
fun appendData(fragments: List<Fragment>) {
val size = this.fragments.size
this.fragments.addAll(fragments)
notifyItemRangeInserted(size, fragments.size)
}
fun getItem(position: Int): Fragment? {
if (position < 0 || position >= fragments.size) {
return null
}
return fragments[position]
}
}
override fun onResumeOneShoot() {
super.onResumeOneShoot()
currentShortPlayFragment?.startPlay()
}
override fun onPause() {
super.onPause()
currentShortPlayFragment?.onPause()
}
} }
\ No newline at end of file
package com.base.appzxhy.ui.play package com.base.appzxhy.ui.play
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.util.AttributeSet import android.util.AttributeSet
import android.util.SparseArray
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.TextView import android.widget.TextView
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
...@@ -15,8 +13,11 @@ import com.base.appzxhy.R ...@@ -15,8 +13,11 @@ import com.base.appzxhy.R
import com.base.appzxhy.databinding.LayoutOverlayForyouBinding import com.base.appzxhy.databinding.LayoutOverlayForyouBinding
import com.base.appzxhy.databinding.LayoutOverlayPlayerBinding import com.base.appzxhy.databinding.LayoutOverlayPlayerBinding
import com.base.appzxhy.ui.play.effect.AnimationEffect import com.base.appzxhy.ui.play.effect.AnimationEffect
import com.base.appzxhy.ui.views.ShortPlayQualityDialog.showShortPlayQualityDialog
import com.base.appzxhy.ui.views.ShortPlaySpeedDialog.showShortPlaySpeedDialog
import com.base.appzxhy.utils.KotlinExt.formatSeconds import com.base.appzxhy.utils.KotlinExt.formatSeconds
import com.base.appzxhy.utils.LogEx import com.base.appzxhy.utils.LogEx
import com.base.appzxhy.utils.ToastUtils.toast
import com.base.appzxhy.utils.Utils.dp import com.base.appzxhy.utils.Utils.dp
import com.bytedance.sdk.shortplay.api.PSSDK import com.bytedance.sdk.shortplay.api.PSSDK
import com.bytedance.sdk.shortplay.api.ShortPlay import com.bytedance.sdk.shortplay.api.ShortPlay
...@@ -35,6 +36,7 @@ class CustomOverlayView : FrameLayout, PSSDK.IControlView { ...@@ -35,6 +36,7 @@ class CustomOverlayView : FrameLayout, PSSDK.IControlView {
private var tvPlayNow: TextView? = null private var tvPlayNow: TextView? = null
private var tvPlayTotal: TextView? = null private var tvPlayTotal: TextView? = null
var bindItemDataCallBack: ((index: Int, customOverlayView: CustomOverlayView) -> Unit)? = null var bindItemDataCallBack: ((index: Int, customOverlayView: CustomOverlayView) -> Unit)? = null
constructor(context: Context, layout: Int) : super(context) { constructor(context: Context, layout: Int) : super(context) {
...@@ -101,6 +103,7 @@ class CustomOverlayView : FrameLayout, PSSDK.IControlView { ...@@ -101,6 +103,7 @@ class CustomOverlayView : FrameLayout, PSSDK.IControlView {
setThumbTintList(ColorStateList.valueOf(thumbColor)) setThumbTintList(ColorStateList.valueOf(thumbColor))
setThumbShadowColor(Color.BLACK) setThumbShadowColor(Color.BLACK)
} }
bindItemDataCallBack?.invoke(index, this) bindItemDataCallBack?.invoke(index, this)
} }
...@@ -121,23 +124,6 @@ class CustomOverlayView : FrameLayout, PSSDK.IControlView { ...@@ -121,23 +124,6 @@ class CustomOverlayView : FrameLayout, PSSDK.IControlView {
niftySlider?.setValue(currentPlayTimeInSeconds.toFloat(), false) niftySlider?.setValue(currentPlayTimeInSeconds.toFloat(), false)
tvPlayNow?.text = currentPlayTimeInSeconds.toLong().formatSeconds() + " / " tvPlayNow?.text = currentPlayTimeInSeconds.toLong().formatSeconds() + " / "
} }
} }
@SuppressLint("SetTextI18n")
fun bindProgressChange(shortPlayFragment: ShortPlayFragment?) {
if (layout == R.layout.layout_overlay_player) {
val binding = LayoutOverlayPlayerBinding.bind(this)
binding.niftySlider.addOnValueChangeListener { slider, value, fromUser ->
if (fromUser) {
LogEx.logDebug(TAG, "value=$value")
shortPlayFragment?.setCurrentPlayTimeSeconds(value.toInt())
binding.tvPlayNow.text = value.toLong().formatSeconds() + " / "
}
}
}
}
} }
\ No newline at end of file
...@@ -6,11 +6,17 @@ import android.util.SparseArray ...@@ -6,11 +6,17 @@ import android.util.SparseArray
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.TextView
import androidx.activity.addCallback
import com.base.appzxhy.R import com.base.appzxhy.R
import com.base.appzxhy.base.BaseActivity import com.base.appzxhy.base.BaseActivity
import com.base.appzxhy.databinding.ActivityPlayFullBinding import com.base.appzxhy.databinding.ActivityPlayFullBinding
import com.base.appzxhy.databinding.LayoutOverlayPlayerBinding
import com.base.appzxhy.ui.views.DialogSelectEP import com.base.appzxhy.ui.views.DialogSelectEP
import com.base.appzxhy.ui.views.ShortPlayEPDialog.showShortPlayEPDialog import com.base.appzxhy.ui.views.ShortPlayEPDialog.showShortPlayEPDialog
import com.base.appzxhy.ui.views.ShortPlayQualityDialog.showShortPlayQualityDialog
import com.base.appzxhy.ui.views.ShortPlaySpeedDialog.showShortPlaySpeedDialog
import com.base.appzxhy.utils.KotlinExt.formatSeconds
import com.base.appzxhy.utils.LogEx import com.base.appzxhy.utils.LogEx
import com.base.appzxhy.utils.ToastUtils.toast import com.base.appzxhy.utils.ToastUtils.toast
import com.bytedance.sdk.shortplay.api.PSSDK import com.bytedance.sdk.shortplay.api.PSSDK
...@@ -21,15 +27,19 @@ import com.bytedance.sdk.shortplay.api.ShortPlay ...@@ -21,15 +27,19 @@ import com.bytedance.sdk.shortplay.api.ShortPlay
import com.bytedance.sdk.shortplay.api.ShortPlayFragment import com.bytedance.sdk.shortplay.api.ShortPlayFragment
import com.google.gson.Gson import com.google.gson.Gson
import com.gyf.immersionbar.ImmersionBar import com.gyf.immersionbar.ImmersionBar
import com.litao.slider.NiftySlider import com.ss.ttvideoengine.Resolution
class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullBinding::inflate) { class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullBinding::inflate) {
private var shortPlay: ShortPlay? = null private var shortPlay: ShortPlay? = null
private var shortPlayFragment: ShortPlayFragment? = null
private var startFromIndex = 1//剧集下标 private var startFromIndex = 1//剧集下标
private val startFromSeconds = 0//开始秒数 private val startFromSeconds = 0//开始秒数
private var shortPlayFragment: ShortPlayFragment? = null
private var playSpeed = 1.0f//0.5 0.75 1.0 1.25 1.5 2.0
private var resolutions: Array<Resolution>? = null
private var currentResolution = Resolution.Auto
// private val playHistory: PlayHistoryHelper.PlayHistory = PlayHistoryHelper.PlayHistory() // private val playHistory: PlayHistoryHelper.PlayHistory = PlayHistoryHelper.PlayHistory()
private val playControlViewSparseArray = SparseArray<CustomOverlayView>() private val playControlViewSparseArray = SparseArray<CustomOverlayView>()
...@@ -42,20 +52,19 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB ...@@ -42,20 +52,19 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB
shortPlay = Gson().fromJson(it, ShortPlay::class.java) shortPlay = Gson().fromJson(it, ShortPlay::class.java)
} }
shortPlay?.let { showDetailFragment(it) } shortPlay?.let { showShortPlayerFragment(it) }
shortPlay?.episodes shortPlay?.episodes
} }
override fun initListener() { override fun initListener() {
super.initListener() super.initListener()
onBackPressedDispatcher.addCallback {
finish()
}
} }
private fun showShortPlayerFragment(shortPlay: ShortPlay) {
/**
* 视频详情页
*/
private fun showDetailFragment(shortPlay: ShortPlay) {
val builder = DetailPageConfig.Builder() val builder = DetailPageConfig.Builder()
builder.displayTextVisibility(DetailPageConfig.TEXT_POS_BOTTOM_DESC, false) builder.displayTextVisibility(DetailPageConfig.TEXT_POS_BOTTOM_DESC, false)
...@@ -127,8 +136,12 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB ...@@ -127,8 +136,12 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB
} }
override fun onShortPlayPlayed(shortPlay: ShortPlay?, index: Int) { override fun onShortPlayPlayed(shortPlay: ShortPlay?, index: Int) {
this@PlayFullActivity.shortPlay = shortPlay
startFromIndex = index startFromIndex = index
LogEx.logDebug(TAG, "onShortPlayPlayed index=$index") LogEx.logDebug(TAG, "onShortPlayPlayed index=$index")
playControlViewSparseArray.get(index)?.findViewById<TextView>(R.id.tvTitle)?.text =
"${shortPlay?.title} $index/${shortPlay?.total}"
// playHistory.shortPlay = shortPlay // playHistory.shortPlay = shortPlay
// playHistory.index = index // playHistory.index = index
// PlayHistoryHelper.savePlayHistory(playHistory) // PlayHistoryHelper.savePlayHistory(playHistory)
...@@ -164,6 +177,8 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB ...@@ -164,6 +177,8 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB
} }
override fun onVideoInfoFetched(shortPlay: ShortPlay?, index: Int, videoPlayInfo: PSSDK.VideoPlayInfo?) { override fun onVideoInfoFetched(shortPlay: ShortPlay?, index: Int, videoPlayInfo: PSSDK.VideoPlayInfo?) {
// 每一集视频准备好时调用此方法告知本集的视频信息
resolutions = videoPlayInfo?.supportResolutions
} }
@SuppressLint("RtlHardcoded", "SetTextI18n") @SuppressLint("RtlHardcoded", "SetTextI18n")
...@@ -249,7 +264,8 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB ...@@ -249,7 +264,8 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB
playControlView.bindItemDataCallBack = { index, view -> playControlView.bindItemDataCallBack = { index, view ->
playControlViewSparseArray[index] = view playControlViewSparseArray[index] = view
} }
playControlView.bindProgressChange(shortPlayFragment) val playerBinding = LayoutOverlayPlayerBinding.bind(playControlView)
bindPlayControlView(playerBinding)
return views return views
} }
}) })
...@@ -267,6 +283,48 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB ...@@ -267,6 +283,48 @@ class PlayFullActivity : BaseActivity<ActivityPlayFullBinding>(ActivityPlayFullB
} }
private fun bindPlayControlView(playerBinding: LayoutOverlayPlayerBinding) {
playerBinding.niftySlider.addOnValueChangeListener { slider, value, fromUser ->
if (fromUser) {
LogEx.logDebug(TAG, "value=$value")
shortPlayFragment?.setCurrentPlayTimeSeconds(value.toInt())
playerBinding.tvPlayNow.text = value.toLong().formatSeconds() + " / "
}
}
playerBinding.tvSpeed.setOnClickListener {
showShortPlaySpeedDialog(playSpeed) { newSpeed ->
if (playSpeed != newSpeed) {
playSpeed = newSpeed
shortPlayFragment?.setVideoSpeed(newSpeed)
playerBinding.tvSpeed.text = "${newSpeed}x"
}
}
}
playerBinding.tvQuality.setOnClickListener {
if (resolutions == null) {
toast("the video not support change resolution", true)
return@setOnClickListener
} else {
resolutions?.let {
showShortPlayQualityDialog(this@PlayFullActivity.currentResolution, it) { resolution, resolutionString ->
if (currentResolution != resolution) {
currentResolution = resolution
shortPlayFragment?.setResolution(resolution)
playerBinding.tvQuality.text = resolutionString
}
}
}
}
}
playerBinding.tvTitle.text = "${shortPlay?.title} $startFromIndex/${shortPlay?.total}"
playerBinding.flBack.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
playerBinding.flMore.setOnClickListener {
}
}
override fun configSystemBar() { override fun configSystemBar() {
ImmersionBar.with(this) ImmersionBar.with(this)
.statusBarColor(R.color.black) .statusBarColor(R.color.black)
......
...@@ -4,11 +4,19 @@ import android.app.AlertDialog ...@@ -4,11 +4,19 @@ import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.view.Gravity import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import androidx.core.content.ContextCompat
import com.base.appzxhy.R
import com.base.appzxhy.databinding.DialogPlayQualityBinding import com.base.appzxhy.databinding.DialogPlayQualityBinding
import com.ss.ttvideoengine.Resolution
object ShortPlayQualityDialog { object ShortPlayQualityDialog {
fun Context.showShortPlayQualityDialog() { fun Context.showShortPlayQualityDialog(
currentResolution: Resolution,
resolutions: Array<Resolution>,
resolutionAction: (resolution: Resolution, resolutionString: String) -> Unit
) {
val dialog = AlertDialog.Builder(this).create() val dialog = AlertDialog.Builder(this).create()
val binding = DialogPlayQualityBinding.inflate(LayoutInflater.from(this)) val binding = DialogPlayQualityBinding.inflate(LayoutInflater.from(this))
dialog.setView(binding.root) dialog.setView(binding.root)
...@@ -19,8 +27,66 @@ object ShortPlayQualityDialog { ...@@ -19,8 +27,66 @@ object ShortPlayQualityDialog {
val params = dialog.window?.attributes val params = dialog.window?.attributes
// params?.width = resources.getDimensionPixelOffset(R.dimen.dp_320) // params?.width = resources.getDimensionPixelOffset(R.dimen.dp_320)
// params?.height = resources.getDimensionPixelOffset(R.dimen.dp_400) // params?.height = resources.getDimensionPixelOffset(R.dimen.dp_400)
params?.gravity = Gravity.CENTER params?.gravity = Gravity.BOTTOM
// params?.y = 50 params?.y = 50
dialog.window?.attributes = params
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
resolutions[0]
if (resolutions.contains(Resolution.High)) {
binding.tvResolution1.text = "480P"
} else {
binding.tvResolution1.visibility = View.GONE
}
if (resolutions.contains(Resolution.SuperHigh)) {
binding.tvResolution2.text = "720p"
} else {
binding.tvResolution2.visibility = View.GONE
}
if (resolutions.contains(Resolution.ExtremelyHigh)) {
binding.tvResolution3.text = "1080P"
} else {
binding.tvResolution3.visibility = View.GONE
}
when (currentResolution) {
Resolution.Auto -> {
binding.tvAuto.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
Resolution.High -> {
binding.tvResolution1.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
Resolution.SuperHigh -> {
binding.tvResolution2.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
Resolution.ExtremelyHigh -> {
binding.tvResolution3.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
else -> {}
}
binding.flClose.setOnClickListener { dialog.dismiss() }
binding.tvAuto.setOnClickListener {
dialog.dismiss()
resolutionAction.invoke(Resolution.Auto, "Auto")
}
binding.tvResolution1.setOnClickListener {
dialog.dismiss()
resolutionAction.invoke(Resolution.High, "480P")
}
binding.tvResolution2.setOnClickListener {
dialog.dismiss()
resolutionAction.invoke(Resolution.SuperHigh, "720P")
}
binding.tvResolution3.setOnClickListener {
dialog.dismiss()
resolutionAction.invoke(Resolution.ExtremelyHigh, "1080P")
}
} }
} }
\ No newline at end of file
...@@ -4,23 +4,79 @@ import android.app.AlertDialog ...@@ -4,23 +4,79 @@ import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.view.Gravity import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.core.content.ContextCompat
import com.base.appzxhy.R
import com.base.appzxhy.databinding.DialogPlaySpeedBinding import com.base.appzxhy.databinding.DialogPlaySpeedBinding
object ShortPlaySpeedDialog { object ShortPlaySpeedDialog {
fun Context.showShortPlaySpeedDialog() { fun Context.showShortPlaySpeedDialog(speed: Float, selectSpeedAction: (speed: Float) -> Unit) {
val dialog = AlertDialog.Builder(this).create() val dialog = AlertDialog.Builder(this).create()
val binding = DialogPlaySpeedBinding.inflate(LayoutInflater.from(this)) val binding = DialogPlaySpeedBinding.inflate(LayoutInflater.from(this))
dialog.setView(binding.root) dialog.setView(binding.root)
dialog.setCanceledOnTouchOutside(false) dialog.setCanceledOnTouchOutside(true)
dialog.show() dialog.show()
val params = dialog.window?.attributes val params = dialog.window?.attributes
// params?.width = resources.getDimensionPixelOffset(R.dimen.dp_320) // params?.width = resources.getDimensionPixelOffset(R.dimen.dp_320)
// params?.height = resources.getDimensionPixelOffset(R.dimen.dp_400) // params?.height = resources.getDimensionPixelOffset(R.dimen.dp_400)
params?.gravity = Gravity.CENTER params?.gravity = Gravity.BOTTOM
// params?.y = 50 params?.y = 50
dialog.window?.attributes = params
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
when (speed) {
0.5f -> {
binding.tv05.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
0.75f -> {
binding.tv075.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
1.0f -> {
binding.tv1.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
1.25f -> {
binding.tv125.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
1.5f -> {
binding.tv15.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
2.0f -> {
binding.tv2.background = ContextCompat.getDrawable(this, R.drawable.bg_stroke_33ffffff_4dff3d71_5)
}
}
binding.tv05.setOnClickListener {
dialog.dismiss()
selectSpeedAction.invoke(0.5f)
}
binding.tv075.setOnClickListener {
dialog.dismiss()
selectSpeedAction.invoke(0.75f)
}
binding.tv1.setOnClickListener {
dialog.dismiss()
selectSpeedAction.invoke(1.0f)
}
binding.tv125.setOnClickListener {
dialog.dismiss()
selectSpeedAction.invoke(1.25f)
}
binding.tv15.setOnClickListener {
dialog.dismiss()
selectSpeedAction.invoke(1.5f)
}
binding.tv2.setOnClickListener {
dialog.dismiss()
selectSpeedAction.invoke(2.0f)
}
binding.flClose.setOnClickListener { dialog.dismiss() }
} }
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#2D2F3D" />
<corners android:radius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="1dp"
android:color="#33ffffff" />
<solid android:color="#4d030303" />
<corners android:radius="5dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="1dp"
android:color="#33ffffff" />
<solid android:color="#4dff3d71" />
<corners android:radius="5dp"/>
</shape>
\ No newline at end of file
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView <androidx.viewpager2.widget.ViewPager2
android:id="@+id/fragment_container" android:id="@+id/viewPager2"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/fl_tab" app:layout_constraintBottom_toTopOf="@id/fl_tab"
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <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_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:background="@drawable/bg_2d2f3d_10">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginTop="10dp"
android:text="@string/quality"
android:textColor="@color/white"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/flClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
app:layout_constraintBottom_toBottomOf="@id/tv"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/guanbi" />
</FrameLayout>
<LinearLayout
android:id="@+id/ll1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="18dp"
app:layout_constraintTop_toBottomOf="@id/tv">
<TextView
android:id="@+id/tvAuto"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="Auto"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tvResolution1"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tvResolution2"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tvResolution3"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:text="Auto-switch to optimal resolution"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll1" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <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_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:background="@drawable/bg_2d2f3d_10">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginTop="10dp"
android:text="@string/playback_speed"
android:textColor="@color/white"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/flClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
app:layout_constraintBottom_toBottomOf="@id/tv"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/guanbi" />
</FrameLayout>
<LinearLayout
android:id="@+id/ll1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="18dp"
app:layout_constraintTop_toBottomOf="@id/tv">
<TextView
android:id="@+id/tv_0_5"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="0.5x"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_0_7_5"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="0.75x"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_1"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="1.0x"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_1_25"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="1.25x"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginBottom="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll1">
<TextView
android:id="@+id/tv_1_5"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="1.5x"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_2"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="2.0x"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:visibility="invisible"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="2.0x"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:visibility="invisible"
android:layout_width="0dp"
android:layout_height="52dp"
android:layout_margin="6dp"
android:layout_weight="1"
android:background="@drawable/bg_stroke_33ffffff_4d030303_5"
android:gravity="center"
android:text="2.0x"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -6,5 +6,9 @@ ...@@ -6,5 +6,9 @@
tools:context=".ui.main.PlaySlideFragment"> tools:context=".ui.main.PlaySlideFragment">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vpShortFeed"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout> </FrameLayout>
\ No newline at end of file
...@@ -6,6 +6,53 @@ ...@@ -6,6 +6,53 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:background="#99000000"> tools:background="#99000000">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginTop="60dp"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/flBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/fanhui" />
</FrameLayout>
<TextView
android:id="@+id/tvTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold"
tools:text="Secret Strangers in Love" />
<FrameLayout
android:id="@+id/flMore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/genduo" />
</FrameLayout>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -38,22 +85,22 @@ ...@@ -38,22 +85,22 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:text="00:00 / "
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="13sp" android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@id/nifty_slider" app:layout_constraintStart_toStartOf="@id/nifty_slider"
app:layout_constraintTop_toBottomOf="@id/nifty_slider" app:layout_constraintTop_toBottomOf="@id/nifty_slider" />
android:text="00:00 / " />
<TextView <TextView
android:id="@+id/tvPlayTotal" android:id="@+id/tvPlayTotal"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="00:00"
android:textColor="#80FFFFFF" android:textColor="#80FFFFFF"
android:textSize="13sp" android:textSize="13sp"
app:layout_constraintStart_toEndOf="@id/tvPlayNow" app:layout_constraintStart_toEndOf="@id/tvPlayNow"
app:layout_constraintTop_toTopOf="@id/tvPlayNow" app:layout_constraintTop_toTopOf="@id/tvPlayNow" />
android:text="00:00" />
<TextView <TextView
android:id="@+id/tvQuality" android:id="@+id/tvQuality"
...@@ -82,5 +129,4 @@ ...@@ -82,5 +129,4 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout> </FrameLayout>
\ No newline at end of file
...@@ -31,5 +31,7 @@ ...@@ -31,5 +31,7 @@
<string name="discover_more">Discover More</string> <string name="discover_more">Discover More</string>
<string name="nothing_here_yet_add_something">Nothing here yet - Add something!</string> <string name="nothing_here_yet_add_something">Nothing here yet - Add something!</string>
<string name="auto">Auto</string> <string name="auto">Auto</string>
<string name="playback_speed">Playback Speed</string>
<string name="quality">Quality</string>
</resources> </resources>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment