add basic updater implementation in gigawear
This commit is contained in:
@@ -21,6 +21,7 @@ dependencies {
|
||||
implementation(project(":libs:base"))
|
||||
implementation(project(":libs:http-client"))
|
||||
implementation(project(":feature:updater:updater-common"))
|
||||
implementation(project(":feature:updater:updater-backend"))
|
||||
implementation(project(":feature:chat:chat-common"))
|
||||
implementation(project(":feature:chat:chat-backend"))
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@ import io.ktor.server.routing.get
|
||||
import io.ktor.server.routing.routing
|
||||
import org.koin.core.annotation.KoinApplication
|
||||
import org.koin.plugin.module.dsl.startKoin
|
||||
import ru.shadowsparky.gigawear.backend.presentation.MOCK_USER_ID
|
||||
import ru.shadowsparky.gigawear.backend.presentation.setupChat
|
||||
import ru.shadowsparky.koin
|
||||
import ru.shadowsparky.updater.backend.presentation.setupUpdates
|
||||
|
||||
@KoinApplication
|
||||
object GigaWearApp
|
||||
@@ -26,5 +28,6 @@ fun Application.module() {
|
||||
routing {
|
||||
get("health") { this.call.respond(HttpStatusCode.OK) }
|
||||
setupChat(koin.get())
|
||||
setupUpdates(koin.get()) { MOCK_USER_ID }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import io.ktor.server.routing.post
|
||||
import ru.shadowsparky.chat.backend.domain.ProcessUserMessageUseCase
|
||||
import ru.shadowsparky.chat.domain.Message
|
||||
|
||||
private const val MOCK_USER_ID = -1L
|
||||
const val MOCK_USER_ID = -1L
|
||||
|
||||
fun Route.setupChat(useCase: ProcessUserMessageUseCase) {
|
||||
post("chat") {
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
package ru.shadowsparky.gigawear.backend.presentation
|
||||
|
||||
import io.ktor.server.request.receive
|
||||
import io.ktor.server.response.respond
|
||||
import io.ktor.server.routing.Route
|
||||
import io.ktor.server.routing.Routing
|
||||
import io.ktor.server.routing.post
|
||||
import ru.shadowsparky.chat.backend.domain.ProcessUserMessageUseCase
|
||||
import ru.shadowsparky.chat.domain.Message
|
||||
|
||||
fun Route.setupUpdate(useCase: ProcessUserMessageUseCase) {
|
||||
post("chat") {
|
||||
val message = call.receive<Message>().copy(timestamp = System.currentTimeMillis())
|
||||
call.respond(useCase.execute(message, MOCK_USER_ID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ dependencies {
|
||||
implementation(project(":libs:http-client"))
|
||||
implementation(project(":libs:base"))
|
||||
implementation(project(":feature:chat:chat-common"))
|
||||
|
||||
implementation(project(":feature:updater:updater-common"))
|
||||
implementation(project(":feature:updater:updater-client"))
|
||||
|
||||
implementation(libs.activity.compose)
|
||||
implementation(libs.androidx.compose.foundation)
|
||||
implementation(libs.androidx.compose.material3)
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLParameters
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLSocket
|
||||
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
|
||||
-dontwarn org.conscrypt.Conscrypt$Version
|
||||
-dontwarn org.conscrypt.Conscrypt
|
||||
-dontwarn org.conscrypt.ConscryptHostnameVerifier
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
|
||||
-dontwarn org.openjsse.net.ssl.OpenJSSE
|
||||
-dontwarn org.slf4j.impl.StaticLoggerBinder
|
||||
-dontwarn java.lang.management.ManagementFactory
|
||||
-dontwarn java.lang.management.RuntimeMXBean
|
||||
-dontwarn kotlinx.atomicfu.**
|
||||
-dontwarn io.netty.**
|
||||
-dontwarn com.typesafe.**
|
||||
-dontwarn org.slf4j.**
|
||||
-dontwarn com.sun.nio.file.SensitivityWatchEventModifier
|
||||
-dontwarn org.xmlpull.v1.**
|
||||
-dontwarn javax.xml.namespace.**
|
||||
-dontwarn androidx.test.platform.app.InstrumentationRegistry
|
||||
-dontwarn androidx.window.extensions.WindowExtensions
|
||||
-dontwarn androidx.window.extensions.WindowExtensionsProvider
|
||||
-dontwarn androidx.window.extensions.area.ExtensionWindowAreaPresentation
|
||||
-dontwarn androidx.window.extensions.core.util.function.Consumer
|
||||
-dontwarn androidx.window.extensions.core.util.function.Function
|
||||
-dontwarn androidx.window.extensions.core.util.function.Predicate
|
||||
-dontwarn androidx.window.extensions.layout.DisplayFeature
|
||||
-dontwarn androidx.window.extensions.layout.FoldingFeature
|
||||
-dontwarn androidx.window.extensions.layout.WindowLayoutComponent
|
||||
-dontwarn androidx.window.extensions.layout.WindowLayoutInfo
|
||||
-dontwarn androidx.window.sidecar.SidecarDeviceState
|
||||
-dontwarn androidx.window.sidecar.SidecarDisplayFeature
|
||||
-dontwarn androidx.window.sidecar.SidecarInterface$SidecarCallback
|
||||
-dontwarn androidx.window.sidecar.SidecarInterface
|
||||
-dontwarn androidx.window.sidecar.SidecarProvider
|
||||
-dontwarn androidx.window.sidecar.SidecarWindowLayoutInfo
|
||||
|
||||
-keep class ru.shadowsparky.vbox.shared.domain.RemoteEvent { *; }
|
||||
-keep class ru.shadowsparky.vbox.shared.domain.RemoteEvent$OnSaved { *; }
|
||||
-keep class ru.shadowsparky.vbox.shared.domain.RemoteEvent$OnRecent { *; }
|
||||
-keep class ru.shadowsparky.vbox.shared.domain.RemoteEvent$OnSearch { *; }
|
||||
|
||||
-keep class ru.shadowsparky.videobox.multiplatform.**$Config { *; }
|
||||
-keep class ru.shadowsparky.videobox.multiplatform.**$Configuration { *; }
|
||||
|
||||
-keepclassmembers class * implements android.os.Parcelable {
|
||||
static ** CREATOR;
|
||||
}
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod
|
||||
|
||||
-keep class com.arkivanov.decompose.** { *; }
|
||||
-keep interface com.arkivanov.decompose.** { *; }
|
||||
-dontwarn com.arkivanov.decompose.**
|
||||
@@ -3,8 +3,21 @@ package ru.shadowsparky.gigawear
|
||||
import org.koin.core.annotation.ComponentScan
|
||||
import org.koin.core.annotation.Configuration
|
||||
import org.koin.core.annotation.Module
|
||||
import org.koin.core.annotation.Singleton
|
||||
import ru.shadowsparky.domain.AppConfig
|
||||
|
||||
@Module
|
||||
@ComponentScan
|
||||
@Configuration
|
||||
class GigaWearModule
|
||||
class GigaWearModule {
|
||||
|
||||
@Singleton
|
||||
fun provideAppConfig(): AppConfig {
|
||||
return object : AppConfig {
|
||||
override val debug = BuildConfig.DEBUG
|
||||
override val appId = "GigaWearClient"
|
||||
override val versionCode = BuildConfig.VERSION_CODE.toLong()
|
||||
override val versionName = BuildConfig.VERSION_NAME
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -8,13 +8,15 @@ import org.koin.core.annotation.Factory
|
||||
import ru.shadowsparky.chat.domain.ChatRepository
|
||||
import ru.shadowsparky.chat.domain.Message
|
||||
|
||||
const val ENDPOINT = "http://192.168.0.76:8181"
|
||||
|
||||
@Factory
|
||||
class GigaChatRepository(
|
||||
private val httpClient: HttpClient
|
||||
) : ChatRepository {
|
||||
override suspend fun query(afterId: Long?): List<Message> = emptyList()
|
||||
override suspend fun send(message: Message): Message {
|
||||
return httpClient.post("http://192.168.0.76:8181/chat") {
|
||||
return httpClient.post("$ENDPOINT/chat") {
|
||||
setBody(message)
|
||||
}.body<Message>()
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package ru.shadowsparky.gigawear.data
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.parameter
|
||||
import org.koin.core.annotation.Factory
|
||||
import ru.shadowsparky.updater.domain.UpdateFetcher
|
||||
import ru.shadowsparky.updater.domain.UpdateInfo
|
||||
|
||||
@Factory
|
||||
class UpdateFetcherImpl(private val httpClient: HttpClient) : UpdateFetcher {
|
||||
override suspend fun fetch(versionCode: Long): UpdateInfo {
|
||||
return httpClient.get("$ENDPOINT/checkUpdates") {
|
||||
parameter(UpdateFetcher.ARG_VERSION_CODE, versionCode)
|
||||
}.body()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package ru.shadowsparky.gigawear.presentation
|
||||
|
||||
import android.app.Application
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.annotation.KoinApplication
|
||||
import org.koin.plugin.module.dsl.startKoin
|
||||
|
||||
@@ -11,6 +12,8 @@ class App : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
startKoin<GigaWearApp>()
|
||||
startKoin<GigaWearApp> {
|
||||
androidContext(this@App)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -1,6 +1,7 @@
|
||||
package ru.shadowsparky.gigawear.presentation.chat
|
||||
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.childContext
|
||||
import com.arkivanov.decompose.value.MutableValue
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import com.arkivanov.decompose.value.update
|
||||
@@ -17,12 +18,15 @@ import ru.shadowsparky.gigawear.presentation.nav.Child
|
||||
import ru.shadowsparky.gigawear.presentation.nav.Route
|
||||
import ru.shadowsparky.ui.nav.ComponentFactory
|
||||
import ru.shadowsparky.ui.nav.RouteNavigator
|
||||
import ru.shadowsparky.updater.presentation.UpdateComponentFactory
|
||||
|
||||
class ChatComponent(
|
||||
private val context: ComponentContext,
|
||||
private val repository: ChatRepository
|
||||
private val repository: ChatRepository,
|
||||
private val updateComponentFactory: UpdateComponentFactory
|
||||
) : ComponentContext by context {
|
||||
private val scope = coroutineScope()
|
||||
val updateComponent = updateComponentFactory.create(childContext("updater"))
|
||||
|
||||
private val _state = MutableValue(ChatUiState())
|
||||
val state: Value<ChatUiState> = _state
|
||||
@@ -30,6 +34,10 @@ class ChatComponent(
|
||||
private val _events = Channel<ComponentEvent>(Channel.BUFFERED)
|
||||
val events = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
updateComponent.checkUpdates(true)
|
||||
}
|
||||
|
||||
fun onMicClicked() {
|
||||
if (_state.value.isLoading) return
|
||||
scope.launch {
|
||||
@@ -75,14 +83,19 @@ class ChatComponent(
|
||||
@Factory
|
||||
@Named(Route.CHAT)
|
||||
class ChatComponentFactory(
|
||||
private val chatRepository: ChatRepository
|
||||
private val chatRepository: ChatRepository,
|
||||
private val updateComponentFactory: UpdateComponentFactory
|
||||
) : ComponentFactory<Child, Route.ChatScreen, Route> {
|
||||
override fun create(
|
||||
route: Route.ChatScreen,
|
||||
child: ComponentContext,
|
||||
root: RouteNavigator<Route>
|
||||
): Child {
|
||||
val component = ChatComponent(child, chatRepository)
|
||||
val component = ChatComponent(
|
||||
child,
|
||||
chatRepository,
|
||||
updateComponentFactory
|
||||
)
|
||||
return Child.MainChild(component)
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -40,6 +40,7 @@ import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import ru.shadowsparky.gigawear.R
|
||||
import ru.shadowsparky.gigawear.presentation.WearErrorContent
|
||||
import ru.shadowsparky.updater.presentation.UpdateDialog
|
||||
import java.util.Locale
|
||||
|
||||
@Composable
|
||||
@@ -171,6 +172,7 @@ fun ChatScreen(component: ChatComponent) {
|
||||
}
|
||||
}
|
||||
) { contentPadding ->
|
||||
UpdateDialog(component.updateComponent)
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
|
||||
Reference in New Issue
Block a user