mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-24 18:04:33 +01:00
Modular Structure
This commit is contained in:
parent
ec1402ef2e
commit
475a64cad5
@ -16,7 +16,7 @@ repositories {
|
|||||||
android {
|
android {
|
||||||
compileSdkVersion(29)
|
compileSdkVersion(29)
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.shabinder.android"
|
applicationId = "com.shabinder.spotiflyer"
|
||||||
minSdkVersion(Versions.minSdkVersion)
|
minSdkVersion(Versions.minSdkVersion)
|
||||||
targetSdkVersion(Versions.targetSdkVersion)
|
targetSdkVersion(Versions.targetSdkVersion)
|
||||||
versionCode = Versions.versionCode
|
versionCode = Versions.versionCode
|
||||||
@ -25,8 +25,8 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
getByName("release") {
|
getByName("release") {
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = true
|
||||||
//isShrinkResources = true
|
isShrinkResources = true
|
||||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,7 +63,8 @@ dependencies {
|
|||||||
implementation(Androidx.androidxActivity)
|
implementation(Androidx.androidxActivity)
|
||||||
|
|
||||||
implementation(project(":common:database"))
|
implementation(project(":common:database"))
|
||||||
implementation(project(":common:compose-ui"))
|
implementation(project(":common:compose"))
|
||||||
|
implementation(project(":common:root"))
|
||||||
implementation(project(":common:dependency-injection"))
|
implementation(project(":common:dependency-injection"))
|
||||||
implementation(project(":common:data-models"))
|
implementation(project(":common:data-models"))
|
||||||
|
|
||||||
@ -82,12 +83,6 @@ dependencies {
|
|||||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$it")
|
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$it")
|
||||||
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$it")
|
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$it")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Coil-Image Loading
|
|
||||||
Versions.coilVersion.let{
|
|
||||||
implementation("dev.chrisbanes.accompanist:accompanist-coil:$it")
|
|
||||||
implementation("dev.chrisbanes.accompanist:accompanist-insets:$it")
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Extras.Android.apply {
|
Extras.Android.apply {
|
||||||
@ -103,7 +98,7 @@ dependencies {
|
|||||||
implementation(Decompose.extensionsCompose)
|
implementation(Decompose.extensionsCompose)
|
||||||
|
|
||||||
//Test
|
//Test
|
||||||
testImplementation("junit:junit:4.13.1")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation(Androidx.junit)
|
androidTestImplementation(Androidx.junit)
|
||||||
androidTestImplementation(Androidx.expresso)
|
androidTestImplementation(Androidx.expresso)
|
||||||
|
|
||||||
|
18
android/proguard-rules.pro
vendored
18
android/proguard-rules.pro
vendored
@ -19,3 +19,21 @@
|
|||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
-keepattributes *Annotation*, InnerClasses
|
||||||
|
-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations
|
||||||
|
|
||||||
|
# kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer
|
||||||
|
-keepclassmembers class kotlinx.serialization.json.** {
|
||||||
|
*** Companion;
|
||||||
|
}
|
||||||
|
-keepclasseswithmembers class kotlinx.serialization.json.** {
|
||||||
|
kotlinx.serialization.KSerializer serializer(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep,includedescriptorclasses class com.shabinder.spotiflyer.**$$serializer { *; } # <-- change package name to your app's
|
||||||
|
-keepclassmembers class com.shabinder.spotiflyer.** { # <-- change package name to your app's
|
||||||
|
*** Companion;
|
||||||
|
}
|
||||||
|
-keepclasseswithmembers class com.shabinder.spotiflyer.** { # <-- change package name to your app's
|
||||||
|
kotlinx.serialization.KSerializer serializer(...);
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="com.shabinder.android">
|
package="com.shabinder.spotiflyer">
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<package android:name="com.gaana" />
|
<package android:name="com.gaana" />
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.shabinder.android
|
package com.shabinder.spotiflyer
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import com.shabinder.android.di.appModule
|
|
||||||
import com.shabinder.common.database.appContext
|
import com.shabinder.common.database.appContext
|
||||||
import com.shabinder.common.di.initKoin
|
import com.shabinder.common.di.initKoin
|
||||||
|
import com.shabinder.spotiflyer.di.appModule
|
||||||
import org.koin.android.ext.koin.androidContext
|
import org.koin.android.ext.koin.androidContext
|
||||||
import org.koin.android.ext.koin.androidLogger
|
import org.koin.android.ext.koin.androidLogger
|
||||||
import org.koin.core.KoinComponent
|
import org.koin.core.KoinComponent
|
@ -1,4 +1,4 @@
|
|||||||
package com.shabinder.android
|
package com.shabinder.spotiflyer
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
@ -12,37 +12,33 @@ import android.util.Log
|
|||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.arkivanov.decompose.ComponentContext
|
import com.arkivanov.decompose.ComponentContext
|
||||||
import com.arkivanov.decompose.extensions.compose.jetbrains.rootComponent
|
import com.arkivanov.decompose.extensions.compose.jetbrains.rememberRootComponent
|
||||||
import com.arkivanov.mvikotlin.logging.store.LoggingStoreFactory
|
import com.arkivanov.mvikotlin.logging.store.LoggingStoreFactory
|
||||||
import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
|
import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
|
||||||
import com.razorpay.Checkout
|
import com.razorpay.Checkout
|
||||||
import com.razorpay.PaymentResultListener
|
import com.razorpay.PaymentResultListener
|
||||||
import com.shabinder.android.utils.checkIfLatestVersion
|
|
||||||
import com.shabinder.android.utils.disableDozeMode
|
|
||||||
import com.shabinder.android.utils.requestStoragePermission
|
|
||||||
import com.shabinder.common.database.activityContext
|
import com.shabinder.common.database.activityContext
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
import com.shabinder.common.di.createDirectories
|
import com.shabinder.common.di.createDirectories
|
||||||
|
import com.shabinder.common.di.showPopUpMessage
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot
|
import com.shabinder.common.root.SpotiFlyerRoot
|
||||||
import com.shabinder.common.root.SpotiFlyerRootContent
|
|
||||||
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
||||||
import com.shabinder.common.ui.SpotiFlyerTheme
|
import com.shabinder.common.uikit.SpotiFlyerRootContent
|
||||||
import com.shabinder.common.ui.colorOffWhite
|
import com.shabinder.common.uikit.SpotiFlyerTheme
|
||||||
import com.shabinder.common.ui.showPopUpMessage
|
import com.shabinder.common.uikit.colorOffWhite
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
|
import com.shabinder.spotiflyer.utils.checkIfLatestVersion
|
||||||
|
import com.shabinder.spotiflyer.utils.disableDozeMode
|
||||||
|
import com.shabinder.spotiflyer.utils.requestStoragePermission
|
||||||
import com.tonyodev.fetch2.Status
|
import com.tonyodev.fetch2.Status
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
@ -81,7 +77,7 @@ class MainActivity : ComponentActivity(), PaymentResultListener {
|
|||||||
insets
|
insets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root = SpotiFlyerRootContent(rootComponent(::spotiFlyerRoot),statusBarHeight)
|
root = SpotiFlyerRootContent(rememberRootComponent(::spotiFlyerRoot),statusBarHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.shabinder.android.di
|
package com.shabinder.spotiflyer.di
|
||||||
|
|
||||||
import com.shabinder.common.database.appContext
|
import com.shabinder.common.database.appContext
|
||||||
import com.tonyodev.fetch2.Fetch
|
import com.tonyodev.fetch2.Fetch
|
@ -1,4 +1,4 @@
|
|||||||
package com.shabinder.android.utils
|
package com.shabinder.spotiflyer.utils
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
@ -12,7 +12,6 @@ import android.provider.Settings
|
|||||||
import com.github.javiersantos.appupdater.AppUpdater
|
import com.github.javiersantos.appupdater.AppUpdater
|
||||||
import com.github.javiersantos.appupdater.enums.Display
|
import com.github.javiersantos.appupdater.enums.Display
|
||||||
import com.github.javiersantos.appupdater.enums.UpdateFrom
|
import com.github.javiersantos.appupdater.enums.UpdateFrom
|
||||||
import com.tonyodev.fetch2.Fetch
|
|
||||||
|
|
||||||
fun Activity.checkIfLatestVersion() {
|
fun Activity.checkIfLatestVersion() {
|
||||||
AppUpdater(this,0).run {
|
AppUpdater(this,0).run {
|
@ -67,12 +67,12 @@ object JetBrains {
|
|||||||
|
|
||||||
object Compose {
|
object Compose {
|
||||||
// __LATEST_COMPOSE_RELEASE_VERSION__
|
// __LATEST_COMPOSE_RELEASE_VERSION__
|
||||||
const val VERSION = "0.3.0"
|
const val VERSION = "0.4.0-build168"
|
||||||
const val gradlePlugin = "org.jetbrains.compose:compose-gradle-plugin:$VERSION"
|
const val gradlePlugin = "org.jetbrains.compose:compose-gradle-plugin:$VERSION"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object Decompose {
|
object Decompose {
|
||||||
private const val VERSION = "0.1.8"
|
private const val VERSION = "0.1.9"
|
||||||
const val decompose = "com.arkivanov.decompose:decompose:$VERSION"
|
const val decompose = "com.arkivanov.decompose:decompose:$VERSION"
|
||||||
const val decomposeIosX64 = "com.arkivanov.decompose:decompose-iosx64:$VERSION"
|
const val decomposeIosX64 = "com.arkivanov.decompose:decompose-iosx64:$VERSION"
|
||||||
const val decomposeIosArm64 = "com.arkivanov.decompose:decompose-iosarm64:$VERSION"
|
const val decomposeIosArm64 = "com.arkivanov.decompose:decompose-iosarm64:$VERSION"
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import org.jetbrains.compose.compose
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.library")
|
id("com.android.library")
|
||||||
id("kotlin-multiplatform")
|
id("kotlin-multiplatform")
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package com.shabinder.common.ui
|
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.MutableState
|
|
||||||
import com.shabinder.common.database.appContext
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
|
|
||||||
actual val dispatcherIO = Dispatchers.IO
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
actual fun Toast(
|
|
||||||
text: String,
|
|
||||||
visibility: MutableState<Boolean>,
|
|
||||||
duration: ToastDuration
|
|
||||||
){
|
|
||||||
//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()
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package com.shabinder.common.ui
|
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
|
||||||
|
|
||||||
expect fun showPopUpMessage(text: String)
|
|
||||||
|
|
||||||
expect val dispatcherIO: CoroutineDispatcher
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2021 Shabinder Singh
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.shabinder.common.ui.utils
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draws a vertical gradient scrim in the foreground.
|
|
||||||
*
|
|
||||||
* @param color The color of the gradient scrim.
|
|
||||||
* @param startYPercentage The start y value, in percentage of the layout's height (0f to 1f)
|
|
||||||
* @param endYPercentage The end y value, in percentage of the layout's height (0f to 1f)
|
|
||||||
* @param decay The exponential decay to apply to the gradient. Defaults to `1.0f` which is
|
|
||||||
* a linear gradient.
|
|
||||||
* @param numStops The number of color stops to draw in the gradient. Higher numbers result in
|
|
||||||
* the higher visual quality at the cost of draw performance. Defaults to `16`.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
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,
|
|
||||||
decay: Float = 1.0f,
|
|
||||||
numStops: Int = 16,
|
|
||||||
fixedHeight: Float? = null
|
|
||||||
): Modifier = composed {
|
|
||||||
val colors = remember(color, numStops) {
|
|
||||||
if (decay != 1f) {
|
|
||||||
// If we have a non-linear decay, we need to create the color gradient steps
|
|
||||||
// manually
|
|
||||||
val baseAlpha = color.alpha
|
|
||||||
List(numStops) { i ->
|
|
||||||
val x = i * 1f / (numStops - 1)
|
|
||||||
val opacity = x.pow(decay)
|
|
||||||
color.copy(alpha = baseAlpha * opacity)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If we have a linear decay, we just create a simple list of start + end colors
|
|
||||||
listOf(color.copy(alpha = 0f), color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var height by remember { mutableStateOf(fixedHeight ?: 0f) }
|
|
||||||
val brush = remember(color, numStops, startYPercentage, endYPercentage, height) {
|
|
||||||
Brush.verticalGradient(
|
|
||||||
colors = colors,
|
|
||||||
startY = height * startYPercentage,
|
|
||||||
endY = height * endYPercentage
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
drawBehind {
|
|
||||||
height = fixedHeight ?: size.height
|
|
||||||
// log("Height",size.height.toString())
|
|
||||||
drawRect(brush = brush)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
26
common/compose/build.gradle.kts
Normal file
26
common/compose/build.gradle.kts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import org.jetbrains.compose.compose
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("multiplatform-compose-setup")
|
||||||
|
id("android-setup")
|
||||||
|
id("kotlin-parcelize")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
implementation(compose.materialIconsExtended)
|
||||||
|
implementation(project(":common:root"))
|
||||||
|
implementation(project(":common:main"))
|
||||||
|
implementation(project(":common:list"))
|
||||||
|
implementation(project(":common:database"))
|
||||||
|
implementation(project(":common:data-models"))
|
||||||
|
implementation(project(":common:dependency-injection"))
|
||||||
|
//DECOMPOSE
|
||||||
|
implementation(Decompose.decompose)
|
||||||
|
implementation(Decompose.extensionsCompose)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
@file:Suppress("FunctionName")
|
@file:Suppress("FunctionName")
|
||||||
|
|
||||||
package com.shabinder.common.ui
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
@ -12,6 +12,7 @@ import androidx.compose.ui.res.vectorResource
|
|||||||
import androidx.compose.ui.text.font.Font
|
import androidx.compose.ui.text.font.Font
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import com.shabinder.common.database.R
|
||||||
|
|
||||||
actual fun montserratFont() = FontFamily(
|
actual fun montserratFont() = FontFamily(
|
||||||
Font(R.font.montserrat_light, FontWeight.Light),
|
Font(R.font.montserrat_light, FontWeight.Light),
|
@ -14,7 +14,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.shabinder.common.ui
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.compose.material.darkColors
|
import androidx.compose.material.darkColors
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
@ -1,15 +1,14 @@
|
|||||||
@file:Suppress("FunctionName")
|
@file:Suppress("FunctionName")
|
||||||
package com.shabinder.common.ui
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.snap
|
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import com.shabinder.common.di.dispatcherIO
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@Composable
|
@Composable
|
@ -14,7 +14,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.shabinder.common.ui
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.Shapes
|
import androidx.compose.material.Shapes
|
@ -1,4 +1,4 @@
|
|||||||
package com.shabinder.common.list
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
@ -15,11 +15,9 @@ import androidx.compose.ui.text.style.TextAlign
|
|||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.shabinder.common.list.SpotiFlyerList
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.ui.*
|
|
||||||
import com.shabinder.common.ui.SpotiFlyerTypography
|
|
||||||
import com.shabinder.common.ui.colorAccent
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
||||||
@Composable
|
@Composable
|
@ -1,5 +1,6 @@
|
|||||||
package com.shabinder.common.main
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.foundation.*
|
import androidx.compose.foundation.*
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
@ -7,9 +8,7 @@ import androidx.compose.foundation.lazy.items
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.Icon
|
|
||||||
import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
|
import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
|
||||||
import androidx.compose.material.Text
|
|
||||||
import androidx.compose.material.TextFieldDefaults.textFieldColors
|
import androidx.compose.material.TextFieldDefaults.textFieldColors
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.History
|
import androidx.compose.material.icons.outlined.History
|
||||||
@ -23,17 +22,19 @@ import androidx.compose.ui.graphics.Brush
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.shabinder.common.di.giveDonation
|
import com.shabinder.common.di.giveDonation
|
||||||
import com.shabinder.common.models.DownloadRecord
|
|
||||||
import com.shabinder.common.main.SpotiFlyerMain.HomeCategory
|
|
||||||
import com.shabinder.common.di.openPlatform
|
import com.shabinder.common.di.openPlatform
|
||||||
import com.shabinder.common.di.shareApp
|
import com.shabinder.common.di.shareApp
|
||||||
import com.shabinder.common.ui.*
|
import com.shabinder.common.di.showPopUpMessage
|
||||||
import com.shabinder.common.ui.SpotiFlyerTypography
|
import com.shabinder.common.main.SpotiFlyerMain
|
||||||
|
import com.shabinder.common.main.SpotiFlyerMain.HomeCategory
|
||||||
|
import com.shabinder.common.models.DownloadRecord
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SpotiFlyerMainContent(component: SpotiFlyerMain){
|
fun SpotiFlyerMainContent(component: SpotiFlyerMain){
|
||||||
@ -129,7 +130,10 @@ fun SearchPanel(
|
|||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri),
|
||||||
modifier = modifier.padding(12.dp).fillMaxWidth()
|
modifier = modifier.padding(12.dp).fillMaxWidth()
|
||||||
.border(
|
.border(
|
||||||
BorderStroke(2.dp, Brush.horizontalGradient(listOf(colorPrimary, colorAccent))),
|
BorderStroke(2.dp, Brush.horizontalGradient(listOf(
|
||||||
|
colorPrimary,
|
||||||
|
colorAccent
|
||||||
|
))),
|
||||||
RoundedCornerShape(30.dp)
|
RoundedCornerShape(30.dp)
|
||||||
),
|
),
|
||||||
shape = RoundedCornerShape(size = 30.dp),
|
shape = RoundedCornerShape(size = 30.dp),
|
||||||
@ -148,7 +152,10 @@ fun SearchPanel(
|
|||||||
onSearch(link)
|
onSearch(link)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
border = BorderStroke(1.dp, Brush.horizontalGradient(listOf(colorPrimary, colorAccent)))
|
border = BorderStroke(1.dp, Brush.horizontalGradient(listOf(
|
||||||
|
colorPrimary,
|
||||||
|
colorAccent
|
||||||
|
)))
|
||||||
){
|
){
|
||||||
Text(text = "Search",style = SpotiFlyerTypography.h6,modifier = Modifier.padding(4.dp))
|
Text(text = "Search",style = SpotiFlyerTypography.h6,modifier = Modifier.padding(4.dp))
|
||||||
}
|
}
|
||||||
@ -299,19 +306,30 @@ fun HistoryColumn(
|
|||||||
loadImage:suspend (String)-> ImageBitmap?,
|
loadImage:suspend (String)-> ImageBitmap?,
|
||||||
onItemClicked: (String) -> Unit
|
onItemClicked: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
LazyColumn(
|
Crossfade(list){
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
if(it.isEmpty()){
|
||||||
content = {
|
Column(Modifier.padding(bottom = 32.dp).fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
items(list.distinctBy { it.coverUrl }) {
|
Icon(Icons.Outlined.Info,"No History Available Yet",modifier = Modifier.size(80.dp),
|
||||||
DownloadRecordItem(
|
colorOffWhite
|
||||||
item = it,
|
|
||||||
loadImage,
|
|
||||||
onItemClicked
|
|
||||||
)
|
)
|
||||||
|
Text("No History Available",style = SpotiFlyerTypography.h4.copy(fontWeight = FontWeight.Light),textAlign = TextAlign.Center)
|
||||||
}
|
}
|
||||||
},
|
}else{
|
||||||
modifier = Modifier.padding(top = 8.dp).fillMaxSize()
|
LazyColumn(
|
||||||
)
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
|
content = {
|
||||||
|
items(it.distinctBy {record -> record.coverUrl }) { record ->
|
||||||
|
DownloadRecordItem(
|
||||||
|
item = record,
|
||||||
|
loadImage,
|
||||||
|
onItemClicked
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier.padding(top = 8.dp).fillMaxSize()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -334,8 +352,8 @@ fun DownloadRecordItem(
|
|||||||
verticalAlignment = Alignment.Bottom,
|
verticalAlignment = Alignment.Bottom,
|
||||||
modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize()
|
modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize()
|
||||||
){
|
){
|
||||||
Text(item.type,fontSize = 13.sp)
|
Text(item.type,fontSize = 13.sp,color = colorOffWhite)
|
||||||
Text("Tracks: ${item.totalFiles}",fontSize = 13.sp)
|
Text("Tracks: ${item.totalFiles}",fontSize = 13.sp,color = colorOffWhite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Image(
|
Image(
|
@ -1,14 +1,16 @@
|
|||||||
package com.shabinder.common.root
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.compose.animation.core.*
|
import androidx.compose.animation.core.*
|
||||||
import androidx.compose.animation.core.Spring.StiffnessLow
|
import androidx.compose.animation.core.Spring.StiffnessLow
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.TopAppBar
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
@ -17,17 +19,14 @@ import androidx.compose.ui.platform.LocalViewConfiguration
|
|||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.arkivanov.decompose.extensions.compose.jetbrains.Children
|
import com.arkivanov.decompose.extensions.compose.jetbrains.Children
|
||||||
import com.shabinder.common.list.SpotiFlyerListContent
|
import com.shabinder.common.root.SpotiFlyerRoot
|
||||||
import com.shabinder.common.main.SpotiFlyerMainContent
|
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot.Child
|
import com.shabinder.common.root.SpotiFlyerRoot.Child
|
||||||
import com.shabinder.common.ui.SpotiFlyerLogo
|
import com.shabinder.common.uikit.splash.Splash
|
||||||
import com.shabinder.common.ui.appNameStyle
|
import com.shabinder.common.uikit.splash.SplashState
|
||||||
import com.shabinder.common.ui.colorPrimaryDark
|
import com.shabinder.common.uikit.utils.verticalGradientScrim
|
||||||
import com.shabinder.common.ui.splash.*
|
|
||||||
import com.shabinder.common.utils.verticalGradientScrim
|
|
||||||
|
|
||||||
@Composable
|
@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 transitionState = remember { MutableTransitionState(SplashState.Shown) }
|
||||||
val transition = updateTransition(transitionState)
|
val transition = updateTransition(transitionState)
|
@ -14,7 +14,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.shabinder.common.ui
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
@ -14,7 +14,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.shabinder.common.ui
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.compose.material.Typography
|
import androidx.compose.material.Typography
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
@ -14,7 +14,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.shabinder.common.ui.splash
|
package com.shabinder.common.uikit.splash
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
@ -29,7 +29,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.shabinder.common.ui.*
|
import com.shabinder.common.uikit.*
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
private const val SplashWaitTime: Long = 2000
|
private const val SplashWaitTime: Long = 2000
|
@ -14,7 +14,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.shabinder.common.ui.utils
|
package com.shabinder.common.uikit.utils
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -14,7 +14,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.shabinder.common.utils
|
package com.shabinder.common.uikit.utils
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
@ -1,5 +1,5 @@
|
|||||||
@file:Suppress("FunctionName")
|
@file:Suppress("FunctionName")
|
||||||
package com.shabinder.common.ui
|
package com.shabinder.common.uikit
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
@ -1,4 +1,4 @@
|
|||||||
package com.shabinder.common.utils
|
package com.shabinder.common.models
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback Utility
|
* Callback Utility
|
@ -4,15 +4,19 @@ import android.app.Activity
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.github.kiulian.downloader.model.YoutubeVideo
|
import com.github.kiulian.downloader.model.YoutubeVideo
|
||||||
import com.github.kiulian.downloader.model.formats.Format
|
import com.github.kiulian.downloader.model.formats.Format
|
||||||
import com.github.kiulian.downloader.model.quality.AudioQuality
|
import com.github.kiulian.downloader.model.quality.AudioQuality
|
||||||
import com.razorpay.Checkout
|
import com.razorpay.Checkout
|
||||||
|
import com.shabinder.common.database.R
|
||||||
import com.shabinder.common.database.activityContext
|
import com.shabinder.common.database.activityContext
|
||||||
|
import com.shabinder.common.database.appContext
|
||||||
import com.shabinder.common.di.worker.ForegroundService
|
import com.shabinder.common.di.worker.ForegroundService
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.ui.R
|
import kotlinx.coroutines.Dispatchers
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
actual fun openPlatform(packageID:String, platformLink:String){
|
actual fun openPlatform(packageID:String, platformLink:String){
|
||||||
@ -29,7 +33,20 @@ actual fun openPlatform(packageID:String, platformLink:String){
|
|||||||
activityContext.startActivity(intent)
|
activityContext.startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
actual val dispatcherIO = Dispatchers.IO
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
actual fun Toast(
|
||||||
|
text: String,
|
||||||
|
visibility: MutableState<Boolean>,
|
||||||
|
duration: ToastDuration
|
||||||
|
){
|
||||||
|
//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 shareApp(){
|
actual fun shareApp(){
|
||||||
val sendIntent: Intent = Intent().apply {
|
val sendIntent: Intent = Intent().apply {
|
||||||
action = Intent.ACTION_SEND
|
action = Intent.ACTION_SEND
|
||||||
|
@ -9,14 +9,16 @@ import androidx.compose.ui.graphics.ImageBitmap
|
|||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.mpatric.mp3agic.Mp3File
|
import com.mpatric.mp3agic.Mp3File
|
||||||
import com.shabinder.common.models.TrackDetails
|
|
||||||
import com.shabinder.common.database.appContext
|
import com.shabinder.common.database.appContext
|
||||||
|
import com.shabinder.common.models.TrackDetails
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.*
|
import java.io.File
|
||||||
import java.lang.Exception
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ package com.shabinder.common.di
|
|||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.github.kiulian.downloader.YoutubeDownloader
|
import com.github.kiulian.downloader.YoutubeDownloader
|
||||||
|
import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
|
||||||
import com.shabinder.common.models.spotify.Source
|
import com.shabinder.common.models.spotify.Source
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
|
@ -33,12 +33,12 @@ import androidx.core.net.toUri
|
|||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.github.kiulian.downloader.YoutubeDownloader
|
import com.github.kiulian.downloader.YoutubeDownloader
|
||||||
import com.github.kiulian.downloader.model.formats.Format
|
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.Dir
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
import com.shabinder.common.di.getData
|
import com.shabinder.common.di.getData
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.ui.R.*
|
|
||||||
import com.tonyodev.fetch2.*
|
import com.tonyodev.fetch2.*
|
||||||
import com.tonyodev.fetch2core.DownloadBlock
|
import com.tonyodev.fetch2core.DownloadBlock
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
@ -2,13 +2,11 @@ package com.shabinder.common.di
|
|||||||
|
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.shabinder.common.di.providers.YoutubeMusic
|
|
||||||
import com.shabinder.common.models.DownloadResult
|
import com.shabinder.common.models.DownloadResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
import io.ktor.client.statement.*
|
import io.ktor.client.statement.*
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.shabinder.common.di
|
package com.shabinder.common.di
|
||||||
|
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
|
||||||
expect fun openPlatform(packageID:String, platformLink:String)
|
expect fun openPlatform(packageID:String, platformLink:String)
|
||||||
|
|
||||||
@ -8,6 +9,10 @@ expect fun shareApp()
|
|||||||
|
|
||||||
expect fun giveDonation()
|
expect fun giveDonation()
|
||||||
|
|
||||||
|
expect fun showPopUpMessage(text: String)
|
||||||
|
|
||||||
|
expect val dispatcherIO: CoroutineDispatcher
|
||||||
|
|
||||||
expect suspend fun downloadTracks(
|
expect suspend fun downloadTracks(
|
||||||
list: List<TrackDetails>,
|
list: List<TrackDetails>,
|
||||||
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package com.shabinder.common.di
|
package com.shabinder.common.di
|
||||||
|
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
|
||||||
import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
||||||
import com.shabinder.common.di.providers.GaanaProvider
|
import com.shabinder.common.di.providers.GaanaProvider
|
||||||
import com.shabinder.common.di.providers.SpotifyProvider
|
import com.shabinder.common.di.providers.SpotifyProvider
|
||||||
import com.shabinder.common.di.providers.YoutubeMp3
|
import com.shabinder.common.di.providers.YoutubeMp3
|
||||||
import com.shabinder.common.di.providers.YoutubeMusic
|
import com.shabinder.common.di.providers.YoutubeMusic
|
||||||
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.shabinder.common.ui
|
package com.shabinder.common.di
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
@ -2,8 +2,8 @@ package com.shabinder.common.di
|
|||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.shabinder.common.database.TokenDBQueries
|
import com.shabinder.common.database.TokenDBQueries
|
||||||
import com.shabinder.common.models.spotify.TokenData
|
|
||||||
import com.shabinder.common.di.spotify.authenticateSpotify
|
import com.shabinder.common.di.spotify.authenticateSpotify
|
||||||
|
import com.shabinder.common.models.spotify.TokenData
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -21,10 +21,10 @@ import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
|||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.finalOutputDir
|
import com.shabinder.common.di.finalOutputDir
|
||||||
import com.shabinder.common.di.gaana.GaanaRequests
|
import com.shabinder.common.di.gaana.GaanaRequests
|
||||||
import com.shabinder.common.models.gaana.GaanaTrack
|
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
|
import com.shabinder.common.models.gaana.GaanaTrack
|
||||||
import com.shabinder.common.models.spotify.Source
|
import com.shabinder.common.models.spotify.Source
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
@ -169,7 +169,7 @@ class GaanaProvider(
|
|||||||
subFolder = link
|
subFolder = link
|
||||||
coverUrl = gaanaPlaceholderImageUrl
|
coverUrl = gaanaPlaceholderImageUrl
|
||||||
val artistDetails =
|
val artistDetails =
|
||||||
getGaanaArtistDetails(seokey = link).artist?.firstOrNull()
|
getGaanaArtistDetails(seokey = link).artist.firstOrNull()
|
||||||
?.also {
|
?.also {
|
||||||
title = it.name
|
title = it.name
|
||||||
coverUrl = it.artworkLink ?: gaanaPlaceholderImageUrl
|
coverUrl = it.artworkLink ?: gaanaPlaceholderImageUrl
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.shabinder.common.di.providers
|
package com.shabinder.common.di.providers
|
||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import co.touchlab.kermit.Logger
|
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.models.YoutubeTrack
|
import com.shabinder.common.models.YoutubeTrack
|
||||||
import com.willowtreeapps.fuzzywuzzy.diffutils.FuzzySearch
|
import com.willowtreeapps.fuzzywuzzy.diffutils.FuzzySearch
|
||||||
|
@ -2,7 +2,6 @@ package com.shabinder.common.di.spotify
|
|||||||
|
|
||||||
import com.shabinder.common.di.kotlinxSerializer
|
import com.shabinder.common.di.kotlinxSerializer
|
||||||
import com.shabinder.common.models.spotify.TokenData
|
import com.shabinder.common.models.spotify.TokenData
|
||||||
import com.shabinder.database.Database
|
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
import io.ktor.client.features.auth.*
|
import io.ktor.client.features.auth.*
|
||||||
import io.ktor.client.features.auth.providers.*
|
import io.ktor.client.features.auth.providers.*
|
||||||
@ -10,7 +9,6 @@ import io.ktor.client.features.json.*
|
|||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
import io.ktor.client.request.forms.*
|
import io.ktor.client.request.forms.*
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
import kotlinx.datetime.Clock
|
|
||||||
|
|
||||||
suspend fun authenticateSpotify(): TokenData {
|
suspend fun authenticateSpotify(): TokenData {
|
||||||
return spotifyAuthClient.post("https://accounts.spotify.com/api/token"){
|
return spotifyAuthClient.post("https://accounts.spotify.com/api/token"){
|
||||||
|
@ -7,8 +7,8 @@ import com.github.kiulian.downloader.model.quality.AudioQuality
|
|||||||
import com.shabinder.common.models.DownloadResult
|
import com.shabinder.common.models.DownloadResult
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.flow.collect
|
||||||
|
|
||||||
actual fun openPlatform(packageID:String, platformLink:String){
|
actual fun openPlatform(packageID:String, platformLink:String){
|
||||||
//TODO
|
//TODO
|
||||||
|
@ -10,7 +10,10 @@ import kotlinx.coroutines.GlobalScope
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jetbrains.skija.Image
|
import org.jetbrains.skija.Image
|
||||||
import java.awt.image.BufferedImage
|
import java.awt.image.BufferedImage
|
||||||
import java.io.*
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import javax.imageio.ImageIO
|
import javax.imageio.ImageIO
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.shabinder.common.ui
|
package com.shabinder.common.di
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
@ -18,10 +18,10 @@ package com.shabinder.common.di
|
|||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import co.touchlab.kermit.Kermit
|
||||||
import com.github.kiulian.downloader.YoutubeDownloader
|
import com.github.kiulian.downloader.YoutubeDownloader
|
||||||
|
import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
|
||||||
import com.shabinder.common.models.spotify.Source
|
import com.shabinder.common.models.spotify.Source
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
<!--
|
|
||||||
~ Copyright (c) 2021 Shabinder Singh
|
|
||||||
~ This program is free software: you can redistribute it and/or modify
|
|
||||||
~ it under the terms of the GNU General Public License as published by
|
|
||||||
~ the Free Software Foundation, either version 3 of the License, or
|
|
||||||
~ (at your option) any later version.
|
|
||||||
~
|
|
||||||
~ This program is distributed in the hope that it will be useful,
|
|
||||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
~ GNU General Public License for more details.
|
|
||||||
~
|
|
||||||
~ You should have received a copy of the GNU General Public License
|
|
||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24"
|
|
||||||
android:tint="?attr/colorControlNormal">
|
|
||||||
<path
|
|
||||||
android:fillColor="@android:color/white"
|
|
||||||
android:pathData="M12,4c4.41,0 8,3.59 8,8s-3.59,8 -8,8s-8,-3.59 -8,-8S7.59,4 12,4M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2L12,2zM13,12l0,-4h-2l0,4H8l4,4l4,-4H13z"/>
|
|
||||||
</vector>
|
|
@ -1,26 +0,0 @@
|
|||||||
<!--
|
|
||||||
~ Copyright (c) 2021 Shabinder Singh
|
|
||||||
~ This program is free software: you can redistribute it and/or modify
|
|
||||||
~ it under the terms of the GNU General Public License as published by
|
|
||||||
~ the Free Software Foundation, either version 3 of the License, or
|
|
||||||
~ (at your option) any later version.
|
|
||||||
~
|
|
||||||
~ This program is distributed in the hope that it will be useful,
|
|
||||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
~ GNU General Public License for more details.
|
|
||||||
~
|
|
||||||
~ You should have received a copy of the GNU General Public License
|
|
||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24"
|
|
||||||
android:tint="?attr/colorControlNormal">
|
|
||||||
<path
|
|
||||||
android:fillColor="@android:color/white"
|
|
||||||
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM16.3,16.3c-0.39,0.39 -1.02,0.39 -1.41,0L12,13.41 9.11,16.3c-0.39,0.39 -1.02,0.39 -1.41,0 -0.39,-0.39 -0.39,-1.02 0,-1.41L10.59,12 7.7,9.11c-0.39,-0.39 -0.39,-1.02 0,-1.41 0.39,-0.39 1.02,-0.39 1.41,0L12,10.59l2.89,-2.89c0.39,-0.39 1.02,-0.39 1.41,0 0.39,0.39 0.39,1.02 0,1.41L13.41,12l2.89,2.89c0.38,0.38 0.38,1.02 0,1.41z"/>
|
|
||||||
</vector>
|
|
@ -1,47 +0,0 @@
|
|||||||
<!--
|
|
||||||
~ Copyright (c) 2021 Shabinder Singh
|
|
||||||
~ This program is free software: you can redistribute it and/or modify
|
|
||||||
~ it under the terms of the GNU General Public License as published by
|
|
||||||
~ the Free Software Foundation, either version 3 of the License, or
|
|
||||||
~ (at your option) any later version.
|
|
||||||
~
|
|
||||||
~ This program is distributed in the hope that it will be useful,
|
|
||||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
~ GNU General Public License for more details.
|
|
||||||
~
|
|
||||||
~ You should have received a copy of the GNU General Public License
|
|
||||||
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<vector android:height="150dp" android:viewportHeight="512"
|
|
||||||
android:viewportWidth="512" android:width="150dp"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:pathData="M256,256m-256,0a256,256 0,1 1,512 0a256,256 0,1 1,-512 0">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient android:endX="437.019" android:endY="74.981"
|
|
||||||
android:startX="74.981" android:startY="437.019" android:type="linear">
|
|
||||||
<item android:color="#FF736BFD" android:offset="0"/>
|
|
||||||
<item android:color="#FFF54187" android:offset="1"/>
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M377,356.7c-68.9,-45.4 -155.6,-56.4 -257.6,-32.7c-20.5,4.8 -13.6,35.8 7.3,31.2C290.7,317 351.6,386 368.2,386C384,386 390.2,365.4 377,356.7z"/>
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M112.1,275.1C203.9,253.4 308.1,266 384,308c18.5,10.2 34,-17.8 15.5,-28c-82.7,-45.7 -195.6,-59.5 -294.7,-36C84.2,248.8 91.5,280 112.1,275.1L112.1,275.1z"/>
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M100,191.9c96.6,-29.6 232.2,-13.4 308.7,36.9c17.6,11.5 35.3,-15.1 17.6,-26.7c-84.9,-55.8 -229.2,-73.3 -335.6,-40.8C70.4,167.5 79.9,198.1 100,191.9L100,191.9z"/>
|
|
||||||
<path android:pathData="M507.8,438.2c-1.6,97.2 -141.9,97.1 -143.5,0C365.9,341 506.2,341 507.8,438.2z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient android:endX="384.197" android:endY="490.009"
|
|
||||||
android:startX="487.832" android:startY="386.374" android:type="linear">
|
|
||||||
<item android:color="#FF736BFD" android:offset="0"/>
|
|
||||||
<item android:color="#FFF54187" android:offset="1"/>
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path android:fillColor="#FF000000"
|
|
||||||
android:pathData="M486.8,456.8c-0.6,-2.4 -6.9,-1 -8.5,-1.4c11.5,-82 -82.4,-86.7 -87.1,-22.2c0.3,1.8 -1,6.7 2.2,6.6c0,0 8.6,0 8.6,0c3.1,0.1 2,-4.7 2.2,-6.6c0.1,-23.3 35,-23.3 35.2,0c0,0 0,6.9 0,6.9c-0.1,2.8 4.4,2.8 4.3,0c5,-35.2 -43.8,-40.1 -43.8,-4.7h-4.3c-1.6,-53.7 77.2,-55.9 78.4,-2.2c0,0 0,24.4 0,24.4c-0.1,2.9 3.8,2.1 5.6,2.2l-20.7,21l-20.7,-21c1.8,-0.1 5.6,0.7 5.6,-2.2c0,0 0,-8.8 0,-8.8c0,-2.8 -4.4,-2.8 -4.3,0c0,0 0,6.6 0,6.6c-2.2,0.2 -11.3,-1.3 -8,3.7c0,0 25.9,26.3 25.9,26.3c0.8,0.9 2.2,0.9 3.1,0C460.6,484.4 489.4,458.3 486.8,456.8z"
|
|
||||||
android:strokeColor="#000" android:strokeWidth=".75"/>
|
|
||||||
<path android:fillColor="#00000000"
|
|
||||||
android:pathData="M510,437.5c-1.7,96.2 -142.1,96.2 -143.8,0C367.9,341.3 508.4,341.3 510,437.5z"
|
|
||||||
android:strokeColor="#000" android:strokeWidth="6"/>
|
|
||||||
</vector>
|
|
22
common/list/build.gradle.kts
Normal file
22
common/list/build.gradle.kts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
plugins {
|
||||||
|
id("multiplatform-compose-setup")
|
||||||
|
id("android-setup")
|
||||||
|
id("kotlin-parcelize")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":common:dependency-injection"))
|
||||||
|
implementation(project(":common:data-models"))
|
||||||
|
implementation(project(":common:database"))
|
||||||
|
implementation(SqlDelight.coroutineExtensions)
|
||||||
|
implementation(MVIKotlin.coroutines)
|
||||||
|
implementation(MVIKotlin.mvikotlin)
|
||||||
|
implementation(Decompose.decompose)
|
||||||
|
implementation(Decompose.extensionsCompose)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
common/list/src/androidMain/AndroidManifest.xml
Normal file
2
common/list/src/androidMain/AndroidManifest.xml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="com.shabinder.common.ui"/>
|
@ -1,21 +1,17 @@
|
|||||||
package com.shabinder.common.list
|
package com.shabinder.common.list
|
||||||
|
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import com.arkivanov.decompose.ComponentContext
|
import com.arkivanov.decompose.ComponentContext
|
||||||
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||||
import com.shabinder.common.list.integration.SpotiFlyerListImpl
|
import com.shabinder.common.list.integration.SpotiFlyerListImpl
|
||||||
|
import com.shabinder.common.models.Consumer
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.spotify.Source
|
|
||||||
import com.shabinder.common.utils.Consumer
|
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
|
|
||||||
interface SpotiFlyerList {
|
interface SpotiFlyerList {
|
||||||
|
|
@ -3,13 +3,13 @@ package com.shabinder.common.list.integration
|
|||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import com.arkivanov.decompose.ComponentContext
|
import com.arkivanov.decompose.ComponentContext
|
||||||
import com.arkivanov.mvikotlin.extensions.coroutines.states
|
import com.arkivanov.mvikotlin.extensions.coroutines.states
|
||||||
import com.shabinder.common.models.TrackDetails
|
|
||||||
import com.shabinder.common.list.SpotiFlyerList
|
import com.shabinder.common.list.SpotiFlyerList
|
||||||
import com.shabinder.common.list.SpotiFlyerList.Dependencies
|
import com.shabinder.common.list.SpotiFlyerList.Dependencies
|
||||||
import com.shabinder.common.list.SpotiFlyerList.State
|
import com.shabinder.common.list.SpotiFlyerList.State
|
||||||
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
||||||
import com.shabinder.common.list.store.SpotiFlyerListStoreProvider
|
import com.shabinder.common.list.store.SpotiFlyerListStoreProvider
|
||||||
import com.shabinder.common.utils.getStore
|
import com.shabinder.common.list.store.getStore
|
||||||
|
import com.shabinder.common.models.TrackDetails
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
internal class SpotiFlyerListImpl(
|
internal class SpotiFlyerListImpl(
|
@ -1,4 +1,4 @@
|
|||||||
package com.shabinder.common.utils
|
package com.shabinder.common.list.store
|
||||||
|
|
||||||
import com.arkivanov.decompose.instancekeeper.InstanceKeeper
|
import com.arkivanov.decompose.instancekeeper.InstanceKeeper
|
||||||
import com.arkivanov.decompose.instancekeeper.getOrCreate
|
import com.arkivanov.decompose.instancekeeper.getOrCreate
|
||||||
@ -8,7 +8,9 @@ fun <T : Store<*, *, *>> InstanceKeeper.getStore(key: Any, factory: () -> T): T
|
|||||||
getOrCreate(key) { StoreHolder(factory()) }
|
getOrCreate(key) { StoreHolder(factory()) }
|
||||||
.store
|
.store
|
||||||
|
|
||||||
inline fun <reified T : Store<*, *, *>> InstanceKeeper.getStore(noinline factory: () -> T): T =
|
inline fun <reified T
|
||||||
|
|
||||||
|
: Store<*, *, *>> InstanceKeeper.getStore(noinline factory: () -> T): T =
|
||||||
getStore(T::class, factory)
|
getStore(T::class, factory)
|
||||||
|
|
||||||
private class StoreHolder<T : Store<*, *, *>>(
|
private class StoreHolder<T : Store<*, *, *>>(
|
@ -1,9 +1,9 @@
|
|||||||
package com.shabinder.common.list.store
|
package com.shabinder.common.list.store
|
||||||
|
|
||||||
import com.arkivanov.mvikotlin.core.store.Store
|
import com.arkivanov.mvikotlin.core.store.Store
|
||||||
import com.shabinder.common.models.TrackDetails
|
|
||||||
import com.shabinder.common.list.SpotiFlyerList.State
|
import com.shabinder.common.list.SpotiFlyerList.State
|
||||||
import com.shabinder.common.list.store.SpotiFlyerListStore.*
|
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
||||||
|
import com.shabinder.common.models.TrackDetails
|
||||||
|
|
||||||
internal interface SpotiFlyerListStore: Store<Intent, State, Nothing> {
|
internal interface SpotiFlyerListStore: Store<Intent, State, Nothing> {
|
||||||
sealed class Intent {
|
sealed class Intent {
|
@ -3,16 +3,12 @@ package com.shabinder.common.list.store
|
|||||||
import com.arkivanov.mvikotlin.core.store.*
|
import com.arkivanov.mvikotlin.core.store.*
|
||||||
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
||||||
import com.shabinder.common.database.getLogger
|
import com.shabinder.common.database.getLogger
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.*
|
||||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
|
||||||
import com.shabinder.common.di.downloadTracks
|
|
||||||
import com.shabinder.common.di.queryActiveTracks
|
|
||||||
import com.shabinder.common.list.SpotiFlyerList.State
|
import com.shabinder.common.list.SpotiFlyerList.State
|
||||||
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.models.PlatformQueryResult
|
import com.shabinder.common.models.PlatformQueryResult
|
||||||
import com.shabinder.common.models.TrackDetails
|
import com.shabinder.common.models.TrackDetails
|
||||||
import com.shabinder.common.ui.showPopUpMessage
|
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
|
2
common/main/src/androidMain/AndroidManifest.xml
Normal file
2
common/main/src/androidMain/AndroidManifest.xml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="com.shabinder.common.ui"/>
|
@ -4,9 +4,9 @@ import androidx.compose.ui.graphics.ImageBitmap
|
|||||||
import com.arkivanov.decompose.ComponentContext
|
import com.arkivanov.decompose.ComponentContext
|
||||||
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.models.DownloadRecord
|
|
||||||
import com.shabinder.common.main.integration.SpotiFlyerMainImpl
|
import com.shabinder.common.main.integration.SpotiFlyerMainImpl
|
||||||
import com.shabinder.common.utils.Consumer
|
import com.shabinder.common.models.Consumer
|
||||||
|
import com.shabinder.common.models.DownloadRecord
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
@ -7,7 +7,7 @@ import com.shabinder.common.main.SpotiFlyerMain
|
|||||||
import com.shabinder.common.main.SpotiFlyerMain.*
|
import com.shabinder.common.main.SpotiFlyerMain.*
|
||||||
import com.shabinder.common.main.store.SpotiFlyerMainStore.Intent
|
import com.shabinder.common.main.store.SpotiFlyerMainStore.Intent
|
||||||
import com.shabinder.common.main.store.SpotiFlyerMainStoreProvider
|
import com.shabinder.common.main.store.SpotiFlyerMainStoreProvider
|
||||||
import com.shabinder.common.utils.getStore
|
import com.shabinder.common.main.store.getStore
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
internal class SpotiFlyerMainImpl(
|
internal class SpotiFlyerMainImpl(
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.shabinder.common.main.store
|
||||||
|
|
||||||
|
import com.arkivanov.decompose.instancekeeper.InstanceKeeper
|
||||||
|
import com.arkivanov.decompose.instancekeeper.getOrCreate
|
||||||
|
import com.arkivanov.mvikotlin.core.store.Store
|
||||||
|
|
||||||
|
fun <T : Store<*, *, *>> InstanceKeeper.getStore(key: Any, factory: () -> T): T =
|
||||||
|
getOrCreate(key) { StoreHolder(factory()) }
|
||||||
|
.store
|
||||||
|
|
||||||
|
inline fun <reified T
|
||||||
|
|
||||||
|
: Store<*, *, *>> InstanceKeeper.getStore(noinline factory: () -> T): T =
|
||||||
|
getStore(T::class, factory)
|
||||||
|
|
||||||
|
private class StoreHolder<T : Store<*, *, *>>(
|
||||||
|
val store: T
|
||||||
|
) : InstanceKeeper.Instance {
|
||||||
|
override fun onDestroy() {
|
||||||
|
store.dispose()
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ package com.shabinder.common.main.store
|
|||||||
|
|
||||||
import com.arkivanov.mvikotlin.core.store.Store
|
import com.arkivanov.mvikotlin.core.store.Store
|
||||||
import com.shabinder.common.main.SpotiFlyerMain
|
import com.shabinder.common.main.SpotiFlyerMain
|
||||||
import com.shabinder.common.main.store.SpotiFlyerMainStore.*
|
import com.shabinder.common.main.store.SpotiFlyerMainStore.Intent
|
||||||
|
|
||||||
internal interface SpotiFlyerMainStore: Store<Intent, SpotiFlyerMain.State, Nothing> {
|
internal interface SpotiFlyerMainStore: Store<Intent, SpotiFlyerMain.State, Nothing> {
|
||||||
sealed class Intent {
|
sealed class Intent {
|
@ -5,13 +5,13 @@ import com.arkivanov.mvikotlin.core.store.SimpleBootstrapper
|
|||||||
import com.arkivanov.mvikotlin.core.store.Store
|
import com.arkivanov.mvikotlin.core.store.Store
|
||||||
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
import com.arkivanov.mvikotlin.core.store.StoreFactory
|
||||||
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
||||||
import com.shabinder.common.models.DownloadRecord
|
|
||||||
import com.shabinder.common.di.giveDonation
|
import com.shabinder.common.di.giveDonation
|
||||||
|
import com.shabinder.common.di.openPlatform
|
||||||
|
import com.shabinder.common.di.shareApp
|
||||||
import com.shabinder.common.main.SpotiFlyerMain
|
import com.shabinder.common.main.SpotiFlyerMain
|
||||||
import com.shabinder.common.main.SpotiFlyerMain.State
|
import com.shabinder.common.main.SpotiFlyerMain.State
|
||||||
import com.shabinder.common.main.store.SpotiFlyerMainStore.Intent
|
import com.shabinder.common.main.store.SpotiFlyerMainStore.Intent
|
||||||
import com.shabinder.common.di.openPlatform
|
import com.shabinder.common.models.DownloadRecord
|
||||||
import com.shabinder.common.di.shareApp
|
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import com.squareup.sqldelight.runtime.coroutines.asFlow
|
import com.squareup.sqldelight.runtime.coroutines.asFlow
|
||||||
import com.squareup.sqldelight.runtime.coroutines.mapToList
|
import com.squareup.sqldelight.runtime.coroutines.mapToList
|
28
common/root/build.gradle.kts
Normal file
28
common/root/build.gradle.kts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import org.jetbrains.compose.compose
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("multiplatform-compose-setup")
|
||||||
|
id("android-setup")
|
||||||
|
id("kotlin-parcelize")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
implementation(compose.materialIconsExtended)
|
||||||
|
implementation(project(":common:dependency-injection"))
|
||||||
|
//implementation("com.alialbaali.kamel:kamel-image:0.1.0")
|
||||||
|
implementation(project(":common:data-models"))
|
||||||
|
implementation(project(":common:database"))
|
||||||
|
implementation(project(":common:list"))
|
||||||
|
implementation(project(":common:main"))
|
||||||
|
implementation(SqlDelight.coroutineExtensions)
|
||||||
|
implementation(MVIKotlin.coroutines)
|
||||||
|
implementation(MVIKotlin.mvikotlin)
|
||||||
|
implementation(Decompose.decompose)
|
||||||
|
implementation(Decompose.extensionsCompose)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
common/root/src/androidMain/AndroidManifest.xml
Normal file
2
common/root/src/androidMain/AndroidManifest.xml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="com.shabinder.common.ui"/>
|
@ -11,11 +11,9 @@ import com.shabinder.common.main.SpotiFlyerMain
|
|||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.DownloadStatus
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot.Dependencies
|
import com.shabinder.common.root.SpotiFlyerRoot.Dependencies
|
||||||
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
||||||
import com.shabinder.database.Database
|
|
||||||
import com.shabinder.common.root.integration.SpotiFlyerRootImpl
|
import com.shabinder.common.root.integration.SpotiFlyerRootImpl
|
||||||
import com.shabinder.common.utils.Consumer
|
import com.shabinder.database.Database
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
|
|
||||||
interface SpotiFlyerRoot {
|
interface SpotiFlyerRoot {
|
||||||
|
|
@ -1,25 +1,17 @@
|
|||||||
package com.shabinder.common.root.integration
|
package com.shabinder.common.root.integration
|
||||||
|
|
||||||
import co.touchlab.kermit.Kermit
|
import com.arkivanov.decompose.*
|
||||||
import com.arkivanov.decompose.ComponentContext
|
|
||||||
import com.arkivanov.decompose.RouterState
|
|
||||||
import com.arkivanov.decompose.pop
|
|
||||||
import com.arkivanov.decompose.push
|
|
||||||
import com.arkivanov.decompose.router
|
|
||||||
import com.arkivanov.decompose.statekeeper.Parcelable
|
import com.arkivanov.decompose.statekeeper.Parcelable
|
||||||
import com.arkivanov.decompose.statekeeper.Parcelize
|
import com.arkivanov.decompose.statekeeper.Parcelize
|
||||||
import com.arkivanov.decompose.value.Value
|
import com.arkivanov.decompose.value.Value
|
||||||
import com.shabinder.common.database.getLogger
|
|
||||||
import com.shabinder.common.di.Dir
|
import com.shabinder.common.di.Dir
|
||||||
import com.shabinder.common.list.SpotiFlyerList
|
import com.shabinder.common.list.SpotiFlyerList
|
||||||
import com.shabinder.common.main.SpotiFlyerMain
|
import com.shabinder.common.main.SpotiFlyerMain
|
||||||
import com.shabinder.common.models.DownloadStatus
|
import com.shabinder.common.models.Consumer
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot
|
import com.shabinder.common.root.SpotiFlyerRoot
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot.Child
|
import com.shabinder.common.root.SpotiFlyerRoot.Child
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot.Dependencies
|
import com.shabinder.common.root.SpotiFlyerRoot.Dependencies
|
||||||
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
|
||||||
import com.shabinder.common.utils.Consumer
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
|
|
||||||
internal class SpotiFlyerRootImpl(
|
internal class SpotiFlyerRootImpl(
|
||||||
componentContext: ComponentContext,
|
componentContext: ComponentContext,
|
@ -21,7 +21,7 @@ kotlin {
|
|||||||
implementation(compose.desktop.currentOs)
|
implementation(compose.desktop.currentOs)
|
||||||
implementation(project(":common:database"))
|
implementation(project(":common:database"))
|
||||||
implementation(project(":common:dependency-injection"))
|
implementation(project(":common:dependency-injection"))
|
||||||
implementation(project(":common:compose-ui"))
|
implementation(project(":common:compose"))
|
||||||
implementation(Decompose.decompose)
|
implementation(Decompose.decompose)
|
||||||
implementation(Decompose.extensionsCompose)
|
implementation(Decompose.extensionsCompose)
|
||||||
implementation(MVIKotlin.mvikotlin)
|
implementation(MVIKotlin.mvikotlin)
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -16,12 +16,11 @@ import com.shabinder.common.di.FetchPlatformQueryResult
|
|||||||
import com.shabinder.common.di.initKoin
|
import com.shabinder.common.di.initKoin
|
||||||
import com.shabinder.common.root.SpotiFlyerRoot
|
import com.shabinder.common.root.SpotiFlyerRoot
|
||||||
import com.shabinder.common.root.SpotiFlyerRootContent
|
import com.shabinder.common.root.SpotiFlyerRootContent
|
||||||
import com.shabinder.common.ui.SpotiFlyerColors
|
import com.shabinder.common.uikit.SpotiFlyerColors
|
||||||
import com.shabinder.common.ui.SpotiFlyerShapes
|
import com.shabinder.common.uikit.SpotiFlyerShapes
|
||||||
import com.shabinder.common.ui.SpotiFlyerTypography
|
import com.shabinder.common.uikit.SpotiFlyerTypography
|
||||||
import com.shabinder.common.ui.colorOffWhite
|
import com.shabinder.common.uikit.colorOffWhite
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class Extractor(private var cutoff: Int = 0) {
|
|||||||
fun extractOne(query: String, choices: Collection<String>, func: Applicable): ExtractedResult {
|
fun extractOne(query: String, choices: Collection<String>, func: Applicable): ExtractedResult {
|
||||||
val extracted = extractWithoutOrder(query, choices, func)
|
val extracted = extractWithoutOrder(query, choices, func)
|
||||||
|
|
||||||
return extracted.max()!!
|
return extracted.maxOrNull()!!
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +95,7 @@ class Extractor(private var cutoff: Int = 0) {
|
|||||||
|
|
||||||
val extracted = extractWithoutOrder(query, choices, toStringFunction, func)
|
val extracted = extractWithoutOrder(query, choices, toStringFunction, func)
|
||||||
|
|
||||||
return extracted.max()!!
|
return extracted.maxOrNull()!!
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("UNCHECKED_CAST")
|
||||||
|
|
||||||
package com.willowtreeapps.fuzzywuzzy.diffutils
|
package com.willowtreeapps.fuzzywuzzy.diffutils
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017 Kotlin Algorithm Club
|
* Copyright (c) 2017 Kotlin Algorithm Club
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user