mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-23 17:34:32 +01:00
Gradle Deps Catalog, Gradle Script Cleanup, Compose, WebApp Updated
This commit is contained in:
parent
f403ca63f2
commit
13471d4a28
@ -16,7 +16,6 @@
|
||||
|
||||
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
|
||||
import org.jetbrains.compose.compose
|
||||
import org.jetbrains.kotlin.kapt.cli.main
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
@ -79,6 +78,9 @@ android {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
packagingOptions {
|
||||
exclude("META-INF/*")
|
||||
}
|
||||
configurations {
|
||||
"implementation" {
|
||||
exclude(group = "androidx.compose.animation")
|
||||
@ -92,7 +94,7 @@ android {
|
||||
dependencies {
|
||||
implementation(compose.material)
|
||||
implementation(compose.materialIconsExtended)
|
||||
implementation(Androidx.androidxActivity)
|
||||
implementation(deps.androidx.activity)
|
||||
|
||||
// Project's SubModules
|
||||
implementation(project(":common:database"))
|
||||
@ -103,43 +105,39 @@ dependencies {
|
||||
implementation(project(":common:core-components"))
|
||||
implementation(project(":common:providers"))
|
||||
|
||||
with(deps) {
|
||||
|
||||
// Koin
|
||||
implementation(Koin.android)
|
||||
implementation(Koin.compose)
|
||||
with(koin) {
|
||||
implementation(androidx.compose)
|
||||
implementation(android)
|
||||
}
|
||||
|
||||
// DECOMPOSE
|
||||
implementation(Decompose.decompose)
|
||||
implementation(Decompose.extensionsCompose)
|
||||
|
||||
// MVI
|
||||
implementation(MVIKotlin.mvikotlin)
|
||||
implementation(MVIKotlin.mvikotlinMain)
|
||||
implementation(MVIKotlin.mvikotlinLogging)
|
||||
implementation(MVIKotlin.mvikotlinTimeTravel)
|
||||
|
||||
// Extras
|
||||
with(Extras.Android) {
|
||||
implementation(countly)
|
||||
implementation(appUpdator)
|
||||
with(decompose) {
|
||||
implementation(dep)
|
||||
implementation(extensions.compose)
|
||||
}
|
||||
|
||||
with(Versions.androidxLifecycle) {
|
||||
implementation("androidx.lifecycle:lifecycle-service:$this")
|
||||
implementation("androidx.lifecycle:lifecycle-common-java8:$this")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$this")
|
||||
}
|
||||
implementation(countly.android)
|
||||
implementation(android.app.notifier)
|
||||
implementation(storage.chooser)
|
||||
|
||||
implementation(Extras.kermit)
|
||||
// implementation("com.jakewharton.timber:timber:4.7.1")
|
||||
implementation("dev.icerock.moko:parcelize:${Versions.mokoParcelize}")
|
||||
implementation("com.github.shabinder:storage-chooser:2.0.4.45")
|
||||
implementation("com.google.accompanist:accompanist-insets:0.16.1")
|
||||
with(bundles) {
|
||||
implementation(androidx.lifecycle)
|
||||
implementation(mviKotlin)
|
||||
implementation(accompanist.inset)
|
||||
}
|
||||
|
||||
// Test
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation(Androidx.junit)
|
||||
androidTestImplementation(Androidx.expresso)
|
||||
testImplementation(junit)
|
||||
androidTestImplementation(androidx.junit)
|
||||
androidTestImplementation(androidx.expresso)
|
||||
|
||||
// Desugaring
|
||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
|
||||
// Desugar
|
||||
coreLibraryDesugaring(androidx.desugar)
|
||||
|
||||
// Debug
|
||||
debugImplementation(leak.canary)
|
||||
}
|
||||
}
|
||||
|
@ -38,15 +38,25 @@ allprojects {
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>>().configureEach {
|
||||
dependsOn(":common:data-models:generateI18n4kFiles")
|
||||
kotlinOptions {
|
||||
if(this is org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions) {
|
||||
if (this is org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions) {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
freeCompilerArgs = (freeCompilerArgs + listOf("-Xopt-in=kotlin.RequiresOptIn"))
|
||||
}
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
eachDependency {
|
||||
if (requested.group == "org.jetbrains.kotlin") {
|
||||
@Suppress("UnstableApiUsage")
|
||||
useVersion(deps.kotlin.kotlinGradlePlugin.get().versionConstraint.requiredVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
afterEvaluate {
|
||||
project.extensions.findByType<org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension>()?.let { kmpExt ->
|
||||
project.extensions.findByType<org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension>()
|
||||
?.let { kmpExt ->
|
||||
kmpExt.sourceSets.run {
|
||||
all {
|
||||
languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn")
|
||||
|
@ -30,17 +30,20 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(Androidx.gradlePlugin)
|
||||
implementation(JetBrains.Compose.gradlePlugin)
|
||||
implementation(JetBrains.Kotlin.gradlePlugin)
|
||||
implementation(JetBrains.Kotlin.serialization)
|
||||
implementation(SqlDelight.gradlePlugin)
|
||||
implementation(KTLint.gradlePlugin)
|
||||
implementation(Internationalization.gradlePlugin)
|
||||
implementation(Mosaic.gradlePlugin)
|
||||
with(deps) {
|
||||
implementation(androidx.gradle.plugin)
|
||||
implementation(kotlin.compose.gradle)
|
||||
implementation(ktlint.gradle)
|
||||
implementation(mosaic.gradle)
|
||||
implementation(kotlin.kotlinGradlePlugin)
|
||||
implementation(sqldelight.gradle.plugin)
|
||||
implementation(i18n4k.gradle.plugin)
|
||||
implementation(kotlin.serialization)
|
||||
}
|
||||
}
|
||||
|
||||
kotlin {
|
||||
// Add Deps to compilation, so it will become available in main project
|
||||
sourceSets.getByName("main").kotlin.srcDir("buildSrc/src/main/kotlin")
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,15 @@
|
||||
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@file:Suppress("MayBeConstant", "SpellCheckingInspection")
|
||||
@file:Suppress("MayBeConstant", "SpellCheckingInspection", "UnstableApiUsage")
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||
import org.gradle.api.artifacts.VersionCatalog
|
||||
import org.gradle.api.artifacts.VersionCatalogsExtension
|
||||
import org.gradle.api.artifacts.dsl.DependencyHandler
|
||||
import org.gradle.kotlin.dsl.accessors.runtime.addDependencyTo
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
object Versions {
|
||||
// App's Version (To be bumped at each update)
|
||||
@ -26,44 +30,10 @@ object Versions {
|
||||
|
||||
const val versionCode = 26
|
||||
|
||||
// Kotlin
|
||||
const val kotlinVersion = "1.5.21"
|
||||
|
||||
const val coroutinesVersion = "1.5.1"
|
||||
|
||||
// Code Formatting
|
||||
const val ktLint = "10.1.0"
|
||||
|
||||
// Console-App UI
|
||||
const val mosaic = "0.1.0"
|
||||
|
||||
// DI
|
||||
const val koin = "3.1.2"
|
||||
|
||||
// Logger
|
||||
const val kermit = "0.1.9"
|
||||
|
||||
const val mokoParcelize = "0.7.1"
|
||||
|
||||
// Internet
|
||||
const val ktor = "1.6.2"
|
||||
|
||||
const val kotlinxSerialization = "1.2.2"
|
||||
|
||||
// Database
|
||||
const val sqlDelight = "1.5.1"
|
||||
|
||||
const val sqliteJdbcDriver = "3.34.0"
|
||||
const val slf4j = "1.7.31"
|
||||
|
||||
// Internationalisation
|
||||
const val i18n4k = "0.1.3"
|
||||
|
||||
// Android
|
||||
const val minSdkVersion = 21
|
||||
const val compileSdkVersion = 30
|
||||
const val compileSdkVersion = 31
|
||||
const val targetSdkVersion = 29
|
||||
const val androidxLifecycle = "2.4.0-alpha03"
|
||||
}
|
||||
|
||||
object HostOS {
|
||||
@ -74,143 +44,46 @@ object HostOS {
|
||||
val isLinux = hostOs.startsWith("Linux", true)
|
||||
}
|
||||
|
||||
object MultiPlatformSettings {
|
||||
const val dep = "com.russhwolf:multiplatform-settings-no-arg:0.7.7"
|
||||
}
|
||||
val Project.Deps: VersionCatalog get() = project.extensions.getByType<VersionCatalogsExtension>().named("deps")
|
||||
|
||||
object KotlinJSWrappers {
|
||||
private const val bomVersion = "0.0.1-pre.235-kotlin-1.5.21"
|
||||
val bom = "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${bomVersion}"
|
||||
const val kotlinReact = "org.jetbrains.kotlin-wrappers:kotlin-react"
|
||||
const val kotlinReactDom = "org.jetbrains.kotlin-wrappers:kotlin-react-dom"
|
||||
const val kotlinStyled = "org.jetbrains.kotlin-wrappers:kotlin-styled"
|
||||
}
|
||||
val VersionCatalog.ktorBundle get() = findBundle("ktor").get()
|
||||
val VersionCatalog.statelyBundle get() = findBundle("stately").get()
|
||||
val VersionCatalog.androidXLifecycleBundle get() = findBundle("androidx-lifecycle").get()
|
||||
val VersionCatalog.androidXCommonBundle get() = findBundle("androidx-common").get()
|
||||
val VersionCatalog.kotlinTestBundle get() = findBundle("kotlin-test").get()
|
||||
val VersionCatalog.sqldelightBundle get() = findBundle("sqldelight").get()
|
||||
val VersionCatalog.mviKotlinBundle get() = findBundle("mviKotlin").get()
|
||||
val VersionCatalog.essentyBundle get() = findBundle("essenty").get()
|
||||
val VersionCatalog.koinAndroidBundle get() = findBundle("koin-android").get()
|
||||
val VersionCatalog.kotlinJSWrappers get() = findBundle("kotlin-js-wrappers").get()
|
||||
|
||||
object Koin {
|
||||
val core = "io.insert-koin:koin-core:${Versions.koin}"
|
||||
val test = "io.insert-koin:koin-test:${Versions.koin}"
|
||||
val android = "io.insert-koin:koin-android:${Versions.koin}"
|
||||
val compose = "io.insert-koin:koin-androidx-compose:${Versions.koin}"
|
||||
}
|
||||
val VersionCatalog.kotlinJunitTest get() = findDependency("kotlin-kotlinTestJunit").get()
|
||||
val VersionCatalog.kotlinJSTest get() = findDependency("kotlin-kotlinTestJs").get()
|
||||
val VersionCatalog.kermit get() = findDependency("kermit").get()
|
||||
val VersionCatalog.decompose get() = findDependency("decompose-dep").get()
|
||||
val VersionCatalog.decomposeComposeExt get() = findDependency("decompose-extensions-compose").get()
|
||||
val VersionCatalog.jaffree get() = findDependency("jaffree").get()
|
||||
|
||||
object Androidx {
|
||||
const val androidxActivity = "androidx.activity:activity-compose:1.3.1"
|
||||
const val core = "androidx.core:core-ktx:1.6.0"
|
||||
const val palette = "androidx.palette:palette-ktx:1.0.0"
|
||||
const val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutinesVersion}"
|
||||
val VersionCatalog.ktlintGradle get() = findDependency("ktlint-gradle").get()
|
||||
val VersionCatalog.androidGradle get() = findDependency("androidx-gradle-plugin").get()
|
||||
val VersionCatalog.mosaicGradle get() = findDependency("mosaic-gradle").get()
|
||||
val VersionCatalog.kotlinComposeGradle get() = findDependency("kotlin-compose-gradle").get()
|
||||
val VersionCatalog.kotlinGradle get() = findDependency("kotlin-kotlinGradlePlugin").get()
|
||||
val VersionCatalog.i18n4kGradle get() = findDependency("i18n4k-gradle-plugin").get()
|
||||
val VersionCatalog.sqlDelightGradle get() = findDependency("sqldelight-gradle-plugin").get()
|
||||
val VersionCatalog.kotlinSerializationPlugin get() = findDependency("kotlin-serialization").get()
|
||||
|
||||
const val junit = "androidx.test.ext:junit:1.1.2"
|
||||
const val expresso = "androidx.test.espresso:espresso-core:3.3.0"
|
||||
val VersionCatalog.koinCore get() = findDependency("koin-core").get()
|
||||
val VersionCatalog.kotlinCoroutines get() = findDependency("kotlin-coroutines").get()
|
||||
val VersionCatalog.kotlinxSerialization get() = findDependency("kotlinx-serialization-json").get()
|
||||
val VersionCatalog.ktorClientIOS get() = findDependency("ktor-client-ios").get()
|
||||
val VersionCatalog.ktorClientAndroid get() = findDependency("ktor-client-android").get()
|
||||
val VersionCatalog.ktorClientApache get() = findDependency("ktor-client-apache").get()
|
||||
val VersionCatalog.ktorClientJS get() = findDependency("ktor-client-js").get()
|
||||
val VersionCatalog.ktorClientCIO get() = findDependency("ktor-client-cio").get()
|
||||
val VersionCatalog.slf4j get() = findDependency("slf4j-simple").get()
|
||||
|
||||
const val gradlePlugin = "com.android.tools.build:gradle:7.0.1"
|
||||
}
|
||||
|
||||
object KTLint {
|
||||
const val gradlePlugin = "org.jlleitschuh.gradle:ktlint-gradle:${Versions.ktLint}"
|
||||
}
|
||||
|
||||
object JetBrains {
|
||||
object Kotlin {
|
||||
const val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1-native-mt"
|
||||
const val gradlePlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlinVersion}"
|
||||
const val serialization = "org.jetbrains.kotlin:kotlin-serialization:${Versions.kotlinVersion}"
|
||||
const val testCommon = "org.jetbrains.kotlin:kotlin-test-common:${Versions.kotlinVersion}"
|
||||
const val testJunit = "org.jetbrains.kotlin:kotlin-test-junit:${Versions.kotlinVersion}"
|
||||
const val testAnnotationsCommon =
|
||||
"org.jetbrains.kotlin:kotlin-test-annotations-common:${Versions.kotlinVersion}"
|
||||
}
|
||||
|
||||
object Compose {
|
||||
// __LATEST_COMPOSE_RELEASE_VERSION__
|
||||
private const val VERSION = "1.0.0-alpha3"
|
||||
const val gradlePlugin = "org.jetbrains.compose:compose-gradle-plugin:$VERSION"
|
||||
}
|
||||
}
|
||||
|
||||
object Mosaic {
|
||||
const val gradlePlugin = "com.jakewharton.mosaic:mosaic-gradle-plugin:${Versions.mosaic}"
|
||||
}
|
||||
|
||||
object Decompose {
|
||||
private const val VERSION = "0.3.1"
|
||||
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"
|
||||
const val extensionsCompose = "com.arkivanov.decompose:extensions-compose-jetbrains:$VERSION"
|
||||
}
|
||||
|
||||
object MVIKotlin {
|
||||
private const val VERSION = "2.0.4"
|
||||
const val rx = "com.arkivanov.mvikotlin:rx:$VERSION"
|
||||
const val mvikotlin = "com.arkivanov.mvikotlin:mvikotlin:$VERSION"
|
||||
const val mvikotlinMain = "com.arkivanov.mvikotlin:mvikotlin-main:$VERSION"
|
||||
const val coroutines = "com.arkivanov.mvikotlin:mvikotlin-extensions-coroutines:$VERSION"
|
||||
const val keepers = "com.arkivanov.mvikotlin:keepers:$VERSION"
|
||||
const val mvikotlinMainIosX64 = "com.arkivanov.mvikotlin:mvikotlin-main-iosx64:$VERSION"
|
||||
const val mvikotlinMainIosArm64 = "com.arkivanov.mvikotlin:mvikotlin-main-iosarm64:$VERSION"
|
||||
const val mvikotlinLogging = "com.arkivanov.mvikotlin:mvikotlin-logging:$VERSION"
|
||||
const val mvikotlinTimeTravel = "com.arkivanov.mvikotlin:mvikotlin-timetravel:$VERSION"
|
||||
const val mvikotlinExtensionsReaktive = "com.arkivanov.mvikotlin:mvikotlin-extensions-reaktive:$VERSION"
|
||||
}
|
||||
|
||||
object Ktor {
|
||||
val clientCore = "io.ktor:ktor-client-core:${Versions.ktor}"
|
||||
val clientJson = "io.ktor:ktor-client-json:${Versions.ktor}"
|
||||
val clientLogging = "io.ktor:ktor-client-logging:${Versions.ktor}"
|
||||
val clientSerialization = "io.ktor:ktor-client-serialization:${Versions.ktor}"
|
||||
|
||||
val auth = "io.ktor:ktor-client-auth:${Versions.ktor}"
|
||||
val clientAndroid = "io.ktor:ktor-client-android:${Versions.ktor}"
|
||||
val clientCurl = "io.ktor:ktor-client-curl:${Versions.ktor}"
|
||||
val clientApache = "io.ktor:ktor-client-apache:${Versions.ktor}"
|
||||
val slf4j = "org.slf4j:slf4j-simple:${Versions.slf4j}"
|
||||
val clientIos = "io.ktor:ktor-client-ios:${Versions.ktor}"
|
||||
val clientCio = "io.ktor:ktor-client-cio:${Versions.ktor}"
|
||||
val clientJs = "io.ktor:ktor-client-js:${Versions.ktor}"
|
||||
}
|
||||
|
||||
object Internationalization {
|
||||
const val dep = "de.comahe.i18n4k:i18n4k-core:${Versions.i18n4k}"
|
||||
const val gradlePlugin = "de.comahe.i18n4k:i18n4k-gradle-plugin:${Versions.i18n4k}"
|
||||
}
|
||||
|
||||
object Extras {
|
||||
const val youtubeDownloader = "io.github.shabinder:youtube-api-dl:1.3"
|
||||
const val fuzzyWuzzy = "io.github.shabinder:fuzzywuzzy:1.1"
|
||||
const val mp3agic = "com.mpatric:mp3agic:0.9.0"
|
||||
const val jaudioTagger = "com.github.Shabinder:JAudioTagger-Android:1.0"
|
||||
const val kermit = "co.touchlab:kermit:${Versions.kermit}"
|
||||
|
||||
object Android {
|
||||
// Self Hosted Analytics & Crashlytics (FOSS)
|
||||
val countly = "ly.count.android:sdk:20.11.8"
|
||||
val appUpdator = "com.github.amitbd1508:AppUpdater:4.1.0"
|
||||
}
|
||||
|
||||
object Desktop {
|
||||
val countly = "ly.count.sdk:java:20.11.0"
|
||||
}
|
||||
}
|
||||
|
||||
object Serialization {
|
||||
val json = "org.jetbrains.kotlinx:kotlinx-serialization-json:${Versions.kotlinxSerialization}"
|
||||
}
|
||||
|
||||
object SqlDelight {
|
||||
val runtime = "com.squareup.sqldelight:runtime:${Versions.sqlDelight}"
|
||||
val coroutineExtensions = "com.squareup.sqldelight:coroutines-extensions:${Versions.sqlDelight}"
|
||||
|
||||
const val gradlePlugin = "com.squareup.sqldelight:gradle-plugin:${Versions.sqlDelight}"
|
||||
const val androidDriver = "com.squareup.sqldelight:android-driver:${Versions.sqlDelight}"
|
||||
const val sqliteDriver = "com.squareup.sqldelight:sqlite-driver:${Versions.sqlDelight}"
|
||||
const val nativeDriver = "com.squareup.sqldelight:native-driver:${Versions.sqlDelight}"
|
||||
val nativeDriverMacos = "com.squareup.sqldelight:native-driver-macosx64:${Versions.sqlDelight}"
|
||||
val jdbcDriver = "org.xerial:sqlite-jdbc:${Versions.sqliteJdbcDriver}"
|
||||
}
|
||||
|
||||
fun DependencyHandler.`implementation`(
|
||||
dependencyNotation: String,
|
||||
dependencyConfiguration: ExternalModuleDependency.() -> Unit
|
||||
): ExternalModuleDependency = addDependencyTo(
|
||||
this, "implementation", dependencyNotation
|
||||
) { dependencyConfiguration() }
|
||||
val VersionCatalog.sqlDelightJDBC get() = findDependency("sqlite-jdbc-driver").get()
|
||||
val VersionCatalog.sqlDelightNative get() = findDependency("sqldelight-native-driver").get()
|
||||
val VersionCatalog.sqlDelightAndroid get() = findDependency("sqldelight-android-driver").get()
|
||||
val VersionCatalog.sqlDelightDriver get() = findDependency("sqldelight-driver").get()
|
||||
|
135
buildSrc/deps.versions.toml
Normal file
135
buildSrc/deps.versions.toml
Normal file
@ -0,0 +1,135 @@
|
||||
[versions]
|
||||
kotlin = "1.5.31"
|
||||
androidCoroutines = "1.5.1"
|
||||
ktLint = "10.1.0"
|
||||
mosaic = "0.1.0"
|
||||
koin = "3.1.2"
|
||||
kermit = "0.1.9"
|
||||
mokoParcelize = "0.7.1"
|
||||
ktor = "1.6.3"
|
||||
kotlinxSerialization = "1.2.2"
|
||||
sqlDelight = "1.5.1"
|
||||
sqliteJdbcDriver = "3.34.0"
|
||||
slf4j = "1.7.31"
|
||||
i18n4k = "0.1.3"
|
||||
essenty = "0.1.3"
|
||||
multiplatformSettings = "0.7.7"
|
||||
decompose = "0.3.1"
|
||||
mviKotlin = "2.0.4"
|
||||
accompanist = "0.18.0"
|
||||
statelyVersion = "1.1.10"
|
||||
statelyIsoVersion = "1.2.0-nmm"
|
||||
androidxLifecycle = "2.4.0-alpha03"
|
||||
|
||||
|
||||
[libraries]
|
||||
kotlin-kotlinGradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
|
||||
kotlin-serialization = { group = "org.jetbrains.kotlin", name = "kotlin-serialization", version.ref = "kotlin" }
|
||||
kotlin-kotlinTestCommon = { group = "org.jetbrains.kotlin", name = "kotlin-test-common", version.ref = "kotlin" }
|
||||
kotlin-kotlinTestJs = { group = "org.jetbrains.kotlin", name = "kotlin-test-js", version.ref = "kotlin" }
|
||||
kotlin-kotlinTestJunit = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit", version.ref = "kotlin" }
|
||||
kotlin-kotlinTestAnnotationsCommon = { group = "org.jetbrains.kotlin", name = "kotlin-test-annotations-common", version.ref = "kotlin" }
|
||||
kotlin-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.5.2-native-mt" }
|
||||
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
|
||||
kotlinx-atomicfu = { group = "org.jetbrains.kotlinx", name = "atomicfu", version = "0.16.3" }
|
||||
kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version = "0.2.1" }
|
||||
|
||||
kotlin-compose-gradle = { group = "org.jetbrains.compose", name = "compose-gradle-plugin", version = "1.0.0-alpha4-build366" }
|
||||
mosaic-gradle = { group = "com.jakewharton.mosaic", name = "mosaic-gradle-plugin", version.ref = "mosaic" }
|
||||
|
||||
essenty-lifecycle = { group = "com.arkivanov.essenty", name = "lifecycle", version.ref = "essenty" }
|
||||
essenty-instanceKeeper = { group = "com.arkivanov.essenty", name = "instance-keeper", version.ref = "essenty" }
|
||||
|
||||
decompose-dep = { group = "com.arkivanov.decompose", name = "decompose", version.ref = "decompose" }
|
||||
decompose-extensions-compose = { group = "com.arkivanov.decompose", name = "extensions-compose-jetbrains", version.ref = "decompose" }
|
||||
|
||||
mviKotlin-dep = { group = "com.arkivanov.mvikotlin", name = "mvikotlin", version.ref = "mviKotlin" }
|
||||
mviKotlin-rx = { group = "com.arkivanov.mvikotlin", name = "rx", version.ref = "mviKotlin" }
|
||||
mviKotlin-main = { group = "com.arkivanov.mvikotlin", name = "mvikotlin-main", version.ref = "mviKotlin" }
|
||||
mviKotlin-coroutines = { group = "com.arkivanov.mvikotlin", name = "mvikotlin-extensions-coroutines", version.ref = "mviKotlin" }
|
||||
mviKotlin-keepers = { group = "com.arkivanov.mvikotlin", name = "keepers", version.ref = "mviKotlin" }
|
||||
mviKotlin-logging = { group = "com.arkivanov.mvikotlin", name = "mvikotlin-logging", version.ref = "mviKotlin" }
|
||||
mviKotlin-timetravel = { group = "com.arkivanov.mvikotlin", name = "mvikotlin-timetravel", version.ref = "mviKotlin" }
|
||||
mviKotlin-extensions-reaktive = { group = "com.arkivanov.mvikotlin", name = "mvikotlin-extensions-reaktive", version.ref = "mviKotlin" }
|
||||
|
||||
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }
|
||||
ktor-client-json = { group = "io.ktor", name = "ktor-client-json", version.ref = "ktor" }
|
||||
ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktor" }
|
||||
ktor-client-serialization = { group = "io.ktor", name = "ktor-client-serialization", version.ref = "ktor" }
|
||||
ktor-client-auth = { group = "io.ktor", name = "ktor-client-auth", version.ref = "ktor" }
|
||||
ktor-client-android = { group = "io.ktor", name = "ktor-client-android", version.ref = "ktor" }
|
||||
ktor-client-curl = { group = "io.ktor", name = "ktor-client-curl", version.ref = "ktor" }
|
||||
ktor-client-apache = { group = "io.ktor", name = "ktor-client-apache", version.ref = "ktor" }
|
||||
ktor-client-ios = { group = "io.ktor", name = "ktor-client-ios", version.ref = "ktor" }
|
||||
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor" }
|
||||
ktor-client-js = { group = "io.ktor", name = "ktor-client-js", version.ref = "ktor" }
|
||||
slf4j-simple = { group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j" }
|
||||
|
||||
i18n4k-core = { group = "de.comahe.i18n4k", name = "i18n4k-core", version.ref = "i18n4k" }
|
||||
i18n4k-gradle-plugin = { group = "de.comahe.i18n4k", name = "i18n4k-gradle-plugin", version.ref = "i18n4k" }
|
||||
|
||||
youtube-downloader = { group = "io.github.shabinder", name = "youtube-api-dl", version = "1.3" }
|
||||
fuzzy-wuzzy = { group = "io.github.shabinder", name = "fuzzywuzzy", version = "1.1" }
|
||||
mp3agic = { group = "com.mpatric", name = "mp3agic", version = "0.9.0" }
|
||||
kermit = { group = "co.touchlab", name = "kermit", version.ref = "kermit" }
|
||||
storage-chooser = { group = "com.github.shabinder", name = "storage-chooser", version = "2.0.4.45" }
|
||||
accompanist-inset = { group = "com.google.accompanist", name = "accompanist-insets", version.ref = "accompanist" }
|
||||
android-app-notifier = { group = "com.github.amitbd1508", name = "AppUpdater", version = "4.1.0" }
|
||||
moko-parcelize = { group = "dev.icerock.moko", name = "parcelize", version.ref = "mokoParcelize" }
|
||||
jaffree = { group = "com.github.kokorin.jaffree", name = "jaffree", version = "2021.08.16" }
|
||||
multiplatform-settings = { group = "com.russhwolf", name = "multiplatform-settings-no-arg", version.ref = "multiplatformSettings" }
|
||||
|
||||
countly-android = { group = "ly.count.android", name = "sdk", version = "20.11.8" }
|
||||
countly-desktop = { group = "ly.count.sdk", name = "java", version = "20.11.0" }
|
||||
|
||||
stately-common = { group = "co.touchlab", name = "stately-common", version.ref = "statelyVersion" }
|
||||
stately-concurrency = { group = "co.touchlab", name = "stately-concurrency", version.ref = "statelyVersion" }
|
||||
stately-isolate = { group = "co.touchlab", name = "stately-isolate", version.ref = "statelyIsoVersion" }
|
||||
stately-iso-collections = { group = "co.touchlab", name = "stately-iso-collections", version.ref = "statelyIsoVersion" }
|
||||
|
||||
sqldelight-runtime = { group = "com.squareup.sqldelight", name = "runtime", version.ref = "sqlDelight" }
|
||||
sqldelight-coroutines-extension = { group = "com.squareup.sqldelight", name = "coroutines-extensions", version.ref = "sqlDelight" }
|
||||
sqldelight-gradle-plugin = { group = "com.squareup.sqldelight", name = "gradle-plugin", version.ref = "sqlDelight" }
|
||||
sqldelight-driver = { group = "com.squareup.sqldelight", name = "sqlite-driver", version.ref = "sqlDelight" }
|
||||
sqldelight-android-driver = { group = "com.squareup.sqldelight", name = "android-driver", version.ref = "sqlDelight" }
|
||||
sqldelight-native-driver = { group = "com.squareup.sqldelight", name = "native-driver", version.ref = "sqlDelight" }
|
||||
sqlite-jdbc-driver = { group = "org.xerial", name = "sqlite-jdbc", version.ref = "sqliteJdbcDriver" }
|
||||
|
||||
koin-core = { group = "io.insert-koin", name = "koin-core", version.ref = "koin" }
|
||||
koin-test = { group = "io.insert-koin", name = "koin-test", version.ref = "koin" }
|
||||
koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" }
|
||||
koin-androidx-compose = { group = "io.insert-koin", name = "koin-androidx-compose", version.ref = "koin" }
|
||||
|
||||
kotlin-js-wrappers-react = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-react", version = "17.0.2-pre.251-kotlin-1.5.31" }
|
||||
kotlin-js-wrappers-reactDom = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-react-dom", version = "17.0.2-pre.251-kotlin-1.5.31" }
|
||||
kotlin-js-wrappers-styled = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-styled", version = "5.3.1-pre.250-kotlin-1.5.31" }
|
||||
kotlin-js-wrappers-ext = { group = "org.jetbrains.kotlin-wrappers", name = "kotlin-extensions", version = "1.0.1-pre.251-kotlin-1.5.31" }
|
||||
|
||||
androidx-activity = { group = "androidx.activity", name = "activity-compose", version = "1.3.1" }
|
||||
androidx-core = { group = "androidx.core", name = "core-ktx", version = "1.6.0" }
|
||||
androidx-palette = { group = "androidx.palette", name = "palette-ktx", version = "1.0.0" }
|
||||
androidx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "androidCoroutines" }
|
||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version = "1.1.2" }
|
||||
androidx-expresso = { group = "androidx.test.espresso", name = "espresso-core", version = "3.3.0" }
|
||||
androidx-gradle-plugin = { group = "com.android.tools.build", name = "gradle", version = "4.2.2" }
|
||||
androidx-lifecycle-service = { group = "androidx.lifecycle", name = "lifecycle-service", version.ref = "androidxLifecycle" }
|
||||
androidx-lifecycle-common = { group = "androidx.lifecycle", name = "lifecycle-common-java8", version.ref = "androidxLifecycle" }
|
||||
androidx-lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidxLifecycle" }
|
||||
androidx-desugar = { group = "com.android.tools", name = "desugar_jdk_libs", version = "1.1.5" }
|
||||
leak-canary = { group = "com.squareup.leakcanary", name = "leakcanary-android", version = "2.7" }
|
||||
junit = { group = "junit", name = "junit", version = "4.13.2" }
|
||||
|
||||
ktlint-gradle = { group = "org.jlleitschuh.gradle", name = "ktlint-gradle", version.ref = "ktLint" }
|
||||
|
||||
[bundles]
|
||||
ktor = ["ktor-client-core","ktor-client-json","ktor-client-auth","ktor-client-logging","ktor-client-serialization"]
|
||||
stately = ["stately-common","stately-concurrency","stately-isolate","stately-iso-collections"]
|
||||
androidx-lifecycle = ["androidx-lifecycle-service","androidx-lifecycle-common","androidx-lifecycle-runtime"]
|
||||
androidx-common = ["androidx-activity","androidx-core"]
|
||||
kotlin-test = ["kotlin-kotlinTestCommon","kotlin-kotlinTestAnnotationsCommon"]
|
||||
sqldelight = ["sqldelight-runtime","sqldelight-coroutines-extension","sqldelight-driver"]
|
||||
mviKotlin = ["mviKotlin-dep","mviKotlin-main","mviKotlin-coroutines","mviKotlin-logging","mviKotlin-timetravel"]
|
||||
kotlinCommon = ["kotlin-coroutines", "kotlin-serialization", "kotlinx-serialization-json", "kotlinx-atomicfu"]
|
||||
essenty = ["essenty-lifecycle","essenty-instanceKeeper"]
|
||||
koin-android = ["koin-androidx-compose","koin-android"]
|
||||
kotlin-js-wrappers = ["kotlin-js-wrappers-react","kotlin-js-wrappers-reactDom","kotlin-js-wrappers-styled","kotlin-js-wrappers-ext"]
|
12
buildSrc/settings.gradle.kts
Normal file
12
buildSrc/settings.gradle.kts
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
enableFeaturePreview("VERSION_CATALOGS")
|
||||
dependencyResolutionManagement {
|
||||
@Suppress("UnstableApiUsage")
|
||||
versionCatalogs {
|
||||
create("deps") {
|
||||
from(files("deps.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "spotiflyer-build"
|
@ -6,10 +6,10 @@ kotlin {
|
||||
sourceSets {
|
||||
all {
|
||||
languageSettings.apply {
|
||||
useExperimentalAnnotation("kotlin.RequiresOptIn")
|
||||
useExperimentalAnnotation("kotlin.Experimental")
|
||||
useExperimentalAnnotation("kotlin.time.ExperimentalTime")
|
||||
useExperimentalAnnotation("kotlinx.serialization.ExperimentalSerializationApi")
|
||||
optIn("kotlin.RequiresOptIn")
|
||||
optIn("kotlin.Experimental")
|
||||
optIn("kotlin.time.ExperimentalTime")
|
||||
optIn("kotlinx.serialization.ExperimentalSerializationApi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,36 +29,23 @@ kotlin {
|
||||
sourceSets {
|
||||
all {
|
||||
languageSettings.apply {
|
||||
useExperimentalAnnotation("androidx.compose.animation")
|
||||
optIn("androidx.compose.animation")
|
||||
}
|
||||
}
|
||||
named("commonMain") {
|
||||
dependencies {
|
||||
// Decompose
|
||||
implementation(Decompose.decompose)
|
||||
|
||||
// MVI
|
||||
implementation(MVIKotlin.coroutines)
|
||||
implementation(MVIKotlin.mvikotlin)
|
||||
|
||||
implementation(compose.ui)
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material)
|
||||
implementation(compose.animation)
|
||||
|
||||
implementation(Extras.kermit)
|
||||
implementation("dev.icerock.moko:parcelize:${Versions.mokoParcelize}")
|
||||
implementation(JetBrains.Kotlin.coroutines) {
|
||||
@Suppress("DEPRECATION")
|
||||
isForce = true
|
||||
}
|
||||
implementation(Deps.kotlinCoroutines)
|
||||
implementation(Deps.decompose)
|
||||
}
|
||||
}
|
||||
named("androidMain") {
|
||||
dependencies {
|
||||
implementation(Androidx.androidxActivity)
|
||||
implementation(Androidx.core)
|
||||
implementation(Deps.androidXCommonBundle)
|
||||
}
|
||||
}
|
||||
named("desktopMain") {
|
||||
|
@ -42,23 +42,24 @@ kotlin {
|
||||
sourceSets {
|
||||
named("commonTest") {
|
||||
dependencies {
|
||||
implementation(JetBrains.Kotlin.testCommon)
|
||||
implementation(JetBrains.Kotlin.testAnnotationsCommon)
|
||||
implementation(Deps.kotlinTestBundle)
|
||||
}
|
||||
}
|
||||
|
||||
named("androidTest") {
|
||||
dependencies {
|
||||
implementation(JetBrains.Kotlin.testJunit)
|
||||
implementation(Deps.kotlinJunitTest)
|
||||
}
|
||||
}
|
||||
named("desktopTest") {
|
||||
dependencies {
|
||||
implementation(JetBrains.Kotlin.testJunit)
|
||||
implementation(Deps.kotlinJunitTest)
|
||||
}
|
||||
}
|
||||
named("jsTest") {
|
||||
dependencies {}
|
||||
dependencies {
|
||||
implementation(Deps.kotlinJSTest)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ plugins {
|
||||
|
||||
kotlin {
|
||||
/*IOS Target Can be only built on Mac*/
|
||||
if(HostOS.isMac){
|
||||
if (HostOS.isMac) {
|
||||
val sdkName: String? = System.getenv("SDK_NAME")
|
||||
val isiOSDevice = sdkName.orEmpty().startsWith("iphoneos")
|
||||
if (isiOSDevice) {
|
||||
@ -50,45 +50,25 @@ kotlin {
|
||||
sourceSets {
|
||||
named("commonMain") {
|
||||
dependencies {
|
||||
// Decompose
|
||||
implementation(Decompose.decompose)
|
||||
|
||||
// MVI
|
||||
implementation(MVIKotlin.coroutines)
|
||||
implementation(MVIKotlin.mvikotlin)
|
||||
|
||||
// Koin
|
||||
implementation(Koin.core)
|
||||
|
||||
implementation(Ktor.auth)
|
||||
implementation(Ktor.clientJson)
|
||||
implementation(Ktor.clientCore)
|
||||
implementation(Ktor.clientLogging)
|
||||
implementation(Ktor.clientSerialization)
|
||||
|
||||
// Extras
|
||||
implementation(Extras.kermit)
|
||||
implementation(Serialization.json)
|
||||
implementation("co.touchlab:stately-common:1.1.7")
|
||||
implementation("dev.icerock.moko:parcelize:${Versions.mokoParcelize}")
|
||||
implementation(JetBrains.Kotlin.coroutines) {
|
||||
@Suppress("DEPRECATION")
|
||||
isForce = true
|
||||
}
|
||||
implementation(Deps.ktorBundle)
|
||||
implementation(Deps.kotlinxSerialization)
|
||||
implementation(Deps.kotlinCoroutines)
|
||||
implementation(Deps.mviKotlinBundle)
|
||||
implementation(Deps.decompose)
|
||||
implementation(Deps.koinCore)
|
||||
}
|
||||
}
|
||||
|
||||
named("androidMain") {
|
||||
dependencies {
|
||||
implementation(Androidx.androidxActivity)
|
||||
implementation(Androidx.core)
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.material)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.materialIconsExtended)
|
||||
implementation(Decompose.extensionsCompose)
|
||||
implementation(Ktor.clientAndroid)
|
||||
implementation(Koin.android)
|
||||
implementation(Deps.androidXCommonBundle)
|
||||
implementation(Deps.decomposeComposeExt)
|
||||
implementation(Deps.ktorClientAndroid)
|
||||
implementation(Deps.koinAndroidBundle)
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,27 +79,20 @@ kotlin {
|
||||
implementation(compose.material)
|
||||
implementation(compose.desktop.common)
|
||||
implementation(compose.materialIconsExtended)
|
||||
implementation(Decompose.extensionsCompose)
|
||||
implementation(Ktor.clientApache)
|
||||
implementation(Ktor.slf4j)
|
||||
implementation(Deps.decomposeComposeExt)
|
||||
implementation(Deps.ktorClientApache)
|
||||
implementation(Deps.slf4j)
|
||||
}
|
||||
}
|
||||
named("jsMain") {
|
||||
dependencies {
|
||||
implementation(Ktor.clientJs)
|
||||
|
||||
/*with(KotlinJSWrappers) {
|
||||
implementation(enforcedPlatform(bom))
|
||||
implementation(kotlinReact)
|
||||
implementation(kotlinReactDom)
|
||||
implementation(kotlinStyled)
|
||||
}*/
|
||||
implementation(Deps.ktorClientJS)
|
||||
}
|
||||
}
|
||||
if(HostOS.isMac){
|
||||
named("iosMain"){
|
||||
if (HostOS.isMac) {
|
||||
named("iosMain") {
|
||||
dependencies {
|
||||
implementation(Ktor.clientIos)
|
||||
implementation(Deps.ktorClientIOS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ kotlin {
|
||||
implementation(project(":common:database"))
|
||||
implementation(project(":common:data-models"))
|
||||
implementation(project(":common:dependency-injection"))
|
||||
implementation(Decompose.extensionsCompose)
|
||||
implementation(deps.decompose.extensions.compose)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,15 +21,19 @@ package com.shabinder.common.uikit
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.loadXmlImageVector
|
||||
import androidx.compose.ui.res.vectorXmlResource
|
||||
import androidx.compose.ui.res.useResource
|
||||
import org.xml.sax.InputSource
|
||||
|
||||
@Composable
|
||||
internal actual fun <T> imageVectorResource(id: T): ImageVector =
|
||||
vectorXmlResource(id as String)
|
||||
internal actual fun <T> imageVectorResource(id: T): ImageVector {
|
||||
val density = LocalDensity.current
|
||||
return useResource(id as String) {
|
||||
loadXmlImageVector(InputSource(it), density)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun DownloadImageTick() {
|
||||
|
@ -12,7 +12,7 @@ import androidx.compose.ui.unit.dp
|
||||
|
||||
actual val MARGIN_SCROLLBAR: Dp = 8.dp
|
||||
|
||||
actual typealias ScrollbarAdapter = androidx.compose.foundation.ScrollbarAdapter
|
||||
actual typealias ScrollbarAdapter = ScrollbarAdapter
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
@ -23,8 +23,6 @@ actual fun rememberScrollbarAdapter(
|
||||
): ScrollbarAdapter =
|
||||
androidx.compose.foundation.rememberScrollbarAdapter(
|
||||
scrollState = scrollState,
|
||||
itemCount = itemCount,
|
||||
averageItemSize = averageItemSize
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
@ -10,29 +10,37 @@ kotlin {
|
||||
dependencies {
|
||||
implementation(project(":common:data-models"))
|
||||
implementation(project(":common:database"))
|
||||
api("org.jetbrains.kotlinx:atomicfu:0.16.2")
|
||||
api(MultiPlatformSettings.dep)
|
||||
implementation(MVIKotlin.rx)
|
||||
with(deps) {
|
||||
api(multiplatform.settings)
|
||||
api(kotlinx.atomicfu)
|
||||
implementation(mviKotlin.rx)
|
||||
implementation(decompose.dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
androidMain {
|
||||
dependencies {
|
||||
implementation(Extras.mp3agic)
|
||||
implementation(Extras.Android.countly)
|
||||
with(deps) {
|
||||
implementation(mp3agic)
|
||||
implementation(countly.android)
|
||||
}
|
||||
implementation(project(":ffmpeg:android-ffmpeg"))
|
||||
}
|
||||
}
|
||||
desktopMain {
|
||||
dependencies {
|
||||
implementation(Extras.mp3agic)
|
||||
implementation(Extras.Desktop.countly)
|
||||
implementation("com.github.kokorin.jaffree:jaffree:2021.08.16")
|
||||
with(deps) {
|
||||
implementation(mp3agic)
|
||||
implementation(countly.desktop)
|
||||
implementation(jaffree)
|
||||
}
|
||||
}
|
||||
}
|
||||
jsMain {
|
||||
dependencies {
|
||||
implementation(npm("browser-id3-writer", "4.4.0"))
|
||||
implementation(npm("file-saver", "2.0.4"))
|
||||
implementation(deps.kotlin.js.wrappers.ext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,17 +30,20 @@ import com.shabinder.common.core_components.removeAllTags
|
||||
import com.shabinder.common.core_components.setId3v1Tags
|
||||
import com.shabinder.common.core_components.setId3v2TagsAndSaveFile
|
||||
import com.shabinder.common.database.SpotiFlyerDatabase
|
||||
import com.shabinder.common.models.Actions
|
||||
import com.shabinder.common.models.DownloadStatus
|
||||
import com.shabinder.common.models.TrackDetails
|
||||
import com.shabinder.common.models.dispatcherIO
|
||||
import com.shabinder.common.models.event.coroutines.SuspendableEvent
|
||||
import com.shabinder.common.models.event.coroutines.failure
|
||||
import com.shabinder.common.models.event.coroutines.map
|
||||
import com.shabinder.common.models.Actions
|
||||
import com.shabinder.database.Database
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import org.jetbrains.skija.Image
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.skia.Image
|
||||
import org.koin.dsl.bind
|
||||
import org.koin.dsl.module
|
||||
import java.awt.image.BufferedImage
|
||||
@ -165,7 +168,7 @@ class DesktopFileManager(
|
||||
}
|
||||
SuspendableEvent.success(trackDetails.outputFilePath)
|
||||
} catch (e: Throwable) {
|
||||
if(e is JaffreeException) Actions.instance.showPopUpMessage("No FFmpeg found at path.")
|
||||
if (e is JaffreeException) Actions.instance.showPopUpMessage("No FFmpeg found at path.")
|
||||
if (songFile.exists()) songFile.delete()
|
||||
logger.e { "${songFile.absolutePath} could not be created" }
|
||||
SuspendableEvent.error(e)
|
||||
|
@ -25,9 +25,6 @@ plugins {
|
||||
id("de.comahe.i18n4k")
|
||||
}
|
||||
|
||||
val statelyVersion = "1.1.7"
|
||||
val statelyIsoVersion = "1.1.7-a1"
|
||||
|
||||
i18n4k {
|
||||
inputDirectory = "../../translations"
|
||||
packageName = "com.shabinder.common.translations"
|
||||
@ -50,11 +47,13 @@ kotlin {
|
||||
}
|
||||
commonMain {
|
||||
dependencies {
|
||||
api("co.touchlab:stately-concurrency:$statelyVersion")
|
||||
api("co.touchlab:stately-isolate:$statelyIsoVersion")
|
||||
api("co.touchlab:stately-iso-collections:$statelyIsoVersion")
|
||||
implementation(Extras.youtubeDownloader)
|
||||
api(Internationalization.dep)
|
||||
with(deps) {
|
||||
api(bundles.stately)
|
||||
api(i18n4k.core)
|
||||
api(kermit)
|
||||
api(moko.parcelize)
|
||||
implementation(youtube.downloader)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,31 +34,32 @@ kotlin {
|
||||
implementation(project(":common:data-models"))
|
||||
|
||||
// SQL Delight
|
||||
implementation(SqlDelight.runtime)
|
||||
implementation(SqlDelight.coroutineExtensions)
|
||||
|
||||
// koin
|
||||
implementation(Koin.test)
|
||||
with(deps.sqldelight) {
|
||||
implementation(runtime)
|
||||
api(coroutines.extension)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
androidMain {
|
||||
dependencies {
|
||||
implementation(SqlDelight.androidDriver)
|
||||
implementation(deps.sqldelight.android.driver)
|
||||
}
|
||||
}
|
||||
|
||||
desktopMain {
|
||||
dependencies {
|
||||
implementation(SqlDelight.sqliteDriver)
|
||||
implementation(SqlDelight.jdbcDriver)
|
||||
with(deps) {
|
||||
implementation(sqldelight.driver)
|
||||
implementation(sqlite.jdbc.driver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HostOS.isMac) {
|
||||
val iosMain by getting {
|
||||
dependencies {
|
||||
implementation(SqlDelight.nativeDriver)
|
||||
implementation(deps.sqldelight.native.driver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,6 @@
|
||||
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import org.jetbrains.compose.compose
|
||||
|
||||
plugins {
|
||||
id("android-setup")
|
||||
id("multiplatform-setup")
|
||||
|
@ -30,7 +30,6 @@ kotlin {
|
||||
implementation(project(":common:database"))
|
||||
implementation(project(":common:providers"))
|
||||
implementation(project(":common:core-components"))
|
||||
implementation(SqlDelight.coroutineExtensions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ kotlin {
|
||||
implementation(project(":common:database"))
|
||||
implementation(project(":common:providers"))
|
||||
implementation(project(":common:core-components"))
|
||||
implementation(SqlDelight.coroutineExtensions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ kotlin {
|
||||
implementation(project(":common:database"))
|
||||
implementation(project(":common:core-components"))
|
||||
implementation(project(":common:providers"))
|
||||
implementation(SqlDelight.coroutineExtensions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,23 +12,25 @@ kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
with(deps) {
|
||||
implementation(project(":common:data-models"))
|
||||
implementation(project(":common:database"))
|
||||
implementation(project(":common:core-components"))
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.2.1")
|
||||
implementation(Extras.youtubeDownloader)
|
||||
implementation(Extras.fuzzyWuzzy)
|
||||
implementation(youtube.downloader)
|
||||
implementation(fuzzy.wuzzy)
|
||||
implementation(kotlinx.datetime)
|
||||
}
|
||||
}
|
||||
}
|
||||
androidMain {
|
||||
dependencies {
|
||||
implementation(Extras.mp3agic)
|
||||
implementation(deps.mp3agic)
|
||||
}
|
||||
}
|
||||
desktopMain {
|
||||
dependencies {
|
||||
implementation(Extras.mp3agic)
|
||||
implementation("com.github.kokorin.jaffree:jaffree:2021.08.16")
|
||||
implementation(deps.mp3agic)
|
||||
implementation(deps.jaffree)
|
||||
}
|
||||
}
|
||||
jsMain {
|
||||
|
@ -32,7 +32,7 @@ interface SoundCloudRequests {
|
||||
}
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
suspend fun getTrack(track: JsonObject): TrackDetails {
|
||||
suspend fun getTrack(track: JsonObject): TrackDetails? {
|
||||
val track = getTrackInfo(track)
|
||||
val title = track.getString("title")
|
||||
|
||||
@ -42,7 +42,7 @@ interface SoundCloudRequests {
|
||||
if (track.getBoolean("streamable") == false)
|
||||
throw SpotiFlyerException.LinkInvalid("\nSound Cloud Reports that $title is not streamable !\n")
|
||||
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,9 +33,10 @@ fun org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer.generateFramewor
|
||||
export(project(":common:providers"))
|
||||
export(project(":common:list"))
|
||||
export(project(":common:preference"))
|
||||
export(Decompose.decompose)
|
||||
export(MVIKotlin.mvikotlinMain)
|
||||
export(MVIKotlin.mvikotlinLogging)
|
||||
with(deps) {
|
||||
export(decompose.dep)
|
||||
export(bundles.mviKotlin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +72,6 @@ kotlin {
|
||||
implementation(project(":common:providers"))
|
||||
implementation(project(":common:core-components"))
|
||||
implementation(project(":common:preference"))
|
||||
implementation(SqlDelight.coroutineExtensions)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,9 +86,10 @@ kotlin {
|
||||
api(project(":common:list"))
|
||||
api(project(":common:main"))
|
||||
api(project(":common:preference"))
|
||||
api(Decompose.decompose)
|
||||
api(MVIKotlin.mvikotlinMain)
|
||||
api(MVIKotlin.mvikotlinLogging)
|
||||
with(deps) {
|
||||
api(decompose.dep)
|
||||
api(bundles.mviKotlin)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -100,7 +101,10 @@ val packForXcode by tasks.creating(Sync::class) {
|
||||
group = "build"
|
||||
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
|
||||
val targetName = "ios"
|
||||
val framework = kotlin.targets.getByName<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>(targetName)
|
||||
val framework =
|
||||
kotlin.targets.getByName<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>(
|
||||
targetName
|
||||
)
|
||||
.binaries.getFramework(mode)
|
||||
inputs.property("mode", mode)
|
||||
dependsOn(framework.linkTask)
|
||||
|
@ -19,6 +19,7 @@ application {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
with(deps) {
|
||||
implementation(Koin.core)
|
||||
implementation(project(":common:database"))
|
||||
implementation(project(":common:data-models"))
|
||||
@ -40,7 +41,6 @@ dependencies {
|
||||
implementation(Koin.core)
|
||||
|
||||
// Matomo
|
||||
implementation("org.piwik.java.tracking:matomo-java-tracker:1.6")
|
||||
|
||||
implementation(Ktor.slf4j)
|
||||
implementation(Ktor.clientCore)
|
||||
@ -51,6 +51,7 @@ dependencies {
|
||||
implementation(Serialization.json)
|
||||
// testDeps
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:1.5.21")
|
||||
}
|
||||
}
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
|
@ -44,19 +44,21 @@ kotlin {
|
||||
implementation(project(":common:compose"))
|
||||
implementation(project(":common:providers"))
|
||||
implementation(project(":common:root"))
|
||||
implementation("com.github.kokorin.jaffree:jaffree:2021.08.16")
|
||||
|
||||
// Decompose
|
||||
implementation(Decompose.decompose)
|
||||
implementation(Decompose.extensionsCompose)
|
||||
with(deps) {
|
||||
implementation(jaffree)
|
||||
|
||||
// MVI
|
||||
implementation(MVIKotlin.mvikotlin)
|
||||
implementation(MVIKotlin.mvikotlinMain)
|
||||
|
||||
// Koin
|
||||
implementation(Koin.core)
|
||||
with(decompose) {
|
||||
implementation(dep)
|
||||
implementation(extensions.compose)
|
||||
}
|
||||
with(mviKotlin) {
|
||||
implementation(dep)
|
||||
implementation(main)
|
||||
}
|
||||
|
||||
implementation(koin.core)
|
||||
}
|
||||
}
|
||||
}
|
||||
val jvmTest by getting
|
||||
|
@ -13,8 +13,6 @@ android {
|
||||
|
||||
minSdk = Versions.minSdkVersion
|
||||
targetSdk = Versions.targetSdkVersion
|
||||
// versionCode = Versions.versionCode
|
||||
// versionName = Versions.versionName
|
||||
|
||||
/*ndk {
|
||||
abiFilters.addAll(setOf("x86", "x86_64", "armeabi-v7a", "arm64-v8a"))
|
||||
|
@ -2,6 +2,7 @@ package nl.bravobit.ffmpeg;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class CpuArchHelper {
|
||||
public static final String X86_CPU = "x86";
|
||||
public static final String X86_64_CPU = "x86_64";
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nl.bravobit.ffmpeg;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
@ -9,10 +8,12 @@ import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
class FFcommandExecuteAsyncTask extends AsyncTask<Void, String, CommandResult> implements FFtask {
|
||||
|
||||
private final String[] cmd;
|
||||
private Map<String, String> environment;
|
||||
private final Map<String, String> environment;
|
||||
private final StringBuilder outputStringBuilder = new StringBuilder();
|
||||
private final FFcommandExecuteResponseHandler ffmpegExecuteResponseHandler;
|
||||
private final ShellCommand shellCommand;
|
||||
private final long timeout;
|
||||
@ -39,6 +40,7 @@ class FFcommandExecuteAsyncTask extends AsyncTask<Void, String, CommandResult> i
|
||||
|
||||
@Override
|
||||
protected CommandResult doInBackground(Void... params) {
|
||||
CommandResult ret = CommandResult.getDummyFailureResponse();
|
||||
try {
|
||||
process = shellCommand.run(cmd, environment);
|
||||
if (process == null) {
|
||||
@ -46,16 +48,19 @@ class FFcommandExecuteAsyncTask extends AsyncTask<Void, String, CommandResult> i
|
||||
}
|
||||
Log.d("Running publishing updates method");
|
||||
checkAndUpdateProcess();
|
||||
return CommandResult.getOutputFromProcess(process);
|
||||
ret = CommandResult.getOutputFromProcess(process);
|
||||
outputStringBuilder.append(ret.output);
|
||||
} catch (TimeoutException e) {
|
||||
Log.e("FFmpeg binary timed out", e);
|
||||
return new CommandResult(false, e.getMessage());
|
||||
ret = new CommandResult(false, e.getMessage());
|
||||
outputStringBuilder.append(ret.output);
|
||||
} catch (Exception e) {
|
||||
Log.e("Error running FFmpeg binary", e);
|
||||
} finally {
|
||||
Util.destroyProcess(process);
|
||||
}
|
||||
return CommandResult.getDummyFailureResponse();
|
||||
output = outputStringBuilder.toString();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -68,7 +73,6 @@ class FFcommandExecuteAsyncTask extends AsyncTask<Void, String, CommandResult> i
|
||||
@Override
|
||||
protected void onPostExecute(CommandResult commandResult) {
|
||||
if (ffmpegExecuteResponseHandler != null) {
|
||||
output += commandResult.output;
|
||||
if (commandResult.success) {
|
||||
ffmpegExecuteResponseHandler.onSuccess(output);
|
||||
} else {
|
||||
@ -107,7 +111,7 @@ class FFcommandExecuteAsyncTask extends AsyncTask<Void, String, CommandResult> i
|
||||
return;
|
||||
}
|
||||
|
||||
output += line + "\n";
|
||||
outputStringBuilder.append(line); outputStringBuilder.append("\n");
|
||||
publishProgress(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -6,6 +6,7 @@ import android.os.AsyncTask;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class FFprobe implements FFbinaryInterface {
|
||||
|
||||
private final FFbinaryContextProvider context;
|
||||
@ -22,12 +23,7 @@ public class FFprobe implements FFbinaryInterface {
|
||||
|
||||
public static FFprobe getInstance(final Context context) {
|
||||
if (instance == null) {
|
||||
instance = new FFprobe(new FFbinaryContextProvider() {
|
||||
@Override
|
||||
public Context provide() {
|
||||
return context;
|
||||
}
|
||||
});
|
||||
instance = new FFprobe(() -> context);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
org.gradle.jvmargs=-Xmx2048m -XX:+UseParallelGC
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
|
@ -18,16 +18,15 @@ application {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(Ktor.slf4j)
|
||||
implementation(Ktor.clientCore)
|
||||
implementation(Ktor.clientJson)
|
||||
implementation(Ktor.clientApache)
|
||||
implementation(Ktor.clientLogging)
|
||||
implementation(Ktor.clientSerialization)
|
||||
implementation(Serialization.json)
|
||||
with(deps) {
|
||||
implementation(slf4j.simple)
|
||||
implementation(bundles.ktor)
|
||||
implementation(ktor.client.apache)
|
||||
implementation(kotlinx.serialization.json)
|
||||
|
||||
// testDeps
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:1.5.21")
|
||||
// testDep
|
||||
testImplementation(kotlin.kotlinTestJunit)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
|
@ -14,6 +14,16 @@
|
||||
* * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
enableFeaturePreview("VERSION_CATALOGS")
|
||||
dependencyResolutionManagement {
|
||||
@Suppress("UnstableApiUsage")
|
||||
versionCatalogs {
|
||||
create("deps") {
|
||||
from(files("buildSrc/deps.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "spotiflyer"
|
||||
|
||||
include(
|
||||
@ -32,5 +42,5 @@ include(
|
||||
":desktop",
|
||||
":web-app",
|
||||
//":console-app",
|
||||
":maintenance-tasks"
|
||||
":maintenance-tasks",
|
||||
)
|
||||
|
@ -21,20 +21,17 @@ plugins {
|
||||
group = "com.shabinder"
|
||||
version = "0.1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
//maven(url = "https://dl.bintray.com/kotlin/kotlin-js-wrappers")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-js:1.5.21")
|
||||
implementation(Koin.core)
|
||||
implementation(Extras.kermit)
|
||||
implementation(Decompose.decompose)
|
||||
implementation(MVIKotlin.mvikotlin)
|
||||
implementation(MVIKotlin.coroutines)
|
||||
implementation(MVIKotlin.mvikotlinMain)
|
||||
implementation(MVIKotlin.mvikotlinLogging)
|
||||
with(deps) {
|
||||
implementation(koin.core)
|
||||
implementation(decompose.dep)
|
||||
implementation(ktor.client.js)
|
||||
with(bundles) {
|
||||
implementation(mviKotlin)
|
||||
implementation(ktor)
|
||||
implementation(kotlin.js.wrappers)
|
||||
}
|
||||
}
|
||||
implementation(project(":common:root"))
|
||||
implementation(project(":common:main"))
|
||||
implementation(project(":common:list"))
|
||||
@ -43,27 +40,7 @@ dependencies {
|
||||
implementation(project(":common:providers"))
|
||||
implementation(project(":common:core-components"))
|
||||
implementation(project(":common:dependency-injection"))
|
||||
implementation("co.touchlab:stately-common:1.1.7")
|
||||
implementation("dev.icerock.moko:parcelize:${Versions.mokoParcelize}")
|
||||
// implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1")
|
||||
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2") {
|
||||
// https://youtrack.jetbrains.com/issue/KTOR-2670
|
||||
@Suppress("DEPRECATION")
|
||||
isForce = true
|
||||
}
|
||||
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1-native-mt") {
|
||||
@Suppress("DEPRECATION")
|
||||
isForce = true
|
||||
}
|
||||
|
||||
with(KotlinJSWrappers) {
|
||||
implementation(enforcedPlatform(bom))
|
||||
implementation(kotlinReact)
|
||||
implementation(kotlinReactDom)
|
||||
implementation(kotlinStyled)
|
||||
}
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-js:${deps.kotlin.kotlinGradlePlugin.get().versionConstraint.requiredVersion}")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
@ -23,21 +23,25 @@ import com.arkivanov.mvikotlin.logging.store.LoggingStoreFactory
|
||||
import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
|
||||
import com.shabinder.common.core_components.file_manager.DownloadProgressFlow
|
||||
import com.shabinder.common.core_components.preference_manager.PreferenceManager
|
||||
import com.shabinder.common.di.ApplicationInit
|
||||
import com.shabinder.common.models.Actions
|
||||
import com.shabinder.common.models.PlatformActions
|
||||
import com.shabinder.common.models.TrackDetails
|
||||
import com.shabinder.common.root.SpotiFlyerRoot
|
||||
import com.shabinder.database.Database
|
||||
import extras.renderableChild
|
||||
import react.*
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.RComponent
|
||||
import react.State
|
||||
import root.RootR
|
||||
|
||||
external interface AppProps : RProps {
|
||||
external interface AppProps : PropsWithChildren {
|
||||
var dependencies: AppDependencies
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.App(attrs: AppProps.() -> Unit): ReactElement {
|
||||
fun RBuilder.App(attrs: AppProps.() -> Unit) {
|
||||
return child(App::class) {
|
||||
this.attrs(attrs)
|
||||
}
|
||||
@ -46,7 +50,7 @@ fun RBuilder.App(attrs: AppProps.() -> Unit): ReactElement {
|
||||
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED", "NON_EXPORTABLE_TYPE")
|
||||
@OptIn(ExperimentalJsExport::class)
|
||||
@JsExport
|
||||
class App(props: AppProps) : RComponent<AppProps, RState>(props) {
|
||||
class App(props: AppProps) : RComponent<AppProps, State>(props) {
|
||||
|
||||
private val lifecycle = LifecycleRegistry()
|
||||
private val ctx = DefaultComponentContext(lifecycle = lifecycle)
|
||||
@ -62,6 +66,7 @@ class App(props: AppProps) : RComponent<AppProps, RState>(props) {
|
||||
override val fetchQuery = dependencies.fetchPlatformQueryResult
|
||||
override val fileManager = dependencies.fileManager
|
||||
override val analyticsManager = dependencies.analyticsManager
|
||||
override val appInit: ApplicationInit = dependencies.appInit
|
||||
override val preferenceManager: PreferenceManager = dependencies.preferenceManager
|
||||
override val database: Database? = fileManager.db
|
||||
override val downloadProgressFlow = DownloadProgressFlow
|
||||
|
@ -18,6 +18,7 @@ import co.touchlab.kermit.Kermit
|
||||
import com.shabinder.common.core_components.analytics.AnalyticsManager
|
||||
import com.shabinder.common.core_components.file_manager.FileManager
|
||||
import com.shabinder.common.core_components.preference_manager.PreferenceManager
|
||||
import com.shabinder.common.di.ApplicationInit
|
||||
import com.shabinder.common.di.initKoin
|
||||
import com.shabinder.common.providers.FetchPlatformQueryResult
|
||||
import kotlinx.browser.document
|
||||
@ -42,6 +43,7 @@ object AppDependencies : KoinComponent {
|
||||
val fetchPlatformQueryResult: FetchPlatformQueryResult
|
||||
val preferenceManager: PreferenceManager
|
||||
val analyticsManager: AnalyticsManager
|
||||
val appInit: ApplicationInit
|
||||
init {
|
||||
initKoin()
|
||||
fileManager = get()
|
||||
@ -49,5 +51,6 @@ object AppDependencies : KoinComponent {
|
||||
fetchPlatformQueryResult = get()
|
||||
preferenceManager = get()
|
||||
analyticsManager = get()
|
||||
appInit = get()
|
||||
}
|
||||
}
|
@ -18,16 +18,16 @@ package extras
|
||||
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import com.arkivanov.decompose.value.ValueObserver
|
||||
import react.PropsWithChildren
|
||||
import react.RComponent
|
||||
import react.RProps
|
||||
import react.RState
|
||||
import react.State
|
||||
import react.setState
|
||||
|
||||
|
||||
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED", "NON_EXPORTABLE_TYPE")
|
||||
@OptIn(ExperimentalJsExport::class)
|
||||
@JsExport
|
||||
abstract class RenderableComponent<T: Any, S: RState>(
|
||||
abstract class RenderableComponent<T : Any, S : State>(
|
||||
props: Props<T>,
|
||||
initialState: S
|
||||
) : RComponent<Props<T>, S>(props) {
|
||||
@ -60,7 +60,6 @@ abstract class RenderableComponent<T: Any, S: RState>(
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected class Subscription<T : Any>(
|
||||
val value: Value<T>,
|
||||
val observer: ValueObserver<T>
|
||||
@ -72,8 +71,8 @@ abstract class RenderableComponent<T: Any, S: RState>(
|
||||
@JsExport
|
||||
class RStateWrapper<T>(
|
||||
var model: T
|
||||
) : RState
|
||||
) : State
|
||||
|
||||
external interface Props<T : Any> : RProps {
|
||||
external interface Props<T : Any> : PropsWithChildren {
|
||||
var component: T
|
||||
}
|
@ -17,39 +17,49 @@
|
||||
package home
|
||||
|
||||
import Styles
|
||||
import kotlinx.css.*
|
||||
import kotlinx.css.borderRadius
|
||||
import kotlinx.css.height
|
||||
import kotlinx.css.margin
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.width
|
||||
import kotlinx.html.id
|
||||
import react.*
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.dom.attrs
|
||||
import styled.*
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledA
|
||||
import styled.styledDiv
|
||||
import styled.styledForm
|
||||
import styled.styledImg
|
||||
|
||||
external interface IconListProps : RProps {
|
||||
var iconsAndPlatforms: Map<String,String>
|
||||
var isBadge:Boolean
|
||||
external interface IconListProps : PropsWithChildren {
|
||||
var iconsAndPlatforms: Map<String, String>
|
||||
var isBadge: Boolean
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.IconList(handler:IconListProps.() -> Unit): ReactElement {
|
||||
return child(iconList){
|
||||
fun RBuilder.IconList(handler: IconListProps.() -> Unit) {
|
||||
return child(iconList) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val iconList = functionalComponent<IconListProps>("IconList") { props ->
|
||||
private val iconList = functionComponent<IconListProps>("IconList") { props ->
|
||||
|
||||
styledDiv {
|
||||
css {
|
||||
margin(18.px)
|
||||
if(props.isBadge) {
|
||||
classes = mutableListOf("info-banners")
|
||||
if (props.isBadge) {
|
||||
classes.add("info-banners")
|
||||
}
|
||||
+ Styles.makeRow
|
||||
+Styles.makeRow
|
||||
}
|
||||
val firstElem = props.iconsAndPlatforms.keys.elementAt(1)
|
||||
for((icon,platformLink) in props.iconsAndPlatforms){
|
||||
if(icon == firstElem && props.isBadge){
|
||||
for ((icon, platformLink) in props.iconsAndPlatforms) {
|
||||
if (icon == firstElem && props.isBadge) {
|
||||
//<form><script src="https://checkout.razorpay.com/v1/payment-button.js" data-payment_button_id="pl_GnKuuDBdBu0ank" async> </script> </form>
|
||||
styledForm {
|
||||
attrs {
|
||||
@ -57,13 +67,13 @@ private val iconList = functionalComponent<IconListProps>("IconList") { props ->
|
||||
}
|
||||
}
|
||||
}
|
||||
styledA(href = platformLink,target="_blank"){
|
||||
styledA(href = platformLink, target = "_blank") {
|
||||
styledImg {
|
||||
attrs {
|
||||
src = icon
|
||||
}
|
||||
css {
|
||||
classes = mutableListOf("glow-button")
|
||||
classes.add("glow-button")
|
||||
margin(8.px)
|
||||
if (!props.isBadge) {
|
||||
height = 42.px
|
||||
|
@ -18,34 +18,32 @@ package home
|
||||
|
||||
import kotlinx.css.em
|
||||
import kotlinx.css.fontSize
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.RProps
|
||||
import react.ReactElement
|
||||
import react.child
|
||||
import react.functionalComponent
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
import styled.styledH1
|
||||
|
||||
external interface MessageProps : RProps {
|
||||
external interface MessageProps : PropsWithChildren {
|
||||
var text: String
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.Message(handler:MessageProps.() -> Unit): ReactElement {
|
||||
return child(message){
|
||||
fun RBuilder.Message(handler: MessageProps.() -> Unit) {
|
||||
return child(message) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val message = functionalComponent<MessageProps>("Message") { props->
|
||||
private val message = functionComponent<MessageProps>("Message") { props ->
|
||||
styledDiv {
|
||||
styledH1 {
|
||||
+ props.text
|
||||
+props.text
|
||||
css {
|
||||
classes = mutableListOf("headingTitle")
|
||||
classes.add("headingTitle")
|
||||
fontSize = 2.6.em
|
||||
}
|
||||
}
|
||||
|
@ -22,32 +22,35 @@ import kotlinx.html.js.onChangeFunction
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import kotlinx.html.js.onKeyDownFunction
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.RProps
|
||||
import react.child
|
||||
import react.dom.attrs
|
||||
import react.functionalComponent
|
||||
import styled.*
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledButton
|
||||
import styled.styledDiv
|
||||
import styled.styledImg
|
||||
import styled.styledInput
|
||||
|
||||
external interface SearchbarProps : RProps {
|
||||
external interface SearchbarProps : PropsWithChildren {
|
||||
var link: String
|
||||
var search:(String)->Unit
|
||||
var onLinkChange:(String)->Unit
|
||||
var search: (String) -> Unit
|
||||
var onLinkChange: (String) -> Unit
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.SearchBar(handler:SearchbarProps.() -> Unit) = child(searchbar){
|
||||
fun RBuilder.SearchBar(handler: SearchbarProps.() -> Unit) = child(searchbar) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
|
||||
val searchbar = functionalComponent<SearchbarProps>("SearchBar"){ props ->
|
||||
styledDiv{
|
||||
val searchbar = functionComponent<SearchbarProps>("SearchBar") { props ->
|
||||
styledDiv {
|
||||
css {
|
||||
classes = mutableListOf("searchBox")
|
||||
classes.add("searchBox")
|
||||
}
|
||||
styledInput(type = InputType.url){
|
||||
styledInput(type = InputType.url) {
|
||||
attrs {
|
||||
placeholder = "Search"
|
||||
onChangeFunction = {
|
||||
@ -55,30 +58,30 @@ val searchbar = functionalComponent<SearchbarProps>("SearchBar"){ props ->
|
||||
props.onLinkChange(target.value)
|
||||
}
|
||||
this.onKeyDownFunction = {
|
||||
if(it.asDynamic().key == "Enter") {
|
||||
if(props.link.isEmpty()) window.alert("Enter a Link from Supported Platforms")
|
||||
if (it.asDynamic().key == "Enter") {
|
||||
if (props.link.isEmpty()) window.alert("Enter a Link from Supported Platforms")
|
||||
else props.search(props.link)
|
||||
}
|
||||
}
|
||||
value = props.link
|
||||
}
|
||||
css {
|
||||
classes = mutableListOf("searchInput")
|
||||
classes.add("searchInput")
|
||||
}
|
||||
}
|
||||
styledButton {
|
||||
attrs {
|
||||
onClickFunction = {
|
||||
if(props.link.isEmpty()) window.alert("Enter a Link from Supported Platforms")
|
||||
if (props.link.isEmpty()) window.alert("Enter a Link from Supported Platforms")
|
||||
else props.search(props.link)
|
||||
}
|
||||
}
|
||||
css {
|
||||
classes = mutableListOf("searchButton")
|
||||
classes.add("searchButton")
|
||||
}
|
||||
styledImg(src = "search.svg") {
|
||||
css {
|
||||
classes = mutableListOf("search-icon")
|
||||
classes.add("search-icon")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,42 +23,44 @@ import kotlinx.css.justifyContent
|
||||
import kotlinx.css.marginBottom
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.width
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.RProps
|
||||
import react.ReactElement
|
||||
import react.child
|
||||
import react.functionalComponent
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
import styled.styledSpan
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.CircularProgressBar(handler: CircularProgressBarProps.() -> Unit): ReactElement {
|
||||
return child(circularProgressBar){
|
||||
fun RBuilder.CircularProgressBar(handler: CircularProgressBarProps.() -> Unit) {
|
||||
return child(circularProgressBar) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
external interface CircularProgressBarProps : RProps {
|
||||
var progress:Int
|
||||
external interface CircularProgressBarProps : PropsWithChildren {
|
||||
var progress: Int
|
||||
}
|
||||
|
||||
private val circularProgressBar = functionalComponent<CircularProgressBarProps>("Circular-Progress-Bar") { props->
|
||||
private val circularProgressBar = functionComponent<CircularProgressBarProps>("Circular-Progress-Bar") { props ->
|
||||
styledDiv {
|
||||
styledSpan { +"${props.progress}%" }
|
||||
styledDiv{
|
||||
styledDiv {
|
||||
css {
|
||||
classes = mutableListOf("left-half-clipper")
|
||||
classes.add("left-half-clipper")
|
||||
}
|
||||
styledDiv{ css { classes = mutableListOf("first50-bar") } }
|
||||
styledDiv{ css { classes = mutableListOf("value-bar") } }
|
||||
styledDiv { css { classes.add("first50-bar") } }
|
||||
styledDiv { css { classes.add("value-bar") } }
|
||||
}
|
||||
css{
|
||||
css {
|
||||
display = Display.flex
|
||||
justifyContent = JustifyContent.center
|
||||
classes = mutableListOf("progress-circle","p${props.progress}").apply { if(props.progress>50) add("over50") }
|
||||
classes.addAll(
|
||||
mutableListOf(
|
||||
"progress-circle",
|
||||
"p${props.progress}"
|
||||
).apply { if (props.progress > 50) add("over50") })
|
||||
width = 50.px
|
||||
marginBottom = 65.px
|
||||
}
|
||||
|
@ -16,32 +16,45 @@
|
||||
|
||||
package list
|
||||
|
||||
import kotlinx.css.*
|
||||
import kotlinx.css.Align
|
||||
import kotlinx.css.Display
|
||||
import kotlinx.css.FlexDirection
|
||||
import kotlinx.css.TextAlign
|
||||
import kotlinx.css.alignItems
|
||||
import kotlinx.css.display
|
||||
import kotlinx.css.flexDirection
|
||||
import kotlinx.css.height
|
||||
import kotlinx.css.marginTop
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.textAlign
|
||||
import kotlinx.css.width
|
||||
import kotlinx.html.id
|
||||
import react.*
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.dom.attrs
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
import styled.styledH1
|
||||
import styled.styledImg
|
||||
|
||||
external interface CoverImageProps : RProps {
|
||||
external interface CoverImageProps : PropsWithChildren {
|
||||
var coverImageURL: String
|
||||
var coverName: String
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.CoverImage(handler: CoverImageProps.() -> Unit): ReactElement {
|
||||
return child(coverImage){
|
||||
fun RBuilder.CoverImage(handler: CoverImageProps.() -> Unit) {
|
||||
return child(coverImage) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val coverImage = functionalComponent<CoverImageProps>("CoverImage"){ props ->
|
||||
private val coverImage = functionComponent<CoverImageProps>("CoverImage") { props ->
|
||||
styledDiv {
|
||||
styledImg(src= props.coverImageURL){
|
||||
styledImg(src = props.coverImageURL) {
|
||||
css {
|
||||
height = 220.px
|
||||
width = 220.px
|
||||
|
@ -16,42 +16,56 @@
|
||||
|
||||
package list
|
||||
|
||||
import kotlinx.css.*
|
||||
import kotlinx.css.Align
|
||||
import kotlinx.css.Display
|
||||
import kotlinx.css.JustifyContent
|
||||
import kotlinx.css.WhiteSpace
|
||||
import kotlinx.css.alignItems
|
||||
import kotlinx.css.display
|
||||
import kotlinx.css.fontSize
|
||||
import kotlinx.css.height
|
||||
import kotlinx.css.justifyContent
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.whiteSpace
|
||||
import kotlinx.html.id
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import react.*
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.dom.attrs
|
||||
import react.functionComponent
|
||||
import react.useEffect
|
||||
import react.useState
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
import styled.styledH5
|
||||
import styled.styledImg
|
||||
|
||||
external interface DownloadAllButtonProps : RProps {
|
||||
var isActive:Boolean
|
||||
var link : String
|
||||
var downloadAll:()->Unit
|
||||
external interface DownloadAllButtonProps : PropsWithChildren {
|
||||
var isActive: Boolean
|
||||
var link: String
|
||||
var downloadAll: () -> Unit
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.DownloadAllButton(handler: DownloadAllButtonProps.() -> Unit): ReactElement {
|
||||
return child(downloadAllButton){
|
||||
fun RBuilder.DownloadAllButton(handler: DownloadAllButtonProps.() -> Unit) {
|
||||
return child(downloadAllButton) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val downloadAllButton = functionalComponent<DownloadAllButtonProps>("DownloadAllButton") { props->
|
||||
private val downloadAllButton = functionComponent<DownloadAllButtonProps>("DownloadAllButton") { props ->
|
||||
|
||||
val (isClicked,setClicked) = useState(false)
|
||||
val (isClicked, setClicked) = useState(false)
|
||||
|
||||
useEffect(mutableListOf(props.link)){
|
||||
useEffect(mutableListOf(props.link)) {
|
||||
setClicked(false)
|
||||
}
|
||||
|
||||
if(props.isActive){
|
||||
if(isClicked) {
|
||||
styledDiv{
|
||||
if (props.isActive) {
|
||||
if (isClicked) {
|
||||
styledDiv {
|
||||
css {
|
||||
display = Display.flex
|
||||
alignItems = Align.center
|
||||
@ -60,8 +74,7 @@ private val downloadAllButton = functionalComponent<DownloadAllButtonProps>("Dow
|
||||
}
|
||||
LoadingSpinner { }
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
styledDiv {
|
||||
attrs {
|
||||
onClickFunction = {
|
||||
@ -71,9 +84,9 @@ private val downloadAllButton = functionalComponent<DownloadAllButtonProps>("Dow
|
||||
}
|
||||
styledDiv {
|
||||
|
||||
styledImg(src = "download.svg",alt = "Download All Button") {
|
||||
styledImg(src = "download.svg", alt = "Download All Button") {
|
||||
css {
|
||||
classes = mutableListOf("download-all-icon")
|
||||
classes.add("download-all-icon")
|
||||
height = 32.px
|
||||
}
|
||||
}
|
||||
@ -82,7 +95,7 @@ private val downloadAllButton = functionalComponent<DownloadAllButtonProps>("Dow
|
||||
attrs {
|
||||
id = "download-all-text"
|
||||
}
|
||||
+ "Download All"
|
||||
+"Download All"
|
||||
css {
|
||||
whiteSpace = WhiteSpace.nowrap
|
||||
fontSize = 15.px
|
||||
@ -90,13 +103,13 @@ private val downloadAllButton = functionalComponent<DownloadAllButtonProps>("Dow
|
||||
}
|
||||
|
||||
css {
|
||||
classes = mutableListOf("download-icon")
|
||||
classes.add("download-icon")
|
||||
display = Display.flex
|
||||
alignItems = Align.center
|
||||
}
|
||||
}
|
||||
css {
|
||||
classes = mutableListOf("download-button")
|
||||
classes.add("download-button")
|
||||
display = Display.flex
|
||||
alignItems = Align.center
|
||||
}
|
||||
|
@ -17,31 +17,37 @@
|
||||
package list
|
||||
|
||||
import com.shabinder.common.models.DownloadStatus
|
||||
import kotlinx.css.*
|
||||
import kotlinx.css.borderRadius
|
||||
import kotlinx.css.em
|
||||
import kotlinx.css.margin
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.width
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import react.*
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.dom.attrs
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
import styled.styledImg
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.DownloadButton(handler: DownloadButtonProps.() -> Unit): ReactElement {
|
||||
return child(downloadButton){
|
||||
fun RBuilder.DownloadButton(handler: DownloadButtonProps.() -> Unit) {
|
||||
return child(downloadButton) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
external interface DownloadButtonProps : RProps {
|
||||
var onClick:()->Unit
|
||||
var status :DownloadStatus
|
||||
external interface DownloadButtonProps : PropsWithChildren {
|
||||
var onClick: () -> Unit
|
||||
var status: DownloadStatus
|
||||
}
|
||||
|
||||
private val downloadButton = functionalComponent<DownloadButtonProps>("Circular-Progress-Bar") { props->
|
||||
private val downloadButton = functionComponent<DownloadButtonProps>("Circular-Progress-Bar") { props ->
|
||||
styledDiv {
|
||||
val src = when(props.status){
|
||||
val src = when (props.status) {
|
||||
is DownloadStatus.NotDownloaded -> "download-gradient.svg"
|
||||
is DownloadStatus.Downloaded -> "check.svg"
|
||||
is DownloadStatus.Failed -> "error.svg"
|
||||
@ -59,7 +65,7 @@ private val downloadButton = functionalComponent<DownloadButtonProps>("Circular-
|
||||
}
|
||||
}
|
||||
css {
|
||||
classes = mutableListOf("glow-button")
|
||||
classes.add("glow-button")
|
||||
borderRadius = 100.px
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ class ListScreen(
|
||||
}
|
||||
|
||||
css {
|
||||
classes = mutableListOf("list-screen")
|
||||
classes.add("list-screen")
|
||||
display = Display.flex
|
||||
padding(8.px)
|
||||
flexDirection = FlexDirection.column
|
||||
|
@ -24,43 +24,41 @@ import kotlinx.css.flexGrow
|
||||
import kotlinx.css.height
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.width
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.RProps
|
||||
import react.ReactElement
|
||||
import react.child
|
||||
import react.functionalComponent
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.LoadingAnim(handler: RProps.() -> Unit): ReactElement {
|
||||
return child(loadingAnim){
|
||||
fun RBuilder.LoadingAnim(handler: PropsWithChildren.() -> Unit) {
|
||||
return child(loadingAnim) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val loadingAnim = functionalComponent<RProps>("Loading Animation") {
|
||||
styledDiv{
|
||||
private val loadingAnim = functionComponent<PropsWithChildren>("Loading Animation") {
|
||||
styledDiv {
|
||||
css {
|
||||
flexGrow = 1.0
|
||||
display = Display.flex
|
||||
alignItems = Align.center
|
||||
}
|
||||
styledDiv {
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube1") } }
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube2") } }
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube3") } }
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube4") } }
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube5") } }
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube6") } }
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube7") } }
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube8") } }
|
||||
styledDiv { css { classes = mutableListOf("sk-cube sk-cube9") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube1") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube2") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube3") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube4") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube5") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube6") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube7") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube8") } }
|
||||
styledDiv { css { classes.add("sk-cube sk-cube9") } }
|
||||
|
||||
css {
|
||||
classes = mutableListOf("sk-cube-grid")
|
||||
classes.add("sk-cube-grid")
|
||||
height = 60.px
|
||||
width = 60.px
|
||||
}
|
||||
|
@ -19,31 +19,29 @@ package list
|
||||
import kotlinx.css.marginRight
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.width
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.RProps
|
||||
import react.ReactElement
|
||||
import react.child
|
||||
import react.functionalComponent
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.LoadingSpinner(handler: RProps.() -> Unit): ReactElement {
|
||||
return child(loadingSpinner){
|
||||
fun RBuilder.LoadingSpinner(handler: PropsWithChildren.() -> Unit) {
|
||||
return child(loadingSpinner) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val loadingSpinner = functionalComponent<RProps>("Loading-Spinner") {
|
||||
private val loadingSpinner = functionComponent<PropsWithChildren>("Loading-Spinner") {
|
||||
styledDiv {
|
||||
styledDiv{}
|
||||
styledDiv{}
|
||||
styledDiv{}
|
||||
styledDiv{}
|
||||
css{
|
||||
classes = mutableListOf("lds-ring")
|
||||
styledDiv {}
|
||||
styledDiv {}
|
||||
styledDiv {}
|
||||
styledDiv {}
|
||||
css {
|
||||
classes.add("lds-ring")
|
||||
width = 50.px
|
||||
marginRight = 8.px
|
||||
}
|
||||
|
@ -18,30 +18,61 @@ package list
|
||||
|
||||
import com.shabinder.common.models.DownloadStatus
|
||||
import com.shabinder.common.models.TrackDetails
|
||||
import kotlinx.css.*
|
||||
import kotlinx.css.Align
|
||||
import kotlinx.css.Display
|
||||
import kotlinx.css.FlexDirection
|
||||
import kotlinx.css.Overflow
|
||||
import kotlinx.css.TextAlign
|
||||
import kotlinx.css.TextOverflow
|
||||
import kotlinx.css.WhiteSpace
|
||||
import kotlinx.css.alignItems
|
||||
import kotlinx.css.display
|
||||
import kotlinx.css.em
|
||||
import kotlinx.css.flexDirection
|
||||
import kotlinx.css.flexGrow
|
||||
import kotlinx.css.fontSize
|
||||
import kotlinx.css.height
|
||||
import kotlinx.css.margin
|
||||
import kotlinx.css.minWidth
|
||||
import kotlinx.css.overflow
|
||||
import kotlinx.css.padding
|
||||
import kotlinx.css.paddingRight
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.textAlign
|
||||
import kotlinx.css.textOverflow
|
||||
import kotlinx.css.whiteSpace
|
||||
import kotlinx.css.width
|
||||
import kotlinx.html.id
|
||||
import react.*
|
||||
import react.PropsWithChildren
|
||||
import react.RBuilder
|
||||
import react.dom.attrs
|
||||
import styled.*
|
||||
import react.functionComponent
|
||||
import react.useEffect
|
||||
import react.useState
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
import styled.styledH3
|
||||
import styled.styledH4
|
||||
import styled.styledImg
|
||||
|
||||
external interface TrackItemProps : RProps {
|
||||
var details:TrackDetails
|
||||
var downloadTrack:(TrackDetails)->Unit
|
||||
external interface TrackItemProps : PropsWithChildren {
|
||||
var details: TrackDetails
|
||||
var downloadTrack: (TrackDetails) -> Unit
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.TrackItem(handler: TrackItemProps.() -> Unit): ReactElement {
|
||||
return child(trackItem){
|
||||
fun RBuilder.TrackItem(handler: TrackItemProps.() -> Unit) {
|
||||
return child(trackItem) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val trackItem = functionalComponent<TrackItemProps>("Track-Item"){ props ->
|
||||
val (downloadStatus,setDownloadStatus) = useState(props.details.downloaded)
|
||||
private val trackItem = functionComponent<TrackItemProps>("Track-Item") { props ->
|
||||
val (downloadStatus, setDownloadStatus) = useState(props.details.downloaded)
|
||||
val details = props.details
|
||||
useEffect(listOf(props.details)){
|
||||
useEffect(listOf(props.details)) {
|
||||
setDownloadStatus(props.details.downloaded)
|
||||
}
|
||||
styledDiv {
|
||||
@ -63,14 +94,14 @@ private val trackItem = functionalComponent<TrackItemProps>("Track-Item"){ props
|
||||
flexDirection = FlexDirection.column
|
||||
margin(8.px)
|
||||
}
|
||||
styledDiv{
|
||||
styledDiv {
|
||||
css {
|
||||
height = 40.px
|
||||
alignItems = Align.center
|
||||
display = Display.flex
|
||||
}
|
||||
styledH3 {
|
||||
+ details.title
|
||||
+details.title
|
||||
css {
|
||||
padding(8.px)
|
||||
fontSize = 1.3.em
|
||||
@ -87,7 +118,7 @@ private val trackItem = functionalComponent<TrackItemProps>("Track-Item"){ props
|
||||
display = Display.flex
|
||||
}
|
||||
styledH4 {
|
||||
+ details.artists.joinToString(",")
|
||||
+details.artists.joinToString(",")
|
||||
css {
|
||||
flexGrow = 1.0
|
||||
padding(8.px)
|
||||
@ -109,12 +140,12 @@ private val trackItem = functionalComponent<TrackItemProps>("Track-Item"){ props
|
||||
whiteSpace = WhiteSpace.nowrap
|
||||
overflow = Overflow.hidden
|
||||
}
|
||||
+ "${details.durationSec/60} min, ${details.durationSec%60} sec"
|
||||
+"${details.durationSec / 60} min, ${details.durationSec % 60} sec"
|
||||
}
|
||||
}
|
||||
}
|
||||
when(downloadStatus){
|
||||
is DownloadStatus.NotDownloaded ->{
|
||||
when (downloadStatus) {
|
||||
is DownloadStatus.NotDownloaded -> {
|
||||
DownloadButton {
|
||||
onClick = {
|
||||
setDownloadStatus(DownloadStatus.Queued)
|
||||
@ -152,7 +183,7 @@ private val trackItem = functionalComponent<TrackItemProps>("Track-Item"){ props
|
||||
|
||||
css {
|
||||
alignItems = Align.center
|
||||
display =Display.flex
|
||||
display = Display.flex
|
||||
paddingRight = 16.px
|
||||
}
|
||||
}
|
||||
|
@ -16,36 +16,55 @@
|
||||
|
||||
package navbar
|
||||
|
||||
import kotlinx.css.*
|
||||
import kotlinx.css.Align
|
||||
import kotlinx.css.Display
|
||||
import kotlinx.css.LinearDimension
|
||||
import kotlinx.css.alignItems
|
||||
import kotlinx.css.display
|
||||
import kotlinx.css.filter
|
||||
import kotlinx.css.fontSize
|
||||
import kotlinx.css.height
|
||||
import kotlinx.css.margin
|
||||
import kotlinx.css.marginLeft
|
||||
import kotlinx.css.marginRight
|
||||
import kotlinx.css.px
|
||||
import kotlinx.css.width
|
||||
import kotlinx.html.id
|
||||
import kotlinx.html.js.onBlurFunction
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import react.*
|
||||
import react.RBuilder
|
||||
import react.RProps
|
||||
import react.dom.attrs
|
||||
import styled.*
|
||||
import react.functionComponent
|
||||
import styled.css
|
||||
import styled.styledA
|
||||
import styled.styledDiv
|
||||
import styled.styledH1
|
||||
import styled.styledImg
|
||||
import styled.styledNav
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun RBuilder.NavBar(handler: NavBarProps.() -> Unit): ReactElement{
|
||||
return child(navBar){
|
||||
fun RBuilder.NavBar(handler: NavBarProps.() -> Unit) {
|
||||
return child(navBar) {
|
||||
attrs {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
external interface NavBarProps:RProps{
|
||||
external interface NavBarProps : RProps {
|
||||
var isBackVisible: Boolean
|
||||
var popBackToHomeScreen: () -> Unit
|
||||
}
|
||||
|
||||
|
||||
private val navBar = functionalComponent<NavBarProps>("NavBar") { props ->
|
||||
private val navBar = functionComponent<NavBarProps>("NavBar") { props ->
|
||||
|
||||
styledNav {
|
||||
css {
|
||||
+NavBarStyles.nav
|
||||
}
|
||||
styledDiv{
|
||||
styledDiv {
|
||||
attrs {
|
||||
onClickFunction = {
|
||||
props.popBackToHomeScreen()
|
||||
@ -54,22 +73,22 @@ private val navBar = functionalComponent<NavBarProps>("NavBar") { props ->
|
||||
props.popBackToHomeScreen()
|
||||
}
|
||||
}
|
||||
styledImg(src = "left-arrow.svg",alt = "Back Arrow"){
|
||||
styledImg(src = "left-arrow.svg", alt = "Back Arrow") {
|
||||
css {
|
||||
height = 42.px
|
||||
width = 42.px
|
||||
display = if(props.isBackVisible) Display.inline else Display.none
|
||||
display = if (props.isBackVisible) Display.inline else Display.none
|
||||
filter = "invert(100)"
|
||||
marginRight = 12.px
|
||||
}
|
||||
}
|
||||
}
|
||||
styledA(href = "https://shabinder.github.io/SpotiFlyer/",target="_blank") {
|
||||
styledA(href = "https://shabinder.github.io/SpotiFlyer/", target = "_blank") {
|
||||
css {
|
||||
display = Display.flex
|
||||
alignItems = Align.center
|
||||
}
|
||||
styledImg(src = "spotiflyer.svg",alt = "Logo") {
|
||||
styledImg(src = "spotiflyer.svg", alt = "Logo") {
|
||||
css {
|
||||
height = 42.px
|
||||
width = 42.px
|
||||
@ -80,7 +99,7 @@ private val navBar = functionalComponent<NavBarProps>("NavBar") { props ->
|
||||
attrs {
|
||||
id = "appName"
|
||||
}
|
||||
css{
|
||||
css {
|
||||
fontSize = 46.px
|
||||
margin(horizontal = 14.px)
|
||||
}
|
||||
@ -93,7 +112,7 @@ private val navBar = functionalComponent<NavBarProps>("NavBar") { props ->
|
||||
setCorsMode(corsProxy)
|
||||
}*/
|
||||
|
||||
styledDiv{
|
||||
styledDiv {
|
||||
|
||||
/*styledH4 { + "Extension" }
|
||||
|
||||
@ -125,8 +144,8 @@ private val navBar = functionalComponent<NavBarProps>("NavBar") { props ->
|
||||
}
|
||||
}*/
|
||||
|
||||
styledA(href = "https://github.com/Shabinder/SpotiFlyer/"){
|
||||
styledImg(src = "github.svg"){
|
||||
styledA(href = "https://github.com/Shabinder/SpotiFlyer/") {
|
||||
styledImg(src = "github.svg") {
|
||||
css {
|
||||
height = 42.px
|
||||
width = 42.px
|
||||
|
@ -26,7 +26,6 @@ import home.HomeScreen
|
||||
import list.ListScreen
|
||||
import navbar.NavBar
|
||||
import react.RBuilder
|
||||
import react.RState
|
||||
|
||||
class RootR(props: Props<SpotiFlyerRoot>) : RenderableComponent<SpotiFlyerRoot, State>(
|
||||
props = props,
|
||||
@ -58,4 +57,4 @@ class RootR(props: Props<SpotiFlyerRoot>) : RenderableComponent<SpotiFlyerRoot,
|
||||
@JsExport
|
||||
class State(
|
||||
var routerState: RouterState<*, Child>
|
||||
) : RState
|
||||
) : react.State
|
||||
|
Loading…
Reference in New Issue
Block a user