mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-22 17:14:32 +01:00
Track List Implemented
This commit is contained in:
parent
86431dbc1c
commit
66064c631b
@ -79,10 +79,11 @@ dependencies {
|
||||
//Compose
|
||||
implementation "androidx.compose.ui:ui:$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.material:material:$compose_version"
|
||||
implementation "androidx.compose.material:material-icons-extended:$compose_version"
|
||||
|
||||
|
||||
//Compose-Navigation
|
||||
implementation "androidx.navigation:navigation-compose:1.0.0-alpha04"
|
||||
|
||||
@ -90,6 +91,7 @@ dependencies {
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
|
||||
|
||||
//Coroutines
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||
@ -98,13 +100,13 @@ dependencies {
|
||||
|
||||
//Room
|
||||
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-runtime:$room_version"
|
||||
|
||||
//Hilt
|
||||
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
|
||||
kapt "com.google.dagger:hilt-android-compiler:$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'
|
||||
|
||||
//FFmpeg
|
||||
|
@ -25,11 +25,16 @@ import androidx.compose.ui.res.vectorResource
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
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.navigateToPlatform
|
||||
import com.shabinder.spotiflyer.networking.SpotifyService
|
||||
import com.shabinder.spotiflyer.networking.SpotifyServiceTokenRequest
|
||||
import com.shabinder.spotiflyer.ui.ComposeLearnTheme
|
||||
import com.shabinder.spotiflyer.ui.appNameStyle
|
||||
import com.shabinder.spotiflyer.ui.colorOffWhite
|
||||
import com.shabinder.spotiflyer.utils.*
|
||||
import com.squareup.moshi.Moshi
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@ -51,6 +56,7 @@ import com.shabinder.spotiflyer.utils.showDialog as showDialog1
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private var spotifyService : SpotifyService? = null
|
||||
lateinit var navController: NavHostController
|
||||
@Inject lateinit var moshi: Moshi
|
||||
@Inject lateinit var spotifyServiceTokenRequest: SpotifyServiceTokenRequest
|
||||
|
||||
@ -62,19 +68,24 @@ class MainActivity : AppCompatActivity() {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
setContent {
|
||||
ComposeLearnTheme {
|
||||
ProvideWindowInsets {
|
||||
Column {
|
||||
val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.87f)
|
||||
Providers(AmbientContentColor provides colorOffWhite) {
|
||||
ProvideWindowInsets {
|
||||
Column {
|
||||
val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.87f)
|
||||
|
||||
// Draw a scrim over the status bar which matches the app bar
|
||||
Spacer(Modifier.background(appBarColor).fillMaxWidth().statusBarsHeight())
|
||||
// Draw a scrim over the status bar which matches the app bar
|
||||
Spacer(
|
||||
Modifier.background(appBarColor).fillMaxWidth().statusBarsHeight()
|
||||
)
|
||||
|
||||
AppBar(
|
||||
backgroundColor = appBarColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
AppBar(
|
||||
backgroundColor = appBarColor,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
navController = rememberNavController()
|
||||
|
||||
ComposeNavigation()
|
||||
ComposeNavigation(navController)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,7 +104,6 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
//Return to MainFragment For Further Processing of this Intent
|
||||
handleIntentFromExternalActivity(intent)
|
||||
}
|
||||
|
||||
@ -172,7 +182,7 @@ class MainActivity : AppCompatActivity() {
|
||||
if ("text/plain" == intent.type) {
|
||||
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
|
||||
log("Intent Received", it)
|
||||
sharedViewModel.intentString.value = it
|
||||
navController.navigateToPlatform(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -238,7 +248,7 @@ fun DefaultPreview() {
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
ComposeNavigation()
|
||||
//ComposeNavigation()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,11 @@ import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.github.kiulian.downloader.YoutubeDownloader
|
||||
import com.shabinder.spotiflyer.database.DatabaseDAO
|
||||
import com.shabinder.spotiflyer.models.PlatformQueryResult
|
||||
import com.shabinder.spotiflyer.networking.GaanaInterface
|
||||
import com.shabinder.spotiflyer.networking.SpotifyService
|
||||
import dagger.hilt.android.scopes.ActivityRetainedScoped
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@ActivityRetainedScoped
|
||||
class SharedViewModel @ViewModelInject constructor(
|
||||
|
@ -2,6 +2,7 @@ package com.shabinder.spotiflyer.navigation
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.*
|
||||
import androidx.navigation.compose.popUpTo
|
||||
@ -14,8 +15,7 @@ import com.shabinder.spotiflyer.utils.sharedViewModel
|
||||
import com.shabinder.spotiflyer.utils.showDialog
|
||||
|
||||
@Composable
|
||||
fun ComposeNavigation() {
|
||||
val navController = rememberNavController()
|
||||
fun ComposeNavigation(navController: NavHostController) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = "home"
|
||||
|
@ -12,6 +12,7 @@ val colorAccent = Color(0xFF9AB3FF)
|
||||
val colorRedError = Color(0xFFFF9494)
|
||||
val colorSuccessGreen = Color(0xFF59C351)
|
||||
val darkBackgroundColor = Color(0xFF000000)
|
||||
val colorOffWhite = Color(0xFFE7E7E7)
|
||||
|
||||
val SpotiFlyerColors = darkColors(
|
||||
primary = colorPrimary,
|
||||
|
@ -80,7 +80,6 @@ val SpotiFlyerTypography = Typography(
|
||||
fontWeight = FontWeight.Medium,
|
||||
lineHeight = 20.sp,
|
||||
letterSpacing = 0.15.sp,
|
||||
color = colorAccent
|
||||
),
|
||||
body2 = TextStyle(
|
||||
fontFamily = Montserrat,
|
||||
|
@ -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)
|
||||
|
||||
}
|
@ -85,7 +85,8 @@ fun AboutColumn(modifier: Modifier = Modifier) {
|
||||
Column(modifier.padding(12.dp)) {
|
||||
Text(
|
||||
text = stringResource(R.string.supported_platform),
|
||||
style = SpotiFlyerTypography.body1
|
||||
style = SpotiFlyerTypography.body1,
|
||||
color = colorAccent
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(top = 12.dp))
|
||||
Row(horizontalArrangement = Arrangement.Center,modifier = modifier.fillMaxWidth()) {
|
||||
@ -115,7 +116,8 @@ fun AboutColumn(modifier: Modifier = Modifier) {
|
||||
Column(modifier.padding(12.dp)) {
|
||||
Text(
|
||||
text = stringResource(R.string.support_development),
|
||||
style = SpotiFlyerTypography.body1
|
||||
style = SpotiFlyerTypography.body1,
|
||||
color = colorAccent
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(top = 6.dp))
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
|
@ -1,8 +1,15 @@
|
||||
package com.shabinder.spotiflyer.ui.platforms.gaana
|
||||
|
||||
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.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 kotlinx.coroutines.launch
|
||||
|
||||
@ -11,6 +18,9 @@ fun Gaana(
|
||||
fullLink: String,
|
||||
navController: NavController
|
||||
) {
|
||||
val source = Source.Gaana
|
||||
var result by remember { mutableStateOf<PlatformQueryResult?>(null) }
|
||||
|
||||
//Coroutine Scope Active till this Composable is Active
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
@ -29,17 +39,17 @@ fun Gaana(
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
val result = gaanaSearch(
|
||||
result = gaanaSearch(
|
||||
type,
|
||||
link,
|
||||
sharedViewModel.gaanaInterface,
|
||||
sharedViewModel.databaseDAO,
|
||||
)
|
||||
|
||||
log("Gaana",result.toString())
|
||||
log("Gaana Tracks",result.trackList.size.toString())
|
||||
|
||||
|
||||
|
||||
}
|
||||
result?.let {
|
||||
TrackList(
|
||||
result = it,
|
||||
source = source
|
||||
)
|
||||
}
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
package com.shabinder.spotiflyer.ui.platforms.spotify
|
||||
|
||||
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.ui.viewinterop.viewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.NavController
|
||||
import com.shabinder.spotiflyer.models.PlatformQueryResult
|
||||
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 kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@ -14,8 +17,8 @@ import kotlinx.coroutines.launch
|
||||
@Composable
|
||||
fun Spotify(fullLink: String, navController: NavController,) {
|
||||
val source: Source = Source.Spotify
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var result by remember { mutableStateOf<PlatformQueryResult?>(null) }
|
||||
|
||||
var spotifyLink =
|
||||
"https://" + fullLink.substringAfterLast("https://").substringBefore(" ").trim()
|
||||
@ -57,7 +60,7 @@ fun Spotify(fullLink: String, navController: NavController,) {
|
||||
showDialog("Authentication Failed")
|
||||
navController.popBackStack()
|
||||
}else{
|
||||
val result = spotifySearch(
|
||||
result = spotifySearch(
|
||||
type,
|
||||
link,
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
@ -1,9 +1,15 @@
|
||||
package com.shabinder.spotiflyer.ui.platforms.youtube
|
||||
|
||||
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.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.sharedViewModel
|
||||
import com.shabinder.spotiflyer.utils.showDialog
|
||||
import kotlinx.coroutines.launch
|
||||
@ -15,7 +21,7 @@ private const val sampleDomain1 = "youtube.com"
|
||||
@Composable
|
||||
fun Youtube(fullLink: String, navController: NavController,) {
|
||||
val source = Source.YouTube
|
||||
|
||||
var result by remember { mutableStateOf<PlatformQueryResult?>(null) }
|
||||
//Coroutine Scope Active till this Composable is Active
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
@ -38,7 +44,7 @@ fun Youtube(fullLink: String, navController: NavController,) {
|
||||
searchId = link.substringAfterLast("/","error")
|
||||
}
|
||||
if(searchId != "error") {
|
||||
getYTTrack(
|
||||
result = getYTTrack(
|
||||
searchId,
|
||||
sharedViewModel.ytDownloader,
|
||||
sharedViewModel.databaseDAO
|
||||
@ -49,4 +55,10 @@ fun Youtube(fullLink: String, navController: NavController,) {
|
||||
}
|
||||
}
|
||||
}
|
||||
result?.let {
|
||||
TrackList(
|
||||
result = it,
|
||||
source = source
|
||||
)
|
||||
}
|
||||
}
|
@ -1,14 +1,69 @@
|
||||
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.ui.Alignment
|
||||
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.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.
|
||||
* */
|
||||
@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))
|
||||
}
|
||||
}
|
@ -2,17 +2,38 @@ package com.shabinder.spotiflyer.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.widget.ImageView
|
||||
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.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.R
|
||||
import com.shabinder.spotiflyer.models.TrackDetails
|
||||
import com.shabinder.spotiflyer.models.spotify.Source
|
||||
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.IOException
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Util. Function To Check Connection Status
|
||||
* */
|
||||
|
27
app/src/main/res/drawable/ic_arrow.xml
Normal file
27
app/src/main/res/drawable/ic_arrow.xml
Normal 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>
|
Loading…
Reference in New Issue
Block a user