Build Fixes and updates

This commit is contained in:
shabinder 2021-05-16 02:07:51 +05:30
parent 658cbbaf91
commit b1cef3c265
21 changed files with 88 additions and 94 deletions

View File

@ -31,7 +31,7 @@ object Versions {
const val koin = "3.0.1" const val koin = "3.0.1"
// Logger // Logger
const val kermit = "0.1.8" const val kermit = "0.1.9"
// Internet // Internet
const val ktor = "1.5.4" const val ktor = "1.5.4"

View File

@ -76,9 +76,8 @@ kotlin {
// Extras // Extras
implementation(Extras.kermit) implementation(Extras.kermit)
implementation("co.touchlab:stately-common:1.1.6") implementation("co.touchlab:stately-common:1.1.7")
implementation("dev.icerock.moko:parcelize:0.6.1") implementation("dev.icerock.moko:parcelize:0.6.1")
// implementation("io.github.reactivecircus.cache4k:cache4k:0.2.0-SNAPSHOT") // Local Maven
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3-native-mt") { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3-native-mt") {
isForce = true isForce = true

View File

@ -34,7 +34,7 @@ import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import co.touchlab.kermit.Kermit import co.touchlab.kermit.Kermit
import com.shabinder.common.di.* import com.shabinder.common.di.*
import com.shabinder.common.di.providers.getData import com.shabinder.common.di.providers.get
import com.shabinder.common.di.utils.ParallelExecutor import com.shabinder.common.di.utils.ParallelExecutor
import com.shabinder.common.models.DownloadResult import com.shabinder.common.models.DownloadResult
import com.shabinder.common.models.DownloadStatus import com.shabinder.common.models.DownloadStatus
@ -183,7 +183,7 @@ class ForegroundService : Service(), CoroutineScope {
try { try {
val url = fetcher.youtubeMp3.getMp3DownloadLink(videoID) val url = fetcher.youtubeMp3.getMp3DownloadLink(videoID)
if (url == null) { if (url == null) {
val audioData: Format = ytDownloader.getVideo(videoID).getData() ?: throw Exception("Java YT Dependency Error") val audioData: Format = ytDownloader?.getVideo(videoID)?.get() ?: throw Exception("Java YT Dependency Error")
val ytUrl = audioData.url!! //We Will catch NPE val ytUrl = audioData.url!! //We Will catch NPE
enqueueDownload(ytUrl, track) enqueueDownload(ytUrl, track)
} else enqueueDownload(url, track) } else enqueueDownload(url, track)

View File

@ -60,17 +60,15 @@ fun commonModule(enableNetworkLogs: Boolean) = module {
} }
@ThreadLocal @ThreadLocal
val kotlinxSerializer = KotlinxSerializer( val globalJson = Json {
Json {
isLenient = true isLenient = true
ignoreUnknownKeys = true ignoreUnknownKeys = true
} }
)
fun createHttpClient(enableNetworkLogs: Boolean = false) = HttpClient { fun createHttpClient(enableNetworkLogs: Boolean = false) = HttpClient {
// https://github.com/Kotlin/kotlinx.serialization/issues/1450 // https://github.com/Kotlin/kotlinx.serialization/issues/1450
install(JsonFeature) { install(JsonFeature) {
serializer = KotlinxSerializer() serializer = KotlinxSerializer(globalJson)
} }
// WorkAround for Freezing // WorkAround for Freezing
// Use httpClient.getData / httpClient.postData Extensions // Use httpClient.getData / httpClient.postData Extensions

View File

@ -17,7 +17,6 @@
package com.shabinder.common.di.gaana package com.shabinder.common.di.gaana
import com.shabinder.common.di.currentPlatform import com.shabinder.common.di.currentPlatform
import com.shabinder.common.di.utils.getData
import com.shabinder.common.models.AllPlatforms import com.shabinder.common.models.AllPlatforms
import com.shabinder.common.models.corsProxy import com.shabinder.common.models.corsProxy
import com.shabinder.common.models.gaana.GaanaAlbum import com.shabinder.common.models.gaana.GaanaAlbum
@ -25,7 +24,6 @@ import com.shabinder.common.models.gaana.GaanaArtistDetails
import com.shabinder.common.models.gaana.GaanaArtistTracks import com.shabinder.common.models.gaana.GaanaArtistTracks
import com.shabinder.common.models.gaana.GaanaPlaylist import com.shabinder.common.models.gaana.GaanaPlaylist
import com.shabinder.common.models.gaana.GaanaSong import com.shabinder.common.models.gaana.GaanaSong
import com.shabinder.common.models.methods
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.request.get import io.ktor.client.request.get
@ -53,7 +51,7 @@ interface GaanaRequests {
format: String = "JSON", format: String = "JSON",
limit: Int = 2000 limit: Int = 2000
): GaanaPlaylist { ): GaanaPlaylist {
return httpClient.getData( return httpClient.get(
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit" "$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
) )
} }
@ -70,7 +68,7 @@ interface GaanaRequests {
format: String = "JSON", format: String = "JSON",
limit: Int = 2000 limit: Int = 2000
): GaanaAlbum { ): GaanaAlbum {
return httpClient.getData( return httpClient.get(
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit" "$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
) )
} }
@ -86,7 +84,7 @@ interface GaanaRequests {
seokey: String, seokey: String,
format: String = "JSON", format: String = "JSON",
): GaanaSong { ): GaanaSong {
return httpClient.getData( return httpClient.get(
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format" "$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format"
) )
} }
@ -102,7 +100,7 @@ interface GaanaRequests {
seokey: String, seokey: String,
format: String = "JSON", format: String = "JSON",
): GaanaArtistDetails { ): GaanaArtistDetails {
return httpClient.getData( return httpClient.get(
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format" "$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format"
) )
} }
@ -119,7 +117,7 @@ interface GaanaRequests {
format: String = "JSON", format: String = "JSON",
limit: Int = 50 limit: Int = 50
): GaanaArtistTracks { ): GaanaArtistTracks {
return httpClient.getData( return httpClient.get(
"$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit" "$BASE_URL/?type=$type&subtype=$subtype&seokey=$seokey&token=$TOKEN&format=$format&limit=$limit"
) )
} }

View File

@ -21,6 +21,7 @@ import com.shabinder.common.di.Dir
import com.shabinder.common.di.TokenStore import com.shabinder.common.di.TokenStore
import com.shabinder.common.di.createHttpClient import com.shabinder.common.di.createHttpClient
import com.shabinder.common.di.finalOutputDir import com.shabinder.common.di.finalOutputDir
import com.shabinder.common.di.globalJson
import com.shabinder.common.di.spotify.SpotifyRequests import com.shabinder.common.di.spotify.SpotifyRequests
import com.shabinder.common.di.spotify.authenticateSpotify import com.shabinder.common.di.spotify.authenticateSpotify
import com.shabinder.common.models.NativeAtomicReference import com.shabinder.common.models.NativeAtomicReference
@ -32,6 +33,8 @@ import com.shabinder.common.models.spotify.Source
import com.shabinder.common.models.spotify.Track import com.shabinder.common.models.spotify.Track
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.features.defaultRequest import io.ktor.client.features.defaultRequest
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
import io.ktor.client.request.header import io.ktor.client.request.header
class SpotifyProvider( class SpotifyProvider(
@ -59,9 +62,9 @@ class SpotifyProvider(
defaultRequest { defaultRequest {
header("Authorization", "Bearer ${token.access_token}") header("Authorization", "Bearer ${token.access_token}")
} }
/*install(JsonFeature) { install(JsonFeature) {
serializer = kotlinxSerializer serializer = KotlinxSerializer(globalJson)
}*/ }
}.also { httpClientRef.value = it } }.also { httpClientRef.value = it }
} }
} }

View File

@ -18,7 +18,6 @@ package com.shabinder.common.di.providers
import co.touchlab.kermit.Kermit import co.touchlab.kermit.Kermit
import com.shabinder.common.di.gaana.corsApi import com.shabinder.common.di.gaana.corsApi
import com.shabinder.common.di.utils.postData
import com.shabinder.common.models.TrackDetails import com.shabinder.common.models.TrackDetails
import com.shabinder.common.models.YoutubeTrack import com.shabinder.common.models.YoutubeTrack
import io.github.shabinder.fuzzywuzzy.diffutils.FuzzySearch import io.github.shabinder.fuzzywuzzy.diffutils.FuzzySearch
@ -29,7 +28,6 @@ import io.ktor.http.ContentType
import io.ktor.http.contentType import io.ktor.http.contentType
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.buildJsonArray import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.contentOrNull

View File

@ -18,8 +18,10 @@ package com.shabinder.common.di.providers
import co.touchlab.kermit.Kermit import co.touchlab.kermit.Kermit
import com.shabinder.common.di.Dir import com.shabinder.common.di.Dir
import com.shabinder.common.di.currentPlatform
import com.shabinder.common.di.finalOutputDir import com.shabinder.common.di.finalOutputDir
import com.shabinder.common.di.utils.removeIllegalChars import com.shabinder.common.di.utils.removeIllegalChars
import com.shabinder.common.models.AllPlatforms
import com.shabinder.common.models.DownloadStatus import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.PlatformQueryResult import com.shabinder.common.models.PlatformQueryResult
import com.shabinder.common.models.TrackDetails import com.shabinder.common.models.TrackDetails
@ -35,7 +37,8 @@ class YoutubeProvider(
private val logger: Kermit, private val logger: Kermit,
private val dir: Dir, private val dir: Dir,
) { ) {
val ytDownloader: YoutubeDownloader = YoutubeDownloader() // Youtube Downloader isn't fully compatible with JS Yet
val ytDownloader: YoutubeDownloader? = if(currentPlatform == AllPlatforms.Js) null else YoutubeDownloader()
/* /*
* YT Album Art Schema * YT Album Art Schema
@ -92,7 +95,7 @@ class YoutubeProvider(
) )
result.apply { result.apply {
try { try {
val playlist = ytDownloader.getPlaylist(searchId) val playlist = ytDownloader?.getPlaylist(searchId) ?: return null
val playlistDetails = playlist.details val playlistDetails = playlist.details
val name = playlistDetails.title val name = playlistDetails.title
subFolder = removeIllegalChars(name) subFolder = removeIllegalChars(name)
@ -151,7 +154,7 @@ class YoutubeProvider(
).apply { ).apply {
try { try {
logger.i { searchId } logger.i { searchId }
val video = ytDownloader.getVideo(searchId) val video = ytDownloader?.getVideo(searchId) ?: return null
coverUrl = "https://i.ytimg.com/vi/$searchId/hqdefault.jpg" coverUrl = "https://i.ytimg.com/vi/$searchId/hqdefault.jpg"
val detail = video.videoDetails val detail = video.videoDetails
val name = detail.title?.replace(detail.author?.toUpperCase() ?: "", "", true) val name = detail.title?.replace(detail.author?.toUpperCase() ?: "", "", true)
@ -193,7 +196,7 @@ class YoutubeProvider(
} }
} }
fun YoutubeVideo.getData(): Format? { fun YoutubeVideo.get(): Format? {
return getAudioWithQuality(AudioQuality.high).getOrNull(0) return getAudioWithQuality(AudioQuality.high).getOrNull(0)
?: getAudioWithQuality(AudioQuality.medium).getOrNull(0) ?: getAudioWithQuality(AudioQuality.medium).getOrNull(0)
?: getAudioWithQuality(AudioQuality.low).getOrNull(0) ?: getAudioWithQuality(AudioQuality.low).getOrNull(0)

View File

@ -16,13 +16,14 @@
package com.shabinder.common.di.spotify package com.shabinder.common.di.spotify
import com.shabinder.common.di.kotlinxSerializer import com.shabinder.common.di.globalJson
import com.shabinder.common.models.methods import com.shabinder.common.models.methods
import com.shabinder.common.models.spotify.TokenData import com.shabinder.common.models.spotify.TokenData
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.features.auth.Auth import io.ktor.client.features.auth.Auth
import io.ktor.client.features.auth.providers.basic import io.ktor.client.features.auth.providers.basic
import io.ktor.client.features.json.JsonFeature import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
import io.ktor.client.request.forms.FormDataContent import io.ktor.client.request.forms.FormDataContent
import io.ktor.client.request.post import io.ktor.client.request.post
import io.ktor.http.Parameters import io.ktor.http.Parameters
@ -53,7 +54,7 @@ private val spotifyAuthClient by lazy {
} }
} }
install(JsonFeature) { install(JsonFeature) {
serializer = kotlinxSerializer serializer = KotlinxSerializer(globalJson)
} }
} }
} }

View File

@ -17,7 +17,6 @@
package com.shabinder.common.di.spotify package com.shabinder.common.di.spotify
import com.shabinder.common.di.gaana.corsApi import com.shabinder.common.di.gaana.corsApi
import com.shabinder.common.di.utils.getData
import com.shabinder.common.models.NativeAtomicReference import com.shabinder.common.models.NativeAtomicReference
import com.shabinder.common.models.spotify.Album import com.shabinder.common.models.spotify.Album
import com.shabinder.common.models.spotify.PagingObjectPlaylistTrack import com.shabinder.common.models.spotify.PagingObjectPlaylistTrack
@ -25,13 +24,6 @@ import com.shabinder.common.models.spotify.Playlist
import com.shabinder.common.models.spotify.Track import com.shabinder.common.models.spotify.Track
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.request.* import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.descriptors.ClassSerialDescriptorBuilder
import kotlinx.serialization.json.Json
import kotlinx.serialization.serializer
private val BASE_URL get() = "${corsApi}https://api.spotify.com/v1" private val BASE_URL get() = "${corsApi}https://api.spotify.com/v1"
@ -43,7 +35,7 @@ interface SpotifyRequests {
suspend fun authenticateSpotifyClient(override: Boolean = false) suspend fun authenticateSpotifyClient(override: Boolean = false)
suspend fun getPlaylist(playlistID: String): Playlist { suspend fun getPlaylist(playlistID: String): Playlist {
return httpClient.getData("$BASE_URL/playlists/$playlistID") return httpClient.get("$BASE_URL/playlists/$playlistID")
} }
suspend fun getPlaylistTracks( suspend fun getPlaylistTracks(
@ -51,26 +43,26 @@ interface SpotifyRequests {
offset: Int = 0, offset: Int = 0,
limit: Int = 100 limit: Int = 100
): PagingObjectPlaylistTrack { ): PagingObjectPlaylistTrack {
return httpClient.getData("$BASE_URL/playlists/$playlistID/tracks?offset=$offset&limit=$limit") return httpClient.get("$BASE_URL/playlists/$playlistID/tracks?offset=$offset&limit=$limit")
} }
suspend fun getTrack(id: String?): Track { suspend fun getTrack(id: String?): Track {
return httpClient.getData("$BASE_URL/tracks/$id") return httpClient.get("$BASE_URL/tracks/$id")
} }
suspend fun getEpisode(id: String?): Track { suspend fun getEpisode(id: String?): Track {
return httpClient.getData("$BASE_URL/episodes/$id") return httpClient.get("$BASE_URL/episodes/$id")
} }
suspend fun getShow(id: String?): Track { suspend fun getShow(id: String?): Track {
return httpClient.getData("$BASE_URL/shows/$id") return httpClient.get("$BASE_URL/shows/$id")
} }
suspend fun getAlbum(id: String): Album { suspend fun getAlbum(id: String): Album {
return httpClient.getData("$BASE_URL/albums/$id") return httpClient.get("$BASE_URL/albums/$id")
} }
suspend fun getResponse(url: String): String { suspend fun getResponse(url: String): String {
return httpClient.getData(url) return httpClient.get(url)
} }
} }

View File

@ -26,35 +26,6 @@ import kotlinx.serialization.serializer
import kotlin.native.concurrent.SharedImmutable import kotlin.native.concurrent.SharedImmutable
import kotlin.native.concurrent.ThreadLocal import kotlin.native.concurrent.ThreadLocal
/*
* WorkAround: https://github.com/Kotlin/kotlinx.serialization/issues/1450
* */
@OptIn(InternalSerializationApi::class)
suspend inline fun <reified T: Any> HttpClient.getData(
urlString: String,
block: HttpRequestBuilder.() -> Unit = {}
): T {
val response = get<HttpResponse> {
url.takeFrom(urlString)
block()
}
val jsonBody = response.readText()
return json.decodeFromString(T::class.serializer(),jsonBody)
}
@OptIn(InternalSerializationApi::class)
suspend inline fun <reified T: Any> HttpClient.postData(
urlString: String,
block: HttpRequestBuilder.() -> Unit = {}
): T {
val response = post<HttpResponse> {
url.takeFrom(urlString)
block()
}
val jsonBody = response.readText()
return json.decodeFromString(T::class.serializer(),jsonBody)
}
@ThreadLocal @ThreadLocal
val json by lazy { Json { val json by lazy { Json {
isLenient = true isLenient = true

View File

@ -18,7 +18,6 @@ package com.shabinder.common.di.youtubeMp3
import co.touchlab.kermit.Kermit import co.touchlab.kermit.Kermit
import com.shabinder.common.di.gaana.corsApi import com.shabinder.common.di.gaana.corsApi
import com.shabinder.common.di.utils.postData
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.request.forms.FormDataContent import io.ktor.client.request.forms.FormDataContent
import io.ktor.client.request.post import io.ktor.client.request.post

View File

@ -17,13 +17,13 @@
package com.shabinder.common.di package com.shabinder.common.di
import com.shabinder.common.di.providers.YoutubeMp3 import com.shabinder.common.di.providers.YoutubeMp3
import com.shabinder.common.di.providers.getData import com.shabinder.common.di.providers.get
import com.shabinder.common.di.utils.ParallelExecutor import com.shabinder.common.di.utils.ParallelExecutor
import com.shabinder.common.models.AllPlatforms import com.shabinder.common.models.AllPlatforms
import com.shabinder.common.models.DownloadResult import com.shabinder.common.models.DownloadResult
import com.shabinder.common.models.DownloadStatus import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails import com.shabinder.common.models.TrackDetails
import com.shabinder.downloader.YoutubeDownloader import io.github.shabinder.YoutubeDownloader
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
@ -75,7 +75,7 @@ suspend fun downloadTrack(
youtubeMp3: YoutubeMp3 youtubeMp3: YoutubeMp3
) { ) {
try { try {
val link = youtubeMp3.getMp3DownloadLink(videoID) ?: ytDownloader.getVideo(videoID).getData()?.url val link = youtubeMp3.getMp3DownloadLink(videoID) ?: ytDownloader.getVideo(videoID).get()?.url
if (link == null) { if (link == null) {
DownloadProgressFlow.emit( DownloadProgressFlow.emit(

View File

@ -63,7 +63,7 @@ suspend fun downloadTrack(
fetcher.dir.logger.i { "LINK: $videoID -> $link" } fetcher.dir.logger.i { "LINK: $videoID -> $link" }
if (link == null) { if (link == null) {
link = fetcher.youtubeProvider.ytDownloader.getVideo(videoID).getData()?.url ?: return link = fetcher.youtubeProvider.ytDownloader.getVideo(videoID).get()?.url ?: return
} }
fetcher.dir.logger.i { "LINK: $videoID -> $link" } fetcher.dir.logger.i { "LINK: $videoID -> $link" }
downloadFile(link).collect { downloadFile(link).collect {

View File

@ -135,5 +135,14 @@ private fun spotiFlyerRoot(componentContext: ComponentContext): SpotiFlyerRoot =
isInternetAccessible() isInternetAccessible()
} }
} }
override val analytics = object: SpotiFlyerRoot.Analytics {
override fun appLaunchEvent() {}
override fun homeScreenVisit() {}
override fun listScreenVisit() {}
override fun donationDialogVisit() {}
}
} }
) )

View File

@ -28,19 +28,31 @@ repositories {
dependencies { dependencies {
implementation(kotlin("stdlib-js")) implementation(kotlin("stdlib-js"))
implementation(Decompose.decompose)
implementation(Koin.core) implementation(Koin.core)
implementation(Ktor.clientJs) implementation(Extras.kermit)
implementation(Decompose.decompose)
implementation(MVIKotlin.mvikotlin) implementation(MVIKotlin.mvikotlin)
implementation(MVIKotlin.coroutines) implementation(MVIKotlin.coroutines)
implementation(MVIKotlin.mvikotlinMain) implementation(MVIKotlin.mvikotlinMain)
implementation(MVIKotlin.mvikotlinLogging) implementation(MVIKotlin.mvikotlinLogging)
implementation(Ktor.auth)
implementation(Ktor.clientJs)
implementation(Ktor.clientJson)
implementation(Ktor.clientCore)
implementation(Ktor.clientLogging)
implementation(Ktor.clientSerialization)
implementation(project(":common:root")) implementation(project(":common:root"))
implementation(project(":common:main")) implementation(project(":common:main"))
implementation(project(":common:list")) implementation(project(":common:list"))
implementation(project(":common:database")) implementation(project(":common:database"))
implementation(project(":common:data-models")) implementation(project(":common:data-models"))
implementation(project(":common:dependency-injection")) implementation(project(":common:dependency-injection"))
implementation("co.touchlab:stately-common:1.1.7")
implementation("dev.icerock.moko:parcelize:0.6.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0") {
// https://youtrack.jetbrains.com/issue/KTOR-2670
isForce = true
}
implementation("org.jetbrains:kotlin-react:17.0.1-pre.148-kotlin-1.4.30") implementation("org.jetbrains:kotlin-react:17.0.1-pre.148-kotlin-1.4.30")
implementation("org.jetbrains:kotlin-react-dom:17.0.1-pre.148-kotlin-1.4.30") implementation("org.jetbrains:kotlin-react-dom:17.0.1-pre.148-kotlin-1.4.30")
implementation("org.jetbrains:kotlin-styled:1.0.0-pre.115-kotlin-1.4.10") implementation("org.jetbrains:kotlin-styled:1.0.0-pre.115-kotlin-1.4.10")

View File

@ -23,13 +23,11 @@ import com.arkivanov.mvikotlin.logging.store.LoggingStoreFactory
import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
import com.shabinder.common.di.DownloadProgressFlow import com.shabinder.common.di.DownloadProgressFlow
import com.shabinder.common.models.Actions import com.shabinder.common.models.Actions
import com.shabinder.common.models.AllPlatforms
import com.shabinder.common.models.PlatformActions import com.shabinder.common.models.PlatformActions
import com.shabinder.common.models.TrackDetails import com.shabinder.common.models.TrackDetails
import com.shabinder.common.root.SpotiFlyerRoot import com.shabinder.common.root.SpotiFlyerRoot
import com.shabinder.database.Database import com.shabinder.database.Database
import extras.renderableChild import extras.renderableChild
import kotlinx.coroutines.Dispatchers
import react.RBuilder import react.RBuilder
import react.RComponent import react.RComponent
import react.RProps import react.RProps
@ -82,6 +80,23 @@ class App(props: AppProps): RComponent<AppProps, RState>(props) {
override val isInternetAvailable: Boolean = true override val isInternetAvailable: Boolean = true
} }
override val analytics = object: SpotiFlyerRoot.Analytics{
override fun appLaunchEvent() {
// TODO("Not yet implemented")
}
override fun homeScreenVisit() {
// TODO("Not yet implemented")
}
override fun listScreenVisit() {
// TODO("Not yet implemented")
}
override fun donationDialogVisit() {
// TODO("Not yet implemented")
}
}
} }
) )

View File

@ -21,9 +21,6 @@ import com.shabinder.common.di.initKoin
import react.dom.render import react.dom.render
import kotlinx.browser.document import kotlinx.browser.document
import kotlinx.browser.window import kotlinx.browser.window
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.get import org.koin.core.component.get
@ -38,7 +35,6 @@ fun main() {
} }
object AppDependencies : KoinComponent { object AppDependencies : KoinComponent {
val appScope = CoroutineScope(Dispatchers.Default)
val logger: Kermit val logger: Kermit
val directories: Dir val directories: Dir
val fetchPlatformQueryResult: FetchPlatformQueryResult val fetchPlatformQueryResult: FetchPlatformQueryResult
@ -47,8 +43,5 @@ object AppDependencies : KoinComponent {
directories = get() directories = get()
logger = get() logger = get()
fetchPlatformQueryResult = get() fetchPlatformQueryResult = get()
appScope.launch {
//fetchPlatformQueryResult.spotifyProvider.authenticateSpotifyClient(true)
}
} }
} }

View File

@ -16,6 +16,7 @@
package extras package extras
import com.arkivanov.decompose.value.Value
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
@ -36,7 +37,7 @@ abstract class RenderableComponent<
initialState: S initialState: S
) : RComponent<RenderableComponent.Props<T>, RenderableComponent.State<S>>(props) { ) : RComponent<RenderableComponent.Props<T>, RenderableComponent.State<S>>(props) {
protected abstract val stateFlow: Flow<S> protected abstract val stateFlow: Value<S>
protected val model: T get() = props.model protected val model: T get() = props.model
protected var scope: CoroutineScope = CoroutineScope(Dispatchers.Default) protected var scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
@ -48,7 +49,7 @@ abstract class RenderableComponent<
if(!scope.isActive) if(!scope.isActive)
scope = CoroutineScope(Dispatchers.Default) scope = CoroutineScope(Dispatchers.Default)
scope.launch { scope.launch {
stateFlow.collect { stateFlow.subscribe {
setState { data = it } setState { data = it }
} }
} }

View File

@ -16,6 +16,7 @@
package home package home
import com.arkivanov.decompose.value.Value
import com.shabinder.common.main.SpotiFlyerMain import com.shabinder.common.main.SpotiFlyerMain
import com.shabinder.common.main.SpotiFlyerMain.State import com.shabinder.common.main.SpotiFlyerMain.State
import extras.RenderableComponent import extras.RenderableComponent
@ -55,7 +56,7 @@ class HomeScreen(
} }
} }
override val stateFlow: Flow<SpotiFlyerMain.State> = model.models override val stateFlow: Value<SpotiFlyerMain.State> = model.models
override fun RBuilder.render() { override fun RBuilder.render() {
styledDiv{ styledDiv{

View File

@ -16,6 +16,7 @@
package list package list
import com.arkivanov.decompose.value.Value
import com.shabinder.common.list.SpotiFlyerList import com.shabinder.common.list.SpotiFlyerList
import com.shabinder.common.list.SpotiFlyerList.State import com.shabinder.common.list.SpotiFlyerList.State
import extras.RenderableComponent import extras.RenderableComponent
@ -39,7 +40,7 @@ class ListScreen(
props: Props<SpotiFlyerList>, props: Props<SpotiFlyerList>,
) : RenderableComponent<SpotiFlyerList, State>(props,initialState = State()) { ) : RenderableComponent<SpotiFlyerList, State>(props,initialState = State()) {
override val stateFlow: Flow<SpotiFlyerList.State> = model.models override val stateFlow: Value<SpotiFlyerList.State> = model.models
override fun RBuilder.render() { override fun RBuilder.render() {