mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-24 18:04:33 +01:00
Scrollbars and various Bug Fixes
This commit is contained in:
parent
d90469d0fd
commit
603314fcd2
@ -48,6 +48,7 @@
|
|||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:largeHeap="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
|
@ -236,7 +236,13 @@ class MainActivity : ComponentActivity(), PaymentResultListener {
|
|||||||
ContextCompat.startForegroundService(this@MainActivity, serviceIntent)
|
ContextCompat.startForegroundService(this@MainActivity, serviceIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun giveDonation() = startPayment(this@MainActivity)
|
override fun giveDonation() {
|
||||||
|
try {
|
||||||
|
startPayment(this@MainActivity)
|
||||||
|
}catch (e:Exception) {
|
||||||
|
openPlatform("",platformLink = "https://razorpay.com/payment-button/pl_GnKuuDBdBu0ank/view/?utm_source=payment_button&utm_medium=button&utm_campaign=payment_button")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun shareApp() {
|
override fun shareApp() {
|
||||||
val sendIntent: Intent = Intent().apply {
|
val sendIntent: Intent = Intent().apply {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
object Versions {
|
object Versions {
|
||||||
// App's Version (To be bumped at each update)
|
// App's Version (To be bumped at each update)
|
||||||
const val versionName = "2.3.0"
|
const val versionName = "2.3.5"
|
||||||
|
|
||||||
// Kotlin
|
// Kotlin
|
||||||
const val kotlinVersion = "1.4.32"
|
const val kotlinVersion = "1.4.32"
|
||||||
@ -45,7 +45,7 @@ object Versions {
|
|||||||
const val slf4j = "1.7.30"
|
const val slf4j = "1.7.30"
|
||||||
|
|
||||||
// Android
|
// Android
|
||||||
const val versionCode = 17
|
const val versionCode = 18
|
||||||
const val minSdkVersion = 21
|
const val minSdkVersion = 21
|
||||||
const val compileSdkVersion = 29
|
const val compileSdkVersion = 29
|
||||||
const val targetSdkVersion = 29
|
const val targetSdkVersion = 29
|
||||||
@ -142,7 +142,7 @@ object Extras {
|
|||||||
const val jaudioTagger = "com.github.Shabinder:JAudioTagger-Android:1.0"
|
const val jaudioTagger = "com.github.Shabinder:JAudioTagger-Android:1.0"
|
||||||
const val kermit = "co.touchlab:kermit:${Versions.kermit}"
|
const val kermit = "co.touchlab:kermit:${Versions.kermit}"
|
||||||
object Android {
|
object Android {
|
||||||
val razorpay = "com.razorpay:checkout:1.6.5"
|
val razorpay = "com.razorpay:checkout:1.6.7"
|
||||||
val fetch = "androidx.tonyodev.fetch2:xfetch2:3.1.6"
|
val fetch = "androidx.tonyodev.fetch2:xfetch2:3.1.6"
|
||||||
val appUpdator = "com.github.amitbd1508:AppUpdater:4.1.0"
|
val appUpdator = "com.github.amitbd1508:AppUpdater:4.1.0"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ScrollState
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
actual val MARGIN_SCROLLBAR: Dp = 0.dp
|
||||||
|
|
||||||
|
actual interface ScrollbarAdapter
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
actual fun rememberScrollbarAdapter(
|
||||||
|
scrollState: ScrollState
|
||||||
|
): ScrollbarAdapter = object : ScrollbarAdapter {}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
actual fun rememberScrollbarAdapter(
|
||||||
|
scrollState: LazyListState,
|
||||||
|
itemCount: Int,
|
||||||
|
averageItemSize: Dp
|
||||||
|
): ScrollbarAdapter =
|
||||||
|
object : ScrollbarAdapter {}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
actual fun VerticalScrollbar(
|
||||||
|
modifier: Modifier,
|
||||||
|
adapter: ScrollbarAdapter
|
||||||
|
) {
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ScrollState
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
|
||||||
|
expect val MARGIN_SCROLLBAR: Dp
|
||||||
|
|
||||||
|
expect interface ScrollbarAdapter
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
expect fun rememberScrollbarAdapter(
|
||||||
|
scrollState: LazyListState,
|
||||||
|
itemCount: Int,
|
||||||
|
averageItemSize: Dp
|
||||||
|
): ScrollbarAdapter
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
expect fun rememberScrollbarAdapter(
|
||||||
|
scrollState: ScrollState
|
||||||
|
): ScrollbarAdapter
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
expect fun VerticalScrollbar(
|
||||||
|
modifier: Modifier,
|
||||||
|
adapter: ScrollbarAdapter
|
||||||
|
)
|
@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.Box
|
|||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
@ -29,6 +30,7 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.CircularProgressIndicator
|
import androidx.compose.material.CircularProgressIndicator
|
||||||
import androidx.compose.material.ExtendedFloatingActionButton
|
import androidx.compose.material.ExtendedFloatingActionButton
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
@ -77,6 +79,9 @@ fun SpotiFlyerListContent(
|
|||||||
Text("Loading..", style = appNameStyle, color = colorPrimary)
|
Text("Loading..", style = appNameStyle, color = colorPrimary)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
val listState = rememberLazyListState()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
content = {
|
content = {
|
||||||
@ -91,12 +96,23 @@ fun SpotiFlyerListContent(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
state = listState,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
)
|
)
|
||||||
|
|
||||||
DownloadAllButton(
|
DownloadAllButton(
|
||||||
onClick = { component.onDownloadAllClicked(model.trackList) },
|
onClick = { component.onDownloadAllClicked(model.trackList) },
|
||||||
modifier = Modifier.padding(bottom = 24.dp).align(Alignment.BottomCenter)
|
modifier = Modifier.padding(bottom = 24.dp).align(Alignment.BottomCenter)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
VerticalScrollbar(
|
||||||
|
modifier = Modifier.padding(end = 2.dp).align(Alignment.CenterEnd).fillMaxHeight(),
|
||||||
|
adapter = rememberScrollbarAdapter(
|
||||||
|
scrollState = listState,
|
||||||
|
itemCount = model.trackList.size,
|
||||||
|
averageItemSize = 72.dp
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,11 @@ import androidx.compose.foundation.background
|
|||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
@ -35,6 +37,7 @@ import androidx.compose.foundation.layout.width
|
|||||||
import androidx.compose.foundation.layout.wrapContentWidth
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
@ -125,7 +128,7 @@ fun HomeTabBar(
|
|||||||
|
|
||||||
TabRow(
|
TabRow(
|
||||||
selectedTabIndex = selectedIndex,
|
selectedTabIndex = selectedIndex,
|
||||||
indicator = indicator,
|
indicator = indicator as @Composable (List<TabPosition>) -> Unit,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
) {
|
) {
|
||||||
categories.forEachIndexed { index, category ->
|
categories.forEachIndexed { index, category ->
|
||||||
@ -219,160 +222,169 @@ fun SearchPanel(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutColumn(modifier: Modifier = Modifier) {
|
fun AboutColumn(modifier: Modifier = Modifier) {
|
||||||
// TODO Make Scrollable
|
|
||||||
Column(modifier.fillMaxSize().padding(8.dp).verticalScroll(rememberScrollState())) {
|
|
||||||
Card(
|
|
||||||
modifier = modifier.fillMaxWidth(),
|
|
||||||
border = BorderStroke(1.dp, Color.Gray)
|
|
||||||
) {
|
|
||||||
Column(modifier.padding(12.dp)) {
|
|
||||||
Text(
|
|
||||||
text = "Supported Platforms",
|
|
||||||
style = SpotiFlyerTypography.body1,
|
|
||||||
color = colorAccent
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.padding(top = 12.dp))
|
|
||||||
Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) {
|
|
||||||
Icon(
|
|
||||||
SpotifyLogo(),
|
|
||||||
"Open Spotify",
|
|
||||||
tint = Color.Unspecified,
|
|
||||||
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
|
|
||||||
onClick = { methods.value.openPlatform("com.spotify.music", "http://open.spotify.com") }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Spacer(modifier = modifier.padding(start = 16.dp))
|
|
||||||
Icon(
|
|
||||||
GaanaLogo(),
|
|
||||||
"Open Gaana",
|
|
||||||
tint = Color.Unspecified,
|
|
||||||
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
|
|
||||||
onClick = { methods.value.openPlatform("com.gaana", "http://gaana.com") }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Spacer(modifier = modifier.padding(start = 16.dp))
|
|
||||||
Icon(
|
|
||||||
YoutubeLogo(),
|
|
||||||
"Open Youtube",
|
|
||||||
tint = Color.Unspecified,
|
|
||||||
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
|
|
||||||
onClick = { methods.value.openPlatform("com.google.android.youtube", "http://m.youtube.com") }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Spacer(modifier = modifier.padding(start = 12.dp))
|
|
||||||
Icon(
|
|
||||||
YoutubeMusicLogo(),
|
|
||||||
"Open Youtube Music",
|
|
||||||
tint = Color.Unspecified,
|
|
||||||
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
|
|
||||||
onClick = { methods.value.openPlatform("com.google.android.apps.youtube.music", "https://music.youtube.com/") }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.padding(top = 8.dp))
|
|
||||||
Card(
|
|
||||||
modifier = modifier.fillMaxWidth(),
|
|
||||||
border = BorderStroke(1.dp, Color.Gray) // Gray
|
|
||||||
) {
|
|
||||||
Column(modifier.padding(12.dp)) {
|
|
||||||
Text(
|
|
||||||
text = "Support Development",
|
|
||||||
style = SpotiFlyerTypography.body1,
|
|
||||||
color = colorAccent
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.padding(top = 6.dp))
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
modifier = Modifier.fillMaxWidth().clickable(
|
|
||||||
onClick = { methods.value.openPlatform("", "http://github.com/Shabinder/SpotiFlyer") }
|
|
||||||
)
|
|
||||||
.padding(vertical = 6.dp)
|
|
||||||
) {
|
|
||||||
Icon(GithubLogo(), "Open Project Repo", tint = Color(0xFFCCCCCC))
|
|
||||||
Spacer(modifier = Modifier.padding(start = 16.dp))
|
|
||||||
Column {
|
|
||||||
Text(
|
|
||||||
text = "GitHub",
|
|
||||||
style = SpotiFlyerTypography.h6
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = "Star / Fork the project on Github.",
|
|
||||||
style = SpotiFlyerTypography.subtitle2
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Row(
|
|
||||||
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
|
||||||
.clickable(onClick = { methods.value.openPlatform("", "http://github.com/Shabinder/SpotiFlyer") }),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
Icon(Icons.Rounded.Flag, "Help Translate", Modifier.size(32.dp))
|
|
||||||
Spacer(modifier = Modifier.padding(start = 16.dp))
|
|
||||||
Column {
|
|
||||||
Text(
|
|
||||||
text = "Translate",
|
|
||||||
style = SpotiFlyerTypography.h6
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = "Help us translate this app in your local language.",
|
|
||||||
style = SpotiFlyerTypography.subtitle2
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var isDonationDialogVisible by remember { mutableStateOf(false) }
|
Box {
|
||||||
|
val stateVertical = rememberScrollState(0)
|
||||||
|
|
||||||
DonationDialog(
|
Column(modifier.fillMaxSize().padding(8.dp).verticalScroll(stateVertical)) {
|
||||||
isDonationDialogVisible
|
Card(
|
||||||
) {
|
modifier = modifier.fillMaxWidth(),
|
||||||
isDonationDialogVisible = false
|
border = BorderStroke(1.dp, Color.Gray)
|
||||||
}
|
) {
|
||||||
|
Column(modifier.padding(12.dp)) {
|
||||||
Row(
|
Text(
|
||||||
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
text = "Supported Platforms",
|
||||||
.clickable(onClick = { isDonationDialogVisible = true }),
|
style = SpotiFlyerTypography.body1,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
color = colorAccent
|
||||||
) {
|
)
|
||||||
Icon(Icons.Rounded.CardGiftcard, "Support Developer")
|
Spacer(modifier = Modifier.padding(top = 12.dp))
|
||||||
Spacer(modifier = Modifier.padding(start = 16.dp))
|
Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) {
|
||||||
Column {
|
Icon(
|
||||||
Text(
|
SpotifyLogo(),
|
||||||
text = "Donate",
|
"Open Spotify",
|
||||||
style = SpotiFlyerTypography.h6
|
tint = Color.Unspecified,
|
||||||
|
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
|
||||||
|
onClick = { methods.value.openPlatform("com.spotify.music", "http://open.spotify.com") }
|
||||||
|
)
|
||||||
)
|
)
|
||||||
Text(
|
Spacer(modifier = modifier.padding(start = 16.dp))
|
||||||
text = "If you think I deserve to get paid for my work, you can support me here.",
|
Icon(
|
||||||
//text = "SpotiFlyer will always be, Free and Open-Source. You can however show us that you care by sending a small donation.",
|
GaanaLogo(),
|
||||||
style = SpotiFlyerTypography.subtitle2
|
"Open Gaana",
|
||||||
|
tint = Color.Unspecified,
|
||||||
|
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
|
||||||
|
onClick = { methods.value.openPlatform("com.gaana", "http://gaana.com") }
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
Spacer(modifier = modifier.padding(start = 16.dp))
|
||||||
}
|
Icon(
|
||||||
Row(
|
YoutubeLogo(),
|
||||||
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
"Open Youtube",
|
||||||
.clickable(
|
tint = Color.Unspecified,
|
||||||
onClick = {
|
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
|
||||||
methods.value.shareApp()
|
onClick = { methods.value.openPlatform("com.google.android.youtube", "http://m.youtube.com") }
|
||||||
}
|
)
|
||||||
),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
Icon(Icons.Rounded.Share, "Share SpotiFlyer App")
|
|
||||||
Spacer(modifier = Modifier.padding(start = 16.dp))
|
|
||||||
Column {
|
|
||||||
Text(
|
|
||||||
text = "Share",
|
|
||||||
style = SpotiFlyerTypography.h6
|
|
||||||
)
|
)
|
||||||
Text(
|
Spacer(modifier = modifier.padding(start = 12.dp))
|
||||||
text = "Share this app with your friends and family.",
|
Icon(
|
||||||
style = SpotiFlyerTypography.subtitle2
|
YoutubeMusicLogo(),
|
||||||
|
"Open Youtube Music",
|
||||||
|
tint = Color.Unspecified,
|
||||||
|
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
|
||||||
|
onClick = { methods.value.openPlatform("com.google.android.apps.youtube.music", "https://music.youtube.com/") }
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Spacer(modifier = Modifier.padding(top = 8.dp))
|
||||||
|
Card(
|
||||||
|
modifier = modifier.fillMaxWidth(),
|
||||||
|
border = BorderStroke(1.dp, Color.Gray) // Gray
|
||||||
|
) {
|
||||||
|
Column(modifier.padding(12.dp)) {
|
||||||
|
Text(
|
||||||
|
text = "Support Development",
|
||||||
|
style = SpotiFlyerTypography.body1,
|
||||||
|
color = colorAccent
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.padding(top = 6.dp))
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.fillMaxWidth().clickable(
|
||||||
|
onClick = { methods.value.openPlatform("", "http://github.com/Shabinder/SpotiFlyer") }
|
||||||
|
)
|
||||||
|
.padding(vertical = 6.dp)
|
||||||
|
) {
|
||||||
|
Icon(GithubLogo(), "Open Project Repo", tint = Color(0xFFCCCCCC))
|
||||||
|
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = "GitHub",
|
||||||
|
style = SpotiFlyerTypography.h6
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Star / Fork the project on Github.",
|
||||||
|
style = SpotiFlyerTypography.subtitle2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
||||||
|
.clickable(onClick = { methods.value.openPlatform("", "http://github.com/Shabinder/SpotiFlyer") }),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(Icons.Rounded.Flag, "Help Translate", Modifier.size(32.dp))
|
||||||
|
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = "Translate",
|
||||||
|
style = SpotiFlyerTypography.h6
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Help us translate this app in your local language.",
|
||||||
|
style = SpotiFlyerTypography.subtitle2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var isDonationDialogVisible by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
DonationDialog(
|
||||||
|
isDonationDialogVisible
|
||||||
|
) {
|
||||||
|
isDonationDialogVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
||||||
|
.clickable(onClick = { isDonationDialogVisible = true }),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(Icons.Rounded.CardGiftcard, "Support Developer")
|
||||||
|
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = "Donate",
|
||||||
|
style = SpotiFlyerTypography.h6
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "If you think I deserve to get paid for my work, you can support me here.",
|
||||||
|
//text = "SpotiFlyer will always be, Free and Open-Source. You can however show us that you care by sending a small donation.",
|
||||||
|
style = SpotiFlyerTypography.subtitle2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
||||||
|
.clickable(
|
||||||
|
onClick = {
|
||||||
|
methods.value.shareApp()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(Icons.Rounded.Share, "Share SpotiFlyer App")
|
||||||
|
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = "Share",
|
||||||
|
style = SpotiFlyerTypography.h6
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Share this app with your friends and family.",
|
||||||
|
style = SpotiFlyerTypography.subtitle2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VerticalScrollbar(
|
||||||
|
modifier = Modifier.padding(end = 2.dp).align(Alignment.CenterEnd).fillMaxHeight(),
|
||||||
|
adapter = rememberScrollbarAdapter(stateVertical)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,19 +404,35 @@ fun HistoryColumn(
|
|||||||
Text("No History Available", style = SpotiFlyerTypography.h4.copy(fontWeight = FontWeight.Light), textAlign = TextAlign.Center)
|
Text("No History Available", style = SpotiFlyerTypography.h4.copy(fontWeight = FontWeight.Light), textAlign = TextAlign.Center)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LazyColumn(
|
Box {
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
|
||||||
content = {
|
val listState = rememberLazyListState()
|
||||||
items(it.distinctBy { record -> record.coverUrl }) { record ->
|
val itemList = it.distinctBy { record -> record.coverUrl }
|
||||||
DownloadRecordItem(
|
|
||||||
item = record,
|
LazyColumn(
|
||||||
loadImage,
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
onItemClicked
|
content = {
|
||||||
)
|
items(itemList) { record ->
|
||||||
}
|
DownloadRecordItem(
|
||||||
},
|
item = record,
|
||||||
modifier = Modifier.padding(top = 8.dp).fillMaxSize()
|
loadImage,
|
||||||
)
|
onItemClicked
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state = listState,
|
||||||
|
modifier = Modifier.padding(top = 8.dp).fillMaxSize()
|
||||||
|
)
|
||||||
|
|
||||||
|
VerticalScrollbar(
|
||||||
|
modifier = Modifier.padding(end = 2.dp).align(Alignment.CenterEnd).fillMaxHeight(),
|
||||||
|
adapter = rememberScrollbarAdapter(
|
||||||
|
scrollState = listState,
|
||||||
|
itemCount = itemList.size,
|
||||||
|
averageItemSize = 70.dp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,14 +67,6 @@ actual fun DownloadImageTick() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
actual fun DonationDialog(
|
|
||||||
isVisible:Boolean,
|
|
||||||
onDismiss:()->Unit
|
|
||||||
){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun montserratFont() = FontFamily(
|
actual fun montserratFont() = FontFamily(
|
||||||
Font("font/montserrat_light.ttf", FontWeight.Light),
|
Font("font/montserrat_light.ttf", FontWeight.Light),
|
||||||
Font("font/montserrat_regular.ttf", FontWeight.Normal),
|
Font("font/montserrat_regular.ttf", FontWeight.Normal),
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.ScrollState
|
||||||
|
import androidx.compose.foundation.ScrollbarAdapter
|
||||||
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
actual val MARGIN_SCROLLBAR: Dp = 8.dp
|
||||||
|
|
||||||
|
actual typealias ScrollbarAdapter = androidx.compose.foundation.ScrollbarAdapter
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
@Composable
|
||||||
|
actual fun rememberScrollbarAdapter(
|
||||||
|
scrollState: LazyListState,
|
||||||
|
itemCount: Int,
|
||||||
|
averageItemSize: Dp
|
||||||
|
): ScrollbarAdapter =
|
||||||
|
androidx.compose.foundation.rememberScrollbarAdapter(
|
||||||
|
scrollState = scrollState,
|
||||||
|
itemCount = itemCount,
|
||||||
|
averageItemSize = averageItemSize
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
actual fun rememberScrollbarAdapter(
|
||||||
|
scrollState: ScrollState
|
||||||
|
): ScrollbarAdapter = remember(scrollState) {
|
||||||
|
ScrollbarAdapter(scrollState)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
actual fun VerticalScrollbar(
|
||||||
|
modifier: Modifier,
|
||||||
|
adapter: ScrollbarAdapter
|
||||||
|
) {
|
||||||
|
androidx.compose.foundation.VerticalScrollbar(
|
||||||
|
modifier = modifier,
|
||||||
|
adapter = adapter
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.material.Card
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
|
import com.shabinder.common.models.methods
|
||||||
|
|
||||||
|
@OptIn(ExperimentalAnimationApi::class)
|
||||||
|
@Composable
|
||||||
|
actual fun DonationDialog(
|
||||||
|
isVisible:Boolean,
|
||||||
|
onDismiss:()->Unit
|
||||||
|
){
|
||||||
|
AnimatedVisibility(
|
||||||
|
isVisible
|
||||||
|
) {
|
||||||
|
|
||||||
|
Dialog(onDismiss) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
border = BorderStroke(1.dp, Color.Gray) // Gray
|
||||||
|
) {
|
||||||
|
Column(Modifier.padding(16.dp)) {
|
||||||
|
Text(
|
||||||
|
"Support Us",
|
||||||
|
style = SpotiFlyerTypography.h5,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = colorAccent,
|
||||||
|
modifier = Modifier
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.padding(vertical = 4.dp))
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.fillMaxWidth().clickable(
|
||||||
|
onClick = {
|
||||||
|
onDismiss()
|
||||||
|
methods.value.openPlatform("", "https://www.paypal.com/paypalme/shabinder")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.padding(vertical = 6.dp)
|
||||||
|
) {
|
||||||
|
Icon(PaypalLogo(), "Paypal Logo", tint = Color(0xFFCCCCCC))
|
||||||
|
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = "Paypal",
|
||||||
|
style = SpotiFlyerTypography.h6
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "International Donations (Outside India).",
|
||||||
|
style = SpotiFlyerTypography.subtitle2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(top = 6.dp)
|
||||||
|
.clickable(onClick = {
|
||||||
|
onDismiss()
|
||||||
|
methods.value.giveDonation()
|
||||||
|
}),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(RazorPay(), "Indian Rupee Logo", Modifier.size(32.dp), tint = Color(0xFFCCCCCC))
|
||||||
|
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = "RazorPay",
|
||||||
|
style = SpotiFlyerTypography.h6
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Indian Donations (UPI / PayTM / PhonePe / Cards).",
|
||||||
|
style = SpotiFlyerTypography.subtitle2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,8 +21,8 @@ plugins {
|
|||||||
kotlin("plugin.serialization")
|
kotlin("plugin.serialization")
|
||||||
}
|
}
|
||||||
|
|
||||||
val statelyVersion = "1.1.6"
|
val statelyVersion = "1.1.7"
|
||||||
val statelyIsoVersion = "1.1.6-a1"
|
val statelyIsoVersion = "1.1.7-a1"
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
@ -161,6 +161,9 @@ actual class Dir actual constructor(
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
null
|
null
|
||||||
|
} catch (e: OutOfMemoryError) {
|
||||||
|
e.printStackTrace()
|
||||||
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,10 +212,10 @@ class ForegroundService : Service(), CoroutineScope {
|
|||||||
is DownloadResult.Error -> {
|
is DownloadResult.Error -> {
|
||||||
launch {
|
launch {
|
||||||
logger.d(tag) { it.message }
|
logger.d(tag) { it.message }
|
||||||
logger.d(tag) { "${track.title} Requesting Download thru Android DM" }
|
/*logger.d(tag) { "${track.title} Requesting Download thru Android DM" }
|
||||||
downloadUsingDM(url, track.outputFilePath, track)
|
downloadUsingDM(url, track.outputFilePath, track)*/
|
||||||
removeFromNotification("Downloading ${track.title}")
|
removeFromNotification("Downloading ${track.title}")
|
||||||
downloaded++
|
failed++
|
||||||
}
|
}
|
||||||
updateNotification()
|
updateNotification()
|
||||||
sendTrackBroadcast(Status.FAILED.name,track)
|
sendTrackBroadcast(Status.FAILED.name,track)
|
||||||
@ -247,15 +247,16 @@ class ForegroundService : Service(), CoroutineScope {
|
|||||||
removeFromNotification("Processing ${track.title}")
|
removeFromNotification("Processing ${track.title}")
|
||||||
}
|
}
|
||||||
logger.d(tag) { "${track.title} Download Completed" }
|
logger.d(tag) { "${track.title} Download Completed" }
|
||||||
|
downloaded++
|
||||||
} catch (
|
} catch (
|
||||||
e: KotlinNullPointerException
|
e: Exception
|
||||||
) {
|
) {
|
||||||
// Try downloading using android DM
|
// Try downloading using android DM
|
||||||
logger.d(tag) { "${track.title} Download Failed! Error:Fetch!!!!" }
|
logger.d(tag) { "${track.title} Download Failed! Error:Fetch!!!!" }
|
||||||
logger.d(tag) { "${track.title} Requesting Download thru Android DM" }
|
failed++
|
||||||
downloadUsingDM(url, track.outputFilePath, track)
|
/*logger.d(tag) { "${track.title} Requesting Download thru Android DM" }
|
||||||
|
downloadUsingDM(url, track.outputFilePath, track)*/
|
||||||
}
|
}
|
||||||
downloaded++
|
|
||||||
removeFromNotification("Downloading ${track.title}")
|
removeFromNotification("Downloading ${track.title}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,7 +264,7 @@ class ForegroundService : Service(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If fetch Fails , Android Download Manager To RESCUE!!
|
* If Custom Downloader Fails , Android Download Manager To RESCUE!!
|
||||||
**/
|
**/
|
||||||
private fun downloadUsingDM(url: String, outputDir: String, track: TrackDetails) {
|
private fun downloadUsingDM(url: String, outputDir: String, track: TrackDetails) {
|
||||||
launch {
|
launch {
|
||||||
|
@ -61,9 +61,21 @@ compose.desktop {
|
|||||||
mainClass = "MainKt"
|
mainClass = "MainKt"
|
||||||
description = "Music Downloader for Spotify, Gaana, Youtube Music."
|
description = "Music Downloader for Spotify, Gaana, Youtube Music."
|
||||||
nativeDistributions {
|
nativeDistributions {
|
||||||
modules("java.sql", "java.security.jgss")
|
modules("java.sql", "java.security.jgss", "jdk.crypto.ec")
|
||||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
||||||
packageName = "SpotiFlyer"
|
packageName = "SpotiFlyer"
|
||||||
|
copyright = "© 2021 Shabinder. All rights reserved."
|
||||||
|
vendor = "Shabinder"
|
||||||
|
val iconsRoot = project.file("src/jvmMain/resources/drawable")
|
||||||
|
macOS {
|
||||||
|
iconFile.set(iconsRoot.resolve("spotiflyer.icns"))
|
||||||
|
}
|
||||||
|
windows {
|
||||||
|
iconFile.set(iconsRoot.resolve("spotiflyer.ico"))
|
||||||
|
}
|
||||||
|
linux {
|
||||||
|
iconFile.set(iconsRoot.resolve("spotiflyer.png"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,12 +14,14 @@
|
|||||||
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import androidx.compose.desktop.AppManager
|
||||||
import androidx.compose.desktop.DesktopMaterialTheme
|
import androidx.compose.desktop.DesktopMaterialTheme
|
||||||
import androidx.compose.desktop.Window
|
import androidx.compose.desktop.Window
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.IntSize
|
||||||
import com.arkivanov.decompose.ComponentContext
|
import com.arkivanov.decompose.ComponentContext
|
||||||
import com.arkivanov.decompose.extensions.compose.jetbrains.rememberRootComponent
|
import com.arkivanov.decompose.extensions.compose.jetbrains.rememberRootComponent
|
||||||
import com.arkivanov.mvikotlin.core.lifecycle.LifecycleRegistry
|
import com.arkivanov.mvikotlin.core.lifecycle.LifecycleRegistry
|
||||||
@ -31,7 +33,6 @@ import com.shabinder.common.di.FetchPlatformQueryResult
|
|||||||
import com.shabinder.common.di.initKoin
|
import com.shabinder.common.di.initKoin
|
||||||
import com.shabinder.common.di.isInternetAccessible
|
import com.shabinder.common.di.isInternetAccessible
|
||||||
import com.shabinder.common.models.Actions
|
import com.shabinder.common.models.Actions
|
||||||
import com.shabinder.common.models.AllPlatforms
|
|
||||||
import com.shabinder.common.models.PlatformActions
|
import com.shabinder.common.models.PlatformActions
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot
|
import com.shabinder.common.root.SpotiFlyerRoot
|
||||||
@ -41,8 +42,12 @@ import com.shabinder.common.uikit.SpotiFlyerShapes
|
|||||||
import com.shabinder.common.uikit.SpotiFlyerTypography
|
import com.shabinder.common.uikit.SpotiFlyerTypography
|
||||||
import com.shabinder.common.uikit.colorOffWhite
|
import com.shabinder.common.uikit.colorOffWhite
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import java.awt.Desktop
|
||||||
|
import java.net.URI
|
||||||
|
import javax.swing.JFileChooser
|
||||||
|
import javax.swing.JFileChooser.APPROVE_OPTION
|
||||||
|
import javax.swing.JFileChooser.CANCEL_OPTION
|
||||||
|
|
||||||
private val koin = initKoin(enableNetworkLogs = true).koin
|
private val koin = initKoin(enableNetworkLogs = true).koin
|
||||||
private lateinit var showToast: (String)->Unit
|
private lateinit var showToast: (String)->Unit
|
||||||
@ -52,7 +57,7 @@ fun main() {
|
|||||||
val lifecycle = LifecycleRegistry()
|
val lifecycle = LifecycleRegistry()
|
||||||
lifecycle.resume()
|
lifecycle.resume()
|
||||||
|
|
||||||
Window("SpotiFlyer") {
|
Window("SpotiFlyer",size = IntSize(450,800)) {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
color = Color.Black,
|
color = Color.Black,
|
||||||
@ -89,19 +94,39 @@ private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun setDownloadDirectoryAction() {
|
override fun setDownloadDirectoryAction() {
|
||||||
showToast("TODO: Still needs to be Implemented")
|
val fileChooser = JFileChooser().apply {
|
||||||
|
fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
|
||||||
|
}
|
||||||
|
when (fileChooser.showOpenDialog(AppManager.focusedWindow?.window)) {
|
||||||
|
APPROVE_OPTION -> {
|
||||||
|
val directory = fileChooser.selectedFile
|
||||||
|
if(directory.canWrite()){
|
||||||
|
directories.setDownloadDirectory(directory.absolutePath)
|
||||||
|
showPopUpMessage("Set New Download Directory:\n${directory.absolutePath}")
|
||||||
|
} else {
|
||||||
|
showPopUpMessage("Cant Write to Selected Directory!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
showPopUpMessage("No Directory Selected")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun queryActiveTracks() {}
|
override fun queryActiveTracks() {/**/}
|
||||||
|
|
||||||
override fun giveDonation() {
|
override fun giveDonation() {
|
||||||
|
openLink("https://razorpay.com/payment-button/pl_GnKuuDBdBu0ank/view/?utm_source=payment_button&utm_medium=button&utm_campaign=payment_button")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shareApp() {}
|
override fun shareApp() = openLink("https://github.com/Shabinder/SpotiFlyer")
|
||||||
|
|
||||||
override fun openPlatform(packageID: String, platformLink: String) {
|
override fun openPlatform(packageID: String, platformLink: String) = openLink(platformLink)
|
||||||
showToast("TODO: Still needs to be Implemented")
|
|
||||||
|
fun openLink(link:String) {
|
||||||
|
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||||
|
Desktop.getDesktop().browse(URI(link))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun writeMp3Tags(trackDetails: TrackDetails) {/*IMPLEMENTED*/}
|
override fun writeMp3Tags(trackDetails: TrackDetails) {/*IMPLEMENTED*/}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
<vector android:height="24dp" android:viewportHeight="456"
|
||||||
|
android:viewportWidth="456" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M61.179,282h-41.2c-6,0 -10.9,4.9 -10.9,10.9v152.2c0,6 4.9,10.9 10.9,10.9h41.2c6,0 10.9,-4.9 10.9,-10.9V292.9C72.079,286.9 67.179,282 61.179,282z"/>
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M443.179,294.4c-0.3,-0.4 -0.6,-0.8 -0.8,-1.2c-6.1,-6.8 -16.4,-7.7 -23.6,-2.1c-20,16.3 -49.2,39.8 -68.1,55.1c-16.7,13.3 -37.3,21 -58.7,21.8l-51.2,1.7c-9.4,0.3 -18.2,-4.5 -23,-12.6l-5.7,-9.7c-1.5,-2.5 -2.5,-5.3 -3.1,-8.2c-2.6,-13.9 6.5,-27.4 20.4,-30l52.9,-10c8.5,-1.7 14.3,-9.7 13.3,-18.3c-1,-8.2 -8,-14.3 -16.2,-14.4c-0.3,0 -0.7,0 -0.8,0c-0.4,0 -0.9,0 -1.3,0l-71.2,-2.9c-24.7,-0.9 -46,3.9 -71.2,16.1l-42.8,20.7v114l35.9,-6.6c0.1,-0.1 0.2,-0.1 0.3,-0.1c13.9,-2 23.1,-2.9 38.2,-2.2l107.5,5c33.7,1.4 66.8,-9.7 92.7,-31.3l74.4,-61.7C447.979,311.7 448.879,301.3 443.179,294.4z"/>
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M307.379,0c-61.2,0.1 -110.7,49.7 -110.8,110.8c0,0.1 0,0.1 0,0.1c0,61.2 49.7,110.8 110.9,110.8s110.8,-49.7 110.8,-110.9S368.579,0 307.379,0zM333.079,80h13.4c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-13.4c-2,7.8 -6,14.9 -11.7,20.6c-7.5,7.5 -17.5,11.9 -28.1,12.5l37.7,35.7c4,3.8 4.2,10.1 0.4,14.1s-10.1,4.2 -14.1,0.4l-55.9,-52.9c-1.9,-1.9 -3.1,-4.5 -3.1,-7.2c-0.1,-5.6 4.4,-10.1 10,-10.2h22.4c6.2,0.1 12.2,-2.3 16.7,-6.7c1.8,-1.9 3.3,-4 4.6,-6.3h-43.7c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h43.7c-3.7,-8 -11.9,-14 -21.3,-14h-22.4c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h78.2c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-19.2C330.079,70.3 331.979,75 333.079,80z"/>
|
||||||
|
</vector>
|
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:viewportHeight="435.505"
|
||||||
|
android:viewportWidth="435.505" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M403.496,101.917c-4.104,-5.073 -8.877,-9.705 -14.166,-13.839c0.707,13.117 -0.508,27.092 -3.668,41.884c-8.627,40.413 -29.256,74.754 -59.656,99.304c-30.375,24.533 -68.305,37.502 -109.686,37.502h-60.344l-19.533,91.512c-3.836,17.959 -19.943,30.99 -38.303,30.99H70.938l-4.898,22.484c-1.258,5.79 0.17,11.839 3.887,16.453c3.715,4.614 9.324,7.298 15.25,7.298h66.498c9.24,0 17.225,-6.459 19.152,-15.495L193.667,313h76.188c36.854,0 70.527,-11.464 97.384,-33.152c26.869,-21.697 45.129,-52.186 52.807,-88.162C427.822,155.309 422.253,125.106 403.496,101.917z"/>
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M117.292,354.191l22.84,-107.008h76.188c36.852,0 70.527,-11.465 97.383,-33.154c26.867,-21.697 45.129,-52.186 52.809,-88.161c7.773,-36.378 2.207,-66.58 -16.553,-89.769C331.952,13.832 301.17,0 269.633,0H103.639c-9.209,0 -17.174,6.417 -19.135,15.414L12.505,345.938c-1.26,5.789 0.168,11.838 3.887,16.453c3.713,4.613 9.32,7.296 15.248,7.296h66.5C107.38,369.687 115.36,363.229 117.292,354.191zM178.235,75.291h52.229c12.287,0 23.274,5.149 30.145,14.129c7.297,9.539 9.431,22.729 5.853,36.188c-0.047,0.171 -0.088,0.342 -0.131,0.516c-6.57,27.73 -33.892,50.291 -60.898,50.291h-50.05L178.235,75.291z"/>
|
||||||
|
</vector>
|
BIN
desktop/src/jvmMain/resources/drawable/spotiflyer.icns
Normal file
BIN
desktop/src/jvmMain/resources/drawable/spotiflyer.icns
Normal file
Binary file not shown.
BIN
desktop/src/jvmMain/resources/drawable/spotiflyer.ico
Normal file
BIN
desktop/src/jvmMain/resources/drawable/spotiflyer.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
BIN
desktop/src/jvmMain/resources/drawable/spotiflyer.png
Normal file
BIN
desktop/src/jvmMain/resources/drawable/spotiflyer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
Loading…
Reference in New Issue
Block a user