From 64626f7730b2faed499f507d78a06bf3e3eb9abd Mon Sep 17 00:00:00 2001 From: AdityaGaikwad Date: Tue, 9 Jul 2024 19:19:03 +0530 Subject: [PATCH] Created Karaoke module: UI and backend Integrated karaoke listing api and data caching Integrated Continue Karaoke api and data caching Data syncing with adapters and MyListFragment Dialog showing for karaoke. Implemented Media3 Player view for KaraokePlayerActivity Custom Player controller view - adding close button and title and hiding full screen and settings icon Player setup, hiding user controller view --- app/src/main/AndroidManifest.xml | 14 +- .../woka/audiobooks/AudioBookRepository.kt | 2 +- .../adapters/ContinueAudioAdapter.kt | 7 +- .../com/woka/home/fragments/Home1Fragment.kt | 7 + .../com/woka/home/fragments/MyListFragment.kt | 131 ++++++- ...KaraokeAdapter.kt => FavKaraokeAdapter.kt} | 48 ++- .../woka/home/mylist/models/FavKaraokeData.kt | 46 +++ .../com/woka/home/mylist/models/Result.kt | 2 +- .../com/woka/karaoke/KaraokeRepository.kt | 121 +++++- .../adapters/ContinueKaraokeAdapter.kt | 134 +++++++ .../woka/karaoke/adapters/KaraokeAdapter.kt | 133 +++++++ .../continuesing/ContinueKaraokeData.kt} | 13 +- .../continuesing/ContinueKaraokeResponse.kt | 6 + .../karaoke/models/listing/KaraokeData.kt | 70 +++- .../karaoke/player/KaraokePlayerActivity.kt | 84 ++++ .../woka/karaoke/player/KaraokePlayerData.kt | 10 + .../com/woka/karaoke/views/KaraokeActivity.kt | 361 ++++++++++++++++++ .../com/woka/userPreference/UserPreference.kt | 2 + .../com/woka/userdata/UserActionApiService.kt | 4 + .../main/res/drawable/gradient_karaoke.xml | 11 + app/src/main/res/drawable/ic_mic.xml | 5 + app/src/main/res/layout/activity_karaoke.xml | 283 ++++++++++++++ .../res/layout/activity_karaoke_playerr.xml | 67 ++++ .../res/layout/exo_player_control_view.xml | 192 ++++++++++ app/src/main/res/values/strings.xml | 4 + 25 files changed, 1716 insertions(+), 41 deletions(-) rename app/src/main/java/com/woka/home/mylist/adapters/{KaraokeAdapter.kt => FavKaraokeAdapter.kt} (56%) create mode 100644 app/src/main/java/com/woka/home/mylist/models/FavKaraokeData.kt create mode 100644 app/src/main/java/com/woka/karaoke/adapters/ContinueKaraokeAdapter.kt create mode 100644 app/src/main/java/com/woka/karaoke/adapters/KaraokeAdapter.kt rename app/src/main/java/com/woka/{home/mylist/models/SingKaraokeData.kt => karaoke/models/continuesing/ContinueKaraokeData.kt} (59%) create mode 100644 app/src/main/java/com/woka/karaoke/models/continuesing/ContinueKaraokeResponse.kt create mode 100644 app/src/main/java/com/woka/karaoke/player/KaraokePlayerActivity.kt create mode 100644 app/src/main/java/com/woka/karaoke/player/KaraokePlayerData.kt create mode 100644 app/src/main/java/com/woka/karaoke/views/KaraokeActivity.kt create mode 100644 app/src/main/res/drawable/gradient_karaoke.xml create mode 100644 app/src/main/res/drawable/ic_mic.xml create mode 100644 app/src/main/res/layout/activity_karaoke.xml create mode 100644 app/src/main/res/layout/activity_karaoke_playerr.xml create mode 100644 app/src/main/res/layout/exo_player_control_view.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 19262f0..a263724 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,13 +15,25 @@ android:supportsRtl="true" android:theme="@style/Theme.Woka" tools:targetApi="31"> + + + android:theme="@style/FullScreenTheme" /> , private var onBookClicked: (ContinueAudioData) -> Unit, - private var onContinueBookChanged: (id: Int) -> Unit): ListAdapter(config) { + private var onContinueBookChanged: (id: Int) -> Unit): ListAdapter(DIFF_CONFIG) { companion object{ private val DIFF_UTIL = object : DiffUtil.ItemCallback(){ @@ -39,10 +38,6 @@ class ContinueAudioAdapter(private val context: Context, .build() } - constructor(context: Context, - onBookClicked: (ContinueAudioData) -> Unit, - onContinueBookChanged: (id: Int) -> Unit): this(context, DIFF_CONFIG, onBookClicked, onContinueBookChanged) - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavoriteViewHolder { return FavoriteViewHolder( FavViewHolderBinding.inflate( 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 6de2ac8..2dacd15 100644 --- a/app/src/main/java/com/woka/home/fragments/Home1Fragment.kt +++ b/app/src/main/java/com/woka/home/fragments/Home1Fragment.kt @@ -25,6 +25,7 @@ import com.woka.home.views.FMActivity import com.woka.home.viewmodels.HomeViewModel import com.woka.home.views.MoreHomeActivity import com.woka.home.models.TimePeriod +import com.woka.karaoke.views.KaraokeActivity import com.woka.userdata.userDataModels.UserDataResponse import com.woka.networking.ApiResult import com.woka.players.views.LiveStreamPlayerActivity @@ -193,6 +194,12 @@ class Home1Fragment : Fragment(), Listener { startActivity(Intent(it, GamesActivity::class.java)) } } + + karaoke.setOnClickListener { + activity?.let { + startActivity(Intent(it, KaraokeActivity::class.java)) + } + } } } diff --git a/app/src/main/java/com/woka/home/fragments/MyListFragment.kt b/app/src/main/java/com/woka/home/fragments/MyListFragment.kt index cd7df64..993b4b1 100644 --- a/app/src/main/java/com/woka/home/fragments/MyListFragment.kt +++ b/app/src/main/java/com/woka/home/fragments/MyListFragment.kt @@ -29,12 +29,15 @@ import com.woka.databinding.FragmentMyListBinding import com.woka.home.mylist.MyListRepository import com.woka.home.mylist.adapters.FavAudioAdapter import com.woka.home.mylist.adapters.FavGamesAdapter -import com.woka.home.mylist.adapters.KaraokeAdapter +import com.woka.home.mylist.adapters.FavKaraokeAdapter import com.woka.home.mylist.adapters.WebSeriesAdapter import com.woka.home.mylist.models.PostType import com.woka.home.mylist.models.BookmarkedShowData import com.woka.home.mylist.models.FavAudioBookData import com.woka.home.mylist.models.FavGameData +import com.woka.home.mylist.models.FavKaraokeData +import com.woka.karaoke.KaraokeRepository +import com.woka.karaoke.models.listing.KaraokeData import com.woka.networking.ApiResult import com.woka.players.models.VideoPlayList import com.woka.players.views.PlayerActivity @@ -59,7 +62,7 @@ class MyListFragment : Fragment() { private lateinit var webSeriesEAdapter: WebSeriesAdapter private lateinit var webSeriesHAdapter: WebSeriesAdapter private lateinit var audioBooksAdapter: FavAudioAdapter - private lateinit var karaokeAdapter: KaraokeAdapter + private lateinit var karaokeAdapter: FavKaraokeAdapter private lateinit var gamesAdapter: FavGamesAdapter private var webShowIntentLauncher: ActivityResultLauncher? = null @@ -77,7 +80,7 @@ class MyListFragment : Fragment() { webSeriesEAdapter = WebSeriesAdapter(requireContext(),"1", ::onListGotEmpty) webSeriesHAdapter = WebSeriesAdapter(requireContext(),"18", ::onListGotEmpty) audioBooksAdapter = FavAudioAdapter(requireContext(), ::onListGotEmpty, ::onAudioBookClicked) - karaokeAdapter = KaraokeAdapter(requireContext(), ::onListGotEmpty) + karaokeAdapter = FavKaraokeAdapter(requireContext(), ::onListGotEmpty, ::onKaraokeClicked) gamesAdapter = FavGamesAdapter(requireContext(), ::onListGotEmpty, ::onGameClicked) // dialogs @@ -606,6 +609,128 @@ class MyListFragment : Fragment() { } } + // karaoke + private fun onKaraokeClicked(karaokeData: FavKaraokeData, position: Int) { + dialogBinding.apply { + karaokeData.content_more_details?.let { moreDetailsList -> + + karaokeData.thumbnail_path?.let { + image.loadImage(it) + } + + fav.isSelected = karaokeData.mark_as_favourite == true + like.isSelected = karaokeData.is_liked == true + likeCount.text = "${karaokeData.likes_count}" + + year.text = try { + karaokeData.release_date?.let { + val cal = Calendar.getInstance() + cal.time = + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).parse( + karaokeData.release_date + )!! + "${cal.get(Calendar.YEAR)}" + } ?: throw Exception() + } catch (e: Exception) { + "${karaokeData.release_date}" + } + + if (moreDetailsList.isNotEmpty()) { + + if (WokaApp.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 = karaokeData.title + description.text = Html.fromHtml( + karaokeData.description?.replace( + "
", + " " + ), Html.FROM_HTML_MODE_LEGACY + ) + } + + activity?.let { + watchCard.backgroundTintList = ColorStateList.valueOf(it.getColor(R.color.game_grad_one)) + } + watchCard.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_mic, 0, 0, 0) + watchCard.text = getString(R.string.sing_now) + watchCard.setOnClickListener { + + } + + like.setOnClickListener { + KaraokeRepository.likeUnLikeSong( + "${karaokeData.id}", + !like.isSelected + ) + + karaokeData.id?.let { + onKaraokeChanged(it) + } + like.isSelected = !like.isSelected + likeCount.text = "${karaokeData.likes_count}" + } + + fav.setOnClickListener { + if (context?.isNetworkConnected() == false){ + toast(getString(R.string.no_internet)) + return@setOnClickListener + } + + KaraokeRepository.updateFavShow( + KaraokeData(karaokeData), + !fav.isSelected + ) + + try { + karaokeAdapter.notifyItemRemoved(position) + } catch (e: Exception) { + // do nothing + } + + if (karaokeAdapter.currentList.isEmpty()){ + onListGotEmpty(PostType.KARAOKE, true) + } + + moduleShowerDialog.dismiss() + } + + close.setOnClickListener { + moduleShowerDialog.dismiss() + } + + moduleShowerDialog.show() + } + } + } + + private fun onKaraokeChanged(id: Int) { + // updating continue book list + val position = karaokeAdapter.currentList.indexOfFirst { it.id == id } + if (position >= 0 && position < karaokeAdapter.currentList.size) { + karaokeAdapter.notifyItemChanged(position) + } + } + companion object { fun newInstance() = MyListFragment() } diff --git a/app/src/main/java/com/woka/home/mylist/adapters/KaraokeAdapter.kt b/app/src/main/java/com/woka/home/mylist/adapters/FavKaraokeAdapter.kt similarity index 56% rename from app/src/main/java/com/woka/home/mylist/adapters/KaraokeAdapter.kt rename to app/src/main/java/com/woka/home/mylist/adapters/FavKaraokeAdapter.kt index a4991c3..abdcad4 100644 --- a/app/src/main/java/com/woka/home/mylist/adapters/KaraokeAdapter.kt +++ b/app/src/main/java/com/woka/home/mylist/adapters/FavKaraokeAdapter.kt @@ -1,34 +1,34 @@ package com.woka.home.mylist.adapters import android.content.Context -import android.util.Log import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.AsyncDifferConfig import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter -import com.bumptech.glide.Glide import com.woka.R import com.woka.databinding.FavViewHolderBinding -import com.woka.home.mylist.MyListRepository +import com.woka.home.mylist.models.FavKaraokeData import com.woka.home.mylist.models.PostType -import com.woka.home.mylist.models.SingKaraokeData -import com.woka.utils.TAG +import com.woka.karaoke.KaraokeRepository +import com.woka.karaoke.models.listing.KaraokeData import com.woka.utils.isNetworkConnected import com.woka.utils.toast import java.util.concurrent.Executors -import kotlin.math.max -class KaraokeAdapter(private val context: Context, - config: AsyncDifferConfig, - private val onListEmptyListener: ((postType: PostType, isEng: Boolean) -> Unit)): ListAdapter(config) { +class FavKaraokeAdapter(private val context: Context, + private val onListEmptyListener: ((postType: PostType, isEng: Boolean) -> Unit), + private var onKaraokeClicked: (FavKaraokeData, Int) -> Unit) + : ListAdapter(DIFF_CONFIG) { companion object{ - private val DIFF_UTIL = object : DiffUtil.ItemCallback(){ - override fun areItemsTheSame(oldItem: SingKaraokeData, newItem: SingKaraokeData): Boolean = oldItem.id == newItem.id - override fun areContentsTheSame(oldItem: SingKaraokeData, newItem: SingKaraokeData): Boolean { - return oldItem.title == newItem.title && + private val DIFF_UTIL = object : DiffUtil.ItemCallback(){ + override fun areItemsTheSame(oldItem: FavKaraokeData, newItem: FavKaraokeData): Boolean = oldItem.id == newItem.id + override fun areContentsTheSame(oldItem: FavKaraokeData, newItem: FavKaraokeData): Boolean { + return oldItem.thumbnail_path == newItem.thumbnail_path && + oldItem.title == newItem.title && oldItem.is_liked == newItem.is_liked && + oldItem.mark_as_favourite == newItem.mark_as_favourite && oldItem.likes_count == newItem.likes_count } } @@ -38,8 +38,6 @@ class KaraokeAdapter(private val context: Context, .build() } - constructor(context: Context, onListEmptyListener: ((postType: PostType, isEng: Boolean) -> Unit)): this(context, DIFF_CONFIG, onListEmptyListener) - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavoriteViewHolder { return FavoriteViewHolder( FavViewHolderBinding.inflate( @@ -74,7 +72,13 @@ class KaraokeAdapter(private val context: Context, return@setOnClickListener } + KaraokeRepository.likeUnLikeSong( + "${karaokeData.id}", + !like.isSelected + ) + like.isSelected = !like.isSelected + likeCount.text = "${karaokeData.likes_count}" } fav.isSelected = true @@ -85,6 +89,20 @@ class KaraokeAdapter(private val context: Context, return@setOnClickListener } + KaraokeRepository.updateFavShow( + KaraokeData(karaokeData), + !fav.isSelected + ) + + notifyItemRemoved(holder.absoluteAdapterPosition) + + if (currentList.isEmpty()){ + onListEmptyListener(PostType.KARAOKE, true) + } + } + + root.setOnClickListener { + onKaraokeClicked(karaokeData, holder.absoluteAdapterPosition) } } } diff --git a/app/src/main/java/com/woka/home/mylist/models/FavKaraokeData.kt b/app/src/main/java/com/woka/home/mylist/models/FavKaraokeData.kt new file mode 100644 index 0000000..7891076 --- /dev/null +++ b/app/src/main/java/com/woka/home/mylist/models/FavKaraokeData.kt @@ -0,0 +1,46 @@ +package com.woka.home.mylist.models + +import com.woka.karaoke.models.listing.ContentMoreDetail +import com.woka.karaoke.models.listing.KaraokeData + +data class FavKaraokeData( + val age_range_master_id: String?, + val bookmark_category_ids: String?, + val bookmark_count: Int?, + val category_master_id: String?, + val content_more_details: List?, + val description: String?, + val duration: String?, + val gender_master_id: String?, + val id: Int?, + var is_liked: Boolean?, + val language_master_id: Int?, + var likes_count: Int?, + val mark_as_favourite: Boolean?, + val release_date: String?, + val thumbnail_path: String?, + val title: String?, + val video_url: String?, + val views_count: Int? +){ + constructor(karaoke: KaraokeData): this( + karaoke.age_range_master_id, + karaoke.bookmark_category_ids, + karaoke.bookmark_count, + karaoke.category_master_id, + karaoke.content_more_details, + karaoke.description, + karaoke.duration, + karaoke.gender_master_id, + karaoke.id, + karaoke.is_liked, + karaoke.language_master_id, + karaoke.likes_count, + karaoke.mark_as_favourite, + karaoke.release_date, + karaoke.thumbnail_path, + karaoke.title, + karaoke.video_url, + karaoke.views_count + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/home/mylist/models/Result.kt b/app/src/main/java/com/woka/home/mylist/models/Result.kt index a2292f8..d44c5a9 100644 --- a/app/src/main/java/com/woka/home/mylist/models/Result.kt +++ b/app/src/main/java/com/woka/home/mylist/models/Result.kt @@ -4,6 +4,6 @@ data class Result( val audio_data: MutableList?, val game_data: MutableList?, val show_data: MutableList?, - val sing_karaoke_data: MutableList?, + val sing_karaoke_data: MutableList?, val video_data: MutableList? ) \ No newline at end of file diff --git a/app/src/main/java/com/woka/karaoke/KaraokeRepository.kt b/app/src/main/java/com/woka/karaoke/KaraokeRepository.kt index b6900f6..b96b5f7 100644 --- a/app/src/main/java/com/woka/karaoke/KaraokeRepository.kt +++ b/app/src/main/java/com/woka/karaoke/KaraokeRepository.kt @@ -3,7 +3,10 @@ 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 +import com.woka.karaoke.models.continuesing.ContinueKaraokeResponse +import com.woka.karaoke.models.listing.KaraokeData import com.woka.karaoke.models.listing.KaraokeResponse import com.woka.networking.ApiResult import com.woka.networking.RetrofitHelper @@ -29,7 +32,14 @@ object KaraokeRepository { private var karaokeData: KaraokeResponse? = null - fun loadGames(){ + // continue sing karaoke data + private val _continueKaraokeLiveData = MutableLiveData>() + val continueKaraokeLiveData: LiveData> + get() = _continueKaraokeLiveData + + private var continueKaraokeData: ContinueKaraokeResponse? = null + + fun loadKaraokeSongs(){ if (karaokeData != null){ _karaokeLiveData.postValue(ApiResult.Success(karaokeData)) return @@ -38,7 +48,7 @@ object KaraokeRepository { CoroutineScope(Dispatchers.IO).launch{ _karaokeLiveData.postValue(ApiResult.Loading()) - val response = RetrofitHelper.handleApiCall { + val response = handleApiCall { apiService.karaokeListing( FormBody.Builder() .build() @@ -60,7 +70,36 @@ object KaraokeRepository { } } - fun likeUnLikeGame(postId: String, likeIt: Boolean){ + 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) + } + } + + fun likeUnLikeSong(postId: String, likeIt: Boolean){ CoroutineScope(Dispatchers.IO).launch { handleApiCall { if (likeIt){ @@ -106,6 +145,27 @@ object KaraokeRepository { } } + // 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){ @@ -120,4 +180,59 @@ object KaraokeRepository { } } } + + fun updateFavShow(karaoke: KaraokeData, addToBookmark: Boolean){ + CoroutineScope(Dispatchers.IO).launch { + handleApiCall { + if (addToBookmark){ + userActionApiService.addToFav( + FormBody.Builder() + .add("post_id", "${karaoke.id}") + .add("post_type", PostType.KARAOKE.value) + .build() + ) + }else{ + userActionApiService.removeFromFav( + FormBody.Builder() + .add("id", "${karaoke.id}") + .add("post_type", PostType.KARAOKE.value) + .build() + ) + } + } + } + + MyListRepository.myFavData.result?.sing_karaoke_data?.let {favAudioData -> + karaoke.mark_as_favourite = addToBookmark + if (addToBookmark){ + favAudioData.add(FavKaraokeData(karaoke)) + }else{ + favAudioData.removeIf{it.id == karaoke.id} + } + } + + karaokeData?.karaoke_data?.let { + for (audio in it){ + if (audio?.id == karaoke.id){ + audio?.mark_as_favourite = addToBookmark + break + } + } + } + + continueKaraokeData?.result?.let { + for (audio in it){ + if (audio?.id == karaoke.id){ + audio?.mark_as_favourite = addToBookmark + break + } + } + } + + } + + fun clearData(){ + karaokeData = null + 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 new file mode 100644 index 0000000..622cf46 --- /dev/null +++ b/app/src/main/java/com/woka/karaoke/adapters/ContinueKaraokeAdapter.kt @@ -0,0 +1,134 @@ +package com.woka.karaoke.adapters + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.AsyncDifferConfig +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView.ViewHolder +import com.woka.R +import com.woka.WokaApp.Companion.userPrefs +import com.woka.databinding.FavViewHolderBinding +import com.woka.karaoke.KaraokeRepository +import com.woka.karaoke.models.continuesing.ContinueKaraokeData +import com.woka.karaoke.models.listing.KaraokeData +import com.woka.utils.isNetworkConnected +import com.woka.utils.show +import com.woka.utils.toast +import java.util.concurrent.Executors + +class ContinueKaraokeAdapter( + private val context: Context, + private var onKaraokeClicked: (KaraokeData) -> Unit, + private var onKaraokeChanged: (id: Int, isFromContinue: Boolean) -> Unit +): ListAdapter(ASYNC_DIFF_UTIL) { + + inner class AudioBookViewHolder(val binding: FavViewHolderBinding): ViewHolder(binding.root) + + companion object{ + val DIFF_UTIL = object : DiffUtil.ItemCallback(){ + override fun areItemsTheSame(oldItem: ContinueKaraokeData, newItem: ContinueKaraokeData): Boolean = oldItem.id == newItem.id + + override fun areContentsTheSame(oldItem: ContinueKaraokeData, newItem: ContinueKaraokeData): Boolean { + return oldItem.thumbnail_path == newItem.thumbnail_path && + oldItem.title == newItem.title && + oldItem.is_liked == newItem.is_liked && + oldItem.mark_as_favourite == newItem.mark_as_favourite && + oldItem.likes_count == newItem.likes_count + } + } + + val ASYNC_DIFF_UTIL = AsyncDifferConfig.Builder(DIFF_UTIL) + .setBackgroundThreadExecutor(Executors.newSingleThreadExecutor()) + .build() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudioBookViewHolder { + return AudioBookViewHolder( + FavViewHolderBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: AudioBookViewHolder, position: Int) { + val karaokeData = getItem(holder.absoluteAdapterPosition) + + holder.binding.apply { + karaokeData.thumbnail_path?.let { + image.loadImage(it) + } + + karaokeData.content_more_details?.let {moreDetailsList -> + title.text = if (moreDetailsList.isNotEmpty()){ + if (userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1){ + moreDetailsList[1]?.title + }else{ + moreDetailsList[0]?.title + } + }else{ + karaokeData.title + } + } + + like.show() + likeCount.show() + fav.show() + + karaokeData.likes_count?.let { + likeCount.text = "$it" + } + + karaokeData.is_liked?.let { + like.isSelected = it + } + + like.setOnClickListener { + if (!context.isNetworkConnected()){ + context.toast(context.getString(R.string.no_internet)) + return@setOnClickListener + } + + KaraokeRepository.likeUnLikeSong( + "${karaokeData.id}", + !like.isSelected + ) + + karaokeData.likes_count?.let { + likeCount.text = "$it" + } + + karaokeData.is_liked?.let { + like.isSelected = it + } + + karaokeData.id?.let{onKaraokeChanged(it, true)} + } + + fav.isSelected = karaokeData.mark_as_favourite == true + + fav.setOnClickListener { + if (!context.isNetworkConnected()){ + context.toast(context.getString(R.string.no_internet)) + return@setOnClickListener + } + + KaraokeRepository.updateFavShow( + KaraokeData(karaokeData), + !fav.isSelected + ) + + fav.isSelected = karaokeData.mark_as_favourite == true + + karaokeData.id?.let{onKaraokeChanged(it, true)} + } + + root.setOnClickListener { + onKaraokeClicked(KaraokeData(karaokeData)) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/karaoke/adapters/KaraokeAdapter.kt b/app/src/main/java/com/woka/karaoke/adapters/KaraokeAdapter.kt new file mode 100644 index 0000000..9b83b36 --- /dev/null +++ b/app/src/main/java/com/woka/karaoke/adapters/KaraokeAdapter.kt @@ -0,0 +1,133 @@ +package com.woka.karaoke.adapters + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.AsyncDifferConfig +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView.ViewHolder +import com.woka.R +import com.woka.WokaApp.Companion.userPrefs +import com.woka.databinding.ShowViewHolderBinding +import com.woka.karaoke.KaraokeRepository +import com.woka.karaoke.models.listing.KaraokeData +import com.woka.utils.isNetworkConnected +import com.woka.utils.show +import com.woka.utils.toast +import java.util.concurrent.Executors + +class KaraokeAdapter( + private val context: Context, + private var onKaraokeClicked: (KaraokeData) -> Unit, + private var onKaraokeChanged: (id: Int, isContinue: Boolean) -> Unit +): ListAdapter(ASYNC_DIFF_UTIL) { + + inner class AudioBookViewHolder(val binding: ShowViewHolderBinding): ViewHolder(binding.root) + + companion object{ + val DIFF_UTIL = object : DiffUtil.ItemCallback(){ + override fun areItemsTheSame(oldItem: KaraokeData, newItem: KaraokeData): Boolean = oldItem.id == newItem.id + + override fun areContentsTheSame(oldItem: KaraokeData, newItem: KaraokeData): Boolean { + return oldItem.thumbnail_path == newItem.thumbnail_path && + oldItem.title == newItem.title && + oldItem.is_liked == newItem.is_liked && + oldItem.mark_as_favourite == newItem.mark_as_favourite && + oldItem.likes_count == newItem.likes_count + } + } + + val ASYNC_DIFF_UTIL = AsyncDifferConfig.Builder(DIFF_UTIL) + .setBackgroundThreadExecutor(Executors.newSingleThreadExecutor()) + .build() + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudioBookViewHolder { + return AudioBookViewHolder( + ShowViewHolderBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ) + } + + override fun onBindViewHolder(holder: AudioBookViewHolder, position: Int) { + val karaokeData = getItem(holder.absoluteAdapterPosition) + + holder.binding.apply { + karaokeData.thumbnail_path?.let { + image.loadImage(it) + } + + karaokeData.content_more_details?.let {moreDetailsList -> + title.text = if (moreDetailsList.isNotEmpty()){ + if (userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1){ + moreDetailsList[1]?.title + }else{ + moreDetailsList[0]?.title + } + }else{ + karaokeData.title + } + } + + like.show() + likeCount.show() + fav.show() + + karaokeData.likes_count?.let { + likeCount.text = "$it" + } + + karaokeData.is_liked?.let { + like.isSelected = it + } + + like.setOnClickListener { + if (!context.isNetworkConnected()){ + context.toast(context.getString(R.string.no_internet)) + return@setOnClickListener + } + + KaraokeRepository.likeUnLikeSong( + "${karaokeData.id}", + !like.isSelected + ) + + karaokeData.likes_count?.let { + likeCount.text = "$it" + } + + karaokeData.is_liked?.let { + like.isSelected = it + } + + karaokeData.id?.let{onKaraokeChanged(it, false)} + } + + fav.isSelected = karaokeData.mark_as_favourite == true + + fav.setOnClickListener { + if (!context.isNetworkConnected()){ + context.toast(context.getString(R.string.no_internet)) + return@setOnClickListener + } + + KaraokeRepository.updateFavShow( + karaokeData, + !fav.isSelected + ) + + fav.isSelected = karaokeData.mark_as_favourite == true + + karaokeData.id?.let{onKaraokeChanged(it, false)} + } + + root.setOnClickListener { + onKaraokeClicked(karaokeData) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/home/mylist/models/SingKaraokeData.kt b/app/src/main/java/com/woka/karaoke/models/continuesing/ContinueKaraokeData.kt similarity index 59% rename from app/src/main/java/com/woka/home/mylist/models/SingKaraokeData.kt rename to app/src/main/java/com/woka/karaoke/models/continuesing/ContinueKaraokeData.kt index 0eb649c..2f547c2 100644 --- a/app/src/main/java/com/woka/home/mylist/models/SingKaraokeData.kt +++ b/app/src/main/java/com/woka/karaoke/models/continuesing/ContinueKaraokeData.kt @@ -1,11 +1,12 @@ -package com.woka.home.mylist.models +package com.woka.karaoke.models.continuesing -data class SingKaraokeData( +import com.woka.karaoke.models.listing.ContentMoreDetail + +data class ContinueKaraokeData( val age_range_master_id: String?, - val bookmark_category_ids: String?, val bookmark_count: Int?, val category_master_id: String?, -// val content_more_details: List?, + val content_more_details: List?, val description: String?, val duration: String?, val gender_master_id: String?, @@ -13,10 +14,12 @@ data class SingKaraokeData( var is_liked: Boolean?, val language_master_id: Int?, var likes_count: Int?, - val mark_as_favourite: Boolean?, + var mark_as_favourite: Boolean?, val release_date: String?, + val show_data_count: Any?, val thumbnail_path: String?, val title: String?, + val user_video_view: List?, val video_url: String?, val views_count: Int? ) \ No newline at end of file diff --git a/app/src/main/java/com/woka/karaoke/models/continuesing/ContinueKaraokeResponse.kt b/app/src/main/java/com/woka/karaoke/models/continuesing/ContinueKaraokeResponse.kt new file mode 100644 index 0000000..16956a9 --- /dev/null +++ b/app/src/main/java/com/woka/karaoke/models/continuesing/ContinueKaraokeResponse.kt @@ -0,0 +1,6 @@ +package com.woka.karaoke.models.continuesing + +data class ContinueKaraokeResponse( + val result: List?, + val total_records: Int? +) \ No newline at end of file diff --git a/app/src/main/java/com/woka/karaoke/models/listing/KaraokeData.kt b/app/src/main/java/com/woka/karaoke/models/listing/KaraokeData.kt index 402dc49..8100e6c 100644 --- a/app/src/main/java/com/woka/karaoke/models/listing/KaraokeData.kt +++ b/app/src/main/java/com/woka/karaoke/models/listing/KaraokeData.kt @@ -1,24 +1,82 @@ package com.woka.karaoke.models.listing +import com.woka.home.mylist.models.FavKaraokeData +import com.woka.karaoke.models.continuesing.ContinueKaraokeData + data class KaraokeData( - val age_range_data: List?, val age_range_master_id: String?, + val bookmark_category_ids: String?, val bookmark_count: Int?, - val category_data: List?, val category_master_id: String?, val content_more_details: List?, val description: String?, val duration: String?, - val gender_data: List?, val gender_master_id: String?, val id: Int?, var is_liked: Boolean?, val language_master_id: Int?, var likes_count: Int?, - val mark_as_favourite: Boolean?, + var mark_as_favourite: Boolean?, val release_date: String?, + val show_data_count: Any?, val thumbnail_path: String?, val title: String?, + val user_video_view: List?, val video_url: String?, - val views_count: Int? -) \ No newline at end of file + val views_count: Int?, + val age_range_data: List?, + val category_data: List?, + val gender_data: List? +){ + constructor(favKaraoke: FavKaraokeData): this( + favKaraoke.age_range_master_id, + favKaraoke.bookmark_category_ids, + favKaraoke.bookmark_count, + favKaraoke.category_master_id, + favKaraoke.content_more_details, + favKaraoke.description, + favKaraoke.duration, + favKaraoke.gender_master_id, + favKaraoke.id, + favKaraoke.is_liked, + favKaraoke.language_master_id, + favKaraoke.likes_count, + favKaraoke.mark_as_favourite, + favKaraoke.release_date, + null, + favKaraoke.thumbnail_path, + favKaraoke.title, + null, + favKaraoke.video_url, + favKaraoke.views_count, + null, + null, + null + ) + + constructor(continueKaraoke: ContinueKaraokeData): this( + continueKaraoke.age_range_master_id, + null, + continueKaraoke.bookmark_count, + continueKaraoke.category_master_id, + continueKaraoke.content_more_details, + continueKaraoke.description, + continueKaraoke.duration, + continueKaraoke.gender_master_id, + continueKaraoke.id, + continueKaraoke.is_liked, + continueKaraoke.language_master_id, + continueKaraoke.likes_count, + continueKaraoke.mark_as_favourite, + continueKaraoke.release_date, + continueKaraoke.show_data_count, + continueKaraoke.thumbnail_path, + continueKaraoke.title, + continueKaraoke.user_video_view, + continueKaraoke.video_url, + continueKaraoke.views_count, + null, + null, + null + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/karaoke/player/KaraokePlayerActivity.kt b/app/src/main/java/com/woka/karaoke/player/KaraokePlayerActivity.kt new file mode 100644 index 0000000..1357693 --- /dev/null +++ b/app/src/main/java/com/woka/karaoke/player/KaraokePlayerActivity.kt @@ -0,0 +1,84 @@ +package com.woka.karaoke.player + +import android.os.Bundle +import android.widget.ImageView +import android.widget.TextView +import androidx.activity.enableEdgeToEdge +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.media3.common.MediaItem +import androidx.media3.exoplayer.ExoPlayer +import com.woka.R +import com.woka.databinding.ActivityKaraokePlayerrBinding +import com.woka.utils.WokaBaseActivity + +class KaraokePlayerActivity : WokaBaseActivity() { + + companion object { + const val EXTRA_KARAOKE_DATA = "extra_karaoke_data" + } + + private lateinit var binding: ActivityKaraokePlayerrBinding + + private var karaokePlayerData: KaraokePlayerData? = null + + private var player: ExoPlayer? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + binding = ActivityKaraokePlayerrBinding.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 + } + + val windowInsetsController = + WindowCompat.getInsetsController(window, window.decorView) + windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()) + + karaokePlayerData = intent.getParcelableExtra(EXTRA_KARAOKE_DATA) + + player = ExoPlayer.Builder(this).build() + binding.playerView.player = player + + playVideo() + + initViews() + + clickEvents() + + } + + override fun onDestroy() { + super.onDestroy() + player?.stop() + player?.release() + } + + private fun initViews(){ + binding.apply { + playerView.findViewById(R.id.player_controller_title).text = karaokePlayerData?.title + } + } + + private fun clickEvents(){ + binding.apply { + playerView.findViewById(R.id.player_controller_close_btn).setOnClickListener { + onBackPressedDispatcher.onBackPressed() + } + } + } + + private fun playVideo() { + if (karaokePlayerData?.karaokeVideoUrl == null) return + + player?.setMediaItem(MediaItem.fromUri(karaokePlayerData?.karaokeVideoUrl!!)) + player?.prepare() + player?.play() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/karaoke/player/KaraokePlayerData.kt b/app/src/main/java/com/woka/karaoke/player/KaraokePlayerData.kt new file mode 100644 index 0000000..523685c --- /dev/null +++ b/app/src/main/java/com/woka/karaoke/player/KaraokePlayerData.kt @@ -0,0 +1,10 @@ +package com.woka.karaoke.player + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class KaraokePlayerData( + val karaokeVideoUrl: String, + val title: String? +): Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/woka/karaoke/views/KaraokeActivity.kt b/app/src/main/java/com/woka/karaoke/views/KaraokeActivity.kt new file mode 100644 index 0000000..96ceb4f --- /dev/null +++ b/app/src/main/java/com/woka/karaoke/views/KaraokeActivity.kt @@ -0,0 +1,361 @@ +package com.woka.karaoke.views + +import android.app.Dialog +import android.content.Intent +import android.content.res.ColorStateList +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.WindowManager +import androidx.activity.enableEdgeToEdge +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.recyclerview.widget.SimpleItemAnimator +import com.google.android.material.appbar.CollapsingToolbarLayout +import com.woka.R +import com.woka.WokaApp +import com.woka.databinding.ActivityKaraokeBinding +import com.woka.databinding.DialogModuleShowerBinding +import com.woka.karaoke.KaraokeRepository +import com.woka.karaoke.adapters.ContinueKaraokeAdapter +import com.woka.karaoke.adapters.KaraokeAdapter +import com.woka.karaoke.models.listing.KaraokeData +import com.woka.karaoke.player.KaraokePlayerActivity +import com.woka.karaoke.player.KaraokePlayerActivity.Companion.EXTRA_KARAOKE_DATA +import com.woka.karaoke.player.KaraokePlayerData +import com.woka.networking.ApiResult +import com.woka.utils.WokaBaseActivity +import com.woka.utils.hide +import com.woka.utils.show +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Locale + +class KaraokeActivity : WokaBaseActivity() { + + private lateinit var binding: ActivityKaraokeBinding + + // adapters + private lateinit var karaokeAdapter: KaraokeAdapter + private lateinit var continueKaraokeAdapter: ContinueKaraokeAdapter + + private lateinit var dialogBinding: DialogModuleShowerBinding + private lateinit var karaokeDialog: Dialog + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityKaraokeBinding.inflate(layoutInflater) + enableEdgeToEdge() + 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.apply { + navigationBarColor = getColor(R.color.color_primary_dark) + } + + karaokeAdapter = KaraokeAdapter(this, ::onKaraokeClicked, ::onKaraokeChanged) + continueKaraokeAdapter = ContinueKaraokeAdapter(this, ::onKaraokeClicked, ::onKaraokeChanged) + + dialogBinding = DialogModuleShowerBinding.inflate(layoutInflater) + karaokeDialog = Dialog(this) + karaokeDialog.setContentView(dialogBinding.root) + + initViews() + + initKaraokeDialog() + + clickEvents() + + setObservers() + + KaraokeRepository.loadKaraokeSongs() + } + + private fun initViews() { + binding.apply { + adjustTrailerImage() + + toolbar.title.text = getString(R.string.karaoke) + + rvKaraoke.adapter = karaokeAdapter + (rvKaraoke.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false + + rvContinueSing.adapter = continueKaraokeAdapter + (rvContinueSing.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false + } + } + + private fun initKaraokeDialog() { + try { + val back = ColorDrawable(Color.TRANSPARENT) + val inset = InsetDrawable(back, 50) + karaokeDialog.window!!.setBackgroundDrawable(inset) + } catch (e: Exception) { + // do nothing + } + + try { + val layoutParams = karaokeDialog.window!!.attributes + layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT + layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT + karaokeDialog.window!!.setAttributes(layoutParams) + } catch (e: Exception) { + // do nothing + } + + dialogBinding.close.setOnClickListener { karaokeDialog.dismiss() } + + dialogBinding.watchCard.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_mic, 0, 0, 0) + dialogBinding.watchCard.backgroundTintList = ColorStateList.valueOf(getColor(R.color.game_grad_one)) + dialogBinding.watchCard.text = getString(R.string.sing_now) + } + + private fun clickEvents() { + binding.apply { + toolbar.backBtn.setOnClickListener { + onBackPressedDispatcher.onBackPressed() + } + + retryBtn.setOnClickListener { + KaraokeRepository.loadKaraokeSongs() + } + } + } + + private fun loadTrailerData(karaokeData: KaraokeData) { + binding.apply { + trailerView.show() + adjustTrailerImage() + + karaokeData.thumbnail_path?.let { + trailerImage.loadImage(it) + } + + karaokeData.content_more_details?.let { moreDetailsList -> + trailerName.text = if (moreDetailsList.isNotEmpty()) { + if (WokaApp.userPrefs?.appLanguage == "hi" && moreDetailsList.size > 1) { + moreDetailsList[1]?.title + } else { + moreDetailsList[0]?.title + } + } else { + karaokeData.title + } + } + + trailerBtn.setOnClickListener { + onSingClicked(karaokeData) + } + } + } + + private fun onSingClicked(karaokeData: KaraokeData){ + karaokeData.video_url?.let { + startActivity(Intent(this@KaraokeActivity, KaraokePlayerActivity::class.java).apply { + putExtra(EXTRA_KARAOKE_DATA, KaraokePlayerData(it, karaokeData.title)) + }) + } + } + + private fun adjustTrailerImage() { + // making space for Trailer image + binding.apply { + topPinnedView.post { + val imgParams = trailerImage.layoutParams as CollapsingToolbarLayout.LayoutParams + imgParams.setMargins(0, 0, 0, topPinnedView.height) + trailerImage.layoutParams = imgParams + } + } + } + + private fun showKaraokeDialog(karaokeData: KaraokeData) { + dialogBinding.apply { + karaokeData.content_more_details?.let { moreDetailsList -> + + karaokeData.thumbnail_path?.let { + image.loadImage(it) + } + + fav.isSelected = karaokeData.mark_as_favourite == true + like.isSelected = karaokeData.is_liked == true + likeCount.text = "${karaokeData.likes_count}" + + year.text = try { + karaokeData.release_date?.let { + val cal = Calendar.getInstance() + cal.time = + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).parse( + karaokeData.release_date + )!! + "${cal.get(Calendar.YEAR)}" + } ?: throw Exception() + } catch (e: Exception) { + "${karaokeData.release_date}" + } + + if (moreDetailsList.isNotEmpty()) { + + if (WokaApp.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 = karaokeData.title + description.text = Html.fromHtml( + karaokeData.description?.replace( + "
", + " " + ), Html.FROM_HTML_MODE_LEGACY + ) + } + + watchCard.setOnClickListener { + onSingClicked(karaokeData) + } + + like.setOnClickListener { + KaraokeRepository.likeUnLikeSong( + "${karaokeData.id}", + !like.isSelected + ) + + karaokeData.id?.let { + onKaraokeChanged(it, false) + onKaraokeChanged(it, true) + } + like.isSelected = !like.isSelected + likeCount.text = "${karaokeData.likes_count}" + } + + fav.setOnClickListener { + KaraokeRepository.updateFavShow( + karaokeData, + !fav.isSelected + ) + + karaokeData.id?.let { + onKaraokeChanged(it, false) + onKaraokeChanged(it, true) + } + + fav.isSelected = !fav.isSelected + } + + close.setOnClickListener { + karaokeDialog.dismiss() + } + + karaokeDialog.show() + } + } + } + + private fun onKaraokeChanged(id: Int, isFromContinue: Boolean) { + if (isFromContinue){ + // updating karaoke list + val position = karaokeAdapter.currentList.indexOfFirst { it.id == id } + if (position >= 0 && position < karaokeAdapter.currentList.size) { + karaokeAdapter.notifyItemChanged(position) + } + }else{ + // updating continue karaoke list + val continuePos = continueKaraokeAdapter.currentList.indexOfFirst { it.id == id } + if (continuePos >= 0 && continuePos < continueKaraokeAdapter.currentList.size) { + continueKaraokeAdapter.notifyItemChanged(continuePos) + } + } + } + + private fun onKaraokeClicked(karaokeData: KaraokeData) { + loadTrailerData(karaokeData) + showKaraokeDialog(karaokeData) + } + + private fun setObservers() { + KaraokeRepository.karaokeLiveData.observe(this) { + when (it) { + is ApiResult.Error -> { + binding.shimmer.hide() + binding.rvKaraoke.hide() + binding.singTxt.hide() + binding.trailerView.hide() + + binding.errorView.show() + } + + is ApiResult.Loading -> { + binding.shimmer.show() + + binding.rvKaraoke.hide() + binding.singTxt.hide() + binding.trailerView.hide() + binding.errorView.hide() + } + + is ApiResult.Success -> { + it.data?.karaoke_data?.filterNotNull()?.let { audioBookData -> + if (audioBookData.isNotEmpty()) { + binding.shimmer.hide() + binding.errorView.hide() + + KaraokeRepository.loadContinueKaraoke() + + loadTrailerData(audioBookData[0]) + binding.rvKaraoke.show() + binding.singTxt.show() + + karaokeAdapter.submitList(audioBookData) + } + } + } + } + } + + KaraokeRepository.continueKaraokeLiveData.observe(this) { + when (it) { + is ApiResult.Error -> { + binding.continueSingTxt.hide() + binding.rvContinueSing.hide() + } + + is ApiResult.Loading -> {} + is ApiResult.Success -> { + it.data?.result?.filterNotNull()?.let {continueData -> + if (continueData.isNotEmpty()) { + binding.continueSingTxt.show() + binding.rvContinueSing.show() + + continueKaraokeAdapter.submitList(continueData) + } else { + binding.continueSingTxt.hide() + binding.rvContinueSing.hide() + } + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/userPreference/UserPreference.kt b/app/src/main/java/com/woka/userPreference/UserPreference.kt index b31717a..fd714a9 100644 --- a/app/src/main/java/com/woka/userPreference/UserPreference.kt +++ b/app/src/main/java/com/woka/userPreference/UserPreference.kt @@ -11,6 +11,7 @@ import androidx.lifecycle.MutableLiveData import com.woka.audiobooks.AudioBookRepository import com.woka.home.models.Theme import com.woka.home.mylist.MyListRepository +import com.woka.karaoke.KaraokeRepository import com.woka.networking.ApiResult import com.woka.onboard.views.OnboardActivity import com.woka.userdata.UserRepository @@ -117,5 +118,6 @@ class UserPreference(val context: Context) { WebSeriesRepository.clearData() MyListRepository.clearData() AudioBookRepository.clearData() + KaraokeRepository.clearData() } } \ No newline at end of file diff --git a/app/src/main/java/com/woka/userdata/UserActionApiService.kt b/app/src/main/java/com/woka/userdata/UserActionApiService.kt index 0ff1fcf..f2674bf 100644 --- a/app/src/main/java/com/woka/userdata/UserActionApiService.kt +++ b/app/src/main/java/com/woka/userdata/UserActionApiService.kt @@ -1,6 +1,7 @@ package com.woka.userdata import com.woka.audiobooks.models.continuedata.ContinueAudioResponse +import com.woka.karaoke.models.continuesing.ContinueKaraokeResponse import com.woka.networking.ApiResponse import com.woka.webseries.models.ContinueEpisodeResponse import okhttp3.FormBody @@ -27,4 +28,7 @@ interface UserActionApiService { @POST("continue_watching") suspend fun continueAudioBookListing(@Body body: FormBody): Response> + + @POST("continue_watching") + suspend fun continueKaraokeListing(@Body body: FormBody): Response> } \ No newline at end of file diff --git a/app/src/main/res/drawable/gradient_karaoke.xml b/app/src/main/res/drawable/gradient_karaoke.xml new file mode 100644 index 0000000..ee489cf --- /dev/null +++ b/app/src/main/res/drawable/gradient_karaoke.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_mic.xml b/app/src/main/res/drawable/ic_mic.xml new file mode 100644 index 0000000..bd90ce0 --- /dev/null +++ b/app/src/main/res/drawable/ic_mic.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/activity_karaoke.xml b/app/src/main/res/layout/activity_karaoke.xml new file mode 100644 index 0000000..1f8ff9f --- /dev/null +++ b/app/src/main/res/layout/activity_karaoke.xml @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +