commit 23b7437940a4806f92a4ea713ffdc54df1f67856
parent 71f8d234eefe9aa930f8c9207d95a652ee0042a7
Author: MTRNord <mtrnord1@gmail.com>
Date: Tue, 26 Sep 2023 21:25:14 +0200
Feat: Partially implement password login
Diffstat:
12 files changed, 526 insertions(+), 147 deletions(-)
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="Palette2">
+ <group name="Swing">
+ <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+ </item>
+ <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+ </item>
+ <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
+ <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+ <initial-values>
+ <property name="text" value="Button" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="RadioButton" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="CheckBox" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="Label" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+ <preferred-size width="200" height="200" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+ <preferred-size width="200" height="200" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+ </item>
+ <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+ <preferred-size width="-1" height="20" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+ </item>
+ <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+ </item>
+ </group>
+ </component>
+</project>
+\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
@@ -4,10 +4,28 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
- <list default="true" id="fc5af14b-7484-46dc-b4cb-0394f9dc3dda" name="Changes" comment="Feat: Add very early and basic state handling">
+ <list default="true" id="fc5af14b-7484-46dc-b4cb-0394f9dc3dda" name="Changes" comment="Cleanup">
+ <change afterPath="$PROJECT_DIR$/.idea/uiDesigner.xml" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/src/jsMain/kotlin/pages/Login.kt" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/src/jsMain/resources/index.html" afterDir="false" />
+ <change afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/.idea/uiDesigner.xml" afterDir="false" />
+ <change afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/src/jsMain/kotlin/pages/Login.kt" afterDir="false" />
+ <change afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/src/jsMain/resources/index.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/.run/browser.run.xml" beforeDir="false" />
+ <change beforePath="$PROJECT_DIR$/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle.kts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/settings.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/settings.gradle.kts" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/kotlin/main.kt" beforeDir="false" afterPath="$PROJECT_DIR$/src/jsMain/kotlin/Main.kt" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/kotlin/pages/Login.kt" beforeDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/resources/index.html" beforeDir="false" />
<change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/.idea/workspace.xml" beforeDir="false" afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/.idea/workspace.xml" afterDir="false" />
- <change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/src/main/kotlin/main.kt" beforeDir="false" afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/src/main/kotlin/main.kt" afterDir="false" />
+ <change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/.run/browser.run.xml" beforeDir="false" />
+ <change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/build.gradle.kts" beforeDir="false" afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/build.gradle.kts" afterDir="false" />
+ <change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/gradle/libs.versions.toml" beforeDir="false" afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/gradle/libs.versions.toml" afterDir="false" />
+ <change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/settings.gradle.kts" beforeDir="false" afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/settings.gradle.kts" afterDir="false" />
+ <change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/src/main/kotlin/main.kt" beforeDir="false" afterPath="/var/home/marcel/IdeaProjects/MagicMatrix/src/jsMain/kotlin/Main.kt" afterDir="false" />
+ <change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/src/main/kotlin/pages/Login.kt" beforeDir="false" />
+ <change beforePath="/var/home/marcel/IdeaProjects/MagicMatrix/src/main/resources/index.html" beforeDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -86,7 +104,29 @@
"vue.rearranger.settings.migration": "true"
}
}]]></component>
- <component name="RunManager" selected="Gradle.browser">
+ <component name="RunManager" selected="Gradle.MagicMatrix::var:home:marcel:IdeaProjects:MagicMatrix [jsBrowserRun]">
+ <configuration name="MagicMatrix::var:home:marcel:IdeaProjects:MagicMatrix [jsBrowserRun]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
+ <ExternalSystemSettings>
+ <option name="executionName" />
+ <option name="externalProjectPath" value="/var/home/marcel/IdeaProjects/MagicMatrix" />
+ <option name="externalSystemIdString" value="GRADLE" />
+ <option name="scriptParameters" value="--continuous" />
+ <option name="taskDescriptions">
+ <list />
+ </option>
+ <option name="taskNames">
+ <list>
+ <option value="jsBrowserRun" />
+ </list>
+ </option>
+ <option name="vmOptions" />
+ </ExternalSystemSettings>
+ <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
+ <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
+ <DebugAllEnabled>false</DebugAllEnabled>
+ <RunAsTest>false</RunAsTest>
+ <method v="2" />
+ </configuration>
<configuration name="MagicMatrix::var:home:marcel:IdeaProjects:MagicMatrix [kotlinUpgradeYarnLock]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
<ExternalSystemSettings>
<option name="executionName" />
@@ -111,6 +151,7 @@
</configuration>
<recent_temporary>
<list>
+ <item itemvalue="Gradle.MagicMatrix::var:home:marcel:IdeaProjects:MagicMatrix [jsBrowserRun]" />
<item itemvalue="Gradle.MagicMatrix::var:home:marcel:IdeaProjects:MagicMatrix [kotlinUpgradeYarnLock]" />
</list>
</recent_temporary>
@@ -123,7 +164,7 @@
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1695740188018</updated>
- <workItem from="1695740189223" duration="5352000" />
+ <workItem from="1695740189223" duration="13483000" />
</task>
<task id="LOCAL-00001" summary="Fix: Fix typo in workflow file">
<option name="closed" value="true" />
@@ -165,7 +206,15 @@
<option name="project" value="LOCAL" />
<updated>1695745278124</updated>
</task>
- <option name="localTasksCounter" value="6" />
+ <task id="LOCAL-00006" summary="Cleanup">
+ <option name="closed" value="true" />
+ <created>1695746206343</created>
+ <option name="number" value="00006" />
+ <option name="presentableId" value="LOCAL-00006" />
+ <option name="project" value="LOCAL" />
+ <updated>1695746206343</updated>
+ </task>
+ <option name="localTasksCounter" value="7" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@@ -190,6 +239,7 @@
<MESSAGE value="Feat: Add silk and make sure the right folder is packaged" />
<MESSAGE value="Fix: use correct github action" />
<MESSAGE value="Feat: Add very early and basic state handling" />
- <option name="LAST_COMMIT_MESSAGE" value="Feat: Add very early and basic state handling" />
+ <MESSAGE value="Cleanup" />
+ <option name="LAST_COMMIT_MESSAGE" value="Cleanup" />
</component>
</project>
\ No newline at end of file
diff --git a/.run/browser.run.xml b/.run/browser.run.xml
@@ -1,23 +0,0 @@
-<component name="ProjectRunConfigurationManager">
- <configuration default="false" name="browser" type="GradleRunConfiguration" factoryName="Gradle">
- <ExternalSystemSettings>
- <option name="executionName" />
- <option name="externalProjectPath" value="$PROJECT_DIR$" />
- <option name="externalSystemIdString" value="GRADLE" />
- <option name="scriptParameters" value="" />
- <option name="taskDescriptions">
- <list />
- </option>
- <option name="taskNames">
- <list>
- <option value=":jsBrowserRun" />
- </list>
- </option>
- <option name="vmOptions" />
- </ExternalSystemSettings>
- <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
- <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
- <DebugAllEnabled>false</DebugAllEnabled>
- <method v="2" />
- </configuration>
-</component>
-\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
@@ -1,5 +1,3 @@
-import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
-
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.jetbrains.compose)
@@ -20,9 +18,6 @@ kotlin {
}
sourceSets {
val jsMain by getting {
- kotlin.srcDir("src/main/kotlin")
- resources.srcDir("src/main/resources")
-
dependencies {
implementation(compose.html.core)
implementation(compose.runtime)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
@@ -1,5 +1,5 @@
[versions]
-jetbrains-compose = "1.5.1"
+jetbrains-compose = "1.5.2"
kotlin = "1.9.10"
trixnity = "1.0.5"
koin = "1.1.0"
diff --git a/settings.gradle.kts b/settings.gradle.kts
@@ -2,9 +2,13 @@ pluginManagement {
repositories {
gradlePluginPortal()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
-
maven("https://us-central1-maven.pkg.dev/varabyte-repos/public")
}
+
+ plugins {
+ kotlin("multiplatform").version("1.9.10")
+ id("org.jetbrains.compose").version("1.5.2")
+ }
}
rootProject.name = "MagicMatrix"
\ No newline at end of file
diff --git a/src/jsMain/kotlin/Main.kt b/src/jsMain/kotlin/Main.kt
@@ -0,0 +1,112 @@
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import com.arkivanov.decompose.DefaultComponentContext
+import com.arkivanov.essenty.lifecycle.LifecycleRegistry
+import com.varabyte.kobweb.silk.SilkStyleSheet
+import com.varabyte.kobweb.silk.init.initSilk
+import com.varabyte.kobweb.silk.init.setSilkVariables
+import de.connect2x.trixnity.messenger.DefaultMatrixClientService
+import de.connect2x.trixnity.messenger.trixnityMessengerModule
+import de.connect2x.trixnity.messenger.viewmodel.MainViewModel
+import de.connect2x.trixnity.messenger.viewmodel.RootRouter
+import de.connect2x.trixnity.messenger.viewmodel.RootViewModel
+import de.connect2x.trixnity.messenger.viewmodel.RootViewModelImpl
+import de.connect2x.trixnity.messenger.viewmodel.connecting.MatrixClientInitializationViewModel
+import de.connect2x.trixnity.messenger.viewmodel.util.toFlow
+import kotlinx.browser.document
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.mapLatest
+import org.jetbrains.compose.web.css.Style
+import org.jetbrains.compose.web.css.padding
+import org.jetbrains.compose.web.css.px
+import org.jetbrains.compose.web.dom.Div
+import org.jetbrains.compose.web.dom.Text
+import org.jetbrains.compose.web.renderComposable
+import org.koin.dsl.koinApplication
+import org.w3c.dom.HTMLElement
+
+fun main() {
+ // Init Kobweb
+ initSilk()
+
+ val koinApplication = koinApplication {
+ modules(trixnityMessengerModule())
+ }
+ val matrixClientService = DefaultMatrixClientService(koinApplication.koin)
+ val componentContext = DefaultComponentContext(LifecycleRegistry())
+
+ val rootViewModel = RootViewModelImpl(
+ componentContext = componentContext,
+ matrixClientService = matrixClientService,
+ koinApplication = koinApplication,
+ initialSyncOnceIsFinished = { finished ->
+
+ }
+ )
+ renderComposable(rootElementId = "root") {
+ // Further Init for kobweb
+ val root = remember { document.getElementById("root") as HTMLElement }
+ root.setSilkVariables()
+ Style(SilkStyleSheet)
+
+ Base(rootViewModel)
+ }
+
+}
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@Composable
+fun Base(rootViewModel: RootViewModel) {
+ // Trixnity messenger router
+ // FIXME: This seems to loose type info?
+ val routerState by rootViewModel.rootStack.toFlow()
+ .mapLatest { it.active.instance }.collectAsState(RootRouter.RootWrapper.None)
+
+ when (routerState) {
+ is RootRouter.RootWrapper.None -> {
+ None()
+ }
+
+ is RootRouter.RootWrapper.MatrixClientInitialization -> {
+ Init((routerState as RootRouter.RootWrapper.MatrixClientInitialization).matrixClientInitializationViewModel)
+ } // show initialization of the MatrixClient (aka loading screen)
+
+ is RootRouter.RootWrapper.Main -> {
+ Main((routerState as RootRouter.RootWrapper.Main).mainViewModel)
+ }
+
+ is RootRouter.RootWrapper.AddMatrixAccount -> {
+ Login((routerState as RootRouter.RootWrapper.AddMatrixAccount).addMatrixAccountViewModel)
+ }
+
+ is RootRouter.RootWrapper.PasswordLogin -> {
+ PasswordLogin((routerState as RootRouter.RootWrapper.PasswordLogin).passwordLoginViewModel)
+ }
+
+ else -> {} // add more cases
+ }
+}
+
+@Composable
+fun Main(mainViewModel: MainViewModel) {
+ Div({ style { padding(25.px) } }) {
+ Text("Main")
+ }
+}
+
+@Composable
+fun Init(matrixClientInitializationViewModel: MatrixClientInitializationViewModel) {
+ val initState by matrixClientInitializationViewModel.currentState.collectAsState();
+ Div({ style { padding(25.px) } }) {
+ Text(initState)
+ }
+}
+
+@Composable
+fun None() {
+ Div({ style { padding(25.px) } }) {
+ Text("Initializing matrix")
+ }
+}
+\ No newline at end of file
diff --git a/src/jsMain/kotlin/pages/Login.kt b/src/jsMain/kotlin/pages/Login.kt
@@ -0,0 +1,173 @@
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import com.varabyte.kobweb.compose.foundation.layout.Row
+import com.varabyte.kobweb.compose.ui.Modifier
+import com.varabyte.kobweb.compose.ui.modifiers.*
+import com.varabyte.kobweb.silk.components.forms.InputGroup
+import com.varabyte.kobweb.silk.components.forms.TextInput
+import de.connect2x.trixnity.messenger.viewmodel.connecting.AddMatrixAccountMethod
+import de.connect2x.trixnity.messenger.viewmodel.connecting.AddMatrixAccountViewModel
+import de.connect2x.trixnity.messenger.viewmodel.connecting.PasswordLoginViewModel
+import kotlinx.coroutines.flow.update
+import org.jetbrains.compose.web.css.*
+import org.jetbrains.compose.web.dom.Button
+import org.jetbrains.compose.web.dom.Div
+import org.jetbrains.compose.web.dom.Text
+
+
+@Composable
+fun PasswordLogin(passwordLoginViewModel: PasswordLoginViewModel) {
+ val username by passwordLoginViewModel.username.collectAsState();
+ val password by passwordLoginViewModel.password.collectAsState();
+ Row(
+ Modifier
+ .display(DisplayStyle.Flex)
+ .fillMaxWidth()
+ .fillMaxHeight()
+ .justifyContent(JustifyContent.Center)
+ .alignItems(AlignItems.Center)
+ ) {
+ Div({
+ style {
+ display(DisplayStyle.Flex)
+ flexDirection(FlexDirection.Column)
+ alignItems(AlignItems.FlexStart)
+ }
+ }) {
+ InputGroup(Modifier.display(DisplayStyle.Flex)) {
+ LeftAddon(
+ Modifier.display(DisplayStyle.Flex).alignItems(AlignItems.Center)
+ ) { Text("Username:") }
+ TextInput(
+ username,
+ password = false,
+ onTextChanged = { newText ->
+ passwordLoginViewModel.username.update {
+ newText
+ }
+ passwordLoginViewModel.accountName.update {
+ newText
+ }
+ })
+ }
+ InputGroup(Modifier.display(DisplayStyle.Flex)) {
+ LeftAddon(
+ Modifier.display(DisplayStyle.Flex).alignItems(AlignItems.Center)
+ ) { Text("Password:") }
+ TextInput(
+ password,
+ password = true,
+ onTextChanged = { newText ->
+ passwordLoginViewModel.password.update {
+ newText
+ }
+ })
+ }
+ Button(attrs = {
+ onClick {
+ if (username.isNotBlank() && password.isNotBlank()) {
+ passwordLoginViewModel.tryLogin()
+ }
+ }
+ }) {
+ Text("Login")
+ }
+ }
+ }
+}
+
+@Composable
+fun Login(addMatrixAccountViewModel: AddMatrixAccountViewModel) {
+ val isFirstMatrixClient by addMatrixAccountViewModel.isFirstMatrixClient.collectAsState();
+ val serverUrl by addMatrixAccountViewModel.serverUrl.collectAsState();
+ val serverDiscoveryState by addMatrixAccountViewModel.serverDiscoveryState.collectAsState();
+
+
+ if (isFirstMatrixClient == true) {
+ Row(
+ Modifier
+ .display(DisplayStyle.Flex)
+ .fillMaxWidth()
+ .fillMaxHeight()
+ .justifyContent(JustifyContent.Center)
+ .alignItems(AlignItems.Center)
+ ) {
+ Div({
+ style {
+ display(DisplayStyle.Flex)
+ flexDirection(FlexDirection.Column)
+ alignItems(AlignItems.FlexStart)
+ }
+ }) {
+ InputGroup(Modifier.display(DisplayStyle.Flex)) {
+ LeftAddon(Modifier.display(DisplayStyle.Flex).alignItems(AlignItems.Center)) { Text("Homeserver:") }
+ TextInput(
+ serverUrl,
+ password = false,
+ onTextChanged = { newText ->
+ addMatrixAccountViewModel.serverUrl.update {
+ newText
+ }
+ })
+ }
+ when (serverDiscoveryState) {
+ is AddMatrixAccountViewModel.ServerDiscoveryState.Loading -> Div({
+ classes("lds-dual-ring")
+ })
+
+ is AddMatrixAccountViewModel.ServerDiscoveryState.Failure -> {
+ Div({ style { color(Color("red")) } }) { Text((serverDiscoveryState as AddMatrixAccountViewModel.ServerDiscoveryState.Failure).message) }
+ }
+
+ is AddMatrixAccountViewModel.ServerDiscoveryState.Success -> {
+ val availableMethods =
+ (serverDiscoveryState as AddMatrixAccountViewModel.ServerDiscoveryState.Success).addMatrixAccountMethods
+
+ Div({
+ style {
+ display(DisplayStyle.Flex)
+ flexDirection(FlexDirection.Row)
+ alignItems(AlignItems.Center)
+ justifyContent(JustifyContent.Center)
+ }
+ }) {
+ // FIXME: Make this a tab view instead to change between register and login
+ availableMethods.map { loginMethod ->
+ if (loginMethod is AddMatrixAccountMethod.Password) {
+ Button(attrs = {
+ onClick {
+ addMatrixAccountViewModel.selectAddMatrixAccountMethod(loginMethod)
+ }
+ }) {
+ Text("Login")
+ }
+ }
+ if (loginMethod is AddMatrixAccountMethod.Register) {
+ Button(attrs = {
+ onClick {
+ addMatrixAccountViewModel.selectAddMatrixAccountMethod(loginMethod)
+ }
+ }) {
+ Text("Register")
+ }
+ }
+ }
+
+ }
+
+ }
+
+ AddMatrixAccountViewModel.ServerDiscoveryState.None -> {}
+ }
+ }
+ }
+ // Render the login
+ // 3. Use selectAddMatrixAccountMethod
+ } else {
+ // Render all accounts + add more
+ Div({ style { padding(25.px) } }) {
+ Text("not isFirstMatrixClient")
+ }
+ }
+}
+\ No newline at end of file
diff --git a/src/jsMain/resources/index.html b/src/jsMain/resources/index.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Magic Matrix</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+ <style>
+ html {
+ height: 100%;
+ margin: 0;
+ }
+
+ #root, body {
+ height: 100%;
+ margin: 0;
+ }
+
+ .lds-dual-ring {
+ display: inline-block;
+ width: 80px;
+ height: 80px;
+ }
+
+ .lds-dual-ring:after {
+ content: " ";
+ display: block;
+ width: 64px;
+ height: 64px;
+ margin: 8px;
+ border-radius: 50%;
+ border: 6px solid #000;
+ border-color: #000 transparent #000 transparent;
+ animation: lds-dual-ring 1.2s linear infinite;
+ }
+
+ @keyframes lds-dual-ring {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ </style>
+</head>
+<body>
+<div id="root"></div>
+<script src="MagicMatrix.js"></script>
+</body>
+</html>
+\ No newline at end of file
diff --git a/src/main/kotlin/main.kt b/src/main/kotlin/main.kt
@@ -1,91 +0,0 @@
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
-import com.arkivanov.decompose.DefaultComponentContext
-import com.arkivanov.essenty.lifecycle.LifecycleRegistry
-import com.varabyte.kobweb.silk.SilkStyleSheet
-import com.varabyte.kobweb.silk.init.initSilk
-import com.varabyte.kobweb.silk.init.setSilkVariables
-import de.connect2x.trixnity.messenger.DefaultMatrixClientService
-import de.connect2x.trixnity.messenger.trixnityMessengerModule
-import de.connect2x.trixnity.messenger.viewmodel.RootRouter
-import de.connect2x.trixnity.messenger.viewmodel.RootViewModel
-import de.connect2x.trixnity.messenger.viewmodel.RootViewModelImpl
-import de.connect2x.trixnity.messenger.viewmodel.connecting.MatrixClientInitializationViewModel
-import de.connect2x.trixnity.messenger.viewmodel.util.toFlow
-import kotlinx.browser.document
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.mapLatest
-import org.jetbrains.compose.web.css.Style
-import org.jetbrains.compose.web.css.padding
-import org.jetbrains.compose.web.css.px
-import org.jetbrains.compose.web.dom.Div
-import org.jetbrains.compose.web.dom.Text
-import org.jetbrains.compose.web.renderComposable
-import org.koin.dsl.koinApplication
-import org.w3c.dom.HTMLElement
-
-fun main() {
- // Init Kobweb
- initSilk()
-
- val koinApplication = koinApplication {
- modules(trixnityMessengerModule())
- }
- val matrixClientService = DefaultMatrixClientService(koinApplication.koin)
- val componentContext = DefaultComponentContext(LifecycleRegistry())
-
- val rootViewModel = RootViewModelImpl(
- componentContext = componentContext,
- matrixClientService = matrixClientService,
- koinApplication = koinApplication,
- initialSyncOnceIsFinished = { finished ->
-
- }
- )
- renderComposable(rootElementId = "root") {
- // Further Init for kobweb
- val root = remember { document.getElementById("root") as HTMLElement }
- root.setSilkVariables()
- Style(SilkStyleSheet)
-
- Base(rootViewModel)
- }
-
-}
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@Composable
-fun Base(rootViewModel: RootViewModel) {
- // Trixnity messenger router
- // FIXME: This seems to loose type info?
- val routerState by rootViewModel.rootStack.toFlow()
- .mapLatest { it.active.instance }.collectAsState(RootRouter.RootWrapper.None)
-
- when (routerState) {
- is RootRouter.RootWrapper.None -> {
- None()
- }
-
- is RootRouter.RootWrapper.MatrixClientInitialization -> {
- Init((routerState as RootRouter.RootWrapper.MatrixClientInitialization).matrixClientInitializationViewModel)
- } // show initialization of the MatrixClient (aka loading screen)
- else -> {} // add more cases
- }
-}
-
-@Composable
-fun Init(matrixClientInitializationViewModel: MatrixClientInitializationViewModel) {
- val initState by matrixClientInitializationViewModel.currentState.collectAsState();
- Div({ style { padding(25.px) } }) {
- Text(initState)
- }
-}
-
-@Composable
-fun None() {
- Div({ style { padding(25.px) } }) {
- Text("Initializing matrix")
- }
-}
-\ No newline at end of file
diff --git a/src/main/kotlin/pages/Login.kt b/src/main/kotlin/pages/Login.kt
@@ -1,5 +0,0 @@
-import androidx.compose.runtime.Composable
-import de.connect2x.trixnity.messenger.viewmodel.RootViewModel
-
-@Composable
-fun Login() {}
-\ No newline at end of file
diff --git a/src/main/resources/index.html b/src/main/resources/index.html
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <title>Magic Matrix</title>
-</head>
-<body>
-<div id="root"></div>
-<script src="MagicMatrix.js"></script>
-</body>
-</html>
-\ No newline at end of file