From 38618bd2b10fa5254951a0c73076fb60323255c4 Mon Sep 17 00:00:00 2001 From: shabinder Date: Tue, 29 Dec 2020 18:48:23 +0530 Subject: [PATCH] Navigation Implemented. --- app/build.gradle | 3 + app/src/main/AndroidManifest.xml | 39 +++- .../com/shabinder/spotiflyer/MainActivity.kt | 17 +- .../com/shabinder/spotiflyer/home/Home.kt | 169 ++++++++++++++---- .../navigation/ComposeNavigation.kt | 37 ++++ .../spotiflyer/tracklist/TrackList.kt | 10 ++ .../java/com/shabinder/spotiflyer/ui/Type.kt | 12 +- .../shabinder/spotiflyer/utils/Extensions.kt | 49 +++++ .../com/shabinder/spotiflyer/utils/Utils.kt | 6 + app/src/main/res/values/strings.xml | 11 ++ 10 files changed, 313 insertions(+), 40 deletions(-) create mode 100644 app/src/main/java/com/shabinder/spotiflyer/navigation/ComposeNavigation.kt create mode 100644 app/src/main/java/com/shabinder/spotiflyer/tracklist/TrackList.kt create mode 100644 app/src/main/java/com/shabinder/spotiflyer/utils/Extensions.kt create mode 100644 app/src/main/java/com/shabinder/spotiflyer/utils/Utils.kt diff --git a/app/build.gradle b/app/build.gradle index f27d39f1..11df113f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -79,6 +79,9 @@ dependencies { 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" //Lifecycle implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 70824052..20a151a7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,24 +1,57 @@ + + + + + + + + + + + + + + + + + + android:theme="@style/Theme.SpotiFlyer" + tools:targetApi="q" + tools:ignore="AllowBackup"> + android:hardwareAccelerated="true" + android:theme="@style/Theme.SpotiFlyer" + android:launchMode="singleTask"> - + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt b/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt index 471bb7d4..002147df 100644 --- a/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt @@ -17,8 +17,10 @@ import androidx.compose.ui.platform.setContent import androidx.compose.ui.res.vectorResource import androidx.core.view.WindowCompat import com.shabinder.spotiflyer.home.Home +import com.shabinder.spotiflyer.navigation.ComposeNavigation import com.shabinder.spotiflyer.ui.ComposeLearnTheme import com.shabinder.spotiflyer.ui.appNameStyle +import com.shabinder.spotiflyer.utils.requestStoragePermission import dev.chrisbanes.accompanist.insets.ProvideWindowInsets import dev.chrisbanes.accompanist.insets.statusBarsHeight @@ -43,11 +45,22 @@ class MainActivity : AppCompatActivity() { modifier = Modifier.fillMaxWidth() ) - Home() + ComposeNavigation() } } } } + + requestStoragePermission() + } + + companion object{ + private lateinit var instance: MainActivity + fun getInstance():MainActivity = this.instance + } + + init { + instance = this } } @@ -72,7 +85,7 @@ fun AppBar( actions = { Providers(AmbientContentAlpha provides ContentAlpha.medium) { IconButton( - onClick = { /* TODO: Open Settings */ } + onClick = { /* TODO: Open Preferences*/ } ) { Icon(Icons.Filled.Settings, tint = Color.Gray) } diff --git a/app/src/main/java/com/shabinder/spotiflyer/home/Home.kt b/app/src/main/java/com/shabinder/spotiflyer/home/Home.kt index 3ed69822..888920f7 100644 --- a/app/src/main/java/com/shabinder/spotiflyer/home/Home.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/home/Home.kt @@ -1,20 +1,18 @@ package com.shabinder.spotiflyer.home -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.border +import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.* +import androidx.compose.material.AmbientTextStyle +import androidx.compose.material.Icon import androidx.compose.material.TabDefaults.tabIndicatorOffset +import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.History import androidx.compose.material.icons.outlined.Info -import androidx.compose.material.icons.rounded.History -import androidx.compose.material.icons.rounded.Info -import androidx.compose.material.icons.rounded.InsertLink +import androidx.compose.material.icons.rounded.* import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue @@ -23,20 +21,22 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.imageResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import androidx.navigation.compose.navigate import com.shabinder.spotiflyer.R import com.shabinder.spotiflyer.ui.SpotiFlyerTypography import com.shabinder.spotiflyer.ui.colorAccent import com.shabinder.spotiflyer.ui.colorPrimary +import com.shabinder.spotiflyer.utils.openPlatform @Composable -fun Home(modifier: Modifier = Modifier) { +fun Home(navController: NavController, modifier: Modifier = Modifier) { val viewModel: HomeViewModel = viewModel() Column(modifier = modifier) { @@ -46,9 +46,10 @@ fun Home(modifier: Modifier = Modifier) { AuthenticationBanner(viewModel,modifier) - SearchBar( + SearchPanel( link, viewModel::updateLink, + navController, modifier ) @@ -61,7 +62,7 @@ fun Home(modifier: Modifier = Modifier) { ) when(selectedCategory){ - HomeCategory.About -> AboutColumn(viewModel,modifier) + HomeCategory.About -> AboutColumn() HomeCategory.History -> HistoryColumn() } @@ -70,25 +71,130 @@ fun Home(modifier: Modifier = Modifier) { @Composable -fun AboutColumn(viewModel: HomeViewModel, modifier: Modifier) { - Card( - modifier = modifier.padding(8.dp).fillMaxWidth(), - border = BorderStroke(1.dp,Color.Gray) - ) { - Column(modifier.padding(8.dp)) { - Text( - text = stringResource(R.string.supported_platform), - style = SpotiFlyerTypography.body1 - ) - Spacer(modifier = Modifier.padding(top = 8.dp)) - Row(horizontalArrangement = Arrangement.Center,modifier = modifier.fillMaxWidth()) { - Icon(imageVector = vectorResource(id = R.drawable.ic_spotify_logo ),tint = Color.Unspecified) - Spacer(modifier = modifier.padding(start = 24.dp)) - Icon(imageVector = vectorResource(id = R.drawable.ic_gaana ),tint = Color.Unspecified) - Spacer(modifier = modifier.padding(start = 24.dp)) - Icon(imageVector = vectorResource(id = R.drawable.ic_youtube),tint = Color.Unspecified) +fun AboutColumn(modifier: Modifier = Modifier) { + ScrollableColumn(modifier.fillMaxSize(),contentPadding = PaddingValues(16.dp)) { + Card( + modifier = modifier.fillMaxWidth(), + border = BorderStroke(1.dp,Color.Gray) + ) { + Column(modifier.padding(12.dp)) { + Text( + text = stringResource(R.string.supported_platform), + style = SpotiFlyerTypography.body1 + ) + Spacer(modifier = Modifier.padding(top = 12.dp)) + Row(horizontalArrangement = Arrangement.Center,modifier = modifier.fillMaxWidth()) { + Icon( + imageVector = vectorResource(id = R.drawable.ic_spotify_logo), tint = Color.Unspecified, + modifier = Modifier.clickable( + onClick = { openPlatform("com.spotify.music","http://open.spotify.com") }) + ) + Spacer(modifier = modifier.padding(start = 24.dp)) + Icon(imageVector = vectorResource(id = R.drawable.ic_gaana ),tint = Color.Unspecified, + modifier = Modifier.clickable( + onClick = { openPlatform("com.gaana","http://gaana.com") }) + ) + Spacer(modifier = modifier.padding(start = 24.dp)) + Icon(imageVector = vectorResource(id = R.drawable.ic_youtube),tint = Color.Unspecified, + modifier = Modifier.clickable( + onClick = { openPlatform("com.google.android.youtube","http://m.youtube.com") }) + ) + } } } + Spacer(modifier = Modifier.padding(top = 8.dp)) + Card( + modifier = modifier.fillMaxWidth(), + border = BorderStroke(1.dp,Color.Gray) + ) { + Column(modifier.padding(12.dp)) { + Text( + text = stringResource(R.string.support_development), + style = SpotiFlyerTypography.body1 + ) + Spacer(modifier = Modifier.padding(top = 6.dp)) + Row(verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth().clickable( + onClick = { openPlatform("http://github.com/Shabinder/SpotiFlyer") }) + .padding(vertical = 6.dp) + ) { + Icon(imageVector = vectorResource(id = R.drawable.ic_github ),tint = Color.LightGray) + Spacer(modifier = Modifier.padding(start = 16.dp)) + Column { + Text( + text = stringResource(R.string.github), + style = SpotiFlyerTypography.h6 + ) + Text( + text = stringResource(R.string.github_star), + style = SpotiFlyerTypography.subtitle2 + ) + } + } + Row(modifier = modifier.fillMaxWidth().padding(vertical = 6.dp),verticalAlignment = Alignment.CenterVertically) { + Icon(Icons.Rounded.Flag.copy(defaultHeight = 32.dp,defaultWidth = 32.dp)) + Spacer(modifier = Modifier.padding(start = 16.dp)) + Column { + Text( + text = stringResource(R.string.translate), + style = SpotiFlyerTypography.h6 + ) + Text( + text = stringResource(R.string.help_us_translate), + style = SpotiFlyerTypography.subtitle2 + ) + } + } + Row(modifier = modifier.fillMaxWidth().padding(vertical = 6.dp),verticalAlignment = Alignment.CenterVertically) { + Icon(Icons.Rounded.CardGiftcard.copy(defaultHeight = 32.dp,defaultWidth = 32.dp)) + Spacer(modifier = Modifier.padding(start = 16.dp)) + Column { + Text( + text = stringResource(R.string.donate), + style = SpotiFlyerTypography.h6 + ) + Text( + text = stringResource(R.string.donate_subtitle), + style = SpotiFlyerTypography.subtitle2 + ) + } + } + Row(modifier = modifier.fillMaxWidth().padding(vertical = 6.dp),verticalAlignment = Alignment.CenterVertically) { + Icon(Icons.Rounded.Share.copy(defaultHeight = 32.dp,defaultWidth = 32.dp)) + Spacer(modifier = Modifier.padding(start = 16.dp)) + Column { + Text( + text = stringResource(R.string.share), + style = SpotiFlyerTypography.h6 + ) + Text( + text = stringResource(R.string.share_subtitle), + style = SpotiFlyerTypography.subtitle2 + ) + } + } + } + } + + Row( + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + modifier = modifier.fillMaxWidth().padding(8.dp) + ) { + Text( + text = stringResource(id = R.string.made_with_love), + color = colorPrimary, + fontSize = 22.sp + ) + Spacer(modifier = Modifier.padding(start = 4.dp)) + Icon(vectorResource(id = R.drawable.ic_heart),tint = Color.Unspecified) + Spacer(modifier = Modifier.padding(start = 4.dp)) + Text( + text = stringResource(id = R.string.in_india), + color = colorPrimary, + fontSize = 22.sp + ) + } } } @@ -150,15 +256,16 @@ fun HomeTabBar( } @Composable -fun SearchBar( +fun SearchPanel( link:String, updateLink:(s:String) -> Unit, + navController: NavController, modifier: Modifier = Modifier ){ Column( horizontalAlignment = Alignment.CenterHorizontally, - modifier = modifier.padding(top = 16.dp,bottom = 16.dp) + modifier = modifier.padding(top = 16.dp,) ){ TextField( leadingIcon = { @@ -182,7 +289,7 @@ fun SearchBar( ) OutlinedButton( modifier = Modifier.padding(12.dp).wrapContentWidth(), - onClick = {/*TODO*/}, + onClick = {navController.navigate("track_list/$link") }, border = BorderStroke(1.dp, Brush.horizontalGradient(listOf(colorPrimary, colorAccent))) ){ Text(text = "Search",style = SpotiFlyerTypography.h6,modifier = Modifier.padding(4.dp)) diff --git a/app/src/main/java/com/shabinder/spotiflyer/navigation/ComposeNavigation.kt b/app/src/main/java/com/shabinder/spotiflyer/navigation/ComposeNavigation.kt new file mode 100644 index 00000000..ab50cf73 --- /dev/null +++ b/app/src/main/java/com/shabinder/spotiflyer/navigation/ComposeNavigation.kt @@ -0,0 +1,37 @@ +package com.shabinder.spotiflyer.navigation + +import androidx.compose.runtime.Composable +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.navArgument +import androidx.navigation.compose.rememberNavController +import com.shabinder.spotiflyer.home.Home +import com.shabinder.spotiflyer.tracklist.TrackList + +@Composable +fun ComposeNavigation() { + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = "home" + ) { + + //HomeScreen - Starting Point + composable("home") { + Home(navController = navController) + } + + //Track list Screen + //Argument `link` = Link of Track/Album/Playlist + composable( + "track_list/{link}", + arguments = listOf(navArgument("link") { type = NavType.StringType }) + ) { + TrackList( + link = it.arguments?.getString("link") ?: "error", + navController = navController + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/tracklist/TrackList.kt b/app/src/main/java/com/shabinder/spotiflyer/tracklist/TrackList.kt new file mode 100644 index 00000000..ec09f838 --- /dev/null +++ b/app/src/main/java/com/shabinder/spotiflyer/tracklist/TrackList.kt @@ -0,0 +1,10 @@ +package com.shabinder.spotiflyer.tracklist + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.navigation.NavController + +@Composable +fun TrackList(link: String,navController: NavController, modifier: Modifier = Modifier){ + +} \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/ui/Type.kt b/app/src/main/java/com/shabinder/spotiflyer/ui/Type.kt index 580a976e..85aee6ad 100644 --- a/app/src/main/java/com/shabinder/spotiflyer/ui/Type.kt +++ b/app/src/main/java/com/shabinder/spotiflyer/ui/Type.kt @@ -1,5 +1,6 @@ package com.shabinder.spotiflyer.ui +import androidx.compose.material.MaterialTheme import androidx.compose.material.Typography import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle @@ -53,9 +54,11 @@ val SpotiFlyerTypography = Typography( ), h6 = TextStyle( fontFamily = Montserrat, - fontSize = 20.sp, - fontWeight = FontWeight.SemiBold, - lineHeight = 24.sp + fontSize = 18.sp, + fontWeight = FontWeight.Medium, + lineHeight = 26.sp, + letterSpacing = 0.5.sp + ), subtitle1 = TextStyle( fontFamily = Montserrat, @@ -76,7 +79,8 @@ val SpotiFlyerTypography = Typography( fontSize = 16.sp, fontWeight = FontWeight.Medium, lineHeight = 20.sp, - letterSpacing = 0.15.sp + letterSpacing = 0.15.sp, + color = colorAccent ), body2 = TextStyle( fontFamily = Montserrat, diff --git a/app/src/main/java/com/shabinder/spotiflyer/utils/Extensions.kt b/app/src/main/java/com/shabinder/spotiflyer/utils/Extensions.kt new file mode 100644 index 00000000..9360edba --- /dev/null +++ b/app/src/main/java/com/shabinder/spotiflyer/utils/Extensions.kt @@ -0,0 +1,49 @@ +package com.shabinder.spotiflyer.utils + +import android.Manifest +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.os.Build +import android.util.Log +import com.shabinder.spotiflyer.BuildConfig +import com.shabinder.spotiflyer.MainActivity + + +/* +* Only Log in Debug Mode +**/ +fun log(tag:String? = "SpotiFlyer",message:String? = "null"){ + if (BuildConfig.DEBUG) { + Log.d(tag ?: "spotiflyer", message ?: "null") + } +} +fun MainActivity.requestStoragePermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + this.requestPermissions( + arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), + 786 + ) + } +} + +fun openPlatform(packageName:String, websiteAddress:String){ + val manager: PackageManager = mainActivity.packageManager + try { + val intent = manager.getLaunchIntentForPackage(packageName) + ?: throw PackageManager.NameNotFoundException() + intent.addCategory(Intent.CATEGORY_LAUNCHER) + mainActivity.startActivity(intent) + } catch (e: PackageManager.NameNotFoundException) { + val uri: Uri = + Uri.parse(websiteAddress) + val intent = Intent(Intent.ACTION_VIEW, uri) + mainActivity.startActivity(intent) + } +} + +fun openPlatform(websiteAddress:String){ + val uri = Uri.parse(websiteAddress) + val intent = Intent(Intent.ACTION_VIEW, uri) + mainActivity.startActivity(intent) +} \ No newline at end of file diff --git a/app/src/main/java/com/shabinder/spotiflyer/utils/Utils.kt b/app/src/main/java/com/shabinder/spotiflyer/utils/Utils.kt new file mode 100644 index 00000000..9df7fb3e --- /dev/null +++ b/app/src/main/java/com/shabinder/spotiflyer/utils/Utils.kt @@ -0,0 +1,6 @@ +package com.shabinder.spotiflyer.utils + +import com.shabinder.spotiflyer.MainActivity + +val mainActivity + get() = MainActivity.getInstance() \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2db2c904..488c8b7f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,4 +3,15 @@ About History Supported Platforms + Support Development + Star / Fork the project on Github. + GitHub + Translate + Help us translate this app in your local language. + Donate + If you think I deserve to get paid for my work, you can leave me some money here. + Share + Share this app with your friends and family. + Made with + in India \ No newline at end of file