Integrated user_video_view api for all modules.

Sync for clicks when logout synchronously.
Sync for clicks when user closes app.
This commit is contained in:
2024-08-16 20:54:56 +05:30
parent e4de3182c0
commit df34a2ee9d
26 changed files with 367 additions and 133 deletions

View File

@@ -2,7 +2,6 @@ package com.woka
import android.annotation.SuppressLint
import android.app.Application
import android.util.Log
import com.jwplayer.pub.api.license.LicenseUtil
import com.onesignal.OneSignal
import com.woka.database.AppDatabase
@@ -10,7 +9,6 @@ import com.woka.streamingurls.StreamingUrlRepository
import com.woka.userPreference.UserPreference
import com.woka.utils.JW_PLAYER_LICENSE
import com.woka.utils.ONESIGNAL_APP_ID
import com.woka.utils.TAG
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

View File

@@ -29,7 +29,7 @@ import com.woka.databinding.ActivityAudioBooksBinding
import com.woka.databinding.DialogModuleShowerBinding
import com.woka.networking.ApiResult
import com.woka.players.models.VideoPlayList
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import com.woka.players.views.PlayerActivity
import com.woka.userPreference.UserType
import com.woka.utils.NoSignInDialog
@@ -377,7 +377,7 @@ class AudioBooksActivity : WokaBaseActivity() {
.build()
)
},
mutableListOf(VideoViewRequestData(
mutableListOf(VideoViewData(
audioBookData.id,
ContentType.AUDIO
))

View File

@@ -7,11 +7,8 @@ import com.woka.database.remote.models.RemoteClickEvent
import com.woka.networking.ApiResult
import com.woka.networking.RetrofitHelper
import com.woka.networking.RetrofitHelper.handleApiCall
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
private const val SYNC_BATCH_COUNT = 10
private const val SYNC_BATCH_COUNT = 15
object RemoteSync {
@@ -20,47 +17,45 @@ object RemoteSync {
private val clicksDao = appDatabase?.clicksDao()
private val apiService = RetrofitHelper.getRetrofit().create(RemoteApiService::class.java)
fun syncClickEvents(){
CoroutineScope(Dispatchers.IO).launch {
Log.d(TAG, "syncClickEvents: CLICK EVENTS SYNC CALLED")
suspend fun syncClickEvents(){
Log.d(TAG, "syncClickEvents: CLICK EVENTS SYNC CALLED")
var roundCount = 0
var roundCount = 0
while (true){
val clicksBatch = clicksDao?.getClickEventBatch(SYNC_BATCH_COUNT)
while (true){
val clicksBatch = clicksDao?.getClickEventBatch(SYNC_BATCH_COUNT)
if (clicksDao == null || clicksBatch.isNullOrEmpty()){
Log.d(TAG, "syncClickEvents: RECEIVED BATCH IS EMPTY")
break
}
Log.d(TAG, "syncClickEvents: BATCH COUNT FROM DATABASE ${clicksBatch.size}")
when (val response = handleApiCall{ apiService.sendClickEvents(clicksBatch.map { RemoteClickEvent(it) })}){
is ApiResult.Error -> {
Log.e(TAG, "syncClickEvents: BATCH SYNC FAILED due to ${response.errorMessage}", response.error)
break
}
is ApiResult.Loading -> {}
is ApiResult.Success -> {
Log.d(TAG, "syncClickEvents: BATCH SYNC IS SUCCESSFUL")
Log.d(TAG, "syncClickEvents: DELETING SYNCED DATA FROM LOCAL DATABASE")
val deleteCount = clicksDao.deleteClickEvents(clicksBatch)
Log.d(TAG, "syncClickEvents: $deleteCount ENTRIES ARE DELETED FROM LOCAL DATABASE")
if (deleteCount <= 0){
Log.e(TAG, "syncClickEvents: NO ENTRIES WERE DELETED FROM LOCAL DATABASE")
}
roundCount++
}
}
Log.d(TAG, "syncClickEvents: \n")
if (clicksDao == null || clicksBatch.isNullOrEmpty()){
Log.d(TAG, "syncClickEvents: RECEIVED BATCH IS EMPTY")
break
}
Log.d(TAG, "syncClickEvents: NUMBER OF ROUND : $roundCount")
Log.d(TAG, "syncClickEvents: BATCH COUNT FROM DATABASE ${clicksBatch.size}")
when (val response = handleApiCall{ apiService.sendClickEvents(clicksBatch.map { RemoteClickEvent(it) })}){
is ApiResult.Error -> {
Log.e(TAG, "syncClickEvents: BATCH SYNC FAILED due to ${response.errorMessage}", response.error)
break
}
is ApiResult.Loading -> {}
is ApiResult.Success -> {
Log.d(TAG, "syncClickEvents: BATCH SYNC IS SUCCESSFUL")
Log.d(TAG, "syncClickEvents: DELETING SYNCED DATA FROM LOCAL DATABASE")
val deleteCount = clicksDao.deleteClickEvents(clicksBatch)
Log.d(TAG, "syncClickEvents: $deleteCount ENTRIES ARE DELETED FROM LOCAL DATABASE")
if (deleteCount <= 0){
Log.e(TAG, "syncClickEvents: NO ENTRIES WERE DELETED FROM LOCAL DATABASE")
}
roundCount++
}
}
Log.d(TAG, "syncClickEvents: \n")
}
Log.d(TAG, "syncClickEvents: NUMBER OF ROUND : $roundCount")
}
}

View File

@@ -14,4 +14,4 @@ data class VideoViewEvent(
@ColumnInfo(name = "post_type") val postType: Int,
@ColumnInfo(name = "categoryId") val categoryId: Int,
@ColumnInfo(name = "total_watch_duration") val watchDuration: Long
)
)

View File

@@ -20,7 +20,7 @@ import com.woka.home.views.FMActivity
import com.woka.karaoke.views.KaraokeActivity
import com.woka.networking.ApiResult
import com.woka.players.models.VideoPlayList
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import com.woka.players.views.LiveStreamPlayerActivity
import com.woka.players.views.PlayerActivity
import com.woka.shop.views.ShopActivity
@@ -155,7 +155,7 @@ class Home2Fragment : Fragment() {
.build()
)
},
mutableListOf(VideoViewRequestData(
mutableListOf(VideoViewData(
0,
ContentType.TEASER
))

View File

@@ -51,7 +51,7 @@ import com.woka.karaoke.player.KaraokePlayerData
import com.woka.networking.ApiResult
import com.woka.onboard.views.OnboardActivity
import com.woka.players.models.VideoPlayList
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import com.woka.players.views.PlayerActivity
import com.woka.userPreference.UserType
import com.woka.userdata.UserRepository
@@ -795,7 +795,7 @@ class MyListFragment : Fragment() {
)
},
mutableListOf(
VideoViewRequestData(
VideoViewData(
audioBookData.id,
ContentType.AUDIO
)

View File

@@ -28,7 +28,7 @@ import com.woka.home.mylist.MyListRepository
import com.woka.home.mylist.viewmodel.FavoriteViewModel
import com.woka.networking.ApiResult
import com.woka.players.models.VideoPlayList
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import com.woka.players.views.PlayerActivity
import com.woka.utils.hide
import com.woka.utils.isNetworkConnected
@@ -346,7 +346,7 @@ class FavAudioFragment : Fragment() {
)
},
mutableListOf(
VideoViewRequestData(
VideoViewData(
audioBookData.id,
ContentType.AUDIO
)

View File

@@ -11,6 +11,7 @@ import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.Player.Listener
import androidx.media3.exoplayer.ExoPlayer
import com.woka.database.helpers.RemoteSync
import com.woka.home.views.BottomNavigation.Companion.HOME
import com.woka.networking.ApiResult
import com.woka.userdata.UserRepository
@@ -97,6 +98,7 @@ class HomeViewModel : ViewModel() {
fun logout() {
viewModelScope.launch {
_logoutLiveData.postValue(ApiResult.Loading())
RemoteSync.syncClickEvents()
_logoutLiveData.postValue(UserRepository.logout())
}
}

View File

@@ -15,6 +15,8 @@ import com.woka.R
import com.woka.database.helpers.ClicksHelper
import com.woka.database.models.ContentType
import com.woka.databinding.ActivityFmactivityBinding
import com.woka.userdata.UserRepository
import com.woka.userdata.userDataModels.VideoViewRequestData
import com.woka.utils.TAG
import com.woka.utils.WokaBaseActivity
import com.woka.utils.hide
@@ -38,6 +40,9 @@ class FMActivity : WokaBaseActivity() {
private val clickHelper = ClicksHelper
private var playbackStartTime: Long = 0
private var totalPlaybackDuration: Long = 0
@SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -66,6 +71,32 @@ class FMActivity : WokaBaseActivity() {
clickEvents()
setObservers()
playbackStartTime = System.currentTimeMillis()
}
override fun onStop() {
super.onStop()
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
val playingDurationInSecs = Math.round(totalPlaybackDuration/1000.0)
if (fmId > 0 && playingDurationInSecs > 0) {
UserRepository.userVideoView(
VideoViewRequestData(
fmId,
ContentType.FM.id,
playingDurationInSecs
)
)
totalPlaybackDuration = 0
playbackStartTime = System.currentTimeMillis()
}
}
override fun onDestroy() {

View File

@@ -22,11 +22,13 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.bumptech.glide.Glide
import com.woka.BuildConfig
import com.woka.R
import com.woka.WokaApp.Companion.userPrefs
import com.woka.database.helpers.ClicksHelper
import com.woka.database.helpers.RemoteSync
import com.woka.database.models.ContentType
import com.woka.databinding.ActivityHomeBinding
import com.woka.home.fragments.Home1Fragment
@@ -69,6 +71,7 @@ import com.woka.utils.lightStatusBar
import com.woka.utils.setVisibility
import com.woka.utils.show
import com.woka.utils.toast
import kotlinx.coroutines.launch
import kotlin.math.min
class HomeActivity : WokaBaseActivity(),
@@ -137,8 +140,12 @@ class HomeActivity : WokaBaseActivity(),
decisionDialog.message = getString(R.string.do_you_want_to_exit_from_the_woka_app)
decisionDialog.setPositiveButton(getString(R.string.yes)){
@Suppress("DEPRECATION")
super.onBackPressed()
lifecycleScope.launch {
RemoteSync.syncClickEvents()
@Suppress("DEPRECATION")
super.onBackPressed()
}
}
decisionDialog.setNegativeButton(getString(R.string.no))

View File

@@ -28,7 +28,7 @@ import com.woka.modules.wokasongs.WokaSongsAdapter
import com.woka.modules.wokasongs.WokaSongsRepository
import com.woka.networking.ApiResult
import com.woka.players.models.VideoPlayList
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import com.woka.players.views.PlayerActivity
import com.woka.utils.WokaBaseActivity
import com.woka.utils.hide
@@ -140,7 +140,7 @@ class MoreHomeActivity : WokaBaseActivity() {
)
},
mutableListOf(
VideoViewRequestData(
VideoViewData(
0,
ContentType.TEASER
)

View File

@@ -35,6 +35,8 @@ import com.woka.database.helpers.ClicksHelper
import com.woka.database.models.ContentType
import com.woka.databinding.ActivityKaraokePlayerrBinding
import com.woka.players.models.PlayBackState
import com.woka.userdata.UserRepository
import com.woka.userdata.userDataModels.VideoViewRequestData
import com.woka.utils.TAG
import com.woka.utils.WokaBaseActivity
import com.woka.utils.hide
@@ -93,6 +95,11 @@ class KaraokePlayerActivity : WokaBaseActivity() {
private lateinit var permissionLauncher: ActivityResultLauncher<String>
private lateinit var storagePermissionLauncher: ActivityResultLauncher<String>
// user video view params
private var playbackStartTime: Long = 0
private var totalPlaybackDuration: Long = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
@@ -150,6 +157,36 @@ class KaraokePlayerActivity : WokaBaseActivity() {
}
override fun onStop() {
super.onStop()
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
val playingDurationInSecs = Math.round(totalPlaybackDuration/1000.0)
karaokePlayerData?.id?.let {
if (it > 0 && playingDurationInSecs > 0) {
UserRepository.userVideoView(
VideoViewRequestData(
it,
ContentType.KARAOKE_VIDEO.id,
playingDurationInSecs
)
)
totalPlaybackDuration = 0
}
}
}
override fun onStart() {
super.onStart()
playbackStartTime = System.currentTimeMillis()
}
override fun onDestroy() {
super.onDestroy()
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
@@ -300,7 +337,7 @@ class KaraokePlayerActivity : WokaBaseActivity() {
RecordingState.PLAYING_AUDIO -> {
recordBtn.text = getString(R.string.stop_recording)
recordBtn.text = getString(R.string.start_recording)
recordBtn.setCompoundDrawablesWithIntrinsicBounds(
R.drawable.ic_rec_mic,
0,

View File

@@ -48,7 +48,7 @@ object RetrofitHelper {
chain.proceed(request.build())
})
clientBuilder.callTimeout(10, TimeUnit.SECONDS)
clientBuilder.callTimeout(20, TimeUnit.SECONDS)
retrofit = Retrofit.Builder()
.baseUrl(BuildConfig.WOKA_STAGINNG_BASE_URL)

View File

@@ -1,7 +1,7 @@
package com.woka.players
import com.woka.networking.ApiResponse
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.POST
@@ -9,6 +9,6 @@ import retrofit2.http.POST
interface PlayerApiService {
@POST("user_video_view")
suspend fun userVideoView(@Body requestData: VideoViewRequestData): Response<ApiResponse<Any>>
suspend fun userVideoView(@Body requestData: VideoViewData): Response<ApiResponse<Any>>
}

View File

@@ -7,5 +7,5 @@ import kotlinx.parcelize.Parcelize
@Parcelize
data class VideoPlayList(
val playlist: ArrayList<PlaylistItem>,
val videoViewRequestDataList: MutableList<VideoViewRequestData>
val videoViewRequestDataList: MutableList<VideoViewData>
): Parcelable

View File

@@ -5,9 +5,9 @@ import com.woka.database.models.ContentType
import kotlinx.parcelize.Parcelize
@Parcelize
data class VideoViewRequestData(
data class VideoViewData(
val id: Int?,
val contentType: ContentType,
val categoryId: String? = null,
var categoryId: String? = null,
var watchedDuration: String? = null
) : Parcelable

View File

@@ -22,12 +22,14 @@ import com.woka.database.models.ContentType
import com.woka.databinding.ActivityLiveStreamPlayerBinding
import com.woka.players.KeepScreenOnHandler
import com.woka.players.models.PlayBackState
import com.woka.userdata.UserRepository
import com.woka.userdata.userDataModels.VideoViewRequestData
import com.woka.utils.hide
import com.woka.utils.show
class LiveStreamPlayerActivity : AppCompatActivity(), FullscreenHandler {
companion object{
companion object {
const val EXTRA_LIVE_STREAM_URL = "extra_live_stream_url"
const val EXTRA_LIVE_STREAM_ID = "extra_live_stream_id"
@@ -75,11 +77,11 @@ class LiveStreamPlayerActivity : AppCompatActivity(), FullscreenHandler {
liveTvId = intent.getIntExtra(EXTRA_LIVE_STREAM_ID, -1)
networkCallback = object : NetworkCallback(){
networkCallback = object : NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
runOnUiThread {
if (playbackState == PlayBackState.STOPPED){
if (playbackState == PlayBackState.STOPPED) {
binding.playerView.show()
binding.errorView.hide()
configureAndPlay()
@@ -98,14 +100,32 @@ class LiveStreamPlayerActivity : AppCompatActivity(), FullscreenHandler {
}
override fun onPause() {
super.onPause()
player.pause()
override fun onStop() {
super.onStop()
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
val playingDurationInSecs = Math.round(totalPlaybackDuration/1000.0)
if (liveTvId > 0 && playingDurationInSecs > 0) {
UserRepository.userVideoView(
VideoViewRequestData(
liveTvId,
ContentType.LIVE_TV.id,
playingDurationInSecs
)
)
totalPlaybackDuration = 0
}
}
override fun onResume() {
super.onResume()
player.pause()
override fun onStart() {
super.onStart()
playbackStartTime = System.currentTimeMillis()
}
override fun onDestroy() {
@@ -116,7 +136,7 @@ class LiveStreamPlayerActivity : AppCompatActivity(), FullscreenHandler {
)
}
private fun setUpPlayer(){
private fun setUpPlayer() {
player = binding.playerView.getPlayer(this)
// to keep up the screen om when video is being played
@@ -130,48 +150,35 @@ class LiveStreamPlayerActivity : AppCompatActivity(), FullscreenHandler {
playlist.add(playlistItem)
playerConfig = PlayerConfig.Builder()
.playlist(playlist)
.autostart(true)
.build()
.playlist(playlist)
.autostart(true)
.build()
}
private fun addListeners(){
private fun addListeners() {
player.addListener(EventType.PLAY, VideoPlayerEvents.OnPlayListener {
playbackState = PlayBackState.PLAY
binding.playerView.show()
binding.errorView.hide()
errorRetryCount = ERROR_RETRY_COUNT
playbackStartTime = System.currentTimeMillis()
upsertClickEvent()
})
player.addListener(EventType.PAUSE, VideoPlayerEvents.OnPauseListener {
playbackState = PlayBackState.PAUSED
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
upsertClickEvent()
})
player.addListener(EventType.ERROR, VideoPlayerEvents.OnErrorListener {
playbackState = PlayBackState.STOPPED
if (errorRetryCount > 0){
if (errorRetryCount > 0) {
errorRetryCount--
configureAndPlay()
}else{
} else {
binding.playerView.hide()
binding.errorView.show()
}
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
})
(getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager).registerNetworkCallback(
@@ -187,7 +194,7 @@ class LiveStreamPlayerActivity : AppCompatActivity(), FullscreenHandler {
player.setup(playerConfig)
}
private fun clickEvents(){
private fun clickEvents() {
binding.apply {
retryBtn.setOnClickListener {
binding.playerView.show()
@@ -201,7 +208,7 @@ class LiveStreamPlayerActivity : AppCompatActivity(), FullscreenHandler {
}
}
private fun upsertClickEvent(){
private fun upsertClickEvent() {
if (liveTvId == -1) return
clickHelper.upsertClickEvent(

View File

@@ -24,10 +24,13 @@ import com.woka.databinding.ActivityPlayerBinding
import com.woka.players.KeepScreenOnHandler
import com.woka.players.models.PlayBackState
import com.woka.players.models.VideoPlayList
import com.woka.utils.TAG
import com.woka.userdata.UserRepository
import com.woka.userdata.userDataModels.VideoViewRequestData
import com.woka.utils.hide
import com.woka.utils.show
private const val TAG = "PlayerActivity_TAG"
class PlayerActivity : AppCompatActivity(), FullscreenHandler {
companion object{
@@ -46,6 +49,9 @@ class PlayerActivity : AppCompatActivity(), FullscreenHandler {
private var playingIndex: Int = 0
private var seekPosition: Double = 0.0
private var playbackStartTime: Long = 0
private var totalPlaybackDuration: Long = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
@@ -96,6 +102,41 @@ class PlayerActivity : AppCompatActivity(), FullscreenHandler {
)
}
override fun onStop() {
super.onStop()
videoPlayList?.videoViewRequestDataList?.let {playlistData ->
if (playingIndex >= 0 && playingIndex < playlistData.size){
with(playlistData[playingIndex]){
// user video view
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
val playingDurationInSecs = Math.round(totalPlaybackDuration/1000.0)
id?.let {id ->
if (id > 0 && playingDurationInSecs > 0) {
UserRepository.userVideoView(
VideoViewRequestData(
id,
contentType.id,
playingDurationInSecs,
categoryId
)
)
totalPlaybackDuration = 0
Log.d(TAG, "onStop: API DONE $playingDurationInSecs")
}
}
}
}
}
}
private fun clickEvents(){
binding.apply {
retryBtn.setOnClickListener {
@@ -155,6 +196,9 @@ class PlayerActivity : AppCompatActivity(), FullscreenHandler {
}
}
}
Log.d(TAG, "addListeners: PLAY")
playbackStartTime = System.currentTimeMillis()
})
player.addListener(EventType.PAUSE, VideoPlayerEvents.OnPauseListener {
playbackState = PlayBackState.PAUSED
@@ -172,6 +216,14 @@ class PlayerActivity : AppCompatActivity(), FullscreenHandler {
}
}
}
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
Log.d(TAG, "addListeners: PAUSE ${Math.round(totalPlaybackDuration/1000.0)}")
})
player.addListener(EventType.ERROR, VideoPlayerEvents.OnErrorListener {
if (player.position != 0.0){
@@ -180,26 +232,58 @@ class PlayerActivity : AppCompatActivity(), FullscreenHandler {
playbackState = PlayBackState.STOPPED
binding.playerView.hide()
binding.errorView.show()
})
player.addListener(EventType.PLAYLIST_ITEM, VideoPlayerEvents.OnPlaylistItemListener {
playingIndex = it.index
videoPlayList?.videoViewRequestDataList?.let {playlistData ->
if (playingIndex >= 0 && playingIndex < playlistData.size){
with(playlistData[playingIndex]){
ClicksHelper.upsertClickEvent(
contentType,
id,
categoryId
)
}
}
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
})
player.addListener(EventType.SEEK, VideoPlayerEvents.OnSeekListener {
Log.d(TAG, "addListeners: ")
player.addListener(EventType.PLAYLIST_ITEM, VideoPlayerEvents.OnPlaylistItemListener {
if (playingIndex != it.index){
videoPlayList?.videoViewRequestDataList?.let {playlistData ->
if (playingIndex >= 0 && playingIndex < playlistData.size){
with(playlistData[playingIndex]){
// user video view
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
val playingDurationInSecs = Math.round(totalPlaybackDuration/1000.0)
id?.let {id ->
if (id > 0 && playingDurationInSecs > 0) {
UserRepository.userVideoView(
VideoViewRequestData(
id,
contentType.id,
playingDurationInSecs,
categoryId
)
)
}
}
// resetting data for new video
totalPlaybackDuration = 0
Log.d(TAG, "onStop: API DONE $playingDurationInSecs")
// clicks event
ClicksHelper.upsertClickEvent(
contentType,
id,
categoryId
)
}
}
}
}
playingIndex = it.index
})
(getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager).registerNetworkCallback(

View File

@@ -4,6 +4,7 @@ import com.woka.home.mylist.models.MyListResponse
import com.woka.home.notifications.models.NotificationData
import com.woka.networking.ApiResponse
import com.woka.userdata.userDataModels.UserDataResponse
import com.woka.userdata.userDataModels.VideoViewRequestData
import okhttp3.FormBody
import retrofit2.Response
import retrofit2.http.Body
@@ -29,4 +30,7 @@ interface UserApiService {
@POST("v2/favourite_listing")
suspend fun getMyFavList(@Body formBody: FormBody): Response<ApiResponse<MyListResponse>>
@POST("user_video_view")
suspend fun userVideoView(@Body videoViewRequestData: VideoViewRequestData): Response<ApiResponse<Any>>
}

View File

@@ -2,10 +2,14 @@ package com.woka.userdata
import com.woka.home.mylist.models.MyListResponse
import com.woka.home.notifications.models.NotificationData
import com.woka.userdata.userDataModels.UserDataResponse
import com.woka.networking.ApiResult
import com.woka.networking.RetrofitHelper
import com.woka.networking.RetrofitHelper.handleApiCall
import com.woka.userdata.userDataModels.UserDataResponse
import com.woka.userdata.userDataModels.VideoViewRequestData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.FormBody
object UserRepository {
@@ -61,4 +65,12 @@ object UserRepository {
)
}
}
fun userVideoView(videoViewRequestData: VideoViewRequestData){
CoroutineScope(Dispatchers.IO).launch {
handleApiCall {
userApiService.userVideoView(videoViewRequestData)
}
}
}
}

View File

@@ -0,0 +1,9 @@
package com.woka.userdata.userDataModels
data class VideoViewRequestData(
val post_id: Int,
val post_type: Int,
val total_watched_duration: Long,
val category_id: String? = null,
val device_type: Int = 1
)

View File

@@ -9,7 +9,7 @@ import com.woka.database.models.ContentType
import com.woka.modules.categorymodels.CategoriesResponse
import com.woka.networking.ApiResult
import com.woka.players.models.VideoPlayList
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import com.woka.utils.PagingData
import com.woka.webseries.WebSeriesRepository
import com.woka.webseries.models.ContinueEpisodeResponse
@@ -269,9 +269,10 @@ class WebSeriesViewModel : ViewModel() {
)
currentPlayListHin.videoViewRequestDataList.add(
VideoViewRequestData(
VideoViewData(
episode.id,
ContentType.EPISODE
ContentType.EPISODE,
"18"
)
)
}
@@ -287,9 +288,10 @@ class WebSeriesViewModel : ViewModel() {
)
currentPlayListEng.videoViewRequestDataList.add(
VideoViewRequestData(
VideoViewData(
episode.id,
ContentType.EPISODE
ContentType.EPISODE,
"1"
)
)
}
@@ -376,9 +378,10 @@ class WebSeriesViewModel : ViewModel() {
)
currentPlayListHin.videoViewRequestDataList.add(
VideoViewRequestData(
VideoViewData(
teaser.id,
ContentType.TEASER
ContentType.EPISODE,
"18"
)
)
}
@@ -394,9 +397,10 @@ class WebSeriesViewModel : ViewModel() {
)
currentPlayListEng.videoViewRequestDataList.add(
VideoViewRequestData(
VideoViewData(
teaser.id,
ContentType.TEASER
ContentType.EPISODE,
"1"
)
)
}

View File

@@ -27,7 +27,7 @@ import com.woka.databinding.DialogContinueEpisodeBinding
import com.woka.databinding.FragmentWebSeriesBinding
import com.woka.networking.ApiResult
import com.woka.players.models.VideoPlayList
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import com.woka.players.views.PlayerActivity
import com.woka.players.views.PlayerActivity.Companion.EXTRA_PLAY_INDEX
import com.woka.players.views.PlayerActivity.Companion.EXTRA_PLAY_LIST
@@ -144,7 +144,7 @@ class WebSeriesFragment : Fragment() {
)
},
mutableListOf(
VideoViewRequestData(
VideoViewData(
0,
ContentType.TEASER
)
@@ -256,7 +256,7 @@ class WebSeriesFragment : Fragment() {
binding.categorySpinner.setSelection(viewModel.selectedCategoryPos)
loadShowData()
if (userPrefs?.userType != UserType.GUEST && !viewModel.continueWatchLiveData.isInitialized) {
if (userPrefs?.userType != UserType.GUEST) {
viewModel.loadContinueWatching()
}
}
@@ -277,7 +277,7 @@ class WebSeriesFragment : Fragment() {
if (continueWatchList.isNotEmpty()) {
binding.rvContinueWatch.show()
binding.continueWatchTxt.show()
continueWatchAdapter.submitList(continueWatchList.reversed())
continueWatchAdapter.submitList(continueWatchList)
} else {
binding.rvContinueWatch.hide()
binding.continueWatchTxt.hide()
@@ -450,7 +450,7 @@ class WebSeriesFragment : Fragment() {
)
videoPlayList.videoViewRequestDataList.add(
VideoViewRequestData(
VideoViewData(
episodeData.id,
ContentType.EPISODE,
"18"
@@ -468,7 +468,7 @@ class WebSeriesFragment : Fragment() {
)
videoPlayList.videoViewRequestDataList.add(
VideoViewRequestData(
VideoViewData(
episodeData.id,
ContentType.EPISODE,
"1"

View File

@@ -27,7 +27,7 @@ import com.woka.databinding.DialogEpisodeBinding
import com.woka.databinding.FragmentWebShowBinding
import com.woka.networking.ApiResult
import com.woka.players.models.VideoPlayList
import com.woka.players.models.VideoViewRequestData
import com.woka.players.models.VideoViewData
import com.woka.players.views.PlayerActivity
import com.woka.userPreference.UserType
import com.woka.utils.NoSignInDialog
@@ -285,9 +285,10 @@ class WebShowFragment : Fragment(), TabLayout.OnTabSelectedListener {
}
val videoPlayList = VideoPlayList(ArrayList(), mutableListOf(
VideoViewRequestData(
VideoViewData(
seasonData.id,
ContentType.SEASON
ContentType.EPISODE,
categoryId
)
))
videoPlayList.playlist.add(playlistItem.build())

View File

@@ -14,6 +14,8 @@ import com.woka.R
import com.woka.database.helpers.ClicksHelper
import com.woka.database.models.ContentType
import com.woka.databinding.ActivityGamePlayerBinding
import com.woka.userdata.UserRepository
import com.woka.userdata.userDataModels.VideoViewRequestData
import com.woka.utils.DecisionDialog
import com.woka.utils.WokaBaseActivity
@@ -30,6 +32,9 @@ class GamePlayerActivity : WokaBaseActivity() {
private var clicksCount = 0
private var playbackStartTime: Long = 0
private var totalPlaybackDuration: Long = 0
@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -64,14 +69,36 @@ class GamePlayerActivity : WokaBaseActivity() {
}
}
override fun onStart() {
super.onStart()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
override fun onStop() {
super.onStop()
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
if (playbackStartTime > 0) {
val elapsed = System.currentTimeMillis() - playbackStartTime
totalPlaybackDuration += elapsed
playbackStartTime = 0
}
val playingDurationInSecs = Math.round(totalPlaybackDuration/1000.0)
gamePlayerData?.id?.let {
if (it > 0 && playingDurationInSecs > 0) {
UserRepository.userVideoView(
VideoViewRequestData(
it,
ContentType.GAME.id,
playingDurationInSecs
)
)
totalPlaybackDuration = 0
}
}
}
override fun onStart() {
super.onStart()
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
playbackStartTime = System.currentTimeMillis()
}
override fun onResume() {
@@ -89,6 +116,20 @@ class GamePlayerActivity : WokaBaseActivity() {
binding.webView.destroy()
ClicksHelper.upsertClickEvent(ContentType.GAME, gamePlayerData?.id, null, clicksCount)
val playingDurationInSecs = totalPlaybackDuration / 1000
gamePlayerData?.id?.let {
if (it > 0 && playingDurationInSecs > 0) {
UserRepository.userVideoView(
VideoViewRequestData(
it,
ContentType.GAME.id,
playingDurationInSecs
)
)
}
}
}
@SuppressLint("SetJavaScriptEnabled")

View File

@@ -41,6 +41,7 @@
android:layout_height="@dimen/_20ssp"
android:contentDescription="@string/image"
android:src="@drawable/ic_home_bn"
android:scaleType="fitXY"
app:tint="@android:color/darker_gray" />
<TextView
@@ -133,6 +134,7 @@
android:layout_height="@dimen/_20ssp"
android:contentDescription="@string/image"
android:src="@drawable/ic_heart_filled"
android:scaleType="fitXY"
app:tint="@android:color/darker_gray"
/>