mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-22 17:14:32 +01:00
Navigation Implemented.
This commit is contained in:
parent
d734c82bf9
commit
38618bd2b1
@ -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"
|
||||
|
@ -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>
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -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){
|
||||
|
||||
}
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.shabinder.spotiflyer.utils
|
||||
|
||||
import com.shabinder.spotiflyer.MainActivity
|
||||
|
||||
val mainActivity
|
||||
get() = MainActivity.getInstance()
|
@ -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>
|
Loading…
Reference in New Issue
Block a user