Scrollbars and various Bug Fixes

This commit is contained in:
shabinder 2021-05-08 20:42:09 +05:30
parent d90469d0fd
commit 603314fcd2
20 changed files with 492 additions and 190 deletions

View File

@ -48,6 +48,7 @@
android:usesCleartextTraffic="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:icon="@mipmap/ic_launcher"
android:largeHeap="true"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:configChanges="orientation|screenSize"

View File

@ -236,7 +236,13 @@ class MainActivity : ComponentActivity(), PaymentResultListener {
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() {
val sendIntent: Intent = Intent().apply {

View File

@ -18,7 +18,7 @@
object Versions {
// App's Version (To be bumped at each update)
const val versionName = "2.3.0"
const val versionName = "2.3.5"
// Kotlin
const val kotlinVersion = "1.4.32"
@ -45,7 +45,7 @@ object Versions {
const val slf4j = "1.7.30"
// Android
const val versionCode = 17
const val versionCode = 18
const val minSdkVersion = 21
const val compileSdkVersion = 29
const val targetSdkVersion = 29
@ -142,7 +142,7 @@ object Extras {
const val jaudioTagger = "com.github.Shabinder:JAudioTagger-Android:1.0"
const val kermit = "co.touchlab:kermit:${Versions.kermit}"
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 appUpdator = "com.github.amitbd1508:AppUpdater:4.1.0"
}

View File

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

View File

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

View File

@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
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.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.ExtendedFloatingActionButton
import androidx.compose.material.Icon
@ -77,6 +79,9 @@ fun SpotiFlyerListContent(
Text("Loading..", style = appNameStyle, color = colorPrimary)
}
} else {
val listState = rememberLazyListState()
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp),
content = {
@ -91,12 +96,23 @@ fun SpotiFlyerListContent(
)
}
},
state = listState,
modifier = Modifier.fillMaxSize(),
)
DownloadAllButton(
onClick = { component.onDownloadAllClicked(model.trackList) },
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
)
)
}
}
}

View File

@ -23,9 +23,11 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
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.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
@ -125,7 +128,7 @@ fun HomeTabBar(
TabRow(
selectedTabIndex = selectedIndex,
indicator = indicator,
indicator = indicator as @Composable (List<TabPosition>) -> Unit,
modifier = modifier,
) {
categories.forEachIndexed { index, category ->
@ -219,160 +222,169 @@ fun SearchPanel(
@Composable
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(
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
Column(modifier.fillMaxSize().padding(8.dp).verticalScroll(stateVertical)) {
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") }
)
)
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
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") }
)
)
}
}
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
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") }
)
)
Text(
text = "Share this app with your friends and family.",
style = SpotiFlyerTypography.subtitle2
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) }
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)
}
} else {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp),
content = {
items(it.distinctBy { record -> record.coverUrl }) { record ->
DownloadRecordItem(
item = record,
loadImage,
onItemClicked
)
}
},
modifier = Modifier.padding(top = 8.dp).fillMaxSize()
)
Box {
val listState = rememberLazyListState()
val itemList = it.distinctBy { record -> record.coverUrl }
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp),
content = {
items(itemList) { record ->
DownloadRecordItem(
item = record,
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
)
)
}
}
}
}

View File

@ -67,14 +67,6 @@ actual fun DownloadImageTick() {
)
}
@Composable
actual fun DonationDialog(
isVisible:Boolean,
onDismiss:()->Unit
){
}
actual fun montserratFont() = FontFamily(
Font("font/montserrat_light.ttf", FontWeight.Light),
Font("font/montserrat_regular.ttf", FontWeight.Normal),

View File

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

View File

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

View File

@ -21,8 +21,8 @@ plugins {
kotlin("plugin.serialization")
}
val statelyVersion = "1.1.6"
val statelyIsoVersion = "1.1.6-a1"
val statelyVersion = "1.1.7"
val statelyIsoVersion = "1.1.7-a1"
kotlin {
sourceSets {

View File

@ -161,6 +161,9 @@ actual class Dir actual constructor(
} catch (e: Exception) {
e.printStackTrace()
null
} catch (e: OutOfMemoryError) {
e.printStackTrace()
null
}
}

View File

@ -212,10 +212,10 @@ class ForegroundService : Service(), CoroutineScope {
is DownloadResult.Error -> {
launch {
logger.d(tag) { it.message }
logger.d(tag) { "${track.title} Requesting Download thru Android DM" }
downloadUsingDM(url, track.outputFilePath, track)
/*logger.d(tag) { "${track.title} Requesting Download thru Android DM" }
downloadUsingDM(url, track.outputFilePath, track)*/
removeFromNotification("Downloading ${track.title}")
downloaded++
failed++
}
updateNotification()
sendTrackBroadcast(Status.FAILED.name,track)
@ -247,15 +247,16 @@ class ForegroundService : Service(), CoroutineScope {
removeFromNotification("Processing ${track.title}")
}
logger.d(tag) { "${track.title} Download Completed" }
downloaded++
} catch (
e: KotlinNullPointerException
e: Exception
) {
// Try downloading using android DM
logger.d(tag) { "${track.title} Download Failed! Error:Fetch!!!!" }
logger.d(tag) { "${track.title} Requesting Download thru Android DM" }
downloadUsingDM(url, track.outputFilePath, track)
failed++
/*logger.d(tag) { "${track.title} Requesting Download thru Android DM" }
downloadUsingDM(url, track.outputFilePath, track)*/
}
downloaded++
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) {
launch {

View File

@ -61,9 +61,21 @@ compose.desktop {
mainClass = "MainKt"
description = "Music Downloader for Spotify, Gaana, Youtube Music."
nativeDistributions {
modules("java.sql", "java.security.jgss")
modules("java.sql", "java.security.jgss", "jdk.crypto.ec")
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
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"))
}
}
}
}

View File

@ -14,12 +14,14 @@
* * 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.Window
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Surface
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.IntSize
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetbrains.rememberRootComponent
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.isInternetAccessible
import com.shabinder.common.models.Actions
import com.shabinder.common.models.AllPlatforms
import com.shabinder.common.models.PlatformActions
import com.shabinder.common.models.TrackDetails
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.colorOffWhite
import com.shabinder.database.Database
import kotlinx.coroutines.Dispatchers
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 lateinit var showToast: (String)->Unit
@ -52,7 +57,7 @@ fun main() {
val lifecycle = LifecycleRegistry()
lifecycle.resume()
Window("SpotiFlyer") {
Window("SpotiFlyer",size = IntSize(450,800)) {
Surface(
modifier = Modifier.fillMaxSize(),
color = Color.Black,
@ -89,19 +94,39 @@ private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
}
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() {
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) {
showToast("TODO: Still needs to be Implemented")
override fun openPlatform(packageID: String, platformLink: String) = openLink(platformLink)
fun openLink(link:String) {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
Desktop.getDesktop().browse(URI(link))
}
}
override fun writeMp3Tags(trackDetails: TrackDetails) {/*IMPLEMENTED*/}

View File

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

View File

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

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB