mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-25 02:14:32 +01:00
Set Up base TrackListFragmentBaseClass and TrackListViewModelBase
This commit is contained in:
parent
f869725953
commit
b3b2e6ed51
@ -16,6 +16,7 @@
|
|||||||
<w>instagram</w>
|
<w>instagram</w>
|
||||||
<w>jetbrains</w>
|
<w>jetbrains</w>
|
||||||
<w>kotlinx</w>
|
<w>kotlinx</w>
|
||||||
|
<w>linkedin</w>
|
||||||
<w>mainfragment</w>
|
<w>mainfragment</w>
|
||||||
<w>maxresdefault</w>
|
<w>maxresdefault</w>
|
||||||
<w>moshi</w>
|
<w>moshi</w>
|
||||||
|
@ -28,7 +28,8 @@ android {
|
|||||||
buildToolsVersion "30.0.2"
|
buildToolsVersion "30.0.2"
|
||||||
|
|
||||||
buildFeatures{
|
buildFeatures{
|
||||||
dataBinding = true
|
//dataBinding = true
|
||||||
|
viewBinding = true
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
@ -30,7 +30,6 @@ import android.util.Log
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.databinding.DataBindingUtil
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
@ -69,12 +68,13 @@ class MainActivity : AppCompatActivity(){
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
//Enabling Dark Mode
|
||||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||||
binding = DataBindingUtil.setContentView(this, R.layout.main_activity)
|
binding = MainActivityBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
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
|
||||||
//Enabling Dark Mode
|
|
||||||
|
|
||||||
authenticateSpotify()
|
authenticateSpotify()
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ import com.shabinder.spotiflyer.models.spotify.Source
|
|||||||
import com.shabinder.spotiflyer.utils.*
|
import com.shabinder.spotiflyer.utils.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class TrackListAdapter(private val viewModel :BaseViewModel): ListAdapter<TrackDetails, TrackListAdapter.ViewHolder>(TrackDiffCallback()) {
|
class TrackListAdapter(private val viewModel :TrackListViewModel): ListAdapter<TrackDetails, TrackListAdapter.ViewHolder>(TrackDiffCallback()) {
|
||||||
|
|
||||||
var source:Source =Source.Spotify
|
var source:Source =Source.Spotify
|
||||||
|
|
||||||
|
@ -21,11 +21,9 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.databinding.DataBindingUtil
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import com.shabinder.spotiflyer.R
|
|
||||||
import com.shabinder.spotiflyer.databinding.DownloadRecordFragmentBinding
|
import com.shabinder.spotiflyer.databinding.DownloadRecordFragmentBinding
|
||||||
import com.shabinder.spotiflyer.models.spotify.Source
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
import com.shabinder.spotiflyer.recyclerView.DownloadRecordAdapter
|
import com.shabinder.spotiflyer.recyclerView.DownloadRecordAdapter
|
||||||
@ -42,7 +40,7 @@ class DownloadRecordFragment : Fragment() {
|
|||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = DataBindingUtil.inflate(inflater,R.layout.download_record_fragment,container,false)
|
binding = DownloadRecordFragmentBinding.inflate(inflater,container,false)
|
||||||
downloadRecordViewModel = ViewModelProvider(this).get(DownloadRecordViewModel::class.java)
|
downloadRecordViewModel = ViewModelProvider(this).get(DownloadRecordViewModel::class.java)
|
||||||
adapter = DownloadRecordAdapter()
|
adapter = DownloadRecordAdapter()
|
||||||
binding.downloadRecordList.adapter = adapter
|
binding.downloadRecordList.adapter = adapter
|
||||||
|
@ -23,24 +23,30 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
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.recyclerview.widget.SimpleItemAnimator
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||||
import com.shabinder.spotiflyer.SharedViewModel
|
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 kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GaanaFragment : BaseFragment() {
|
@AndroidEntryPoint
|
||||||
|
class GaanaFragment : TrackListFragment<GaanaViewModel,GaanaFragmentArgs>() {
|
||||||
|
|
||||||
override lateinit var baseViewModel: BaseViewModel
|
@Inject lateinit var youtubeMusicApi: YoutubeMusicApi
|
||||||
|
@Inject lateinit var gaanaInterface: GaanaInterface
|
||||||
|
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
|
||||||
private val viewModel:GaanaViewModel
|
override val args: GaanaFragmentArgs by navArgs()
|
||||||
get() = baseViewModel as GaanaViewModel
|
|
||||||
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@ -75,16 +81,16 @@ class GaanaFragment : BaseFragment() {
|
|||||||
binding.downloadingFab.visibility = View.VISIBLE
|
binding.downloadingFab.visibility = View.VISIBLE
|
||||||
|
|
||||||
rotateAnim(binding.downloadingFab)
|
rotateAnim(binding.downloadingFab)
|
||||||
for (track in baseViewModel.trackList.value!!){
|
for (track in viewModel.trackList.value!!){
|
||||||
if(track.downloaded != DownloadStatus.Downloaded){
|
if(track.downloaded != DownloadStatus.Downloaded){
|
||||||
track.downloaded = DownloadStatus.Downloading
|
track.downloaded = DownloadStatus.Downloading
|
||||||
adapter.notifyItemChanged(baseViewModel.trackList.value!!.indexOf(track))
|
adapter.notifyItemChanged(viewModel.trackList.value!!.indexOf(track))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showMessage("Processing!")
|
showMessage("Processing!")
|
||||||
sharedViewModel.uiScope.launch(Dispatchers.Default){
|
sharedViewModel.uiScope.launch(Dispatchers.Default){
|
||||||
val urlList = arrayListOf<String>()
|
val urlList = arrayListOf<String>()
|
||||||
baseViewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
|
viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
|
||||||
//Appending Source
|
//Appending Source
|
||||||
urlList.add("gaana")
|
urlList.add("gaana")
|
||||||
loadAllImages(
|
loadAllImages(
|
||||||
@ -92,12 +98,12 @@ class GaanaFragment : BaseFragment() {
|
|||||||
urlList
|
urlList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
baseViewModel.uiScope.launch {
|
viewModel.uiScope.launch {
|
||||||
val finalList = baseViewModel.trackList.value
|
val finalList = viewModel.trackList.value
|
||||||
if(finalList.isNullOrEmpty())showMessage("Not Downloading Any Song")
|
if(finalList.isNullOrEmpty())showMessage("Not Downloading Any Song")
|
||||||
DownloadHelper.downloadAllTracks(
|
DownloadHelper.downloadAllTracks(
|
||||||
baseViewModel.folderType,
|
viewModel.folderType,
|
||||||
baseViewModel.subFolder,
|
viewModel.subFolder,
|
||||||
finalList ?: listOf(),
|
finalList ?: listOf(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -112,7 +118,7 @@ class GaanaFragment : BaseFragment() {
|
|||||||
**/
|
**/
|
||||||
private fun initializeAll() {
|
private fun initializeAll() {
|
||||||
sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java)
|
sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java)
|
||||||
baseViewModel = ViewModelProvider(this).get(GaanaViewModel::class.java)
|
viewModel = ViewModelProvider(this).get(GaanaViewModel::class.java)
|
||||||
viewModel.gaanaInterface = gaanaInterface
|
viewModel.gaanaInterface = gaanaInterface
|
||||||
adapter = TrackListAdapter(viewModel)
|
adapter = TrackListAdapter(viewModel)
|
||||||
DownloadHelper.youtubeMusicApi = youtubeMusicApi
|
DownloadHelper.youtubeMusicApi = youtubeMusicApi
|
||||||
|
@ -27,15 +27,15 @@ import com.shabinder.spotiflyer.models.TrackDetails
|
|||||||
import com.shabinder.spotiflyer.models.gaana.*
|
import com.shabinder.spotiflyer.models.gaana.*
|
||||||
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.BaseViewModel
|
|
||||||
import com.shabinder.spotiflyer.utils.Provider
|
import com.shabinder.spotiflyer.utils.Provider
|
||||||
|
import com.shabinder.spotiflyer.utils.TrackListViewModel
|
||||||
import com.shabinder.spotiflyer.utils.finalOutputDir
|
import com.shabinder.spotiflyer.utils.finalOutputDir
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
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) : BaseViewModel(){
|
class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : TrackListViewModel(){
|
||||||
|
|
||||||
override var folderType:String = ""
|
override var folderType:String = ""
|
||||||
override var subFolder:String = ""
|
override var subFolder:String = ""
|
||||||
|
@ -25,7 +25,6 @@ import android.text.SpannableStringBuilder
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.databinding.DataBindingUtil
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
@ -57,7 +56,7 @@ class MainFragment : Fragment() {
|
|||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = DataBindingUtil.inflate(inflater,R.layout.main_fragment,container,false)
|
binding = MainFragmentBinding.inflate(inflater,container,false)
|
||||||
initializeAll()
|
initializeAll()
|
||||||
binding.btnSearch.setOnClickListener {
|
binding.btnSearch.setOnClickListener {
|
||||||
if(!isOnline()){
|
if(!isOnline()){
|
||||||
|
@ -24,26 +24,29 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
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.recyclerview.widget.SimpleItemAnimator
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||||
import com.shabinder.spotiflyer.MainActivity
|
import com.shabinder.spotiflyer.MainActivity
|
||||||
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 kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@AndroidEntryPoint
|
||||||
class SpotifyFragment : BaseFragment() {
|
class SpotifyFragment : TrackListFragment<SpotifyViewModel,SpotifyFragmentArgs>() {
|
||||||
|
|
||||||
override lateinit var baseViewModel: BaseViewModel
|
@Inject lateinit var youtubeMusicApi: YoutubeMusicApi
|
||||||
|
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
|
||||||
private val viewModel: SpotifyViewModel
|
override val args: SpotifyFragmentArgs by navArgs()
|
||||||
get() = baseViewModel as SpotifyViewModel
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@ -53,7 +56,7 @@ class SpotifyFragment : BaseFragment() {
|
|||||||
super.onCreateView(inflater, container, savedInstanceState)
|
super.onCreateView(inflater, container, savedInstanceState)
|
||||||
initializeAll()
|
initializeAll()
|
||||||
|
|
||||||
val spotifyLink = SpotifyFragmentArgs.fromBundle(requireArguments()).link.substringAfter("open.spotify.com/")
|
val spotifyLink = args.link.substringAfter("open.spotify.com/")
|
||||||
|
|
||||||
val link = spotifyLink.substringAfterLast('/', "Error").substringBefore('?')
|
val link = spotifyLink.substringAfterLast('/', "Error").substringBefore('?')
|
||||||
val type = spotifyLink.substringBeforeLast('/', "Error").substringAfterLast('/')
|
val type = spotifyLink.substringBeforeLast('/', "Error").substringAfterLast('/')
|
||||||
@ -75,7 +78,7 @@ class SpotifyFragment : BaseFragment() {
|
|||||||
showMessage("Implementing Soon, Stay Tuned!")
|
showMessage("Implementing Soon, Stay Tuned!")
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
viewModel.spotifySearch(type,link)
|
this.viewModel.spotifySearch(type,link)
|
||||||
|
|
||||||
binding.btnDownloadAll.setOnClickListener {
|
binding.btnDownloadAll.setOnClickListener {
|
||||||
if(!isOnline()){
|
if(!isOnline()){
|
||||||
@ -86,16 +89,16 @@ class SpotifyFragment : BaseFragment() {
|
|||||||
binding.downloadingFab.visibility = View.VISIBLE
|
binding.downloadingFab.visibility = View.VISIBLE
|
||||||
|
|
||||||
rotateAnim(binding.downloadingFab)
|
rotateAnim(binding.downloadingFab)
|
||||||
for (track in viewModel.trackList.value!!){
|
for (track in this.viewModel.trackList.value!!){
|
||||||
if(track.downloaded != DownloadStatus.Downloaded){
|
if(track.downloaded != DownloadStatus.Downloaded){
|
||||||
track.downloaded = DownloadStatus.Downloading
|
track.downloaded = DownloadStatus.Downloading
|
||||||
adapter.notifyItemChanged(viewModel.trackList.value!!.indexOf(track))
|
adapter.notifyItemChanged(this.viewModel.trackList.value!!.indexOf(track))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showMessage("Processing!")
|
showMessage("Processing!")
|
||||||
sharedViewModel.uiScope.launch(Dispatchers.Default){
|
sharedViewModel.uiScope.launch(Dispatchers.Default){
|
||||||
val urlList = arrayListOf<String>()
|
val urlList = arrayListOf<String>()
|
||||||
viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
|
this@SpotifyFragment.viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
|
||||||
//Appending Source
|
//Appending Source
|
||||||
urlList.add("spotify")
|
urlList.add("spotify")
|
||||||
loadAllImages(
|
loadAllImages(
|
||||||
@ -103,7 +106,7 @@ class SpotifyFragment : BaseFragment() {
|
|||||||
urlList
|
urlList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
viewModel.uiScope.launch {
|
this.viewModel.uiScope.launch {
|
||||||
val finalList = viewModel.trackList.value
|
val finalList = viewModel.trackList.value
|
||||||
if(finalList.isNullOrEmpty())showMessage("Not Downloading Any Song")
|
if(finalList.isNullOrEmpty())showMessage("Not Downloading Any Song")
|
||||||
DownloadHelper.downloadAllTracks(
|
DownloadHelper.downloadAllTracks(
|
||||||
@ -124,10 +127,10 @@ class SpotifyFragment : BaseFragment() {
|
|||||||
* Basic Initialization
|
* Basic Initialization
|
||||||
**/
|
**/
|
||||||
private fun initializeAll() {
|
private fun initializeAll() {
|
||||||
baseViewModel = ViewModelProvider(this).get(SpotifyViewModel::class.java)
|
this.viewModel = ViewModelProvider(this).get(SpotifyViewModel::class.java)
|
||||||
adapter = TrackListAdapter(viewModel)
|
adapter = TrackListAdapter(this.viewModel)
|
||||||
sharedViewModel.spotifyService.observe(viewLifecycleOwner, {
|
sharedViewModel.spotifyService.observe(viewLifecycleOwner, {
|
||||||
viewModel.spotifyService = it
|
this.viewModel.spotifyService = it
|
||||||
})
|
})
|
||||||
DownloadHelper.youtubeMusicApi = youtubeMusicApi
|
DownloadHelper.youtubeMusicApi = youtubeMusicApi
|
||||||
DownloadHelper.sharedViewModel = sharedViewModel
|
DownloadHelper.sharedViewModel = sharedViewModel
|
||||||
|
@ -26,15 +26,15 @@ 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.*
|
||||||
import com.shabinder.spotiflyer.networking.SpotifyService
|
import com.shabinder.spotiflyer.networking.SpotifyService
|
||||||
import com.shabinder.spotiflyer.utils.BaseViewModel
|
|
||||||
import com.shabinder.spotiflyer.utils.Provider
|
import com.shabinder.spotiflyer.utils.Provider
|
||||||
|
import com.shabinder.spotiflyer.utils.TrackListViewModel
|
||||||
import com.shabinder.spotiflyer.utils.finalOutputDir
|
import com.shabinder.spotiflyer.utils.finalOutputDir
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
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) : BaseViewModel(){
|
class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : TrackListViewModel(){
|
||||||
|
|
||||||
override var folderType:String = ""
|
override var folderType:String = ""
|
||||||
override var subFolder:String = ""
|
override var subFolder:String = ""
|
||||||
@ -145,6 +145,7 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
private fun List<Track>.toTrackDetailsList() = this.map {
|
private fun List<Track>.toTrackDetailsList() = this.map {
|
||||||
TrackDetails(
|
TrackDetails(
|
||||||
title = it.name.toString(),
|
title = it.name.toString(),
|
||||||
|
@ -22,31 +22,37 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
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 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
|
||||||
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 kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class YoutubeFragment : BaseFragment() {
|
private const val sampleDomain2 = "youtu.be"
|
||||||
|
private const val sampleDomain1 = "youtube.com"
|
||||||
|
|
||||||
override lateinit var baseViewModel: BaseViewModel
|
@AndroidEntryPoint
|
||||||
|
class YoutubeFragment : TrackListFragment<YoutubeViewModel,YoutubeFragmentArgs>() {
|
||||||
|
|
||||||
|
@Inject lateinit var ytDownloader: YoutubeDownloader
|
||||||
|
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
|
||||||
private val viewModel: YoutubeViewModel
|
override val args: YoutubeFragmentArgs by navArgs()
|
||||||
get() = baseViewModel as YoutubeViewModel
|
|
||||||
private val sampleDomain2 = "youtu.be"
|
|
||||||
private val sampleDomain1 = "youtube.com"
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
super.onCreateView(inflater, container, savedInstanceState)
|
super.onCreateView(inflater, container, savedInstanceState)
|
||||||
baseViewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java)
|
this.viewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java)
|
||||||
adapter = TrackListAdapter(viewModel)
|
adapter = TrackListAdapter(this.viewModel)
|
||||||
binding.trackList.adapter = adapter
|
binding.trackList.adapter = adapter
|
||||||
|
|
||||||
val args = YoutubeFragmentArgs.fromBundle(requireArguments())
|
val args = YoutubeFragmentArgs.fromBundle(requireArguments())
|
||||||
@ -60,7 +66,7 @@ class YoutubeFragment : BaseFragment() {
|
|||||||
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("&")
|
||||||
viewModel.getYTPlaylist(playlistId,ytDownloader)
|
this.viewModel.getYTPlaylist(playlistId,ytDownloader)
|
||||||
}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) ){
|
||||||
@ -70,7 +76,7 @@ class YoutubeFragment : BaseFragment() {
|
|||||||
searchId = link.substringAfterLast("/","error")
|
searchId = link.substringAfterLast("/","error")
|
||||||
}
|
}
|
||||||
if(searchId != "error") {
|
if(searchId != "error") {
|
||||||
viewModel.getYTTrack(searchId,ytDownloader)
|
this.viewModel.getYTTrack(searchId,ytDownloader)
|
||||||
}else{showMessage("Your Youtube Link is not of a Video!!")}
|
}else{showMessage("Your Youtube Link is not of a Video!!")}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,10 +93,10 @@ class YoutubeFragment : BaseFragment() {
|
|||||||
|
|
||||||
rotateAnim(binding.downloadingFab)
|
rotateAnim(binding.downloadingFab)
|
||||||
|
|
||||||
for (track in viewModel.trackList.value?: listOf()){
|
for (track in this.viewModel.trackList.value?: listOf()){
|
||||||
if(track.downloaded != DownloadStatus.Downloaded){
|
if(track.downloaded != DownloadStatus.Downloaded){
|
||||||
track.downloaded = DownloadStatus.Downloading
|
track.downloaded = DownloadStatus.Downloading
|
||||||
adapter.notifyItemChanged(viewModel.trackList.value!!.indexOf(track))
|
adapter.notifyItemChanged(this.viewModel.trackList.value!!.indexOf(track))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showMessage("Processing!")
|
showMessage("Processing!")
|
||||||
|
@ -27,8 +27,8 @@ 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.Source
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
import com.shabinder.spotiflyer.utils.BaseViewModel
|
|
||||||
import com.shabinder.spotiflyer.utils.Provider.defaultDir
|
import com.shabinder.spotiflyer.utils.Provider.defaultDir
|
||||||
|
import com.shabinder.spotiflyer.utils.TrackListViewModel
|
||||||
import com.shabinder.spotiflyer.utils.finalOutputDir
|
import com.shabinder.spotiflyer.utils.finalOutputDir
|
||||||
import com.shabinder.spotiflyer.utils.removeIllegalChars
|
import com.shabinder.spotiflyer.utils.removeIllegalChars
|
||||||
import com.shabinder.spotiflyer.utils.showMessage
|
import com.shabinder.spotiflyer.utils.showMessage
|
||||||
@ -37,7 +37,7 @@ 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) : BaseViewModel(){
|
class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : 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"
|
||||||
|
@ -26,35 +26,27 @@ import android.util.Log
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.databinding.DataBindingUtil
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import com.github.kiulian.downloader.YoutubeDownloader
|
import androidx.navigation.NavArgs
|
||||||
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.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
|
||||||
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 dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
abstract class TrackListFragment<VM : TrackListViewModel , args: NavArgs> : Fragment() {
|
||||||
abstract class BaseFragment : Fragment() {
|
|
||||||
|
|
||||||
@Inject open lateinit var youtubeMusicApi: YoutubeMusicApi
|
protected lateinit var sharedViewModel: SharedViewModel
|
||||||
@Inject open lateinit var ytDownloader: YoutubeDownloader
|
protected lateinit var binding: TrackListFragmentBinding
|
||||||
@Inject open lateinit var gaanaInterface: GaanaInterface
|
protected abstract var viewModel: VM
|
||||||
open lateinit var sharedViewModel: SharedViewModel
|
protected abstract var adapter: TrackListAdapter
|
||||||
open lateinit var binding: TrackListFragmentBinding
|
protected abstract var source: Source
|
||||||
abstract var baseViewModel: BaseViewModel
|
|
||||||
abstract var adapter: TrackListAdapter
|
|
||||||
abstract var source: Source
|
|
||||||
private var intentFilter: IntentFilter? = null
|
private var intentFilter: IntentFilter? = null
|
||||||
private var updateUIReceiver: BroadcastReceiver? = null
|
private var updateUIReceiver: BroadcastReceiver? = null
|
||||||
|
protected abstract val args:NavArgs
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -66,7 +58,7 @@ abstract class BaseFragment : Fragment() {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = DataBindingUtil.inflate(inflater,R.layout.track_list_fragment, container, false)
|
binding = TrackListFragmentBinding.inflate(inflater,container,false)
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,11 +66,12 @@ abstract class BaseFragment : Fragment() {
|
|||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
initializeLiveDataObservers()
|
initializeLiveDataObservers()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Live Data Observers
|
*Live Data Observers
|
||||||
**/
|
**/
|
||||||
open fun initializeLiveDataObservers() {
|
private fun initializeLiveDataObservers() {
|
||||||
baseViewModel.trackList.observe(viewLifecycleOwner, {
|
viewModel.trackList.observe(viewLifecycleOwner, {
|
||||||
if (it.isNotEmpty()){
|
if (it.isNotEmpty()){
|
||||||
Log.i("GaanaFragment","TrackList Updated")
|
Log.i("GaanaFragment","TrackList Updated")
|
||||||
adapter.submitList(it, source)
|
adapter.submitList(it, source)
|
||||||
@ -86,16 +79,16 @@ abstract class BaseFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
baseViewModel.coverUrl.observe(viewLifecycleOwner, {
|
viewModel.coverUrl.observe(viewLifecycleOwner, {
|
||||||
if(it!="Loading") bindImage(binding.coverImage,it, source)
|
if(it!="Loading") bindImage(binding.coverImage,it, source)
|
||||||
})
|
})
|
||||||
|
|
||||||
baseViewModel.title.observe(viewLifecycleOwner, {
|
viewModel.title.observe(viewLifecycleOwner, {
|
||||||
binding.titleView.text = it
|
binding.titleView.text = it
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun initializeBroadcast() {
|
private fun initializeBroadcast() {
|
||||||
intentFilter = IntentFilter()
|
intentFilter = IntentFilter()
|
||||||
intentFilter?.addAction("track_download_completed")
|
intentFilter?.addAction("track_download_completed")
|
||||||
|
|
||||||
@ -105,13 +98,13 @@ abstract class BaseFragment : Fragment() {
|
|||||||
if (intent != null){
|
if (intent != null){
|
||||||
val trackDetails = intent.getParcelableExtra<TrackDetails?>("track")
|
val trackDetails = intent.getParcelableExtra<TrackDetails?>("track")
|
||||||
trackDetails?.let {
|
trackDetails?.let {
|
||||||
val position: Int = baseViewModel.trackList.value?.map { it.title }?.indexOf(trackDetails.title) ?: -1
|
val position: Int = viewModel.trackList.value?.map { it.title }?.indexOf(trackDetails.title) ?: -1
|
||||||
Log.i("Track","Download Completed Intent :$position")
|
Log.i("Track","Download Completed Intent :$position")
|
||||||
if(position != -1) {
|
if(position != -1) {
|
||||||
val track = baseViewModel.trackList.value?.get(position)
|
val track = viewModel.trackList.value?.get(position)
|
||||||
track?.let{
|
track?.let{
|
||||||
it.downloaded = DownloadStatus.Downloaded
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
baseViewModel.trackList.value?.set(position, it)
|
viewModel.trackList.value?.set(position, it)
|
||||||
adapter.notifyItemChanged(position)
|
adapter.notifyItemChanged(position)
|
||||||
checkIfAllDownloaded()
|
checkIfAllDownloaded()
|
||||||
}
|
}
|
||||||
@ -133,8 +126,8 @@ abstract class BaseFragment : Fragment() {
|
|||||||
requireActivity().unregisterReceiver(updateUIReceiver)
|
requireActivity().unregisterReceiver(updateUIReceiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun checkIfAllDownloaded() {
|
private fun checkIfAllDownloaded() {
|
||||||
if(!baseViewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){
|
if(!viewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){
|
||||||
//All Tracks Downloaded
|
//All Tracks Downloaded
|
||||||
binding.btnDownloadAll.visibility = View.GONE
|
binding.btnDownloadAll.visibility = View.GONE
|
||||||
binding.downloadingFab.apply{
|
binding.downloadingFab.apply{
|
@ -25,7 +25,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
|
||||||
abstract class BaseViewModel:ViewModel() {
|
abstract class TrackListViewModel:ViewModel() {
|
||||||
abstract var folderType:String
|
abstract var folderType:String
|
||||||
abstract var subFolder:String
|
abstract var subFolder:String
|
||||||
open val trackList = MutableLiveData<MutableList<TrackDetails>>()
|
open val trackList = MutableLiveData<MutableList<TrackDetails>>()
|
@ -16,7 +16,8 @@
|
|||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
|
||||||
|
<solid android:color="@color/black"/>
|
||||||
<gradient
|
<gradient
|
||||||
android:angle="90"
|
android:angle="90"
|
||||||
android:centerColor="#0F6200FF"
|
android:centerColor="#0F6200FF"
|
||||||
|
BIN
app/src/main/res/font/nunito_sans.ttf
Normal file
BIN
app/src/main/res/font/nunito_sans.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/nunito_sans_light.ttf
Normal file
BIN
app/src/main/res/font/nunito_sans_light.ttf
Normal file
Binary file not shown.
@ -15,12 +15,10 @@
|
|||||||
~ You should have received a copy of the GNU General Public License
|
~ You should have received a copy of the GNU General Public License
|
||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:background="@color/black"
|
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -28,14 +26,10 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:background="@drawable/text_background_accented"
|
style="@style/Widget.AppCompat.EditText.Gradient"
|
||||||
android:drawablePadding="5dp"
|
android:drawablePadding="5dp"
|
||||||
android:fontFamily="@font/raleway_semibold"
|
android:fontFamily="@font/raleway_semibold"
|
||||||
android:gravity="center"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:text=" Download History "
|
android:text=" Download History "
|
||||||
android:textAlignment="center"
|
|
||||||
android:textColor="#E1FFFFFF"
|
|
||||||
android:textSize="21sp"
|
android:textSize="21sp"
|
||||||
app:drawableStartCompat="@drawable/ic_history"
|
app:drawableStartCompat="@drawable/ic_history"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
@ -84,4 +78,3 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
|
app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</layout>
|
|
@ -17,89 +17,81 @@
|
|||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<data>
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
<variable
|
android:layout_width="match_parent"
|
||||||
name="downloadRecord"
|
android:layout_height="92dp"
|
||||||
type="com.shabinder.spotiflyer.database.DownloadRecord" />
|
android:background="#000000"
|
||||||
</data>
|
android:paddingBottom="12dp">
|
||||||
|
|
||||||
<RelativeLayout
|
<ImageView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/coverUrl"
|
||||||
android:layout_height="92dp"
|
android:layout_width="100dp"
|
||||||
android:background="#000000"
|
android:layout_height="80dp"
|
||||||
android:paddingBottom="12dp">
|
android:layout_alignParentStart="true"
|
||||||
|
android:contentDescription="Track Image"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
android:src="@drawable/ic_song_placeholder" />
|
||||||
|
|
||||||
<ImageView
|
<TextView
|
||||||
android:id="@+id/coverUrl"
|
android:id="@+id/item_name"
|
||||||
android:layout_width="100dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="80dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentTop="true"
|
||||||
android:contentDescription="Track Image"
|
android:layout_marginStart="12dp"
|
||||||
android:scaleType="centerInside"
|
android:layout_marginTop="14dp"
|
||||||
android:src="@drawable/ic_song_placeholder" />
|
android:layout_marginEnd="12dp"
|
||||||
|
android:layout_toStartOf="@+id/btn_action"
|
||||||
|
android:layout_toEndOf="@+id/coverUrl"
|
||||||
|
android:fontFamily="@font/raleway_semibold"
|
||||||
|
android:letterSpacing="0.04"
|
||||||
|
android:lines="1"
|
||||||
|
android:text="Weekend Chills"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
|
||||||
|
android:textColor="#9AB3FF"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/item_name"
|
android:id="@+id/type"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignBottom="@+id/coverUrl"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
android:layout_marginTop="14dp"
|
android:layout_marginEnd="0dp"
|
||||||
android:layout_marginEnd="12dp"
|
android:layout_marginBottom="15dp"
|
||||||
android:layout_toStartOf="@+id/btn_action"
|
android:layout_toStartOf="@+id/totalItems"
|
||||||
android:layout_toEndOf="@+id/coverUrl"
|
android:layout_toEndOf="@+id/coverUrl"
|
||||||
android:fontFamily="@font/raleway_semibold"
|
android:paddingLeft="9dp"
|
||||||
android:letterSpacing="0.04"
|
android:text="Playlist"
|
||||||
android:lines="1"
|
android:textSize="12sp" />
|
||||||
android:text="Weekend Chills"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
|
|
||||||
android:textColor="#9AB3FF"
|
|
||||||
android:textSize="20sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/type"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignBottom="@+id/coverUrl"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:layout_marginEnd="0dp"
|
|
||||||
android:layout_marginBottom="15dp"
|
|
||||||
android:layout_toStartOf="@+id/totalItems"
|
|
||||||
android:layout_toEndOf="@+id/coverUrl"
|
|
||||||
android:paddingLeft="9dp"
|
|
||||||
android:text="Playlist"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/totalItems"
|
android:id="@+id/totalItems"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignBottom="@+id/coverUrl"
|
android:layout_alignBottom="@+id/coverUrl"
|
||||||
android:layout_marginTop="7dp"
|
android:layout_marginTop="7dp"
|
||||||
android:layout_marginEnd="25dp"
|
android:layout_marginEnd="25dp"
|
||||||
android:layout_marginBottom="15dp"
|
android:layout_marginBottom="15dp"
|
||||||
android:layout_toStartOf="@+id/btn_action"
|
android:layout_toStartOf="@+id/btn_action"
|
||||||
android:paddingLeft="9dp"
|
android:paddingLeft="9dp"
|
||||||
android:text="50 Tracks"
|
android:text="50 Tracks"
|
||||||
android:textSize="12sp" />
|
android:textSize="12sp" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_action"
|
android:id="@+id/btn_action"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="80dp"
|
android:layout_height="80dp"
|
||||||
android:layout_alignBottom="@+id/coverUrl"
|
android:layout_alignBottom="@+id/coverUrl"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:backgroundTint="@color/black"
|
android:backgroundTint="@color/black"
|
||||||
android:scaleType="centerInside"
|
android:scaleType="centerInside"
|
||||||
android:src="@drawable/ic_share_open"
|
android:src="@drawable/ic_share_open"
|
||||||
android:tint="@null" />
|
android:tint="@null" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</layout>
|
|
||||||
|
|
||||||
|
@ -16,39 +16,36 @@
|
|||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/mainActivity"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<View
|
||||||
|
android:id="@+id/snackBarPosition"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:background="@drawable/transparent"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:visibility="invisible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<fragment
|
||||||
android:id="@+id/mainActivity"
|
android:id="@+id/navHostFragment"
|
||||||
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:background="@color/black"
|
android:layout_height="0dp"
|
||||||
android:layout_height="match_parent">
|
app:defaultNavHost="true"
|
||||||
<View
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:id="@+id/snackBarPosition"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:layout_width="wrap_content"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:layout_height="wrap_content"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:layout_marginBottom="16dp"
|
app:navGraph="@navigation/navigation"
|
||||||
android:background="@drawable/transparent"
|
tools:ignore="FragmentTagUsage" />
|
||||||
android:visibility="invisible"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<fragment
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
android:id="@+id/navHostFragment"
|
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:defaultNavHost="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:navGraph="@navigation/navigation"
|
|
||||||
tools:ignore="FragmentTagUsage" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
</layout>
|
|
@ -15,47 +15,40 @@
|
|||||||
~ You should have received a copy of the GNU General Public License
|
~ You should have received a copy of the GNU General Public License
|
||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fillViewport="true"
|
android:fillViewport="true"
|
||||||
android:background="@color/black"
|
tools:ignore="HardcodedText"
|
||||||
>
|
>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/linkSearch"
|
android:id="@+id/linkSearch"
|
||||||
android:layout_width="wrap_content"
|
style="@style/Widget.AppCompat.EditText.Gradient"
|
||||||
android:layout_height="46dp"
|
android:layout_height="46dp"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
android:background="@drawable/text_background_accented"
|
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:hint="Paste Link here"
|
android:hint="Paste Link here"
|
||||||
android:inputType="text"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textColorHint="@color/grey"
|
|
||||||
android:textSize="19sp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/btn_search"
|
app:layout_constraintEnd_toStartOf="@+id/btn_search"
|
||||||
app:layout_constraintHorizontal_chainStyle="spread"
|
app:layout_constraintHorizontal_chainStyle="spread"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:importantForAutofill="no"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:id="@+id/btn_search"
|
android:id="@+id/btn_search"
|
||||||
android:layout_width="wrap_content"
|
style="@style/Widget.AppCompat.Button.Colored.Gradient"
|
||||||
android:layout_height="44dp"
|
android:layout_height="44dp"
|
||||||
android:background="@drawable/btn_design"
|
android:fontFamily="@font/nunito_sans_light"
|
||||||
android:paddingLeft="4dp"
|
android:text=" Search "
|
||||||
android:paddingRight="4dp"
|
android:textStyle="bold"
|
||||||
android:text="Search"
|
|
||||||
android:textColor="@color/black"
|
|
||||||
android:textSize="16sp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/linkSearch"
|
app:layout_constraintBottom_toBottomOf="@+id/linkSearch"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/linkSearch"
|
app:layout_constraintStart_toEndOf="@+id/linkSearch"
|
||||||
@ -75,19 +68,16 @@
|
|||||||
app:layout_collapseMode="parallax"
|
app:layout_collapseMode="parallax"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/linkSearch" />
|
app:layout_constraintTop_toBottomOf="@+id/linkSearch"
|
||||||
|
tools:ignore="UnusedAttribute" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_history"
|
android:id="@+id/btn_history"
|
||||||
android:layout_width="40dp"
|
style="@style/Widget.AppCompat.ImageButton.40dp"
|
||||||
android:layout_height="40dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:background="@drawable/transparent"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/appLogo"
|
app:layout_constraintBottom_toBottomOf="@+id/appLogo"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:srcCompat="@drawable/ic_history" />
|
android:contentDescription="Open Download History Button"
|
||||||
|
app:srcCompat="@drawable/ic_history"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/appName"
|
android:id="@+id/appName"
|
||||||
@ -95,16 +85,13 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:fontFamily="@font/raleway_semibold"
|
android:fontFamily="@font/raleway_semibold"
|
||||||
android:gravity="end"
|
|
||||||
android:text='"SpotiFlyer"'
|
android:text='"SpotiFlyer"'
|
||||||
android:textAlignment="viewEnd"
|
android:textColor="@color/colorAccent"
|
||||||
android:textColor="#9AB3FF"
|
|
||||||
android:textSize="40sp"
|
android:textSize="40sp"
|
||||||
android:typeface="normal"
|
|
||||||
android:visibility="visible"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/appLogo" />
|
app:layout_constraintTop_toBottomOf="@id/appLogo"
|
||||||
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/appSubTitle"
|
android:id="@+id/appSubTitle"
|
||||||
@ -120,50 +107,26 @@
|
|||||||
app:layout_constraintStart_toStartOf="@+id/appName"
|
app:layout_constraintStart_toStartOf="@+id/appName"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/appName" />
|
app:layout_constraintTop_toBottomOf="@+id/appName" />
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/platforms"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="32dp"
|
|
||||||
android:layout_marginEnd="2dp"
|
|
||||||
android:fontFamily="@font/raleway_semibold"
|
|
||||||
android:text="Supports: "
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textColor="#9AB3FF"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:visibility="visible"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/btn_spotify"
|
|
||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/appSubTitle" />
|
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_spotify"
|
android:id="@+id/btn_spotify"
|
||||||
android:layout_width="46dp"
|
style="@style/Widget.AppCompat.ImageButton.platformIcon"
|
||||||
android:layout_height="46dp"
|
|
||||||
android:layout_marginEnd="2dp"
|
android:layout_marginEnd="2dp"
|
||||||
android:background="@color/black"
|
android:contentDescription="Open Spotify App Button"
|
||||||
android:padding="5dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_spotify_logo"
|
android:src="@drawable/ic_spotify_logo"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/platforms"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/btn_youtube"
|
app:layout_constraintEnd_toStartOf="@+id/btn_youtube"
|
||||||
app:layout_constraintStart_toEndOf="@+id/platforms"
|
android:padding="6dp"
|
||||||
app:layout_constraintTop_toTopOf="@+id/platforms" />
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/appSubTitle"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/appSubTitle"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_youtube"
|
android:id="@+id/btn_youtube"
|
||||||
android:layout_width="52dp"
|
style="@style/Widget.AppCompat.ImageButton.platformIcon"
|
||||||
android:layout_height="52dp"
|
|
||||||
android:background="@color/black"
|
|
||||||
android:padding="5dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_youtube"
|
android:src="@drawable/ic_youtube"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/btn_spotify"
|
app:layout_constraintBottom_toBottomOf="@+id/btn_spotify"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:contentDescription="Open Youtube App Button"
|
||||||
app:layout_constraintStart_toEndOf="@+id/btn_spotify"
|
app:layout_constraintStart_toEndOf="@+id/btn_spotify"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/appSubTitle"
|
||||||
app:layout_constraintTop_toTopOf="@+id/btn_spotify" />
|
app:layout_constraintTop_toTopOf="@+id/btn_spotify" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -171,11 +134,11 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
|
android:gravity="center"
|
||||||
android:text="Usage Instructions!"
|
android:text="Usage Instructions!"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="#D0838383"
|
android:textColor="#D0838383"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:gravity="center"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/developer_insta_spotify"
|
app:layout_constraintBottom_toBottomOf="@+id/developer_insta_spotify"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/btn_linkedin"
|
app:layout_constraintStart_toEndOf="@+id/btn_linkedin"
|
||||||
@ -189,6 +152,7 @@
|
|||||||
android:background="@drawable/text_background_accented"
|
android:background="@drawable/text_background_accented"
|
||||||
android:drawableEnd="@drawable/ic_mug"
|
android:drawableEnd="@drawable/ic_mug"
|
||||||
android:drawablePadding="5dp"
|
android:drawablePadding="5dp"
|
||||||
|
android:contentDescription="Donate Money Button"
|
||||||
android:fontFamily="@font/capriola"
|
android:fontFamily="@font/capriola"
|
||||||
android:foreground="@drawable/rounded_gradient"
|
android:foreground="@drawable/rounded_gradient"
|
||||||
android:gravity="end|center_vertical"
|
android:gravity="end|center_vertical"
|
||||||
@ -214,39 +178,30 @@
|
|||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_github_spotify"
|
android:id="@+id/btn_github_spotify"
|
||||||
android:layout_width="48dp"
|
style="@style/Widget.AppCompat.ImageButton.platformIcon"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@color/black"
|
|
||||||
android:padding="5dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_github"
|
android:src="@drawable/ic_github"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/btn_linkedin"
|
app:layout_constraintBottom_toTopOf="@+id/btn_linkedin"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/btn_youtube"
|
app:layout_constraintTop_toBottomOf="@+id/btn_youtube"
|
||||||
app:layout_constraintVertical_chainStyle="packed" />
|
android:contentDescription="Open Github App Button"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_linkedin"
|
android:id="@+id/btn_linkedin"
|
||||||
android:layout_width="48dp"
|
style="@style/Widget.AppCompat.ImageButton.platformIcon"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@color/black"
|
|
||||||
android:padding="5dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_linkedin"
|
android:src="@drawable/ic_linkedin"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/developer_insta_spotify"
|
app:layout_constraintBottom_toTopOf="@+id/developer_insta_spotify"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/btn_github_spotify" />
|
android:contentDescription="Open LinkedIN App Button"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/btn_github_spotify"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/developer_insta_spotify"
|
android:id="@+id/developer_insta_spotify"
|
||||||
android:layout_width="48dp"
|
style="@style/Widget.AppCompat.ImageButton.platformIcon"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@color/black"
|
|
||||||
android:padding="5dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_instagram"
|
android:src="@drawable/ic_instagram"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/btn_donate"
|
app:layout_constraintBottom_toTopOf="@+id/btn_donate"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:contentDescription="Open Instagram App Button"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/btn_linkedin" />
|
app:layout_constraintTop_toBottomOf="@+id/btn_linkedin" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -290,4 +245,3 @@
|
|||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</layout>
|
|
@ -16,16 +16,16 @@
|
|||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/main"
|
android:id="@+id/main"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:background="@color/black"
|
android:background="@color/black"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="25dp"
|
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
|
android:paddingTop="16dp"
|
||||||
tools:context=".ui.spotify.SpotifyFragment">
|
tools:context=".ui.spotify.SpotifyFragment">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatButton
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
@ -155,4 +155,4 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@id/appbar" />
|
app:layout_constraintTop_toBottomOf="@id/appbar" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
</layout>
|
|
||||||
|
@ -16,97 +16,84 @@
|
|||||||
~ You should have received a copy of the GNU General Public License
|
~ You should have received a copy of the GNU General Public License
|
||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
-->
|
-->
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:background="#000000">
|
||||||
|
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<ImageView
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
android:id="@+id/imageUrl"
|
||||||
|
android:layout_width="100dp"
|
||||||
<data>
|
|
||||||
<variable
|
|
||||||
name="track"
|
|
||||||
type="com.shabinder.spotiflyer.models.spotify.Track" />
|
|
||||||
</data>
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="80dp"
|
android:layout_height="80dp"
|
||||||
android:background="#000000"
|
android:contentDescription="Track Image"
|
||||||
android:layout_marginBottom="12dp"
|
android:scaleType="centerInside"
|
||||||
>
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/artist"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_song_placeholder" />
|
||||||
|
|
||||||
<ImageView
|
<TextView
|
||||||
android:id="@+id/imageUrl"
|
android:id="@+id/track_name"
|
||||||
android:layout_width="100dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="80dp"
|
android:layout_height="wrap_content"
|
||||||
android:contentDescription="Track Image"
|
android:layout_marginStart="8dp"
|
||||||
android:scaleType="centerInside"
|
android:layout_marginTop="14dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:fontFamily="@font/raleway_semibold"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/artist"
|
android:letterSpacing="0.04"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:lines="1"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
android:text="The Spectre"
|
||||||
app:srcCompat="@drawable/ic_song_placeholder" />
|
android:textAllCaps="false"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
|
||||||
|
android:textColor="#9AB3FF"
|
||||||
|
android:textSize="20sp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/artist"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/track_name"
|
android:id="@+id/artist"
|
||||||
android:layout_width="0dp"
|
style="@style/TextAppearance.AppCompat.Body2"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="14dp"
|
android:layout_marginStart="12dp"
|
||||||
android:fontFamily="@font/raleway_semibold"
|
android:layout_marginTop="8dp"
|
||||||
android:letterSpacing="0.04"
|
android:layout_marginBottom="8dp"
|
||||||
android:lines="1"
|
android:paddingLeft="9dp"
|
||||||
android:text="The Spectre"
|
android:text="Alan Walker"
|
||||||
android:textAllCaps="false"
|
android:textSize="12sp"
|
||||||
android:textAppearance="@style/TextAppearance.AppTheme.Headline4"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:textColor="#9AB3FF"
|
app:layout_constraintEnd_toStartOf="@+id/duration"
|
||||||
android:textSize="20sp"
|
app:layout_constraintStart_toEndOf="@+id/imageUrl"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
app:layout_constraintTop_toBottomOf="@+id/track_name" />
|
||||||
app:layout_constraintStart_toStartOf="@+id/artist"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/artist"
|
|
||||||
style="@style/TextAppearance.AppCompat.Body2"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:paddingLeft="9dp"
|
|
||||||
android:text="Alan Walker"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/duration"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/imageUrl"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/track_name" />
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/duration"
|
android:id="@+id/duration"
|
||||||
style="@style/TextAppearance.AppCompat.Body2"
|
style="@style/TextAppearance.AppCompat.Body2"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="3dp"
|
android:layout_marginEnd="3dp"
|
||||||
android:paddingLeft="9dp"
|
android:paddingLeft="9dp"
|
||||||
android:text="4 minutes, 20 sec"
|
android:text="4 minutes, 20 sec"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/artist"
|
app:layout_constraintBottom_toBottomOf="@+id/artist"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
app:layout_constraintEnd_toStartOf="@+id/btn_download"
|
||||||
app:layout_constraintStart_toEndOf="@+id/artist"
|
app:layout_constraintStart_toEndOf="@+id/artist"
|
||||||
app:layout_constraintTop_toTopOf="@+id/artist" />
|
app:layout_constraintTop_toTopOf="@+id/artist" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_download"
|
android:id="@+id/btn_download"
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:backgroundTint="@color/black"
|
android:backgroundTint="@color/black"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:srcCompat="@drawable/ic_arrow" />
|
app:srcCompat="@drawable/ic_arrow" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</layout>
|
|
||||||
|
|
||||||
|
@ -20,10 +20,12 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<color name="colorPrimary">#FC5C7D</color>
|
<color name="colorPrimary">#FC5C7D</color>
|
||||||
<color name="colorPrimaryDark">#CE1CFF</color>
|
<color name="colorPrimaryDark">#CE1CFF</color>
|
||||||
<color name="colorAccent">#799BFF</color>
|
<color name="colorAccent">#9AB3FF</color>
|
||||||
<color name="white">#FFFFFF</color>
|
<color name="white">#FFFFFF</color>
|
||||||
<color name="grey">#99FFFFFF</color>
|
<color name="grey">#99FFFFFF</color>
|
||||||
<color name="black">#000000</color>
|
<color name="black">#000000</color>
|
||||||
|
<color name="dark">#121212</color>
|
||||||
|
<color name="successGreen">#4BB543</color>
|
||||||
|
<color name="errorRed">#FF9494</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -19,12 +19,22 @@
|
|||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||||
<!-- Customize your theme here. -->
|
<!-- Customize your theme here. -->
|
||||||
<item name="colorPrimaryDark">#000000</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="android:colorBackground">@color/black</item>
|
||||||
|
<item name="colorOnBackground">@color/white</item>
|
||||||
|
<item name="colorError">#FF5E5E</item>
|
||||||
|
<item name="colorOnError">@color/black</item>
|
||||||
|
<item name="colorSurface">@color/dark</item>
|
||||||
|
<item name="colorOnSurface">@color/white</item>
|
||||||
<item name="colorPrimary">#FC5C7D</item>
|
<item name="colorPrimary">#FC5C7D</item>
|
||||||
|
<item name="colorOnPrimary">@color/white</item>
|
||||||
|
<item name="colorSecondary">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorOnSecondary">@color/white</item>
|
||||||
<item name="android:textColor">#FFFFFF</item>
|
<item name="android:textColor">#FFFFFF</item>
|
||||||
<item name="colorAccent">#6A82FB</item>
|
<item name="android:textColorHint">@color/grey</item>
|
||||||
<item name="android:outlineAmbientShadowColor" tools:targetApi="p">#A9B200FF</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
<item name="android:radius">11dp</item>
|
<item name="android:outlineAmbientShadowColor" tools:targetApi="p">@color/colorPrimaryDark</item>
|
||||||
|
<item name="android:radius">12dp</item>
|
||||||
<!-- Text Appearances !-->
|
<!-- Text Appearances !-->
|
||||||
<!-- use our brand's custom TextAppearance4 !-->
|
<!-- use our brand's custom TextAppearance4 !-->
|
||||||
<item name="textAppearanceHeadline4">@style/TextAppearance.AppTheme.Headline4</item>
|
<item name="textAppearanceHeadline4">@style/TextAppearance.AppTheme.Headline4</item>
|
||||||
@ -32,7 +42,42 @@
|
|||||||
<item name="textAppearanceBody2">@style/TextAppearance.MaterialComponents.Body2</item>
|
<item name="textAppearanceBody2">@style/TextAppearance.MaterialComponents.Body2</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="Widget.AppCompat.Button.Colored.Gradient" parent="Widget.AppCompat.ActionButton">
|
||||||
|
<item name="android:layout_width">wrap_content</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:background">@drawable/btn_design</item>
|
||||||
|
<item name="android:textColor">@color/black</item>
|
||||||
|
<item name="android:textAllCaps">true</item>
|
||||||
|
<item name="android:textAlignment">center</item>
|
||||||
|
<item name="android:paddingLeft">4dp</item>
|
||||||
|
<item name="android:paddingRight">4dp</item>
|
||||||
|
<item name="android:textSize">16sp</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Widget.AppCompat.ImageButton.40dp" parent="Widget.AppCompat.ImageButton">
|
||||||
|
<item name="android:layout_width">40dp</item>
|
||||||
|
<item name="android:layout_height">40dp</item>
|
||||||
|
<item name="android:background">@drawable/transparent</item>
|
||||||
|
<item name="android:scaleType">fitCenter</item>
|
||||||
|
<item name="android:layout_margin">8dp</item>
|
||||||
|
</style>
|
||||||
|
<style name="Widget.AppCompat.EditText.Gradient" parent="Widget.AppCompat.EditText">
|
||||||
|
<item name="android:background">@drawable/text_background_accented</item>
|
||||||
|
<item name="android:textAlignment">center</item>
|
||||||
|
<item name="android:layout_width">wrap_content</item>
|
||||||
|
<item name="android:inputType">text</item>
|
||||||
|
<item name="android:padding">8dp</item>
|
||||||
|
<item name="android:textSize">18sp</item>
|
||||||
|
<item name="android:textColor">@color/white</item>
|
||||||
|
</style>
|
||||||
|
<style name="Widget.AppCompat.ImageButton.platformIcon" parent="Widget.AppCompat.ImageButton">
|
||||||
|
<item name="android:layout_width">48dp</item>
|
||||||
|
<item name="android:layout_height">48dp</item>
|
||||||
|
<item name="android:background">@color/black</item>
|
||||||
|
<item name="android:scaleType">fitCenter</item>
|
||||||
|
<item name="android:padding">4dp</item>
|
||||||
|
</style>
|
||||||
<style name="AlertDialogTheme" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
|
<style name="AlertDialogTheme" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
|
||||||
<item name="shapeAppearanceMediumComponent">@style/CutShapeAppearance</item>
|
<item name="shapeAppearanceMediumComponent">@style/CutShapeAppearance</item>
|
||||||
<item name="buttonBarPositiveButtonStyle">@style/Alert.Button.Positive</item>
|
<item name="buttonBarPositiveButtonStyle">@style/Alert.Button.Positive</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user