diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index aaa7c99..c4cb747 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,8 +3,8 @@
xmlns:tools="http://schemas.android.com/tools">
-
-
+
+
+
+ android:supportsPictureInPicture="true" />
+ android:screenOrientation="portrait" />
>
+ suspend fun audioBookListing(@Body formBody: FormBody): Response>
}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/audiobooks/AudioBookRepository.kt b/app/src/main/java/com/woka/audiobooks/AudioBookRepository.kt
index 4f3f30e..fff45bd 100644
--- a/app/src/main/java/com/woka/audiobooks/AudioBookRepository.kt
+++ b/app/src/main/java/com/woka/audiobooks/AudioBookRepository.kt
@@ -1,7 +1,5 @@
package com.woka.audiobooks
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
import com.woka.audiobooks.models.audiodata.AudioBookData
import com.woka.audiobooks.models.audiodata.AudioBooksResponse
import com.woka.audiobooks.models.continuedata.ContinueAudioResponse
@@ -12,7 +10,6 @@ import com.woka.networking.ApiResult
import com.woka.networking.RetrofitHelper
import com.woka.networking.RetrofitHelper.handleApiCall
import com.woka.userdata.UserActionApiService
-import com.woka.utils.TAG
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -25,75 +22,25 @@ object AudioBookRepository {
private val apiService = RetrofitHelper.getRetrofit().create(AudioBookApiService::class.java)
private val userActionApiService = RetrofitHelper.getRetrofit().create(UserActionApiService::class.java)
- // live data
- // audio books data (loose caching)
- private val _audioBooksLiveData = MutableLiveData>()
- val audioBooksLiveData: LiveData>
- get() = _audioBooksLiveData
-
- private var audioBooksData: AudioBooksResponse? = null
-
- // continue watch audio books data
- private val _continueAudioBooksLiveData = MutableLiveData>()
- val continueAudioBooksLiveData: LiveData>
- get() = _continueAudioBooksLiveData
-
- private var continueAudioData: ContinueAudioResponse? = null
-
- fun loadAudioBooks(){
- if (audioBooksData != null){
- _audioBooksLiveData.postValue(ApiResult.Success(audioBooksData))
- return
- }
-
- CoroutineScope(Dispatchers.IO).launch{
- _audioBooksLiveData.postValue(ApiResult.Loading())
-
- val response = handleApiCall{
- apiService.audioBookListing()
- }
-
- when (response){
- is ApiResult.Error -> _audioBooksLiveData.postValue(ApiResult.Error(response.errorMessage, response.error))
- is ApiResult.Loading -> _audioBooksLiveData.postValue(ApiResult.Loading())
- is ApiResult.Success -> {
- response.data?.let {
- audioBooksData = it
- _audioBooksLiveData.postValue(ApiResult.Success(it))
- }?:{
- _audioBooksLiveData.postValue(ApiResult.Error())
- }
- }
- }
+ suspend fun loadAudioBooks(pageNo: Int, quantity: Int): ApiResult {
+ return handleApiCall {
+ apiService.audioBookListing(
+ FormBody.Builder()
+ .add("api_version", "v2")
+ .add("start", "$pageNo")
+ .add("limit", "$quantity")
+ .build()
+ )
}
}
- fun loadContinueListening(){
- if (continueAudioData != null){
- _continueAudioBooksLiveData.postValue(ApiResult.Success(continueAudioData))
- return
- }
-
- CoroutineScope(Dispatchers.IO).launch {
- val response = handleApiCall {
- userActionApiService.continueAudioBookListing(
- FormBody.Builder()
- .add("post_type", PostType.AUDIO_BOOKS.value)
- .build()
- )
- }
-
- when (response){
- is ApiResult.Error -> {}
- is ApiResult.Loading -> {}
- is ApiResult.Success -> {
- response.data?.let {
- continueAudioData = it
- }
- }
- }
-
- _continueAudioBooksLiveData.postValue(response)
+ suspend fun loadContinueLiveData(): ApiResult {
+ return handleApiCall {
+ userActionApiService.continueAudioBookListing(
+ FormBody.Builder()
+ .add("post_type", PostType.AUDIO_BOOKS.value)
+ .build()
+ )
}
}
@@ -122,48 +69,6 @@ object AudioBookRepository {
}
private fun changeLikeLocally(id: String, isLiked: Boolean){
- // changing in audio books locally
- audioBooksData?.audio_data?.let {audioBooks ->
- for (audio in audioBooks){
- var found = false
- audio?.let {data ->
- if ("${data.id}" == id){
-
- data.is_liked = isLiked
-
- data.likes_count?.let { count ->
- data.likes_count = if (isLiked) count + 1
- else max(0, count - 1)
- }
-
- found = true
- }
- }
- if (found) break
- }
- }
-
- // continue audio books data update
- continueAudioData?.result?.let {
- for (audio in it){
- var found = false
- audio?.let {data ->
- if ("${data.id}" == id){
-
- data.is_liked = isLiked
-
- data.likes_count?.let { count ->
- data.likes_count = if (isLiked) count + 1
- else max(0, count - 1)
- }
-
- found = true
- }
- }
- if (found) break
- }
- }
-
// changing in fav list locally
MyListRepository.myFavData.result?.audio_data?.let {
for (audioData in it){
@@ -208,29 +113,5 @@ object AudioBookRepository {
favAudioData.removeIf{it.id == audioBookData.id}
}
}
-
- audioBooksData?.audio_data?.let {
- for (audio in it){
- if (audio?.id == audioBookData.id){
- audio?.mark_as_favourite = addToBookmark
- break
- }
- }
- }
-
- continueAudioData?.result?.let {
- for (audio in it){
- if (audio?.id == audioBookData.id){
- audio?.mark_as_favourite = addToBookmark
- break
- }
- }
- }
-
- }
-
- fun clearData(){
- audioBooksData = null
- continueAudioData = null
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/audiobooks/adapters/AudioBooksAdapter.kt b/app/src/main/java/com/woka/audiobooks/adapters/AudioBooksAdapter.kt
index 5c8e859..c3ccc7d 100644
--- a/app/src/main/java/com/woka/audiobooks/adapters/AudioBooksAdapter.kt
+++ b/app/src/main/java/com/woka/audiobooks/adapters/AudioBooksAdapter.kt
@@ -16,11 +16,12 @@ import com.woka.utils.isNetworkConnected
import com.woka.utils.show
import com.woka.utils.toast
import java.util.concurrent.Executors
+import kotlin.math.max
class AudioBooksAdapter(
private val context: Context,
private var onBookClicked: (AudioBookData) -> Unit,
- private var onBookChanged: (id: Int) -> Unit
+ private var onBookChanged: (id: Int, AudioBookData) -> Unit
): ListAdapter(ASYNC_DIFF_UTIL) {
inner class AudioBookViewHolder(val binding: ShowViewHolderBinding): ViewHolder(binding.root)
@@ -96,10 +97,24 @@ class AudioBooksAdapter(
!like.isSelected
)
+ audioBook.likes_count?.let {
+ audioBook.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
+ }
+
+ audioBook.is_liked = !like.isSelected
+
like.isSelected = !like.isSelected
likeCount.text = "${audioBook.likes_count}"
- audioBook.id?.let(onBookChanged)
+ audioBook.id?.let{
+ onBookChanged(it, audioBook)
+ }
}
fav.isSelected = audioBook.mark_as_favourite == true
@@ -115,8 +130,12 @@ class AudioBooksAdapter(
!fav.isSelected
)
+ audioBook.mark_as_favourite = !fav.isSelected
+
fav.isSelected = audioBook.mark_as_favourite == true
- audioBook.id?.let(onBookChanged)
+ audioBook.id?.let{
+ onBookChanged(it, audioBook)
+ }
}
root.setOnClickListener {
diff --git a/app/src/main/java/com/woka/audiobooks/adapters/ContinueAudioAdapter.kt b/app/src/main/java/com/woka/audiobooks/adapters/ContinueAudioAdapter.kt
index 77961c4..d381cc2 100644
--- a/app/src/main/java/com/woka/audiobooks/adapters/ContinueAudioAdapter.kt
+++ b/app/src/main/java/com/woka/audiobooks/adapters/ContinueAudioAdapter.kt
@@ -17,10 +17,11 @@ import com.woka.utils.isNetworkConnected
import com.woka.utils.show
import com.woka.utils.toast
import java.util.concurrent.Executors
+import kotlin.math.max
class ContinueAudioAdapter(private val context: Context,
private var onBookClicked: (ContinueAudioData) -> Unit,
- private var onContinueBookChanged: (id: Int) -> Unit): ListAdapter(DIFF_CONFIG) {
+ private var onContinueBookChanged: (id: Int, AudioBookData) -> Unit): ListAdapter(DIFF_CONFIG) {
companion object{
private val DIFF_UTIL = object : DiffUtil.ItemCallback(){
@@ -91,10 +92,22 @@ class ContinueAudioAdapter(private val context: Context,
!like.isSelected
)
+ audioBook.likes_count?.let {
+ audioBook.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
+ }
+
+ audioBook.is_liked = !like.isSelected
+
like.isSelected = !like.isSelected
likeCount.text = "${audioBook.likes_count}"
- audioBook?.id?.let(onContinueBookChanged)
+ audioBook?.id?.let{onContinueBookChanged(it, AudioBookData(audioBook))}
}
fav.isSelected = audioBook.mark_as_favourite == true
@@ -110,8 +123,11 @@ class ContinueAudioAdapter(private val context: Context,
!fav.isSelected
)
+ audioBook.mark_as_favourite = !fav.isSelected
+
fav.isSelected = audioBook.mark_as_favourite == true
- audioBook?.id?.let(onContinueBookChanged)
+
+ audioBook?.id?.let{onContinueBookChanged(it, AudioBookData(audioBook))}
}
root.setOnClickListener {
diff --git a/app/src/main/java/com/woka/audiobooks/viewmodels/AudioBookViewModel.kt b/app/src/main/java/com/woka/audiobooks/viewmodels/AudioBookViewModel.kt
new file mode 100644
index 0000000..424cb84
--- /dev/null
+++ b/app/src/main/java/com/woka/audiobooks/viewmodels/AudioBookViewModel.kt
@@ -0,0 +1,81 @@
+package com.woka.audiobooks.viewmodels
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.woka.audiobooks.AudioBookRepository
+import com.woka.audiobooks.models.audiodata.AudioBookData
+import com.woka.audiobooks.models.continuedata.ContinueAudioData
+import com.woka.networking.ApiResult
+import kotlinx.coroutines.launch
+
+class AudioBookViewModel: ViewModel() {
+
+ private val _audioBookData = MutableLiveData>>()
+ val audioBookLiveData: LiveData>>
+ get() = _audioBookData
+
+ private val audioBookList = ArrayList()
+
+ private var nextPageToLoad: Int = 0
+ private var quantityPerPage: Int = 6
+ var lastPage = false
+
+ private val _audioContinueLiveData = MutableLiveData>>()
+ val audioContinueLiveData: LiveData>>
+ get() = _audioContinueLiveData
+
+ fun loadKaraokeSongs() {
+ viewModelScope.launch {
+ _audioBookData.postValue(ApiResult.Loading())
+
+ when (val value = AudioBookRepository.loadAudioBooks(nextPageToLoad, quantityPerPage)) {
+ is ApiResult.Error -> _audioBookData.postValue(
+ ApiResult.Error(
+ value.errorMessage,
+ value.error
+ )
+ )
+
+ is ApiResult.Loading -> _audioBookData.postValue(ApiResult.Loading())
+ is ApiResult.Success -> {
+ value.data?.let {
+ it.audio_data?.filterNotNull()?.let { newList ->
+ audioBookList.addAll(newList)
+
+ lastPage = audioBookList.size == it.total_records
+
+ _audioBookData.postValue(ApiResult.Success(audioBookList))
+ nextPageToLoad++
+ }
+ }
+ }
+ }
+ }
+ }
+
+ fun loadContinueData(){
+ viewModelScope.launch {
+ _audioContinueLiveData.postValue(ApiResult.Loading())
+
+ when (val value = AudioBookRepository.loadContinueLiveData()) {
+ is ApiResult.Error -> _audioContinueLiveData.postValue(
+ ApiResult.Error(
+ value.errorMessage,
+ value.error
+ )
+ )
+
+ is ApiResult.Loading -> _audioContinueLiveData.postValue(ApiResult.Loading())
+ is ApiResult.Success -> {
+ value.data?.let {
+ it.result?.filterNotNull()?.let { newList ->
+ _audioContinueLiveData.postValue(ApiResult.Success(newList))
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/audiobooks/views/AudioBooksActivity.kt b/app/src/main/java/com/woka/audiobooks/views/AudioBooksActivity.kt
index d1d0749..50cf1b4 100644
--- a/app/src/main/java/com/woka/audiobooks/views/AudioBooksActivity.kt
+++ b/app/src/main/java/com/woka/audiobooks/views/AudioBooksActivity.kt
@@ -11,32 +11,37 @@ import android.view.WindowManager
import androidx.activity.enableEdgeToEdge
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
+import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.SimpleItemAnimator
import com.google.android.material.appbar.CollapsingToolbarLayout
import com.jwplayer.pub.api.media.playlists.PlaylistItem
import com.woka.R
-import com.woka.WokaApp
import com.woka.WokaApp.Companion.userPrefs
import com.woka.audiobooks.AudioBookRepository
import com.woka.audiobooks.adapters.AudioBooksAdapter
import com.woka.audiobooks.adapters.ContinueAudioAdapter
import com.woka.audiobooks.models.audiodata.AudioBookData
import com.woka.audiobooks.models.continuedata.ContinueAudioData
+import com.woka.audiobooks.viewmodels.AudioBookViewModel
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.views.PlayerActivity
+import com.woka.userPreference.UserType
import com.woka.utils.WokaBaseActivity
import com.woka.utils.hide
+import com.woka.utils.setVisibility
import com.woka.utils.show
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
+import kotlin.math.max
class AudioBooksActivity : WokaBaseActivity() {
private lateinit var binding: ActivityAudioBooksBinding
+ private lateinit var viewModel: AudioBookViewModel
private lateinit var audioBookAdapter: AudioBooksAdapter
private lateinit var continueAudioAdapter: ContinueAudioAdapter
@@ -59,6 +64,8 @@ class AudioBooksActivity : WokaBaseActivity() {
navigationBarColor = getColor(R.color.color_primary_dark)
}
+ viewModel = ViewModelProvider(this)[AudioBookViewModel::class.java]
+
audioBookAdapter = AudioBooksAdapter(this, ::onBookClicked, ::onBookChanged)
continueAudioAdapter =
ContinueAudioAdapter(this, ::onContinueBookClicked, ::onContinueBookChanged)
@@ -75,7 +82,9 @@ class AudioBooksActivity : WokaBaseActivity() {
setObservers()
- AudioBookRepository.loadAudioBooks()
+ if (!viewModel.audioBookLiveData.isInitialized){
+ viewModel.loadKaraokeSongs()
+ }
}
private fun initViews() {
@@ -120,52 +129,81 @@ class AudioBooksActivity : WokaBaseActivity() {
}
retryBtn.setOnClickListener {
- AudioBookRepository.loadAudioBooks()
+ viewModel.loadKaraokeSongs()
+ }
+
+ loadMoreBtn.setOnClickListener {
+ viewModel.loadKaraokeSongs()
}
}
}
private fun setObservers() {
- AudioBookRepository.audioBooksLiveData.observe(this) {
- when (it) {
+ viewModel.audioBookLiveData.observe(this){
+ when(it){
is ApiResult.Error -> {
binding.shimmer.hide()
- binding.rvAudioBooks.hide()
- binding.listenTxt.hide()
- binding.trailerView.hide()
+ if (audioBookAdapter.currentList.size == 0) {
+ // none of the data is yet loaded
+ binding.rvAudioBooks.hide()
+ binding.listenTxt.hide()
+ binding.trailerView.hide()
- binding.errorView.show()
+ binding.errorView.show()
+ } else {
+ // error in loading more
+ binding.loadMoreProgress.hide()
+ binding.loadMoreBtn.text = getString(R.string.retry)
+ binding.loadMoreBtn.show()
+ }
}
-
is ApiResult.Loading -> {
- binding.shimmer.show()
-
- binding.rvAudioBooks.hide()
- binding.listenTxt.hide()
- binding.trailerView.hide()
- binding.errorView.hide()
+ if (audioBookAdapter.currentList.size == 0) {
+ // loading first data
+ binding.shimmer.show()
+ binding.errorView.hide()
+ } else {
+ // loading more data
+ binding.loadMoreProgress.show()
+ binding.loadMoreBtn.hide()
+ }
}
-
is ApiResult.Success -> {
- it.data?.audio_data?.filterNotNull()?.let { audioBookData ->
- if (audioBookData.isNotEmpty()) {
- binding.shimmer.hide()
- binding.errorView.hide()
-
- AudioBookRepository.loadContinueListening()
-
- loadTrailerData(audioBookData[0])
+ it.data?.let {newList ->
+ if (newList.isNotEmpty()){
binding.rvAudioBooks.show()
binding.listenTxt.show()
+ binding.trailerView.show()
- audioBookAdapter.submitList(audioBookData)
+ binding.errorView.hide()
+ binding.shimmer.hide()
+
+ binding.loadMoreProgress.hide()
+ binding.loadMoreBtn.text = getString(R.string.load_more)
+ binding.loadMoreBtn.setVisibility(!viewModel.lastPage)
+
+ if (audioBookAdapter.currentList.isEmpty()){
+ // first data load
+ if (userPrefs?.userType != UserType.GUEST && !viewModel.audioContinueLiveData.isInitialized){
+ viewModel.loadContinueData()
+ }
+
+ loadTrailerData(newList[0])
+ audioBookAdapter.submitList(newList)
+ }else{
+ // loaded more data
+ audioBookAdapter.notifyItemRangeInserted(
+ audioBookAdapter.currentList.size,
+ newList.size
+ )
+ }
}
}
}
}
}
- AudioBookRepository.continueAudioBooksLiveData.observe(this) {
+ viewModel.audioContinueLiveData.observe(this) {
when (it) {
is ApiResult.Error -> {
binding.continueListenTxt.hide()
@@ -174,12 +212,12 @@ class AudioBooksActivity : WokaBaseActivity() {
is ApiResult.Loading -> {}
is ApiResult.Success -> {
- it.data?.result?.filterNotNull()?.let { continueData ->
- if (continueData.isNotEmpty()) {
+ it.data?.let { continueList ->
+ if (continueList.isNotEmpty()) {
binding.continueListenTxt.show()
binding.rvContinueListen.show()
- continueAudioAdapter.submitList(continueData.toMutableList())
+ continueAudioAdapter.submitList(continueList)
} else {
binding.continueListenTxt.hide()
binding.rvContinueListen.hide()
@@ -201,7 +239,7 @@ class AudioBooksActivity : WokaBaseActivity() {
audioBookData.content_more_details?.let { moreDetailsList ->
trailerName.text = if (moreDetailsList.isNotEmpty()) {
- if (WokaApp.userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) {
+ if (userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) {
moreDetailsList[1]?.title
} else {
moreDetailsList[0]?.title
@@ -238,18 +276,32 @@ class AudioBooksActivity : WokaBaseActivity() {
showAudioDialog(AudioBookData(audioBookData))
}
- private fun onBookChanged(id: Int) {
+ private fun onBookChanged(id: Int, audioBookData: AudioBookData) {
// updating continue book list
val position = continueAudioAdapter.currentList.indexOfFirst { it.id == id }
if (position >= 0 && position < continueAudioAdapter.currentList.size) {
+ val currKaraoke = continueAudioAdapter.currentList[position]
+
+ // updating possible data changes
+ currKaraoke.is_liked = audioBookData.is_liked
+ currKaraoke.likes_count = audioBookData.likes_count
+ currKaraoke.mark_as_favourite = audioBookData.mark_as_favourite
+
continueAudioAdapter.notifyItemChanged(position)
}
}
- private fun onContinueBookChanged(id: Int) {
+ private fun onContinueBookChanged(id: Int, audioBookData: AudioBookData) {
// updating book list
val position = audioBookAdapter.currentList.indexOfFirst { it.id == id }
if (position >= 0 && position < audioBookAdapter.currentList.size) {
+ val currKaraoke = audioBookAdapter.currentList[position]
+
+ // updating possible data changes
+ currKaraoke.is_liked = audioBookData.is_liked
+ currKaraoke.likes_count = audioBookData.likes_count
+ currKaraoke.mark_as_favourite = audioBookData.mark_as_favourite
+
audioBookAdapter.notifyItemChanged(position)
}
}
@@ -323,7 +375,7 @@ class AudioBooksActivity : WokaBaseActivity() {
if (moreDetailsList.isNotEmpty()) {
- if (WokaApp.userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) {
+ if (userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) {
moreDetailsList[1]?.let { data ->
title.text = data.title
description.text = Html.fromHtml(
@@ -364,9 +416,21 @@ class AudioBooksActivity : WokaBaseActivity() {
!like.isSelected
)
+ audioBookData.likes_count?.let {
+ audioBookData.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
+ }
+
+ audioBookData.is_liked = !like.isSelected
+
audioBookData.id?.let {
- onBookChanged(it)
- onContinueBookChanged(it)
+ onBookChanged(it, audioBookData)
+ onContinueBookChanged(it, audioBookData)
}
like.isSelected = !like.isSelected
likeCount.text = "${audioBookData.likes_count}"
@@ -378,9 +442,11 @@ class AudioBooksActivity : WokaBaseActivity() {
!fav.isSelected
)
+ audioBookData.mark_as_favourite = !fav.isSelected
+
audioBookData.id?.let {
- onBookChanged(it)
- onContinueBookChanged(it)
+ onBookChanged(it, audioBookData)
+ onContinueBookChanged(it, audioBookData)
}
fav.isSelected = !fav.isSelected
diff --git a/app/src/main/java/com/woka/home/fragments/Home1Fragment.kt b/app/src/main/java/com/woka/home/fragments/Home1Fragment.kt
index 2dacd15..98d74c1 100644
--- a/app/src/main/java/com/woka/home/fragments/Home1Fragment.kt
+++ b/app/src/main/java/com/woka/home/fragments/Home1Fragment.kt
@@ -33,6 +33,7 @@ import com.woka.userPreference.UserType
import com.woka.utils.hide
import com.woka.utils.scaleAnimate
import com.woka.utils.show
+import com.woka.webseries.views.SeriesActivity
import com.woka.webseries.views.WebSeriesActivity
import com.woka.wokagames.views.GamesActivity
@@ -179,7 +180,7 @@ class Home1Fragment : Fragment(), Listener {
webSeries.setOnClickListener {
activity?.let {
- startActivity(Intent(it, WebSeriesActivity::class.java))
+ startActivity(Intent(it, SeriesActivity::class.java))
}
}
diff --git a/app/src/main/java/com/woka/home/views/HomeActivity.kt b/app/src/main/java/com/woka/home/views/HomeActivity.kt
index 927278f..e028c53 100644
--- a/app/src/main/java/com/woka/home/views/HomeActivity.kt
+++ b/app/src/main/java/com/woka/home/views/HomeActivity.kt
@@ -464,6 +464,7 @@ class HomeActivity : WokaBaseActivity(),
.replace(R.id.fc_home, Home2Fragment.newInstance())
.runOnCommit {
binding.notifications.show()
+ binding.notiCountView.show()
window.lightStatusBar()
binding.root.backgroundTintList = ColorStateList.valueOf(getColor(R.color.color_primary))
@@ -477,6 +478,7 @@ class HomeActivity : WokaBaseActivity(),
.replace(R.id.fc_home, Home1Fragment.newInstance())
.runOnCommit {
binding.notifications.show()
+ binding.notiCountView.show()
window.lightStatusBar()
binding.root.backgroundTintList = null
@@ -508,6 +510,7 @@ class HomeActivity : WokaBaseActivity(),
window.lightStatusBar()
binding.notifications.hide()
+ binding.notiCountView.hide()
binding.root.background = ContextCompat.getDrawable(this, R.drawable.grad_my_list)
}
.commit()
diff --git a/app/src/main/java/com/woka/karaoke/KaraokeRepository.kt b/app/src/main/java/com/woka/karaoke/KaraokeRepository.kt
index cd0ca46..3105e34 100644
--- a/app/src/main/java/com/woka/karaoke/KaraokeRepository.kt
+++ b/app/src/main/java/com/woka/karaoke/KaraokeRepository.kt
@@ -1,7 +1,5 @@
package com.woka.karaoke
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
import com.woka.home.mylist.MyListRepository
import com.woka.home.mylist.models.FavKaraokeData
import com.woka.home.mylist.models.PostType
@@ -24,13 +22,6 @@ object KaraokeRepository {
private val apiService = RetrofitHelper.getRetrofit().create(KaraokeApiService::class.java)
private val userActionApiService = RetrofitHelper.getRetrofit().create(UserActionApiService::class.java)
- // continue sing karaoke data
- private val _continueKaraokeLiveData = MutableLiveData>()
- val continueKaraokeLiveData: LiveData>
- get() = _continueKaraokeLiveData
-
- private var continueKaraokeData: ContinueKaraokeResponse? = null
-
suspend fun loadKaraokeSongs(pageNo: Int, quantity: Int): ApiResult {
return handleApiCall {
apiService.karaokeListing(
@@ -43,32 +34,13 @@ object KaraokeRepository {
}
}
- fun loadContinueKaraoke(){
- if (continueKaraokeData != null){
- _continueKaraokeLiveData.postValue(ApiResult.Success(continueKaraokeData))
- return
- }
-
- CoroutineScope(Dispatchers.IO).launch {
- val response = handleApiCall {
- userActionApiService.continueKaraokeListing(
- FormBody.Builder()
- .add("post_type", PostType.KARAOKE.value)
- .build()
- )
- }
-
- when (response){
- is ApiResult.Error -> {}
- is ApiResult.Loading -> {}
- is ApiResult.Success -> {
- response.data?.let {
- continueKaraokeData = it
- }
- }
- }
-
- _continueKaraokeLiveData.postValue(response)
+ suspend fun loadContinueLiveData(): ApiResult {
+ return handleApiCall {
+ userActionApiService.continueKaraokeListing(
+ FormBody.Builder()
+ .add("post_type", PostType.KARAOKE.value)
+ .build()
+ )
}
}
@@ -97,28 +69,6 @@ object KaraokeRepository {
}
private fun changeLikeLocally(id: String, isLiked: Boolean){
-
- // continue Karaoke data update
- continueKaraokeData?.result?.let {
- for (audio in it){
- var found = false
- audio?.let {data ->
- if ("${data.id}" == id){
-
- data.is_liked = isLiked
-
- data.likes_count?.let { count ->
- data.likes_count = if (isLiked) count + 1
- else max(0, count - 1)
- }
-
- found = true
- }
- }
- if (found) break
- }
- }
-
// changing in fav list locally
MyListRepository.myFavData.result?.sing_karaoke_data?.let {
for (audioData in it){
@@ -164,18 +114,5 @@ object KaraokeRepository {
}
}
- continueKaraokeData?.result?.let {
- for (audio in it){
- if (audio?.id == karaoke.id){
- audio?.mark_as_favourite = addToBookmark
- break
- }
- }
- }
-
- }
-
- fun clearData(){
- continueKaraokeData = null
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/karaoke/adapters/ContinueKaraokeAdapter.kt b/app/src/main/java/com/woka/karaoke/adapters/ContinueKaraokeAdapter.kt
index 622cf46..cca0bc7 100644
--- a/app/src/main/java/com/woka/karaoke/adapters/ContinueKaraokeAdapter.kt
+++ b/app/src/main/java/com/woka/karaoke/adapters/ContinueKaraokeAdapter.kt
@@ -17,11 +17,12 @@ import com.woka.utils.isNetworkConnected
import com.woka.utils.show
import com.woka.utils.toast
import java.util.concurrent.Executors
+import kotlin.math.max
class ContinueKaraokeAdapter(
private val context: Context,
private var onKaraokeClicked: (KaraokeData) -> Unit,
- private var onKaraokeChanged: (id: Int, isFromContinue: Boolean) -> Unit
+ private var onKaraokeChanged: (id: Int, isFromContinue: Boolean, KaraokeData) -> Unit
): ListAdapter(ASYNC_DIFF_UTIL) {
inner class AudioBookViewHolder(val binding: FavViewHolderBinding): ViewHolder(binding.root)
@@ -97,6 +98,18 @@ class ContinueKaraokeAdapter(
!like.isSelected
)
+ karaokeData.likes_count?.let {
+ karaokeData.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
+ }
+
+ karaokeData.is_liked = !like.isSelected
+
karaokeData.likes_count?.let {
likeCount.text = "$it"
}
@@ -105,7 +118,7 @@ class ContinueKaraokeAdapter(
like.isSelected = it
}
- karaokeData.id?.let{onKaraokeChanged(it, true)}
+ karaokeData.id?.let{onKaraokeChanged(it, true, KaraokeData(karaokeData))}
}
fav.isSelected = karaokeData.mark_as_favourite == true
@@ -121,9 +134,11 @@ class ContinueKaraokeAdapter(
!fav.isSelected
)
+ karaokeData.mark_as_favourite = !fav.isSelected
+
fav.isSelected = karaokeData.mark_as_favourite == true
- karaokeData.id?.let{onKaraokeChanged(it, true)}
+ karaokeData.id?.let{onKaraokeChanged(it, true, KaraokeData(karaokeData))}
}
root.setOnClickListener {
diff --git a/app/src/main/java/com/woka/karaoke/adapters/KaraokeAdapter.kt b/app/src/main/java/com/woka/karaoke/adapters/KaraokeAdapter.kt
index 9b83b36..9926880 100644
--- a/app/src/main/java/com/woka/karaoke/adapters/KaraokeAdapter.kt
+++ b/app/src/main/java/com/woka/karaoke/adapters/KaraokeAdapter.kt
@@ -16,11 +16,12 @@ import com.woka.utils.isNetworkConnected
import com.woka.utils.show
import com.woka.utils.toast
import java.util.concurrent.Executors
+import kotlin.math.max
class KaraokeAdapter(
private val context: Context,
private var onKaraokeClicked: (KaraokeData) -> Unit,
- private var onKaraokeChanged: (id: Int, isContinue: Boolean) -> Unit
+ private var onKaraokeChanged: (id: Int, isContinue: Boolean, KaraokeData) -> Unit
): ListAdapter(ASYNC_DIFF_UTIL) {
inner class AudioBookViewHolder(val binding: ShowViewHolderBinding): ViewHolder(binding.root)
@@ -96,6 +97,18 @@ class KaraokeAdapter(
!like.isSelected
)
+ karaokeData.likes_count?.let {
+ karaokeData.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
+ }
+
+ karaokeData.is_liked = !like.isSelected
+
karaokeData.likes_count?.let {
likeCount.text = "$it"
}
@@ -104,7 +117,7 @@ class KaraokeAdapter(
like.isSelected = it
}
- karaokeData.id?.let{onKaraokeChanged(it, false)}
+ karaokeData.id?.let{onKaraokeChanged(it, false, karaokeData)}
}
fav.isSelected = karaokeData.mark_as_favourite == true
@@ -120,9 +133,11 @@ class KaraokeAdapter(
!fav.isSelected
)
+ karaokeData.mark_as_favourite = !fav.isSelected
+
fav.isSelected = karaokeData.mark_as_favourite == true
- karaokeData.id?.let{onKaraokeChanged(it, false)}
+ karaokeData.id?.let{onKaraokeChanged(it, false, karaokeData)}
}
root.setOnClickListener {
diff --git a/app/src/main/java/com/woka/karaoke/viewmodels/KaraokeViewModel.kt b/app/src/main/java/com/woka/karaoke/viewmodels/KaraokeViewModel.kt
index a8c0219..c3653fa 100644
--- a/app/src/main/java/com/woka/karaoke/viewmodels/KaraokeViewModel.kt
+++ b/app/src/main/java/com/woka/karaoke/viewmodels/KaraokeViewModel.kt
@@ -5,28 +5,73 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.woka.karaoke.KaraokeRepository
+import com.woka.karaoke.models.continuesing.ContinueKaraokeData
import com.woka.karaoke.models.listing.KaraokeData
import com.woka.networking.ApiResult
import kotlinx.coroutines.launch
-class KaraokeViewModel: ViewModel() {
+class KaraokeViewModel : ViewModel() {
- private val _karaokeLiveData = MutableLiveData>>()
- val karaokeLiveData: LiveData>>
+ private val _karaokeLiveData = MutableLiveData>>()
+ val karaokeLiveData: LiveData>>
get() = _karaokeLiveData
- var nextPageToLoad: Int = 0
- private var quantityPerPage: Int = 10
- private var lastPage = false
+ private val karaokeList = ArrayList()
- fun loadKaraokeSongs(currentItemCount: Int){
+ private var nextPageToLoad: Int = 0
+ private var quantityPerPage: Int = 6
+ var lastPage = false
+
+ private val _karaokeContinueLiveData = MutableLiveData>>()
+ val karaokeContinueLiveData: LiveData>>
+ get() = _karaokeContinueLiveData
+
+ fun loadKaraokeSongs() {
viewModelScope.launch {
- when (val value = KaraokeRepository.loadKaraokeSongs(nextPageToLoad, quantityPerPage)){
- is ApiResult.Error -> _karaokeLiveData.postValue(ApiResult.Error(value.errorMessage, value.error))
+ _karaokeLiveData.postValue(ApiResult.Loading())
+ when (val value = KaraokeRepository.loadKaraokeSongs(nextPageToLoad, quantityPerPage)) {
+ is ApiResult.Error -> _karaokeLiveData.postValue(
+ ApiResult.Error(
+ value.errorMessage,
+ value.error
+ )
+ )
+
is ApiResult.Loading -> _karaokeLiveData.postValue(ApiResult.Loading())
is ApiResult.Success -> {
- value.data?.karaoke_data?.filterNotNull()?.let {
+ value.data?.let {
+ it.karaoke_data?.filterNotNull()?.let { newList ->
+ karaokeList.addAll(newList)
+ lastPage = karaokeList.size == it.total_records
+
+ _karaokeLiveData.postValue(ApiResult.Success(karaokeList))
+ nextPageToLoad++
+ }
+ }
+ }
+ }
+ }
+ }
+
+ fun loadContinueData(){
+ viewModelScope.launch {
+ _karaokeContinueLiveData.postValue(ApiResult.Loading())
+
+ when (val value = KaraokeRepository.loadContinueLiveData()) {
+ is ApiResult.Error -> _karaokeContinueLiveData.postValue(
+ ApiResult.Error(
+ value.errorMessage,
+ value.error
+ )
+ )
+
+ is ApiResult.Loading -> _karaokeContinueLiveData.postValue(ApiResult.Loading())
+ is ApiResult.Success -> {
+ value.data?.let {
+ it.result?.filterNotNull()?.let { newList ->
+ _karaokeContinueLiveData.postValue(ApiResult.Success(newList))
+ }
}
}
}
diff --git a/app/src/main/java/com/woka/karaoke/views/KaraokeActivity.kt b/app/src/main/java/com/woka/karaoke/views/KaraokeActivity.kt
index 1f8102a..46d8141 100644
--- a/app/src/main/java/com/woka/karaoke/views/KaraokeActivity.kt
+++ b/app/src/main/java/com/woka/karaoke/views/KaraokeActivity.kt
@@ -16,7 +16,6 @@ import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.SimpleItemAnimator
import com.google.android.material.appbar.CollapsingToolbarLayout
import com.woka.R
-import com.woka.WokaApp
import com.woka.WokaApp.Companion.userPrefs
import com.woka.databinding.ActivityKaraokeBinding
import com.woka.databinding.DialogModuleShowerBinding
@@ -37,6 +36,7 @@ import com.woka.utils.show
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
+import kotlin.math.max
class KaraokeActivity : WokaBaseActivity() {
@@ -83,6 +83,10 @@ class KaraokeActivity : WokaBaseActivity() {
clickEvents()
setObservers()
+
+ if (!viewModel.karaokeLiveData.isInitialized){
+ viewModel.loadKaraokeSongs()
+ }
}
private fun initViews() {
@@ -132,11 +136,11 @@ class KaraokeActivity : WokaBaseActivity() {
}
retryBtn.setOnClickListener {
-
+ viewModel.loadKaraokeSongs()
}
loadMoreBtn.setOnClickListener {
-
+ viewModel.loadKaraokeSongs()
}
}
}
@@ -152,7 +156,7 @@ class KaraokeActivity : WokaBaseActivity() {
karaokeData.content_more_details?.let { moreDetailsList ->
trailerName.text = if (moreDetailsList.isNotEmpty()) {
- if (WokaApp.userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) {
+ if (userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) {
moreDetailsList[1]?.title
} else {
moreDetailsList[0]?.title
@@ -214,7 +218,7 @@ class KaraokeActivity : WokaBaseActivity() {
if (moreDetailsList.isNotEmpty()) {
- if (WokaApp.userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) {
+ if (userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) {
moreDetailsList[1]?.let { data ->
title.text = data.title
description.text = Html.fromHtml(
@@ -255,9 +259,21 @@ class KaraokeActivity : WokaBaseActivity() {
!like.isSelected
)
+ karaokeData.likes_count?.let {
+ karaokeData.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
+ }
+
+ karaokeData.is_liked = !like.isSelected
+
karaokeData.id?.let {
- onKaraokeChanged(it, false)
- onKaraokeChanged(it, true)
+ onKaraokeChanged(it, false, karaokeData)
+ onKaraokeChanged(it, true, karaokeData)
}
like.isSelected = !like.isSelected
likeCount.text = "${karaokeData.likes_count}"
@@ -269,9 +285,11 @@ class KaraokeActivity : WokaBaseActivity() {
!fav.isSelected
)
+ karaokeData.mark_as_favourite = !fav.isSelected
+
karaokeData.id?.let {
- onKaraokeChanged(it, false)
- onKaraokeChanged(it, true)
+ onKaraokeChanged(it, false, karaokeData)
+ onKaraokeChanged(it, true, karaokeData)
}
fav.isSelected = !fav.isSelected
@@ -286,17 +304,31 @@ class KaraokeActivity : WokaBaseActivity() {
}
}
- private fun onKaraokeChanged(id: Int, isFromContinue: Boolean) {
+ private fun onKaraokeChanged(id: Int, isFromContinue: Boolean, karaokeData: KaraokeData) {
if (isFromContinue) {
// updating karaoke list
val position = karaokeAdapter.currentList.indexOfFirst { it.id == id }
if (position >= 0 && position < karaokeAdapter.currentList.size) {
+ val currKaraoke = karaokeAdapter.currentList[position]
+
+ // updating possible data changes
+ currKaraoke.is_liked = karaokeData.is_liked
+ currKaraoke.likes_count = karaokeData.likes_count
+ currKaraoke.mark_as_favourite = karaokeData.mark_as_favourite
+
karaokeAdapter.notifyItemChanged(position)
}
} else {
// updating continue karaoke list
val continuePos = continueKaraokeAdapter.currentList.indexOfFirst { it.id == id }
if (continuePos >= 0 && continuePos < continueKaraokeAdapter.currentList.size) {
+ val currKaraoke = continueKaraokeAdapter.currentList[continuePos]
+
+ // updating possible data changes
+ currKaraoke.is_liked = karaokeData.is_liked
+ currKaraoke.likes_count = karaokeData.likes_count
+ currKaraoke.mark_as_favourite = karaokeData.mark_as_favourite
+
continueKaraokeAdapter.notifyItemChanged(continuePos)
}
}
@@ -308,67 +340,71 @@ class KaraokeActivity : WokaBaseActivity() {
}
private fun setObservers() {
-// viewModel.karaokeLiveData.observe(this) {
-// when (it) {
-// is ApiResult.Error -> {
-// binding.shimmer.hide()
-// if (karaokeAdapter.currentList.size == 0) {
-// binding.rvKaraoke.hide()
-// binding.singTxt.hide()
-// binding.trailerView.hide()
-//
-// binding.errorView.show()
-// } else {
-// // error in loading more
-// binding.loadMoreProgress.hide()
-// binding.loadMoreBtn.show()
-// }
-// }
-//
-// is ApiResult.Loading -> {
-// if (karaokeAdapter.currentList.size == 0) {
-// binding.shimmer.show()
-//
-// binding.rvKaraoke.hide()
-// binding.singTxt.hide()
-// binding.trailerView.hide()
-// binding.errorView.hide()
-// } else {
-// // error in loading more
-// binding.loadMoreProgress.show()
-// binding.loadMoreBtn.hide()
-// }
-// }
-//
-// is ApiResult.Success -> {
-// it.data?.let { data ->
-// binding.loadMoreProgress.hide()
-//
-// data.karaoke_data?.filterNotNull()?.let { karaokeData ->
-// if (karaokeData.isNotEmpty()) {
-// binding.shimmer.hide()
-// binding.errorView.hide()
-//
-// if (userPrefs?.userType != UserType.GUEST) {
-// KaraokeRepository.loadContinueKaraoke()
-// }
-//
-// loadTrailerData(karaokeData[0])
-// binding.rvKaraoke.show()
-// binding.singTxt.show()
-//
-// karaokeAdapter.submitList(karaokeData)
-// }
-//
-// }
-//
-// binding.loadMoreBtn.setVisibility(karaokeAdapter.currentList.size != data.total_records)
-// }
-// }
-// }
-// }
+ viewModel.karaokeLiveData.observe(this){
+ when(it){
+ is ApiResult.Error -> {
+ binding.shimmer.hide()
+ if (karaokeAdapter.currentList.size == 0) {
+ // none of the data is yet loaded
+ binding.rvKaraoke.hide()
+ binding.singTxt.hide()
+ binding.trailerView.hide()
- KaraokeRepository.continueKaraokeLiveData.observe(this) {
+ binding.errorView.show()
+ } else {
+ // error in loading more
+ binding.loadMoreProgress.hide()
+ binding.loadMoreBtn.text = getString(R.string.retry)
+ binding.loadMoreBtn.show()
+ }
+ }
+ is ApiResult.Loading -> {
+ if (karaokeAdapter.currentList.size == 0) {
+ // loading first data
+ binding.shimmer.show()
+ binding.errorView.hide()
+ } else {
+ // loading more data
+ binding.loadMoreProgress.show()
+ binding.loadMoreBtn.hide()
+ }
+ }
+ is ApiResult.Success -> {
+ it.data?.let {newList ->
+ if (newList.isNotEmpty()){
+ binding.rvKaraoke.show()
+ binding.singTxt.show()
+ binding.trailerView.show()
+
+ binding.errorView.hide()
+ binding.shimmer.hide()
+
+ binding.loadMoreProgress.hide()
+ binding.loadMoreBtn.text = getString(R.string.load_more)
+ binding.loadMoreBtn.setVisibility(!viewModel.lastPage)
+
+ if (karaokeAdapter.currentList.isEmpty()){
+ // first data load
+ if (userPrefs?.userType != UserType.GUEST && !viewModel.karaokeContinueLiveData.isInitialized){
+ viewModel.loadContinueData()
+ }
+
+ loadTrailerData(newList[0])
+ karaokeAdapter.submitList(newList)
+ }else{
+ // loaded more data
+ karaokeAdapter.notifyItemRangeInserted(
+ karaokeAdapter.currentList.size,
+ newList.size
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+
+ viewModel.karaokeContinueLiveData.observe(this) {
when (it) {
is ApiResult.Error -> {
binding.continueSingTxt.hide()
@@ -377,12 +413,12 @@ class KaraokeActivity : WokaBaseActivity() {
is ApiResult.Loading -> {}
is ApiResult.Success -> {
- it.data?.result?.filterNotNull()?.let { continueData ->
- if (continueData.isNotEmpty()) {
+ it.data?.let { continueList ->
+ if (continueList.isNotEmpty()) {
binding.continueSingTxt.show()
binding.rvContinueSing.show()
- continueKaraokeAdapter.submitList(continueData)
+ continueKaraokeAdapter.submitList(continueList)
} else {
binding.continueSingTxt.hide()
binding.rvContinueSing.hide()
diff --git a/app/src/main/java/com/woka/userPreference/UserPreference.kt b/app/src/main/java/com/woka/userPreference/UserPreference.kt
index fd714a9..336c895 100644
--- a/app/src/main/java/com/woka/userPreference/UserPreference.kt
+++ b/app/src/main/java/com/woka/userPreference/UserPreference.kt
@@ -117,7 +117,5 @@ class UserPreference(val context: Context) {
private fun clearData(){
WebSeriesRepository.clearData()
MyListRepository.clearData()
- AudioBookRepository.clearData()
- KaraokeRepository.clearData()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/webseries/Repository.kt b/app/src/main/java/com/woka/webseries/Repository.kt
new file mode 100644
index 0000000..95d3a5c
--- /dev/null
+++ b/app/src/main/java/com/woka/webseries/Repository.kt
@@ -0,0 +1,189 @@
+package com.woka.webseries
+
+import com.woka.home.mylist.MyListRepository
+import com.woka.home.mylist.models.BookmarkedShowData
+import com.woka.home.mylist.models.PostType
+import com.woka.modules.categorymodels.CategoriesResponse
+import com.woka.networking.ApiResult
+import com.woka.networking.RetrofitHelper
+import com.woka.networking.RetrofitHelper.handleApiCall
+import com.woka.userdata.UserActionApiService
+import com.woka.webseries.models.ContinueEpisodeResponse
+import com.woka.webseries.models.ShowData
+import com.woka.webseries.models.WebSeriesResponse
+import com.woka.webseries.models.episodedata.EpisodeResponseData
+import com.woka.webseries.models.seasondata.SeasonDataResponse
+import com.woka.webseries.models.teaserdata.TeaserResponseData
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.FormBody
+import kotlin.math.max
+
+object Repository {
+ // api services
+ private val apiService = RetrofitHelper.getRetrofit().create(WebSeriesApiService::class.java)
+ private val userActionApiService = RetrofitHelper.getRetrofit().create(UserActionApiService::class.java)
+
+ suspend fun loadCategories(): ApiResult {
+ return handleApiCall {
+ apiService.categoryListing(
+ FormBody.Builder()
+ .add("module_id", "7")
+ .build()
+ )
+ }
+ }
+
+ suspend fun loadTeaserData(showId: Int, seasonId: Int): ApiResult {
+ return handleApiCall{
+ apiService.teaserListing(
+ FormBody.Builder()
+ .add("watch_show_master_id", "$showId")
+ .add("season_master_id", "$seasonId")
+ .build()
+ )
+ }
+ }
+
+ suspend fun loadEpisodeData(showId: Int, seasonId: Int): ApiResult {
+ return handleApiCall {
+ apiService.episodeListing(
+ FormBody.Builder()
+ .add("watch_show_master_id", "$showId")
+ .add("season_master_id", "$seasonId")
+ .build()
+ )
+ }
+ }
+
+ suspend fun loadSeasonListing(showId: Int, categoryId: String): ApiResult {
+ return handleApiCall {
+ apiService.seasonListing(
+ FormBody.Builder()
+ .add("watch_show_id", "$showId")
+ .add("category_id", categoryId)
+ .build()
+ )
+ }
+ }
+
+ suspend fun loadContinueWatchData(): ApiResult {
+ return handleApiCall {
+ userActionApiService.continueWatchingShowListing(
+ FormBody.Builder()
+ .add("post_type", "3")
+ .build()
+ )
+ }
+ }
+
+ suspend fun loadWebSeries(categoryId: String, pageNo: Int, quantity: Int): ApiResult {
+ return handleApiCall {
+ apiService.getWebSeries(
+ FormBody.Builder()
+ .add("category_id", categoryId)
+ .add("api_version", "v2")
+ .add("start", "$pageNo")
+ .add("limit", "$quantity")
+ .build()
+ )
+ }
+ }
+
+ fun likeUnLikeShow(postId: String, likeIt: Boolean){
+ CoroutineScope(Dispatchers.IO).launch {
+ handleApiCall {
+ if (likeIt){
+ userActionApiService.likePost(
+ FormBody.Builder()
+ .add("post_id", postId)
+ .add("post_type", PostType.WEB_SERIES.value)
+ .build()
+ )
+ }else{
+ userActionApiService.unLikePost(
+ FormBody.Builder()
+ .add("post_id", postId)
+ .add("post_type", PostType.WEB_SERIES.value)
+ .build()
+ )
+ }
+ }
+ }
+
+ changeLikeLocally(postId, likeIt)
+ }
+
+ private fun changeLikeLocally(id: String, isLiked: Boolean){
+ // changing in fav list locally
+ MyListRepository.myFavData.result?.show_data?.let {
+ for (show in it){
+ if ("${show.id}" == id){
+ show.is_liked = isLiked
+ show.likes_count?.let { count ->
+ show.likes_count = if (isLiked) count + 1
+ else max(0, count - 1)
+ }
+ break
+ }
+ }
+ }
+ }
+
+ fun updateFavShow(showData: ShowData, addToBookmark: Boolean, categoryId: String){
+ CoroutineScope(Dispatchers.IO).launch {
+ handleApiCall {
+ if (addToBookmark){
+ userActionApiService.addToFav(
+ FormBody.Builder()
+ .add("post_id", "${showData.id}")
+ .add("post_type", PostType.WEB_SERIES.value)
+ .add("category_id", categoryId)
+ .build()
+ )
+ }else{
+ userActionApiService.removeFromFav(
+ FormBody.Builder()
+ .add("id", "${showData.id}")
+ .add("post_type", PostType.WEB_SERIES.value)
+ .add("category_id", categoryId)
+ .build()
+ )
+ }
+ }
+ }
+
+ MyListRepository.myFavData.result?.show_data?.let {
+ var found = false
+ var showFound: BookmarkedShowData? = null
+
+ for (show in it){
+ if (showData.id == show.id){
+
+ if (addToBookmark){
+ show.addAsBookMark(categoryId)
+ }else{
+ show.removeAsBookMark(categoryId)
+ }
+
+ showFound = show
+ found = true
+ break
+ }
+ }
+
+ if (!found && addToBookmark){
+ MyListRepository.myFavData.result?.show_data?.add(BookmarkedShowData(showData, categoryId))
+ }
+
+ if (found){
+ showFound?.let {bookMarkShowData ->
+ if (!bookMarkShowData.isBookMarked()){
+ it.remove(bookMarkShowData)
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/webseries/WebSeriesApiService.kt b/app/src/main/java/com/woka/webseries/WebSeriesApiService.kt
index ce67eb8..841fbea 100644
--- a/app/src/main/java/com/woka/webseries/WebSeriesApiService.kt
+++ b/app/src/main/java/com/woka/webseries/WebSeriesApiService.kt
@@ -1,5 +1,6 @@
package com.woka.webseries
+import com.woka.modules.categorymodels.CategoriesResponse
import com.woka.networking.ApiResponse
import com.woka.webseries.models.WebSeriesResponse
import com.woka.webseries.models.episodedata.EpisodeResponseData
@@ -23,4 +24,7 @@ interface WebSeriesApiService {
@POST("teaser_listing")
suspend fun teaserListing(@Body formBody: FormBody): Response>
+
+ @POST("category_listing")
+ suspend fun categoryListing(@Body body: FormBody): Response>
}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/webseries/adapters/WebSeriesShowAdapter.kt b/app/src/main/java/com/woka/webseries/adapters/WebSeriesShowAdapter.kt
index 226bd04..c02436e 100644
--- a/app/src/main/java/com/woka/webseries/adapters/WebSeriesShowAdapter.kt
+++ b/app/src/main/java/com/woka/webseries/adapters/WebSeriesShowAdapter.kt
@@ -12,7 +12,7 @@ import com.woka.databinding.ShowViewHolderBinding
import com.woka.utils.isNetworkConnected
import com.woka.utils.show
import com.woka.utils.toast
-import com.woka.webseries.WebSeriesRepository
+import com.woka.webseries.Repository
import com.woka.webseries.models.ShowData
import kotlin.math.max
@@ -84,12 +84,20 @@ class WebSeriesShowAdapter(
return@setOnClickListener
}
- if (like.isSelected){
- WebSeriesRepository.likeUnLikeShow("${showData.id}", false)
- }else{
- WebSeriesRepository.likeUnLikeShow("${showData.id}", true)
+ Repository.likeUnLikeShow("${showData.id}", !like.isSelected)
+
+ showData.likes_count?.let {
+ showData.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
}
+ showData.is_liked = !like.isSelected
+
like.isSelected = !like.isSelected
showData.likes_count?.let {
likeCount.text = "$it"
@@ -105,12 +113,14 @@ class WebSeriesShowAdapter(
}
categoryId?.let {
- WebSeriesRepository.updateFavShow(
+ Repository.updateFavShow(
showData,
!fav.isSelected,
it
)
+ showData.addAsBookMark(it)
+
fav.isSelected = !fav.isSelected
}
}
diff --git a/app/src/main/java/com/woka/webseries/viewmodel/ViewModel.kt b/app/src/main/java/com/woka/webseries/viewmodel/ViewModel.kt
new file mode 100644
index 0000000..713e5e2
--- /dev/null
+++ b/app/src/main/java/com/woka/webseries/viewmodel/ViewModel.kt
@@ -0,0 +1,111 @@
+package com.woka.webseries.viewmodel
+
+import android.util.Log
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.woka.modules.categorymodels.CategoriesResponse
+import com.woka.networking.ApiResult
+import com.woka.utils.TAG
+import com.woka.webseries.Repository
+import com.woka.webseries.models.ContinueEpisodeResponse
+import com.woka.webseries.models.ShowData
+import kotlinx.coroutines.launch
+
+class ViewModel : ViewModel() {
+
+ private val repository = Repository
+
+ // categories listing
+ data class PagingData(
+ var nextPageToLoad: Int = 0, var quantityPerPage: Int = 6,
+ var lastPage: Boolean = false
+ )
+
+ private val _showCategoryLiveData = MutableLiveData>()
+ val showCategoryLiveData: LiveData>
+ get() = _showCategoryLiveData
+
+ var categoryPagingData = HashMap()
+
+ fun loadCategories() {
+ viewModelScope.launch {
+ _showCategoryLiveData.postValue(ApiResult.Loading())
+ _showCategoryLiveData.postValue(repository.loadCategories())
+ }
+ }
+
+ // continue watching
+ private val _continueWatchLiveData = MutableLiveData>()
+ val continueWatchLiveData: LiveData>
+ get() = _continueWatchLiveData
+
+ fun loadContinueWatching() {
+ viewModelScope.launch {
+ _continueWatchLiveData.postValue(ApiResult.Loading())
+ _continueWatchLiveData.postValue(repository.loadContinueWatchData())
+ }
+ }
+
+ // show data
+ private val _webSeriesLiveData =
+ MutableLiveData>>()
+ val webSeriesLiveData: LiveData>>
+ get() = _webSeriesLiveData
+
+ // map of series data where key is category
+ private var webSeriesData = HashMap>()
+
+ fun loadWebSeries(categoryId: String){
+ if (webSeriesData.containsKey(categoryId) && webSeriesData[categoryId]?.isNotEmpty() == true){
+ _webSeriesLiveData.postValue(ApiResult.Success(webSeriesData[categoryId]))
+ }else{
+ loadMoreWebSeries(categoryId)
+ }
+ }
+
+ fun loadMoreWebSeries(categoryId: String) {
+ viewModelScope.launch {
+ _webSeriesLiveData.postValue(ApiResult.Loading())
+
+ val pagingData = if (categoryPagingData.containsKey(categoryId)){
+ categoryPagingData[categoryId]!!
+ }else{
+ val pagingData = PagingData()
+ categoryPagingData[categoryId] = pagingData
+ pagingData
+ }
+
+ when (val response = repository.loadWebSeries(categoryId, pagingData.nextPageToLoad, pagingData.quantityPerPage)) {
+ is ApiResult.Error -> {
+ _webSeriesLiveData.postValue(
+ ApiResult.Error(
+ response.errorMessage,
+ response.error
+ )
+ )
+ }
+
+ is ApiResult.Loading -> {
+ _webSeriesLiveData.postValue(ApiResult.Loading())
+ }
+
+ is ApiResult.Success -> {
+ response.data?.let { data ->
+ data.show_data?.filterNotNull()?.let { newList ->
+ val currentList = webSeriesData.getOrDefault(categoryId, ArrayList())
+ currentList.addAll(newList)
+ webSeriesData[categoryId] = currentList
+
+ pagingData.lastPage = webSeriesData[categoryId]?.size == data.total_records
+
+ _webSeriesLiveData.postValue(ApiResult.Success(webSeriesData[categoryId]))
+ pagingData.nextPageToLoad++
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/webseries/views/SeriesActivity.kt b/app/src/main/java/com/woka/webseries/views/SeriesActivity.kt
new file mode 100644
index 0000000..184c900
--- /dev/null
+++ b/app/src/main/java/com/woka/webseries/views/SeriesActivity.kt
@@ -0,0 +1,37 @@
+package com.woka.webseries.views
+
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.content.res.AppCompatResources
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+import com.woka.R
+import com.woka.databinding.ActivitySeriesBinding
+import com.woka.utils.WokaBaseActivity
+import com.woka.webseries.views.fragments.WebSeriesFragment
+
+class SeriesActivity : WokaBaseActivity() {
+
+ private lateinit var binding: ActivitySeriesBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ binding = ActivitySeriesBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
+ val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
+ insets
+ }
+
+ window.navigationBarColor = getColor(R.color.color_primary_dark)
+
+ supportFragmentManager.beginTransaction()
+ .add(R.id.fcv_web_series, WebSeriesFragment.newInstance())
+ .runOnCommit {
+ window.setBackgroundDrawable(AppCompatResources.getDrawable(this, R.drawable.gradient_web_series))
+ }
+ .commit()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/webseries/views/fragments/WebSeriesFragment.kt b/app/src/main/java/com/woka/webseries/views/fragments/WebSeriesFragment.kt
new file mode 100644
index 0000000..f92ec30
--- /dev/null
+++ b/app/src/main/java/com/woka/webseries/views/fragments/WebSeriesFragment.kt
@@ -0,0 +1,402 @@
+package com.woka.webseries.views.fragments
+
+import android.app.Dialog
+import android.content.Intent
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.graphics.drawable.InsetDrawable
+import android.os.Bundle
+import android.text.Html
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowManager
+import android.widget.AdapterView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.SimpleItemAnimator
+import com.google.android.material.appbar.CollapsingToolbarLayout
+import com.jwplayer.pub.api.media.playlists.PlaylistItem
+import com.woka.R
+import com.woka.WokaApp.Companion.userPrefs
+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.views.PlayerActivity
+import com.woka.players.views.PlayerActivity.Companion.EXTRA_PLAY_INDEX
+import com.woka.players.views.PlayerActivity.Companion.EXTRA_PLAY_LIST
+import com.woka.userPreference.UserType
+import com.woka.utils.hide
+import com.woka.utils.setVisibility
+import com.woka.utils.show
+import com.woka.webseries.adapters.ContinueEpisodeAdapter
+import com.woka.webseries.adapters.SpinnerAdapter
+import com.woka.webseries.adapters.WebSeriesShowAdapter
+import com.woka.webseries.models.ContinueEpisodeData
+import com.woka.webseries.models.ShowData
+import com.woka.webseries.viewmodel.ViewModel
+import java.util.Collections
+
+class WebSeriesFragment private constructor(): Fragment() {
+
+ private lateinit var binding: FragmentWebSeriesBinding
+
+ private lateinit var viewModel: ViewModel
+
+ private lateinit var showAdapter: WebSeriesShowAdapter
+
+ private lateinit var continueWatchAdapter: ContinueEpisodeAdapter
+
+ private var catSpinnerAdapter: SpinnerAdapter? = null
+
+ private lateinit var episodeDialogBinding: DialogContinueEpisodeBinding
+ private lateinit var episodeDialog: Dialog
+
+ companion object {
+ fun newInstance() = WebSeriesFragment()
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = FragmentWebSeriesBinding.inflate(inflater, container, false)
+ viewModel = ViewModelProvider(this)[ViewModel::class.java]
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ initViews()
+
+ initEpisodeDialog()
+
+ clickEvents()
+
+ setObservers()
+
+ if (!viewModel.showCategoryLiveData.isInitialized){
+ viewModel.loadCategories()
+ }
+ }
+
+ private fun clickEvents() {
+ binding.apply {
+ toolbar.backBtn.setOnClickListener {
+ activity?.onBackPressedDispatcher?.onBackPressed()
+ }
+
+ retryBtn.setOnClickListener {
+ binding.shimmer.show()
+ binding.errorView.hide()
+
+ viewModel.loadCategories()
+ }
+
+ loadMoreBtn.setOnClickListener {
+ catSpinnerAdapter?.selectedCategoryType?.let {
+ viewModel.loadMoreWebSeries(it)
+ }
+ }
+ }
+ }
+ private fun initViews(){
+
+ // adapters
+ activity?.let {
+ showAdapter = WebSeriesShowAdapter(it, ::onShowClicked)
+ continueWatchAdapter = ContinueEpisodeAdapter(it)
+ }
+
+ binding.apply {
+ adjustMasilaImage()
+
+ toolbar.title.text = getString(R.string.web_series)
+
+ rvWebSeries.adapter = showAdapter
+ rvContinueWatch.adapter = continueWatchAdapter
+ continueWatchAdapter.onEpisodeClicked = ::onContinueEpisodeClicked
+
+ ((rvWebSeries.itemAnimator) as SimpleItemAnimator).supportsChangeAnimations = false
+ ((rvContinueWatch.itemAnimator) as SimpleItemAnimator).supportsChangeAnimations = false
+ }
+
+ }
+
+ private fun adjustMasilaImage() {
+ // making space for masila image
+ binding.apply {
+ topPinnedView.post {
+ val imgParams = masilaImage.layoutParams as CollapsingToolbarLayout.LayoutParams
+ imgParams.setMargins(0, 0, 0, topPinnedView.height)
+ masilaImage.layoutParams = imgParams
+ }
+ }
+ }
+
+ private fun initEpisodeDialog(){
+ episodeDialogBinding = DialogContinueEpisodeBinding.inflate(layoutInflater)
+ episodeDialog = Dialog(requireContext())
+
+ episodeDialog.setContentView(episodeDialogBinding.root)
+
+ try {
+ val back = ColorDrawable(Color.TRANSPARENT)
+ val inset = InsetDrawable(back, 50)
+ episodeDialog.window!!.setBackgroundDrawable(inset)
+ } catch (e: Exception) {
+ // do nothing
+ }
+
+ try {
+ val layoutParams = episodeDialog.window!!.attributes
+ layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
+ layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
+ layoutParams.horizontalMargin = 0F
+ episodeDialog.window!!.setAttributes(layoutParams)
+ } catch (e: Exception) {
+ // do nothing
+ }
+
+ episodeDialogBinding.close.setOnClickListener { episodeDialog.dismiss() }
+ }
+
+ private fun loadShowData(){
+ catSpinnerAdapter?.selectedCategoryType?.let {
+ showAdapter.submitListShowList(Collections.emptyList(), it)
+ viewModel.loadWebSeries(it)
+ }
+ }
+
+ private fun setObservers(){
+ viewModel.showCategoryLiveData.observe(viewLifecycleOwner){
+ when(it){
+ is ApiResult.Error -> {
+ binding.errorView.show()
+ binding.shimmer.hide()
+ }
+ is ApiResult.Loading -> {}
+ is ApiResult.Success -> {
+ it.data?.result?.let {catList ->
+ binding.shimmer.hide()
+
+ binding.trailerView.show()
+
+ adjustMasilaImage()
+
+ binding.spinnerCard.show()
+ binding.selectLangTxt.show()
+
+ activity?.let {activity ->
+ catSpinnerAdapter = SpinnerAdapter(activity, catList.filterNotNull())
+ binding.categorySpinner.setAdapter(catSpinnerAdapter)
+
+ loadShowData()
+ viewModel.loadContinueWatching()
+ }
+ }
+ }
+ }
+ }
+
+ viewModel.continueWatchLiveData.observe(viewLifecycleOwner){
+ when (it){
+ is ApiResult.Error -> {
+ binding.rvContinueWatch.hide()
+ binding.continueWatchTxt.hide()
+ }
+ is ApiResult.Loading -> {}
+ is ApiResult.Success -> {
+ it.data?.result?.let {continueWatchList ->
+ if (continueWatchList.isNotEmpty()){
+ binding.rvContinueWatch.show()
+ binding.continueWatchTxt.show()
+ continueWatchAdapter.submitList(continueWatchList.asReversed())
+ }else{
+ binding.rvContinueWatch.hide()
+ binding.continueWatchTxt.hide()
+ }
+ }
+ }
+ }
+ }
+
+ viewModel.webSeriesLiveData.observe(viewLifecycleOwner){
+ when (it){
+ is ApiResult.Error -> {
+ binding.shimmerShowData.hide()
+ if (showAdapter.showList.isNotEmpty()){
+ // load more
+ binding.loadMoreBtn.text = getString(R.string.retry)
+ binding.loadMoreBtn.show()
+ }else{
+ // first time load
+ binding.rvWebSeries.hide()
+ binding.shimmerShowData.hide()
+ binding.loadMoreBtn.hide()
+ }
+ }
+ is ApiResult.Loading -> {
+ binding.shimmerShowData.show()
+ binding.loadMoreBtn.hide()
+ binding.rvWebSeries.setVisibility(showAdapter.showList.isNotEmpty())
+ }
+ is ApiResult.Success -> {
+ catSpinnerAdapter?.selectedCategoryType?.let { categoryType ->
+ it.data?.let {showList ->
+
+ binding.rvWebSeries.show()
+ binding.shimmerShowData.hide()
+
+ binding.loadMoreBtn.text = getString(R.string.load_more)
+ binding.loadMoreBtn.setVisibility(viewModel.categoryPagingData[categoryType]?.lastPage == false)
+
+ if (showAdapter.showList.isNotEmpty()){
+ // loaded more data
+ showAdapter.notifyItemRangeInserted(
+ showAdapter.showList.size,
+ showList.size
+ )
+ }else{
+ // new category data load
+ showAdapter.submitListShowList(showList, categoryType)
+ }
+
+ if (userPrefs?.userType != UserType.GUEST && !viewModel.continueWatchLiveData.isInitialized){
+ viewModel.loadContinueWatching()
+ }
+ }
+ }
+ }
+ }
+ }
+
+ binding.categorySpinner.onItemSelectedListener = object :
+ AdapterView.OnItemSelectedListener {
+ override fun onItemSelected(
+ parent: AdapterView<*>?,
+ view: View?,
+ position: Int,
+ id: Long
+ ) {
+ if (position != catSpinnerAdapter?.currentSelection){
+ catSpinnerAdapter?.let {
+ it.selectPosition(position)
+ loadShowData()
+ }
+ }
+ }
+
+ override fun onNothingSelected(parent: AdapterView<*>?) {}
+ }
+ }
+
+ private fun onShowClicked(showData: ShowData, position: Int, categoryId: String){
+
+ }
+
+ private fun onContinueEpisodeClicked(episodeData: ContinueEpisodeData){
+ episodeDialogBinding.apply {
+ episodeData.content_more_details?.let {moreDetailsList ->
+
+ episodeData.thumbnail_path?.let {
+ image.loadImage(it)
+ }
+
+ if (moreDetailsList.isNotEmpty()){
+
+ if (userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1){
+ moreDetailsList[1].let {data ->
+ title.text = data.title
+ description.text = Html.fromHtml(
+ data.description?.replace(
+ "
",
+ " "
+ ), Html.FROM_HTML_MODE_LEGACY
+ )
+ }
+ }else{
+ moreDetailsList[0].let {data ->
+ title.text = data.title
+ description.text = Html.fromHtml(
+ data.description?.replace(
+ "
",
+ " "
+ ), Html.FROM_HTML_MODE_LEGACY
+ )
+ }
+ }
+ }else{
+ title.text = episodeData.episode_title
+ description.text = Html.fromHtml(
+ episodeData.episode_description?.replace(
+ "
",
+ " "
+ ), Html.FROM_HTML_MODE_LEGACY
+ )
+ }
+
+ watchCard.setOnClickListener {
+ episodeData.content_more_details.let {moreDetailsList ->
+ val videoPlayList = VideoPlayList(ArrayList(), ArrayList())
+
+ if (moreDetailsList.isNotEmpty()){
+ if (userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1){
+ videoPlayList.playlist.add(
+ PlaylistItem.Builder()
+ .file(moreDetailsList[1].content_hd_url)
+ .title(moreDetailsList[1].title)
+ .image(moreDetailsList[1].content_hd_url)
+ .build()
+ )
+
+ videoPlayList.videoViewRequestDataList?.add(
+ VideoViewRequestData(
+ "${episodeData.id}",
+ "3",
+ null,
+ category_id = "18"
+ )
+ )
+ }else{
+ videoPlayList.playlist.add(
+ PlaylistItem.Builder()
+ .file(moreDetailsList[0].content_hd_url)
+ .title(moreDetailsList[0].title)
+ .image(moreDetailsList[0].content_hd_url)
+ .build()
+ )
+
+ videoPlayList.videoViewRequestDataList?.add(
+ VideoViewRequestData(
+ "${episodeData.id}",
+ "3",
+ null,
+ "1"
+ )
+ )
+ }
+ }
+
+ activity?.let {
+ startActivity(Intent(it, PlayerActivity::class.java)
+ .apply {
+ putExtra(EXTRA_PLAY_LIST, videoPlayList)
+ putExtra(EXTRA_PLAY_INDEX, 0)
+ })
+ }
+ }
+ }
+
+ close.setOnClickListener {
+ episodeDialog.dismiss()
+ }
+
+ episodeDialog.show()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/wokagames/GamesRepository.kt b/app/src/main/java/com/woka/wokagames/GamesRepository.kt
index 27a8452..2a43aac 100644
--- a/app/src/main/java/com/woka/wokagames/GamesRepository.kt
+++ b/app/src/main/java/com/woka/wokagames/GamesRepository.kt
@@ -1,11 +1,6 @@
package com.woka.wokagames
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import com.woka.audiobooks.AudioBookRepository
-import com.woka.audiobooks.models.audiodata.AudioBookData
import com.woka.home.mylist.MyListRepository
-import com.woka.home.mylist.models.FavAudioBookData
import com.woka.home.mylist.models.FavGameData
import com.woka.home.mylist.models.PostType
import com.woka.networking.ApiResult
@@ -25,43 +20,15 @@ object GamesRepository {
private val apiService = RetrofitHelper.getRetrofit().create(WokaGamesApiService::class.java)
private val userActionApiService = RetrofitHelper.getRetrofit().create(UserActionApiService::class.java)
- // live data
-
- // audio books data (loose caching)
- private val _gamesLiveData = MutableLiveData>()
- val gamesLiveData: LiveData>
- get() = _gamesLiveData
-
- private var gamesData: GamesResponse? = null
-
- fun loadGames(){
- if (gamesData != null){
- _gamesLiveData.postValue(ApiResult.Success(gamesData))
- return
- }
-
- CoroutineScope(Dispatchers.IO).launch{
- _gamesLiveData.postValue(ApiResult.Loading())
-
- val response = RetrofitHelper.handleApiCall {
- apiService.gamesListing(
- FormBody.Builder()
- .build()
- )
- }
-
- when (response){
- is ApiResult.Error -> _gamesLiveData.postValue(ApiResult.Error(response.errorMessage, response.error))
- is ApiResult.Loading -> _gamesLiveData.postValue(ApiResult.Loading())
- is ApiResult.Success -> {
- response.data?.let {
- gamesData = it
- _gamesLiveData.postValue(ApiResult.Success(it))
- }?:{
- _gamesLiveData.postValue(ApiResult.Error())
- }
- }
- }
+ suspend fun loadGames(pageNo: Int, quantity: Int): ApiResult {
+ return handleApiCall {
+ apiService.gamesListing(
+ FormBody.Builder()
+ .add("api_version", "v2")
+ .add("start", "$pageNo")
+ .add("limit", "$quantity")
+ .build()
+ )
}
}
@@ -90,27 +57,6 @@ object GamesRepository {
}
private fun changeLikeLocally(id: String, isLiked: Boolean){
- // changing in games locally
- gamesData?.game_data?.let {audioBooks ->
- for (audio in audioBooks){
- var found = false
- audio?.let {data ->
- if ("${data.id}" == id){
-
- data.is_liked = isLiked
-
- data.likes_count?.let { count ->
- data.likes_count = if (isLiked) count + 1
- else max(0, count - 1)
- }
-
- found = true
- }
- }
- if (found) break
- }
- }
-
// changing in fav list locally
MyListRepository.myFavData.result?.game_data?.let {
for (audioData in it){
@@ -155,15 +101,5 @@ object GamesRepository {
favAudioData.removeIf{it.id == gameData.id}
}
}
-
- gamesData?.game_data?.let {
- for (game in it){
- if (game?.id == gameData.id){
- game?.mark_as_favourite = addToBookmark
- break
- }
- }
- }
-
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/wokagames/adapters/GamesAdapter.kt b/app/src/main/java/com/woka/wokagames/adapters/GamesAdapter.kt
index 51ea1d0..c2aec91 100644
--- a/app/src/main/java/com/woka/wokagames/adapters/GamesAdapter.kt
+++ b/app/src/main/java/com/woka/wokagames/adapters/GamesAdapter.kt
@@ -16,6 +16,7 @@ import com.woka.utils.toast
import com.woka.wokagames.GamesRepository
import com.woka.wokagames.models.listing.GameData
import java.util.concurrent.Executors
+import kotlin.math.max
class GamesAdapter(var context: Context,
private var onGameClicked: (GameData) -> Unit): ListAdapter(
@@ -93,6 +94,18 @@ class GamesAdapter(var context: Context,
!like.isSelected
)
+ gameData.likes_count?.let {
+ gameData.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
+ }
+
+ gameData.is_liked = !like.isSelected
+
like.isSelected = !like.isSelected
likeCount.text = "${gameData.likes_count}"
}
@@ -110,6 +123,8 @@ class GamesAdapter(var context: Context,
!fav.isSelected
)
+ gameData.mark_as_favourite = !fav.isSelected
+
fav.isSelected = gameData.mark_as_favourite == true
}
diff --git a/app/src/main/java/com/woka/wokagames/viewmodels/GamesViewModel.kt b/app/src/main/java/com/woka/wokagames/viewmodels/GamesViewModel.kt
new file mode 100644
index 0000000..82056e6
--- /dev/null
+++ b/app/src/main/java/com/woka/wokagames/viewmodels/GamesViewModel.kt
@@ -0,0 +1,53 @@
+package com.woka.wokagames.viewmodels
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.woka.networking.ApiResult
+import com.woka.wokagames.GamesRepository
+import com.woka.wokagames.models.listing.GameData
+import kotlinx.coroutines.launch
+
+class GamesViewModel: ViewModel() {
+
+ private val _gamesLiveData = MutableLiveData>>()
+ val gamesLiveData: LiveData>>
+ get() = _gamesLiveData
+
+ private val gamesList = ArrayList()
+
+ private var nextPageToLoad: Int = 0
+ private var quantityPerPage: Int = 6
+ var lastPage = false
+
+ fun loadGames() {
+ viewModelScope.launch {
+ _gamesLiveData.postValue(ApiResult.Loading())
+
+ when (val value = GamesRepository.loadGames(nextPageToLoad, quantityPerPage)) {
+ is ApiResult.Error -> _gamesLiveData.postValue(
+ ApiResult.Error(
+ value.errorMessage,
+ value.error
+ )
+ )
+
+ is ApiResult.Loading -> _gamesLiveData.postValue(ApiResult.Loading())
+ is ApiResult.Success -> {
+ value.data?.let {
+ it.game_data?.filterNotNull()?.let { newList ->
+ gamesList.addAll(newList)
+
+ lastPage = gamesList.size == it.total_records
+
+ _gamesLiveData.postValue(ApiResult.Success(gamesList))
+ nextPageToLoad++
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/woka/wokagames/views/GamesActivity.kt b/app/src/main/java/com/woka/wokagames/views/GamesActivity.kt
index 375b336..9947cb5 100644
--- a/app/src/main/java/com/woka/wokagames/views/GamesActivity.kt
+++ b/app/src/main/java/com/woka/wokagames/views/GamesActivity.kt
@@ -12,6 +12,7 @@ import android.view.WindowManager
import androidx.activity.enableEdgeToEdge
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
+import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.SimpleItemAnimator
import com.google.android.material.appbar.CollapsingToolbarLayout
import com.woka.R
@@ -21,6 +22,7 @@ import com.woka.databinding.DialogModuleShowerBinding
import com.woka.networking.ApiResult
import com.woka.utils.WokaBaseActivity
import com.woka.utils.hide
+import com.woka.utils.setVisibility
import com.woka.utils.show
import com.woka.wokagames.GamesRepository
import com.woka.wokagames.adapters.GamesAdapter
@@ -28,13 +30,16 @@ import com.woka.wokagames.models.listing.GameData
import com.woka.wokagames.playerr.GamePlayerActivity
import com.woka.wokagames.playerr.GamePlayerActivity.Companion.EXTRA_GAME_PLAYER_DATA
import com.woka.wokagames.playerr.GamePlayerData
+import com.woka.wokagames.viewmodels.GamesViewModel
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
+import kotlin.math.max
class GamesActivity : WokaBaseActivity() {
private lateinit var binding: ActivityGamesBinding
+ private lateinit var viewModel: GamesViewModel
private lateinit var gameAdapter: GamesAdapter
@@ -56,6 +61,8 @@ class GamesActivity : WokaBaseActivity() {
navigationBarColor = getColor(R.color.color_primary_dark)
}
+ viewModel = ViewModelProvider(this)[GamesViewModel::class.java]
+
gameAdapter = GamesAdapter(this, ::onGameClicked)
dialogBinding = DialogModuleShowerBinding.inflate(layoutInflater)
@@ -70,7 +77,9 @@ class GamesActivity : WokaBaseActivity() {
setObservers()
- GamesRepository.loadGames()
+ if (!viewModel.gamesLiveData.isInitialized){
+ viewModel.loadGames()
+ }
}
private fun initViews() {
@@ -115,7 +124,11 @@ class GamesActivity : WokaBaseActivity() {
}
retryBtn.setOnClickListener {
- GamesRepository.loadGames()
+ viewModel.loadGames()
+ }
+
+ loadMoreBtn.setOnClickListener {
+ viewModel.loadGames()
}
}
}
@@ -239,8 +252,20 @@ class GamesActivity : WokaBaseActivity() {
!like.isSelected
)
+ gameData.likes_count?.let {
+ gameData.likes_count = if (like.isSelected){
+ // unlike
+ max(0, it - 1)
+ }else{
+ // like
+ it + 1
+ }
+ }
+
+ gameData.is_liked = !like.isSelected
+
gameData.id?.let {
- onGameChanged(it)
+ onGameChanged(it, gameData)
}
like.isSelected = !like.isSelected
likeCount.text = "${gameData.likes_count}"
@@ -252,8 +277,10 @@ class GamesActivity : WokaBaseActivity() {
!fav.isSelected
)
+ gameData.mark_as_favourite = !fav.isSelected
+
gameData.id?.let {
- onGameChanged(it)
+ onGameChanged(it, gameData)
}
fav.isSelected = !fav.isSelected
@@ -268,46 +295,75 @@ class GamesActivity : WokaBaseActivity() {
}
}
- private fun onGameChanged(id: Int) {
+ private fun onGameChanged(id: Int, gameData: GameData) {
// updating continue book list
val position = gameAdapter.currentList.indexOfFirst { it.id == id }
if (position >= 0 && position < gameAdapter.currentList.size) {
+ val currKaraoke = gameAdapter.currentList[position]
+
+ // updating possible data changes
+ currKaraoke.is_liked = gameData.is_liked
+ currKaraoke.likes_count = gameData.likes_count
+ currKaraoke.mark_as_favourite = gameData.mark_as_favourite
gameAdapter.notifyItemChanged(position)
}
}
private fun setObservers(){
- GamesRepository.gamesLiveData.observe(this) {
- when (it) {
+ viewModel.gamesLiveData.observe(this){
+ when(it){
is ApiResult.Error -> {
binding.shimmer.hide()
- binding.rvGames.hide()
- binding.listenTxt.hide()
- binding.trailerView.hide()
+ if (gameAdapter.currentList.size == 0) {
+ // none of the data is yet loaded
+ binding.rvGames.hide()
+ binding.listenTxt.hide()
+ binding.trailerView.hide()
- binding.errorView.show()
+ binding.errorView.show()
+ } else {
+ // error in loading more
+ binding.loadMoreProgress.hide()
+ binding.loadMoreBtn.text = getString(R.string.retry)
+ binding.loadMoreBtn.show()
+ }
}
-
is ApiResult.Loading -> {
- binding.shimmer.show()
-
- binding.rvGames.hide()
- binding.listenTxt.hide()
- binding.trailerView.hide()
- binding.errorView.hide()
+ if (gameAdapter.currentList.size == 0) {
+ // loading first data
+ binding.shimmer.show()
+ binding.errorView.hide()
+ } else {
+ // loading more data
+ binding.loadMoreProgress.show()
+ binding.loadMoreBtn.hide()
+ }
}
-
is ApiResult.Success -> {
- it.data?.game_data?.filterNotNull()?.let { gameData ->
- if (gameData.isNotEmpty()) {
- binding.shimmer.hide()
- binding.errorView.hide()
-
- loadTrailerData(gameData[0])
+ it.data?.let {newList ->
+ if (newList.isNotEmpty()){
binding.rvGames.show()
binding.listenTxt.show()
+ binding.trailerView.show()
- gameAdapter.submitList(gameData)
+ binding.errorView.hide()
+ binding.shimmer.hide()
+
+ binding.loadMoreProgress.hide()
+ binding.loadMoreBtn.text = getString(R.string.load_more)
+ binding.loadMoreBtn.setVisibility(!viewModel.lastPage)
+
+ if (gameAdapter.currentList.isEmpty()){
+ // first data load
+ loadTrailerData(newList[0])
+ gameAdapter.submitList(newList)
+ }else{
+ // loaded more data
+ gameAdapter.notifyItemRangeInserted(
+ gameAdapter.currentList.size,
+ newList.size
+ )
+ }
}
}
}
diff --git a/app/src/main/res/layout/activity_audio_books.xml b/app/src/main/res/layout/activity_audio_books.xml
index ed1666a..6822f38 100644
--- a/app/src/main/res/layout/activity_audio_books.xml
+++ b/app/src/main/res/layout/activity_audio_books.xml
@@ -274,6 +274,42 @@
tools:listitem="@layout/show_view_holder"
/>
+
+
+
+
diff --git a/app/src/main/res/layout/activity_games.xml b/app/src/main/res/layout/activity_games.xml
index 83767b5..b0c0213 100644
--- a/app/src/main/res/layout/activity_games.xml
+++ b/app/src/main/res/layout/activity_games.xml
@@ -246,6 +246,42 @@
tools:listitem="@layout/show_view_holder"
/>
+
+
+
+
diff --git a/app/src/main/res/layout/activity_series.xml b/app/src/main/res/layout/activity_series.xml
new file mode 100644
index 0000000..5dd02a6
--- /dev/null
+++ b/app/src/main/res/layout/activity_series.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_web_series.xml b/app/src/main/res/layout/fragment_web_series.xml
new file mode 100644
index 0000000..53bd010
--- /dev/null
+++ b/app/src/main/res/layout/fragment_web_series.xml
@@ -0,0 +1,346 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file