mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-25 02:14:32 +01:00
Dependencies Handling at Lower Level.
This commit is contained in:
parent
c58f73be1d
commit
04b6f13b22
@ -36,6 +36,7 @@ import androidx.navigation.findNavController
|
|||||||
import com.github.javiersantos.appupdater.AppUpdater
|
import com.github.javiersantos.appupdater.AppUpdater
|
||||||
import com.github.javiersantos.appupdater.enums.UpdateFrom
|
import com.github.javiersantos.appupdater.enums.UpdateFrom
|
||||||
import com.shabinder.spotiflyer.databinding.MainActivityBinding
|
import com.shabinder.spotiflyer.databinding.MainActivityBinding
|
||||||
|
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
|
||||||
import com.shabinder.spotiflyer.networking.SpotifyService
|
import com.shabinder.spotiflyer.networking.SpotifyService
|
||||||
import com.shabinder.spotiflyer.networking.SpotifyServiceTokenRequest
|
import com.shabinder.spotiflyer.networking.SpotifyServiceTokenRequest
|
||||||
import com.shabinder.spotiflyer.utils.*
|
import com.shabinder.spotiflyer.utils.*
|
||||||
@ -57,9 +58,9 @@ import javax.inject.Inject
|
|||||||
class MainActivity : AppCompatActivity(){
|
class MainActivity : AppCompatActivity(){
|
||||||
private var spotifyService : SpotifyService? = null
|
private var spotifyService : SpotifyService? = null
|
||||||
private lateinit var binding: MainActivityBinding
|
private lateinit var binding: MainActivityBinding
|
||||||
lateinit var snackBarAnchor: View
|
|
||||||
private lateinit var sharedViewModel: SharedViewModel
|
private lateinit var sharedViewModel: SharedViewModel
|
||||||
private lateinit var navController: NavController
|
lateinit var snackBarAnchor: View
|
||||||
|
lateinit var navController: NavController
|
||||||
@Inject lateinit var moshi: Moshi
|
@Inject lateinit var moshi: Moshi
|
||||||
@Inject lateinit var spotifyServiceTokenRequest: SpotifyServiceTokenRequest
|
@Inject lateinit var spotifyServiceTokenRequest: SpotifyServiceTokenRequest
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ class MainActivity : AppCompatActivity(){
|
|||||||
sharedViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
|
sharedViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
|
||||||
navController = findNavController(R.id.navHostFragment)
|
navController = findNavController(R.id.navHostFragment)
|
||||||
snackBarAnchor = binding.snackBarPosition
|
snackBarAnchor = binding.snackBarPosition
|
||||||
|
DownloadHelper.youtubeMusicApi = sharedViewModel.youtubeMusicApi
|
||||||
|
|
||||||
authenticateSpotify()
|
authenticateSpotify()
|
||||||
|
|
||||||
@ -80,7 +82,6 @@ class MainActivity : AppCompatActivity(){
|
|||||||
checkIfLatestVersion()
|
checkIfLatestVersion()
|
||||||
createDirectories()
|
createDirectories()
|
||||||
Log.i("Connection Status", isOnline().toString())
|
Log.i("Connection Status", isOnline().toString())
|
||||||
|
|
||||||
//starting Notification and Downloader Service!
|
//starting Notification and Downloader Service!
|
||||||
startService(this)
|
startService(this)
|
||||||
|
|
||||||
|
@ -17,14 +17,18 @@
|
|||||||
|
|
||||||
package com.shabinder.spotiflyer
|
package com.shabinder.spotiflyer
|
||||||
|
|
||||||
|
import androidx.hilt.lifecycle.ViewModelInject
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.shabinder.spotiflyer.networking.SpotifyService
|
import com.shabinder.spotiflyer.networking.SpotifyService
|
||||||
|
import com.shabinder.spotiflyer.networking.YoutubeMusicApi
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
|
||||||
class SharedViewModel : ViewModel() {
|
class SharedViewModel @ViewModelInject constructor(
|
||||||
|
val youtubeMusicApi: YoutubeMusicApi
|
||||||
|
) : ViewModel() {
|
||||||
var intentString = MutableLiveData<String>()
|
var intentString = MutableLiveData<String>()
|
||||||
var spotifyService = MutableLiveData<SpotifyService>()
|
var spotifyService = MutableLiveData<SpotifyService>()
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package com.shabinder.spotiflyer.recyclerView
|
package com.shabinder.spotiflyer.recyclerView
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -46,6 +47,7 @@ class TrackListAdapter(private val viewModel :TrackListViewModel): ListAdapter<T
|
|||||||
return ViewHolder(binding)
|
return ViewHolder(binding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val item = getItem(position)
|
val item = getItem(position)
|
||||||
if(itemCount == 1){ holder.binding.imageUrl.visibility = View.GONE}else{
|
if(itemCount == 1){ holder.binding.imageUrl.visibility = View.GONE}else{
|
||||||
@ -100,8 +102,8 @@ class TrackListAdapter(private val viewModel :TrackListViewModel): ListAdapter<T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.binding.trackName.text = "${if(item.title.length > 17){"${item.title.subSequence(0,16)}..."}else{item.title}}"
|
holder.binding.trackName.text = if(item.title.length > 20){"${item.title.subSequence(0,18)}..."}else{item.title}
|
||||||
holder.binding.artist.text = "${item.artists.get(0)}..."
|
holder.binding.artist.text = "${item.artists.firstOrNull()}..."
|
||||||
holder.binding.duration.text = "${item.durationSec/60} minutes, ${item.durationSec%60} sec"
|
holder.binding.duration.text = "${item.durationSec/60} minutes, ${item.durationSec%60} sec"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,25 +24,18 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
|
||||||
import com.shabinder.spotiflyer.SharedViewModel
|
|
||||||
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
|
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
|
||||||
import com.shabinder.spotiflyer.models.DownloadStatus
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
import com.shabinder.spotiflyer.models.spotify.Source
|
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.recyclerView.TrackListAdapter
|
||||||
import com.shabinder.spotiflyer.utils.*
|
import com.shabinder.spotiflyer.utils.*
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class GaanaFragment : TrackListFragment<GaanaViewModel,GaanaFragmentArgs>() {
|
class GaanaFragment : TrackListFragment<GaanaViewModel,GaanaFragmentArgs>() {
|
||||||
|
|
||||||
@Inject lateinit var youtubeMusicApi: YoutubeMusicApi
|
|
||||||
@Inject lateinit var gaanaInterface: GaanaInterface
|
|
||||||
override lateinit var viewModel: GaanaViewModel
|
override lateinit var viewModel: GaanaViewModel
|
||||||
override lateinit var adapter: TrackListAdapter
|
override lateinit var adapter: TrackListAdapter
|
||||||
override var source: Source = Source.Gaana
|
override var source: Source = Source.Gaana
|
||||||
@ -53,8 +46,8 @@ class GaanaFragment : TrackListFragment<GaanaViewModel,GaanaFragmentArgs>() {
|
|||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
super.onCreateView(inflater, container, savedInstanceState)
|
super.onCreateView(inflater, container, savedInstanceState)
|
||||||
|
viewModel = ViewModelProvider(this).get(GaanaViewModel::class.java)
|
||||||
initializeAll()
|
adapter = TrackListAdapter(viewModel)
|
||||||
|
|
||||||
val gaanaLink = GaanaFragmentArgs.fromBundle(requireArguments()).link.substringAfter("gaana.com/")
|
val gaanaLink = GaanaFragmentArgs.fromBundle(requireArguments()).link.substringAfter("gaana.com/")
|
||||||
//Link Schema: https://gaana.com/type/link
|
//Link Schema: https://gaana.com/type/link
|
||||||
@ -112,21 +105,4 @@ class GaanaFragment : TrackListFragment<GaanaViewModel,GaanaFragmentArgs>() {
|
|||||||
}
|
}
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Basic Initialization
|
|
||||||
**/
|
|
||||||
private fun initializeAll() {
|
|
||||||
sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java)
|
|
||||||
viewModel = ViewModelProvider(this).get(GaanaViewModel::class.java)
|
|
||||||
viewModel.gaanaInterface = gaanaInterface
|
|
||||||
adapter = TrackListAdapter(viewModel)
|
|
||||||
DownloadHelper.youtubeMusicApi = youtubeMusicApi
|
|
||||||
DownloadHelper.sharedViewModel = sharedViewModel
|
|
||||||
DownloadHelper.statusBar = binding.statusBar
|
|
||||||
binding.trackList.adapter = adapter
|
|
||||||
(binding.trackList.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -18,13 +18,12 @@
|
|||||||
package com.shabinder.spotiflyer.ui.gaana
|
package com.shabinder.spotiflyer.ui.gaana
|
||||||
|
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.util.Log
|
|
||||||
import androidx.hilt.lifecycle.ViewModelInject
|
import androidx.hilt.lifecycle.ViewModelInject
|
||||||
import com.shabinder.spotiflyer.database.DatabaseDAO
|
import com.shabinder.spotiflyer.database.DatabaseDAO
|
||||||
import com.shabinder.spotiflyer.database.DownloadRecord
|
import com.shabinder.spotiflyer.database.DownloadRecord
|
||||||
import com.shabinder.spotiflyer.models.DownloadStatus
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
import com.shabinder.spotiflyer.models.TrackDetails
|
import com.shabinder.spotiflyer.models.TrackDetails
|
||||||
import com.shabinder.spotiflyer.models.gaana.*
|
import com.shabinder.spotiflyer.models.gaana.GaanaTrack
|
||||||
import com.shabinder.spotiflyer.models.spotify.Source
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
import com.shabinder.spotiflyer.networking.GaanaInterface
|
import com.shabinder.spotiflyer.networking.GaanaInterface
|
||||||
import com.shabinder.spotiflyer.utils.Provider
|
import com.shabinder.spotiflyer.utils.Provider
|
||||||
@ -35,18 +34,20 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : TrackListViewModel(){
|
class GaanaViewModel @ViewModelInject constructor(
|
||||||
|
val databaseDAO: DatabaseDAO,
|
||||||
|
val gaanaInterface : GaanaInterface
|
||||||
|
) : TrackListViewModel(){
|
||||||
|
|
||||||
override var folderType:String = ""
|
override var folderType:String = ""
|
||||||
override var subFolder:String = ""
|
override var subFolder:String = ""
|
||||||
var gaanaInterface : GaanaInterface? = null
|
private val gaanaPlaceholderImageUrl = "https://a10.gaanacdn.com/images/social/gaana_social.jpg"
|
||||||
val gaanaPlaceholderImageUrl = "https://a10.gaanacdn.com/images/social/gaana_social.jpg"
|
|
||||||
|
|
||||||
fun gaanaSearch(type:String,link:String){
|
fun gaanaSearch(type:String,link:String){
|
||||||
when(type){
|
when(type){
|
||||||
"song" -> {
|
"song" -> {
|
||||||
uiScope.launch {
|
uiScope.launch {
|
||||||
getGaanaSong(link)?.tracks?.firstOrNull()?.also {
|
gaanaInterface.getGaanaSong(seokey = link).value?.tracks?.firstOrNull()?.also {
|
||||||
folderType = "Tracks"
|
folderType = "Tracks"
|
||||||
if(File(finalOutputDir(it.track_title,folderType,subFolder)).exists()){//Download Already Present!!
|
if(File(finalOutputDir(it.track_title,folderType,subFolder)).exists()){//Download Already Present!!
|
||||||
it.downloaded = DownloadStatus.Downloaded
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
@ -72,7 +73,7 @@ class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO)
|
|||||||
}
|
}
|
||||||
"album" -> {
|
"album" -> {
|
||||||
uiScope.launch {
|
uiScope.launch {
|
||||||
getGaanaAlbum(link)?.also {
|
gaanaInterface.getGaanaAlbum(seokey = link).value?.also {
|
||||||
folderType = "Albums"
|
folderType = "Albums"
|
||||||
subFolder = link
|
subFolder = link
|
||||||
it.tracks.forEach { track ->
|
it.tracks.forEach { track ->
|
||||||
@ -99,7 +100,7 @@ class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO)
|
|||||||
}
|
}
|
||||||
"playlist" -> {
|
"playlist" -> {
|
||||||
uiScope.launch {
|
uiScope.launch {
|
||||||
getGaanaPlaylist(link)?.also {
|
gaanaInterface.getGaanaPlaylist(seokey = link).value?.also {
|
||||||
folderType = "Playlists"
|
folderType = "Playlists"
|
||||||
subFolder = link
|
subFolder = link
|
||||||
it.tracks.forEach {track ->
|
it.tracks.forEach {track ->
|
||||||
@ -129,11 +130,11 @@ class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO)
|
|||||||
uiScope.launch {
|
uiScope.launch {
|
||||||
folderType = "Artist"
|
folderType = "Artist"
|
||||||
subFolder = link
|
subFolder = link
|
||||||
val artistDetails = getGaanaArtistDetails(link)?.artist?.firstOrNull()?.also {
|
val artistDetails = gaanaInterface.getGaanaArtistDetails(seokey = link).value?.artist?.firstOrNull()?.also {
|
||||||
title.value = it.name
|
title.value = it.name
|
||||||
coverUrl.value = it.artworkLink
|
coverUrl.value = it.artworkLink
|
||||||
}
|
}
|
||||||
getGaanaArtistTracks(link)?.also {
|
gaanaInterface.getGaanaArtistTracks(seokey = link).value?.also {
|
||||||
it.tracks.forEach {track ->
|
it.tracks.forEach {track ->
|
||||||
if(File(finalOutputDir(track.track_title,folderType,subFolder)).exists()){//Download Already Present!!
|
if(File(finalOutputDir(track.track_title,folderType,subFolder)).exists()){//Download Already Present!!
|
||||||
track.downloaded = DownloadStatus.Downloaded
|
track.downloaded = DownloadStatus.Downloaded
|
||||||
@ -175,25 +176,4 @@ class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO)
|
|||||||
albumArtURL = it.artworkLink
|
albumArtURL = it.artworkLink
|
||||||
)
|
)
|
||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
|
|
||||||
private suspend fun getGaanaSong(songLink:String): GaanaSong?{
|
|
||||||
Log.i("Requesting","https://gaana.com/song/$songLink")
|
|
||||||
return gaanaInterface?.getGaanaSong(seokey = songLink)?.value
|
|
||||||
}
|
|
||||||
private suspend fun getGaanaAlbum(albumLink:String): GaanaAlbum?{
|
|
||||||
Log.i("Requesting","https://gaana.com/album/$albumLink")
|
|
||||||
return gaanaInterface?.getGaanaAlbum(seokey = albumLink)?.value
|
|
||||||
}
|
|
||||||
private suspend fun getGaanaPlaylist(link:String): GaanaPlaylist?{
|
|
||||||
Log.i("Requesting","https://gaana.com/playlist/$link")
|
|
||||||
return gaanaInterface?.getGaanaPlaylist(seokey = link)?.value
|
|
||||||
}
|
|
||||||
private suspend fun getGaanaArtistDetails(link:String): GaanaArtistDetails?{
|
|
||||||
Log.i("Requesting","https://gaana.com/artist/$link")
|
|
||||||
return gaanaInterface?.getGaanaArtistDetails(seokey = link)?.value
|
|
||||||
}
|
|
||||||
private suspend fun getGaanaArtistTracks(link:String,limit:Int = 50): GaanaArtistTracks?{
|
|
||||||
Log.i("Requesting","Tracks of: https://gaana.com/artist/$link")
|
|
||||||
return gaanaInterface?.getGaanaArtistTracks(seokey = link,limit = limit)?.value
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -25,23 +25,19 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
|
||||||
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
|
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
|
||||||
import com.shabinder.spotiflyer.models.DownloadStatus
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
import com.shabinder.spotiflyer.models.spotify.Source
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
import com.shabinder.spotiflyer.networking.YoutubeMusicApi
|
|
||||||
import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
|
import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
|
||||||
import com.shabinder.spotiflyer.utils.*
|
import com.shabinder.spotiflyer.utils.*
|
||||||
import com.shabinder.spotiflyer.utils.Provider.mainActivity
|
import com.shabinder.spotiflyer.utils.Provider.mainActivity
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SpotifyFragment : TrackListFragment<SpotifyViewModel,SpotifyFragmentArgs>() {
|
class SpotifyFragment : TrackListFragment<SpotifyViewModel,SpotifyFragmentArgs>() {
|
||||||
|
|
||||||
@Inject lateinit var youtubeMusicApi: YoutubeMusicApi
|
|
||||||
override lateinit var viewModel: SpotifyViewModel
|
override lateinit var viewModel: SpotifyViewModel
|
||||||
override lateinit var adapter: TrackListAdapter
|
override lateinit var adapter: TrackListAdapter
|
||||||
override var source: Source = Source.Spotify
|
override var source: Source = Source.Spotify
|
||||||
@ -132,10 +128,5 @@ class SpotifyFragment : TrackListFragment<SpotifyViewModel,SpotifyFragmentArgs>(
|
|||||||
sharedViewModel.spotifyService.observe(viewLifecycleOwner, {
|
sharedViewModel.spotifyService.observe(viewLifecycleOwner, {
|
||||||
this.viewModel.spotifyService = it
|
this.viewModel.spotifyService = it
|
||||||
})
|
})
|
||||||
DownloadHelper.youtubeMusicApi = youtubeMusicApi
|
|
||||||
DownloadHelper.sharedViewModel = sharedViewModel
|
|
||||||
DownloadHelper.statusBar = binding.statusBar
|
|
||||||
binding.trackList.adapter = adapter
|
|
||||||
(binding.trackList.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,7 +24,10 @@ import com.shabinder.spotiflyer.database.DatabaseDAO
|
|||||||
import com.shabinder.spotiflyer.database.DownloadRecord
|
import com.shabinder.spotiflyer.database.DownloadRecord
|
||||||
import com.shabinder.spotiflyer.models.DownloadStatus
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
import com.shabinder.spotiflyer.models.TrackDetails
|
import com.shabinder.spotiflyer.models.TrackDetails
|
||||||
import com.shabinder.spotiflyer.models.spotify.*
|
import com.shabinder.spotiflyer.models.spotify.Album
|
||||||
|
import com.shabinder.spotiflyer.models.spotify.Image
|
||||||
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
|
import com.shabinder.spotiflyer.models.spotify.Track
|
||||||
import com.shabinder.spotiflyer.networking.SpotifyService
|
import com.shabinder.spotiflyer.networking.SpotifyService
|
||||||
import com.shabinder.spotiflyer.utils.Provider
|
import com.shabinder.spotiflyer.utils.Provider
|
||||||
import com.shabinder.spotiflyer.utils.TrackListViewModel
|
import com.shabinder.spotiflyer.utils.TrackListViewModel
|
||||||
@ -34,7 +37,9 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : TrackListViewModel(){
|
class SpotifyViewModel @ViewModelInject constructor(
|
||||||
|
val databaseDAO: DatabaseDAO,
|
||||||
|
) : TrackListViewModel(){
|
||||||
|
|
||||||
override var folderType:String = ""
|
override var folderType:String = ""
|
||||||
override var subFolder:String = ""
|
override var subFolder:String = ""
|
||||||
@ -42,19 +47,28 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
var spotifyService : SpotifyService? = null
|
var spotifyService : SpotifyService? = null
|
||||||
|
|
||||||
fun spotifySearch(type:String,link: String){
|
fun spotifySearch(type:String,link: String){
|
||||||
|
uiScope.launch {
|
||||||
when (type) {
|
when (type) {
|
||||||
"track" -> {
|
"track" -> {
|
||||||
uiScope.launch {
|
spotifyService?.getTrack(link)?.value?.also {
|
||||||
getTrackDetails(link)?.also {
|
|
||||||
folderType = "Tracks"
|
folderType = "Tracks"
|
||||||
if(File(finalOutputDir(it.name,folderType,subFolder)).exists()){//Download Already Present!!
|
if (File(
|
||||||
|
finalOutputDir(
|
||||||
|
it.name,
|
||||||
|
folderType,
|
||||||
|
subFolder
|
||||||
|
)
|
||||||
|
).exists()
|
||||||
|
) {//Download Already Present!!
|
||||||
it.downloaded = DownloadStatus.Downloaded
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
}
|
}
|
||||||
trackList.value = listOf(it).toTrackDetailsList()
|
trackList.value = listOf(it).toTrackDetailsList()
|
||||||
title.value = it.name
|
title.value = it.name
|
||||||
coverUrl.value = it.album!!.images?.elementAtOrNull(1)?.url ?: it.album!!.images?.elementAtOrNull(0)?.url
|
coverUrl.value = it.album!!.images?.elementAtOrNull(1)?.url
|
||||||
|
?: it.album!!.images?.elementAtOrNull(0)?.url
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
databaseDAO.insert(DownloadRecord(
|
databaseDAO.insert(
|
||||||
|
DownloadRecord(
|
||||||
type = "Track",
|
type = "Track",
|
||||||
name = title.value!!,
|
name = title.value!!,
|
||||||
link = "https://open.spotify.com/$type/$link",
|
link = "https://open.spotify.com/$type/$link",
|
||||||
@ -62,50 +76,76 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
totalFiles = 1,
|
totalFiles = 1,
|
||||||
downloaded = it.downloaded == DownloadStatus.Downloaded,
|
downloaded = it.downloaded == DownloadStatus.Downloaded,
|
||||||
directory = finalOutputDir(it.name, folderType, subFolder)
|
directory = finalOutputDir(it.name, folderType, subFolder)
|
||||||
))
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"album" -> {
|
"album" -> {
|
||||||
uiScope.launch {
|
val albumObject = spotifyService?.getAlbum(link)?.value
|
||||||
val albumObject = getAlbumDetails(link)
|
|
||||||
folderType = "Albums"
|
folderType = "Albums"
|
||||||
subFolder = albumObject?.name.toString()
|
subFolder = albumObject?.name.toString()
|
||||||
albumObject?.tracks?.items?.forEach {
|
albumObject?.tracks?.items?.forEach {
|
||||||
if(File(finalOutputDir(it.name!!,folderType,subFolder)).exists()){//Download Already Present!!
|
if (File(
|
||||||
|
finalOutputDir(
|
||||||
|
it.name!!,
|
||||||
|
folderType,
|
||||||
|
subFolder
|
||||||
|
)
|
||||||
|
).exists()
|
||||||
|
) {//Download Already Present!!
|
||||||
it.downloaded = DownloadStatus.Downloaded
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
}
|
}
|
||||||
it.album = Album(images = listOf(Image(url = albumObject.images?.elementAtOrNull(1)?.url ?: albumObject.images?.elementAtOrNull(0)?.url )))
|
it.album = Album(
|
||||||
|
images = listOf(
|
||||||
|
Image(
|
||||||
|
url = albumObject.images?.elementAtOrNull(1)?.url
|
||||||
|
?: albumObject.images?.elementAtOrNull(0)?.url
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
trackList.value = albumObject?.tracks?.items?.toTrackDetailsList()
|
trackList.value = albumObject?.tracks?.items?.toTrackDetailsList()
|
||||||
title.value = albumObject?.name
|
title.value = albumObject?.name
|
||||||
coverUrl.value = albumObject?.images?.elementAtOrNull(1)?.url ?: albumObject?.images?.elementAtOrNull(0)?.url
|
coverUrl.value = albumObject?.images?.elementAtOrNull(1)?.url
|
||||||
|
?: albumObject?.images?.elementAtOrNull(0)?.url
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
databaseDAO.insert(DownloadRecord(
|
databaseDAO.insert(
|
||||||
|
DownloadRecord(
|
||||||
type = "Album",
|
type = "Album",
|
||||||
name = title.value!!,
|
name = title.value!!,
|
||||||
link = "https://open.spotify.com/$type/$link",
|
link = "https://open.spotify.com/$type/$link",
|
||||||
coverUrl = coverUrl.value.toString(),
|
coverUrl = coverUrl.value.toString(),
|
||||||
totalFiles = trackList.value?.size ?: 0,
|
totalFiles = trackList.value?.size ?: 0,
|
||||||
downloaded = File(finalOutputDir(type = folderType,subFolder = subFolder)).listFiles()?.size == trackList.value?.size,
|
downloaded = File(
|
||||||
|
finalOutputDir(
|
||||||
|
type = folderType,
|
||||||
|
subFolder = subFolder
|
||||||
|
)
|
||||||
|
).listFiles()?.size == trackList.value?.size,
|
||||||
directory = finalOutputDir(type = folderType, subFolder = subFolder)
|
directory = finalOutputDir(type = folderType, subFolder = subFolder)
|
||||||
))
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"playlist" -> {
|
"playlist" -> {
|
||||||
uiScope.launch {
|
val playlistObject = spotifyService?.getPlaylist(link)?.value
|
||||||
val playlistObject = getPlaylistDetails(link)
|
|
||||||
folderType = "Playlists"
|
folderType = "Playlists"
|
||||||
subFolder = playlistObject?.name.toString()
|
subFolder = playlistObject?.name.toString()
|
||||||
val tempTrackList = mutableListOf<Track>()
|
val tempTrackList = mutableListOf<Track>()
|
||||||
Log.i("Tracks Fetched", playlistObject?.tracks?.items?.size.toString())
|
Log.i("Tracks Fetched", playlistObject?.tracks?.items?.size.toString())
|
||||||
playlistObject?.tracks?.items?.forEach {
|
playlistObject?.tracks?.items?.forEach {
|
||||||
it.track?.let {
|
it.track?.let { it1 ->
|
||||||
it1 -> if(File(finalOutputDir(it1.name!!,folderType,subFolder)).exists()){//Download Already Present!!
|
if (File(
|
||||||
|
finalOutputDir(
|
||||||
|
it1.name!!,
|
||||||
|
folderType,
|
||||||
|
subFolder
|
||||||
|
)
|
||||||
|
).exists()
|
||||||
|
) {//Download Already Present!!
|
||||||
it1.downloaded = DownloadStatus.Downloaded
|
it1.downloaded = DownloadStatus.Downloaded
|
||||||
}
|
}
|
||||||
tempTrackList.add(it1)
|
tempTrackList.add(it1)
|
||||||
@ -115,7 +155,7 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
|
|
||||||
while (moreTracksAvailable) {
|
while (moreTracksAvailable) {
|
||||||
//Check For More Tracks If available
|
//Check For More Tracks If available
|
||||||
val moreTracks = getPlaylistTrackDetails(link,offset = tempTrackList.size)
|
val moreTracks = spotifyService?.getPlaylistTracks(link, offset = tempTrackList.size)?.value
|
||||||
moreTracks?.items?.forEach {
|
moreTracks?.items?.forEach {
|
||||||
it.track?.let { it1 -> tempTrackList.add(it1) }
|
it.track?.let { it1 -> tempTrackList.add(it1) }
|
||||||
}
|
}
|
||||||
@ -124,18 +164,25 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
Log.i("Total Tracks Fetched", tempTrackList.size.toString())
|
Log.i("Total Tracks Fetched", tempTrackList.size.toString())
|
||||||
trackList.value = tempTrackList.toTrackDetailsList()
|
trackList.value = tempTrackList.toTrackDetailsList()
|
||||||
title.value = playlistObject?.name
|
title.value = playlistObject?.name
|
||||||
coverUrl.value = playlistObject?.images?.elementAtOrNull(1)?.url ?: playlistObject?.images?.firstOrNull()?.url.toString()
|
coverUrl.value = playlistObject?.images?.elementAtOrNull(1)?.url
|
||||||
|
?: playlistObject?.images?.firstOrNull()?.url.toString()
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
databaseDAO.insert(DownloadRecord(
|
databaseDAO.insert(
|
||||||
|
DownloadRecord(
|
||||||
type = "Playlist",
|
type = "Playlist",
|
||||||
name = title.value.toString(),
|
name = title.value.toString(),
|
||||||
link = "https://open.spotify.com/$type/$link",
|
link = "https://open.spotify.com/$type/$link",
|
||||||
coverUrl = coverUrl.value.toString(),
|
coverUrl = coverUrl.value.toString(),
|
||||||
totalFiles = tempTrackList.size,
|
totalFiles = tempTrackList.size,
|
||||||
downloaded = File(finalOutputDir(type = folderType,subFolder = subFolder)).listFiles()?.size == tempTrackList.size,
|
downloaded = File(
|
||||||
|
finalOutputDir(
|
||||||
|
type = folderType,
|
||||||
|
subFolder = subFolder
|
||||||
|
)
|
||||||
|
).listFiles()?.size == tempTrackList.size,
|
||||||
directory = finalOutputDir(type = folderType, subFolder = subFolder)
|
directory = finalOutputDir(type = folderType, subFolder = subFolder)
|
||||||
))
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"episode" -> {//TODO
|
"episode" -> {//TODO
|
||||||
@ -144,6 +191,7 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
private fun List<Track>.toTrackDetailsList() = this.map {
|
private fun List<Track>.toTrackDetailsList() = this.map {
|
||||||
@ -163,21 +211,4 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
albumArtURL = it.album?.images?.elementAtOrNull(1)?.url ?: it.album?.images?.firstOrNull()?.url.toString()
|
albumArtURL = it.album?.images?.elementAtOrNull(1)?.url ?: it.album?.images?.firstOrNull()?.url.toString()
|
||||||
)
|
)
|
||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
|
|
||||||
private suspend fun getTrackDetails(trackLink:String): Track?{
|
|
||||||
Log.i("Requesting","https://api.spotify.com/v1/tracks/$trackLink")
|
|
||||||
return spotifyService?.getTrack(trackLink)?.value
|
|
||||||
}
|
|
||||||
private suspend fun getAlbumDetails(albumLink:String): Album?{
|
|
||||||
Log.i("Requesting","https://api.spotify.com/v1/albums/$albumLink")
|
|
||||||
return spotifyService?.getAlbum(albumLink)?.value
|
|
||||||
}
|
|
||||||
private suspend fun getPlaylistDetails(link:String): Playlist?{
|
|
||||||
Log.i("Requesting","https://api.spotify.com/v1/playlists/$link")
|
|
||||||
return spotifyService?.getPlaylist(link)?.value
|
|
||||||
}
|
|
||||||
private suspend fun getPlaylistTrackDetails(link:String,offset:Int = 0,limit:Int = 100): PagingObjectPlaylistTrack?{
|
|
||||||
Log.i("Requesting","https://api.spotify.com/v1/playlists/$link/tracks?offset=$offset&limit=$limit")
|
|
||||||
return spotifyService?.getPlaylistTracks(link, offset, limit)?.value
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -23,7 +23,6 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import com.github.kiulian.downloader.YoutubeDownloader
|
|
||||||
import com.shabinder.spotiflyer.downloadHelper.YTDownloadHelper
|
import com.shabinder.spotiflyer.downloadHelper.YTDownloadHelper
|
||||||
import com.shabinder.spotiflyer.models.DownloadStatus
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
import com.shabinder.spotiflyer.models.spotify.Source
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
@ -32,7 +31,6 @@ import com.shabinder.spotiflyer.utils.*
|
|||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
private const val sampleDomain2 = "youtu.be"
|
private const val sampleDomain2 = "youtu.be"
|
||||||
private const val sampleDomain1 = "youtube.com"
|
private const val sampleDomain1 = "youtube.com"
|
||||||
@ -40,7 +38,6 @@ private const val sampleDomain1 = "youtube.com"
|
|||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class YoutubeFragment : TrackListFragment<YoutubeViewModel,YoutubeFragmentArgs>() {
|
class YoutubeFragment : TrackListFragment<YoutubeViewModel,YoutubeFragmentArgs>() {
|
||||||
|
|
||||||
@Inject lateinit var ytDownloader: YoutubeDownloader
|
|
||||||
override lateinit var viewModel: YoutubeViewModel
|
override lateinit var viewModel: YoutubeViewModel
|
||||||
override lateinit var adapter : TrackListAdapter
|
override lateinit var adapter : TrackListAdapter
|
||||||
override var source: Source = Source.YouTube
|
override var source: Source = Source.YouTube
|
||||||
@ -53,7 +50,6 @@ class YoutubeFragment : TrackListFragment<YoutubeViewModel,YoutubeFragmentArgs>(
|
|||||||
super.onCreateView(inflater, container, savedInstanceState)
|
super.onCreateView(inflater, container, savedInstanceState)
|
||||||
this.viewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java)
|
this.viewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java)
|
||||||
adapter = TrackListAdapter(this.viewModel)
|
adapter = TrackListAdapter(this.viewModel)
|
||||||
binding.trackList.adapter = adapter
|
|
||||||
|
|
||||||
val args = YoutubeFragmentArgs.fromBundle(requireArguments())
|
val args = YoutubeFragmentArgs.fromBundle(requireArguments())
|
||||||
val link = args.link
|
val link = args.link
|
||||||
@ -66,7 +62,7 @@ class YoutubeFragment : TrackListFragment<YoutubeViewModel,YoutubeFragmentArgs>(
|
|||||||
if(link.contains("playlist",true) || link.contains("list",true)){
|
if(link.contains("playlist",true) || link.contains("list",true)){
|
||||||
// Given Link is of a Playlist
|
// Given Link is of a Playlist
|
||||||
val playlistId = link.substringAfter("?list=").substringAfter("&list=").substringBefore("&")
|
val playlistId = link.substringAfter("?list=").substringAfter("&list=").substringBefore("&")
|
||||||
this.viewModel.getYTPlaylist(playlistId,ytDownloader)
|
this.viewModel.getYTPlaylist(playlistId)
|
||||||
}else{//Given Link is of a Video
|
}else{//Given Link is of a Video
|
||||||
var searchId = "error"
|
var searchId = "error"
|
||||||
if(link.contains(sampleDomain1,true) ){
|
if(link.contains(sampleDomain1,true) ){
|
||||||
@ -76,7 +72,7 @@ class YoutubeFragment : TrackListFragment<YoutubeViewModel,YoutubeFragmentArgs>(
|
|||||||
searchId = link.substringAfterLast("/","error")
|
searchId = link.substringAfterLast("/","error")
|
||||||
}
|
}
|
||||||
if(searchId != "error") {
|
if(searchId != "error") {
|
||||||
this.viewModel.getYTTrack(searchId,ytDownloader)
|
this.viewModel.getYTTrack(searchId)
|
||||||
}else{showMessage("Your Youtube Link is not of a Video!!")}
|
}else{showMessage("Your Youtube Link is not of a Video!!")}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,10 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : TrackListViewModel(){
|
class YoutubeViewModel @ViewModelInject constructor(
|
||||||
|
val databaseDAO: DatabaseDAO,
|
||||||
|
val ytDownloader: YoutubeDownloader
|
||||||
|
) : TrackListViewModel(){
|
||||||
/*
|
/*
|
||||||
* YT Album Art Schema
|
* YT Album Art Schema
|
||||||
* HI-RES Url: https://i.ytimg.com/vi/$searchId/maxresdefault.jpg"
|
* HI-RES Url: https://i.ytimg.com/vi/$searchId/maxresdefault.jpg"
|
||||||
@ -44,7 +47,7 @@ class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
override var folderType = "YT_Downloads"
|
override var folderType = "YT_Downloads"
|
||||||
override var subFolder = ""
|
override var subFolder = ""
|
||||||
|
|
||||||
fun getYTPlaylist(searchId:String, ytDownloader:YoutubeDownloader){
|
fun getYTPlaylist(searchId:String){
|
||||||
if(!isOnline())return
|
if(!isOnline())return
|
||||||
try{
|
try{
|
||||||
uiScope.launch(Dispatchers.IO) {
|
uiScope.launch(Dispatchers.IO) {
|
||||||
@ -102,7 +105,7 @@ class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
fun getYTTrack(searchId:String, ytDownloader:YoutubeDownloader) {
|
fun getYTTrack(searchId:String) {
|
||||||
if(!isOnline())return
|
if(!isOnline())return
|
||||||
try{
|
try{
|
||||||
uiScope.launch(Dispatchers.IO) {
|
uiScope.launch(Dispatchers.IO) {
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
|
|
||||||
package com.shabinder.spotiflyer.utils
|
package com.shabinder.spotiflyer.utils
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.Protocol
|
import okhttp3.Protocol
|
||||||
import okhttp3.RequestBody
|
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||||
|
|
||||||
@ -27,13 +27,14 @@ const val NoInternetErrorCode = 222
|
|||||||
|
|
||||||
class NetworkInterceptor: Interceptor {
|
class NetworkInterceptor: Interceptor {
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
Log.i("Network Requesting",chain.request().url.toString())
|
||||||
return if (!isOnline()){
|
return if (!isOnline()){
|
||||||
//No Internet Connection
|
//No Internet Connection
|
||||||
showNoConnectionAlert()
|
showNoConnectionAlert()
|
||||||
//Lets Stop the Incoming Request
|
//Lets Stop the Incoming Request
|
||||||
Response.Builder()
|
Response.Builder()
|
||||||
.code(NoInternetErrorCode) // code(200.300) = successful else = unsuccessful
|
.code(NoInternetErrorCode) // code(200.300) = successful else = unsuccessful
|
||||||
.body("{}".toResponseBody(null)) // Whatever body
|
.body("{}".toResponseBody(null)) // Empty Object
|
||||||
.protocol(Protocol.HTTP_2)
|
.protocol(Protocol.HTTP_2)
|
||||||
.message("No Internet Connection")
|
.message("No Internet Connection")
|
||||||
.request(chain.request())
|
.request(chain.request())
|
||||||
@ -52,15 +53,7 @@ class NetworkInterceptor: Interceptor {
|
|||||||
.message(response.message)
|
.message(response.message)
|
||||||
.request(chain.request())
|
.request(chain.request())
|
||||||
.build()
|
.build()
|
||||||
|
// chain.proceed(chain.request())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* Converts REQUEST's Body to String
|
|
||||||
* */
|
|
||||||
private fun RequestBody?.bodyToString(): String {
|
|
||||||
if (this == null) return ""
|
|
||||||
val buffer = okio.Buffer()
|
|
||||||
writeTo(buffer)
|
|
||||||
return buffer.readUtf8()
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -49,6 +49,11 @@ import javax.inject.Singleton
|
|||||||
@Module
|
@Module
|
||||||
object Provider {
|
object Provider {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mainActivity Instance to use whereEver Needed , as Its God Activity.
|
||||||
|
* (i.e, Active Through out App' Lifecycle )
|
||||||
|
* */
|
||||||
|
|
||||||
val mainActivity: MainActivity = MainActivity.getInstance()
|
val mainActivity: MainActivity = MainActivity.getInstance()
|
||||||
val defaultDir = Environment.DIRECTORY_MUSIC + File.separator + "SpotiFlyer" + File.separator
|
val defaultDir = Environment.DIRECTORY_MUSIC + File.separator + "SpotiFlyer" + File.separator
|
||||||
|
|
||||||
|
@ -29,9 +29,11 @@ import android.view.ViewGroup
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.navigation.NavArgs
|
import androidx.navigation.NavArgs
|
||||||
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||||
import com.shabinder.spotiflyer.R
|
import com.shabinder.spotiflyer.R
|
||||||
import com.shabinder.spotiflyer.SharedViewModel
|
import com.shabinder.spotiflyer.SharedViewModel
|
||||||
import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding
|
import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding
|
||||||
|
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
|
||||||
import com.shabinder.spotiflyer.models.DownloadStatus
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
import com.shabinder.spotiflyer.models.TrackDetails
|
import com.shabinder.spotiflyer.models.TrackDetails
|
||||||
import com.shabinder.spotiflyer.models.spotify.Source
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
@ -53,7 +55,7 @@ abstract class TrackListFragment<VM : TrackListViewModel , args: NavArgs> : Frag
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if(!isOnline()){
|
if(!isOnline()){
|
||||||
showNoConnectionAlert()
|
showNoConnectionAlert()
|
||||||
mainActivity.onBackPressed()
|
mainActivity.navController.popBackStack()
|
||||||
}
|
}
|
||||||
sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java)
|
sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java)
|
||||||
}
|
}
|
||||||
@ -64,11 +66,20 @@ abstract class TrackListFragment<VM : TrackListViewModel , args: NavArgs> : Frag
|
|||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = TrackListFragmentBinding.inflate(inflater,container,false)
|
binding = TrackListFragmentBinding.inflate(inflater,container,false)
|
||||||
|
initializeAll()
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initializeAll() {
|
||||||
|
DownloadHelper.youtubeMusicApi = sharedViewModel.youtubeMusicApi
|
||||||
|
DownloadHelper.sharedViewModel = sharedViewModel
|
||||||
|
DownloadHelper.statusBar = binding.statusBar
|
||||||
|
(binding.trackList.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
binding.trackList.adapter = adapter
|
||||||
initializeLiveDataObservers()
|
initializeLiveDataObservers()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +141,6 @@ abstract class TrackListFragment<VM : TrackListViewModel , args: NavArgs> : Frag
|
|||||||
super.onPause()
|
super.onPause()
|
||||||
requireActivity().unregisterReceiver(updateUIReceiver)
|
requireActivity().unregisterReceiver(updateUIReceiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIfAllDownloaded() {
|
private fun checkIfAllDownloaded() {
|
||||||
if(!viewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){
|
if(!viewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){
|
||||||
//All Tracks Downloaded
|
//All Tracks Downloaded
|
||||||
@ -142,5 +152,5 @@ abstract class TrackListFragment<VM : TrackListViewModel , args: NavArgs> : Frag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
open fun applicationContext(): Context = requireActivity().applicationContext
|
||||||
}
|
}
|
@ -116,19 +116,19 @@
|
|||||||
app:layout_constraintBottom_toTopOf="@+id/cover_image"
|
app:layout_constraintBottom_toTopOf="@+id/cover_image"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title_view"
|
android:id="@+id/title_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:layout_marginBottom="22dp"
|
|
||||||
android:background="#00000000"
|
android:background="#00000000"
|
||||||
android:fontFamily="@font/raleway_semibold"
|
android:fontFamily="@font/raleway_semibold"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:text='"Loading..."'
|
android:text='"Loading..."'
|
||||||
android:textAlignment="viewEnd"
|
android:textAlignment="viewEnd"
|
||||||
android:textColor="#9AB3FF"
|
android:textColor="#9AB3FF"
|
||||||
android:textSize="28sp"
|
android:textSize="26sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
|
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
|
||||||
android:textColor="#9AB3FF"
|
android:textColor="#9AB3FF"
|
||||||
android:textSize="20sp"
|
android:textSize="18sp"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
||||||
app:layout_constraintStart_toStartOf="@+id/artist"
|
app:layout_constraintStart_toStartOf="@+id/artist"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
Loading…
Reference in New Issue
Block a user