diff --git a/android/build.gradle.kts b/android/build.gradle.kts index a031c07d..970989fd 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -95,7 +95,6 @@ dependencies { implementation(razorpay) implementation(fetch) } - implementation(MVIKotlin.mvikotlin) implementation(MVIKotlin.mvikotlinMain) implementation(MVIKotlin.mvikotlinLogging) diff --git a/android/src/main/java/com/shabinder/android/MainActivity.kt b/android/src/main/java/com/shabinder/android/MainActivity.kt index c6887a2d..e5e0e9b7 100644 --- a/android/src/main/java/com/shabinder/android/MainActivity.kt +++ b/android/src/main/java/com/shabinder/android/MainActivity.kt @@ -12,6 +12,14 @@ import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent 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 com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.extensions.compose.jetbrains.rootComponent @@ -53,17 +61,27 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + // This app draws behind the system bars, so we want to handle fitting system windows + WindowCompat.setDecorFitsSystemWindows(window, false) + setContent { SpotiFlyerTheme { 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() } diff --git a/common/compose-ui/src/commonMain/kotlin/com/shabinder/common/root/SpotiFlyerRootUi.kt b/common/compose-ui/src/commonMain/kotlin/com/shabinder/common/root/SpotiFlyerRootUi.kt index 439d3864..c75390ae 100644 --- a/common/compose-ui/src/commonMain/kotlin/com/shabinder/common/root/SpotiFlyerRootUi.kt +++ b/common/compose-ui/src/commonMain/kotlin/com/shabinder/common/root/SpotiFlyerRootUi.kt @@ -3,6 +3,7 @@ package com.shabinder.common.root import androidx.compose.animation.core.* import androidx.compose.animation.core.Spring.StiffnessLow import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.material.icons.Icons @@ -12,6 +13,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha 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 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.ui.SpotiFlyerLogo import com.shabinder.common.ui.appNameStyle +import com.shabinder.common.ui.colorPrimaryDark import com.shabinder.common.ui.splash.* +import com.shabinder.common.utils.verticalGradientScrim @Composable -fun SpotiFlyerRootContent(component: SpotiFlyerRoot):SpotiFlyerRoot { +fun SpotiFlyerRootContent(component: SpotiFlyerRoot,statusBarHeight:Dp = 0.dp):SpotiFlyerRoot { val transitionState = remember { MutableTransitionState(SplashState.Shown) } val transition = updateTransition(transitionState) @@ -52,6 +56,7 @@ fun SpotiFlyerRootContent(component: SpotiFlyerRoot):SpotiFlyerRoot { MainScreen( Modifier.alpha(contentAlpha), contentTopPadding, + statusBarHeight, component ) } @@ -59,17 +64,21 @@ fun SpotiFlyerRootContent(component: SpotiFlyerRoot):SpotiFlyerRoot { } @Composable -fun MainScreen(modifier: Modifier = Modifier, topPadding: Dp = 0.dp,component: SpotiFlyerRoot) { - val appBarColor = MaterialTheme.colors.surface +fun MainScreen(modifier: Modifier = Modifier, topPadding: Dp = 0.dp,statusBarHeight: Dp = 0.dp,component: SpotiFlyerRoot) { + + val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.65f) + Column( modifier = modifier.fillMaxSize() - /*.verticalGradientScrim( - color = sharedViewModel.gradientColor.copy(alpha = 0.38f), - color = appBarColor.copy(alpha = 0.38f), + .verticalGradientScrim( + color = colorPrimaryDark.copy(alpha = 0.38f), startYPercentage = 0.29f, endYPercentage = 0f, - )*/ + ) ) { + Spacer(Modifier.background(appBarColor).height(statusBarHeight).fillMaxWidth()) + LocalViewConfiguration.current + AppBar( backgroundColor = appBarColor, modifier = Modifier.fillMaxWidth() @@ -107,14 +116,14 @@ fun AppBar( style = appNameStyle ) } - }, + },/* actions = { IconButton( - onClick = { /*TODO: Open Preferences*/ } + onClick = { *//*TODO: Open Preferences*//* } ) { Icon(Icons.Filled.Settings,"Preferences", tint = Color.Gray) } - }, + },*/ modifier = modifier, elevation = 0.dp ) diff --git a/common/compose-ui/src/commonMain/kotlin/com/shabinder/common/utils/GradientScrim.kt b/common/compose-ui/src/commonMain/kotlin/com/shabinder/common/utils/GradientScrim.kt new file mode 100644 index 00000000..37f1e7eb --- /dev/null +++ b/common/compose-ui/src/commonMain/kotlin/com/shabinder/common/utils/GradientScrim.kt @@ -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 . + */ + +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) + } +} diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt index fb23a1f5..50eeaf4f 100644 --- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt +++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt @@ -53,9 +53,11 @@ actual class YoutubeProvider actual constructor( // Given Link is of a Playlist logger.i{ link } val playlistId = link.substringAfter("?list=").substringAfter("&list=").substringBefore("&").substringBefore("?") - return getYTPlaylist( - playlistId - ) + return withContext(Dispatchers.IO){ + getYTPlaylist( + playlistId + ) + } }else{//Given Link is of a Video var searchId = "error" when{ @@ -70,9 +72,11 @@ actual class YoutubeProvider actual constructor( } } return if(searchId != "error") { - getYTTrack( - searchId - ) + withContext(Dispatchers.IO){ + getYTTrack( + searchId + ) + } }else{ logger.d{"Your Youtube Link is not of a Video!!"} null