mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-26 02:24:31 +01:00
gradient
This commit is contained in:
parent
760ffae8f3
commit
1f548e82e0
@ -95,7 +95,6 @@ dependencies {
|
|||||||
implementation(razorpay)
|
implementation(razorpay)
|
||||||
implementation(fetch)
|
implementation(fetch)
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation(MVIKotlin.mvikotlin)
|
implementation(MVIKotlin.mvikotlin)
|
||||||
implementation(MVIKotlin.mvikotlinMain)
|
implementation(MVIKotlin.mvikotlinMain)
|
||||||
implementation(MVIKotlin.mvikotlinLogging)
|
implementation(MVIKotlin.mvikotlinLogging)
|
||||||
|
@ -12,6 +12,14 @@ import android.util.Log
|
|||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.arkivanov.decompose.ComponentContext
|
import com.arkivanov.decompose.ComponentContext
|
||||||
import com.arkivanov.decompose.extensions.compose.jetbrains.rootComponent
|
import com.arkivanov.decompose.extensions.compose.jetbrains.rootComponent
|
||||||
@ -53,17 +61,27 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
// This app draws behind the system bars, so we want to handle fitting system windows
|
||||||
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
SpotiFlyerTheme {
|
SpotiFlyerTheme {
|
||||||
Surface(contentColor = colorOffWhite) {
|
Surface(contentColor = colorOffWhite) {
|
||||||
root = SpotiFlyerRootContent(rootComponent(::spotiFlyerRoot))
|
|
||||||
|
var statusBarHeight by remember { mutableStateOf(27.dp) }
|
||||||
|
val view = LocalView.current
|
||||||
|
|
||||||
|
LaunchedEffect(view){
|
||||||
|
view.setOnApplyWindowInsetsListener { _, insets ->
|
||||||
|
statusBarHeight = insets.systemWindowInsetTop.dp
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root = SpotiFlyerRootContent(rootComponent(::spotiFlyerRoot),statusBarHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*lifecycleScope.launch {
|
|
||||||
val string = fetcher.youtubeMp3.getMp3DownloadLink("lVfVrqu1G0U")
|
|
||||||
Log.i("Mp3Test",string)
|
|
||||||
}*/
|
|
||||||
initialise()
|
initialise()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package com.shabinder.common.root
|
|||||||
import androidx.compose.animation.core.*
|
import androidx.compose.animation.core.*
|
||||||
import androidx.compose.animation.core.Spring.StiffnessLow
|
import androidx.compose.animation.core.Spring.StiffnessLow
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@ -12,6 +13,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalViewConfiguration
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.arkivanov.decompose.extensions.compose.jetbrains.Children
|
import com.arkivanov.decompose.extensions.compose.jetbrains.Children
|
||||||
@ -20,10 +22,12 @@ import com.shabinder.common.main.SpotiFlyerMainContent
|
|||||||
import com.shabinder.common.root.SpotiFlyerRoot.Child
|
import com.shabinder.common.root.SpotiFlyerRoot.Child
|
||||||
import com.shabinder.common.ui.SpotiFlyerLogo
|
import com.shabinder.common.ui.SpotiFlyerLogo
|
||||||
import com.shabinder.common.ui.appNameStyle
|
import com.shabinder.common.ui.appNameStyle
|
||||||
|
import com.shabinder.common.ui.colorPrimaryDark
|
||||||
import com.shabinder.common.ui.splash.*
|
import com.shabinder.common.ui.splash.*
|
||||||
|
import com.shabinder.common.utils.verticalGradientScrim
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SpotiFlyerRootContent(component: SpotiFlyerRoot):SpotiFlyerRoot {
|
fun SpotiFlyerRootContent(component: SpotiFlyerRoot,statusBarHeight:Dp = 0.dp):SpotiFlyerRoot {
|
||||||
|
|
||||||
val transitionState = remember { MutableTransitionState(SplashState.Shown) }
|
val transitionState = remember { MutableTransitionState(SplashState.Shown) }
|
||||||
val transition = updateTransition(transitionState)
|
val transition = updateTransition(transitionState)
|
||||||
@ -52,6 +56,7 @@ fun SpotiFlyerRootContent(component: SpotiFlyerRoot):SpotiFlyerRoot {
|
|||||||
MainScreen(
|
MainScreen(
|
||||||
Modifier.alpha(contentAlpha),
|
Modifier.alpha(contentAlpha),
|
||||||
contentTopPadding,
|
contentTopPadding,
|
||||||
|
statusBarHeight,
|
||||||
component
|
component
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -59,17 +64,21 @@ fun SpotiFlyerRootContent(component: SpotiFlyerRoot):SpotiFlyerRoot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainScreen(modifier: Modifier = Modifier, topPadding: Dp = 0.dp,component: SpotiFlyerRoot) {
|
fun MainScreen(modifier: Modifier = Modifier, topPadding: Dp = 0.dp,statusBarHeight: Dp = 0.dp,component: SpotiFlyerRoot) {
|
||||||
val appBarColor = MaterialTheme.colors.surface
|
|
||||||
|
val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.65f)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier.fillMaxSize()
|
modifier = modifier.fillMaxSize()
|
||||||
/*.verticalGradientScrim(
|
.verticalGradientScrim(
|
||||||
color = sharedViewModel.gradientColor.copy(alpha = 0.38f),
|
color = colorPrimaryDark.copy(alpha = 0.38f),
|
||||||
color = appBarColor.copy(alpha = 0.38f),
|
|
||||||
startYPercentage = 0.29f,
|
startYPercentage = 0.29f,
|
||||||
endYPercentage = 0f,
|
endYPercentage = 0f,
|
||||||
)*/
|
)
|
||||||
) {
|
) {
|
||||||
|
Spacer(Modifier.background(appBarColor).height(statusBarHeight).fillMaxWidth())
|
||||||
|
LocalViewConfiguration.current
|
||||||
|
|
||||||
AppBar(
|
AppBar(
|
||||||
backgroundColor = appBarColor,
|
backgroundColor = appBarColor,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
@ -107,14 +116,14 @@ fun AppBar(
|
|||||||
style = appNameStyle
|
style = appNameStyle
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},/*
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { /*TODO: Open Preferences*/ }
|
onClick = { *//*TODO: Open Preferences*//* }
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Filled.Settings,"Preferences", tint = Color.Gray)
|
Icon(Icons.Filled.Settings,"Preferences", tint = Color.Gray)
|
||||||
}
|
}
|
||||||
},
|
},*/
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
elevation = 0.dp
|
elevation = 0.dp
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.common.utils
|
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.composed
|
||||||
|
import androidx.compose.ui.draw.drawBehind
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a vertical gradient scrim in the foreground.
|
||||||
|
*
|
||||||
|
* @param color The color of the gradient scrim.
|
||||||
|
* @param startYPercentage The start y value, in percentage of the layout's height (0f to 1f)
|
||||||
|
* @param endYPercentage The end y value, in percentage of the layout's height (0f to 1f)
|
||||||
|
* @param decay The exponential decay to apply to the gradient. Defaults to `1.0f` which is
|
||||||
|
* a linear gradient.
|
||||||
|
* @param numStops The number of color stops to draw in the gradient. Higher numbers result in
|
||||||
|
* the higher visual quality at the cost of draw performance. Defaults to `16`.
|
||||||
|
*/
|
||||||
|
fun Modifier.verticalGradientScrim(
|
||||||
|
color: Color,
|
||||||
|
/*@FloatRange(from = 0.0, to = 1.0)*/ startYPercentage: Float = 0f,
|
||||||
|
/*@FloatRange(from = 0.0, to = 1.0)*/ endYPercentage: Float = 1f,
|
||||||
|
decay: Float = 1.0f,
|
||||||
|
numStops: Int = 16,
|
||||||
|
fixedHeight: Float? = null
|
||||||
|
): Modifier = composed {
|
||||||
|
val colors = remember(color, numStops) {
|
||||||
|
if (decay != 1f) {
|
||||||
|
// If we have a non-linear decay, we need to create the color gradient steps
|
||||||
|
// manually
|
||||||
|
val baseAlpha = color.alpha
|
||||||
|
List(numStops) { i ->
|
||||||
|
val x = i * 1f / (numStops - 1)
|
||||||
|
val opacity = x.pow(decay)
|
||||||
|
color.copy(alpha = baseAlpha * opacity)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If we have a linear decay, we just create a simple list of start + end colors
|
||||||
|
listOf(color.copy(alpha = 0f), color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var height by remember { mutableStateOf(fixedHeight ?: 0f) }
|
||||||
|
val brush = remember(color, numStops, startYPercentage, endYPercentage, height) {
|
||||||
|
Brush.verticalGradient(
|
||||||
|
colors = colors,
|
||||||
|
startY = height * startYPercentage,
|
||||||
|
endY = height * endYPercentage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
drawBehind {
|
||||||
|
height = fixedHeight ?: size.height
|
||||||
|
// log("Height",size.height.toString())
|
||||||
|
drawRect(brush = brush)
|
||||||
|
}
|
||||||
|
}
|
@ -53,9 +53,11 @@ actual class YoutubeProvider actual constructor(
|
|||||||
// Given Link is of a Playlist
|
// Given Link is of a Playlist
|
||||||
logger.i{ link }
|
logger.i{ link }
|
||||||
val playlistId = link.substringAfter("?list=").substringAfter("&list=").substringBefore("&").substringBefore("?")
|
val playlistId = link.substringAfter("?list=").substringAfter("&list=").substringBefore("&").substringBefore("?")
|
||||||
return getYTPlaylist(
|
return withContext(Dispatchers.IO){
|
||||||
|
getYTPlaylist(
|
||||||
playlistId
|
playlistId
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}else{//Given Link is of a Video
|
}else{//Given Link is of a Video
|
||||||
var searchId = "error"
|
var searchId = "error"
|
||||||
when{
|
when{
|
||||||
@ -70,9 +72,11 @@ actual class YoutubeProvider actual constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return if(searchId != "error") {
|
return if(searchId != "error") {
|
||||||
|
withContext(Dispatchers.IO){
|
||||||
getYTTrack(
|
getYTTrack(
|
||||||
searchId
|
searchId
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
logger.d{"Your Youtube Link is not of a Video!!"}
|
logger.d{"Your Youtube Link is not of a Video!!"}
|
||||||
null
|
null
|
||||||
|
Loading…
Reference in New Issue
Block a user