Skip to content

Commit

Permalink
java.lang.NoClassDefFoundError: Failed resolution of: Lkotlinx/atomic…
Browse files Browse the repository at this point in the history
…fu/AtomicFU

Signed-off-by: mramotar <[email protected]>
  • Loading branch information
matt-ramotar committed Dec 29, 2022
1 parent c78d49e commit 4f7b3c4
Show file tree
Hide file tree
Showing 31 changed files with 1,391 additions and 67 deletions.
13 changes: 12 additions & 1 deletion android/app/src/main/kotlin/so/howl/android/app/HowlApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Application
import com.squareup.anvil.annotations.ContributesBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import so.howl.android.app.wiring.AppComponent
import so.howl.android.app.wiring.AppDependencies
import so.howl.android.app.wiring.DaggerAppComponent
Expand All @@ -14,6 +15,8 @@ import so.howl.android.common.scoping.ComponentHolder
import so.howl.android.common.scoping.SingleIn
import so.howl.common.storekit.api.HowlApi
import so.howl.common.storekit.api.fake.FakeHowlUsers
import so.howl.common.storekit.store.howler.sot.DriverFactory
import so.howl.common.storekit.store.howler.sot.HowlDatabaseProvider

@SingleIn(AppScope::class)
@ContributesBinding(AppScope::class, boundType = Application::class)
Expand All @@ -32,7 +35,15 @@ class HowlApp : Application(), ComponentHolder {

override fun onCreate() {
super.onCreate()
component = DaggerAppComponent.create()
val application = this
coroutineScope.launch {
val database = HowlDatabaseProvider().provide(DriverFactory(applicationContext))
component = DaggerAppComponent.factory().create(
application = application,
database = database,
applicationContext = applicationContext
)
}
}

companion object {
Expand Down
36 changes: 23 additions & 13 deletions android/app/src/main/kotlin/so/howl/android/app/HowlMainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import so.howl.android.app.ui.HowlScaffold
Expand All @@ -21,9 +20,11 @@ import so.howl.android.app.wiring.UserComponent
import so.howl.android.common.hig.HigTheme
import so.howl.android.common.scoping.ComponentHolder
import so.howl.android.common.scoping.UserDependencies
import so.howl.common.storekit.api.fake.FakeHowlers
import so.howl.common.storekit.entities.howler.output.Howler
import so.howl.common.storekit.entities.howler.output.Howlers
import so.howl.common.storekit.entities.howler.output.RealHowler
import so.howl.common.storekit.entities.user.output.RealHowlUser
import so.howl.common.storekit.result.RequestResult

class HowlMainActivity : ComponentActivity(), ComponentHolder {
private val coroutineScope = CoroutineScope(Dispatchers.Default)
Expand All @@ -32,12 +33,6 @@ class HowlMainActivity : ComponentActivity(), ComponentHolder {

private val initialized = MutableStateFlow(false)


private suspend fun transition() {
delay(200)
initialized.value = true
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
coroutineScope.launch {
Expand All @@ -46,11 +41,26 @@ class HowlMainActivity : ComponentActivity(), ComponentHolder {
val howlerComponentFactory = (userComponent as HowlerComponent.ParentBindings).howlerComponentFactory()

val userDependencies = userComponent as UserDependencies
val howlers: List<Howler> = listOf(FakeHowlers.Tag.output)
println("HITTING AFTER HOWLERS")
val howlerComponent: HowlerComponent = howlerComponentFactory.create(Howlers.from(howlers))
component = Pair(userComponent, howlerComponent)
transition()

val response = userDependencies.howlerApi.getHowlersByOwnerId(userComponent.user.id)
if (response is RequestResult.Success) {
val howlers: List<Howler> = response.data.map {
RealHowler(
it.id,
it.name,
it.avatarUrl,
it.owners.map { RealHowlUser(it.id, it.name, it.email, it.username, it.avatarUrl, it.howlerIds) })
}
val howlerComponent: HowlerComponent = howlerComponentFactory.create(Howlers.from(howlers))
component = Pair(userComponent, howlerComponent)
println("SUCCESS == $response")
initialized.value = true
} else {
println("RESPONSE === $response")
component = Pair(userComponent, null)
initialized.value = true
}

}

setContent {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
package so.howl.android.app.wiring

import android.content.Context
import com.squareup.anvil.annotations.MergeComponent
import dagger.BindsInstance
import dagger.Component
import so.howl.android.app.HowlApp
import so.howl.android.common.scoping.AppScope
import so.howl.android.common.scoping.SingleIn
import so.howl.android.common.scoping.UserScope
import so.howl.common.storekit.HowlDatabase

@SingleIn(AppScope::class)
@MergeComponent(AppScope::class)
interface AppComponent
interface AppComponent {
@Component.Factory
interface Factory {
fun create(
@BindsInstance application: HowlApp,
@BindsInstance database: HowlDatabase,
@BindsInstance applicationContext: Context
): AppComponent
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,22 @@ package so.howl.android.app.wiring
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import org.mobilenativefoundation.store.store5.MutableStore
import so.howl.android.common.scoping.HowlerScope
import so.howl.android.common.scoping.SingleIn
import so.howl.common.storekit.HowlDatabase
import so.howl.common.storekit.api.HowlerApi
import so.howl.common.storekit.entities.howler.output.Howler
import so.howl.common.storekit.repository.HowlerRepository
import so.howl.common.storekit.repository.RealHowlerRepository
import so.howl.common.storekit.store.StoreOutput
import so.howl.common.storekit.store.howler.HowlerKey
import so.howl.common.storekit.store.howler.HowlerStoreProvider


@Module
@ContributesTo(HowlerScope::class)
object HowlerModule {
private fun provideHowlerStore(api: HowlerApi): MutableStore<HowlerKey, StoreOutput<Howler>> =
HowlerStoreProvider(api).provide()

@SingleIn(HowlerScope::class)
@Provides
fun provideHowlerRepository(api: HowlerApi): HowlerRepository {
val store = provideHowlerStore(api)
fun provideHowlerRepository(api: HowlerApi, database: HowlDatabase): HowlerRepository {
val store = HowlerStoreProvider(api, database).provide()
return RealHowlerRepository(store)
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import org.mobilenativefoundation.store.store5.StoreReadRequest
import so.howl.android.feature.home.model.event.HomeTabEvent
import so.howl.android.feature.home.model.state.HomeTabState
import so.howl.android.feature.home.model.state.HomeTabViewState
import so.howl.common.storekit.entities.howler.output.Howlers
import so.howl.common.storekit.entities.user.output.HowlUser
import so.howl.common.storekit.repository.HowlerRepository
import so.howl.common.storekit.store.StoreOutput
import so.howl.common.storekit.store.howler.HowlerKey

class HomeTabViewModel(
private val user: HowlUser,
Expand Down Expand Up @@ -41,6 +45,29 @@ class HomeTabViewModel(

suspend fun fetch(refresh: Boolean = false) {
setState(HomeTabState(HomeTabViewState.Loading))
howlerRepository.stream(StoreReadRequest.fresh(HowlerKey.Read.ByOwnerId("a"))).collect {

val data = it.dataOrNull()
when (data) {
null -> {
// TODO()
}
is StoreOutput.Data.Collection -> {
val first = data.items.first()
setState(HomeTabState(HomeTabViewState.Success(data.items.first())))
}
is StoreOutput.Data.Single -> {
// TODO()
}
is StoreOutput.Error.Exception -> {
// TODO()
}
is StoreOutput.Error.Message -> {
// TODO()
}
}

}
}

private fun onEvent(event: HomeTabEvent) {
Expand Down
28 changes: 25 additions & 3 deletions common/storekit/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {
`maven-publish`
kotlin("native.cocoapods")
alias(libs.plugins.native.coroutines)
id("com.squareup.sqldelight")
}

kotlin {
Expand Down Expand Up @@ -47,15 +48,30 @@ kotlin {
implementation(libs.sqldelight.android.driver)
}
}

val desktopMain by getting {
dependencies {
implementation(libs.sqldelight.sqlite.driver)
}
}
val iosX64Main by getting
val iosArm64Main by getting

val nativeMain by creating {
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)

dependencies {
implementation(libs.sqldelight.native.driver)
}
}

val desktopMain by getting
val jsMain by getting {
dependencies {
implementation(libs.sqldelight.sqljs.driver)
}
}
}
}

Expand All @@ -76,4 +92,10 @@ kmmbridge {
githubReleaseVersions()
versionPrefix.set("0.0")
spm()
}
}

sqldelight {
database("HowlDatabase") {
packageName = "so.howl.common.storekit"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package so.howl.common.storekit.store.howler.sot

import android.content.Context
import com.squareup.sqldelight.android.AndroidSqliteDriver
import com.squareup.sqldelight.db.SqlDriver
import so.howl.common.storekit.HowlDatabase

actual class DriverFactory(private val context: Context) {
actual suspend fun createDriver(): SqlDriver {
return AndroidSqliteDriver(HowlDatabase.Schema, context, "howl.database")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class HttpClientProvider {
json(Json {
isLenient = true
ignoreUnknownKeys = true
encodeDefaults = true
})
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:OptIn(InternalSerializationApi::class)

package so.howl.common.storekit.api

import io.ktor.client.HttpClient
Expand All @@ -6,9 +8,14 @@ import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.request.put
import io.ktor.client.request.setBody
import io.ktor.client.statement.bodyAsText
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.serializer
import so.howl.common.storekit.entities.howler.HowlerId
import so.howl.common.storekit.entities.howler.network.NetworkHowler
import so.howl.common.storekit.entities.howler.network.NetworkResponse
import so.howl.common.storekit.entities.howler.output.Howler
import so.howl.common.storekit.entities.user.HowlUserId
import so.howl.common.storekit.result.RequestResult
Expand All @@ -34,9 +41,15 @@ class RealHowlApi(private val client: HttpClient) : HowlApi {
}

override suspend fun getHowlersByOwnerId(ownerId: HowlUserId): RequestResult<List<NetworkHowler>> = try {
val response = client.get("$ROOT_API_URL/${ownerId}/howlers")
RequestResult.Success(response.body())
val response = client.get("$ROOT_API_URL/howlers")
println("RESPONSE API == $response")
println(response.bodyAsText())
println(response.body<NetworkResponse>())
val networkResponse = response.body<NetworkResponse>()
println("NETWORK RESPONSE ==== $networkResponse")
RequestResult.Success(networkResponse.value)
} catch (error: Throwable) {
println("ERROR API === $error")
RequestResult.Exception(error)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import so.howl.common.storekit.entities.howler.HowlerId
import so.howl.common.storekit.entities.howler.network.NetworkHowler
import so.howl.common.storekit.entities.howler.output.Howler
import so.howl.common.storekit.entities.user.HowlUserId
import so.howl.common.storekit.entities.user.network.NetworkHowlUser
import so.howl.common.storekit.entities.user.output.HowlUser

object FakeHowlers {
Expand All @@ -17,7 +18,7 @@ object FakeHowlers {
override val id: HowlerId = ID
override val name: String = NAME
override val avatarUrl: String = AVATAR_URL
override val owners: List<HowlUser> = OWNERS
override val owners: List<NetworkHowlUser> = listOf()
}

val output = object : Howler {
Expand All @@ -39,7 +40,7 @@ object FakeHowlers {
override val id: HowlerId = ID
override val name: String = NAME
override val avatarUrl: String = AVATAR_URL
override val owners: List<HowlUser> = OWNERS
override val owners: List<NetworkHowlUser> = listOf()
}

val output = object : Howler {
Expand All @@ -60,7 +61,7 @@ object FakeHowlers {
override val id: HowlerId = ID
override val name: String = NAME
override val avatarUrl: String = AVATAR_URL
override val owners: List<HowlUser> = OWNERS
override val owners: List<NetworkHowlUser> = listOf()
}

val output = object : Howler {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package so.howl.common.storekit.entities.howler.network

import so.howl.common.storekit.entities.howler.HowlerId
import so.howl.common.storekit.entities.user.network.NetworkHowlUser
import so.howl.common.storekit.entities.user.output.HowlUser

interface NetworkHowler {
val id: HowlerId
val name: String
val avatarUrl: String
val owners: List<HowlUser>
val avatarUrl: String?
val owners: List<NetworkHowlUser>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package so.howl.common.storekit.entities.howler.network

import kotlinx.serialization.Serializable

@Serializable
data class NetworkResponse(
val value: List<RealNetworkHowler>
)
Loading

0 comments on commit 4f7b3c4

Please sign in to comment.