App Name Set To SpotiFlyer! and Separated Download Directories.Ready for release!

This commit is contained in:
shabinder 2020-07-25 19:04:39 +05:30
parent d429925a62
commit 0b27456fcf
41 changed files with 455 additions and 170 deletions

View File

@ -1,13 +1,17 @@
<component name="ProjectDictionaryState"> <component name="ProjectDictionaryState">
<dictionary name="shabinder"> <dictionary name="shabinder">
<words> <words>
<w>flyer</w>
<w>moshi</w> <w>moshi</w>
<w>musicforeveryone</w> <w>musicforeveryone</w>
<w>musicplaceholder</w> <w>musicplaceholder</w>
<w>shabinder</w> <w>shabinder</w>
<w>singh</w> <w>singh</w>
<w>spoti</w>
<w>spotiflyer</w>
<w>spotify</w> <w>spotify</w>
<w>spotifydownloader</w> <w>spotifydownloader</w>
<w>spotifyler</w>
</words> </words>
</dictionary> </dictionary>
</component> </component>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

View File

@ -1,3 +1,20 @@
/*
* Copyright (C) 2020 Shabinder Singh
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
@ -15,7 +32,7 @@ android {
} }
defaultConfig { defaultConfig {
applicationId 'com.shabinder.musicforeveryone' applicationId 'com.shabinder.spotiflyer'
minSdkVersion 22 minSdkVersion 22
targetSdkVersion 29 targetSdkVersion 29
versionCode 1 versionCode 1
@ -55,9 +72,9 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7"
implementation "androidx.room:room-runtime:2.2.5" // implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5" // kapt "androidx.room:room-compiler:2.2.5"
implementation "androidx.room:room-ktx:2.2.5" // implementation "androidx.room:room-ktx:2.2.5"
implementation "com.github.bumptech.glide:glide:4.11.0" implementation "com.github.bumptech.glide:glide:4.11.0"
kapt "com.github.bumptech.glide:compiler:4.11.0" kapt "com.github.bumptech.glide:compiler:4.11.0"
@ -73,7 +90,7 @@ dependencies {
implementation "com.squareup.moshi:moshi-kotlin:1.9.3" implementation "com.squareup.moshi:moshi-kotlin:1.9.3"
implementation "com.squareup.retrofit2:converter-moshi:2.9.0" implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
implementation 'com.shreyaspatil:EasyUpiPayment:2.2'
implementation 'com.github.sealedtx:java-youtube-downloader:2.2.2' implementation 'com.github.sealedtx:java-youtube-downloader:2.2.2'
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava' implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'

View File

@ -1,22 +0,0 @@
package com.shabinder.musicForEveryone
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.shabinder.spotifydownloader", appContext.packageName)
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2020 Shabinder Singh
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.shabinder.spotiflyer
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.shabinder.spotifydownloader", appContext.packageName)
}
}

View File

@ -1,6 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 Shabinder Singh
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.shabinder.musicForEveryone"> package="com.shabinder.spotiflyer">
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" />
@ -20,7 +37,7 @@
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity android:name="com.shabinder.musicForEveryone.MainActivity"> <activity android:name="com.shabinder.spotiflyer.MainActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
@ -28,7 +45,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="com.shabinder.musicForEveryone.splash.SplashScreen" <activity android:name="com.shabinder.spotiflyer.splash.SplashScreen"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/Theme.Transparent"> android:theme="@style/Theme.Transparent">

View File

@ -1,21 +0,0 @@
package com.shabinder.musicForEveryone.utils
import android.widget.ImageView
import androidx.core.net.toUri
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.shabinder.musicForEveryone.R
@BindingAdapter("imageUrl")
fun bindImage(imgView: ImageView, imgUrl: String?) {
imgUrl?.let {
val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()
Glide.with(imgView.context)
.load(imgUri)
.apply(RequestOptions()
.placeholder(R.drawable.ic_song_placeholder)
.error(R.drawable.ic_musicplaceholder))
.into(imgView)
}
}

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone package com.shabinder.spotiflyer
import android.Manifest import android.Manifest
import android.app.DownloadManager import android.app.DownloadManager
@ -30,11 +30,12 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.github.kiulian.downloader.YoutubeDownloader import com.github.kiulian.downloader.YoutubeDownloader
import com.shabinder.musicForEveryone.databinding.MainActivityBinding import com.shabinder.spotiflyer.databinding.MainActivityBinding
import com.shabinder.musicForEveryone.downloadHelper.DownloadHelper import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
import com.shabinder.musicForEveryone.utils.SpotifyService import com.shabinder.spotiflyer.utils.SpotifyService
import com.shabinder.musicForEveryone.utils.SpotifyServiceToken import com.shabinder.spotiflyer.utils.SpotifyServiceToken
import com.shabinder.musicForEveryone.utils.YoutubeInterface import com.shabinder.spotiflyer.utils.YoutubeInterface
import com.shreyaspatil.EasyUpiPayment.EasyUpiPayment
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -45,6 +46,7 @@ import okhttp3.Response
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory import retrofit2.converter.moshi.MoshiConverterFactory
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
class MainActivity : AppCompatActivity() ,DownloadHelper{ class MainActivity : AppCompatActivity() ,DownloadHelper{
private lateinit var binding: MainActivityBinding private lateinit var binding: MainActivityBinding
@ -52,12 +54,12 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
private var spotifyService : SpotifyService? = null private var spotifyService : SpotifyService? = null
private var spotifyServiceToken : SpotifyServiceToken? = null private var spotifyServiceToken : SpotifyServiceToken? = null
private var downloadManager : DownloadManager? = null private var downloadManager : DownloadManager? = null
// private val redirectUri = "musicforeveryone://callback" // private val redirectUri = "spotiflyer://callback"
private val clientId:String = "694d8bf4f6ec420fa66ea7fb4c68f89d" private val clientId:String = "694d8bf4f6ec420fa66ea7fb4c68f89d"
private val clientSecret:String = "02ca2d4021a7452dae2328b47a6e8fe8" private val clientSecret:String = "02ca2d4021a7452dae2328b47a6e8fe8"
private var isConnected: Boolean = false private var isConnected: Boolean = false
private var sharedPref :SharedPreferences? = null private var sharedPref :SharedPreferences? = null
private var easyUpiPayment:EasyUpiPayment? = null
private var token :String ="" private var token :String =""
private lateinit var sharedViewModel: SharedViewModel private lateinit var sharedViewModel: SharedViewModel
@ -100,9 +102,22 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
Log.i("Connection Status",isConnected.toString()) Log.i("Connection Status",isConnected.toString())
easyUpiPayment = EasyUpiPayment.Builder()
.with(this)
.setPayeeVpa("technoshab@paytm")
.setPayeeName("Shabinder Singh")
.setTransactionId("UNIQUE_TRANSACTION_ID")
.setTransactionRefId("UNIQUE_TRANSACTION_REF_ID")
.setDescription("Thanks for donating")
.setAmount("39.00")
.build()
sharedViewModel.easyUpiPayment = easyUpiPayment
handleIntentFromExternalActivity() handleIntentFromExternalActivity()
} }
/** /**
* Adding my own new Spotify Web Api Requests! * Adding my own new Spotify Web Api Requests!
* */ * */
@ -162,7 +177,7 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
} }
private fun authenticateSpotify() { fun authenticateSpotify() {
if (spotifyServiceToken == null) { if (spotifyServiceToken == null) {
getSpotifyToken() getSpotifyToken()
} }

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone package com.shabinder.spotiflyer
import android.app.DownloadManager import android.app.DownloadManager
import android.content.Context import android.content.Context
@ -24,10 +24,11 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.github.kiulian.downloader.YoutubeDownloader import com.github.kiulian.downloader.YoutubeDownloader
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.shabinder.musicForEveryone.models.Album import com.shabinder.spotiflyer.models.Album
import com.shabinder.musicForEveryone.models.Playlist import com.shabinder.spotiflyer.models.Playlist
import com.shabinder.musicForEveryone.models.Track import com.shabinder.spotiflyer.models.Track
import com.shabinder.musicForEveryone.utils.SpotifyService import com.shabinder.spotiflyer.utils.SpotifyService
import com.shreyaspatil.EasyUpiPayment.EasyUpiPayment
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -39,6 +40,8 @@ class SharedViewModel : ViewModel() {
var ytDownloader : YoutubeDownloader? = null var ytDownloader : YoutubeDownloader? = null
var downloadManager : DownloadManager? = null var downloadManager : DownloadManager? = null
var isConnected = MutableLiveData<Boolean>().apply { value = false } var isConnected = MutableLiveData<Boolean>().apply { value = false }
var easyUpiPayment: EasyUpiPayment? = null
private var viewModelJob = Job() private var viewModelJob = Job()

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.downloadHelper package com.shabinder.spotiflyer.downloadHelper
import android.app.DownloadManager import android.app.DownloadManager
import android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED import android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED
@ -25,9 +25,9 @@ import android.util.Log
import com.github.kiulian.downloader.YoutubeDownloader import com.github.kiulian.downloader.YoutubeDownloader
import com.github.kiulian.downloader.model.formats.Format import com.github.kiulian.downloader.model.formats.Format
import com.github.kiulian.downloader.model.quality.AudioQuality import com.github.kiulian.downloader.model.quality.AudioQuality
import com.shabinder.musicForEveryone.fragments.MainFragment import com.shabinder.spotiflyer.fragments.MainFragment
import com.shabinder.musicForEveryone.models.Track import com.shabinder.spotiflyer.models.Track
import com.shabinder.musicForEveryone.utils.YoutubeInterface import com.shabinder.spotiflyer.utils.YoutubeInterface
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File import java.io.File
@ -37,13 +37,18 @@ interface DownloadHelper {
/** /**
* Function To Download All Tracks Available in a List * Function To Download All Tracks Available in a List
**/ **/
suspend fun downloadAllTracks(trackList : List<Track>, ytDownloader: YoutubeDownloader?, downloadManager: DownloadManager?) { suspend fun downloadAllTracks(
trackList.forEach { downloadTrack(null,ytDownloader,downloadManager,"${it.name} ${it.artists?.get(0)?.name ?:""}") } type:String,
subFolder: String?,
trackList: List<Track>, ytDownloader: YoutubeDownloader?, downloadManager: DownloadManager?) {
trackList.forEach { downloadTrack(null,type,subFolder,ytDownloader,downloadManager,"${it.name} ${it.artists?.get(0)?.name ?:""}") }
} }
suspend fun downloadTrack( suspend fun downloadTrack(
mainFragment: MainFragment?, mainFragment: MainFragment?,
type:String,
subFolder:String?,
ytDownloader: YoutubeDownloader?, ytDownloader: YoutubeDownloader?,
downloadManager: DownloadManager?, downloadManager: DownloadManager?,
searchQuery: String searchQuery: String
@ -63,7 +68,7 @@ interface DownloadHelper {
val audioUrl = format.url() val audioUrl = format.url()
Log.i("DHelper Link Found", audioUrl) Log.i("DHelper Link Found", audioUrl)
if (audioUrl != null) { if (audioUrl != null) {
downloadFile(audioUrl, downloadManager, details!!.title()) downloadFile(audioUrl, downloadManager, details!!.title(),subFolder,type)
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
mainFragment?.showToast("Download Started") mainFragment?.showToast("Download Started")
} }
@ -77,7 +82,7 @@ interface DownloadHelper {
val audioUrl = format.url() val audioUrl = format.url()
Log.i("DHelper Link Found", audioUrl) Log.i("DHelper Link Found", audioUrl)
if (audioUrl != null) { if (audioUrl != null) {
downloadFile(audioUrl, downloadManager, details!!.title()) downloadFile(audioUrl, downloadManager, details!!.title(),subFolder,type)
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
mainFragment?.showToast("Download Started") mainFragment?.showToast("Download Started")
} }
@ -91,7 +96,7 @@ interface DownloadHelper {
val audioUrl = format.url() val audioUrl = format.url()
Log.i("DHelper Link Found", audioUrl) Log.i("DHelper Link Found", audioUrl)
if (audioUrl != null) { if (audioUrl != null) {
downloadFile(audioUrl, downloadManager, details!!.title()) downloadFile(audioUrl, downloadManager, details!!.title(),subFolder,type)
withContext(Dispatchers.Main){ withContext(Dispatchers.Main){
mainFragment?.showToast("Download Started") mainFragment?.showToast("Download Started")
} }
@ -113,11 +118,11 @@ interface DownloadHelper {
/** /**
* Downloading Using Android Download Manager * Downloading Using Android Download Manager
* */ * */
suspend fun downloadFile(url: String, downloadManager: DownloadManager?, title: String) { suspend fun downloadFile(url: String, downloadManager: DownloadManager?, title: String,subFolder: String?,type: String) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val audioUri = Uri.parse(url) val audioUri = Uri.parse(url)
val outputDir = val outputDir:String =
File.separator + "Spotify-Downloads" + File.separator + "${removeIllegalChars(title)}.mp3" File.separator + "SpotiFlyer" + File.separator + type + File.separator + (if(subFolder == null){""}else{subFolder + File.separator}) + "${removeIllegalChars(title)}.mp3"
val request = DownloadManager.Request(audioUri) val request = DownloadManager.Request(audioUri)
.setAllowedNetworkTypes( .setAllowedNetworkTypes(

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.fragments package com.shabinder.spotiflyer.fragments
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -33,14 +33,15 @@ import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.shabinder.musicForEveryone.R import com.shabinder.spotiflyer.MainActivity
import com.shabinder.musicForEveryone.SharedViewModel import com.shabinder.spotiflyer.R
import com.shabinder.musicForEveryone.databinding.MainFragmentBinding import com.shabinder.spotiflyer.SharedViewModel
import com.shabinder.musicForEveryone.downloadHelper.DownloadHelper import com.shabinder.spotiflyer.databinding.MainFragmentBinding
import com.shabinder.musicForEveryone.models.Track import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
import com.shabinder.musicForEveryone.recyclerView.TrackListAdapter import com.shabinder.spotiflyer.models.Track
import com.shabinder.musicForEveryone.utils.SpotifyService import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
import com.shabinder.musicForEveryone.utils.bindImage import com.shabinder.spotiflyer.utils.SpotifyService
import com.shabinder.spotiflyer.utils.bindImage
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -73,6 +74,10 @@ class MainFragment : Fragment(),DownloadHelper {
binding.usage.text = spanStringBuilder binding.usage.text = spanStringBuilder
openSpotifyButton() openSpotifyButton()
binding.btnDonate.setOnClickListener {
sharedViewModel.easyUpiPayment?.startPayment()
}
binding.btnSearch.setOnClickListener { binding.btnSearch.setOnClickListener {
sharedViewModel.isConnected.value = isOnline() sharedViewModel.isConnected.value = isOnline()
spotifyLink = binding.linkSearch.text.toString() spotifyLink = binding.linkSearch.text.toString()
@ -82,6 +87,10 @@ class MainFragment : Fragment(),DownloadHelper {
Log.i("Fragment", "$type : $link") Log.i("Fragment", "$type : $link")
if(sharedViewModel.spotifyService == null){
(activity as MainActivity).authenticateSpotify()
}
if (type == "Error" || link == "Error") { if (type == "Error" || link == "Error") {
showToast("Please Check Your Link!") showToast("Please Check Your Link!")
} else if(sharedViewModel.isConnected.value == false){ } else if(sharedViewModel.isConnected.value == false){
@ -115,6 +124,8 @@ class MainFragment : Fragment(),DownloadHelper {
sharedViewModel.uiScope.launch { sharedViewModel.uiScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
downloadAllTracks( downloadAllTracks(
"Tracks",
null,
trackList, trackList,
sharedViewModel.ytDownloader, sharedViewModel.ytDownloader,
sharedViewModel.downloadManager sharedViewModel.downloadManager
@ -141,6 +152,8 @@ class MainFragment : Fragment(),DownloadHelper {
sharedViewModel.uiScope.launch { sharedViewModel.uiScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
downloadAllTracks( downloadAllTracks(
"Albums",
albumObject.name,
trackList, trackList,
sharedViewModel.ytDownloader, sharedViewModel.ytDownloader,
sharedViewModel.downloadManager sharedViewModel.downloadManager
@ -167,6 +180,8 @@ class MainFragment : Fragment(),DownloadHelper {
sharedViewModel.uiScope.launch { sharedViewModel.uiScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
downloadAllTracks( downloadAllTracks(
"Playlists",
playlistObject.name,
trackList, trackList,
sharedViewModel.ytDownloader, sharedViewModel.ytDownloader,
sharedViewModel.downloadManager sharedViewModel.downloadManager
@ -189,7 +204,8 @@ class MainFragment : Fragment(),DownloadHelper {
} }
} }
handleIntent() handleIntent()
if(savedInstanceState != null && binding.linkSearch.text.toString() != ""){ //Handling Device Configuration Change
if(savedInstanceState != null && savedInstanceState["searchLink"].toString() != ""){
binding.linkSearch.setText(savedInstanceState["searchLink"].toString()) binding.linkSearch.setText(savedInstanceState["searchLink"].toString())
binding.btnSearch.performClick() binding.btnSearch.performClick()
setUiVisibility() setUiVisibility()

View File

@ -15,14 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.fragments package com.shabinder.spotiflyer.fragments
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.shabinder.musicForEveryone.models.Track import com.shabinder.spotiflyer.models.Track
class MainViewModel: ViewModel() { class MainViewModel: ViewModel() {
var searchLink:String = "" var searchLink:String = ""
var trackList = mutableListOf<Track>() var trackList = mutableListOf<Track>()
var coverUrl:String = "" var coverUrl:String = ""
} }

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class Artist( data class Artist(
var external_urls: Map<String?, String?>? = null, var external_urls: Map<String?, String?>? = null,
var href: String? = null, var href: String? = null,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class Copyright( data class Copyright(
var text: String? = null, var text: String? = null,
var type: String? = null) var type: String? = null)

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class Episodes( data class Episodes(
var audio_preview_url:String?, var audio_preview_url:String?,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class Followers( data class Followers(
var href: String? = null, var href: String? = null,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class Image( data class Image(
var width: Int? = null, var width: Int? = null,
var height: Int? = null, var height: Int? = null,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class LinkedTrack( data class LinkedTrack(
var external_urls: Map<String?, String?>? = null, var external_urls: Map<String?, String?>? = null,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class PagingObject<T>( data class PagingObject<T>(
var href: String? = null, var href: String? = null,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
import com.squareup.moshi.Json import com.squareup.moshi.Json
data class Playlist( data class Playlist(

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class PlaylistTrack( data class PlaylistTrack(
var added_at: String? = null, var added_at: String? = null,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class Token( data class Token(
var access_token:String, var access_token:String,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class Track( data class Track(
var artists: List<Artist?>? = null, var artists: List<Artist?>? = null,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class UserPrivate( data class UserPrivate(
val country:String, val country:String,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.models package com.shabinder.spotiflyer.models
data class UserPublic( data class UserPublic(
var display_name: String? = null, var display_name: String? = null,

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.recyclerView package com.shabinder.spotiflyer.recyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -24,12 +24,12 @@ import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.shabinder.musicForEveryone.R import com.shabinder.spotiflyer.R
import com.shabinder.musicForEveryone.SharedViewModel import com.shabinder.spotiflyer.SharedViewModel
import com.shabinder.musicForEveryone.downloadHelper.DownloadHelper import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
import com.shabinder.musicForEveryone.fragments.MainFragment import com.shabinder.spotiflyer.fragments.MainFragment
import com.shabinder.musicForEveryone.models.Track import com.shabinder.spotiflyer.models.Track
import com.shabinder.musicForEveryone.utils.bindImage import com.shabinder.spotiflyer.utils.bindImage
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class TrackListAdapter:RecyclerView.Adapter<TrackListAdapter.ViewHolder>(),DownloadHelper { class TrackListAdapter:RecyclerView.Adapter<TrackListAdapter.ViewHolder>(),DownloadHelper {
@ -60,7 +60,7 @@ class TrackListAdapter:RecyclerView.Adapter<TrackListAdapter.ViewHolder>(),Downl
holder.duration.text = "${item.duration_ms/1000/60} minutes, ${(item.duration_ms/1000)%60} sec" holder.duration.text = "${item.duration_ms/1000/60} minutes, ${(item.duration_ms/1000)%60} sec"
holder.downloadBtn.setOnClickListener{ holder.downloadBtn.setOnClickListener{
sharedViewModel.uiScope.launch { sharedViewModel.uiScope.launch {
downloadTrack(mainFragment,sharedViewModel.ytDownloader,sharedViewModel.downloadManager,"${item.name} ${item.artists?.get(0)!!.name?:""}") downloadTrack(mainFragment,"Tracks",null,sharedViewModel.ytDownloader,sharedViewModel.downloadManager,"${item.name} ${item.artists?.get(0)!!.name?:""}")
} }
} }

View File

@ -15,14 +15,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.splash package com.shabinder.spotiflyer.splash
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.shabinder.musicForEveryone.MainActivity import com.shabinder.spotiflyer.MainActivity
import com.shabinder.musicForEveryone.R import com.shabinder.spotiflyer.R
class SplashScreen : AppCompatActivity(){ class SplashScreen : AppCompatActivity(){

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2020 Shabinder Singh
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.shabinder.spotiflyer.utils
import android.widget.ImageView
import androidx.core.net.toUri
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.shabinder.spotiflyer.R
@BindingAdapter("imageUrl")
fun bindImage(imgView: ImageView, imgUrl: String?) {
imgUrl?.let {
val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()
Glide.with(imgView.context)
.load(imgUri)
.apply(RequestOptions()
.placeholder(R.drawable.ic_song_placeholder)
.error(R.drawable.ic_musicplaceholder))
.into(imgView)
}
}

View File

@ -15,9 +15,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.shabinder.musicForEveryone.utils package com.shabinder.spotiflyer.utils
import com.shabinder.musicForEveryone.models.* import com.shabinder.spotiflyer.models.*
import retrofit2.http.* import retrofit2.http.*
/* /*

View File

@ -1,4 +1,21 @@
package com.shabinder.musicForEveryone.utils /*
* Copyright (C) 2020 Shabinder Singh
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.shabinder.spotiflyer.utils
import android.util.Log import android.util.Log
import com.google.api.client.http.HttpRequestInitializer import com.google.api.client.http.HttpRequestInitializer
@ -16,7 +33,7 @@ object YoutubeInterface {
fun youtubeConnector() { fun youtubeConnector() {
youtube = youtube =
YouTube.Builder(NetHttpTransport(), JacksonFactory(), HttpRequestInitializer { }) YouTube.Builder(NetHttpTransport(), JacksonFactory(), HttpRequestInitializer { })
.setApplicationName("Music For Everyone").build() .setApplicationName("spotifyler").build()
try { try {
query = youtube?.search()?.list("id,snippet") query = youtube?.search()?.list("id,snippet")
query?.key = apiKey query?.key = apiKey

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 Shabinder Singh
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="Amita">
</font-family>

View File

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 Shabinder Singh
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android" <layout 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">
@ -105,13 +122,14 @@
</com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:id="@+id/open_spotify" android:id="@+id/open_spotify"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
app:layout_constraintTop_toBottomOf="@id/appbar" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"> app:layout_constraintTop_toBottomOf="@id/appbar">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint_layout" android:id="@+id/constraint_layout"
@ -125,16 +143,30 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:fontFamily="@font/raleway_semibold" android:fontFamily="@font/raleway_semibold"
android:text='"Spotify Downloader"' android:gravity="end"
android:textAlignment="center" android:text='"SpotiFlyer"'
android:textAlignment="viewEnd"
android:textColor="#9AB3FF" android:textColor="#9AB3FF"
android:textSize="32sp" android:textSize="34sp"
android:textStyle="bold" android:textStyle="bold"
android:visibility="visible" 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_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:fontFamily="@font/raleway_semibold"
android:text=" -Spotify Downloader"
android:textAlignment="center"
android:textColor="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="@+id/title_view"
app:layout_constraintStart_toStartOf="@+id/title_view"
app:layout_constraintTop_toBottomOf="@+id/title_view" />
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -153,7 +185,7 @@
android:id="@+id/btn_openSpotify" android:id="@+id/btn_openSpotify"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="42dp" android:layout_height="42dp"
android:layout_marginTop="100dp" android:layout_marginTop="80dp"
android:background="@drawable/text_background" android:background="@drawable/text_background"
android:fontFamily="@font/raleway_semibold" android:fontFamily="@font/raleway_semibold"
android:padding="12dp" android:padding="12dp"
@ -162,39 +194,55 @@
android:textSize="13sp" android:textSize="13sp"
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/title_view" /> app:layout_constraintTop_toBottomOf="@+id/textView2" />
<androidx.appcompat.widget.AppCompatButton <androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_donate" android:id="@+id/btn_donate"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="46dp" android:layout_height="44dp"
android:layout_marginTop="24dp"
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:fontFamily="@font/capriola"
android:foreground="@drawable/rounded_gradient" android:foreground="@drawable/rounded_gradient"
android:gravity="end|center_vertical" android:gravity="end|center_vertical"
android:padding="8dp" android:padding="5dp"
android:text="Buy Me a Coffee" android:text="Buy Me a Coffee"
android:textSize="14sp" android:textSize="13sp"
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/usage" /> app:layout_constraintTop_toBottomOf="@+id/textView4" />
<TextView <TextView
android:id="@+id/usage" android:id="@+id/usage"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
android:layout_marginTop="100dp" android:layout_marginTop="90dp"
android:text="Usage Instructions!" android:text="Usage Instructions!"
android:textColor="#D0838383" android:textColor="#D0838383"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/btn_donate" app:layout_constraintBottom_toTopOf="@+id/btn_donate"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_openSpotify" /> app:layout_constraintTop_toBottomOf="@+id/btn_openSpotify" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:padding="4dp"
android:text="Like This App?"
android:textColor="@color/colorPrimary"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@+id/btn_donate"
app:layout_constraintEnd_toEndOf="@+id/btn_donate"
app:layout_constraintStart_toStartOf="@+id/btn_donate"
app:layout_constraintTop_toBottomOf="@+id/usage" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/track_list" android:id="@+id/track_list"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 Shabinder Singh
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<navigation xmlns:android="http://schemas.android.com/apk/res/android" <navigation 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"
@ -7,7 +24,7 @@
<fragment <fragment
android:id="@+id/mainFragment" android:id="@+id/mainFragment"
android:name="com.shabinder.musicForEveryone.fragments.MainFragment" android:name="com.shabinder.spotiflyer.fragments.MainFragment"
android:label="main_fragment" android:label="main_fragment"
tools:layout="@layout/main_fragment" /> tools:layout="@layout/main_fragment" />
</navigation> </navigation>

View File

@ -1,6 +1,24 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2020 Shabinder Singh
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<resources> <resources>
<array name="preloaded_fonts" translatable="false"> <array name="preloaded_fonts" translatable="false">
<item>@font/amita</item>
<item>@font/averia_libre</item> <item>@font/averia_libre</item>
<item>@font/capriola</item> <item>@font/capriola</item>
<item>@font/raleway</item> <item>@font/raleway</item>

View File

@ -1,5 +1,22 @@
<!--
~ Copyright (C) 2020 Shabinder Singh
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<resources> <resources>
<string name="app_name">musicForEveryone</string> <string name="app_name">SpotiFlyer</string>
<string name="d_one"><b><i>Usage Instructions:</i></b></string> <string name="d_one"><b><i>Usage Instructions:</i></b></string>
<string name="d_two"><b>1. Paste</b>, Your Copied Link in Search Box at Top.</string> <string name="d_two"><b>1. Paste</b>, Your Copied Link in Search Box at Top.</string>
<string name="d_three"><b>2. Share directly</b> from <b>Spotify</b> App to this App.</string> <string name="d_three"><b>2. Share directly</b> from <b>Spotify</b> App to this App.</string>

View File

@ -1,16 +0,0 @@
package com.shabinder.musicForEveryone
import org.junit.Assert.assertEquals
import org.junit.Test
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2020 Shabinder Singh
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.shabinder.spotiflyer
import org.junit.Assert.assertEquals
import org.junit.Test
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@ -1,2 +1,19 @@
/*
* Copyright (C) 2020 Shabinder Singh
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include ':app' include ':app'
rootProject.name = "musicForEveryone" rootProject.name = "spotiflyer"