Navigation Implemented.

This commit is contained in:
shabinder 2020-12-29 18:48:23 +05:30
parent d734c82bf9
commit 38618bd2b1
10 changed files with 313 additions and 40 deletions

View File

@ -80,6 +80,9 @@ dependencies {
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"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"

View File

@ -1,24 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.shabinder.spotiflyer">
<queries>
<package android:name="com.gaana" />
<package android:name="com.spotify.music" />
<package android:name="com.google.android.youtube" />
</queries>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_STORAGE_PERMISSION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:forceDarkAllowed="true"
android:supportsRtl="true"
android:theme="@style/Theme.SpotiFlyer">
android:theme="@style/Theme.SpotiFlyer"
tools:targetApi="q"
tools:ignore="AllowBackup">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.SpotiFlyer">
android:hardwareAccelerated="true"
android:theme="@style/Theme.SpotiFlyer"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<data android:mimeType="text/plain" />
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Add your API key here -->
<meta-data
android:name="com.razorpay.ApiKey"
android:value="rzp_live_3ZQeoFYOxjmXye"
/>
</application>
</manifest>

View File

@ -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)
}

View File

@ -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,26 +71,131 @@ fun Home(modifier: Modifier = Modifier) {
@Composable
fun AboutColumn(viewModel: HomeViewModel, modifier: Modifier) {
fun AboutColumn(modifier: Modifier = Modifier) {
ScrollableColumn(modifier.fillMaxSize(),contentPadding = PaddingValues(16.dp)) {
Card(
modifier = modifier.padding(8.dp).fillMaxWidth(),
modifier = modifier.fillMaxWidth(),
border = BorderStroke(1.dp,Color.Gray)
) {
Column(modifier.padding(8.dp)) {
Column(modifier.padding(12.dp)) {
Text(
text = stringResource(R.string.supported_platform),
style = SpotiFlyerTypography.body1
)
Spacer(modifier = Modifier.padding(top = 8.dp))
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)
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)
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)
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
)
}
}
}
@Composable
@ -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))

View File

@ -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
)
}
}
}

View File

@ -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){
}

View File

@ -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,

View File

@ -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)
}

View File

@ -0,0 +1,6 @@
package com.shabinder.spotiflyer.utils
import com.shabinder.spotiflyer.MainActivity
val mainActivity
get() = MainActivity.getInstance()

View File

@ -3,4 +3,15 @@
<string name="home_about">About</string>
<string name="home_history">History</string>
<string name="supported_platform">Supported Platforms</string>
<string name="support_development">Support Development</string>
<string name="github_star">Star / Fork the project on Github.</string>
<string name="github">GitHub</string>
<string name="translate">Translate</string>
<string name="help_us_translate">Help us translate this app in your local language.</string>
<string name="donate">Donate</string>
<string name="donate_subtitle">If you think I deserve to get paid for my work, you can leave me some money here.</string>
<string name="share">Share</string>
<string name="share_subtitle">Share this app with your friends and family.</string>
<string name="made_with_love">Made with</string>
<string name="in_india">in India</string>
</resources>