Login.kt (7688B)
1 import androidx.compose.runtime.Composable 2 import androidx.compose.runtime.collectAsState 3 import androidx.compose.runtime.getValue 4 import com.varabyte.kobweb.compose.foundation.layout.Row 5 import com.varabyte.kobweb.compose.ui.Modifier 6 import com.varabyte.kobweb.compose.ui.modifiers.* 7 import com.varabyte.kobweb.silk.components.forms.InputGroup 8 import com.varabyte.kobweb.silk.components.forms.TextInput 9 import de.connect2x.trixnity.messenger.viewmodel.connecting.AddMatrixAccountMethod 10 import de.connect2x.trixnity.messenger.viewmodel.connecting.AddMatrixAccountState 11 import de.connect2x.trixnity.messenger.viewmodel.connecting.AddMatrixAccountViewModel 12 import de.connect2x.trixnity.messenger.viewmodel.connecting.PasswordLoginViewModel 13 import kotlinx.coroutines.flow.update 14 import org.jetbrains.compose.web.css.* 15 import org.jetbrains.compose.web.dom.Button 16 import org.jetbrains.compose.web.dom.Div 17 import org.jetbrains.compose.web.dom.Text 18 19 @Composable 20 fun PasswordLogin(passwordLoginViewModel: PasswordLoginViewModel) { 21 val username by passwordLoginViewModel.username.collectAsState(); 22 val password by passwordLoginViewModel.password.collectAsState(); 23 val canLogin by passwordLoginViewModel.canLogin.collectAsState(); 24 val loginState by passwordLoginViewModel.addMatrixAccountState.collectAsState(); 25 Row( 26 Modifier 27 .display(DisplayStyle.Flex) 28 .fillMaxWidth() 29 .fillMaxHeight() 30 .justifyContent(JustifyContent.Center) 31 .alignItems(AlignItems.Center) 32 ) { 33 Div({ 34 style { 35 display(DisplayStyle.Flex) 36 flexDirection(FlexDirection.Column) 37 alignItems(AlignItems.FlexStart) 38 } 39 }) { 40 InputGroup(Modifier.display(DisplayStyle.Flex)) { 41 LeftAddon( 42 Modifier.display(DisplayStyle.Flex).alignItems(AlignItems.Center) 43 ) { Text("Username:") } 44 TextInput( 45 username, 46 password = false, 47 onTextChanged = { newText -> 48 passwordLoginViewModel.accountName.update { 49 newText 50 } 51 passwordLoginViewModel.username.update { 52 newText 53 } 54 }) 55 } 56 InputGroup(Modifier.display(DisplayStyle.Flex)) { 57 LeftAddon( 58 Modifier.display(DisplayStyle.Flex).alignItems(AlignItems.Center) 59 ) { Text("Password:") } 60 TextInput( 61 password, 62 password = true, 63 onTextChanged = { newText -> 64 passwordLoginViewModel.password.update { 65 newText 66 } 67 }) 68 } 69 if (canLogin && loginState !is AddMatrixAccountState.Connecting) { 70 Button(attrs = { 71 onClick { 72 if (username.isNotBlank() && password.isNotBlank() && canLogin) { 73 passwordLoginViewModel.tryLogin() 74 } 75 } 76 }) { 77 Text("Login") 78 } 79 } else if (loginState is AddMatrixAccountState.Connecting) { 80 Div({ 81 classes("lds-dual-ring") 82 }) 83 } 84 } 85 } 86 } 87 88 @Composable 89 fun Login(addMatrixAccountViewModel: AddMatrixAccountViewModel) { 90 val isFirstMatrixClient by addMatrixAccountViewModel.isFirstMatrixClient.collectAsState(); 91 val serverUrl by addMatrixAccountViewModel.serverUrl.collectAsState(); 92 val serverDiscoveryState by addMatrixAccountViewModel.serverDiscoveryState.collectAsState(); 93 94 95 if (isFirstMatrixClient == true) { 96 Row( 97 Modifier 98 .display(DisplayStyle.Flex) 99 .fillMaxWidth() 100 .fillMaxHeight() 101 .justifyContent(JustifyContent.Center) 102 .alignItems(AlignItems.Center) 103 ) { 104 Div({ 105 style { 106 display(DisplayStyle.Flex) 107 flexDirection(FlexDirection.Column) 108 alignItems(AlignItems.FlexStart) 109 } 110 }) { 111 InputGroup(Modifier.display(DisplayStyle.Flex)) { 112 LeftAddon(Modifier.display(DisplayStyle.Flex).alignItems(AlignItems.Center)) { Text("Homeserver:") } 113 TextInput( 114 serverUrl, 115 password = false, 116 onTextChanged = { newText -> 117 addMatrixAccountViewModel.serverUrl.update { 118 newText 119 } 120 }) 121 } 122 when (serverDiscoveryState) { 123 is AddMatrixAccountViewModel.ServerDiscoveryState.Loading -> Div({ 124 classes("lds-dual-ring") 125 }) 126 127 is AddMatrixAccountViewModel.ServerDiscoveryState.Failure -> { 128 Div({ style { color(Color("red")) } }) { Text((serverDiscoveryState as AddMatrixAccountViewModel.ServerDiscoveryState.Failure).message) } 129 } 130 131 is AddMatrixAccountViewModel.ServerDiscoveryState.Success -> { 132 val availableMethods = 133 (serverDiscoveryState as AddMatrixAccountViewModel.ServerDiscoveryState.Success).addMatrixAccountMethods 134 135 Div({ 136 style { 137 display(DisplayStyle.Flex) 138 flexDirection(FlexDirection.Row) 139 alignItems(AlignItems.Center) 140 justifyContent(JustifyContent.Center) 141 } 142 }) { 143 // FIXME: Make this a tab view instead to change between register and login 144 availableMethods.map { loginMethod -> 145 if (loginMethod is AddMatrixAccountMethod.Password) { 146 Button(attrs = { 147 onClick { 148 addMatrixAccountViewModel.selectAddMatrixAccountMethod(loginMethod) 149 } 150 }) { 151 Text("Login") 152 } 153 } 154 if (loginMethod is AddMatrixAccountMethod.Register) { 155 Button(attrs = { 156 onClick { 157 addMatrixAccountViewModel.selectAddMatrixAccountMethod(loginMethod) 158 } 159 }) { 160 Text("Register") 161 } 162 } 163 } 164 } 165 } 166 167 AddMatrixAccountViewModel.ServerDiscoveryState.None -> {} 168 } 169 } 170 } 171 // Render the login 172 // 3. Use selectAddMatrixAccountMethod 173 } else { 174 // Render all accounts + add more 175 Div({ style { padding(25.px) } }) { 176 Text("not isFirstMatrixClient") 177 } 178 } 179 }