Set Up base TrackListFragmentBaseClass and TrackListViewModelBase

This commit is contained in:
Shabinder 2020-11-10 14:13:41 +05:30
parent f869725953
commit b3b2e6ed51
25 changed files with 365 additions and 386 deletions

View File

@ -16,6 +16,7 @@
<w>instagram</w>
<w>jetbrains</w>
<w>kotlinx</w>
<w>linkedin</w>
<w>mainfragment</w>
<w>maxresdefault</w>
<w>moshi</w>

View File

@ -28,7 +28,8 @@ android {
buildToolsVersion "30.0.2"
buildFeatures{
dataBinding = true
//dataBinding = true
viewBinding = true
}
defaultConfig {

View File

@ -30,7 +30,6 @@ import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.findNavController
@ -69,12 +68,13 @@ class MainActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//Enabling Dark Mode
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)
navController = findNavController(R.id.navHostFragment)
snackBarAnchor = binding.snackBarPosition
//Enabling Dark Mode
authenticateSpotify()

View File

@ -33,7 +33,7 @@ import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.utils.*
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

View File

@ -21,11 +21,9 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.tabs.TabLayout
import com.shabinder.spotiflyer.R
import com.shabinder.spotiflyer.databinding.DownloadRecordFragmentBinding
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.recyclerView.DownloadRecordAdapter
@ -42,7 +40,7 @@ class DownloadRecordFragment : Fragment() {
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): 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)
adapter = DownloadRecordAdapter()
binding.downloadRecordList.adapter = adapter

View File

@ -23,24 +23,30 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
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.models.DownloadStatus
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.networking.GaanaInterface
import com.shabinder.spotiflyer.networking.YoutubeMusicApi
import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
import com.shabinder.spotiflyer.utils.*
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject
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 var source: Source = Source.Gaana
private val viewModel:GaanaViewModel
get() = baseViewModel as GaanaViewModel
override val args: GaanaFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@ -75,16 +81,16 @@ class GaanaFragment : BaseFragment() {
binding.downloadingFab.visibility = View.VISIBLE
rotateAnim(binding.downloadingFab)
for (track in baseViewModel.trackList.value!!){
for (track in viewModel.trackList.value!!){
if(track.downloaded != DownloadStatus.Downloaded){
track.downloaded = DownloadStatus.Downloading
adapter.notifyItemChanged(baseViewModel.trackList.value!!.indexOf(track))
adapter.notifyItemChanged(viewModel.trackList.value!!.indexOf(track))
}
}
showMessage("Processing!")
sharedViewModel.uiScope.launch(Dispatchers.Default){
val urlList = arrayListOf<String>()
baseViewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
//Appending Source
urlList.add("gaana")
loadAllImages(
@ -92,12 +98,12 @@ class GaanaFragment : BaseFragment() {
urlList
)
}
baseViewModel.uiScope.launch {
val finalList = baseViewModel.trackList.value
viewModel.uiScope.launch {
val finalList = viewModel.trackList.value
if(finalList.isNullOrEmpty())showMessage("Not Downloading Any Song")
DownloadHelper.downloadAllTracks(
baseViewModel.folderType,
baseViewModel.subFolder,
viewModel.folderType,
viewModel.subFolder,
finalList ?: listOf(),
)
}
@ -112,7 +118,7 @@ class GaanaFragment : BaseFragment() {
**/
private fun initializeAll() {
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
adapter = TrackListAdapter(viewModel)
DownloadHelper.youtubeMusicApi = youtubeMusicApi

View File

@ -27,15 +27,15 @@ import com.shabinder.spotiflyer.models.TrackDetails
import com.shabinder.spotiflyer.models.gaana.*
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.networking.GaanaInterface
import com.shabinder.spotiflyer.utils.BaseViewModel
import com.shabinder.spotiflyer.utils.Provider
import com.shabinder.spotiflyer.utils.TrackListViewModel
import com.shabinder.spotiflyer.utils.finalOutputDir
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
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 subFolder:String = ""

View File

@ -25,7 +25,6 @@ import android.text.SpannableStringBuilder
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
@ -57,7 +56,7 @@ class MainFragment : Fragment() {
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater,R.layout.main_fragment,container,false)
binding = MainFragmentBinding.inflate(inflater,container,false)
initializeAll()
binding.btnSearch.setOnClickListener {
if(!isOnline()){

View File

@ -24,26 +24,29 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.SimpleItemAnimator
import com.shabinder.spotiflyer.MainActivity
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
import com.shabinder.spotiflyer.models.DownloadStatus
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.networking.YoutubeMusicApi
import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
import com.shabinder.spotiflyer.utils.*
import com.shabinder.spotiflyer.utils.Provider.mainActivity
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject
@Suppress("DEPRECATION")
class SpotifyFragment : BaseFragment() {
@AndroidEntryPoint
class SpotifyFragment : TrackListFragment<SpotifyViewModel,SpotifyFragmentArgs>() {
override lateinit var baseViewModel: BaseViewModel
@Inject lateinit var youtubeMusicApi: YoutubeMusicApi
override lateinit var viewModel: SpotifyViewModel
override lateinit var adapter: TrackListAdapter
override var source: Source = Source.Spotify
private val viewModel: SpotifyViewModel
get() = baseViewModel as SpotifyViewModel
override val args: SpotifyFragmentArgs by navArgs()
@SuppressLint("SetJavaScriptEnabled")
override fun onCreateView(
@ -53,7 +56,7 @@ class SpotifyFragment : BaseFragment() {
super.onCreateView(inflater, container, savedInstanceState)
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 type = spotifyLink.substringBeforeLast('/', "Error").substringAfterLast('/')
@ -75,7 +78,7 @@ class SpotifyFragment : BaseFragment() {
showMessage("Implementing Soon, Stay Tuned!")
}
else{
viewModel.spotifySearch(type,link)
this.viewModel.spotifySearch(type,link)
binding.btnDownloadAll.setOnClickListener {
if(!isOnline()){
@ -86,16 +89,16 @@ class SpotifyFragment : BaseFragment() {
binding.downloadingFab.visibility = View.VISIBLE
rotateAnim(binding.downloadingFab)
for (track in viewModel.trackList.value!!){
for (track in this.viewModel.trackList.value!!){
if(track.downloaded != DownloadStatus.Downloaded){
track.downloaded = DownloadStatus.Downloading
adapter.notifyItemChanged(viewModel.trackList.value!!.indexOf(track))
adapter.notifyItemChanged(this.viewModel.trackList.value!!.indexOf(track))
}
}
showMessage("Processing!")
sharedViewModel.uiScope.launch(Dispatchers.Default){
val urlList = arrayListOf<String>()
viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
this@SpotifyFragment.viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
//Appending Source
urlList.add("spotify")
loadAllImages(
@ -103,7 +106,7 @@ class SpotifyFragment : BaseFragment() {
urlList
)
}
viewModel.uiScope.launch {
this.viewModel.uiScope.launch {
val finalList = viewModel.trackList.value
if(finalList.isNullOrEmpty())showMessage("Not Downloading Any Song")
DownloadHelper.downloadAllTracks(
@ -124,10 +127,10 @@ class SpotifyFragment : BaseFragment() {
* Basic Initialization
**/
private fun initializeAll() {
baseViewModel = ViewModelProvider(this).get(SpotifyViewModel::class.java)
adapter = TrackListAdapter(viewModel)
this.viewModel = ViewModelProvider(this).get(SpotifyViewModel::class.java)
adapter = TrackListAdapter(this.viewModel)
sharedViewModel.spotifyService.observe(viewLifecycleOwner, {
viewModel.spotifyService = it
this.viewModel.spotifyService = it
})
DownloadHelper.youtubeMusicApi = youtubeMusicApi
DownloadHelper.sharedViewModel = sharedViewModel

View File

@ -26,15 +26,15 @@ import com.shabinder.spotiflyer.models.DownloadStatus
import com.shabinder.spotiflyer.models.TrackDetails
import com.shabinder.spotiflyer.models.spotify.*
import com.shabinder.spotiflyer.networking.SpotifyService
import com.shabinder.spotiflyer.utils.BaseViewModel
import com.shabinder.spotiflyer.utils.Provider
import com.shabinder.spotiflyer.utils.TrackListViewModel
import com.shabinder.spotiflyer.utils.finalOutputDir
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
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 subFolder:String = ""
@ -145,6 +145,7 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
}
}
@Suppress("DEPRECATION")
private fun List<Track>.toTrackDetailsList() = this.map {
TrackDetails(
title = it.name.toString(),

View File

@ -22,31 +22,37 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
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.models.DownloadStatus
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
import com.shabinder.spotiflyer.utils.*
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject
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 var source: Source = Source.YouTube
private val viewModel: YoutubeViewModel
get() = baseViewModel as YoutubeViewModel
private val sampleDomain2 = "youtu.be"
private val sampleDomain1 = "youtube.com"
override val args: YoutubeFragmentArgs by navArgs()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)
baseViewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java)
adapter = TrackListAdapter(viewModel)
this.viewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java)
adapter = TrackListAdapter(this.viewModel)
binding.trackList.adapter = adapter
val args = YoutubeFragmentArgs.fromBundle(requireArguments())
@ -60,7 +66,7 @@ class YoutubeFragment : BaseFragment() {
if(link.contains("playlist",true) || link.contains("list",true)){
// Given Link is of a Playlist
val playlistId = link.substringAfter("?list=").substringAfter("&list=").substringBefore("&")
viewModel.getYTPlaylist(playlistId,ytDownloader)
this.viewModel.getYTPlaylist(playlistId,ytDownloader)
}else{//Given Link is of a Video
var searchId = "error"
if(link.contains(sampleDomain1,true) ){
@ -70,7 +76,7 @@ class YoutubeFragment : BaseFragment() {
searchId = link.substringAfterLast("/","error")
}
if(searchId != "error") {
viewModel.getYTTrack(searchId,ytDownloader)
this.viewModel.getYTTrack(searchId,ytDownloader)
}else{showMessage("Your Youtube Link is not of a Video!!")}
}
@ -87,10 +93,10 @@ class YoutubeFragment : BaseFragment() {
rotateAnim(binding.downloadingFab)
for (track in viewModel.trackList.value?: listOf()){
for (track in this.viewModel.trackList.value?: listOf()){
if(track.downloaded != DownloadStatus.Downloaded){
track.downloaded = DownloadStatus.Downloading
adapter.notifyItemChanged(viewModel.trackList.value!!.indexOf(track))
adapter.notifyItemChanged(this.viewModel.trackList.value!!.indexOf(track))
}
}
showMessage("Processing!")

View File

@ -27,8 +27,8 @@ import com.shabinder.spotiflyer.database.DownloadRecord
import com.shabinder.spotiflyer.models.DownloadStatus
import com.shabinder.spotiflyer.models.TrackDetails
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.TrackListViewModel
import com.shabinder.spotiflyer.utils.finalOutputDir
import com.shabinder.spotiflyer.utils.removeIllegalChars
import com.shabinder.spotiflyer.utils.showMessage
@ -37,7 +37,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : BaseViewModel(){
class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : TrackListViewModel(){
/*
* YT Album Art Schema
* HI-RES Url: https://i.ytimg.com/vi/$searchId/maxresdefault.jpg"

View File

@ -26,35 +26,27 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.github.kiulian.downloader.YoutubeDownloader
import androidx.navigation.NavArgs
import com.shabinder.spotiflyer.R
import com.shabinder.spotiflyer.SharedViewModel
import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding
import com.shabinder.spotiflyer.models.DownloadStatus
import com.shabinder.spotiflyer.models.TrackDetails
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.networking.GaanaInterface
import com.shabinder.spotiflyer.networking.YoutubeMusicApi
import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
abstract class BaseFragment : Fragment() {
abstract class TrackListFragment<VM : TrackListViewModel , args: NavArgs> : Fragment() {
@Inject open lateinit var youtubeMusicApi: YoutubeMusicApi
@Inject open lateinit var ytDownloader: YoutubeDownloader
@Inject open lateinit var gaanaInterface: GaanaInterface
open lateinit var sharedViewModel: SharedViewModel
open lateinit var binding: TrackListFragmentBinding
abstract var baseViewModel: BaseViewModel
abstract var adapter: TrackListAdapter
abstract var source: Source
protected lateinit var sharedViewModel: SharedViewModel
protected lateinit var binding: TrackListFragmentBinding
protected abstract var viewModel: VM
protected abstract var adapter: TrackListAdapter
protected abstract var source: Source
private var intentFilter: IntentFilter? = null
private var updateUIReceiver: BroadcastReceiver? = null
protected abstract val args:NavArgs
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -66,7 +58,7 @@ abstract class BaseFragment : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater,R.layout.track_list_fragment, container, false)
binding = TrackListFragmentBinding.inflate(inflater,container,false)
return binding.root
}
@ -74,11 +66,12 @@ abstract class BaseFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
initializeLiveDataObservers()
}
/**
*Live Data Observers
**/
open fun initializeLiveDataObservers() {
baseViewModel.trackList.observe(viewLifecycleOwner, {
private fun initializeLiveDataObservers() {
viewModel.trackList.observe(viewLifecycleOwner, {
if (it.isNotEmpty()){
Log.i("GaanaFragment","TrackList Updated")
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)
})
baseViewModel.title.observe(viewLifecycleOwner, {
viewModel.title.observe(viewLifecycleOwner, {
binding.titleView.text = it
})
}
open fun initializeBroadcast() {
private fun initializeBroadcast() {
intentFilter = IntentFilter()
intentFilter?.addAction("track_download_completed")
@ -105,13 +98,13 @@ abstract class BaseFragment : Fragment() {
if (intent != null){
val trackDetails = intent.getParcelableExtra<TrackDetails?>("track")
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")
if(position != -1) {
val track = baseViewModel.trackList.value?.get(position)
val track = viewModel.trackList.value?.get(position)
track?.let{
it.downloaded = DownloadStatus.Downloaded
baseViewModel.trackList.value?.set(position, it)
viewModel.trackList.value?.set(position, it)
adapter.notifyItemChanged(position)
checkIfAllDownloaded()
}
@ -133,8 +126,8 @@ abstract class BaseFragment : Fragment() {
requireActivity().unregisterReceiver(updateUIReceiver)
}
open fun checkIfAllDownloaded() {
if(!baseViewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){
private fun checkIfAllDownloaded() {
if(!viewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){
//All Tracks Downloaded
binding.btnDownloadAll.visibility = View.GONE
binding.downloadingFab.apply{

View File

@ -25,7 +25,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
abstract class BaseViewModel:ViewModel() {
abstract class TrackListViewModel:ViewModel() {
abstract var folderType:String
abstract var subFolder:String
open val trackList = MutableLiveData<MutableList<TrackDetails>>()

View File

@ -16,7 +16,8 @@
~ 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
android:angle="90"
android:centerColor="#0F6200FF"

Binary file not shown.

Binary file not shown.

View File

@ -15,12 +15,10 @@
~ You should have received a copy of the GNU General Public License
~ 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
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="@color/black"
android:layout_height="match_parent">
<TextView
@ -28,14 +26,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/text_background_accented"
style="@style/Widget.AppCompat.EditText.Gradient"
android:drawablePadding="5dp"
android:fontFamily="@font/raleway_semibold"
android:gravity="center"
android:padding="8dp"
android:text=" Download History "
android:textAlignment="center"
android:textColor="#E1FFFFFF"
android:textSize="21sp"
app:drawableStartCompat="@drawable/ic_history"
app:layout_constraintEnd_toEndOf="parent"
@ -83,5 +77,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -17,89 +17,81 @@
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="downloadRecord"
type="com.shabinder.spotiflyer.database.DownloadRecord" />
</data>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="92dp"
android:background="#000000"
android:paddingBottom="12dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="92dp"
android:background="#000000"
android:paddingBottom="12dp">
<ImageView
android:id="@+id/coverUrl"
android:layout_width="100dp"
android:layout_height="80dp"
android:layout_alignParentStart="true"
android:contentDescription="Track Image"
android:scaleType="centerInside"
android:src="@drawable/ic_song_placeholder" />
<ImageView
android:id="@+id/coverUrl"
android:layout_width="100dp"
android:layout_height="80dp"
android:layout_alignParentStart="true"
android:contentDescription="Track Image"
android:scaleType="centerInside"
android:src="@drawable/ic_song_placeholder" />
<TextView
android:id="@+id/item_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="12dp"
android:layout_marginTop="14dp"
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
android:id="@+id/item_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="12dp"
android:layout_marginTop="14dp"
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
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
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
android:id="@+id/totalItems"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/coverUrl"
android:layout_marginTop="7dp"
android:layout_marginEnd="25dp"
android:layout_marginBottom="15dp"
android:layout_toStartOf="@+id/btn_action"
android:paddingLeft="9dp"
android:text="50 Tracks"
android:textSize="12sp" />
<TextView
android:id="@+id/totalItems"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/coverUrl"
android:layout_marginTop="7dp"
android:layout_marginEnd="25dp"
android:layout_marginBottom="15dp"
android:layout_toStartOf="@+id/btn_action"
android:paddingLeft="9dp"
android:text="50 Tracks"
android:textSize="12sp" />
<ImageButton
android:id="@+id/btn_action"
android:layout_width="60dp"
android:layout_height="80dp"
android:layout_alignBottom="@+id/coverUrl"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="5dp"
android:backgroundTint="@color/black"
android:scaleType="centerInside"
android:src="@drawable/ic_share_open"
android:tint="@null" />
<ImageButton
android:id="@+id/btn_action"
android:layout_width="60dp"
android:layout_height="80dp"
android:layout_alignBottom="@+id/coverUrl"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="5dp"
android:backgroundTint="@color/black"
android:scaleType="centerInside"
android:src="@drawable/ic_share_open"
android:tint="@null" />
</RelativeLayout>
</layout>
</RelativeLayout>

View File

@ -16,39 +16,36 @@
~ 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: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
android:id="@+id/mainActivity"
<fragment
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:background="@color/black"
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:visibility="invisible"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="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" />
<fragment
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>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -15,47 +15,40 @@
~ You should have received a copy of the GNU General Public License
~ 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
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_height="match_parent"
android:fillViewport="true"
android:background="@color/black"
tools:ignore="HardcodedText"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/linkSearch"
android:layout_width="wrap_content"
style="@style/Widget.AppCompat.EditText.Gradient"
android:layout_height="46dp"
android:layout_marginTop="24dp"
android:background="@drawable/text_background_accented"
android:ems="10"
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_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
android:importantForAutofill="no"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_search"
android:layout_width="wrap_content"
style="@style/Widget.AppCompat.Button.Colored.Gradient"
android:layout_height="44dp"
android:background="@drawable/btn_design"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:text="Search"
android:textColor="@color/black"
android:textSize="16sp"
android:fontFamily="@font/nunito_sans_light"
android:text=" Search "
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/linkSearch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/linkSearch"
@ -75,19 +68,16 @@
app:layout_collapseMode="parallax"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linkSearch" />
app:layout_constraintTop_toBottomOf="@+id/linkSearch"
tools:ignore="UnusedAttribute" />
<ImageButton
android:id="@+id/btn_history"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/transparent"
android:scaleType="fitCenter"
style="@style/Widget.AppCompat.ImageButton.40dp"
app:layout_constraintBottom_toBottomOf="@+id/appLogo"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_history" />
android:contentDescription="Open Download History Button"
app:srcCompat="@drawable/ic_history"/>
<TextView
android:id="@+id/appName"
@ -95,16 +85,13 @@
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:fontFamily="@font/raleway_semibold"
android:gravity="end"
android:text='"SpotiFlyer"'
android:textAlignment="viewEnd"
android:textColor="#9AB3FF"
android:textColor="@color/colorAccent"
android:textSize="40sp"
android:typeface="normal"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appLogo" />
app:layout_constraintTop_toBottomOf="@id/appLogo"
/>
<TextView
android:id="@+id/appSubTitle"
@ -120,50 +107,26 @@
app:layout_constraintStart_toStartOf="@+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
android:id="@+id/btn_spotify"
android:layout_width="46dp"
android:layout_height="46dp"
style="@style/Widget.AppCompat.ImageButton.platformIcon"
android:layout_marginEnd="2dp"
android:background="@color/black"
android:padding="5dp"
android:scaleType="fitCenter"
android:contentDescription="Open Spotify App Button"
android:src="@drawable/ic_spotify_logo"
app:layout_constraintBottom_toBottomOf="@+id/platforms"
app:layout_constraintEnd_toStartOf="@+id/btn_youtube"
app:layout_constraintStart_toEndOf="@+id/platforms"
app:layout_constraintTop_toTopOf="@+id/platforms" />
android:padding="6dp"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@+id/appSubTitle"
app:layout_constraintTop_toBottomOf="@+id/appSubTitle"/>
<ImageButton
android:id="@+id/btn_youtube"
android:layout_width="52dp"
android:layout_height="52dp"
android:background="@color/black"
android:padding="5dp"
android:scaleType="fitCenter"
style="@style/Widget.AppCompat.ImageButton.platformIcon"
android:src="@drawable/ic_youtube"
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_constraintEnd_toEndOf="@+id/appSubTitle"
app:layout_constraintTop_toTopOf="@+id/btn_spotify" />
<TextView
@ -171,11 +134,11 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="24dp"
android:gravity="center"
android:text="Usage Instructions!"
android:textAlignment="center"
android:textColor="#D0838383"
android:textSize="14sp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="@+id/developer_insta_spotify"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btn_linkedin"
@ -189,6 +152,7 @@
android:background="@drawable/text_background_accented"
android:drawableEnd="@drawable/ic_mug"
android:drawablePadding="5dp"
android:contentDescription="Donate Money Button"
android:fontFamily="@font/capriola"
android:foreground="@drawable/rounded_gradient"
android:gravity="end|center_vertical"
@ -214,39 +178,30 @@
<ImageButton
android:id="@+id/btn_github_spotify"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:background="@color/black"
android:padding="5dp"
android:scaleType="fitCenter"
style="@style/Widget.AppCompat.ImageButton.platformIcon"
android:src="@drawable/ic_github"
app:layout_constraintBottom_toTopOf="@+id/btn_linkedin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_youtube"
app:layout_constraintVertical_chainStyle="packed" />
android:contentDescription="Open Github App Button"
app:layout_constraintVertical_chainStyle="packed"/>
<ImageButton
android:id="@+id/btn_linkedin"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:background="@color/black"
android:padding="5dp"
android:scaleType="fitCenter"
style="@style/Widget.AppCompat.ImageButton.platformIcon"
android:src="@drawable/ic_linkedin"
app:layout_constraintBottom_toTopOf="@+id/developer_insta_spotify"
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
android:id="@+id/developer_insta_spotify"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:background="@color/black"
android:padding="5dp"
android:scaleType="fitCenter"
style="@style/Widget.AppCompat.ImageButton.platformIcon"
android:src="@drawable/ic_instagram"
app:layout_constraintBottom_toTopOf="@+id/btn_donate"
app:layout_constraintStart_toStartOf="parent"
android:contentDescription="Open Instagram App Button"
app:layout_constraintTop_toBottomOf="@+id/btn_linkedin" />
<TextView
@ -289,5 +244,4 @@
app:layout_constraintStart_toEndOf="@+id/heart" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>
</ScrollView>

View File

@ -16,16 +16,16 @@
~ 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
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:layout_width="match_parent"
android:background="@color/black"
android:layout_height="match_parent"
android:layout_marginTop="25dp"
android:fitsSystemWindows="true"
android:paddingTop="16dp"
tools:context=".ui.spotify.SpotifyFragment">
<androidx.appcompat.widget.AppCompatButton
@ -155,4 +155,4 @@
app:layout_constraintTop_toBottomOf="@id/appbar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

View File

@ -16,97 +16,84 @@
~ You should have received a copy of the GNU General Public License
~ 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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="track"
type="com.shabinder.spotiflyer.models.spotify.Track" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
<ImageView
android:id="@+id/imageUrl"
android:layout_width="100dp"
android:layout_height="80dp"
android:background="#000000"
android:layout_marginBottom="12dp"
>
android:contentDescription="Track Image"
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
android:id="@+id/imageUrl"
android:layout_width="100dp"
android:layout_height="80dp"
android:contentDescription="Track Image"
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" />
<TextView
android:id="@+id/track_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="14dp"
android:fontFamily="@font/raleway_semibold"
android:letterSpacing="0.04"
android:lines="1"
android:text="The Spectre"
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
android:id="@+id/track_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="14dp"
android:fontFamily="@font/raleway_semibold"
android:letterSpacing="0.04"
android:lines="1"
android:text="The Spectre"
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
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
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
android:id="@+id/duration"
style="@style/TextAppearance.AppCompat.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="3dp"
android:paddingLeft="9dp"
android:text="4 minutes, 20 sec"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/artist"
app:layout_constraintEnd_toStartOf="@+id/btn_download"
app:layout_constraintStart_toEndOf="@+id/artist"
app:layout_constraintTop_toTopOf="@+id/artist" />
<TextView
android:id="@+id/duration"
style="@style/TextAppearance.AppCompat.Body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="3dp"
android:paddingLeft="9dp"
android:text="4 minutes, 20 sec"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/artist"
app:layout_constraintEnd_toStartOf="@+id/btn_download"
app:layout_constraintStart_toEndOf="@+id/artist"
app:layout_constraintTop_toTopOf="@+id/artist" />
<ImageButton
android:id="@+id/btn_download"
android:layout_width="60dp"
android:layout_height="0dp"
android:backgroundTint="@color/black"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_arrow" />
<ImageButton
android:id="@+id/btn_download"
android:layout_width="60dp"
android:layout_height="0dp"
android:backgroundTint="@color/black"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_arrow" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -20,10 +20,12 @@
<resources>
<color name="colorPrimary">#FC5C7D</color>
<color name="colorPrimaryDark">#CE1CFF</color>
<color name="colorAccent">#799BFF</color>
<color name="colorAccent">#9AB3FF</color>
<color name="white">#FFFFFF</color>
<color name="grey">#99FFFFFF</color>
<color name="black">#000000</color>
<color name="dark">#121212</color>
<color name="successGreen">#4BB543</color>
<color name="errorRed">#FF9494</color>
</resources>

View File

@ -19,12 +19,22 @@
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- 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="colorOnPrimary">@color/white</item>
<item name="colorSecondary">@color/colorPrimaryDark</item>
<item name="colorOnSecondary">@color/white</item>
<item name="android:textColor">#FFFFFF</item>
<item name="colorAccent">#6A82FB</item>
<item name="android:outlineAmbientShadowColor" tools:targetApi="p">#A9B200FF</item>
<item name="android:radius">11dp</item>
<item name="android:textColorHint">@color/grey</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:outlineAmbientShadowColor" tools:targetApi="p">@color/colorPrimaryDark</item>
<item name="android:radius">12dp</item>
<!-- Text Appearances !-->
<!-- use our brand's custom TextAppearance4 !-->
<item name="textAppearanceHeadline4">@style/TextAppearance.AppTheme.Headline4</item>
@ -32,7 +42,42 @@
<item name="textAppearanceBody2">@style/TextAppearance.MaterialComponents.Body2</item>
</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">
<item name="shapeAppearanceMediumComponent">@style/CutShapeAppearance</item>
<item name="buttonBarPositiveButtonStyle">@style/Alert.Button.Positive</item>