diff --git a/android/src/main/java/com/shabinder/spotiflyer/MainActivity.kt b/android/src/main/java/com/shabinder/spotiflyer/MainActivity.kt
index 68421994..1cfc2fbe 100644
--- a/android/src/main/java/com/shabinder/spotiflyer/MainActivity.kt
+++ b/android/src/main/java/com/shabinder/spotiflyer/MainActivity.kt
@@ -58,7 +58,6 @@ import com.shabinder.common.models.TrackDetails
import com.shabinder.common.root.SpotiFlyerRoot
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
import com.shabinder.common.uikit.*
-import com.shabinder.database.Database
import com.shabinder.spotiflyer.utils.*
import com.tonyodev.fetch2.Status
import kotlinx.coroutines.*
diff --git a/build.gradle.kts b/build.gradle.kts
index f5b8cd55..305b7e55 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -16,6 +16,8 @@
plugins {
`kotlin-dsl`
+ id("org.jlleitschuh.gradle.ktlint")
+ id("org.jlleitschuh.gradle.ktlint-idea")
}
allprojects {
@@ -27,7 +29,7 @@ allprojects {
maven(url = "https://dl.bintray.com/ekito/koin")
maven(url = "https://kotlin.bintray.com/kotlinx/")
maven(url = "https://dl.bintray.com/icerockdev/moko")
- //maven(url = "https://kotlin.bintray.com/kotlin-js-wrappers/")
+ // maven(url = "https://kotlin.bintray.com/kotlin-js-wrappers/")
maven(url = "https://dl.bintray.com/kotlin/kotlin-js-wrappers")
maven(url = "https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index 532dc1a3..caf506b6 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -16,7 +16,6 @@
plugins {
`kotlin-dsl`
- //`kotlin-dsl-precompiled-script-plugins`
}
group = "com.shabinder"
@@ -28,6 +27,7 @@ repositories {
mavenCentral()
google()
maven(url = "https://jitpack.io")
+ maven(url = "https://plugins.gradle.org/m2/")
maven(url = "https://dl.bintray.com/kotlin/kotlin-js-wrappers")
maven(url = "https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
@@ -37,6 +37,7 @@ dependencies {
implementation("com.google.gms:google-services:4.3.5")
implementation("com.google.firebase:perf-plugin:1.3.5")
implementation("com.google.firebase:firebase-crashlytics-gradle:2.5.1")
+ implementation("org.jlleitschuh.gradle:ktlint-gradle:${Versions.ktLint}")
implementation(JetBrains.Compose.gradlePlugin)
implementation(JetBrains.Kotlin.gradlePlugin)
implementation(JetBrains.Kotlin.serialization)
@@ -50,4 +51,4 @@ kotlinDslPluginOptions {
kotlin {
// Add Deps to compilation, so it will become available in main project
sourceSets.getByName("main").kotlin.srcDir("buildSrc/src/main/kotlin")
-}
\ No newline at end of file
+}
diff --git a/buildSrc/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/buildSrc/src/main/kotlin/Versions.kt
index af9f2e27..be862598 100644
--- a/buildSrc/buildSrc/src/main/kotlin/Versions.kt
+++ b/buildSrc/buildSrc/src/main/kotlin/Versions.kt
@@ -21,26 +21,29 @@ object Versions {
const val kotlinVersion = "1.4.31"
const val coroutinesVersion = "1.4.2"
- //const val compose = "1.0.0-alpha12"
const val coilVersion = "0.4.1"
- //DI
+
+ // Code Formatting
+ const val ktLint = "10.0.0"
+
+ // DI
const val koin = "3.0.1-beta-1"
- //Logger
+ // Logger
const val kermit = "0.1.8"
- //Internet
+ // Internet
const val ktor = "1.5.2"
const val kotlinxSerialization = "1.1.0-RC"
- //Database
+ // Database
const val sqlDelight = "1.4.4"
const val sqliteJdbcDriver = "3.30.1"
const val slf4j = "1.7.30"
- //Android
+ // Android
const val versionCode = 15
const val minSdkVersion = 24
const val compileSdkVersion = 29
@@ -53,7 +56,7 @@ object Koin {
val android = "io.insert-koin:koin-android:${Versions.koin}"
val compose = "io.insert-koin:koin-androidx-compose:${Versions.koin}"
}
-object Androidx{
+object Androidx {
const val androidxActivity = "androidx.activity:activity-compose:1.3.0-alpha02"
const val core = "androidx.core:core-ktx:1.3.2"
const val palette = "androidx.palette:palette-ktx:1.0.0"
@@ -162,4 +165,4 @@ object SqlDelight {
const val nativeDriver = "com.squareup.sqldelight:native-driver:${Versions.sqlDelight}"
val nativeDriverMacos = "com.squareup.sqldelight:native-driver-macosx64:${Versions.sqlDelight}"
val jdbcDriver = "org.xerial:sqlite-jdbc:${Versions.sqliteJdbcDriver}"
-}
\ No newline at end of file
+}
diff --git a/buildSrc/src/main/kotlin/android-setup.gradle.kts b/buildSrc/src/main/kotlin/android-setup.gradle.kts
index 1766f295..e932119b 100644
--- a/buildSrc/src/main/kotlin/android-setup.gradle.kts
+++ b/buildSrc/src/main/kotlin/android-setup.gradle.kts
@@ -16,6 +16,7 @@
plugins {
id("com.android.library")
+ id("ktlint-setup")
}
android {
@@ -43,5 +44,4 @@ android {
res.srcDirs("src/androidMain/res")
}
}
-
}
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/NetworkResponse.kt b/buildSrc/src/main/kotlin/ktlint-setup.gradle.kts
similarity index 50%
rename from common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/NetworkResponse.kt
rename to buildSrc/src/main/kotlin/ktlint-setup.gradle.kts
index 7c082001..972eee6b 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/NetworkResponse.kt
+++ b/buildSrc/src/main/kotlin/ktlint-setup.gradle.kts
@@ -14,9 +14,31 @@
* * along with this program. If not, see .
*/
-package com.shabinder.common.di
+plugins {
+ id("org.jlleitschuh.gradle.ktlint")
+ id("org.jlleitschuh.gradle.ktlint-idea")
+}
-sealed class NetworkResponse {
- data class Success(val value:T):NetworkResponse()
- data class Error(val message:String):NetworkResponse()
+subprojects {
+ apply(plugin = "org.jlleitschuh.gradle.ktlint")
+ apply(plugin = "org.jlleitschuh.gradle.ktlint-idea")
+ repositories {
+ // Required to download KtLint
+ mavenCentral()
+ }
+ ktlint {
+ android.set(true)
+ outputToConsole.set(true)
+ ignoreFailures.set(true)
+ coloredOutput.set(true)
+ verbose.set(true)
+ filter {
+ exclude("**/generated/**")
+ exclude("**/build/**")
+ }
+ }
+ // Optionally configure plugin
+ /*configure {
+ debug.set(true)
+ }*/
}
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/multiplatform-compose-setup.gradle.kts b/buildSrc/src/main/kotlin/multiplatform-compose-setup.gradle.kts
index d050dc06..19232ab7 100644
--- a/buildSrc/src/main/kotlin/multiplatform-compose-setup.gradle.kts
+++ b/buildSrc/src/main/kotlin/multiplatform-compose-setup.gradle.kts
@@ -18,6 +18,7 @@ plugins {
id("com.android.library")
id("kotlin-multiplatform")
id("org.jetbrains.compose")
+ id("ktlint-setup")
}
kotlin {
diff --git a/buildSrc/src/main/kotlin/multiplatform-setup-test.gradle.kts b/buildSrc/src/main/kotlin/multiplatform-setup-test.gradle.kts
index 3ceb2e98..21df8da8 100644
--- a/buildSrc/src/main/kotlin/multiplatform-setup-test.gradle.kts
+++ b/buildSrc/src/main/kotlin/multiplatform-setup-test.gradle.kts
@@ -17,15 +17,16 @@
plugins {
id("com.android.library")
id("kotlin-multiplatform")
+ id("ktlint-setup")
}
kotlin {
jvm("desktop")
android()
- //ios()
+ // ios()
js() {
browser()
- //nodejs()
+ // nodejs()
binaries.executable()
}
sourceSets {
@@ -47,9 +48,7 @@ kotlin {
}
}
named("jsTest") {
- dependencies {
-
- }
+ dependencies {}
}
}
diff --git a/buildSrc/src/main/kotlin/multiplatform-setup.gradle.kts b/buildSrc/src/main/kotlin/multiplatform-setup.gradle.kts
index a216a575..2e7d5c85 100644
--- a/buildSrc/src/main/kotlin/multiplatform-setup.gradle.kts
+++ b/buildSrc/src/main/kotlin/multiplatform-setup.gradle.kts
@@ -14,17 +14,11 @@
* * along with this program. If not, see .
*/
-import gradle.kotlin.dsl.accessors._2e23d8fadf0ed92ae13e19db3d83f86d.compose
-import gradle.kotlin.dsl.accessors._2e23d8fadf0ed92ae13e19db3d83f86d.kotlin
-import gradle.kotlin.dsl.accessors._2e23d8fadf0ed92ae13e19db3d83f86d.sourceSets
-import org.gradle.kotlin.dsl.withType
-import org.jetbrains.compose.compose
-
plugins {
-// id("com.android.library")
id("android-setup")
id("kotlin-multiplatform")
id("org.jetbrains.compose")
+ id("ktlint-setup")
}
kotlin {
@@ -32,14 +26,12 @@ kotlin {
android()
js() {
browser()
- //nodejs()
+ // nodejs()
binaries.executable()
}
sourceSets {
named("commonMain") {
- dependencies {
-
- }
+ dependencies {}
}
named("androidMain") {
diff --git a/common/compose/build.gradle.kts b/common/compose/build.gradle.kts
index 48dac2a5..3de1f191 100644
--- a/common/compose/build.gradle.kts
+++ b/common/compose/build.gradle.kts
@@ -33,7 +33,7 @@ kotlin {
implementation(project(":common:database"))
implementation(project(":common:data-models"))
implementation(project(":common:dependency-injection"))
- //DECOMPOSE
+ // DECOMPOSE
implementation(Decompose.decompose)
implementation(Decompose.extensionsCompose)
}
diff --git a/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt b/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt
index 55e6ddcf..f459ab12 100644
--- a/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt
+++ b/common/compose/src/androidMain/kotlin/com/shabinder/common/uikit/AndroidImages.kt
@@ -21,7 +21,13 @@ package com.shabinder.common.uikit
import androidx.annotation.DrawableRes
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.Image
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.vector.ImageVector
@@ -39,21 +45,21 @@ import kotlinx.coroutines.withContext
@Composable
actual fun ImageLoad(
- link:String,
- loader:suspend (String) -> Picture,
+ link: String,
+ loader: suspend (String) -> Picture,
desc: String,
- modifier:Modifier,
- //placeholder: ImageVector
+ modifier: Modifier,
+ // placeholder: ImageVector
) {
var pic by remember(link) { mutableStateOf(null) }
- LaunchedEffect(link){
+ LaunchedEffect(link) {
withContext(dispatcherIO) {
pic = loader(link).image
}
}
- Crossfade(pic){
- if(it == null) Image(PlaceHolderImage(), desc, modifier,contentScale = ContentScale.Crop) else Image(it, desc, modifier,contentScale = ContentScale.Crop)
+ Crossfade(pic) {
+ if (it == null) Image(PlaceHolderImage(), desc, modifier, contentScale = ContentScale.Crop) else Image(it, desc, modifier, contentScale = ContentScale.Crop)
}
}
@@ -68,9 +74,8 @@ actual fun pristineFont() = FontFamily(
Font(R.font.pristine_script, FontWeight.Bold)
)
-
@Composable
-actual fun DownloadImageTick(){
+actual fun DownloadImageTick() {
Image(
painterResource(R.drawable.ic_tick),
"Download Done"
@@ -78,7 +83,7 @@ actual fun DownloadImageTick(){
}
@Composable
-actual fun DownloadImageError(){
+actual fun DownloadImageError() {
Image(
painterResource(R.drawable.ic_error),
"Error! Cant Download this track"
@@ -86,7 +91,7 @@ actual fun DownloadImageError(){
}
@Composable
-actual fun DownloadImageArrow(modifier: Modifier){
+actual fun DownloadImageArrow(modifier: Modifier) {
Image(
painterResource(R.drawable.ic_arrow),
"Start Download",
@@ -125,16 +130,16 @@ actual fun YoutubeMusicLogo() = vectorResource(R.drawable.ic_youtube_music_logo)
actual fun GithubLogo() = vectorResource(R.drawable.ic_github)
@Composable
-fun vectorResource(@DrawableRes id: Int) = ImageVector.Companion.vectorResource(id)
+fun vectorResource(@DrawableRes id: Int) = ImageVector.Companion.vectorResource(id)
@Composable
actual fun Toast(
text: String,
visibility: MutableState,
duration: ToastDuration
-){
- //We Have Android's Implementation of Toast so its just Empty
+) {
+ // We Have Android's Implementation of Toast so its just Empty
+}
+actual fun showPopUpMessage(text: String) {
+ android.widget.Toast.makeText(appContext, text, android.widget.Toast.LENGTH_SHORT).show()
}
-actual fun showPopUpMessage(text: String){
- android.widget.Toast.makeText(appContext,text, android.widget.Toast.LENGTH_SHORT).show()
-}
\ No newline at end of file
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt
index c71d658a..f4f66bbe 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/ExpectImages.kt
@@ -17,55 +17,55 @@
@file:Suppress("FunctionName")
package com.shabinder.common.uikit
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import com.shabinder.common.di.Picture
@Composable
expect fun ImageLoad(
- link:String,
- loader:suspend (String) ->Picture,
+ link: String,
+ loader: suspend (String) -> Picture,
desc: String = "Album Art",
- modifier:Modifier = Modifier,
- //placeholder:ImageVector = PlaceHolderImage()
+ modifier: Modifier = Modifier,
+ // placeholder:ImageVector = PlaceHolderImage()
)
@Composable
expect fun DownloadImageTick()
@Composable
-expect fun DownloadAllImage():ImageVector
+expect fun DownloadAllImage(): ImageVector
@Composable
-expect fun ShareImage():ImageVector
+expect fun ShareImage(): ImageVector
@Composable
-expect fun PlaceHolderImage():ImageVector
+expect fun PlaceHolderImage(): ImageVector
@Composable
-expect fun SpotiFlyerLogo():ImageVector
+expect fun SpotiFlyerLogo(): ImageVector
@Composable
-expect fun SpotifyLogo():ImageVector
+expect fun SpotifyLogo(): ImageVector
@Composable
-expect fun YoutubeLogo():ImageVector
+expect fun YoutubeLogo(): ImageVector
@Composable
-expect fun GaanaLogo():ImageVector
+expect fun GaanaLogo(): ImageVector
@Composable
-expect fun YoutubeMusicLogo():ImageVector
+expect fun YoutubeMusicLogo(): ImageVector
@Composable
-expect fun GithubLogo():ImageVector
+expect fun GithubLogo(): ImageVector
@Composable
-expect fun HeartIcon():ImageVector
+expect fun HeartIcon(): ImageVector
@Composable
expect fun DownloadImageError()
@Composable
-expect fun DownloadImageArrow(modifier: Modifier)
\ No newline at end of file
+expect fun DownloadImageArrow(modifier: Modifier)
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Shape.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Shape.kt
index 3bfc97fa..d37cbc51 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Shape.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Shape.kt
@@ -21,7 +21,7 @@ import androidx.compose.material.Shapes
import androidx.compose.ui.unit.dp
val SpotiFlyerShapes = Shapes(
- small = RoundedCornerShape(percent = 50),
- medium = RoundedCornerShape(size = 8.dp),
- large = RoundedCornerShape(size = 0.dp)
-)
\ No newline at end of file
+ small = RoundedCornerShape(percent = 50),
+ medium = RoundedCornerShape(size = 8.dp),
+ large = RoundedCornerShape(size = 0.dp)
+)
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerListUi.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerListUi.kt
index 004b06a8..42e5474d 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerListUi.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerListUi.kt
@@ -17,16 +17,30 @@
package com.shabinder.common.uikit
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
+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.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+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.material.*
-import androidx.compose.runtime.*
+import androidx.compose.material.CircularProgressIndicator
+import androidx.compose.material.ExtendedFloatingActionButton
+import androidx.compose.material.Icon
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -35,7 +49,6 @@ import com.shabinder.common.di.Picture
import com.shabinder.common.list.SpotiFlyerList
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails
-import kotlinx.coroutines.CoroutineScope
@Composable
fun SpotiFlyerListContent(
@@ -44,23 +57,21 @@ fun SpotiFlyerListContent(
) {
val model by component.models.collectAsState(SpotiFlyerList.State())
- val coroutineScope = rememberCoroutineScope()
-
Box(modifier = modifier.fillMaxSize()) {
- //TODO Better Null Handling
+ // TODO Better Null Handling
val result = model.queryResult
- if(result == null){
- Column(Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {
+ if (result == null) {
+ Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
CircularProgressIndicator()
Spacer(modifier.padding(8.dp))
- Text("Loading..",style = appNameStyle,color = colorPrimary)
+ Text("Loading..", style = appNameStyle, color = colorPrimary)
}
- }else{
+ } else {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp),
content = {
item {
- CoverImage(result.title, result.coverUrl, coroutineScope,component::loadImage)
+ CoverImage(result.title, result.coverUrl, component::loadImage)
}
itemsIndexed(model.trackList) { index, item ->
TrackCard(
@@ -73,7 +84,7 @@ fun SpotiFlyerListContent(
modifier = Modifier.fillMaxSize(),
)
DownloadAllButton(
- onClick = {component.onDownloadAllClicked(model.trackList)},
+ onClick = { component.onDownloadAllClicked(model.trackList) },
modifier = Modifier.padding(bottom = 24.dp).align(Alignment.BottomCenter)
)
}
@@ -83,10 +94,10 @@ fun SpotiFlyerListContent(
@Composable
fun TrackCard(
track: TrackDetails,
- downloadTrack:()->Unit,
- loadImage:suspend (String)-> Picture
+ downloadTrack: () -> Unit,
+ loadImage: suspend (String) -> Picture
) {
- Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp)) {
+ Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp)) {
ImageLoad(
track.albumArtURL,
loadImage,
@@ -96,18 +107,18 @@ fun TrackCard(
.height(70.dp)
.clip(MaterialTheme.shapes.medium)
)
- Column(modifier = Modifier.padding(horizontal = 8.dp).height(60.dp).weight(1f),verticalArrangement = Arrangement.SpaceEvenly) {
- Text(track.title,maxLines = 1,overflow = TextOverflow.Ellipsis,style = SpotiFlyerTypography.h6,color = colorAccent)
+ Column(modifier = Modifier.padding(horizontal = 8.dp).height(60.dp).weight(1f), verticalArrangement = Arrangement.SpaceEvenly) {
+ Text(track.title, maxLines = 1, overflow = TextOverflow.Ellipsis, style = SpotiFlyerTypography.h6, color = colorAccent)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.Bottom,
modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize()
- ){
- Text("${track.artists.firstOrNull()}...",fontSize = 12.sp,maxLines = 1)
- Text("${track.durationSec/60} min, ${track.durationSec%60} sec",fontSize = 12.sp,maxLines = 1,overflow = TextOverflow.Ellipsis)
+ ) {
+ Text("${track.artists.firstOrNull()}...", fontSize = 12.sp, maxLines = 1)
+ Text("${track.durationSec / 60} min, ${track.durationSec % 60} sec", fontSize = 12.sp, maxLines = 1, overflow = TextOverflow.Ellipsis)
}
}
- when(track.downloaded){
+ when (track.downloaded) {
is DownloadStatus.Downloaded -> {
DownloadImageTick()
}
@@ -118,15 +129,19 @@ fun TrackCard(
DownloadImageError()
}
is DownloadStatus.Downloading -> {
- CircularProgressIndicator(progress = (track.downloaded as DownloadStatus.Downloading).progress.toFloat()/100f)
+ CircularProgressIndicator(progress = (track.downloaded as DownloadStatus.Downloading).progress.toFloat() / 100f)
}
is DownloadStatus.Converting -> {
- CircularProgressIndicator(progress = 100f,color = colorAccent)
+ CircularProgressIndicator(progress = 100f, color = colorAccent)
}
is DownloadStatus.NotDownloaded -> {
- DownloadImageArrow(Modifier.clickable(onClick = {
- downloadTrack()
- }))
+ DownloadImageArrow(
+ Modifier.clickable(
+ onClick = {
+ downloadTrack()
+ }
+ )
+ )
}
}
}
@@ -136,7 +151,6 @@ fun TrackCard(
fun CoverImage(
title: String,
coverURL: String,
- scope: CoroutineScope,
loadImage: suspend (String) -> Picture,
modifier: Modifier = Modifier,
) {
@@ -160,7 +174,6 @@ fun CoverImage(
maxLines = 2,
textAlign = TextAlign.Center,
overflow = TextOverflow.Ellipsis,
- //color = colorAccent,
)
}
/*scope.launch {
@@ -173,8 +186,8 @@ fun DownloadAllButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
ExtendedFloatingActionButton(
text = { Text("Download All") },
onClick = onClick,
- icon = { Icon(imageVector = DownloadAllImage(),"Download All Button",tint = Color(0xFF000000)) },
+ icon = { Icon(imageVector = DownloadAllImage(), "Download All Button", tint = Color(0xFF000000)) },
backgroundColor = colorAccent,
modifier = modifier
)
-}
\ No newline at end of file
+}
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerMainUi.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerMainUi.kt
index 2936511f..c76d32af 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerMainUi.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerMainUi.kt
@@ -17,26 +17,54 @@
package com.shabinder.common.uikit
import androidx.compose.animation.Crossfade
-import androidx.compose.foundation.*
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Image
+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.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.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+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.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
-import androidx.compose.material.*
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Card
+import androidx.compose.material.Icon
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.OutlinedButton
+import androidx.compose.material.Tab
+import androidx.compose.material.TabPosition
+import androidx.compose.material.TabRow
import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
+import androidx.compose.material.Text
+import androidx.compose.material.TextField
import androidx.compose.material.TextFieldDefaults.textFieldColors
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.*
-import androidx.compose.runtime.*
+import androidx.compose.material.icons.rounded.CardGiftcard
+import androidx.compose.material.icons.rounded.Edit
+import androidx.compose.material.icons.rounded.Flag
+import androidx.compose.material.icons.rounded.Share
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
@@ -53,7 +81,7 @@ import com.shabinder.common.main.SpotiFlyerMain.HomeCategory
import com.shabinder.common.models.DownloadRecord
@Composable
-fun SpotiFlyerMainContent(component: SpotiFlyerMain){
+fun SpotiFlyerMainContent(component: SpotiFlyerMain) {
val model by component.models.collectAsState(SpotiFlyerMain.State())
Column {
@@ -69,7 +97,7 @@ fun SpotiFlyerMainContent(component: SpotiFlyerMain){
component::selectCategory
)
- when(model.selectedCategory){
+ when (model.selectedCategory) {
HomeCategory.About -> AboutColumn()
HomeCategory.History -> HistoryColumn(
model.records.sortedByDescending { it.id },
@@ -87,7 +115,7 @@ fun HomeTabBar(
selectCategory: (HomeCategory) -> Unit,
modifier: Modifier = Modifier
) {
- val selectedIndex =categories.indexOfFirst { it == selectedCategory }
+ val selectedIndex = categories.indexOfFirst { it == selectedCategory }
val indicator = @Composable { tabPositions: List ->
HomeCategoryTabIndicator(
Modifier.tabIndicatorOffset(tabPositions[selectedIndex])
@@ -99,57 +127,62 @@ fun HomeTabBar(
indicator = indicator,
modifier = modifier,
) {
- categories.forEachIndexed { index, category ->
- Tab(
- selected = index == selectedIndex,
- onClick = { selectCategory(category) },
- text = {
- Text(
- text = when (category) {
- HomeCategory.About -> "About"
- HomeCategory.History -> "History"
- },
- style = MaterialTheme.typography.body2
- )
- },
- icon = {
- when (category) {
- HomeCategory.About -> Icon(Icons.Outlined.Info,"Info Tab")
- HomeCategory.History -> Icon(Icons.Outlined.History,"History Tab")
- }
+ categories.forEachIndexed { index, category ->
+ Tab(
+ selected = index == selectedIndex,
+ onClick = { selectCategory(category) },
+ text = {
+ Text(
+ text = when (category) {
+ HomeCategory.About -> "About"
+ HomeCategory.History -> "History"
+ },
+ style = MaterialTheme.typography.body2
+ )
+ },
+ icon = {
+ when (category) {
+ HomeCategory.About -> Icon(Icons.Outlined.Info, "Info Tab")
+ HomeCategory.History -> Icon(Icons.Outlined.History, "History Tab")
}
- )
- }
+ }
+ )
}
+ }
}
@Composable
fun SearchPanel(
- link:String,
- updateLink:(String) -> Unit,
- onSearch:(String) -> Unit,
+ link: String,
+ updateLink: (String) -> Unit,
+ onSearch: (String) -> Unit,
modifier: Modifier = Modifier
-){
+) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.padding(top = 16.dp)
- ){
+ ) {
TextField(
value = link,
- onValueChange = updateLink ,
+ onValueChange = updateLink,
leadingIcon = {
- Icon(Icons.Rounded.Edit,"Link Text Box",tint = Color.LightGray)
+ Icon(Icons.Rounded.Edit, "Link Text Box", tint = Color.LightGray)
},
- label = { Text(text = "Paste Link Here...",color = Color.LightGray) },
+ label = { Text(text = "Paste Link Here...", color = Color.LightGray) },
singleLine = true,
- textStyle = TextStyle.Default.merge(TextStyle(fontSize = 18.sp,color = Color.White)),
+ textStyle = TextStyle.Default.merge(TextStyle(fontSize = 18.sp, color = Color.White)),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri),
modifier = modifier.padding(12.dp).fillMaxWidth()
.border(
- BorderStroke(2.dp, Brush.horizontalGradient(listOf(
- colorPrimary,
- colorAccent
- ))),
+ BorderStroke(
+ 2.dp,
+ Brush.horizontalGradient(
+ listOf(
+ colorPrimary,
+ colorAccent
+ )
+ )
+ ),
RoundedCornerShape(30.dp)
),
shape = RoundedCornerShape(size = 30.dp),
@@ -162,29 +195,34 @@ fun SearchPanel(
OutlinedButton(
modifier = Modifier.padding(12.dp).wrapContentWidth(),
onClick = {
- if(link.isBlank()) showPopUpMessage("Enter A Link!")
- else{
- //TODO if(!isOnline(ctx)) showPopUpMessage("Check Your Internet Connection") else
+ if (link.isBlank()) showPopUpMessage("Enter A Link!")
+ else {
+ // TODO if(!isOnline(ctx)) showPopUpMessage("Check Your Internet Connection") else
onSearch(link)
}
},
- border = BorderStroke(1.dp, Brush.horizontalGradient(listOf(
- colorPrimary,
- colorAccent
- )))
- ){
- Text(text = "Search",style = SpotiFlyerTypography.h6,modifier = Modifier.padding(4.dp))
+ border = BorderStroke(
+ 1.dp,
+ Brush.horizontalGradient(
+ listOf(
+ colorPrimary,
+ colorAccent
+ )
+ )
+ )
+ ) {
+ Text(text = "Search", style = SpotiFlyerTypography.h6, modifier = Modifier.padding(4.dp))
}
}
}
@Composable
fun AboutColumn(modifier: Modifier = Modifier) {
- //TODO Make Scrollable
+ // TODO Make Scrollable
Column(modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
Card(
modifier = modifier.fillMaxWidth(),
- border = BorderStroke(1.dp,Color.Gray)
+ border = BorderStroke(1.dp, Color.Gray)
) {
Column(modifier.padding(12.dp)) {
Text(
@@ -193,34 +231,41 @@ fun AboutColumn(modifier: Modifier = Modifier) {
color = colorAccent
)
Spacer(modifier = Modifier.padding(top = 12.dp))
- Row(horizontalArrangement = Arrangement.Center,modifier = modifier.fillMaxWidth()) {
+ Row(horizontalArrangement = Arrangement.Center, modifier = modifier.fillMaxWidth()) {
Icon(
imageVector = SpotifyLogo(),
"Open Spotify",
tint = Color.Unspecified,
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
- onClick = { openPlatform("com.spotify.music","http://open.spotify.com") })
+ onClick = { openPlatform("com.spotify.music", "http://open.spotify.com") }
+ )
)
Spacer(modifier = modifier.padding(start = 16.dp))
- Icon(imageVector = GaanaLogo(),
+ Icon(
+ imageVector = GaanaLogo(),
"Open Gaana",
tint = Color.Unspecified,
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
- onClick = { openPlatform("com.gaana","http://gaana.com") })
+ onClick = { openPlatform("com.gaana", "http://gaana.com") }
+ )
)
Spacer(modifier = modifier.padding(start = 16.dp))
- Icon(imageVector = YoutubeLogo(),
+ Icon(
+ imageVector = YoutubeLogo(),
"Open Youtube",
tint = Color.Unspecified,
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
- onClick = { openPlatform("com.google.android.youtube","http://m.youtube.com") })
+ onClick = { openPlatform("com.google.android.youtube", "http://m.youtube.com") }
+ )
)
Spacer(modifier = modifier.padding(start = 12.dp))
- Icon(imageVector = YoutubeMusicLogo(),
+ Icon(
+ imageVector = YoutubeMusicLogo(),
"Open Youtube Music",
tint = Color.Unspecified,
modifier = Modifier.clip(SpotiFlyerShapes.small).clickable(
- onClick = { openPlatform("com.google.android.apps.youtube.music","https://music.youtube.com/") })
+ onClick = { openPlatform("com.google.android.apps.youtube.music", "https://music.youtube.com/") }
+ )
)
}
}
@@ -228,7 +273,7 @@ fun AboutColumn(modifier: Modifier = Modifier) {
Spacer(modifier = Modifier.padding(top = 8.dp))
Card(
modifier = modifier.fillMaxWidth(),
- border = BorderStroke(1.dp,Color.Gray)//Gray
+ border = BorderStroke(1.dp, Color.Gray) // Gray
) {
Column(modifier.padding(12.dp)) {
Text(
@@ -237,12 +282,14 @@ fun AboutColumn(modifier: Modifier = Modifier) {
color = colorAccent
)
Spacer(modifier = Modifier.padding(top = 6.dp))
- Row(verticalAlignment = Alignment.CenterVertically,
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth().clickable(
- onClick = { openPlatform("","http://github.com/Shabinder/SpotiFlyer") })
+ onClick = { openPlatform("", "http://github.com/Shabinder/SpotiFlyer") }
+ )
.padding(vertical = 6.dp)
) {
- Icon(imageVector = GithubLogo(),"Open Project Repo",tint = Color(0xFFCCCCCC))
+ Icon(imageVector = GithubLogo(), "Open Project Repo", tint = Color(0xFFCCCCCC))
Spacer(modifier = Modifier.padding(start = 16.dp))
Column {
Text(
@@ -257,10 +304,10 @@ fun AboutColumn(modifier: Modifier = Modifier) {
}
Row(
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
- .clickable(onClick = { openPlatform("","http://github.com/Shabinder/SpotiFlyer") }),
+ .clickable(onClick = { openPlatform("", "http://github.com/Shabinder/SpotiFlyer") }),
verticalAlignment = Alignment.CenterVertically
) {
- Icon(Icons.Rounded.Flag,"Help Translate",Modifier.size(32.dp))
+ Icon(Icons.Rounded.Flag, "Help Translate", Modifier.size(32.dp))
Spacer(modifier = Modifier.padding(start = 16.dp))
Column {
Text(
@@ -278,7 +325,7 @@ fun AboutColumn(modifier: Modifier = Modifier) {
.clickable(onClick = { giveDonation() }),
verticalAlignment = Alignment.CenterVertically
) {
- Icon(Icons.Rounded.CardGiftcard,"Support Developer")
+ Icon(Icons.Rounded.CardGiftcard, "Support Developer")
Spacer(modifier = Modifier.padding(start = 16.dp))
Column {
Text(
@@ -293,12 +340,14 @@ fun AboutColumn(modifier: Modifier = Modifier) {
}
Row(
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
- .clickable(onClick = {
- shareApp()
- }),
+ .clickable(
+ onClick = {
+ shareApp()
+ }
+ ),
verticalAlignment = Alignment.CenterVertically
) {
- Icon(Icons.Rounded.Share,"Share SpotiFlyer App")
+ Icon(Icons.Rounded.Share, "Share SpotiFlyer App")
Spacer(modifier = Modifier.padding(start = 16.dp))
Column {
Text(
@@ -319,22 +368,23 @@ fun AboutColumn(modifier: Modifier = Modifier) {
@Composable
fun HistoryColumn(
list: List,
- loadImage:suspend (String)-> Picture,
+ loadImage: suspend (String) -> Picture,
onItemClicked: (String) -> Unit
) {
- Crossfade(list){
- if(it.isEmpty()){
- Column(Modifier.padding(bottom = 32.dp).fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {
- Icon(Icons.Outlined.Info,"No History Available Yet",modifier = Modifier.size(80.dp),
+ Crossfade(list) {
+ if (it.isEmpty()) {
+ Column(Modifier.padding(bottom = 32.dp).fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally) {
+ Icon(
+ Icons.Outlined.Info, "No History Available Yet", modifier = Modifier.size(80.dp),
colorOffWhite
)
- 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(
verticalArrangement = Arrangement.spacedBy(12.dp),
content = {
- items(it.distinctBy {record -> record.coverUrl }) { record ->
+ items(it.distinctBy { record -> record.coverUrl }) { record ->
DownloadRecordItem(
item = record,
loadImage,
@@ -351,39 +401,40 @@ fun HistoryColumn(
@Composable
fun DownloadRecordItem(
item: DownloadRecord,
- loadImage:suspend (String)-> Picture,
- onItemClicked:(String)->Unit
+ loadImage: suspend (String) -> Picture,
+ onItemClicked: (String) -> Unit
) {
- Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier.fillMaxWidth().padding(end = 8.dp)) {
+ Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().padding(end = 8.dp)) {
ImageLoad(
item.coverUrl,
loadImage,
"Album Art",
modifier = Modifier.height(70.dp).width(70.dp).clip(SpotiFlyerShapes.medium)
)
- Column(modifier = Modifier.padding(horizontal = 8.dp).height(60.dp).weight(1f),verticalArrangement = Arrangement.SpaceEvenly) {
- Text(item.name,maxLines = 1,overflow = TextOverflow.Ellipsis,style = SpotiFlyerTypography.h6,color = colorAccent)
+ Column(modifier = Modifier.padding(horizontal = 8.dp).height(60.dp).weight(1f), verticalArrangement = Arrangement.SpaceEvenly) {
+ Text(item.name, maxLines = 1, overflow = TextOverflow.Ellipsis, style = SpotiFlyerTypography.h6, color = colorAccent)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.Bottom,
modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize()
- ){
- Text(item.type,fontSize = 13.sp,color = colorOffWhite)
- Text("Tracks: ${item.totalFiles}",fontSize = 13.sp,color = colorOffWhite)
+ ) {
+ Text(item.type, fontSize = 13.sp, color = colorOffWhite)
+ Text("Tracks: ${item.totalFiles}", fontSize = 13.sp, color = colorOffWhite)
}
}
Image(
imageVector = ShareImage(),
"Research",
- modifier = Modifier.clickable(onClick = {
- //if(!isOnline(ctx)) showDialog("Check Your Internet Connection") else
- onItemClicked(item.link)
- })
+ modifier = Modifier.clickable(
+ onClick = {
+ // if(!isOnline(ctx)) showDialog("Check Your Internet Connection") else
+ onItemClicked(item.link)
+ }
+ )
)
}
}
-
@Composable
fun HomeCategoryTabIndicator(
modifier: Modifier = Modifier,
@@ -394,4 +445,4 @@ fun HomeCategoryTabIndicator(
.height(4.dp)
.background(color, RoundedCornerShape(topStartPercent = 100, topEndPercent = 100))
)
-}
\ No newline at end of file
+}
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerRootUi.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerRootUi.kt
index 12b5d108..ba39886b 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerRootUi.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/SpotiFlyerRootUi.kt
@@ -16,11 +16,24 @@
package com.shabinder.common.uikit
-import androidx.compose.animation.core.*
+import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.Spring.StiffnessLow
+import androidx.compose.animation.core.animateDp
+import androidx.compose.animation.core.animateFloat
+import androidx.compose.animation.core.spring
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.*
+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.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
@@ -45,7 +58,7 @@ import com.shabinder.common.uikit.utils.verticalGradientScrim
private var isSplashShown = SplashState.Shown
@Composable
-fun SpotiFlyerRootContent(component: SpotiFlyerRoot, statusBarHeight:Dp = 0.dp): SpotiFlyerRoot {
+fun SpotiFlyerRootContent(component: SpotiFlyerRoot, statusBarHeight: Dp = 0.dp): SpotiFlyerRoot {
val transitionState = remember { MutableTransitionState(SplashState.Shown) }
val transition = updateTransition(transitionState)
@@ -63,10 +76,10 @@ fun SpotiFlyerRootContent(component: SpotiFlyerRoot, statusBarHeight:Dp = 0.dp):
val contentTopPadding by transition.animateDp(
transitionSpec = { spring(stiffness = StiffnessLow) }
) {
- if (it == SplashState.Shown && isSplashShown == SplashState.Shown) 100.dp else 0.dp
+ if (it == SplashState.Shown && isSplashShown == SplashState.Shown) 100.dp else 0.dp
}
- Box{
+ Box {
Splash(
modifier = Modifier.alpha(splashAlpha),
onTimeout = {
@@ -85,17 +98,17 @@ fun SpotiFlyerRootContent(component: SpotiFlyerRoot, statusBarHeight:Dp = 0.dp):
}
@Composable
-fun MainScreen(modifier: Modifier = Modifier, topPadding: Dp = 0.dp,statusBarHeight: Dp = 0.dp,component: SpotiFlyerRoot) {
+fun MainScreen(modifier: Modifier = Modifier, topPadding: Dp = 0.dp, statusBarHeight: Dp = 0.dp, component: SpotiFlyerRoot) {
val appBarColor = MaterialTheme.colors.surface.copy(alpha = 0.65f)
Column(
modifier = modifier.fillMaxSize()
- .verticalGradientScrim(
- color = colorPrimaryDark.copy(alpha = 0.38f),
- startYPercentage = 0.29f,
- endYPercentage = 0f,
- )
+ .verticalGradientScrim(
+ color = colorPrimaryDark.copy(alpha = 0.38f),
+ startYPercentage = 0.29f,
+ endYPercentage = 0f,
+ )
) {
Spacer(Modifier.background(appBarColor).height(statusBarHeight).fillMaxWidth())
LocalViewConfiguration.current
@@ -136,7 +149,7 @@ fun AppBar(
style = appNameStyle
)
}
- },/*
+ }, /*
actions = {
IconButton(
onClick = { *//*TODO: Open Preferences*//* }
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Theme.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Theme.kt
index a62c7913..fdf13ddf 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Theme.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Theme.kt
@@ -20,11 +20,11 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
@Composable
-fun SpotiFlyerTheme(content: @Composable() () -> Unit) {
+fun SpotiFlyerTheme(content: @Composable () -> Unit) {
MaterialTheme(
- colors = SpotiFlyerColors,
- typography = SpotiFlyerTypography,
- shapes = SpotiFlyerShapes,
- content = content
+ colors = SpotiFlyerColors,
+ typography = SpotiFlyerTypography,
+ shapes = SpotiFlyerShapes,
+ content = content
)
-}
\ No newline at end of file
+}
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Toast.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Toast.kt
index ce36a479..fa4a088e 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Toast.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Toast.kt
@@ -31,4 +31,4 @@ expect fun Toast(
text: String,
visibility: MutableState = mutableStateOf(false),
duration: ToastDuration = ToastDuration.Long
-)
\ No newline at end of file
+)
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Type.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Type.kt
index 01d59ee3..b4140437 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Type.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/Type.kt
@@ -23,107 +23,106 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
-
-expect fun montserratFont():FontFamily
-expect fun pristineFont():FontFamily
+expect fun montserratFont(): FontFamily
+expect fun pristineFont(): FontFamily
val SpotiFlyerTypography = Typography(
- h1 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 96.sp,
- fontWeight = FontWeight.Light,
- lineHeight = 117.sp,
- letterSpacing = (-1.5).sp
- ),
- h2 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 60.sp,
- fontWeight = FontWeight.Light,
- lineHeight = 73.sp,
- letterSpacing = (-0.5).sp
- ),
- h3 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 48.sp,
- fontWeight = FontWeight.Normal,
- lineHeight = 59.sp
- ),
- h4 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 30.sp,
- fontWeight = FontWeight.SemiBold,
- lineHeight = 37.sp
- ),
- h5 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 24.sp,
- fontWeight = FontWeight.SemiBold,
- lineHeight = 29.sp
- ),
- h6 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 18.sp,
- fontWeight = FontWeight.Medium,
- lineHeight = 26.sp,
- letterSpacing = 0.5.sp
+ h1 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 96.sp,
+ fontWeight = FontWeight.Light,
+ lineHeight = 117.sp,
+ letterSpacing = (-1.5).sp
+ ),
+ h2 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 60.sp,
+ fontWeight = FontWeight.Light,
+ lineHeight = 73.sp,
+ letterSpacing = (-0.5).sp
+ ),
+ h3 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 48.sp,
+ fontWeight = FontWeight.Normal,
+ lineHeight = 59.sp
+ ),
+ h4 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 30.sp,
+ fontWeight = FontWeight.SemiBold,
+ lineHeight = 37.sp
+ ),
+ h5 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 24.sp,
+ fontWeight = FontWeight.SemiBold,
+ lineHeight = 29.sp
+ ),
+ h6 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 18.sp,
+ fontWeight = FontWeight.Medium,
+ lineHeight = 26.sp,
+ letterSpacing = 0.5.sp
- ),
- subtitle1 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 16.sp,
- fontWeight = FontWeight.SemiBold,
- lineHeight = 20.sp,
- letterSpacing = 0.5.sp
- ),
- subtitle2 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 14.sp,
- fontWeight = FontWeight.Medium,
- lineHeight = 17.sp,
- letterSpacing = 0.1.sp
- ),
- body1 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 16.sp,
- fontWeight = FontWeight.Medium,
- lineHeight = 20.sp,
- letterSpacing = 0.15.sp,
- ),
- body2 = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 14.sp,
- fontWeight = FontWeight.SemiBold,
- lineHeight = 20.sp,
- letterSpacing = 0.25.sp
- ),
- button = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 14.sp,
- fontWeight = FontWeight.SemiBold,
- lineHeight = 16.sp,
- letterSpacing = 1.25.sp
- ),
- caption = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 12.sp,
- fontWeight = FontWeight.SemiBold,
- lineHeight = 16.sp,
- letterSpacing = 0.sp
- ),
- overline = TextStyle(
- fontFamily = montserratFont(),
- fontSize = 12.sp,
- fontWeight = FontWeight.SemiBold,
- lineHeight = 16.sp,
- letterSpacing = 1.sp
- )
+ ),
+ subtitle1 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 16.sp,
+ fontWeight = FontWeight.SemiBold,
+ lineHeight = 20.sp,
+ letterSpacing = 0.5.sp
+ ),
+ subtitle2 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 14.sp,
+ fontWeight = FontWeight.Medium,
+ lineHeight = 17.sp,
+ letterSpacing = 0.1.sp
+ ),
+ body1 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 16.sp,
+ fontWeight = FontWeight.Medium,
+ lineHeight = 20.sp,
+ letterSpacing = 0.15.sp,
+ ),
+ body2 = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 14.sp,
+ fontWeight = FontWeight.SemiBold,
+ lineHeight = 20.sp,
+ letterSpacing = 0.25.sp
+ ),
+ button = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 14.sp,
+ fontWeight = FontWeight.SemiBold,
+ lineHeight = 16.sp,
+ letterSpacing = 1.25.sp
+ ),
+ caption = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 12.sp,
+ fontWeight = FontWeight.SemiBold,
+ lineHeight = 16.sp,
+ letterSpacing = 0.sp
+ ),
+ overline = TextStyle(
+ fontFamily = montserratFont(),
+ fontSize = 12.sp,
+ fontWeight = FontWeight.SemiBold,
+ lineHeight = 16.sp,
+ letterSpacing = 1.sp
+ )
)
val appNameStyle = TextStyle(
- fontFamily = pristineFont(),
- fontSize = 40.sp,
- fontWeight = FontWeight.SemiBold,
- lineHeight = 42.sp,
- letterSpacing = (1.5).sp,
- color = Color(0xFFECECEC)
-)
\ No newline at end of file
+ fontFamily = pristineFont(),
+ fontSize = 40.sp,
+ fontWeight = FontWeight.SemiBold,
+ lineHeight = 42.sp,
+ letterSpacing = (1.5).sp,
+ color = Color(0xFFECECEC)
+)
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/splash/Splash.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/splash/Splash.kt
index fc03a7a6..40634a4a 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/splash/Splash.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/splash/Splash.kt
@@ -17,7 +17,13 @@
package com.shabinder.common.uikit.splash
import androidx.compose.foundation.Image
-import androidx.compose.foundation.layout.*
+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.fillMaxSize
+import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
@@ -29,7 +35,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import com.shabinder.common.uikit.*
+import com.shabinder.common.uikit.HeartIcon
+import com.shabinder.common.uikit.SpotiFlyerLogo
+import com.shabinder.common.uikit.SpotiFlyerTypography
+import com.shabinder.common.uikit.colorAccent
+import com.shabinder.common.uikit.colorPrimary
import kotlinx.coroutines.delay
private const val SplashWaitTime: Long = 2000
@@ -45,7 +55,7 @@ fun Splash(modifier: Modifier = Modifier, onTimeout: () -> Unit) {
delay(SplashWaitTime)
currentOnTimeout()
}
- Image(imageVector = SpotiFlyerLogo(),"SpotiFlyer Logo")
+ Image(imageVector = SpotiFlyerLogo(), "SpotiFlyer Logo")
MadeInIndia(Modifier.align(Alignment.BottomCenter))
}
}
@@ -53,7 +63,7 @@ fun Splash(modifier: Modifier = Modifier, onTimeout: () -> Unit) {
@Composable
fun MadeInIndia(
modifier: Modifier = Modifier
-){
+) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.padding(8.dp)
@@ -68,7 +78,7 @@ fun MadeInIndia(
fontSize = 22.sp
)
Spacer(modifier = Modifier.padding(start = 4.dp))
- Icon(HeartIcon(),"Love",tint = Color.Unspecified)
+ Icon(HeartIcon(), "Love", tint = Color.Unspecified)
Spacer(modifier = Modifier.padding(start = 4.dp))
Text(
text = " in India",
@@ -83,4 +93,4 @@ fun MadeInIndia(
fontSize = 14.sp
)
}
-}
\ No newline at end of file
+}
diff --git a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/utils/GradientScrim.kt b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/utils/GradientScrim.kt
index 327b495d..cb245a0f 100644
--- a/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/utils/GradientScrim.kt
+++ b/common/compose/src/commonMain/kotlin/com/shabinder/common/uikit/utils/GradientScrim.kt
@@ -40,8 +40,10 @@ import kotlin.math.pow
*/
fun Modifier.verticalGradientScrim(
color: Color,
- /*@FloatRange(from = 0.0, to = 1.0)*/ startYPercentage: Float = 0f,
- /*@FloatRange(from = 0.0, to = 1.0)*/ endYPercentage: Float = 1f,
+ /*@FloatRange(from = 0.0, to = 1.0)*/
+ startYPercentage: Float = 0f,
+ /*@FloatRange(from = 0.0, to = 1.0)*/
+ endYPercentage: Float = 1f,
decay: Float = 1.0f,
numStops: Int = 16,
fixedHeight: Float? = null
diff --git a/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt b/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt
index bb72edf2..67a1839d 100644
--- a/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt
+++ b/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopImages.kt
@@ -19,7 +19,12 @@ package com.shabinder.common.uikit
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.Image
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.vector.ImageVector
@@ -34,26 +39,26 @@ import kotlinx.coroutines.withContext
@Composable
actual fun ImageLoad(
- link:String,
- loader:suspend (String) -> Picture,
+ link: String,
+ loader: suspend (String) -> Picture,
desc: String,
- modifier:Modifier,
- //placeholder: ImageVector
+ modifier: Modifier,
+ // placeholder: ImageVector
) {
var pic by remember(link) { mutableStateOf(null) }
- LaunchedEffect(link){
+ LaunchedEffect(link) {
withContext(dispatcherIO) {
pic = loader(link).image
}
}
- Crossfade(pic){
- if(it == null) Image(PlaceHolderImage(), desc, modifier,contentScale = ContentScale.Crop) else Image(it, desc, modifier,contentScale = ContentScale.Crop)
+ Crossfade(pic) {
+ if (it == null) Image(PlaceHolderImage(), desc, modifier, contentScale = ContentScale.Crop) else Image(it, desc, modifier, contentScale = ContentScale.Crop)
}
}
@Composable
-actual fun DownloadImageTick(){
+actual fun DownloadImageTick() {
Image(
vectorXmlResource("drawable/ic_tick.xml"),
"Downloaded"
@@ -72,7 +77,7 @@ actual fun pristineFont() = FontFamily(
)
@Composable
-actual fun DownloadImageError(){
+actual fun DownloadImageError() {
Image(
vectorXmlResource("drawable/ic_error.xml"),
"Can't Download"
@@ -80,7 +85,7 @@ actual fun DownloadImageError(){
}
@Composable
-actual fun DownloadImageArrow(modifier: Modifier){
+actual fun DownloadImageArrow(modifier: Modifier) {
Image(
vectorXmlResource("drawable/ic_arrow.xml"),
"Download",
@@ -89,33 +94,32 @@ actual fun DownloadImageArrow(modifier: Modifier){
}
@Composable
-actual fun DownloadAllImage():ImageVector = vectorXmlResource("drawable/ic_download_arrow.xml")
+actual fun DownloadAllImage(): ImageVector = vectorXmlResource("drawable/ic_download_arrow.xml")
@Composable
-actual fun ShareImage():ImageVector = vectorXmlResource("drawable/ic_share_open.xml")
+actual fun ShareImage(): ImageVector = vectorXmlResource("drawable/ic_share_open.xml")
@Composable
-actual fun PlaceHolderImage():ImageVector = vectorXmlResource("drawable/music.xml")
-
+actual fun PlaceHolderImage(): ImageVector = vectorXmlResource("drawable/music.xml")
@Composable
-actual fun SpotiFlyerLogo():ImageVector =
+actual fun SpotiFlyerLogo(): ImageVector =
vectorXmlResource("drawable/ic_spotiflyer_logo.xml")
@Composable
-actual fun HeartIcon():ImageVector = vectorXmlResource("drawable/ic_heart.xml")
+actual fun HeartIcon(): ImageVector = vectorXmlResource("drawable/ic_heart.xml")
@Composable
-actual fun SpotifyLogo():ImageVector = vectorXmlResource("drawable/ic_spotify_logo.xml")
+actual fun SpotifyLogo(): ImageVector = vectorXmlResource("drawable/ic_spotify_logo.xml")
@Composable
-actual fun YoutubeLogo():ImageVector = vectorXmlResource("drawable/ic_youtube.xml")
+actual fun YoutubeLogo(): ImageVector = vectorXmlResource("drawable/ic_youtube.xml")
@Composable
-actual fun GaanaLogo():ImageVector = vectorXmlResource("drawable/ic_gaana.xml")
+actual fun GaanaLogo(): ImageVector = vectorXmlResource("drawable/ic_gaana.xml")
@Composable
-actual fun YoutubeMusicLogo():ImageVector = vectorXmlResource("drawable/ic_youtube_music_logo.xml")
+actual fun YoutubeMusicLogo(): ImageVector = vectorXmlResource("drawable/ic_youtube_music_logo.xml")
@Composable
-actual fun GithubLogo():ImageVector = vectorXmlResource("drawable/ic_github.xml")
+actual fun GithubLogo(): ImageVector = vectorXmlResource("drawable/ic_github.xml")
diff --git a/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopToast.kt b/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopToast.kt
index c1be0e0f..dea14703 100644
--- a/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopToast.kt
+++ b/common/compose/src/desktopMain/kotlin/com/shabinder/common/uikit/DesktopToast.kt
@@ -78,9 +78,9 @@ actual fun Toast(
isShown = false
visibility.value = false
}
- onDispose { }
+ onDispose { }
}
}
}
}
-}
\ No newline at end of file
+}
diff --git a/common/data-models/build.gradle.kts b/common/data-models/build.gradle.kts
index 882e4f0a..e44de175 100644
--- a/common/data-models/build.gradle.kts
+++ b/common/data-models/build.gradle.kts
@@ -31,4 +31,4 @@ kotlin {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/AllPlatforms.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/AllPlatforms.kt
index b11c56de..14f894f1 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/AllPlatforms.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/AllPlatforms.kt
@@ -16,8 +16,8 @@
package com.shabinder.common.models
-sealed class AllPlatforms{
- object Js:AllPlatforms()
- object Jvm:AllPlatforms()
- object Native:AllPlatforms()
+sealed class AllPlatforms {
+ object Js : AllPlatforms()
+ object Jvm : AllPlatforms()
+ object Native : AllPlatforms()
}
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/CorsProxy.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/CorsProxy.kt
index 079dd2bb..8a6c0e0a 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/CorsProxy.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/CorsProxy.kt
@@ -16,24 +16,24 @@
package com.shabinder.common.models
-sealed class CorsProxy(open val url: String){
- data class SelfHostedCorsProxy(override val url:String = "https://kind-grasshopper-73.telebit.io/cors/"):CorsProxy(url)
- data class PublicProxyWithExtension(override val url:String = "https://cors.bridged.cc/"):CorsProxy(url)
+sealed class CorsProxy(open val url: String) {
+ data class SelfHostedCorsProxy(override val url: String = "https://kind-grasshopper-73.telebit.io/cors/") : CorsProxy(url)
+ data class PublicProxyWithExtension(override val url: String = "https://cors.bridged.cc/") : CorsProxy(url)
- fun toggle(mode:CorsProxy? = null):CorsProxy{
+ fun toggle(mode: CorsProxy? = null): CorsProxy {
mode?.let {
corsProxy = mode
return corsProxy
}
- corsProxy = when(corsProxy){
+ corsProxy = when (corsProxy) {
is SelfHostedCorsProxy -> PublicProxyWithExtension()
is PublicProxyWithExtension -> SelfHostedCorsProxy()
}
return corsProxy
}
- fun extensionMode():Boolean{
- return when(corsProxy){
+ fun extensionMode(): Boolean {
+ return when (corsProxy) {
is SelfHostedCorsProxy -> false
is PublicProxyWithExtension -> true
}
@@ -44,4 +44,4 @@ sealed class CorsProxy(open val url: String){
* This Var Keeps Track for Cors Config in JS Platform
* Default Self Hosted, However ask user to use extension if possible.
* */
-var corsProxy:CorsProxy = CorsProxy.SelfHostedCorsProxy()
+var corsProxy: CorsProxy = CorsProxy.SelfHostedCorsProxy()
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadObject.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadObject.kt
index b3aae462..7d004ed6 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadObject.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadObject.kt
@@ -24,30 +24,29 @@ import kotlinx.serialization.Serializable
@Parcelize
@Serializable
data class TrackDetails(
- var title:String,
- var artists:List,
- var durationSec:Int,
- var albumName:String?=null,
- var year:String?=null,
- var comment:String?=null,
- var lyrics:String?=null,
- var trackUrl:String?=null,
+ var title: String,
+ var artists: List,
+ var durationSec: Int,
+ var albumName: String? = null,
+ var year: String? = null,
+ var comment: String? = null,
+ var lyrics: String? = null,
+ var trackUrl: String? = null,
var albumArtPath: String,
var albumArtURL: String,
var source: Source,
val progress: Int = 2,
val downloaded: DownloadStatus = DownloadStatus.NotDownloaded,
var outputFilePath: String,
- var videoID:String? = null,
-):Parcelable
-
+ var videoID: String? = null,
+) : Parcelable
@Serializable
-sealed class DownloadStatus:Parcelable {
- @Parcelize object Downloaded :DownloadStatus()
- @Parcelize data class Downloading(val progress: Int = 2):DownloadStatus()
- @Parcelize object Queued :DownloadStatus()
- @Parcelize object NotDownloaded :DownloadStatus()
- @Parcelize object Converting :DownloadStatus()
- @Parcelize object Failed :DownloadStatus()
+sealed class DownloadStatus : Parcelable {
+ @Parcelize object Downloaded : DownloadStatus()
+ @Parcelize data class Downloading(val progress: Int = 2) : DownloadStatus()
+ @Parcelize object Queued : DownloadStatus()
+ @Parcelize object NotDownloaded : DownloadStatus()
+ @Parcelize object Converting : DownloadStatus()
+ @Parcelize object Failed : DownloadStatus()
}
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadRecord.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadRecord.kt
index f90001be..0c8cf7bb 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadRecord.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadRecord.kt
@@ -17,10 +17,10 @@
package com.shabinder.common.models
data class DownloadRecord(
- var id:Long = 0,
- var type:String,
- var name:String,
- var link:String,
- var coverUrl:String,
- var totalFiles:Long = 1,
-)
\ No newline at end of file
+ var id: Long = 0,
+ var type: String,
+ var name: String,
+ var link: String,
+ var coverUrl: String,
+ var totalFiles: Long = 1,
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadResult.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadResult.kt
index 9fb22d58..9d5d26f3 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadResult.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/DownloadResult.kt
@@ -20,7 +20,7 @@ sealed class DownloadResult {
data class Error(val message: String, val cause: Exception? = null) : DownloadResult()
- data class Progress(val progress: Int): DownloadResult()
+ data class Progress(val progress: Int) : DownloadResult()
data class Success(val byteArray: ByteArray) : DownloadResult() {
override fun equals(other: Any?): Boolean {
@@ -38,4 +38,4 @@ sealed class DownloadResult {
return byteArray.contentHashCode()
}
}
-}
\ No newline at end of file
+}
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/Optional.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/Optional.kt
index a8e960de..3b24765e 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/Optional.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/Optional.kt
@@ -19,4 +19,4 @@ package com.shabinder.common.models
import kotlinx.serialization.Serializable
@Serializable
-data class Optional(val value: T?)
\ No newline at end of file
+data class Optional(val value: T?)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/PlatformQueryResult.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/PlatformQueryResult.kt
index 04c39366..ceeeed63 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/PlatformQueryResult.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/PlatformQueryResult.kt
@@ -27,4 +27,4 @@ data class PlatformQueryResult(
var coverUrl: String,
var trackList: List,
var source: Source
-)
\ No newline at end of file
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/YoutubeTrack.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/YoutubeTrack.kt
index 87ba0762..dc1abc90 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/YoutubeTrack.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/YoutubeTrack.kt
@@ -21,8 +21,8 @@ import kotlinx.serialization.Serializable
@Serializable
data class YoutubeTrack(
var name: String? = null,
- var type: String? = null, // Song / Video
+ var type: String? = null, // Song / Video
var artist: String? = null,
- var duration:String? = null,
+ var duration: String? = null,
var videoId: String? = null
-)
\ No newline at end of file
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Artist.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Artist.kt
index 2e8cadab..fba24e20 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Artist.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Artist.kt
@@ -20,9 +20,9 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
-data class Artist (
- val popularity : Int,
- val seokey : String,
- val name : String,
- @SerialName("artwork_175x175")var artworkLink :String? = null
-)
\ No newline at end of file
+data class Artist(
+ val popularity: Int,
+ val seokey: String,
+ val name: String,
+ @SerialName("artwork_175x175")var artworkLink: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/CustomArtworks.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/CustomArtworks.kt
index d6718ce8..76ffabdc 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/CustomArtworks.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/CustomArtworks.kt
@@ -17,14 +17,13 @@
package com.shabinder.common.models.gaana
import kotlinx.serialization.SerialName
-
import kotlinx.serialization.Serializable
@Serializable
-data class CustomArtworks (
- @SerialName("40x40") val size_40p : String,
- @SerialName("80x80") val size_80p : String,
- @SerialName("110x110")val size_110p : String,
- @SerialName("175x175")val size_175p : String,
- @SerialName("480x480")val size_480p : String,
-)
\ No newline at end of file
+data class CustomArtworks(
+ @SerialName("40x40") val size_40p: String,
+ @SerialName("80x80") val size_80p: String,
+ @SerialName("110x110")val size_110p: String,
+ @SerialName("175x175")val size_175p: String,
+ @SerialName("480x480")val size_480p: String,
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaAlbum.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaAlbum.kt
index cb01d110..b050acf9 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaAlbum.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaAlbum.kt
@@ -19,10 +19,10 @@ package com.shabinder.common.models.gaana
import kotlinx.serialization.Serializable
@Serializable
-data class GaanaAlbum (
- val tracks : List,
- val count : Int,
- val custom_artworks : CustomArtworks,
- val release_year : Int,
- val favorite_count : Int,
-)
\ No newline at end of file
+data class GaanaAlbum(
+ val tracks: List,
+ val count: Int,
+ val custom_artworks: CustomArtworks,
+ val release_year: Int,
+ val favorite_count: Int,
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaArtistDetails.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaArtistDetails.kt
index 82093577..c8d8271d 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaArtistDetails.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaArtistDetails.kt
@@ -20,6 +20,6 @@ import kotlinx.serialization.Serializable
@Serializable
data class GaanaArtistDetails(
- val artist : List,
- val count : Int,
-)
\ No newline at end of file
+ val artist: List,
+ val count: Int,
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaArtistTracks.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaArtistTracks.kt
index 75cc908d..e54a5a96 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaArtistTracks.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaArtistTracks.kt
@@ -20,6 +20,6 @@ import kotlinx.serialization.Serializable
@Serializable
data class GaanaArtistTracks(
- val count : Int,
- val tracks : List? = null
-)
\ No newline at end of file
+ val count: Int,
+ val tracks: List? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaPlaylist.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaPlaylist.kt
index b8b96a12..94f6032c 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaPlaylist.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaPlaylist.kt
@@ -19,10 +19,10 @@ package com.shabinder.common.models.gaana
import kotlinx.serialization.Serializable
@Serializable
-data class GaanaPlaylist (
- val modified_on : String,
- val count : Int,
- val created_on : String,
- val favorite_count : Int,
- val tracks : List,
-)
\ No newline at end of file
+data class GaanaPlaylist(
+ val modified_on: String,
+ val count: Int,
+ val created_on: String,
+ val favorite_count: Int,
+ val tracks: List,
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaSong.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaSong.kt
index 39d0a9c0..d421b7b6 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaSong.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaSong.kt
@@ -20,5 +20,5 @@ import kotlinx.serialization.Serializable
@Serializable
data class GaanaSong(
- val tracks : List
-)
\ No newline at end of file
+ val tracks: List
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaTrack.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaTrack.kt
index e687b5ac..ece6bd99 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaTrack.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/GaanaTrack.kt
@@ -21,22 +21,22 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
-data class GaanaTrack (
- val tags : List? = null,
- val seokey : String,
- val albumseokey : String? = null,
- val track_title : String,
- val album_title : String? = null,
- val language : String? = null,
+data class GaanaTrack(
+ val tags: List? = null,
+ val seokey: String,
+ val albumseokey: String? = null,
+ val track_title: String,
+ val album_title: String? = null,
+ val language: String? = null,
val duration: Int,
- @SerialName("artwork_large") val artworkLink : String,
- val artist : List = emptyList(),
- @SerialName("gener") val genre : List? = null,
- val lyrics_url : String? = null,
- val youtube_id : String? = null,
- val total_favourite_count : Int? = null,
- val release_date : String? = null,
- val play_ct : String? = null,
- val secondary_language : String? = null,
+ @SerialName("artwork_large") val artworkLink: String,
+ val artist: List = emptyList(),
+ @SerialName("gener") val genre: List? = null,
+ val lyrics_url: String? = null,
+ val youtube_id: String? = null,
+ val total_favourite_count: Int? = null,
+ val release_date: String? = null,
+ val play_ct: String? = null,
+ val secondary_language: String? = null,
var downloaded: DownloadStatus? = DownloadStatus.NotDownloaded
-)
\ No newline at end of file
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Genre.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Genre.kt
index bc17dc04..ea8a6fdd 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Genre.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Genre.kt
@@ -19,7 +19,7 @@ package com.shabinder.common.models.gaana
import kotlinx.serialization.Serializable
@Serializable
-data class Genre (
- val genre_id : Int,
- val name : String
-)
\ No newline at end of file
+data class Genre(
+ val genre_id: Int,
+ val name: String
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Tags.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Tags.kt
index bc550cbe..5852c335 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Tags.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/gaana/Tags.kt
@@ -19,7 +19,7 @@ package com.shabinder.common.models.gaana
import kotlinx.serialization.Serializable
@Serializable
-data class Tags (
- val tag_id : Int,
- val tag_name : String
-)
\ No newline at end of file
+data class Tags(
+ val tag_id: Int,
+ val tag_name: String
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Album.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Album.kt
index d8474cb5..dbe59c6f 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Album.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Album.kt
@@ -30,11 +30,12 @@ data class Album(
var href: String? = null,
var id: String? = null,
var images: List? = null,
- var label :String? = null,
+ var label: String? = null,
var name: String? = null,
var popularity: Int? = null,
var release_date: String? = null,
var release_date_precision: String? = null,
var tracks: PagingObjectTrack? = null,
var type: String? = null,
- var uri: String? = null)
\ No newline at end of file
+ var uri: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Artist.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Artist.kt
index 70153fa5..8d2e3548 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Artist.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Artist.kt
@@ -25,4 +25,5 @@ data class Artist(
var id: String? = null,
var name: String? = null,
var type: String? = null,
- var uri: String? = null)
\ No newline at end of file
+ var uri: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Copyright.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Copyright.kt
index 5e592beb..da53182b 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Copyright.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Copyright.kt
@@ -21,4 +21,5 @@ import kotlinx.serialization.Serializable
@Serializable
data class Copyright(
var text: String? = null,
- var type: String? = null)
\ No newline at end of file
+ var type: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Episodes.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Episodes.kt
index 7adb0384..94f85dd0 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Episodes.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Episodes.kt
@@ -20,21 +20,21 @@ import kotlinx.serialization.Serializable
@Serializable
data class Episodes(
- var audio_preview_url:String?,
- var description:String?,
- var duration_ms:Int?,
- var explicit:Boolean?,
- var external_urls:Map?,
- var href:String?,
- var id:String?,
- var images:List?,
- var is_externally_hosted:Boolean?,
- var is_playable:Boolean?,
- var language:String?,
- var languages:List?,
- var name:String?,
- var release_date:String?,
- var release_date_precision:String?,
- var type:String?,
- var uri:String
-)
\ No newline at end of file
+ var audio_preview_url: String?,
+ var description: String?,
+ var duration_ms: Int?,
+ var explicit: Boolean?,
+ var external_urls: Map?,
+ var href: String?,
+ var id: String?,
+ var images: List?,
+ var is_externally_hosted: Boolean?,
+ var is_playable: Boolean?,
+ var language: String?,
+ var languages: List?,
+ var name: String?,
+ var release_date: String?,
+ var release_date_precision: String?,
+ var type: String?,
+ var uri: String
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Followers.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Followers.kt
index 312b9c33..254c26fc 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Followers.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Followers.kt
@@ -21,4 +21,5 @@ import kotlinx.serialization.Serializable
@Serializable
data class Followers(
var href: String? = null,
- var total: Int? = null)
\ No newline at end of file
+ var total: Int? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Image.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Image.kt
index 5e5e5138..692e5d45 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Image.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Image.kt
@@ -22,4 +22,5 @@ import kotlinx.serialization.Serializable
data class Image(
var width: Int? = null,
var height: Int? = null,
- var url: String? = null)
\ No newline at end of file
+ var url: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/LinkedTrack.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/LinkedTrack.kt
index d73d5061..8e381ef8 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/LinkedTrack.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/LinkedTrack.kt
@@ -24,4 +24,5 @@ data class LinkedTrack(
var href: String? = null,
var id: String? = null,
var type: String? = null,
- var uri: String? = null)
\ No newline at end of file
+ var uri: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PagingObjectPlaylistTrack.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PagingObjectPlaylistTrack.kt
index 8715d028..71add0eb 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PagingObjectPlaylistTrack.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PagingObjectPlaylistTrack.kt
@@ -26,4 +26,5 @@ data class PagingObjectPlaylistTrack(
var next: String? = null,
var offset: Int = 0,
var previous: String? = null,
- var total: Int = 0)
\ No newline at end of file
+ var total: Int = 0
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PagingObjectTrack.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PagingObjectTrack.kt
index 81cb29eb..49a0e982 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PagingObjectTrack.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PagingObjectTrack.kt
@@ -26,4 +26,5 @@ data class PagingObjectTrack(
var next: String? = null,
var offset: Int = 0,
var previous: String? = null,
- var total: Int = 0)
\ No newline at end of file
+ var total: Int = 0
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Playlist.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Playlist.kt
index 95769656..851e7144 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Playlist.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Playlist.kt
@@ -34,4 +34,5 @@ data class Playlist(
var snapshot_id: String? = null,
var tracks: PagingObjectPlaylistTrack? = null,
var type: String? = null,
- var uri: String? = null)
\ No newline at end of file
+ var uri: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PlaylistTrack.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PlaylistTrack.kt
index d09cc7de..e0c2cda1 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PlaylistTrack.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/PlaylistTrack.kt
@@ -23,4 +23,5 @@ data class PlaylistTrack(
var added_at: String? = null,
var added_by: UserPublic? = null,
var track: Track? = null,
- var is_local: Boolean? = null)
\ No newline at end of file
+ var is_local: Boolean? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Source.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Source.kt
index 2fed43c3..b7e99c6a 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Source.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Source.kt
@@ -20,4 +20,4 @@ enum class Source {
Spotify,
YouTube,
Gaana,
-}
\ No newline at end of file
+}
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/TokenData.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/TokenData.kt
index 5ffee873..41d82a2c 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/TokenData.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/TokenData.kt
@@ -21,7 +21,7 @@ import kotlinx.serialization.Serializable
@Serializable
data class TokenData(
- var access_token:String?,
- var token_type:String?,
- @SerialName("expires_in") var expiry:Long?
-)
\ No newline at end of file
+ var access_token: String?,
+ var token_type: String?,
+ @SerialName("expires_in") var expiry: Long?
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Track.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Track.kt
index 72799110..83a87ae9 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Track.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/Track.kt
@@ -40,4 +40,3 @@ data class Track(
var popularity: Int? = null,
var downloaded: DownloadStatus = DownloadStatus.NotDownloaded
)
-
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/UserPrivate.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/UserPrivate.kt
index b2300fe1..b3a2e8b5 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/UserPrivate.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/UserPrivate.kt
@@ -20,14 +20,15 @@ import kotlinx.serialization.Serializable
@Serializable
data class UserPrivate(
- val country:String,
+ val country: String,
var display_name: String,
- val email:String,
+ val email: String,
var external_urls: Map? = null,
var followers: Followers? = null,
var href: String? = null,
var id: String? = null,
var images: List? = null,
- var product:String,
+ var product: String,
var type: String? = null,
- var uri: String? = null)
\ No newline at end of file
+ var uri: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/UserPublic.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/UserPublic.kt
index 0321c41b..5addc5d9 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/UserPublic.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/spotify/UserPublic.kt
@@ -27,4 +27,5 @@ data class UserPublic(
var id: String? = null,
var images: List? = null,
var type: String? = null,
- var uri: String? = null)
\ No newline at end of file
+ var uri: String? = null
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/AlbumRefWynk.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/AlbumRefWynk.kt
index 279dbdd8..679bb3b6 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/AlbumRefWynk.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/AlbumRefWynk.kt
@@ -22,4 +22,4 @@ data class AlbumRefWynk(
val smallImage: String,
val title: String,
val type: String
-)
\ No newline at end of file
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/HtDataWynk.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/HtDataWynk.kt
index 932ba640..38d292c4 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/HtDataWynk.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/HtDataWynk.kt
@@ -20,4 +20,4 @@ data class HtDataWynk(
val cutName: String,
val previewUrl: String,
val vcode: String
-)
\ No newline at end of file
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/ItemWynk.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/ItemWynk.kt
index f0774f79..b28ff434 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/ItemWynk.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/ItemWynk.kt
@@ -27,7 +27,7 @@ data class ItemWynk(
val cues: List,
val downloadPrice: String,
val downloadUrl: String,
- val duration: Int, //in Seconds
+ val duration: Int, // in Seconds
val exclusive: Boolean,
val formats: List,
val htData: List,
@@ -42,11 +42,11 @@ data class ItemWynk(
val rentUrl: String,
val serverEtag: String,
val shortUrl: String,
- val smallImage: String, //Cover Image after Replacing 120x120 with 720x720
+ val smallImage: String, // Cover Image after Replacing 120x120 with 720x720
val subtitle: String, // String : `ArtistName - TrackName`
- val subtitleId: String, //ARTIST NAME,artist-id , etc //USE SUBTITLE INSTEAD
+ val subtitleId: String, // ARTIST NAME,artist-id , etc //USE SUBTITLE INSTEAD
val subtitleType: String, // ARTIST etc
val title: String,
- val type: String, //Song ,etc
+ val type: String, // Song ,etc
val videoPresent: Boolean
-)
\ No newline at end of file
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/ShortURLWynk.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/ShortURLWynk.kt
index 99506322..66f90c0e 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/ShortURLWynk.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/ShortURLWynk.kt
@@ -16,8 +16,6 @@
package com.shabinder.common.models.wynk
-
-
// Use Kotlinx JSON Parsing as in YT Music
data class ShortURLWynk(
val actualTotal: Int,
@@ -33,15 +31,15 @@ data class ShortURLWynk(
val isFollowable: Boolean,
val isHt: Boolean,
val itemIds: List,
- val itemTypes: List, //Songs , etc
+ val itemTypes: List, // Songs , etc
val items: List,
val lang: String,
- val largeImage: String, //Cover Image Alternate
+ val largeImage: String, // Cover Image Alternate
val lastUpdated: Long,
val offset: Int,
val owner: String,
val playIcon: Boolean,
- val playlistImage: String, //Cover Image
+ val playlistImage: String, // Cover Image
val redesignFeaturedImage: String,
val shortUrl: String,
val singers: List,
@@ -49,4 +47,4 @@ data class ShortURLWynk(
val title: String,
val total: Int,
val type: String
-)
\ No newline at end of file
+)
diff --git a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/SingerWynk.kt b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/SingerWynk.kt
index c5f1b473..a5f91408 100644
--- a/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/SingerWynk.kt
+++ b/common/data-models/src/commonMain/kotlin/com/shabinder/common/models/wynk/SingerWynk.kt
@@ -23,4 +23,4 @@ data class SingerWynk(
val smallImage: String,
val title: String,
val type: String
-)
\ No newline at end of file
+)
diff --git a/common/database/build.gradle.kts b/common/database/build.gradle.kts
index 787d25f0..d29f34f2 100644
--- a/common/database/build.gradle.kts
+++ b/common/database/build.gradle.kts
@@ -31,7 +31,7 @@ kotlin {
commonMain {
dependencies {
implementation(project(":common:data-models"))
- //implementation(Badoo.Reaktive.reaktive)
+ // implementation(Badoo.Reaktive.reaktive)
// SQL Delight
implementation(SqlDelight.runtime)
implementation(SqlDelight.coroutineExtensions)
diff --git a/common/database/src/androidMain/kotlin/com/shabinder/common/database/Actual.kt b/common/database/src/androidMain/kotlin/com/shabinder/common/database/Actual.kt
index 91515e53..72ff26e7 100644
--- a/common/database/src/androidMain/kotlin/com/shabinder/common/database/Actual.kt
+++ b/common/database/src/androidMain/kotlin/com/shabinder/common/database/Actual.kt
@@ -36,4 +36,4 @@ actual fun createDatabase(): Database? {
val driver = AndroidSqliteDriver(Database.Schema, appContext, "Database.db")
return Database(driver)
}
-actual fun getLogger(): Logger = LogcatLogger()
\ No newline at end of file
+actual fun getLogger(): Logger = LogcatLogger()
diff --git a/common/database/src/commonMain/kotlin/com/shabinder/common/database/Expect.kt b/common/database/src/commonMain/kotlin/com/shabinder/common/database/Expect.kt
index 1efdbc7c..20d36185 100644
--- a/common/database/src/commonMain/kotlin/com/shabinder/common/database/Expect.kt
+++ b/common/database/src/commonMain/kotlin/com/shabinder/common/database/Expect.kt
@@ -19,5 +19,5 @@ package com.shabinder.common.database
import co.touchlab.kermit.Logger
import com.shabinder.database.Database
-expect fun createDatabase() : Database?
-expect fun getLogger(): Logger
\ No newline at end of file
+expect fun createDatabase(): Database?
+expect fun getLogger(): Logger
diff --git a/common/database/src/desktopMain/kotlin/com/shabinder/common/database/Actual.kt b/common/database/src/desktopMain/kotlin/com/shabinder/common/database/Actual.kt
index 7bf40007..df6200aa 100644
--- a/common/database/src/desktopMain/kotlin/com/shabinder/common/database/Actual.kt
+++ b/common/database/src/desktopMain/kotlin/com/shabinder/common/database/Actual.kt
@@ -29,4 +29,4 @@ actual fun createDatabase(): Database? {
.also { Database.Schema.create(it) }
return Database(driver)
}
-actual fun getLogger(): Logger = CommonLogger()
\ No newline at end of file
+actual fun getLogger(): Logger = CommonLogger()
diff --git a/common/database/src/jsMain/kotlin/com/shabinder/common/database/Actual.kt b/common/database/src/jsMain/kotlin/com/shabinder/common/database/Actual.kt
index 87492a88..35871b53 100644
--- a/common/database/src/jsMain/kotlin/com/shabinder/common/database/Actual.kt
+++ b/common/database/src/jsMain/kotlin/com/shabinder/common/database/Actual.kt
@@ -21,4 +21,4 @@ import co.touchlab.kermit.Logger
import com.shabinder.database.Database
actual fun createDatabase(): Database? = null
-actual fun getLogger(): Logger = CommonLogger()
\ No newline at end of file
+actual fun getLogger(): Logger = CommonLogger()
diff --git a/common/dependency-injection/build.gradle.kts b/common/dependency-injection/build.gradle.kts
index f6223bf9..b3b2de94 100644
--- a/common/dependency-injection/build.gradle.kts
+++ b/common/dependency-injection/build.gradle.kts
@@ -44,7 +44,7 @@ kotlin {
}
}
androidMain {
- dependencies{
+ dependencies {
implementation(compose.materialIconsExtended)
implementation(Koin.android)
implementation(Ktor.clientAndroid)
@@ -52,11 +52,11 @@ kotlin {
implementation(Extras.Android.razorpay)
api(Extras.youtubeDownloader)
api(Extras.mp3agic)
- //api(files("$rootDir/libs/mobile-ffmpeg.aar"))
+ // api(files("$rootDir/libs/mobile-ffmpeg.aar"))
}
}
desktopMain {
- dependencies{
+ dependencies {
implementation(compose.materialIconsExtended)
implementation(Ktor.clientApache)
implementation(Ktor.slf4j)
@@ -68,9 +68,9 @@ kotlin {
dependencies {
implementation(project(":common:data-models"))
implementation(Ktor.clientJs)
- implementation(npm("browser-id3-writer","4.4.0"))
- implementation(npm("file-saver","2.0.4"))
- //implementation(npm("@types/file-saver","2.0.1",generateExternals = true))
+ implementation(npm("browser-id3-writer", "4.4.0"))
+ implementation(npm("file-saver", "2.0.4"))
+ // implementation(npm("@types/file-saver","2.0.1",generateExternals = true))
}
}
}
diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidActual.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidActual.kt
index ee1966db..3ec239c7 100644
--- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidActual.kt
+++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidActual.kt
@@ -32,7 +32,7 @@ import com.shabinder.common.models.TrackDetails
import kotlinx.coroutines.Dispatchers
import org.json.JSONObject
-actual fun openPlatform(packageID:String, platformLink:String){
+actual fun openPlatform(packageID: String, platformLink: String) {
val manager: PackageManager = activityContext.packageManager
try {
val intent = manager.getLaunchIntentForPackage(packageID)
@@ -49,10 +49,10 @@ actual fun openPlatform(packageID:String, platformLink:String){
actual val dispatcherIO = Dispatchers.IO
actual val currentPlatform: AllPlatforms = AllPlatforms.Jvm
-actual val isInternetAvailable:Boolean
+actual val isInternetAvailable: Boolean
get() = internetAvailability.value ?: true
-actual fun shareApp(){
+actual fun shareApp() {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "Hey, checkout this excellent Music Downloader http://github.com/Shabinder/SpotiFlyer")
@@ -78,18 +78,18 @@ private fun startPayment(mainActivity: Activity = activityContext as Activity) {
val preFill = JSONObject()
val options = JSONObject().apply {
- put("name","SpotiFlyer")
- put("description","Thanks For the Donation!")
- //You can omit the image option to fetch the image from dashboard
- //put("image","https://github.com/Shabinder/SpotiFlyer/raw/master/app/SpotifyDownload.png")
- put("currency","INR")
- put("amount","4900")
- put("prefill",preFill)
+ put("name", "SpotiFlyer")
+ put("description", "Thanks For the Donation!")
+ // You can omit the image option to fetch the image from dashboard
+ // put("image","https://github.com/Shabinder/SpotiFlyer/raw/master/app/SpotifyDownload.png")
+ put("currency", "INR")
+ put("amount", "4900")
+ put("prefill", preFill)
}
- co.open(mainActivity,options)
- }catch (e: Exception){
- //showPop("Error in payment: "+ e.message)
+ co.open(mainActivity, options)
+ } catch (e: Exception) {
+ // showPop("Error in payment: "+ e.message)
e.printStackTrace()
}
}
@@ -104,15 +104,15 @@ actual suspend fun downloadTracks(
list: List,
fetcher: FetchPlatformQueryResult,
dir: Dir
-){
- if(!list.isNullOrEmpty()){
+) {
+ if (!list.isNullOrEmpty()) {
val serviceIntent = Intent(activityContext, ForegroundService::class.java)
- serviceIntent.putParcelableArrayListExtra("object",ArrayList(list))
+ serviceIntent.putParcelableArrayListExtra("object", ArrayList(list))
activityContext.let { ContextCompat.startForegroundService(it, serviceIntent) }
}
}
-fun YoutubeVideo.getData(): Format?{
+fun YoutubeVideo.getData(): Format? {
return try {
findAudioWithQuality(AudioQuality.medium)?.get(0) as Format
} catch (e: java.lang.IndexOutOfBoundsException) {
@@ -126,4 +126,4 @@ fun YoutubeVideo.getData(): Format?{
}
}
}
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidDir.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidDir.kt
index c26a2735..492355c4 100644
--- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidDir.kt
+++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidDir.kt
@@ -21,7 +21,6 @@ import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaScannerConnection
import android.os.Environment
-import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import co.touchlab.kermit.Kermit
import com.mpatric.mp3agic.Mp3File
@@ -55,33 +54,28 @@ actual class Dir actual constructor(
@Suppress("DEPRECATION")
actual fun defaultDir(): String =
Environment.getExternalStorageDirectory().toString() + File.separator +
- Environment.DIRECTORY_MUSIC + File.separator +
- "SpotiFlyer"+ File.separator
+ Environment.DIRECTORY_MUSIC + File.separator +
+ "SpotiFlyer" + File.separator
actual fun isPresent(path: String): Boolean = File(path).exists()
actual fun createDirectory(dirPath: String) {
val yourAppDir = File(dirPath)
- if(!yourAppDir.exists() && !yourAppDir.isDirectory)
- { // create empty directory
- if (yourAppDir.mkdirs())
- {logger.i{"$dirPath created"}}
- else
- {
- logger.e{"Unable to create Dir: $dirPath!"}
+ if (!yourAppDir.exists() && !yourAppDir.isDirectory) { // create empty directory
+ if (yourAppDir.mkdirs()) { logger.i { "$dirPath created" } } else {
+ logger.e { "Unable to create Dir: $dirPath!" }
}
- }
- else {
+ } else {
logger.i { "$dirPath already exists" }
}
}
- actual suspend fun clearCache(){
+ actual suspend fun clearCache() {
File(imageCacheDir()).deleteRecursively()
}
- actual suspend fun cacheImage(image: Any,path:String) {
+ actual suspend fun cacheImage(image: Any, path: String) {
try {
FileOutputStream(path).use { out ->
(image as? Bitmap)?.compress(Bitmap.CompressFormat.JPEG, 100, out)
@@ -100,9 +94,9 @@ actual class Dir actual constructor(
/*
* Check , if Fetch was Used, File is saved Already, else write byteArray we Received
* */
- //if(!m4aFile.exists()) m4aFile.writeBytes(mp3ByteArray)
+ // if(!m4aFile.exists()) m4aFile.writeBytes(mp3ByteArray)
- when(trackDetails.outputFilePath.substringAfterLast('.')){
+ when (trackDetails.outputFilePath.substringAfterLast('.')) {
".mp3" -> {
Mp3File(File(songFile.absolutePath))
.removeAllTags()
@@ -136,22 +130,23 @@ actual class Dir actual constructor(
}*/
}
else -> {
- try{
+ try {
Mp3File(File(songFile.absolutePath))
.removeAllTags()
.setId3v1Tags(trackDetails)
.setId3v2TagsAndSaveFile(trackDetails)
addToLibrary(songFile.absolutePath)
- }catch (e:Exception){e.printStackTrace()}
+ } catch (e: Exception) { e.printStackTrace() }
}
}
}
- actual fun addToLibrary(path:String) {
- logger.d{"Scanning File"}
+ actual fun addToLibrary(path: String) {
+ logger.d { "Scanning File" }
MediaScannerConnection.scanFile(
appContext,
- listOf(path).toTypedArray(), null,null)
+ listOf(path).toTypedArray(), null, null
+ )
}
actual suspend fun loadImage(url: String): Picture {
@@ -167,7 +162,7 @@ actual class Dir actual constructor(
null
}
}
- private suspend fun freshImage(url:String): Bitmap?{
+ private suspend fun freshImage(url: String): Bitmap? {
return try {
val source = URL(url)
val connection: HttpURLConnection = source.openConnection() as HttpURLConnection
@@ -179,7 +174,7 @@ actual class Dir actual constructor(
if (result != null) {
GlobalScope.launch(Dispatchers.IO) {
- cacheImage(result,imageCacheDir() + getNameURL(url))
+ cacheImage(result, imageCacheDir() + getNameURL(url))
}
result
} else null
@@ -190,4 +185,4 @@ actual class Dir actual constructor(
}
actual val db: Database? = database
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidNetworkObserver.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidNetworkObserver.kt
index 815b0033..43935ab7 100644
--- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidNetworkObserver.kt
+++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidNetworkObserver.kt
@@ -24,7 +24,6 @@ import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
import android.net.NetworkRequest
import android.util.Log
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.lifecycle.LiveData
import com.shabinder.common.database.appContext
@@ -41,8 +40,8 @@ const val TAG = "C-Manager"
val internetAvailability by lazy { ConnectionLiveData(appContext) }
@Composable
-fun isInternetAvailableState(): State{
- return internetAvailability.observeAsState()
+fun isInternetAvailableState(): State {
+ return internetAvailability.observeAsState()
}
/**
@@ -83,17 +82,17 @@ class ConnectionLiveData(context: Context = appContext) : LiveData() {
Source: https://developer.android.com/reference/android/net/ConnectivityManager.NetworkCallback#onAvailable(android.net.Network)
*/
override fun onAvailable(network: Network) {
- Log.d(TAG, "onAvailable: ${network}")
+ Log.d(TAG, "onAvailable: $network")
val networkCapabilities = cm.getNetworkCapabilities(network)
val hasInternetCapability = networkCapabilities?.hasCapability(NET_CAPABILITY_INTERNET)
- Log.d(TAG, "onAvailable: ${network}, $hasInternetCapability")
+ Log.d(TAG, "onAvailable: $network, $hasInternetCapability")
if (hasInternetCapability == true) {
// check if this network actually has internet
CoroutineScope(Dispatchers.IO).launch {
val hasInternet = DoesNetworkHaveInternet.execute(network.socketFactory)
- if(hasInternet){
- withContext(Dispatchers.Main){
- Log.d(TAG, "onAvailable: adding network. ${network}")
+ if (hasInternet) {
+ withContext(Dispatchers.Main) {
+ Log.d(TAG, "onAvailable: adding network. $network")
validNetworks.add(network)
checkValidNetworks()
}
@@ -107,11 +106,10 @@ class ConnectionLiveData(context: Context = appContext) : LiveData() {
Source: https://developer.android.com/reference/android/net/ConnectivityManager.NetworkCallback#onLost(android.net.Network)
*/
override fun onLost(network: Network) {
- Log.d(TAG, "onLost: ${network}")
+ Log.d(TAG, "onLost: $network")
validNetworks.remove(network)
checkValidNetworks()
}
-
}
/**
@@ -122,17 +120,17 @@ class ConnectionLiveData(context: Context = appContext) : LiveData() {
// Make sure to execute this on a background thread.
fun execute(socketFactory: SocketFactory): Boolean {
- return try{
+ return try {
Log.d(TAG, "PINGING google.")
val socket = socketFactory.createSocket() ?: throw IOException("Socket is null.")
socket.connect(InetSocketAddress("8.8.8.8", 53), 1500)
socket.close()
Log.d(TAG, "PING success.")
true
- }catch (e: IOException){
+ } catch (e: IOException) {
Log.e(TAG, "No internet connection. $e")
false
}
}
}
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidPicture.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidPicture.kt
index 5db54e38..35b485a7 100644
--- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidPicture.kt
+++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/AndroidPicture.kt
@@ -18,6 +18,6 @@ package com.shabinder.common.di
import androidx.compose.ui.graphics.ImageBitmap
-actual data class Picture (
+actual data class Picture(
var image: ImageBitmap?
-)
\ No newline at end of file
+)
diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/ID3Tagging.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/ID3Tagging.kt
index 17ea7e4d..89cea5c7 100644
--- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/ID3Tagging.kt
+++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/ID3Tagging.kt
@@ -48,7 +48,7 @@ fun Mp3File.setId3v1Tags(track: TrackDetails): Mp3File {
}
@Suppress("BlockingMethodInNonBlockingContext")
-suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails){
+suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails) {
val id3v2Tag = ID3v24Tag().apply {
artist = track.artists.joinToString(",")
title = track.title
@@ -58,37 +58,37 @@ suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails){
lyrics = "Gonna Implement Soon"
url = track.trackUrl
}
- try{
+ try {
val art = File(track.albumArtPath)
val bytesArray = ByteArray(art.length().toInt())
val fis = FileInputStream(art)
- fis.read(bytesArray) //read file into bytes[]
+ fis.read(bytesArray) // read file into bytes[]
fis.close()
id3v2Tag.setAlbumImage(bytesArray, "image/jpeg")
this.id3v2Tag = id3v2Tag
saveFile(track.outputFilePath)
- }catch (e: java.io.FileNotFoundException){
+ } catch (e: java.io.FileNotFoundException) {
try {
- //Image Still Not Downloaded!
- //Lets Download Now and Write it into Album Art
+ // Image Still Not Downloaded!
+ // Lets Download Now and Write it into Album Art
downloadFile(track.albumArtURL).collect {
- when(it){
- is DownloadResult.Error -> {}//Error
+ when (it) {
+ is DownloadResult.Error -> {} // Error
is DownloadResult.Success -> {
id3v2Tag.setAlbumImage(it.byteArray, "image/jpeg")
this.id3v2Tag = id3v2Tag
saveFile(track.outputFilePath)
}
- is DownloadResult.Progress -> {}//Nothing for Now , no progress bar to show
+ is DownloadResult.Progress -> {} // Nothing for Now , no progress bar to show
}
}
- }catch (e: Exception){
- //log("Error", "Couldn't Write Mp3 Album Art, error: ${e.stackTrace}")
+ } catch (e: Exception) {
+ // log("Error", "Couldn't Write Mp3 Album Art, error: ${e.stackTrace}")
}
}
}
-fun Mp3File.saveFile(filePath: String){
+fun Mp3File.saveFile(filePath: String) {
save(filePath.substringBeforeLast('.') + ".new.mp3")
val m4aFile = File(filePath)
m4aFile.delete()
diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/LiveDataExt.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/LiveDataExt.kt
index ab6ab74a..2350f57c 100644
--- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/LiveDataExt.kt
+++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/LiveDataExt.kt
@@ -16,7 +16,11 @@
package com.shabinder.common.di
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.State
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
@@ -46,4 +50,4 @@ fun LiveData.observeAsState(initial: R): State {
onDispose { removeObserver(observer) }
}
return state
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt
index 20af782b..c026ed45 100644
--- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt
+++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt
@@ -23,7 +23,7 @@ import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.PlatformQueryResult
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.models.spotify.Source
-import io.ktor.client.*
+import io.ktor.client.HttpClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -31,7 +31,7 @@ actual class YoutubeProvider actual constructor(
private val httpClient: HttpClient,
private val logger: Kermit,
private val dir: Dir,
-){
+) {
val ytDownloader: YoutubeDownloader = YoutubeDownloader()
/*
* YT Album Art Schema
@@ -42,38 +42,38 @@ actual class YoutubeProvider actual constructor(
private val sampleDomain2 = "youtube.com"
private val sampleDomain3 = "youtu.be"
- actual suspend fun query(fullLink: String): PlatformQueryResult?{
+ actual suspend fun query(fullLink: String): PlatformQueryResult? {
val link = fullLink.removePrefix("https://").removePrefix("http://")
- if(link.contains("playlist",true) || link.contains("list",true)){
+ if (link.contains("playlist", true) || link.contains("list", true)) {
// Given Link is of a Playlist
- logger.i{ link }
+ logger.i { link }
val playlistId = link.substringAfter("?list=").substringAfter("&list=").substringBefore("&").substringBefore("?")
- return withContext(Dispatchers.IO){
+ return withContext(Dispatchers.IO) {
getYTPlaylist(
playlistId
)
}
- }else{//Given Link is of a Video
+ } else { // Given Link is of a Video
var searchId = "error"
- when{
- link.contains(sampleDomain1,true) -> {//Youtube Music
- searchId = link.substringAfterLast("/","error").substringBefore("&").substringAfterLast("=")
+ when {
+ link.contains(sampleDomain1, true) -> { // Youtube Music
+ searchId = link.substringAfterLast("/", "error").substringBefore("&").substringAfterLast("=")
}
- link.contains(sampleDomain2,true) -> {//Standard Youtube Link
- searchId = link.substringAfterLast("=","error").substringBefore("&")
+ link.contains(sampleDomain2, true) -> { // Standard Youtube Link
+ searchId = link.substringAfterLast("=", "error").substringBefore("&")
}
- link.contains(sampleDomain3,true) -> {//Shortened Youtube Link
- searchId = link.substringAfterLast("/","error").substringBefore("&")
+ link.contains(sampleDomain3, true) -> { // Shortened Youtube Link
+ searchId = link.substringAfterLast("/", "error").substringBefore("&")
}
}
- return if(searchId != "error") {
- withContext(Dispatchers.IO){
+ return if (searchId != "error") {
+ withContext(Dispatchers.IO) {
getYTTrack(
searchId
)
}
- }else{
- logger.d{"Your Youtube Link is not of a Video!!"}
+ } else {
+ logger.d { "Your Youtube Link is not of a Video!!" }
null
}
}
@@ -81,7 +81,7 @@ actual class YoutubeProvider actual constructor(
private suspend fun getYTPlaylist(
searchId: String
- ): PlatformQueryResult?{
+ ): PlatformQueryResult? {
val result = PlatformQueryResult(
folderType = "",
subFolder = "",
@@ -99,7 +99,7 @@ actual class YoutubeProvider actual constructor(
val videos = playlist.videos()
coverUrl = "https://i.ytimg.com/vi/${
- videos.firstOrNull()?.videoId()
+ videos.firstOrNull()?.videoId()
}/hqdefault.jpg"
title = name
@@ -113,11 +113,11 @@ actual class YoutubeProvider actual constructor(
albumArtURL = "https://i.ytimg.com/vi/${it.videoId()}/hqdefault.jpg",
downloaded = if (dir.isPresent(
dir.finalOutputDir(
- itemName = it.title(),
- type = folderType,
- subFolder = subFolder,
- dir.defaultDir()
- )
+ itemName = it.title(),
+ type = folderType,
+ subFolder = subFolder,
+ dir.defaultDir()
+ )
)
)
DownloadStatus.Downloaded
@@ -130,16 +130,16 @@ actual class YoutubeProvider actual constructor(
}
} catch (e: Exception) {
e.printStackTrace()
- logger.d{"An Error Occurred While Processing!"}
+ logger.d { "An Error Occurred While Processing!" }
}
}
- return if(result.title.isNotBlank()) result
+ return if (result.title.isNotBlank()) result
else null
}
@Suppress("DefaultLocale")
private suspend fun getYTTrack(
- searchId:String,
+ searchId: String,
): PlatformQueryResult? {
val result = PlatformQueryResult(
folderType = "",
@@ -148,15 +148,15 @@ actual class YoutubeProvider actual constructor(
coverUrl = "",
trackList = listOf(),
Source.YouTube
- ).apply{
+ ).apply {
try {
- logger.i{searchId}
+ logger.i { searchId }
val video = ytDownloader.getVideo(searchId)
coverUrl = "https://i.ytimg.com/vi/$searchId/hqdefault.jpg"
val detail = video?.details()
val name = detail?.title()?.replace(detail.author()!!.toUpperCase(), "", true)
?: detail?.title() ?: ""
- //logger.i{ detail.toString() }
+ // logger.i{ detail.toString() }
trackList = listOf(
TrackDetails(
title = name,
@@ -167,11 +167,11 @@ actual class YoutubeProvider actual constructor(
albumArtURL = "https://i.ytimg.com/vi/$searchId/hqdefault.jpg",
downloaded = if (dir.isPresent(
dir.finalOutputDir(
- itemName = name,
- type = folderType,
- subFolder = subFolder,
- defaultDir = dir.defaultDir()
- )
+ itemName = name,
+ type = folderType,
+ subFolder = subFolder,
+ defaultDir = dir.defaultDir()
+ )
)
)
DownloadStatus.Downloaded
@@ -185,10 +185,10 @@ actual class YoutubeProvider actual constructor(
title = name
} catch (e: Exception) {
e.printStackTrace()
- logger.e{"An Error Occurred While Processing!,$searchId"}
+ logger.e { "An Error Occurred While Processing!,$searchId" }
}
}
- return if(result.title.isNotBlank()) result
+ return if (result.title.isNotBlank()) result
else null
}
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/worker/ForegroundService.kt b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/worker/ForegroundService.kt
index 637c96a5..485e9634 100644
--- a/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/worker/ForegroundService.kt
+++ b/common/dependency-injection/src/androidMain/kotlin/com/shabinder/common/di/worker/ForegroundService.kt
@@ -17,15 +17,22 @@
package com.shabinder.common.di.worker
import android.annotation.SuppressLint
-import android.app.*
+import android.app.DownloadManager
import android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
import android.app.PendingIntent.FLAG_CANCEL_CURRENT
+import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
-import android.os.*
+import android.os.Build
+import android.os.IBinder
+import android.os.PowerManager
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
@@ -33,33 +40,43 @@ import androidx.core.net.toUri
import co.touchlab.kermit.Kermit
import com.github.kiulian.downloader.YoutubeDownloader
import com.github.kiulian.downloader.model.formats.Format
-import com.shabinder.common.database.R.*
import com.shabinder.common.di.Dir
import com.shabinder.common.di.FetchPlatformQueryResult
+import com.shabinder.common.di.R
import com.shabinder.common.di.getData
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails
-import com.tonyodev.fetch2.*
+import com.tonyodev.fetch2.Download
+import com.tonyodev.fetch2.Error
+import com.tonyodev.fetch2.Fetch
+import com.tonyodev.fetch2.FetchListener
+import com.tonyodev.fetch2.NetworkType
+import com.tonyodev.fetch2.Priority
+import com.tonyodev.fetch2.Request
+import com.tonyodev.fetch2.Status
import com.tonyodev.fetch2core.DownloadBlock
-import kotlinx.coroutines.*
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import java.io.File
-import java.util.*
import kotlin.coroutines.CoroutineContext
-class ForegroundService : Service(),CoroutineScope{
+class ForegroundService : Service(), CoroutineScope {
private val tag: String = "Foreground Service"
private val channelId = "ForegroundDownloaderService"
private val notificationId = 101
- private var total = 0 //Total Downloads Requested
- private var converted = 0//Total Files Converted
- private var downloaded = 0//Total Files downloaded
- private var failed = 0//Total Files failed
+ private var total = 0 // Total Downloads Requested
+ private var converted = 0 // Total Files Converted
+ private var downloaded = 0 // Total Files downloaded
+ private var failed = 0 // Total Files failed
private val isFinished: Boolean
get() = converted + failed == total
private var isSingleDownload: Boolean = false
- private lateinit var serviceJob :Job
+ private lateinit var serviceJob: Job
override val coroutineContext: CoroutineContext
get() = serviceJob + Dispatchers.IO
@@ -67,18 +84,17 @@ class ForegroundService : Service(),CoroutineScope{
private val allTracksStatus = hashMapOf()
private var wakeLock: PowerManager.WakeLock? = null
private var isServiceStarted = false
- private var messageList = mutableListOf("", "", "", "","")
- private lateinit var cancelIntent:PendingIntent
- private lateinit var downloadManager : DownloadManager
+ private var messageList = mutableListOf("", "", "", "", "")
+ private lateinit var cancelIntent: PendingIntent
+ private lateinit var downloadManager: DownloadManager
private val fetcher: FetchPlatformQueryResult by inject()
private val logger: Kermit by inject()
private val fetch: Fetch by inject()
private val dir: Dir by inject()
- private val ytDownloader:YoutubeDownloader
+ private val ytDownloader: YoutubeDownloader
get() = fetcher.youtubeProvider.ytDownloader
-
-
+
override fun onBind(intent: Intent): IBinder? = null
@SuppressLint("UnspecifiedImmutableFlag")
@@ -86,13 +102,13 @@ class ForegroundService : Service(),CoroutineScope{
super.onCreate()
serviceJob = SupervisorJob()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- createNotificationChannel(channelId,"Downloader Service")
+ createNotificationChannel(channelId, "Downloader Service")
}
val intent = Intent(
this,
ForegroundService::class.java
- ).apply{action = "kill"}
- cancelIntent = PendingIntent.getService (this, 0 , intent , FLAG_CANCEL_CURRENT )
+ ).apply { action = "kill" }
+ cancelIntent = PendingIntent.getService(this, 0, intent, FLAG_CANCEL_CURRENT)
downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
fetch.removeAllListeners().addListener(fetchListener)
}
@@ -100,16 +116,16 @@ class ForegroundService : Service(),CoroutineScope{
@SuppressLint("WakelockTimeout")
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// Send a notification that service is started
- Log.i(tag,"Foreground Service Started.")
+ Log.i(tag, "Foreground Service Started.")
startForeground(notificationId, getNotification())
- intent?.let{
+ intent?.let {
when (it.action) {
"kill" -> killService()
"query" -> {
val response = Intent().apply {
action = "query_result"
- synchronized(allTracksStatus){
+ synchronized(allTracksStatus) {
putExtra("tracks", allTracksStatus)
}
}
@@ -117,9 +133,11 @@ class ForegroundService : Service(),CoroutineScope{
}
}
- val downloadObjects: ArrayList? = (it.getParcelableArrayListExtra("object") ?: it.extras?.getParcelableArrayList(
- "object"
- ))
+ val downloadObjects: ArrayList? = (
+ it.getParcelableArrayListExtra("object") ?: it.extras?.getParcelableArrayList(
+ "object"
+ )
+ )
downloadObjects?.let { list ->
downloadObjects.size.let { size ->
@@ -133,13 +151,13 @@ class ForegroundService : Service(),CoroutineScope{
downloadAllTracks(list)
}
}
- //Wake locks and misc tasks from here :
- return if (isServiceStarted){
- //Service Already Started
+ // Wake locks and misc tasks from here :
+ return if (isServiceStarted) {
+ // Service Already Started
START_STICKY
- } else{
+ } else {
isServiceStarted = true
- Log.i(tag,"Starting the foreground service task")
+ Log.i(tag, "Starting the foreground service task")
wakeLock =
(getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "EndlessService::lock").apply {
@@ -156,56 +174,55 @@ class ForegroundService : Service(),CoroutineScope{
private fun downloadAllTracks(trackList: List) {
trackList.forEach {
launch {
- if (!it.videoID.isNullOrBlank()) {//Video ID already known!
+ if (!it.videoID.isNullOrBlank()) { // Video ID already known!
downloadTrack(it.videoID!!, it)
} else {
val searchQuery = "${it.title} - ${it.artists.joinToString(",")}"
- val videoID = fetcher.youtubeMusic.getYTIDBestMatch(searchQuery,it)
+ val videoID = fetcher.youtubeMusic.getYTIDBestMatch(searchQuery, it)
logger.d("Service VideoID") { videoID ?: "Not Found" }
if (videoID.isNullOrBlank()) {
sendTrackBroadcast(Status.FAILED.name, it)
failed++
updateNotification()
allTracksStatus[it.title] = DownloadStatus.Failed
- } else {//Found Youtube Video ID
+ } else { // Found Youtube Video ID
downloadTrack(videoID, it)
}
}
}
}
}
-
- private fun downloadTrack(videoID:String, track: TrackDetails){
+ private fun downloadTrack(videoID: String, track: TrackDetails) {
launch {
try {
val url = fetcher.youtubeMp3.getMp3DownloadLink(videoID)
- if (url == null){
- val audioData:Format = ytDownloader.getVideo(videoID).getData() ?: throw Exception("Java YT Dependency Error")
+ if (url == null) {
+ val audioData: Format = ytDownloader.getVideo(videoID).getData() ?: throw Exception("Java YT Dependency Error")
val ytUrl: String = audioData.url()
- enqueueDownload(ytUrl,track)
- } else enqueueDownload(url,track)
- }catch (e: Exception){
- logger.d("Service YT Error"){e.message.toString()}
- sendTrackBroadcast(Status.FAILED.name,track)
+ enqueueDownload(ytUrl, track)
+ } else enqueueDownload(url, track)
+ } catch (e: Exception) {
+ logger.d("Service YT Error") { e.message.toString() }
+ sendTrackBroadcast(Status.FAILED.name, track)
allTracksStatus[track.title] = DownloadStatus.Failed
}
}
}
-
- private fun enqueueDownload(url:String,track:TrackDetails){
- val request= Request(url, track.outputFilePath).apply{
+ private fun enqueueDownload(url: String, track: TrackDetails) {
+ val request = Request(url, track.outputFilePath).apply {
priority = Priority.NORMAL
networkType = NetworkType.ALL
}
- fetch.enqueue(request,
+ fetch.enqueue(
+ request,
{ request1 ->
requestMap[request1] = track
- logger.d(tag){"Enqueuing Download"}
+ logger.d(tag) { "Enqueuing Download" }
},
{ error ->
- logger.d(tag){"Enqueuing Error:${error.throwable.toString()}"}
+ logger.d(tag) { "Enqueuing Error:${error.throwable}" }
}
)
}
@@ -235,12 +252,12 @@ class ForegroundService : Service(),CoroutineScope{
totalBlocks: Int
) {
launch {
- val track = requestMap[download.request]
+ val track = requestMap[download.request]
addToNotification("Downloading ${track?.title}")
- logger.d(tag){"${track?.title} Download Started"}
- track?.let{
+ logger.d(tag) { "${track?.title} Download Started" }
+ track?.let {
allTracksStatus[it.title] = DownloadStatus.Downloading()
- sendTrackBroadcast(Status.DOWNLOADING.name,track)
+ sendTrackBroadcast(Status.DOWNLOADING.name, track)
}
}
}
@@ -259,25 +276,25 @@ class ForegroundService : Service(),CoroutineScope{
override fun onCompleted(download: Download) {
val track = requestMap[download.request]
- try{
+ try {
track?.let {
- val job = launch { dir.saveFileWithMetadata(byteArrayOf(),it) }
+ val job = launch { dir.saveFileWithMetadata(byteArrayOf(), it) }
allTracksStatus[it.title] = DownloadStatus.Converting
- sendTrackBroadcast("Converting",it)
+ sendTrackBroadcast("Converting", it)
addToNotification("Processing ${it.title}")
job.invokeOnCompletion { _ ->
converted++
allTracksStatus[it.title] = DownloadStatus.Downloaded
- sendTrackBroadcast(Status.COMPLETED.name,it)
+ sendTrackBroadcast(Status.COMPLETED.name, it)
removeFromNotification("Processing ${it.title}")
}
}
- logger.d(tag){"${track?.title} Download Completed"}
- }catch (
+ logger.d(tag) { "${track?.title} Download Completed" }
+ } catch (
e: KotlinNullPointerException
- ){
- logger.d(tag){"${track?.title} Download Failed! Error:Fetch!!!!"}
- logger.d(tag){"${track?.title} Requesting Download thru Android DM"}
+ ) {
+ logger.d(tag) { "${track?.title} Download Failed! Error:Fetch!!!!" }
+ logger.d(tag) { "${track?.title} Requesting Download thru Android DM" }
downloadUsingDM(download.request.url, download.request.file, track!!)
}
downloaded++
@@ -301,8 +318,8 @@ class ForegroundService : Service(),CoroutineScope{
launch {
val track = requestMap[download.request]
downloaded++
- logger.d(tag){download.error.throwable.toString()}
- logger.d(tag){"${track?.title} Requesting Download thru Android DM"}
+ logger.d(tag) { download.error.throwable.toString() }
+ logger.d(tag) { "${track?.title} Requesting Download thru Android DM" }
downloadUsingDM(download.request.url, download.request.file, track!!)
requestMap.remove(download.request)
removeFromNotification("Downloading ${track.title}")
@@ -322,8 +339,7 @@ class ForegroundService : Service(),CoroutineScope{
launch {
requestMap[download.request]?.run {
allTracksStatus[title] = DownloadStatus.Downloading(download.progress)
- logger.d(tag){"${title} ETA: ${etaInMilliSeconds / 1000} sec"}
-
+ logger.d(tag) { "$title ETA: ${etaInMilliSeconds / 1000} sec" }
val intent = Intent().apply {
action = "Progress"
@@ -337,15 +353,15 @@ class ForegroundService : Service(),CoroutineScope{
}
/**
- * If fetch Fails , Android Download Manager To RESCUE!!
- **/
- fun downloadUsingDM(url: String, outputDir: String, track: TrackDetails){
+ * If fetch Fails , Android Download Manager To RESCUE!!
+ **/
+ fun downloadUsingDM(url: String, outputDir: String, track: TrackDetails) {
launch {
val uri = Uri.parse(url)
val request = DownloadManager.Request(uri).apply {
setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI or
- DownloadManager.Request.NETWORK_MOBILE
+ DownloadManager.Request.NETWORK_MOBILE
)
setAllowedOverRoaming(false)
setTitle(track.title)
@@ -354,19 +370,19 @@ class ForegroundService : Service(),CoroutineScope{
setNotificationVisibility(VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
}
- //Start Download
+ // Start Download
val downloadID = downloadManager.enqueue(request)
- logger.d("DownloadManager"){"Download Request Sent"}
+ logger.d("DownloadManager") { "Download Request Sent" }
val onDownloadComplete: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
- //Fetching the download id received with the broadcast
+ // Fetching the download id received with the broadcast
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
- //Checking if the received broadcast is for our enqueued download by matching download id
+ // Checking if the received broadcast is for our enqueued download by matching download id
if (downloadID == id) {
allTracksStatus[track.title] = DownloadStatus.Converting
- launch { dir.saveFileWithMetadata(byteArrayOf(),track);converted++ }
- //Unregister this broadcast Receiver
+ launch { dir.saveFileWithMetadata(byteArrayOf(), track); converted++ }
+ // Unregister this broadcast Receiver
this@ForegroundService.unregisterReceiver(this)
}
}
@@ -375,8 +391,6 @@ class ForegroundService : Service(),CoroutineScope{
}
}
-
-
/**
* This is the method that can be called to update the Notification
*/
@@ -387,7 +401,7 @@ class ForegroundService : Service(),CoroutineScope{
}
private fun releaseWakeLock() {
- logger.d(tag){"Releasing Wake Lock"}
+ logger.d(tag) { "Releasing Wake Lock" }
try {
wakeLock?.let {
if (it.isHeld) {
@@ -395,14 +409,14 @@ class ForegroundService : Service(),CoroutineScope{
}
}
} catch (e: Exception) {
- logger.d(tag){"Service stopped without being started: ${e.message}"}
+ logger.d(tag) { "Service stopped without being started: ${e.message}" }
}
isServiceStarted = false
}
@Suppress("SameParameterValue")
@RequiresApi(Build.VERSION_CODES.O)
- private fun createNotificationChannel(channelId: String, channelName: String){
+ private fun createNotificationChannel(channelId: String, channelName: String) {
val channel = NotificationChannel(
channelId,
channelName, NotificationManager.IMPORTANCE_DEFAULT
@@ -416,15 +430,15 @@ class ForegroundService : Service(),CoroutineScope{
* Cleaning All Residual Files except Mp3 Files
**/
private fun cleanFiles(dir: File) {
- logger.d(tag){"Starting Cleaning in ${dir.path} "}
+ logger.d(tag) { "Starting Cleaning in ${dir.path} " }
val fList = dir.listFiles()
fList?.let {
for (file in fList) {
if (file.isDirectory) {
cleanFiles(file)
- } else if(file.isFile) {
- if(file.path.toString().substringAfterLast(".") != "mp3"){
- logger.d(tag){ "Cleaning ${file.path}"}
+ } else if (file.isFile) {
+ if (file.path.toString().substringAfterLast(".") != "mp3") {
+ logger.d(tag) { "Cleaning ${file.path}" }
file.delete()
}
}
@@ -433,41 +447,41 @@ class ForegroundService : Service(),CoroutineScope{
}
private fun killService() {
- launch{
- logger.d(tag){"Killing Self"}
- messageList = mutableListOf("Cleaning And Exiting","","","","")
+ launch {
+ logger.d(tag) { "Killing Self" }
+ messageList = mutableListOf("Cleaning And Exiting", "", "", "", "")
fetch.cancelAll()
fetch.removeAll()
updateNotification()
cleanFiles(File(dir.defaultDir()))
- //TODO cleanFiles(File(dir.imageCacheDir()))
- messageList = mutableListOf("","","","","")
+ // TODO cleanFiles(File(dir.imageCacheDir()))
+ messageList = mutableListOf("", "", "", "", "")
releaseWakeLock()
serviceJob.cancel()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
stopForeground(true)
} else {
- stopSelf()//System will automatically close it
+ stopSelf() // System will automatically close it
}
}
}
override fun onDestroy() {
super.onDestroy()
- if(isFinished){
+ if (isFinished) {
killService()
}
}
override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
- if(isFinished){
+ if (isFinished) {
killService()
}
}
- private fun getNotification():Notification = NotificationCompat.Builder(this, channelId).run {
- setSmallIcon(drawable.ic_download_arrow)
+ private fun getNotification(): Notification = NotificationCompat.Builder(this, channelId).run {
+ setSmallIcon(R.drawable.ic_download_arrow)
setContentTitle("Total: $total Completed:$converted Failed:$failed")
setSilent(true)
setStyle(
@@ -479,22 +493,22 @@ class ForegroundService : Service(),CoroutineScope{
addLine(messageList[messageList.size - 5])
}
)
- addAction(drawable.ic_round_cancel_24,"Exit",cancelIntent)
+ addAction(R.drawable.ic_round_cancel_24, "Exit", cancelIntent)
build()
}
- private fun addToNotification(message:String){
+ private fun addToNotification(message: String) {
messageList.add(message)
updateNotification()
}
- private fun removeFromNotification(message: String){
+ private fun removeFromNotification(message: String) {
messageList.remove(message)
updateNotification()
}
- fun sendTrackBroadcast(action:String,track:TrackDetails){
- val intent = Intent().apply{
+ fun sendTrackBroadcast(action: String, track: TrackDetails) {
+ val intent = Intent().apply {
setAction(action)
putExtra("track", track)
}
@@ -502,9 +516,9 @@ class ForegroundService : Service(),CoroutineScope{
}
}
-private fun Fetch.removeAllListeners():Fetch{
+private fun Fetch.removeAllListeners(): Fetch {
for (listener in this.getListenerSet()) {
this.removeListener(listener)
}
return this
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/DI.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/DI.kt
index 1a7eca55..837a054b 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/DI.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/DI.kt
@@ -23,10 +23,13 @@ import com.shabinder.common.di.providers.GaanaProvider
import com.shabinder.common.di.providers.SpotifyProvider
import com.shabinder.common.di.providers.YoutubeMp3
import com.shabinder.common.di.providers.YoutubeMusic
-import io.ktor.client.*
-import io.ktor.client.features.json.*
-import io.ktor.client.features.json.serializer.*
-import io.ktor.client.features.logging.*
+import io.ktor.client.HttpClient
+import io.ktor.client.features.json.JsonFeature
+import io.ktor.client.features.json.serializer.KotlinxSerializer
+import io.ktor.client.features.logging.DEFAULT
+import io.ktor.client.features.logging.LogLevel
+import io.ktor.client.features.logging.Logger
+import io.ktor.client.features.logging.Logging
import kotlinx.serialization.json.Json
import org.koin.core.context.startKoin
import org.koin.dsl.KoinAppDeclaration
@@ -40,23 +43,25 @@ fun initKoin(enableNetworkLogs: Boolean = false, appDeclaration: KoinAppDeclarat
fun commonModule(enableNetworkLogs: Boolean) = module {
single { createHttpClient(enableNetworkLogs = enableNetworkLogs) }
- single { Dir(get(),createDatabase()) }
+ single { Dir(get(), createDatabase()) }
single { Kermit(getLogger()) }
- single { TokenStore(get(),get()) }
- single { YoutubeMusic(get(),get()) }
- single { SpotifyProvider(get(),get(),get()) }
- single { GaanaProvider(get(),get(),get()) }
- single { YoutubeProvider(get(),get(),get()) }
- single { YoutubeMp3(get(),get(),get()) }
- single { FetchPlatformQueryResult(get(),get(),get(),get(),get(),get()) }
+ single { TokenStore(get(), get()) }
+ single { YoutubeMusic(get(), get()) }
+ single { SpotifyProvider(get(), get(), get()) }
+ single { GaanaProvider(get(), get(), get()) }
+ single { YoutubeProvider(get(), get(), get()) }
+ single { YoutubeMp3(get(), get(), get()) }
+ single { FetchPlatformQueryResult(get(), get(), get(), get(), get(), get()) }
}
-val kotlinxSerializer = KotlinxSerializer( Json {
- isLenient = true
- ignoreUnknownKeys = true
-})
+val kotlinxSerializer = KotlinxSerializer(
+ Json {
+ isLenient = true
+ ignoreUnknownKeys = true
+ }
+)
-fun createHttpClient(enableNetworkLogs: Boolean = false,serializer: KotlinxSerializer = kotlinxSerializer) = HttpClient {
+fun createHttpClient(enableNetworkLogs: Boolean = false, serializer: KotlinxSerializer = kotlinxSerializer) = HttpClient {
install(JsonFeature) {
this.serializer = serializer
}
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Dir.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Dir.kt
index 2dd32d61..0a6be2e7 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Dir.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Dir.kt
@@ -22,9 +22,10 @@ import com.shabinder.common.di.utils.removeIllegalChars
import com.shabinder.common.models.DownloadResult
import com.shabinder.common.models.TrackDetails
import com.shabinder.database.Database
-import io.ktor.client.request.*
-import io.ktor.client.statement.*
-import io.ktor.http.*
+import io.ktor.client.request.get
+import io.ktor.client.statement.HttpStatement
+import io.ktor.http.contentLength
+import io.ktor.http.isSuccess
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlin.math.roundToInt
@@ -33,17 +34,17 @@ expect class Dir(
logger: Kermit,
database: Database? = createDatabase()
) {
- val db :Database?
- fun isPresent(path:String):Boolean
+ val db: Database?
+ fun isPresent(path: String): Boolean
fun fileSeparator(): String
fun defaultDir(): String
fun imageCacheDir(): String
- fun createDirectory(dirPath:String)
- suspend fun cacheImage(image: Any,path: String) // in Android = ImageBitmap, Desktop = BufferedImage
- suspend fun loadImage(url:String): Picture
+ fun createDirectory(dirPath: String)
+ suspend fun cacheImage(image: Any, path: String) // in Android = ImageBitmap, Desktop = BufferedImage
+ suspend fun loadImage(url: String): Picture
suspend fun clearCache()
suspend fun saveFileWithMetadata(mp3ByteArray: ByteArray, trackDetails: TrackDetails)
- fun addToLibrary(path:String)
+ fun addToLibrary(path: String)
}
suspend fun downloadFile(url: String): Flow {
@@ -67,7 +68,7 @@ suspend fun downloadFile(url: String): Flow {
}
}
fun getNameURL(url: String): String {
- return url.substring(url.lastIndexOf('/',url.lastIndexOf('/')-1) + 1, url.length).replace('/','_')
+ return url.substring(url.lastIndexOf('/', url.lastIndexOf('/') - 1) + 1, url.length).replace('/', '_')
}
/*
* Call this function at startup!
@@ -80,7 +81,7 @@ fun Dir.createDirectories() {
createDirectory(defaultDir() + "Playlists/")
createDirectory(defaultDir() + "YT_Downloads/")
}
-fun Dir.finalOutputDir(itemName:String, type:String, subFolder:String, defaultDir:String, extension:String = ".mp3" ): String =
+fun Dir.finalOutputDir(itemName: String, type: String, subFolder: String, defaultDir: String, extension: String = ".mp3"): String =
defaultDir + removeIllegalChars(type) + this.fileSeparator() +
- if(subFolder.isEmpty())"" else { removeIllegalChars(subFolder) + this.fileSeparator()} +
- removeIllegalChars(itemName) + extension
+ if (subFolder.isEmpty())"" else { removeIllegalChars(subFolder) + this.fileSeparator() } +
+ removeIllegalChars(itemName) + extension
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Expect.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Expect.kt
index 13dbe1fc..2001575d 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Expect.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Expect.kt
@@ -20,7 +20,7 @@ import com.shabinder.common.models.AllPlatforms
import com.shabinder.common.models.TrackDetails
import kotlinx.coroutines.CoroutineDispatcher
-expect fun openPlatform(packageID:String, platformLink:String)
+expect fun openPlatform(packageID: String, platformLink: String)
expect fun shareApp()
@@ -28,7 +28,7 @@ expect fun giveDonation()
expect val dispatcherIO: CoroutineDispatcher
-expect val isInternetAvailable:Boolean
+expect val isInternetAvailable: Boolean
expect val currentPlatform: AllPlatforms
@@ -38,4 +38,4 @@ expect suspend fun downloadTracks(
dir: Dir
)
-expect fun queryActiveTracks()
\ No newline at end of file
+expect fun queryActiveTracks()
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/FetchPlatformQueryResult.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/FetchPlatformQueryResult.kt
index e1aff479..e1fba2a5 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/FetchPlatformQueryResult.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/FetchPlatformQueryResult.kt
@@ -22,33 +22,32 @@ import com.shabinder.common.di.providers.SpotifyProvider
import com.shabinder.common.di.providers.YoutubeMp3
import com.shabinder.common.di.providers.YoutubeMusic
import com.shabinder.common.models.PlatformQueryResult
-import com.shabinder.database.Database
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class FetchPlatformQueryResult(
private val gaanaProvider: GaanaProvider,
- val spotifyProvider: SpotifyProvider,
+ private val spotifyProvider: SpotifyProvider,
val youtubeProvider: YoutubeProvider,
val youtubeMusic: YoutubeMusic,
val youtubeMp3: YoutubeMp3,
private val dir: Dir
) {
- private val db:DownloadRecordDatabaseQueries?
+ private val db: DownloadRecordDatabaseQueries?
get() = dir.db?.downloadRecordDatabaseQueries
- suspend fun query(link:String): PlatformQueryResult?{
- val result = when{
- //SPOTIFY
- link.contains("spotify",true) ->
+ suspend fun query(link: String): PlatformQueryResult? {
+ val result = when {
+ // SPOTIFY
+ link.contains("spotify", true) ->
spotifyProvider.query(link)
- //YOUTUBE
- link.contains("youtube.com",true) || link.contains("youtu.be",true) ->
+ // YOUTUBE
+ link.contains("youtube.com", true) || link.contains("youtu.be", true) ->
youtubeProvider.query(link)
- //GAANA
- link.contains("gaana",true) ->
+ // GAANA
+ link.contains("gaana", true) ->
gaanaProvider.query(link)
else -> {
@@ -56,7 +55,7 @@ class FetchPlatformQueryResult(
}
}
result?.run {
- withContext(Dispatchers.Default){
+ withContext(Dispatchers.Default) {
db?.add(
folderType, title, link, coverUrl, trackList.size.toLong()
)
@@ -64,4 +63,4 @@ class FetchPlatformQueryResult(
}
return result
}
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Picture.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Picture.kt
index 39f5ef25..3e90c5d6 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Picture.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/Picture.kt
@@ -16,4 +16,4 @@
package com.shabinder.common.di
-expect class Picture
\ No newline at end of file
+expect class Picture
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/TokenStore.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/TokenStore.kt
index 4f31e1b9..0d139628 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/TokenStore.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/TokenStore.kt
@@ -31,21 +31,21 @@ class TokenStore(
private val db: TokenDBQueries?
get() = dir.db?.tokenDBQueries
- private fun save(token: TokenData){
- if(!token.access_token.isNullOrBlank() && token.expiry != null)
+ private fun save(token: TokenData) {
+ if (!token.access_token.isNullOrBlank() && token.expiry != null)
db?.add(token.access_token!!, token.expiry!! + Clock.System.now().epochSeconds)
}
suspend fun getToken(): TokenData? {
var token: TokenData? = db?.select()?.executeAsOneOrNull()?.let {
- TokenData(it.accessToken,null,it.expiry)
+ TokenData(it.accessToken, null, it.expiry)
}
- logger.d{"System Time:${Clock.System.now().epochSeconds} , Token Expiry:${token?.expiry}"}
- if(Clock.System.now().epochSeconds > token?.expiry ?:0 || token == null){
- logger.d{"Requesting New Token"}
+ logger.d { "System Time:${Clock.System.now().epochSeconds} , Token Expiry:${token?.expiry}" }
+ if (Clock.System.now().epochSeconds > token?.expiry ?: 0 || token == null) {
+ logger.d { "Requesting New Token" }
token = authenticateSpotify()
GlobalScope.launch { token?.access_token?.let { save(token) } }
}
return token
}
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt
index 7393e5d3..909946ee 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/YoutubeProvider.kt
@@ -18,8 +18,7 @@ package com.shabinder.common.di
import co.touchlab.kermit.Kermit
import com.shabinder.common.models.PlatformQueryResult
-import com.shabinder.database.Database
-import io.ktor.client.*
+import io.ktor.client.HttpClient
expect class YoutubeProvider(
httpClient: HttpClient,
@@ -27,4 +26,4 @@ expect class YoutubeProvider(
dir: Dir
) {
suspend fun query(fullLink: String): PlatformQueryResult?
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/gaana/GaanaRequests.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/gaana/GaanaRequests.kt
index a5901bf1..99a232af 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/gaana/GaanaRequests.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/gaana/GaanaRequests.kt
@@ -19,11 +19,15 @@ package com.shabinder.common.di.gaana
import com.shabinder.common.di.currentPlatform
import com.shabinder.common.models.AllPlatforms
import com.shabinder.common.models.corsProxy
-import com.shabinder.common.models.gaana.*
-import io.ktor.client.*
-import io.ktor.client.request.*
+import com.shabinder.common.models.gaana.GaanaAlbum
+import com.shabinder.common.models.gaana.GaanaArtistDetails
+import com.shabinder.common.models.gaana.GaanaArtistTracks
+import com.shabinder.common.models.gaana.GaanaPlaylist
+import com.shabinder.common.models.gaana.GaanaSong
+import io.ktor.client.HttpClient
+import io.ktor.client.request.get
-val corsApi get() = if(currentPlatform is AllPlatforms.Js){
+val corsApi get() = if (currentPlatform is AllPlatforms.Js) {
corsProxy.url
} // "https://spotiflyer-cors.azurewebsites.net/" //"https://spotiflyer-cors.herokuapp.com/"//"https://cors.bridged.cc/"
else ""
@@ -33,7 +37,7 @@ private val BASE_URL get() = "${corsApi}https://api.gaana.com"
interface GaanaRequests {
- val httpClient:HttpClient
+ val httpClient: HttpClient
/*
* Api Request: http://api.gaana.com/?type=playlist&subtype=playlist_detail&seokey=gaana-dj-hindi-top-50-1&token=b2e6d7fbc136547a940516e9b77e5990&format=JSON
@@ -117,4 +121,4 @@ interface GaanaRequests {
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
)
}
-}
\ No newline at end of file
+}
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/providers/GaanaProvider.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/providers/GaanaProvider.kt
index dd91a539..9bf63da0 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/providers/GaanaProvider.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/providers/GaanaProvider.kt
@@ -25,25 +25,25 @@ import com.shabinder.common.models.PlatformQueryResult
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.models.gaana.GaanaTrack
import com.shabinder.common.models.spotify.Source
-import io.ktor.client.*
+import io.ktor.client.HttpClient
class GaanaProvider(
override val httpClient: HttpClient,
private val logger: Kermit,
private val dir: Dir,
-): GaanaRequests {
+) : GaanaRequests {
private val gaanaPlaceholderImageUrl = "https://a10.gaanacdn.com/images/social/gaana_social.jpg"
- suspend fun query(fullLink: String): PlatformQueryResult?{
- //Link Schema: https://gaana.com/type/link
+ suspend fun query(fullLink: String): PlatformQueryResult? {
+ // Link Schema: https://gaana.com/type/link
val gaanaLink = fullLink.substringAfter("gaana.com/")
val link = gaanaLink.substringAfterLast('/', "error")
val type = gaanaLink.substringBeforeLast('/', "error").substringAfterLast('/')
- //Error
- if (type == "Error" || link == "Error"){
+ // Error
+ if (type == "Error" || link == "Error") {
return null
}
return gaanaSearch(
@@ -53,8 +53,8 @@ class GaanaProvider(
}
private suspend fun gaanaSearch(
- type:String,
- link:String,
+ type: String,
+ link: String,
): PlatformQueryResult {
val result = PlatformQueryResult(
folderType = "",
@@ -64,22 +64,14 @@ class GaanaProvider(
trackList = listOf(),
Source.Gaana
)
+ logger.i { "GAANA SEARCH: $type - $link" }
with(result) {
when (type) {
"song" -> {
getGaanaSong(seokey = link).tracks.firstOrNull()?.also {
folderType = "Tracks"
subFolder = ""
- if (dir.isPresent(
- dir.finalOutputDir(
- it.track_title,
- folderType,
- subFolder,
- dir.defaultDir()
- )
- )) {//Download Already Present!!
- it.downloaded = DownloadStatus.Downloaded
- }
+ it.updateStatusIfPresent(folderType, subFolder)
trackList = listOf(it).toTrackDetailsList(folderType, subFolder)
title = it.track_title
coverUrl = it.artworkLink
@@ -90,17 +82,7 @@ class GaanaProvider(
folderType = "Albums"
subFolder = link
it.tracks.forEach { track ->
- if (dir.isPresent(
- dir.finalOutputDir(
- track.track_title,
- folderType,
- subFolder,
- dir.defaultDir()
- )
- )
- ) {//Download Already Present!!
- track.downloaded = DownloadStatus.Downloaded
- }
+ track.updateStatusIfPresent(folderType, subFolder)
}
trackList = it.tracks.toTrackDetailsList(folderType, subFolder)
title = link
@@ -112,21 +94,11 @@ class GaanaProvider(
folderType = "Playlists"
subFolder = link
it.tracks.forEach { track ->
- if (dir.isPresent(
- dir.finalOutputDir(
- track.track_title,
- folderType,
- subFolder,
- dir.defaultDir()
- )
- )
- ) {//Download Already Present!!
- track.downloaded = DownloadStatus.Downloaded
- }
+ track.updateStatusIfPresent(folderType, subFolder)
}
trackList = it.tracks.toTrackDetailsList(folderType, subFolder)
title = link
- //coverUrl.value = "TODO"
+ // coverUrl.value = "TODO"
coverUrl = gaanaPlaceholderImageUrl
}
}
@@ -134,37 +106,27 @@ class GaanaProvider(
folderType = "Artist"
subFolder = link
coverUrl = gaanaPlaceholderImageUrl
- val artistDetails =
- getGaanaArtistDetails(seokey = link).artist.firstOrNull()
- ?.also {
- title = it.name
- coverUrl = it.artworkLink ?: gaanaPlaceholderImageUrl
- }
+ getGaanaArtistDetails(seokey = link).artist.firstOrNull()
+ ?.also {
+ title = it.name
+ coverUrl = it.artworkLink ?: gaanaPlaceholderImageUrl
+ }
getGaanaArtistTracks(seokey = link).also {
it.tracks?.forEach { track ->
- if (dir.isPresent(
- dir.finalOutputDir(
- track.track_title,
- folderType,
- subFolder,
- dir.defaultDir()
- )
- )
- ) {//Download Already Present!!
- track.downloaded = DownloadStatus.Downloaded
- }
+ track.updateStatusIfPresent(folderType, subFolder)
}
trackList = it.tracks?.toTrackDetailsList(folderType, subFolder) ?: emptyList()
}
}
- else -> {//TODO Handle Error}
+ else -> {
+ // TODO Handle Error
}
}
return result
}
}
- private fun List.toTrackDetailsList(type:String, subFolder:String) = this.map {
+ private fun List.toTrackDetailsList(type: String, subFolder: String) = this.map {
TrackDetails(
title = it.track_title,
artists = it.artist.map { artist -> artist?.name.toString() },
@@ -172,12 +134,25 @@ class GaanaProvider(
albumArtPath = dir.imageCacheDir() + (it.artworkLink.substringBeforeLast('/').substringAfterLast('/')) + ".jpeg",
albumName = it.album_title,
year = it.release_date,
- comment = "Genres:${it.genre?.map { genre -> genre?.name }?.reduceOrNull { acc, s -> acc + s }}",
+ comment = "Genres:${it.genre?.map { genre -> genre?.name }?.reduceOrNull { acc, s -> acc + s }}",
trackUrl = it.lyrics_url,
downloaded = it.downloaded ?: DownloadStatus.NotDownloaded,
source = Source.Gaana,
albumArtURL = it.artworkLink,
- outputFilePath = dir.finalOutputDir(it.track_title,type, subFolder,dir.defaultDir()/*,".m4a"*/)
+ outputFilePath = dir.finalOutputDir(it.track_title, type, subFolder, dir.defaultDir()/*,".m4a"*/)
)
}
+ private fun GaanaTrack.updateStatusIfPresent(folderType: String, subFolder: String) {
+ if (dir.isPresent(
+ dir.finalOutputDir(
+ track_title,
+ folderType,
+ subFolder,
+ dir.defaultDir()
+ )
+ )
+ ) { // Download Already Present!!
+ downloaded = DownloadStatus.Downloaded
+ }
+ }
}
diff --git a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/providers/SpotifyProvider.kt b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/providers/SpotifyProvider.kt
index d49a2a32..475f8a6d 100644
--- a/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/providers/SpotifyProvider.kt
+++ b/common/dependency-injection/src/commonMain/kotlin/com/shabinder/common/di/providers/SpotifyProvider.kt
@@ -17,7 +17,11 @@
package com.shabinder.common.di.providers
import co.touchlab.kermit.Kermit
-import com.shabinder.common.di.*
+import com.shabinder.common.di.Dir
+import com.shabinder.common.di.TokenStore
+import com.shabinder.common.di.currentPlatform
+import com.shabinder.common.di.finalOutputDir
+import com.shabinder.common.di.kotlinxSerializer
import com.shabinder.common.di.spotify.SpotifyRequests
import com.shabinder.common.di.spotify.authenticateSpotify
import com.shabinder.common.models.AllPlatforms
@@ -27,10 +31,10 @@ import com.shabinder.common.models.spotify.Album
import com.shabinder.common.models.spotify.Image
import com.shabinder.common.models.spotify.Source
import com.shabinder.common.models.spotify.Track
-import io.ktor.client.*
-import io.ktor.client.features.*
-import io.ktor.client.features.json.*
-import io.ktor.client.request.*
+import io.ktor.client.HttpClient
+import io.ktor.client.features.defaultRequest
+import io.ktor.client.features.json.JsonFeature
+import io.ktor.client.request.header
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@@ -44,23 +48,22 @@ class SpotifyProvider(
init {
logger.d { "Creating Spotify Provider" }
GlobalScope.launch(Dispatchers.Default) {
- if(currentPlatform is AllPlatforms.Js){
+ if (currentPlatform is AllPlatforms.Js) {
authenticateSpotifyClient(override = true)
- }else authenticateSpotifyClient()
+ } else authenticateSpotifyClient()
}
}
- override suspend fun authenticateSpotifyClient(override:Boolean): HttpClient?{
- val token = if(override) authenticateSpotify() else tokenStore.getToken()
- return if(token == null) {
- logger.d{ "Please Check your Network Connection" }
+ override suspend fun authenticateSpotifyClient(override: Boolean): HttpClient? {
+ val token = if (override) authenticateSpotify() else tokenStore.getToken()
+ return if (token == null) {
+ logger.d { "Please Check your Network Connection" }
null
- }
- else{
+ } else {
logger.d { "Spotify Provider Created with $token" }
httpClient = HttpClient {
defaultRequest {
- header("Authorization","Bearer ${token.access_token}")
+ header("Authorization", "Bearer ${token.access_token}")
}
install(JsonFeature) {
serializer = kotlinxSerializer
@@ -72,9 +75,9 @@ class SpotifyProvider(
override lateinit var httpClient: HttpClient
- suspend fun query(fullLink: String): PlatformQueryResult?{
+ suspend fun query(fullLink: String): PlatformQueryResult? {
- if(!this::httpClient.isInitialized){
+ if (!this::httpClient.isInitialized) {
authenticateSpotifyClient()
}
@@ -82,20 +85,19 @@ class SpotifyProvider(
"https://" + fullLink.substringAfterLast("https://").substringBefore(" ").trim()
if (!spotifyLink.contains("open.spotify")) {
- //Very Rare instance
+ // Very Rare instance
spotifyLink = resolveLink(spotifyLink)
}
val link = spotifyLink.substringAfterLast('/', "Error").substringBefore('?')
val type = spotifyLink.substringBeforeLast('/', "Error").substringAfterLast('/')
-
if (type == "Error" || link == "Error") {
return null
}
if (type == "episode" || type == "show") {
- //TODO Implementation
+ // TODO Implementation
return null
}
@@ -106,7 +108,7 @@ class SpotifyProvider(
}
private suspend fun spotifySearch(
- type:String,
+ type: String,
link: String
): PlatformQueryResult {
val result = PlatformQueryResult(
@@ -123,21 +125,13 @@ class SpotifyProvider(
getTrack(link).also {
folderType = "Tracks"
subFolder = ""
- if (dir.isPresent(
- dir.finalOutputDir(
- it.name.toString(),
- folderType,
- subFolder,
- dir.defaultDir()
- )
- )
- ) {//Download Already Present!!
- it.downloaded = com.shabinder.common.models.DownloadStatus.Downloaded
- }
+ it.updateStatusIfPresent(folderType, subFolder)
trackList = listOf(it).toTrackDetailsList(folderType, subFolder)
title = it.name.toString()
- coverUrl = (it.album?.images?.elementAtOrNull(1)?.url
- ?: it.album?.images?.elementAtOrNull(0)?.url).toString()
+ coverUrl = (
+ it.album?.images?.elementAtOrNull(1)?.url
+ ?: it.album?.images?.elementAtOrNull(0)?.url
+ ).toString()
}
}
@@ -146,17 +140,7 @@ class SpotifyProvider(
folderType = "Albums"
subFolder = albumObject.name.toString()
albumObject.tracks?.items?.forEach {
- if (dir.isPresent(
- dir.finalOutputDir(
- it.name.toString(),
- folderType,
- subFolder,
- dir.defaultDir()
- )
- )
- ) {//Download Already Present!!
- it.downloaded = com.shabinder.common.models.DownloadStatus.Downloaded
- }
+ it.updateStatusIfPresent(folderType, subFolder)
it.album = Album(
images = listOf(
Image(
@@ -168,12 +152,14 @@ class SpotifyProvider(
}
albumObject.tracks?.items?.toTrackDetailsList(folderType, subFolder).let {
if (it.isNullOrEmpty()) {
- //TODO Handle Error
+ // TODO Handle Error
} else {
trackList = it
title = albumObject.name.toString()
- coverUrl = (albumObject.images?.elementAtOrNull(1)?.url
- ?: albumObject.images?.elementAtOrNull(0)?.url).toString()
+ coverUrl = (
+ albumObject.images?.elementAtOrNull(1)?.url
+ ?: albumObject.images?.elementAtOrNull(0)?.url
+ ).toString()
}
}
}
@@ -183,27 +169,17 @@ class SpotifyProvider(
folderType = "Playlists"
subFolder = playlistObject.name.toString()
val tempTrackList = mutableListOf