Create login module

This commit is contained in:
Benoit Marty 2022-10-07 17:31:27 +02:00
parent 94d031ffce
commit a18d272462
13 changed files with 224 additions and 37 deletions

View file

@ -47,6 +47,7 @@ android {
dependencies { dependencies {
implementation project(":libraries:ui:theme") implementation project(":libraries:ui:theme")
implementation project(":libraries:ui:screens:login")
implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-ktx:1.9.0'
implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.ui:ui:$compose_version"

View file

@ -11,12 +11,10 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.ElementX" android:theme="@style/Theme.ElementX"
tools:targetApi="31"> tools:targetApi="33">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true">
android:label="@string/app_name"
android:theme="@style/Theme.ElementX">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

View file

@ -1,43 +1,16 @@
package io.element.android.x package io.element.android.x
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import io.element.android.x.ui.screen.login.LoginActivity
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.x.ui.theme.ElementXTheme
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { // Just start the LoginActivity for now.
ElementXTheme { // TODO if a session exist, start the room list
// A surface container using the 'background' color from the theme startActivity(Intent(this, LoginActivity::class.java))
Surface( finish()
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
}
}
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ElementXTheme {
Greeting("Android")
} }
} }

View file

@ -0,0 +1,57 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'io.element.android.x.ui.screen.login'
compileSdk 33
defaultConfig {
minSdk 29
targetSdk 33
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation project(":libraries:ui:theme")
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation 'androidx.compose.material3:material3:1.0.0-rc01'
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation 'androidx.activity:activity-compose:1.6.0'
implementation 'androidx.fragment:fragment-ktx:1.5.3'
}

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name="LoginActivity" />
</application>
</manifest>

View file

@ -0,0 +1,7 @@
package io.element.android.x.ui.screen.login
sealed interface LoginActions {
data class SetLogin(val login: String) : LoginActions
data class SetPassword(val password: String) : LoginActions
object Submit : LoginActions
}

View file

@ -0,0 +1,62 @@
package io.element.android.x.ui.screen.login
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import io.element.android.x.ui.theme.ElementXTheme
import io.element.android.x.ui.theme.components.VectorButton
import io.element.android.x.ui.theme.components.VectorTextField
class LoginActivity : ComponentActivity() {
private val viewModel: LoginViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ElementXTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
color = MaterialTheme.colorScheme.background
) {
Column(
modifier = Modifier.fillMaxSize()
) {
val state = viewModel.state.collectAsState().value
VectorTextField(
value = state.login,
onValueChange = {
viewModel.handle(LoginActions.SetLogin(it))
})
VectorTextField(
value = state.password,
onValueChange = {
viewModel.handle(LoginActions.SetPassword(it))
}
)
VectorButton(
text = "Submit",
onClick = {
viewModel.handle(LoginActions.Submit)
},
enabled = state.submitEnabled,
)
}
}
}
}
}
}

View file

@ -0,0 +1,37 @@
package io.element.android.x.ui.screen.login
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
class LoginViewModel : ViewModel() {
private val _state = MutableStateFlow(LoginViewState())
val state = _state.asStateFlow()
fun handle(action: LoginActions) {
when (action) {
is LoginActions.SetLogin -> handleSetName(action)
is LoginActions.SetPassword -> handleSetPassword(action)
LoginActions.Submit -> handleSubmit()
}
}
private fun handleSubmit() {
// TODO
}
private fun handleSetPassword(action: LoginActions.SetPassword) {
_state.value = _state.value.copy(
password = action.password,
submitEnabled = _state.value.login.isNotEmpty() && action.password.isNotEmpty()
)
}
private fun handleSetName(action: LoginActions.SetLogin) {
_state.value = _state.value.copy(
login = action.login,
submitEnabled = action.login.isNotEmpty() && _state.value.password.isNotEmpty()
)
}
}

View file

@ -0,0 +1,7 @@
package io.element.android.x.ui.screen.login
data class LoginViewState(
val login: String = "",
val password: String = "",
val submitEnabled: Boolean = false,
)

View file

@ -45,4 +45,6 @@ dependencies {
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
} }

View file

@ -0,0 +1,16 @@
package io.element.android.x.ui.theme.components
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun VectorButton(text: String, enabled: Boolean, onClick: () -> Unit) {
Button(
onClick = onClick,
enabled = enabled,
) {
Text(text = text)
}
}

View file

@ -0,0 +1,18 @@
package io.element.android.x.ui.theme.components
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun VectorTextField(value: String, onValueChange: (String) -> Unit) {
OutlinedTextField(
value = value,
onValueChange = onValueChange,
modifier = Modifier.fillMaxWidth()
)
}

View file

@ -15,3 +15,4 @@ dependencyResolutionManagement {
rootProject.name = "ElementX" rootProject.name = "ElementX"
include ':app' include ':app'
include ':libraries:ui:theme' include ':libraries:ui:theme'
include ':libraries:ui:screens:login'