From f86972595370398c72fbace6236b5d5b14691bfc Mon Sep 17 00:00:00 2001 From: Shabinder Date: Mon, 9 Nov 2020 23:53:22 +0530 Subject: [PATCH] Fragment Code Clean , and Unification --- .../com/shabinder/spotiflyer/MainActivity.kt | 10 +- .../downloadHelper/DownloadHelper.kt | 2 +- .../spotiflyer/ui/gaana/GaanaFragment.kt | 120 ++------------ .../spotiflyer/ui/spotify/SpotifyFragment.kt | 110 ++----------- .../spotiflyer/ui/youtube/YoutubeFragment.kt | 109 +------------ .../spotiflyer/utils/BaseFragment.kt | 148 ++++++++++++++++++ .../spotiflyer/utils/BaseViewModel.kt | 1 + .../com/shabinder/spotiflyer/utils/Utils.kt | 18 ++- build.gradle | 2 +- 9 files changed, 208 insertions(+), 312 deletions(-) create mode 100644 app/src/main/java/com/shabinder/spotiflyer/utils/BaseFragment.kt diff --git a/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt b/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt index 2e96f354..9ffe9cfc 100755 --- a/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt @@ -69,12 +69,12 @@ class MainActivity : AppCompatActivity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) binding = DataBindingUtil.setContentView(this, R.layout.main_activity) sharedViewModel = ViewModelProvider(this).get(SharedViewModel::class.java) navController = findNavController(R.id.navHostFragment) snackBarAnchor = binding.snackBarPosition //Enabling Dark Mode - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) authenticateSpotify() @@ -145,10 +145,10 @@ class MainActivity : AppCompatActivity(){ }).addInterceptor(NetworkInterceptor()) val retrofit = Retrofit.Builder() - .baseUrl("https://api.spotify.com/v1/") - .client(httpClient.build()) - .addConverterFactory(MoshiConverterFactory.create(moshi)) - .build() + .baseUrl("https://api.spotify.com/v1/") + .client(httpClient.build()) + .addConverterFactory(MoshiConverterFactory.create(moshi)) + .build() spotifyService = retrofit.create(SpotifyService::class.java) sharedViewModel.spotifyService.value = spotifyService diff --git a/app/src/main/java/com/shabinder/spotiflyer/downloadHelper/DownloadHelper.kt b/app/src/main/java/com/shabinder/spotiflyer/downloadHelper/DownloadHelper.kt index d764162f..78c73484 100755 --- a/app/src/main/java/com/shabinder/spotiflyer/downloadHelper/DownloadHelper.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/downloadHelper/DownloadHelper.kt @@ -76,7 +76,7 @@ object DownloadHelper { //Delay is Added ,if a request is in processing it may finish Log.i("Spotify Helper","Download Request Sent") sharedViewModel?.uiScope?.launch (Dispatchers.Main){ - Toast.makeText(mainActivity,"Download Started, Now You can leave the App!", Toast.LENGTH_SHORT).show() + showMessage("Download Started, Now You can leave the App!") } startService(mainActivity,downloadList) },5000) diff --git a/app/src/main/java/com/shabinder/spotiflyer/ui/gaana/GaanaFragment.kt b/app/src/main/java/com/shabinder/spotiflyer/ui/gaana/GaanaFragment.kt index 05cc9159..b407c4f9 100644 --- a/app/src/main/java/com/shabinder/spotiflyer/ui/gaana/GaanaFragment.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/ui/gaana/GaanaFragment.kt @@ -17,55 +17,38 @@ package com.shabinder.spotiflyer.ui.gaana -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.SimpleItemAnimator -import com.shabinder.spotiflyer.R import com.shabinder.spotiflyer.SharedViewModel -import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding import com.shabinder.spotiflyer.downloadHelper.DownloadHelper import com.shabinder.spotiflyer.models.DownloadStatus -import com.shabinder.spotiflyer.models.TrackDetails import com.shabinder.spotiflyer.models.spotify.Source -import com.shabinder.spotiflyer.networking.GaanaInterface -import com.shabinder.spotiflyer.networking.YoutubeMusicApi import com.shabinder.spotiflyer.recyclerView.TrackListAdapter import com.shabinder.spotiflyer.utils.* -import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import javax.inject.Inject -@AndroidEntryPoint -class GaanaFragment : Fragment() { +class GaanaFragment : BaseFragment() { + + override lateinit var baseViewModel: BaseViewModel + override lateinit var adapter: TrackListAdapter + override var source: Source = Source.Gaana + private val viewModel:GaanaViewModel + get() = baseViewModel as GaanaViewModel - private lateinit var binding: TrackListFragmentBinding - private lateinit var sharedViewModel: SharedViewModel - @Inject lateinit var youtubeMusicApi: YoutubeMusicApi - private lateinit var viewModel: GaanaViewModel - private lateinit var adapter: TrackListAdapter - @Inject lateinit var gaanaInterface: GaanaInterface - private var intentFilter: IntentFilter? = null - private var updateUIReceiver: BroadcastReceiver? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - binding = DataBindingUtil.inflate(inflater,R.layout.track_list_fragment, container, false) + super.onCreateView(inflater, container, savedInstanceState) + initializeAll() - initializeLiveDataObservers() - initializeBroadcast() val gaanaLink = GaanaFragmentArgs.fromBundle(requireArguments()).link.substringAfter("gaana.com/") //Link Schema: https://gaana.com/type/link @@ -92,16 +75,16 @@ class GaanaFragment : Fragment() { binding.downloadingFab.visibility = View.VISIBLE rotateAnim(binding.downloadingFab) - for (track in viewModel.trackList.value!!){ + for (track in baseViewModel.trackList.value!!){ if(track.downloaded != DownloadStatus.Downloaded){ track.downloaded = DownloadStatus.Downloading - adapter.notifyItemChanged(viewModel.trackList.value!!.indexOf(track)) + adapter.notifyItemChanged(baseViewModel.trackList.value!!.indexOf(track)) } } showMessage("Processing!") sharedViewModel.uiScope.launch(Dispatchers.Default){ val urlList = arrayListOf() - viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) } + baseViewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) } //Appending Source urlList.add("gaana") loadAllImages( @@ -109,19 +92,18 @@ class GaanaFragment : Fragment() { urlList ) } - viewModel.uiScope.launch { - val finalList = viewModel.trackList.value + baseViewModel.uiScope.launch { + val finalList = baseViewModel.trackList.value if(finalList.isNullOrEmpty())showMessage("Not Downloading Any Song") DownloadHelper.downloadAllTracks( - viewModel.folderType, - viewModel.subFolder, + baseViewModel.folderType, + baseViewModel.subFolder, finalList ?: listOf(), ) } } } } - return binding.root } @@ -130,7 +112,7 @@ class GaanaFragment : Fragment() { **/ private fun initializeAll() { sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java) - viewModel = ViewModelProvider(this).get(GaanaViewModel::class.java) + baseViewModel = ViewModelProvider(this).get(GaanaViewModel::class.java) viewModel.gaanaInterface = gaanaInterface adapter = TrackListAdapter(viewModel) DownloadHelper.youtubeMusicApi = youtubeMusicApi @@ -140,73 +122,5 @@ class GaanaFragment : Fragment() { (binding.trackList.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false } - /** - *Live Data Observers - **/ - private fun initializeLiveDataObservers() { - viewModel.trackList.observe(viewLifecycleOwner, { - if (it.isNotEmpty()){ - Log.i("GaanaFragment","TrackList Updated") - adapter.submitList(it,Source.Gaana) - checkIfAllDownloaded() - } - }) - viewModel.coverUrl.observe(viewLifecycleOwner, { - if(it!="Loading") bindImage(binding.coverImage,it, Source.Gaana) - }) - - viewModel.title.observe(viewLifecycleOwner, { - binding.titleView.text = it - }) - } - - private fun checkIfAllDownloaded() { - if(!viewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){ - //All Tracks Downloaded - binding.btnDownloadAll.visibility = View.GONE - binding.downloadingFab.apply{ - setImageResource(R.drawable.ic_tick) - visibility = View.VISIBLE - clearAnimation() - } - } - } - private fun initializeBroadcast() { - intentFilter = IntentFilter() - intentFilter?.addAction("track_download_completed") - - updateUIReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - //UI update here - if (intent != null){ - val trackDetails = intent.getParcelableExtra("track") - trackDetails?.let { - val position: Int = viewModel.trackList.value?.map { it.title }?.indexOf(trackDetails.title) ?: -1 - Log.i("Track","Download Completed Intent :$position") - if(position != -1) { - val track = viewModel.trackList.value?.get(position) - track?.let{ - it.downloaded = DownloadStatus.Downloaded - viewModel.trackList.value?.set(position, it) - adapter.notifyItemChanged(position) - checkIfAllDownloaded() - } - } - } - } - } - } - requireActivity().registerReceiver(updateUIReceiver, intentFilter) - } - - override fun onResume() { - super.onResume() - initializeBroadcast() - } - - override fun onPause() { - super.onPause() - requireActivity().unregisterReceiver(updateUIReceiver) - } } \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/ui/spotify/SpotifyFragment.kt b/app/src/main/java/com/shabinder/spotiflyer/ui/spotify/SpotifyFragment.kt index 9390196a..093fc854 100755 --- a/app/src/main/java/com/shabinder/spotiflyer/ui/spotify/SpotifyFragment.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/ui/spotify/SpotifyFragment.kt @@ -18,47 +18,31 @@ package com.shabinder.spotiflyer.ui.spotify import android.annotation.SuppressLint -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.SimpleItemAnimator import com.shabinder.spotiflyer.MainActivity -import com.shabinder.spotiflyer.R -import com.shabinder.spotiflyer.SharedViewModel -import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding import com.shabinder.spotiflyer.downloadHelper.DownloadHelper import com.shabinder.spotiflyer.models.DownloadStatus -import com.shabinder.spotiflyer.models.TrackDetails import com.shabinder.spotiflyer.models.spotify.Source -import com.shabinder.spotiflyer.networking.YoutubeMusicApi import com.shabinder.spotiflyer.recyclerView.TrackListAdapter import com.shabinder.spotiflyer.utils.* import com.shabinder.spotiflyer.utils.Provider.mainActivity -import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import javax.inject.Inject @Suppress("DEPRECATION") +class SpotifyFragment : BaseFragment() { -@AndroidEntryPoint -class SpotifyFragment : Fragment() { - private lateinit var binding:TrackListFragmentBinding - private lateinit var sharedViewModel: SharedViewModel - @Inject lateinit var youtubeMusicApi: YoutubeMusicApi - private lateinit var viewModel: SpotifyViewModel - private lateinit var adapter:TrackListAdapter - private var intentFilter:IntentFilter? = null - private var updateUIReceiver: BroadcastReceiver? = null + override lateinit var baseViewModel: BaseViewModel + override lateinit var adapter: TrackListAdapter + override var source: Source = Source.Spotify + private val viewModel: SpotifyViewModel + get() = baseViewModel as SpotifyViewModel @SuppressLint("SetJavaScriptEnabled") @@ -66,13 +50,11 @@ class SpotifyFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - binding = DataBindingUtil.inflate(inflater,R.layout.track_list_fragment,container,false) + super.onCreateView(inflater, container, savedInstanceState) initializeAll() - initializeLiveDataObservers() - initializeBroadcast() val spotifyLink = SpotifyFragmentArgs.fromBundle(requireArguments()).link.substringAfter("open.spotify.com/") - + val link = spotifyLink.substringAfterLast('/', "Error").substringBefore('?') val type = spotifyLink.substringBeforeLast('/', "Error").substringAfterLast('/') @@ -142,87 +124,15 @@ class SpotifyFragment : Fragment() { * Basic Initialization **/ private fun initializeAll() { - sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java) - viewModel = ViewModelProvider(this).get(SpotifyViewModel::class.java) + baseViewModel = ViewModelProvider(this).get(SpotifyViewModel::class.java) + adapter = TrackListAdapter(viewModel) sharedViewModel.spotifyService.observe(viewLifecycleOwner, { viewModel.spotifyService = it }) - adapter = TrackListAdapter(viewModel) DownloadHelper.youtubeMusicApi = youtubeMusicApi DownloadHelper.sharedViewModel = sharedViewModel DownloadHelper.statusBar = binding.statusBar binding.trackList.adapter = adapter (binding.trackList.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false } - - - /** - *Live Data Observers - **/ - private fun initializeLiveDataObservers() { - viewModel.trackList.observe(viewLifecycleOwner, { - if (it.isNotEmpty()){ - Log.i("SpotifyFragment","TrackList Updated") - adapter.submitList(it,Source.Spotify) - checkIfAllDownloaded() - } - }) - - viewModel.coverUrl.observe(viewLifecycleOwner, { - if(it!="Loading") bindImage(binding.coverImage,it, Source.Spotify) - }) - - viewModel.title.observe(viewLifecycleOwner, { - binding.titleView.text = it - }) - } - - private fun checkIfAllDownloaded() { - if(!viewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){ - //All Tracks Downloaded - binding.btnDownloadAll.visibility = View.GONE - binding.downloadingFab.apply{ - setImageResource(R.drawable.ic_tick) - visibility = View.VISIBLE - clearAnimation() - } - } - } - private fun initializeBroadcast() { - intentFilter = IntentFilter() - intentFilter?.addAction("track_download_completed") - - updateUIReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - //UI update here - if (intent != null){ - val trackDetails = intent.getParcelableExtra("track") - trackDetails?.let { - val position: Int = viewModel.trackList.value?.map { it.title }?.indexOf(trackDetails.title) ?: -1 - Log.i("Track","Download Completed Intent :$position") - if(position != -1) { - val track = viewModel.trackList.value?.get(position) - track?.let{ - it.downloaded = DownloadStatus.Downloaded - viewModel.trackList.value?.set(position, it) - adapter.notifyItemChanged(position) - checkIfAllDownloaded() - } - } - } - } - } - } - requireActivity().registerReceiver(updateUIReceiver, intentFilter) - } - - override fun onResume() { - super.onResume() - initializeBroadcast() - } - - override fun onPause() { - super.onPause() - requireActivity().unregisterReceiver(updateUIReceiver) - } } \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/ui/youtube/YoutubeFragment.kt b/app/src/main/java/com/shabinder/spotiflyer/ui/youtube/YoutubeFragment.kt index bb8e261c..1a9baa08 100755 --- a/app/src/main/java/com/shabinder/spotiflyer/ui/youtube/YoutubeFragment.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/ui/youtube/YoutubeFragment.kt @@ -17,43 +17,26 @@ package com.shabinder.spotiflyer.ui.youtube -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider -import com.github.kiulian.downloader.YoutubeDownloader -import com.shabinder.spotiflyer.R -import com.shabinder.spotiflyer.SharedViewModel -import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding import com.shabinder.spotiflyer.downloadHelper.YTDownloadHelper import com.shabinder.spotiflyer.models.DownloadStatus -import com.shabinder.spotiflyer.models.TrackDetails import com.shabinder.spotiflyer.models.spotify.Source import com.shabinder.spotiflyer.recyclerView.TrackListAdapter import com.shabinder.spotiflyer.utils.* -import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import javax.inject.Inject -@AndroidEntryPoint -class YoutubeFragment : Fragment() { +class YoutubeFragment : BaseFragment() { - private lateinit var binding: TrackListFragmentBinding - private lateinit var viewModel: YoutubeViewModel - private lateinit var sharedViewModel: SharedViewModel - @Inject lateinit var ytDownloader: YoutubeDownloader - private lateinit var adapter : TrackListAdapter - private var intentFilter: IntentFilter? = null - private var updateUIReceiver: BroadcastReceiver? = null + override lateinit var baseViewModel: BaseViewModel + override lateinit var adapter : TrackListAdapter + override var source: Source = Source.YouTube + private val viewModel: YoutubeViewModel + get() = baseViewModel as YoutubeViewModel private val sampleDomain2 = "youtu.be" private val sampleDomain1 = "youtube.com" @@ -61,15 +44,11 @@ class YoutubeFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - binding = DataBindingUtil.inflate(inflater,R.layout.track_list_fragment,container,false) - viewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java) - sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java) + super.onCreateView(inflater, container, savedInstanceState) + baseViewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java) adapter = TrackListAdapter(viewModel) binding.trackList.adapter = adapter - initializeLiveDataObservers() - initializeBroadcast() - val args = YoutubeFragmentArgs.fromBundle(requireArguments()) val link = args.link youtubeSearch(link) @@ -135,76 +114,4 @@ class YoutubeFragment : Fragment() { } } } - override fun onResume() { - super.onResume() - initializeBroadcast() - } - - private fun initializeBroadcast() { - intentFilter = IntentFilter() - intentFilter?.addAction("track_download_completed") - - updateUIReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - //UI update here - if (intent != null){ - val trackDetails = intent.getParcelableExtra("track") - trackDetails?.let { - val position: Int = viewModel.trackList.value?.map { it.title }?.indexOf(trackDetails.title) ?: -1 - Log.i("Track","Download Completed Intent :$position") - if(position != -1) { - val track = viewModel.trackList.value?.get(position) - track?.let{ - it.downloaded = DownloadStatus.Downloaded - viewModel.trackList.value?.set(position, it) - adapter.notifyItemChanged(position) - checkIfAllDownloaded() - } - } - } - } - } - } - requireActivity().registerReceiver(updateUIReceiver, intentFilter) - } - - override fun onPause() { - super.onPause() - requireActivity().unregisterReceiver(updateUIReceiver) - } - - private fun checkIfAllDownloaded() { - if(!viewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){ - //All Tracks Downloaded - binding.btnDownloadAll.visibility = View.GONE - binding.downloadingFab.apply{ - setImageResource(R.drawable.ic_tick) - visibility = View.VISIBLE - clearAnimation() - } - } - } - private fun initializeLiveDataObservers() { - /** - * CoverUrl Binding Observer! - **/ - viewModel.coverUrl.observe(viewLifecycleOwner, { - if(it!="Loading") bindImage(binding.coverImage,it, Source.YouTube) - }) - - /** - * TrackList Binding Observer! - **/ - viewModel.trackList.observe(viewLifecycleOwner, { - adapter.submitList(it,Source.YouTube) - }) - - /** - * Title Binding Observer! - **/ - viewModel.title.observe(viewLifecycleOwner, { - binding.titleView.text = it - }) - - } } diff --git a/app/src/main/java/com/shabinder/spotiflyer/utils/BaseFragment.kt b/app/src/main/java/com/shabinder/spotiflyer/utils/BaseFragment.kt new file mode 100644 index 00000000..b9695857 --- /dev/null +++ b/app/src/main/java/com/shabinder/spotiflyer/utils/BaseFragment.kt @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2020 Shabinder Singh + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.shabinder.spotiflyer.utils + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import com.github.kiulian.downloader.YoutubeDownloader +import com.shabinder.spotiflyer.R +import com.shabinder.spotiflyer.SharedViewModel +import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding +import com.shabinder.spotiflyer.models.DownloadStatus +import com.shabinder.spotiflyer.models.TrackDetails +import com.shabinder.spotiflyer.models.spotify.Source +import com.shabinder.spotiflyer.networking.GaanaInterface +import com.shabinder.spotiflyer.networking.YoutubeMusicApi +import com.shabinder.spotiflyer.recyclerView.TrackListAdapter +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject + +@AndroidEntryPoint +abstract class BaseFragment : Fragment() { + + @Inject open lateinit var youtubeMusicApi: YoutubeMusicApi + @Inject open lateinit var ytDownloader: YoutubeDownloader + @Inject open lateinit var gaanaInterface: GaanaInterface + open lateinit var sharedViewModel: SharedViewModel + open lateinit var binding: TrackListFragmentBinding + abstract var baseViewModel: BaseViewModel + abstract var adapter: TrackListAdapter + abstract var source: Source + private var intentFilter: IntentFilter? = null + private var updateUIReceiver: BroadcastReceiver? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = DataBindingUtil.inflate(inflater,R.layout.track_list_fragment, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initializeLiveDataObservers() + } + /** + *Live Data Observers + **/ + open fun initializeLiveDataObservers() { + baseViewModel.trackList.observe(viewLifecycleOwner, { + if (it.isNotEmpty()){ + Log.i("GaanaFragment","TrackList Updated") + adapter.submitList(it, source) + checkIfAllDownloaded() + } + }) + + baseViewModel.coverUrl.observe(viewLifecycleOwner, { + if(it!="Loading") bindImage(binding.coverImage,it, source) + }) + + baseViewModel.title.observe(viewLifecycleOwner, { + binding.titleView.text = it + }) + } + + open fun initializeBroadcast() { + intentFilter = IntentFilter() + intentFilter?.addAction("track_download_completed") + + updateUIReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + //UI update here + if (intent != null){ + val trackDetails = intent.getParcelableExtra("track") + trackDetails?.let { + val position: Int = baseViewModel.trackList.value?.map { it.title }?.indexOf(trackDetails.title) ?: -1 + Log.i("Track","Download Completed Intent :$position") + if(position != -1) { + val track = baseViewModel.trackList.value?.get(position) + track?.let{ + it.downloaded = DownloadStatus.Downloaded + baseViewModel.trackList.value?.set(position, it) + adapter.notifyItemChanged(position) + checkIfAllDownloaded() + } + } + } + } + } + } + requireActivity().registerReceiver(updateUIReceiver, intentFilter) + } + + override fun onResume() { + super.onResume() + initializeBroadcast() + } + + override fun onPause() { + super.onPause() + requireActivity().unregisterReceiver(updateUIReceiver) + } + + open fun checkIfAllDownloaded() { + if(!baseViewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){ + //All Tracks Downloaded + binding.btnDownloadAll.visibility = View.GONE + binding.downloadingFab.apply{ + setImageResource(R.drawable.ic_tick) + visibility = View.VISIBLE + clearAnimation() + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/utils/BaseViewModel.kt b/app/src/main/java/com/shabinder/spotiflyer/utils/BaseViewModel.kt index e0f88fce..c70a2223 100644 --- a/app/src/main/java/com/shabinder/spotiflyer/utils/BaseViewModel.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/utils/BaseViewModel.kt @@ -29,6 +29,7 @@ abstract class BaseViewModel:ViewModel() { abstract var folderType:String abstract var subFolder:String open val trackList = MutableLiveData>() + private val viewModelJob:CompletableJob = Job() open val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob) diff --git a/app/src/main/java/com/shabinder/spotiflyer/utils/Utils.kt b/app/src/main/java/com/shabinder/spotiflyer/utils/Utils.kt index 0bd93d70..887fb227 100755 --- a/app/src/main/java/com/shabinder/spotiflyer/utils/Utils.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/utils/Utils.kt @@ -280,4 +280,20 @@ fun createDirectories() { } fun getEmojiByUnicode(unicode: Int): String? { return String(Character.toChars(unicode)) -} \ No newline at end of file +} + +/* +internal val nullOnEmptyConverterFactory = object : Converter.Factory() { + fun converterFactory() = this + override fun responseBodyConverter( + type: Type, + annotations: Array, + retrofit: Retrofit + ) = object : Converter { + val nextResponseBodyConverter = + retrofit.nextResponseBodyConverter(converterFactory(), type, annotations) + + override fun convert(value: ResponseBody) = + if (value.contentLength() != 0L) nextResponseBodyConverter.convert(value) else null + } +}*/ diff --git a/build.gradle b/build.gradle index ea0f8eaa..0c91bfef 100755 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ buildscript { ext{ kotlin_version = "1.4.10" navigationVersion = '2.3.0' - ext.hilt_version = '2.28-alpha' + ext.hilt_version = '2.29.1-alpha' } repositories { google()