Add basic WebSocket connectivity with Dero node.
- Created a new stargate module that will contain the code to connect with the Dero nodes. This stargate module will use the ktor library, which is a multiplatform networking library that works on both Android and iOS. - Added a bassic connectivity with a Dero node. It just connects with the node, listens for messages, and prints them out to the standard output. - Introduced the ScreenModel library and created a basic ImportAccountScreenModel. ScreenModel classes serve to host all the logic for their corresponding screens. - Added the Internet permssion to the Android app, to be able to connect with the internet. - Removed the Desktop target. After discussing with Ken, we decided that investing on a Desktop app does not make sense. We will focus on Android and iOS only.
This commit is contained in:
parent
34c82ba8f6
commit
8b9727082a
11 changed files with 141 additions and 65 deletions
|
@ -1,5 +1,3 @@
|
||||||
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.kotlinMultiplatform)
|
alias(libs.plugins.kotlinMultiplatform)
|
||||||
alias(libs.plugins.androidApplication)
|
alias(libs.plugins.androidApplication)
|
||||||
|
@ -15,8 +13,6 @@ kotlin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jvm("desktop")
|
|
||||||
|
|
||||||
listOf(
|
listOf(
|
||||||
iosX64(),
|
iosX64(),
|
||||||
iosArm64(),
|
iosArm64(),
|
||||||
|
@ -29,26 +25,39 @@ kotlin {
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
val desktopMain by getting
|
val androidMain by getting {
|
||||||
|
dependencies {
|
||||||
androidMain.dependencies {
|
implementation(libs.compose.ui.tooling.preview)
|
||||||
implementation(libs.compose.ui.tooling.preview)
|
implementation(libs.androidx.activity.compose)
|
||||||
implementation(libs.androidx.activity.compose)
|
}
|
||||||
}
|
}
|
||||||
commonMain.dependencies {
|
|
||||||
implementation(projects.shared.preferences)
|
|
||||||
|
|
||||||
implementation(compose.components.resources)
|
val commonMain by getting {
|
||||||
implementation(compose.components.uiToolingPreview)
|
commonMain.dependencies {
|
||||||
implementation(compose.foundation)
|
implementation(projects.shared.preferences)
|
||||||
implementation(compose.material3)
|
implementation(projects.shared.stargate)
|
||||||
implementation(compose.runtime)
|
|
||||||
implementation(compose.ui)
|
implementation(compose.components.resources)
|
||||||
implementation(libs.voyager.navigator)
|
implementation(compose.components.uiToolingPreview)
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.1")
|
implementation(compose.foundation)
|
||||||
|
implementation(compose.material3)
|
||||||
|
implementation(compose.runtime)
|
||||||
|
implementation(compose.ui)
|
||||||
|
implementation(libs.coroutines.core)
|
||||||
|
implementation(libs.voyager.navigator)
|
||||||
|
implementation(libs.voyager.screenmodel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
desktopMain.dependencies {
|
|
||||||
implementation(compose.desktop.currentOs)
|
val iosX64Main by getting
|
||||||
|
val iosArm64Main by getting
|
||||||
|
val iosSimulatorArm64Main by getting
|
||||||
|
val iosMain by creating {
|
||||||
|
dependsOn(commonMain)
|
||||||
|
iosX64Main.dependsOn(this)
|
||||||
|
iosArm64Main.dependsOn(this)
|
||||||
|
iosSimulatorArm64Main.dependsOn(this)
|
||||||
|
dependencies {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,15 +95,3 @@ android {
|
||||||
debugImplementation(libs.compose.ui.tooling)
|
debugImplementation(libs.compose.ui.tooling)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compose.desktop {
|
|
||||||
application {
|
|
||||||
mainClass = "MainKt"
|
|
||||||
|
|
||||||
nativeDistributions {
|
|
||||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
|
||||||
packageName = "net.agorise.kee"
|
|
||||||
packageVersion = "1.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
|
|
@ -7,6 +7,7 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import kee.composeapp.generated.resources.Res
|
import kee.composeapp.generated.resources.Res
|
||||||
|
@ -22,9 +23,10 @@ import ui.theme.KeeTheme
|
||||||
private const val RECOVERY_WORDS_COUNT = 25
|
private const val RECOVERY_WORDS_COUNT = 25
|
||||||
|
|
||||||
class ImportAccountScreen : Screen {
|
class ImportAccountScreen : Screen {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() = KeeTheme {
|
override fun Content() = KeeTheme {
|
||||||
|
val screenModel = rememberScreenModel { ImportAccountScreenModel() }
|
||||||
|
|
||||||
ImportAccountScreenContent()
|
ImportAccountScreenContent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +35,7 @@ class ImportAccountScreen : Screen {
|
||||||
@Composable
|
@Composable
|
||||||
private fun ImportAccountScreenContent() {
|
private fun ImportAccountScreenContent() {
|
||||||
val navigator = LocalNavigator.current
|
val navigator = LocalNavigator.current
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = { KeeTopAppBar("Import Account") }
|
topBar = { KeeTopAppBar("Import Account") }
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package net.agorise.kee.ui.screen.importaccount
|
||||||
|
|
||||||
|
import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.IO
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import net.agorise.shared.stargate.Bridge
|
||||||
|
|
||||||
|
class ImportAccountScreenModel : ScreenModel {
|
||||||
|
private val bridge = Bridge()
|
||||||
|
|
||||||
|
init {
|
||||||
|
screenModelScope.launch(Dispatchers.IO) {
|
||||||
|
bridge.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDispose() {
|
||||||
|
super.onDispose()
|
||||||
|
bridge.stop()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
package net.agorise.kee
|
|
||||||
|
|
||||||
class JVMPlatform: Platform {
|
|
||||||
override val name: String = "Java ${System.getProperty("java.version")}"
|
|
||||||
}
|
|
||||||
|
|
||||||
actual fun getPlatform(): Platform = JVMPlatform()
|
|
|
@ -1,20 +0,0 @@
|
||||||
package net.agorise.kee
|
|
||||||
|
|
||||||
import androidx.compose.ui.unit.DpSize
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.window.Window
|
|
||||||
import androidx.compose.ui.window.WindowPosition
|
|
||||||
import androidx.compose.ui.window.application
|
|
||||||
import androidx.compose.ui.window.rememberWindowState
|
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
|
||||||
import net.agorise.kee.ui.screen.home.HomeScreen
|
|
||||||
|
|
||||||
fun main() = application {
|
|
||||||
val state = rememberWindowState(
|
|
||||||
size = DpSize(420.dp, 880.dp),
|
|
||||||
position = WindowPosition(300.dp, 300.dp)
|
|
||||||
)
|
|
||||||
Window(title = "Kee", onCloseRequest = ::exitApplication, state = state) {
|
|
||||||
Navigator(HomeScreen())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,9 +4,11 @@ android-compileSdk = "34"
|
||||||
android-minSdk = "26"
|
android-minSdk = "26"
|
||||||
android-targetSdk = "34"
|
android-targetSdk = "34"
|
||||||
androidx-activityCompose = "1.8.2"
|
androidx-activityCompose = "1.8.2"
|
||||||
compose = "1.6.2"
|
compose = "1.6.4"
|
||||||
compose-plugin = "1.6.0"
|
compose-plugin = "1.6.0"
|
||||||
|
coroutines = "1.8.0"
|
||||||
kotlin = "1.9.22"
|
kotlin = "1.9.22"
|
||||||
|
ktor = "2.3.9"
|
||||||
multiplatform-settings = "1.1.1"
|
multiplatform-settings = "1.1.1"
|
||||||
voyager = "1.0.0"
|
voyager = "1.0.0"
|
||||||
|
|
||||||
|
@ -14,8 +16,13 @@ voyager = "1.0.0"
|
||||||
androidx-activity-compose = { group = "androidx.activity", name ="activity-compose", version.ref = "androidx-activityCompose" }
|
androidx-activity-compose = { group = "androidx.activity", name ="activity-compose", version.ref = "androidx-activityCompose" }
|
||||||
compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "compose" }
|
compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "compose" }
|
||||||
compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview", version.ref = "compose" }
|
compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview", version.ref = "compose" }
|
||||||
|
coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
|
||||||
|
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor" }
|
||||||
|
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }
|
||||||
|
ktor-client-websockets = { group = "io.ktor", name = "ktor-client-websockets", version.ref = "ktor" }
|
||||||
multiplatform-settings = { group="com.russhwolf", name = "multiplatform-settings-no-arg", version.ref = "multiplatform-settings" }
|
multiplatform-settings = { group="com.russhwolf", name = "multiplatform-settings-no-arg", version.ref = "multiplatform-settings" }
|
||||||
voyager-navigator = { group = "cafe.adriel.voyager", name = "voyager-navigator", version.ref = "voyager" }
|
voyager-navigator = { group = "cafe.adriel.voyager", name = "voyager-navigator", version.ref = "voyager" }
|
||||||
|
voyager-screenmodel = { group = "cafe.adriel.voyager", name = "voyager-screenmodel", version.ref = "voyager" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|
|
@ -20,3 +20,4 @@ dependencyResolutionManagement {
|
||||||
|
|
||||||
include(":composeApp")
|
include(":composeApp")
|
||||||
include(":shared:preferences")
|
include(":shared:preferences")
|
||||||
|
include(":shared:stargate")
|
||||||
|
|
|
@ -12,8 +12,6 @@ kotlin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jvm()
|
|
||||||
|
|
||||||
iosX64()
|
iosX64()
|
||||||
iosArm64()
|
iosArm64()
|
||||||
iosSimulatorArm64()
|
iosSimulatorArm64()
|
||||||
|
|
40
shared/stargate/build.gradle.kts
Normal file
40
shared/stargate/build.gradle.kts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
plugins {
|
||||||
|
alias(libs.plugins.kotlinMultiplatform)
|
||||||
|
alias(libs.plugins.androidLibrary)
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
androidTarget {
|
||||||
|
compilations.all {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "11"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iosX64()
|
||||||
|
iosArm64()
|
||||||
|
iosSimulatorArm64()
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
commonMain.dependencies {
|
||||||
|
implementation(libs.ktor.client.cio)
|
||||||
|
implementation(libs.ktor.client.core)
|
||||||
|
implementation(libs.ktor.client.websockets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "net.agorise.shared.stargate"
|
||||||
|
compileSdk = libs.versions.android.compileSdk.get().toInt()
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = libs.versions.android.minSdk.get().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package net.agorise.shared.stargate
|
||||||
|
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.engine.cio.CIO
|
||||||
|
import io.ktor.client.plugins.websocket.DefaultClientWebSocketSession
|
||||||
|
import io.ktor.client.plugins.websocket.WebSockets
|
||||||
|
import io.ktor.client.plugins.websocket.webSocket
|
||||||
|
import io.ktor.http.HttpMethod
|
||||||
|
import io.ktor.websocket.Frame
|
||||||
|
import io.ktor.websocket.readText
|
||||||
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
|
|
||||||
|
class Bridge {
|
||||||
|
private val client: HttpClient = HttpClient(CIO) { install(WebSockets) }
|
||||||
|
|
||||||
|
suspend fun start() {
|
||||||
|
client.webSocket(method = HttpMethod.Get, host = "node.derofoundation.org", port = 11012, path = "/ws") {
|
||||||
|
outputMessages()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
|
client.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun DefaultClientWebSocketSession.outputMessages() {
|
||||||
|
incoming.receiveAsFlow().collect { message ->
|
||||||
|
(message as? Frame.Text)?.let { textFrame ->
|
||||||
|
println(textFrame.readText())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue