Track List Implemented

This commit is contained in:
shabinder 2020-12-30 20:12:10 +05:30
parent 86431dbc1c
commit 66064c631b
14 changed files with 187 additions and 77 deletions

View File

@ -79,6 +79,7 @@ dependencies {
//Compose //Compose
implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.ui:ui-tooling:$compose_version" implementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation "androidx.compose.animation:animation:$compose_version"
implementation "androidx.compose.runtime:runtime-livedata:$compose_version" implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
implementation "androidx.compose.material:material:$compose_version" implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.material:material-icons-extended:$compose_version" implementation "androidx.compose.material:material-icons-extended:$compose_version"
@ -90,6 +91,7 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
//Coroutines //Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
@ -98,13 +100,13 @@ dependencies {
//Room //Room
kapt "androidx.room:room-compiler:$room_version" kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version" implementation "androidx.room:room-ktx:$room_version"
implementation "androidx.room:room-runtime:$room_version"
//Hilt //Hilt
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
kapt "com.google.dagger:hilt-android-compiler:$hilt_version" kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
implementation "com.google.dagger:hilt-android:$hilt_version" implementation "com.google.dagger:hilt-android:$hilt_version"
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02' implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02'
//FFmpeg //FFmpeg

View File

@ -25,11 +25,16 @@ import androidx.compose.ui.res.vectorResource
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.shabinder.spotiflyer.navigation.ComposeNavigation import com.shabinder.spotiflyer.navigation.ComposeNavigation
import com.shabinder.spotiflyer.navigation.navigateToPlatform
import com.shabinder.spotiflyer.networking.SpotifyService import com.shabinder.spotiflyer.networking.SpotifyService
import com.shabinder.spotiflyer.networking.SpotifyServiceTokenRequest import com.shabinder.spotiflyer.networking.SpotifyServiceTokenRequest
import com.shabinder.spotiflyer.ui.ComposeLearnTheme import com.shabinder.spotiflyer.ui.ComposeLearnTheme
import com.shabinder.spotiflyer.ui.appNameStyle import com.shabinder.spotiflyer.ui.appNameStyle
import com.shabinder.spotiflyer.ui.colorOffWhite
import com.shabinder.spotiflyer.utils.* import com.shabinder.spotiflyer.utils.*
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@ -51,6 +56,7 @@ import com.shabinder.spotiflyer.utils.showDialog as showDialog1
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private var spotifyService : SpotifyService? = null private var spotifyService : SpotifyService? = null
lateinit var navController: NavHostController
@Inject lateinit var moshi: Moshi @Inject lateinit var moshi: Moshi
@Inject lateinit var spotifyServiceTokenRequest: SpotifyServiceTokenRequest @Inject lateinit var spotifyServiceTokenRequest: SpotifyServiceTokenRequest
@ -62,19 +68,24 @@ class MainActivity : AppCompatActivity() {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
setContent { setContent {
ComposeLearnTheme { ComposeLearnTheme {
ProvideWindowInsets { Providers(AmbientContentColor provides colorOffWhite) {
Column { ProvideWindowInsets {
val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.87f) Column {
val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.87f)
// Draw a scrim over the status bar which matches the app bar // Draw a scrim over the status bar which matches the app bar
Spacer(Modifier.background(appBarColor).fillMaxWidth().statusBarsHeight()) Spacer(
Modifier.background(appBarColor).fillMaxWidth().statusBarsHeight()
)
AppBar( AppBar(
backgroundColor = appBarColor, backgroundColor = appBarColor,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
navController = rememberNavController()
ComposeNavigation() ComposeNavigation(navController)
}
} }
} }
} }
@ -93,7 +104,6 @@ class MainActivity : AppCompatActivity() {
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent) super.onNewIntent(intent)
//Return to MainFragment For Further Processing of this Intent
handleIntentFromExternalActivity(intent) handleIntentFromExternalActivity(intent)
} }
@ -172,7 +182,7 @@ class MainActivity : AppCompatActivity() {
if ("text/plain" == intent.type) { if ("text/plain" == intent.type) {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let { intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
log("Intent Received", it) log("Intent Received", it)
sharedViewModel.intentString.value = it navController.navigateToPlatform(it)
} }
} }
} }
@ -238,7 +248,7 @@ fun DefaultPreview() {
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
ComposeNavigation() //ComposeNavigation()
} }
} }
} }

View File

@ -22,9 +22,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.shabinder.spotiflyer.database.DatabaseDAO import com.shabinder.spotiflyer.database.DatabaseDAO
import com.shabinder.spotiflyer.models.PlatformQueryResult
import com.shabinder.spotiflyer.networking.GaanaInterface import com.shabinder.spotiflyer.networking.GaanaInterface
import com.shabinder.spotiflyer.networking.SpotifyService import com.shabinder.spotiflyer.networking.SpotifyService
import dagger.hilt.android.scopes.ActivityRetainedScoped import dagger.hilt.android.scopes.ActivityRetainedScoped
import kotlinx.coroutines.flow.Flow
@ActivityRetainedScoped @ActivityRetainedScoped
class SharedViewModel @ViewModelInject constructor( class SharedViewModel @ViewModelInject constructor(

View File

@ -2,6 +2,7 @@ package com.shabinder.spotiflyer.navigation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.NavType import androidx.navigation.NavType
import androidx.navigation.compose.* import androidx.navigation.compose.*
import androidx.navigation.compose.popUpTo import androidx.navigation.compose.popUpTo
@ -14,8 +15,7 @@ import com.shabinder.spotiflyer.utils.sharedViewModel
import com.shabinder.spotiflyer.utils.showDialog import com.shabinder.spotiflyer.utils.showDialog
@Composable @Composable
fun ComposeNavigation() { fun ComposeNavigation(navController: NavHostController) {
val navController = rememberNavController()
NavHost( NavHost(
navController = navController, navController = navController,
startDestination = "home" startDestination = "home"

View File

@ -12,6 +12,7 @@ val colorAccent = Color(0xFF9AB3FF)
val colorRedError = Color(0xFFFF9494) val colorRedError = Color(0xFFFF9494)
val colorSuccessGreen = Color(0xFF59C351) val colorSuccessGreen = Color(0xFF59C351)
val darkBackgroundColor = Color(0xFF000000) val darkBackgroundColor = Color(0xFF000000)
val colorOffWhite = Color(0xFFE7E7E7)
val SpotiFlyerColors = darkColors( val SpotiFlyerColors = darkColors(
primary = colorPrimary, primary = colorPrimary,

View File

@ -80,7 +80,6 @@ val SpotiFlyerTypography = Typography(
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
lineHeight = 20.sp, lineHeight = 20.sp,
letterSpacing = 0.15.sp, letterSpacing = 0.15.sp,
color = colorAccent
), ),
body2 = TextStyle( body2 = TextStyle(
fontFamily = Montserrat, fontFamily = Montserrat,

View File

@ -1,40 +0,0 @@
/*
* 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.ui.base
import androidx.lifecycle.ViewModel
import com.shabinder.spotiflyer.models.TrackDetails
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
abstract class TrackListViewModel:ViewModel() {
abstract var folderType:String
abstract var subFolder:String
private val _trackList = MutableStateFlow<List<TrackDetails>>(mutableListOf())
open val trackList:StateFlow<List<TrackDetails>>
get() = _trackList
fun updateTrackList(list:List<TrackDetails>){
_trackList.value = list
}
private val loading = "Loading!"
open var title = MutableStateFlow(loading)
open var coverUrl = MutableStateFlow(loading)
}

View File

@ -85,7 +85,8 @@ fun AboutColumn(modifier: Modifier = Modifier) {
Column(modifier.padding(12.dp)) { Column(modifier.padding(12.dp)) {
Text( Text(
text = stringResource(R.string.supported_platform), text = stringResource(R.string.supported_platform),
style = SpotiFlyerTypography.body1 style = SpotiFlyerTypography.body1,
color = colorAccent
) )
Spacer(modifier = Modifier.padding(top = 12.dp)) Spacer(modifier = Modifier.padding(top = 12.dp))
Row(horizontalArrangement = Arrangement.Center,modifier = modifier.fillMaxWidth()) { Row(horizontalArrangement = Arrangement.Center,modifier = modifier.fillMaxWidth()) {
@ -115,7 +116,8 @@ fun AboutColumn(modifier: Modifier = Modifier) {
Column(modifier.padding(12.dp)) { Column(modifier.padding(12.dp)) {
Text( Text(
text = stringResource(R.string.support_development), text = stringResource(R.string.support_development),
style = SpotiFlyerTypography.body1 style = SpotiFlyerTypography.body1,
color = colorAccent
) )
Spacer(modifier = Modifier.padding(top = 6.dp)) Spacer(modifier = Modifier.padding(top = 6.dp))
Row(verticalAlignment = Alignment.CenterVertically, Row(verticalAlignment = Alignment.CenterVertically,

View File

@ -1,8 +1,15 @@
package com.shabinder.spotiflyer.ui.platforms.gaana package com.shabinder.spotiflyer.ui.platforms.gaana
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.navigation.NavController import androidx.navigation.NavController
import com.shabinder.spotiflyer.models.PlatformQueryResult
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.ui.tracklist.TrackList
import com.shabinder.spotiflyer.utils.* import com.shabinder.spotiflyer.utils.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -11,6 +18,9 @@ fun Gaana(
fullLink: String, fullLink: String,
navController: NavController navController: NavController
) { ) {
val source = Source.Gaana
var result by remember { mutableStateOf<PlatformQueryResult?>(null) }
//Coroutine Scope Active till this Composable is Active //Coroutine Scope Active till this Composable is Active
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
@ -29,17 +39,17 @@ fun Gaana(
} }
coroutineScope.launch { coroutineScope.launch {
val result = gaanaSearch( result = gaanaSearch(
type, type,
link, link,
sharedViewModel.gaanaInterface, sharedViewModel.gaanaInterface,
sharedViewModel.databaseDAO, sharedViewModel.databaseDAO,
) )
}
log("Gaana",result.toString()) result?.let {
log("Gaana Tracks",result.trackList.size.toString()) TrackList(
result = it,
source = source
)
} }
} }

View File

@ -1,12 +1,15 @@
package com.shabinder.spotiflyer.ui.platforms.spotify package com.shabinder.spotiflyer.ui.platforms.spotify
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.viewinterop.viewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavController import androidx.navigation.NavController
import com.shabinder.spotiflyer.models.PlatformQueryResult
import com.shabinder.spotiflyer.models.spotify.Source import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.networking.SpotifyService import com.shabinder.spotiflyer.ui.tracklist.TrackList
import com.shabinder.spotiflyer.utils.* import com.shabinder.spotiflyer.utils.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -14,8 +17,8 @@ import kotlinx.coroutines.launch
@Composable @Composable
fun Spotify(fullLink: String, navController: NavController,) { fun Spotify(fullLink: String, navController: NavController,) {
val source: Source = Source.Spotify val source: Source = Source.Spotify
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
var result by remember { mutableStateOf<PlatformQueryResult?>(null) }
var spotifyLink = var spotifyLink =
"https://" + fullLink.substringAfterLast("https://").substringBefore(" ").trim() "https://" + fullLink.substringAfterLast("https://").substringBefore(" ").trim()
@ -57,7 +60,7 @@ fun Spotify(fullLink: String, navController: NavController,) {
showDialog("Authentication Failed") showDialog("Authentication Failed")
navController.popBackStack() navController.popBackStack()
}else{ }else{
val result = spotifySearch( result = spotifySearch(
type, type,
link, link,
sharedViewModel.spotifyService.value!!, sharedViewModel.spotifyService.value!!,
@ -66,4 +69,11 @@ fun Spotify(fullLink: String, navController: NavController,) {
} }
} }
} }
result?.let {
log("Spotify",it.trackList.size.toString())
TrackList(
result = it,
source = source
)
}
} }

View File

@ -1,9 +1,15 @@
package com.shabinder.spotiflyer.ui.platforms.youtube package com.shabinder.spotiflyer.ui.platforms.youtube
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.navigation.NavController import androidx.navigation.NavController
import com.shabinder.spotiflyer.models.PlatformQueryResult
import com.shabinder.spotiflyer.models.spotify.Source import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.ui.tracklist.TrackList
import com.shabinder.spotiflyer.utils.sharedViewModel import com.shabinder.spotiflyer.utils.sharedViewModel
import com.shabinder.spotiflyer.utils.showDialog import com.shabinder.spotiflyer.utils.showDialog
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -15,7 +21,7 @@ private const val sampleDomain1 = "youtube.com"
@Composable @Composable
fun Youtube(fullLink: String, navController: NavController,) { fun Youtube(fullLink: String, navController: NavController,) {
val source = Source.YouTube val source = Source.YouTube
var result by remember { mutableStateOf<PlatformQueryResult?>(null) }
//Coroutine Scope Active till this Composable is Active //Coroutine Scope Active till this Composable is Active
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
@ -38,7 +44,7 @@ fun Youtube(fullLink: String, navController: NavController,) {
searchId = link.substringAfterLast("/","error") searchId = link.substringAfterLast("/","error")
} }
if(searchId != "error") { if(searchId != "error") {
getYTTrack( result = getYTTrack(
searchId, searchId,
sharedViewModel.ytDownloader, sharedViewModel.ytDownloader,
sharedViewModel.databaseDAO sharedViewModel.databaseDAO
@ -49,4 +55,10 @@ fun Youtube(fullLink: String, navController: NavController,) {
} }
} }
} }
result?.let {
TrackList(
result = it,
source = source
)
}
} }

View File

@ -1,14 +1,69 @@
package com.shabinder.spotiflyer.ui.tracklist package com.shabinder.spotiflyer.ui.tracklist
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.viewModel import androidx.compose.ui.viewinterop.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import com.bumptech.glide.RequestManager
import com.shabinder.spotiflyer.R
import com.shabinder.spotiflyer.models.PlatformQueryResult
import com.shabinder.spotiflyer.models.TrackDetails
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.ui.SpotiFlyerTypography
import com.shabinder.spotiflyer.ui.colorAccent
import dev.chrisbanes.accompanist.glide.GlideImage
/* /*
* UI for List of Tracks to be universally used. * UI for List of Tracks to be universally used.
* */ * */
@Composable @Composable
fun TrackList(modifier: Modifier = Modifier){ fun TrackList(
result: PlatformQueryResult,
source: Source,
modifier: Modifier = Modifier
){
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp),
content = {
items(result.trackList) {
TrackCard(track = it)
}
},
modifier = Modifier.fillMaxSize()
)
}
@Composable
fun TrackCard(track:TrackDetails) {
Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp)) {
GlideImage(
data = track.albumArtURL,
loading = { Image(vectorResource(id = R.drawable.ic_song_placeholder)) },
error = { Image(vectorResource(id = R.drawable.ic_musicplaceholder)) },
contentScale = ContentScale.Inside,
modifier = Modifier.preferredHeight(75.dp).preferredWidth(90.dp)
)
Column(modifier = Modifier.padding(horizontal = 8.dp).fillMaxHeight().weight(1f),verticalArrangement = Arrangement.SpaceBetween) {
Text(track.title,maxLines = 1,overflow = TextOverflow.Ellipsis,style = SpotiFlyerTypography.h6,color = colorAccent)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.padding(horizontal = 12.dp).fillMaxSize()
){
Text("${track.artists.firstOrNull()}...",fontSize = 13.sp)
Text("${track.durationSec/60} minutes, ${track.durationSec%60} sec",fontSize = 13.sp)
}
}
Image(vectorResource(id = R.drawable.ic_arrow))
}
} }

View File

@ -2,17 +2,38 @@ package com.shabinder.spotiflyer.utils
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.drawable.Drawable
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import android.widget.ImageView
import android.widget.Toast import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.vectorResource
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.net.toUri
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestManager
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.shabinder.spotiflyer.MainActivity import com.shabinder.spotiflyer.MainActivity
import com.shabinder.spotiflyer.R
import com.shabinder.spotiflyer.models.TrackDetails import com.shabinder.spotiflyer.models.TrackDetails
import com.shabinder.spotiflyer.models.spotify.Source import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.worker.ForegroundService import com.shabinder.spotiflyer.worker.ForegroundService
import dev.chrisbanes.accompanist.glide.GlideImage
import dev.chrisbanes.accompanist.glide.GlideImageDefaults
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.io.IOException
/** /**
* mainActivity Instance to use whereEver Needed , as Its God Activity. * mainActivity Instance to use whereEver Needed , as Its God Activity.
@ -54,7 +75,6 @@ fun finalOutputDir(itemName:String ,type:String, subFolder:String,extension:Stri
removeIllegalChars(itemName) + extension removeIllegalChars(itemName) + extension
} }
/** /**
* Util. Function To Check Connection Status * Util. Function To Check Connection Status
* */ * */

View File

@ -0,0 +1,27 @@
<!--
~ 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/>.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="36dp"
android:height="32dp" android:viewportWidth="512" android:viewportHeight="512">
<path android:fillColor="#516AEC" android:pathData="m296,288 l60,-60c7.73,-7.73 17.86,-11.6 28,-11.6 10.055,0 20.101,3.806 27.806,11.407 15.612,15.402 15.207,41.18 -0.3,56.687l-134.293,134.293c-11.716,11.716 -30.711,11.716 -42.426,0l-134.787,-134.787c-7.73,-7.73 -11.6,-17.86 -11.6,-28 0,-10.055 3.806,-20.101 11.407,-27.806 15.402,-15.612 41.18,-15.207 56.687,0.3l59.506,59.506v-232c0,-22.091 17.909,-40 40,-40 22.091,0 40,17.909 40,40z"/>
<path android:fillColor="#EC7EBA" android:pathData="m411.51,284.49 l-134.3,134.3c-11.71,11.71 -30.71,11.71 -42.42,0l-12.74,-12.74c10.69,4.06 23.23,1.77 31.84,-6.84l134.29,-134.29c12.51,-12.51 15.19,-31.7 7.57,-46.74 5.86,1.81 11.39,5.03 16.06,9.63 15.61,15.4 15.2,41.18 -0.3,56.68z"/>
<path android:fillColor="#EC7EBA" android:pathData="m251.88,27.72c-3.46,-3.46 -7.55,-6.29 -12.08,-8.3 4.95,-2.2 10.43,-3.42 16.2,-3.42 11.04,0 21.04,4.48 28.28,11.72s11.72,17.24 11.72,28.28v232l-15.329,15.329c-6.3,6.3 -17.071,1.838 -17.071,-7.071v-240.258c0,-11.04 -4.48,-21.04 -11.72,-28.28z"/>
<path android:fillColor="#6A82FB" android:pathData="m496,512h-24c-8.836,0 -16,-7.164 -16,-16s7.164,-16 16,-16h24c8.836,0 16,7.164 16,16s-7.164,16 -16,16z"/>
<path android:fillColor="#6A82FB" android:pathData="m40,512h-24c-8.836,0 -16,-7.164 -16,-16s7.164,-16 16,-16h24c8.836,0 16,7.164 16,16s-7.164,16 -16,16z"/>
<path android:fillColor="#FC5C7D" android:pathData="m416,512h-320c-8.836,0 -16,-7.164 -16,-16s7.164,-16 16,-16h320c8.836,0 16,7.164 16,16s-7.164,16 -16,16z"/>
<path android:fillColor="#4AFC5C7D" android:pathData="m256,443.552c-11.78,0 -23.56,-4.484 -32.527,-13.452l-134.786,-134.787c-10.503,-10.502 -16.287,-24.463 -16.287,-39.313 0,-14.708 5.688,-28.573 16.017,-39.042 10.31,-10.451 24.214,-16.233 39.151,-16.284h0.189c14.966,0 29.552,6.009 40.05,16.507l32.193,32.192v-193.373c0,-30.878 25.122,-56 56,-56s56,25.122 56,56v193.373l32.687,-32.687c10.501,-10.502 24.463,-16.286 39.313,-16.286 14.708,0 28.573,5.688 39.042,16.017 10.45,10.31 16.233,24.214 16.284,39.151 0.051,15.032 -5.966,29.698 -16.507,40.24l-134.292,134.292c-8.967,8.968 -20.747,13.452 -32.527,13.452zM127.761,232.673c-0.028,0 -0.056,0 -0.084,0 -6.349,0.021 -12.202,2.421 -16.479,6.758 -4.383,4.443 -6.797,10.327 -6.797,16.569 0,6.302 2.456,12.228 6.914,16.686l134.785,134.787c5.459,5.459 14.341,5.459 19.8,0l134.292,-134.292c4.556,-4.557 7.157,-10.937 7.134,-17.504 -0.021,-6.349 -2.421,-12.202 -6.758,-16.479 -4.443,-4.383 -10.327,-6.797 -16.569,-6.797 -6.302,0 -12.228,2.456 -16.687,6.914l-60,60c-4.575,4.577 -11.456,5.945 -17.437,3.469 -5.977,-2.478 -9.875,-8.313 -9.875,-14.784v-232c0,-13.234 -10.767,-24 -24,-24 -13.234,0 -24,10.766 -24,24v232c0,6.471 -3.898,12.306 -9.877,14.782 -5.978,2.476 -12.861,1.108 -17.437,-3.469l-59.506,-59.505c-4.536,-4.537 -10.882,-7.135 -17.419,-7.135z"/>
</vector>