Modular Structure

This commit is contained in:
shabinder 2021-02-25 18:58:33 +05:30
parent ec1402ef2e
commit 475a64cad5
104 changed files with 299 additions and 360 deletions

View File

@ -16,7 +16,7 @@ repositories {
android {
compileSdkVersion(29)
defaultConfig {
applicationId = "com.shabinder.android"
applicationId = "com.shabinder.spotiflyer"
minSdkVersion(Versions.minSdkVersion)
targetSdkVersion(Versions.targetSdkVersion)
versionCode = Versions.versionCode
@ -25,8 +25,8 @@ android {
buildTypes {
getByName("release") {
isMinifyEnabled = false
//isShrinkResources = true
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
@ -63,7 +63,8 @@ dependencies {
implementation(Androidx.androidxActivity)
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:data-models"))
@ -82,12 +83,6 @@ dependencies {
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$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 {
@ -103,7 +98,7 @@ dependencies {
implementation(Decompose.extensionsCompose)
//Test
testImplementation("junit:junit:4.13.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation(Androidx.junit)
androidTestImplementation(Androidx.expresso)

View File

@ -19,3 +19,21 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-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(...);
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.shabinder.android">
package="com.shabinder.spotiflyer">
<queries>
<package android:name="com.gaana" />

View File

@ -14,12 +14,12 @@
* 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 com.shabinder.android.di.appModule
import com.shabinder.common.database.appContext
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.androidLogger
import org.koin.core.KoinComponent

View File

@ -1,4 +1,4 @@
package com.shabinder.android
package com.shabinder.spotiflyer
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
@ -12,37 +12,33 @@ import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material.Surface
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope
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.main.store.DefaultStoreFactory
import com.razorpay.Checkout
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.di.Dir
import com.shabinder.common.di.FetchPlatformQueryResult
import com.shabinder.common.di.createDirectories
import com.shabinder.common.di.showPopUpMessage
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.root.SpotiFlyerRoot
import com.shabinder.common.root.SpotiFlyerRootContent
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
import com.shabinder.common.ui.SpotiFlyerTheme
import com.shabinder.common.ui.colorOffWhite
import com.shabinder.common.ui.showPopUpMessage
import com.shabinder.common.uikit.SpotiFlyerRootContent
import com.shabinder.common.uikit.SpotiFlyerTheme
import com.shabinder.common.uikit.colorOffWhite
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 kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
@ -81,7 +77,7 @@ class MainActivity : ComponentActivity(), PaymentResultListener {
insets
}
}
root = SpotiFlyerRootContent(rootComponent(::spotiFlyerRoot),statusBarHeight)
root = SpotiFlyerRootContent(rememberRootComponent(::spotiFlyerRoot),statusBarHeight)
}
}
}

View File

@ -1,4 +1,4 @@
package com.shabinder.android.di
package com.shabinder.spotiflyer.di
import com.shabinder.common.database.appContext
import com.tonyodev.fetch2.Fetch

View File

@ -1,4 +1,4 @@
package com.shabinder.android.utils
package com.shabinder.spotiflyer.utils
import android.Manifest
import android.annotation.SuppressLint
@ -12,7 +12,6 @@ import android.provider.Settings
import com.github.javiersantos.appupdater.AppUpdater
import com.github.javiersantos.appupdater.enums.Display
import com.github.javiersantos.appupdater.enums.UpdateFrom
import com.tonyodev.fetch2.Fetch
fun Activity.checkIfLatestVersion() {
AppUpdater(this,0).run {

View File

@ -67,12 +67,12 @@ object JetBrains {
object Compose {
// __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"
}
}
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 decomposeIosX64 = "com.arkivanov.decompose:decompose-iosx64:$VERSION"
const val decomposeIosArm64 = "com.arkivanov.decompose:decompose-iosarm64:$VERSION"

View File

@ -1,5 +1,3 @@
import org.jetbrains.compose.compose
plugins {
id("com.android.library")
id("kotlin-multiplatform")

View File

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

View File

@ -1,7 +0,0 @@
package com.shabinder.common.ui
import kotlinx.coroutines.CoroutineDispatcher
expect fun showPopUpMessage(text: String)
expect val dispatcherIO: CoroutineDispatcher

View File

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

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

View File

@ -1,6 +1,6 @@
@file:Suppress("FunctionName")
package com.shabinder.common.ui
package com.shabinder.common.uikit
import androidx.annotation.DrawableRes
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.FontFamily
import androidx.compose.ui.text.font.FontWeight
import com.shabinder.common.database.R
actual fun montserratFont() = FontFamily(
Font(R.font.montserrat_light, FontWeight.Light),

View File

@ -14,7 +14,7 @@
* 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.ui.graphics.Color

View File

@ -1,15 +1,14 @@
@file:Suppress("FunctionName")
package com.shabinder.common.ui
package com.shabinder.common.uikit
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.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import com.shabinder.common.di.dispatcherIO
import kotlinx.coroutines.withContext
@Composable

View File

@ -14,7 +14,7 @@
* 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.material.Shapes

View File

@ -1,4 +1,4 @@
package com.shabinder.common.list
package com.shabinder.common.uikit
import androidx.compose.foundation.clickable
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.unit.dp
import androidx.compose.ui.unit.sp
import com.shabinder.common.list.SpotiFlyerList
import com.shabinder.common.models.DownloadStatus
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
@Composable

View File

@ -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.layout.*
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.text.KeyboardOptions
import androidx.compose.material.*
import androidx.compose.material.Icon
import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material.Text
import androidx.compose.material.TextFieldDefaults.textFieldColors
import androidx.compose.material.icons.Icons
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.ImageBitmap
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.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
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.shareApp
import com.shabinder.common.ui.*
import com.shabinder.common.ui.SpotiFlyerTypography
import com.shabinder.common.di.showPopUpMessage
import com.shabinder.common.main.SpotiFlyerMain
import com.shabinder.common.main.SpotiFlyerMain.HomeCategory
import com.shabinder.common.models.DownloadRecord
@Composable
fun SpotiFlyerMainContent(component: SpotiFlyerMain){
@ -129,7 +130,10 @@ fun SearchPanel(
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),
@ -148,7 +152,10 @@ fun SearchPanel(
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))
}
@ -299,12 +306,21 @@ fun HistoryColumn(
loadImage:suspend (String)-> ImageBitmap?,
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),
colorOffWhite
)
Text("No History Available",style = SpotiFlyerTypography.h4.copy(fontWeight = FontWeight.Light),textAlign = TextAlign.Center)
}
}else{
LazyColumn(
verticalArrangement = Arrangement.spacedBy(12.dp),
content = {
items(list.distinctBy { it.coverUrl }) {
items(it.distinctBy {record -> record.coverUrl }) { record ->
DownloadRecordItem(
item = it,
item = record,
loadImage,
onItemClicked
)
@ -312,6 +328,8 @@ fun HistoryColumn(
},
modifier = Modifier.padding(top = 8.dp).fillMaxSize()
)
}
}
}
@Composable
@ -334,8 +352,8 @@ fun DownloadRecordItem(
verticalAlignment = Alignment.Bottom,
modifier = Modifier.padding(horizontal = 8.dp).fillMaxSize()
){
Text(item.type,fontSize = 13.sp)
Text("Tracks: ${item.totalFiles}",fontSize = 13.sp)
Text(item.type,fontSize = 13.sp,color = colorOffWhite)
Text("Tracks: ${item.totalFiles}",fontSize = 13.sp,color = colorOffWhite)
}
}
Image(

View File

@ -1,14 +1,16 @@
package com.shabinder.common.root
package com.shabinder.common.uikit
import androidx.compose.animation.core.*
import androidx.compose.animation.core.Spring.StiffnessLow
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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 com.arkivanov.decompose.extensions.compose.jetbrains.Children
import com.shabinder.common.list.SpotiFlyerListContent
import com.shabinder.common.main.SpotiFlyerMainContent
import com.shabinder.common.root.SpotiFlyerRoot
import com.shabinder.common.root.SpotiFlyerRoot.Child
import com.shabinder.common.ui.SpotiFlyerLogo
import com.shabinder.common.ui.appNameStyle
import com.shabinder.common.ui.colorPrimaryDark
import com.shabinder.common.ui.splash.*
import com.shabinder.common.utils.verticalGradientScrim
import com.shabinder.common.uikit.splash.Splash
import com.shabinder.common.uikit.splash.SplashState
import com.shabinder.common.uikit.utils.verticalGradientScrim
@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)

View File

@ -14,7 +14,7 @@
* 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.runtime.Composable

View File

@ -14,7 +14,7 @@
* 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.ui.graphics.Color

View File

@ -14,7 +14,7 @@
* 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.layout.*
@ -29,7 +29,7 @@ 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.ui.*
import com.shabinder.common.uikit.*
import kotlinx.coroutines.delay
private const val SplashWaitTime: Long = 2000

View File

@ -14,7 +14,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.shabinder.common.ui.utils
package com.shabinder.common.uikit.utils
/*

View File

@ -14,7 +14,7 @@
* 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.mutableStateOf

View File

@ -1,5 +1,5 @@
@file:Suppress("FunctionName")
package com.shabinder.common.ui
package com.shabinder.common.uikit
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable

View File

@ -1,4 +1,4 @@
package com.shabinder.common.utils
package com.shabinder.common.models
/*
* Callback Utility

View File

@ -4,15 +4,19 @@ import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.core.content.ContextCompat
import com.github.kiulian.downloader.model.YoutubeVideo
import com.github.kiulian.downloader.model.formats.Format
import com.github.kiulian.downloader.model.quality.AudioQuality
import com.razorpay.Checkout
import com.shabinder.common.database.R
import com.shabinder.common.database.activityContext
import com.shabinder.common.database.appContext
import com.shabinder.common.di.worker.ForegroundService
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.ui.R
import kotlinx.coroutines.Dispatchers
import org.json.JSONObject
actual fun openPlatform(packageID:String, platformLink:String){
@ -29,7 +33,20 @@ actual fun openPlatform(packageID:String, platformLink:String){
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(){
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND

View File

@ -9,14 +9,16 @@ import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import co.touchlab.kermit.Kermit
import com.mpatric.mp3agic.Mp3File
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.database.appContext
import com.shabinder.common.models.TrackDetails
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.*
import java.lang.Exception
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL

View File

@ -18,10 +18,10 @@ package com.shabinder.common.di
import co.touchlab.kermit.Kermit
import com.github.kiulian.downloader.YoutubeDownloader
import com.shabinder.common.database.DownloadRecordDatabaseQueries
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.PlatformQueryResult
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.database.DownloadRecordDatabaseQueries
import com.shabinder.common.models.spotify.Source
import com.shabinder.database.Database
import io.ktor.client.*

View File

@ -33,12 +33,12 @@ 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.getData
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.ui.R.*
import com.tonyodev.fetch2.*
import com.tonyodev.fetch2core.DownloadBlock
import kotlinx.coroutines.*

View File

@ -2,13 +2,11 @@ package com.shabinder.common.di
import androidx.compose.ui.graphics.ImageBitmap
import co.touchlab.kermit.Kermit
import com.shabinder.common.di.providers.YoutubeMusic
import com.shabinder.common.models.DownloadResult
import com.shabinder.common.models.TrackDetails
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlin.math.roundToInt

View File

@ -1,6 +1,7 @@
package com.shabinder.common.di
import com.shabinder.common.models.TrackDetails
import kotlinx.coroutines.CoroutineDispatcher
expect fun openPlatform(packageID:String, platformLink:String)
@ -8,6 +9,10 @@ expect fun shareApp()
expect fun giveDonation()
expect fun showPopUpMessage(text: String)
expect val dispatcherIO: CoroutineDispatcher
expect suspend fun downloadTracks(
list: List<TrackDetails>,
getYTIDBestMatch:suspend (String,TrackDetails)->String?,

View File

@ -1,11 +1,11 @@
package com.shabinder.common.di
import com.shabinder.common.models.PlatformQueryResult
import com.shabinder.common.database.DownloadRecordDatabaseQueries
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 com.shabinder.common.models.PlatformQueryResult
import com.shabinder.database.Database
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

View File

@ -1,4 +1,4 @@
package com.shabinder.common.ui
package com.shabinder.common.di
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState

View File

@ -2,8 +2,8 @@ package com.shabinder.common.di
import co.touchlab.kermit.Kermit
import com.shabinder.common.database.TokenDBQueries
import com.shabinder.common.models.spotify.TokenData
import com.shabinder.common.di.spotify.authenticateSpotify
import com.shabinder.common.models.spotify.TokenData
import com.shabinder.database.Database
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

View File

@ -21,10 +21,10 @@ import com.shabinder.common.database.DownloadRecordDatabaseQueries
import com.shabinder.common.di.Dir
import com.shabinder.common.di.finalOutputDir
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.PlatformQueryResult
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.models.gaana.GaanaTrack
import com.shabinder.common.models.spotify.Source
import com.shabinder.database.Database
import io.ktor.client.*
@ -169,7 +169,7 @@ class GaanaProvider(
subFolder = link
coverUrl = gaanaPlaceholderImageUrl
val artistDetails =
getGaanaArtistDetails(seokey = link).artist?.firstOrNull()
getGaanaArtistDetails(seokey = link).artist.firstOrNull()
?.also {
title = it.name
coverUrl = it.artworkLink ?: gaanaPlaceholderImageUrl

View File

@ -1,7 +1,6 @@
package com.shabinder.common.di.providers
import co.touchlab.kermit.Kermit
import co.touchlab.kermit.Logger
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.models.YoutubeTrack
import com.willowtreeapps.fuzzywuzzy.diffutils.FuzzySearch

View File

@ -2,7 +2,6 @@ package com.shabinder.common.di.spotify
import com.shabinder.common.di.kotlinxSerializer
import com.shabinder.common.models.spotify.TokenData
import com.shabinder.database.Database
import io.ktor.client.*
import io.ktor.client.features.auth.*
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.forms.*
import io.ktor.http.*
import kotlinx.datetime.Clock
suspend fun authenticateSpotify(): TokenData {
return spotifyAuthClient.post("https://accounts.spotify.com/api/token"){

View File

@ -7,8 +7,8 @@ import com.github.kiulian.downloader.model.quality.AudioQuality
import com.shabinder.common.models.DownloadResult
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collect
actual fun openPlatform(packageID:String, platformLink:String){
//TODO

View File

@ -10,7 +10,10 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.jetbrains.skija.Image
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.URL
import javax.imageio.ImageIO

View File

@ -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.material.Surface
import androidx.compose.material.Text

View File

@ -18,10 +18,10 @@ package com.shabinder.common.di
import co.touchlab.kermit.Kermit
import com.github.kiulian.downloader.YoutubeDownloader
import com.shabinder.common.database.DownloadRecordDatabaseQueries
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.PlatformQueryResult
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.database.DownloadRecordDatabaseQueries
import com.shabinder.common.models.spotify.Source
import com.shabinder.database.Database
import io.ktor.client.*

View File

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

View File

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

View File

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

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

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.shabinder.common.ui"/>

View File

@ -1,21 +1,17 @@
package com.shabinder.common.list
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.graphics.ImageBitmap
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.shabinder.common.di.Dir
import com.shabinder.common.di.FetchPlatformQueryResult
import com.shabinder.common.list.integration.SpotiFlyerListImpl
import com.shabinder.common.models.Consumer
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.TrackDetails
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.StateFlow
interface SpotiFlyerList {

View File

@ -3,13 +3,13 @@ package com.shabinder.common.list.integration
import androidx.compose.ui.graphics.ImageBitmap
import com.arkivanov.decompose.ComponentContext
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.Dependencies
import com.shabinder.common.list.SpotiFlyerList.State
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
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
internal class SpotiFlyerListImpl(

View File

@ -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.getOrCreate
@ -8,7 +8,9 @@ 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 =
inline fun <reified T
: Store<*, *, *>> InstanceKeeper.getStore(noinline factory: () -> T): T =
getStore(T::class, factory)
private class StoreHolder<T : Store<*, *, *>>(

View File

@ -1,9 +1,9 @@
package com.shabinder.common.list.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.store.SpotiFlyerListStore.*
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
import com.shabinder.common.models.TrackDetails
internal interface SpotiFlyerListStore: Store<Intent, State, Nothing> {
sealed class Intent {

View File

@ -3,16 +3,12 @@ package com.shabinder.common.list.store
import com.arkivanov.mvikotlin.core.store.*
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
import com.shabinder.common.database.getLogger
import com.shabinder.common.di.Dir
import com.shabinder.common.di.FetchPlatformQueryResult
import com.shabinder.common.di.downloadTracks
import com.shabinder.common.di.queryActiveTracks
import com.shabinder.common.di.*
import com.shabinder.common.list.SpotiFlyerList.State
import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.PlatformQueryResult
import com.shabinder.common.models.TrackDetails
import com.shabinder.common.ui.showPopUpMessage
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collectLatest

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.shabinder.common.ui"/>

View File

@ -4,9 +4,9 @@ import androidx.compose.ui.graphics.ImageBitmap
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.shabinder.common.di.Dir
import com.shabinder.common.models.DownloadRecord
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 kotlinx.coroutines.flow.Flow

View File

@ -7,7 +7,7 @@ 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.SpotiFlyerMainStoreProvider
import com.shabinder.common.utils.getStore
import com.shabinder.common.main.store.getStore
import kotlinx.coroutines.flow.Flow
internal class SpotiFlyerMainImpl(

View File

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

View File

@ -2,7 +2,7 @@ package com.shabinder.common.main.store
import com.arkivanov.mvikotlin.core.store.Store
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> {
sealed class Intent {

View File

@ -5,13 +5,13 @@ import com.arkivanov.mvikotlin.core.store.SimpleBootstrapper
import com.arkivanov.mvikotlin.core.store.Store
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
import com.shabinder.common.models.DownloadRecord
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.State
import com.shabinder.common.main.store.SpotiFlyerMainStore.Intent
import com.shabinder.common.di.openPlatform
import com.shabinder.common.di.shareApp
import com.shabinder.common.models.DownloadRecord
import com.shabinder.database.Database
import com.squareup.sqldelight.runtime.coroutines.asFlow
import com.squareup.sqldelight.runtime.coroutines.mapToList

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

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.shabinder.common.ui"/>

View File

@ -11,11 +11,9 @@ import com.shabinder.common.main.SpotiFlyerMain
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.root.SpotiFlyerRoot.Dependencies
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
import com.shabinder.database.Database
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.StateFlow
interface SpotiFlyerRoot {

View File

@ -1,25 +1,17 @@
package com.shabinder.common.root.integration
import co.touchlab.kermit.Kermit
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.*
import com.arkivanov.decompose.statekeeper.Parcelable
import com.arkivanov.decompose.statekeeper.Parcelize
import com.arkivanov.decompose.value.Value
import com.shabinder.common.database.getLogger
import com.shabinder.common.di.Dir
import com.shabinder.common.list.SpotiFlyerList
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.Child
import com.shabinder.common.root.SpotiFlyerRoot.Dependencies
import com.shabinder.common.root.callbacks.SpotiFlyerRootCallBacks
import com.shabinder.common.utils.Consumer
import kotlinx.coroutines.flow.StateFlow
internal class SpotiFlyerRootImpl(
componentContext: ComponentContext,

View File

@ -21,7 +21,7 @@ kotlin {
implementation(compose.desktop.currentOs)
implementation(project(":common:database"))
implementation(project(":common:dependency-injection"))
implementation(project(":common:compose-ui"))
implementation(project(":common:compose"))
implementation(Decompose.decompose)
implementation(Decompose.extensionsCompose)
implementation(MVIKotlin.mvikotlin)

View File

@ -16,12 +16,11 @@ import com.shabinder.common.di.FetchPlatformQueryResult
import com.shabinder.common.di.initKoin
import com.shabinder.common.root.SpotiFlyerRoot
import com.shabinder.common.root.SpotiFlyerRootContent
import com.shabinder.common.ui.SpotiFlyerColors
import com.shabinder.common.ui.SpotiFlyerShapes
import com.shabinder.common.ui.SpotiFlyerTypography
import com.shabinder.common.ui.colorOffWhite
import com.shabinder.common.uikit.SpotiFlyerColors
import com.shabinder.common.uikit.SpotiFlyerShapes
import com.shabinder.common.uikit.SpotiFlyerTypography
import com.shabinder.common.uikit.colorOffWhite
import com.shabinder.database.Database
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

View File

@ -78,7 +78,7 @@ class Extractor(private var cutoff: Int = 0) {
fun extractOne(query: String, choices: Collection<String>, func: Applicable): ExtractedResult {
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)
return extracted.max()!!
return extracted.maxOrNull()!!
}

View File

@ -1,3 +1,5 @@
@file:Suppress("UNCHECKED_CAST")
package com.willowtreeapps.fuzzywuzzy.diffutils
/*
* Copyright (c) 2017 Kotlin Algorithm Club

Some files were not shown because too many files have changed in this diff Show More