diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2d9d1f4..bd1128e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - @@ -33,7 +32,8 @@ + android:exported="true" + android:theme="@android:style/Theme.NoTitleBar"> @@ -42,8 +42,12 @@ - + android:name=".ui.login.LoginActivity" + android:theme="@android:style/Theme.NoTitleBar" /> + + diff --git a/app/src/main/java/eu/steffo/twom/HomeserverActivity.kt b/app/src/main/java/eu/steffo/twom/HomeserverActivity.kt deleted file mode 100644 index f856787..0000000 --- a/app/src/main/java/eu/steffo/twom/HomeserverActivity.kt +++ /dev/null @@ -1,21 +0,0 @@ -package eu.steffo.twom - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import eu.steffo.twom.ui.fragment.HomeserverFragment -import eu.steffo.twom.ui.theme.TwoMTheme - - -class HomeserverActivity : ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - actionBar?.hide() - - setContent { - TwoMTheme { - HomeserverFragment() - } - } - } -} diff --git a/app/src/main/java/eu/steffo/twom/MainActivity.kt b/app/src/main/java/eu/steffo/twom/MainActivity.kt index 054882e..e6bf100 100644 --- a/app/src/main/java/eu/steffo/twom/MainActivity.kt +++ b/app/src/main/java/eu/steffo/twom/MainActivity.kt @@ -2,30 +2,65 @@ package eu.steffo.twom import android.content.Intent import android.os.Bundle +import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold import androidx.compose.material3.Text -import eu.steffo.twom.global.TwoMMatrix +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import eu.steffo.twom.matrix.TwoMMatrix +import eu.steffo.twom.ui.login.LoginActivity import eu.steffo.twom.ui.theme.TwoMTheme +@OptIn(ExperimentalMaterial3Api::class) class MainActivity : ComponentActivity() { + private lateinit var loginLauncher: ActivityResultLauncher + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) actionBar?.hide() TwoMMatrix.initMatrix(applicationContext) - TwoMMatrix.initSessionFromStorage() + TwoMMatrix.tryInitSessionFromStorage() - // Do this in a better way - if(TwoMMatrix.session == null) { - val homeserverIntent = Intent(applicationContext, HomeserverActivity::class.java) - startActivity(homeserverIntent) + loginLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + Log.i("Garasauto", "Garaso") } + } + + override fun onStart() { + super.onStart() setContent { TwoMTheme { - Text("Garasauto") + Scaffold( + topBar = { + CenterAlignedTopAppBar ( + title = { Text(LocalContext.current.getString(R.string.app_name)) } + ) + } + ) { + Row(Modifier.padding(it)) { + Button( + modifier = Modifier.fillMaxWidth(), + onClick = { + loginLauncher.launch(Intent(applicationContext, LoginActivity::class.java)) + } + ) { + Text("→") + } + } + } } } } diff --git a/app/src/main/java/eu/steffo/twom/global/TwoMMatrix.kt b/app/src/main/java/eu/steffo/twom/global/TwoMMatrix.kt deleted file mode 100644 index ec9ab2c..0000000 --- a/app/src/main/java/eu/steffo/twom/global/TwoMMatrix.kt +++ /dev/null @@ -1,38 +0,0 @@ -package eu.steffo.twom.global - -import TwoMRoomDisplayNameFallbackProvider -import android.content.Context -import org.matrix.android.sdk.api.Matrix -import org.matrix.android.sdk.api.MatrixConfiguration -import org.matrix.android.sdk.api.session.Session - - -object TwoMMatrix { - lateinit var matrix: Matrix - private set - - fun initMatrix(context: Context) { - matrix = Matrix( - context = context.applicationContext, - matrixConfiguration = MatrixConfiguration( - applicationFlavor = "TwoM", - roomDisplayNameFallbackProvider = TwoMRoomDisplayNameFallbackProvider(context.applicationContext) - ) - ) - } - - var session: Session? = null - - fun initSessionFromStorage() { - val lastSession = matrix.authenticationService().getLastAuthenticatedSession() - if(lastSession != null) { - session = lastSession - } - } - - fun openSession() { - // FIXME: Possible race condition here? - session?.open() - session?.syncService()?.startSync(true) - } -} diff --git a/app/src/main/java/eu/steffo/twom/matrix/MatrixAlreadyInitializedError.kt b/app/src/main/java/eu/steffo/twom/matrix/MatrixAlreadyInitializedError.kt new file mode 100644 index 0000000..75a5ad6 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/matrix/MatrixAlreadyInitializedError.kt @@ -0,0 +1,3 @@ +package eu.steffo.twom.matrix + +class MatrixAlreadyInitializedError : Exception() diff --git a/app/src/main/java/eu/steffo/twom/matrix/SessionAlreadyInitializedError.kt b/app/src/main/java/eu/steffo/twom/matrix/SessionAlreadyInitializedError.kt new file mode 100644 index 0000000..7b073fe --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/matrix/SessionAlreadyInitializedError.kt @@ -0,0 +1,3 @@ +package eu.steffo.twom.matrix + +class SessionAlreadyInitializedError : Exception() diff --git a/app/src/main/java/eu/steffo/twom/matrix/SessionNotInitializedError.kt b/app/src/main/java/eu/steffo/twom/matrix/SessionNotInitializedError.kt new file mode 100644 index 0000000..ad59ba9 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/matrix/SessionNotInitializedError.kt @@ -0,0 +1,3 @@ +package eu.steffo.twom.matrix + +class SessionNotInitializedError : Exception() diff --git a/app/src/main/java/eu/steffo/twom/matrix/TwoMMatrix.kt b/app/src/main/java/eu/steffo/twom/matrix/TwoMMatrix.kt new file mode 100644 index 0000000..98f25d0 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/matrix/TwoMMatrix.kt @@ -0,0 +1,56 @@ +package eu.steffo.twom.matrix + +import TwoMRoomDisplayNameFallbackProvider +import android.content.Context +import androidx.compose.runtime.currentComposer +import org.matrix.android.sdk.api.Matrix +import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.session.Session + + +object TwoMMatrix { + var matrix: Matrix? = null + private set + + fun initMatrix(context: Context) { + if(matrix != null) { + throw MatrixAlreadyInitializedError() + } + matrix = Matrix( + context = context.applicationContext, + matrixConfiguration = MatrixConfiguration( + applicationFlavor = "TwoM", + roomDisplayNameFallbackProvider = TwoMRoomDisplayNameFallbackProvider(context.applicationContext) + ) + ) + } + + var session: Session? = null + private set + + fun tryInitSessionFromStorage() { + val lastSession = matrix?.authenticationService()?.getLastAuthenticatedSession() + if(lastSession != null) { + session = lastSession + } + } + + // TODO: Does this throw an error if the session is already open? + fun openSession() { + val currentSession = session ?: throw SessionNotInitializedError() + currentSession.open() + currentSession.syncService().startSync(true) + } + + // TODO: Does this throw an error if the session is already closed? + fun closeSession() { + val currentSession = session ?: throw SessionNotInitializedError() + currentSession.close() + currentSession.syncService().stopSync() + } + + fun clearSession() { + closeSession() + session = null + } +} diff --git a/app/src/main/java/eu/steffo/twom/global/TwoMRoomDisplayNameFallbackProvider.kt b/app/src/main/java/eu/steffo/twom/matrix/TwoMRoomDisplayNameFallbackProvider.kt similarity index 100% rename from app/src/main/java/eu/steffo/twom/global/TwoMRoomDisplayNameFallbackProvider.kt rename to app/src/main/java/eu/steffo/twom/matrix/TwoMRoomDisplayNameFallbackProvider.kt diff --git a/app/src/main/java/eu/steffo/twom/ui/fragment/HomeserverFragment.kt b/app/src/main/java/eu/steffo/twom/ui/fragment/HomeserverFragment.kt deleted file mode 100644 index 8a28fad..0000000 --- a/app/src/main/java/eu/steffo/twom/ui/fragment/HomeserverFragment.kt +++ /dev/null @@ -1,119 +0,0 @@ -package eu.steffo.twom.ui.fragment - -import android.net.Uri -import android.webkit.URLUtil -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Button -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import eu.steffo.twom.R -import eu.steffo.twom.global.TwoMMatrix -import eu.steffo.twom.ui.input.SelectHomeserverField -import eu.steffo.twom.ui.input.SelectHomeserverFieldState -import eu.steffo.twom.ui.scaffold.TwoMTopAppBar -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig - -@Composable -@Preview -fun HomeserverFragment() { - val scope = rememberCoroutineScope() - val matrix = TwoMMatrix.matrix - - var homeserver by rememberSaveable { mutableStateOf("") } - var state by rememberSaveable { mutableStateOf(SelectHomeserverFieldState.Empty) } - var urlValid by rememberSaveable { mutableStateOf(null) } - var flowValid by rememberSaveable { mutableStateOf(null) } - - TwoMTopAppBar { - Column( - modifier = Modifier.padding(it) - ) { - Row( - modifier = Modifier.padding(start = 20.dp, end = 20.dp, bottom = 10.dp) - ) { - Text(LocalContext.current.getString(R.string.login_welcome_text)) - } - Row( - modifier = Modifier.padding(start = 20.dp, end = 20.dp, bottom = 10.dp) - ) { - SelectHomeserverField( - modifier = Modifier.fillMaxWidth(), - value = homeserver, - onValueChange = OnValueChange@{ - homeserver = it - urlValid = null - flowValid = null - state = SelectHomeserverFieldState.Empty - - if(homeserver == "") { - return@OnValueChange - } - - if(!(URLUtil.isHttpUrl(homeserver) || URLUtil.isHttpsUrl(homeserver))) { - state = SelectHomeserverFieldState.Error - urlValid = false - return@OnValueChange - } - urlValid = true - - val uri = Uri.parse(homeserver) - - scope.launch ValidateFlows@{ - state = SelectHomeserverFieldState.Waiting - delay(500L) - if(homeserver != it) return@ValidateFlows - - val authenticationService = matrix.authenticationService() - - state = SelectHomeserverFieldState.Validating - try { - authenticationService.getLoginFlow(HomeServerConnectionConfig( - homeServerUri = uri, - )) - } - catch(e: Throwable) { - state = SelectHomeserverFieldState.Error - flowValid = false - return@ValidateFlows - } - - state = SelectHomeserverFieldState.Done - flowValid = true - } - }, - state = state, - error = - if(urlValid == false) LocalContext.current.getString(R.string.homeserver_error_malformedurl) - else if(flowValid == false) LocalContext.current.getString(R.string.homeserver_error_notmatrix) - else null - , - ) - } - Row( - modifier = Modifier.padding(start = 20.dp, end = 20.dp, top = 10.dp, bottom = 10.dp) - ) { - Button( - onClick = {}, - enabled = urlValid == true && flowValid == true, - modifier = Modifier.fillMaxWidth(), - ) { - Text(LocalContext.current.getString(R.string.login_button_continue_text)) - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverActivity.kt b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverActivity.kt new file mode 100644 index 0000000..6f353d6 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverActivity.kt @@ -0,0 +1,30 @@ +package eu.steffo.twom.ui.homeserver + +import android.content.Intent +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent + + +class SelectHomeserverActivity : ComponentActivity() { + companion object { + const val HOMESERVER_EXTRA_KEY = "homeserver" + } + + override fun onStart() { + super.onStart() + setContent { + SelectHomeserverScaffold( + onBack = { + setResult(RESULT_CANCELED) + finish() + }, + onComplete = { + val result = Intent() + result.putExtra(HOMESERVER_EXTRA_KEY, it) + setResult(RESULT_OK, result) + finish() + } + ) + } + } +} diff --git a/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverControl.kt b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverControl.kt new file mode 100644 index 0000000..6d6ad7a --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverControl.kt @@ -0,0 +1,102 @@ +package eu.steffo.twom.ui.homeserver + +import android.net.Uri +import android.webkit.URLUtil +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import eu.steffo.twom.R +import eu.steffo.twom.matrix.TwoMMatrix +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig + + +@Composable +@Preview(showBackground = true) +fun SelectHomeserverControl( + modifier: Modifier = Modifier, + onComplete: (homeserver: String) -> Unit = {}, +) { + val scope = rememberCoroutineScope() + + var homeserver by rememberSaveable { mutableStateOf("") } + var state by rememberSaveable { mutableStateOf(SelectHomeserverFieldState.Empty) } + + val padding = Modifier.padding(all = 10.dp) + + Column(modifier) { + Row(padding) { + Text(LocalContext.current.getString(R.string.selecthomeserver_text)) + } + Row(padding) { + SelectHomeserverField( + modifier = Modifier.fillMaxWidth(), + value = homeserver, + onValueChange = OnValueChange@{ + homeserver = it + state = SelectHomeserverFieldState.Empty + + if (homeserver == "") { + return@OnValueChange + } + + if (!(URLUtil.isHttpUrl(homeserver) || URLUtil.isHttpsUrl(homeserver))) { + state = SelectHomeserverFieldState.URLInvalid + return@OnValueChange + } + + val uri = Uri.parse(homeserver) + + scope.launch ValidateFlows@{ + state = SelectHomeserverFieldState.Waiting + delay(500L) + if (homeserver != it) return@ValidateFlows + + val authenticationService = TwoMMatrix.matrix!!.authenticationService() + + state = SelectHomeserverFieldState.Validating + try { + authenticationService.getLoginFlow( + HomeServerConnectionConfig( + homeServerUri = uri, + ) + ) + } catch (e: Throwable) { + state = SelectHomeserverFieldState.FlowInvalid + return@ValidateFlows + } + + state = SelectHomeserverFieldState.Valid + } + }, + enabled = (TwoMMatrix.matrix != null), + state = state, + ) + } + Row(padding) { + Button( + onClick = { + onComplete(homeserver) + }, + enabled = (state == SelectHomeserverFieldState.Valid), + modifier = Modifier.fillMaxWidth(), + ) { + Text(LocalContext.current.getString(R.string.selecthomeserver_complete_text)) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverField.kt b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverField.kt new file mode 100644 index 0000000..02e8937 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverField.kt @@ -0,0 +1,70 @@ +package eu.steffo.twom.ui.homeserver + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Create +import androidx.compose.material.icons.filled.Send +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview +import eu.steffo.twom.R + + +@Composable +@Preview +fun SelectHomeserverField( + modifier: Modifier = Modifier, + value: String = "", + onValueChange: (String) -> Unit = {}, + enabled: Boolean = true, + state: SelectHomeserverFieldState = SelectHomeserverFieldState.Empty, +) { + TextField( + modifier = modifier, + value = value, + onValueChange = onValueChange, + enabled = enabled, + singleLine = true, + label = { + Text(LocalContext.current.getString(R.string.selecthomeserver_input_label)) + }, + placeholder = { + Text(LocalContext.current.getString(R.string.selecthomeserver_input_placeholder)) + }, + trailingIcon = { + Icon( + when(state) { + SelectHomeserverFieldState.Empty -> Icons.Default.Create + SelectHomeserverFieldState.Waiting -> Icons.Default.Create + SelectHomeserverFieldState.Validating -> Icons.Default.Send + SelectHomeserverFieldState.URLInvalid -> Icons.Default.Close + SelectHomeserverFieldState.FlowInvalid -> Icons.Default.Close + SelectHomeserverFieldState.Valid -> Icons.Default.Check + }, + null + ) + }, + supportingText = { + Text( + when(state) { + SelectHomeserverFieldState.Empty -> LocalContext.current.getString(R.string.selecthomeserver_input_supporting_empty) + SelectHomeserverFieldState.Waiting -> LocalContext.current.getString(R.string.selecthomeserver_input_supporting_waiting) + SelectHomeserverFieldState.Validating -> LocalContext.current.getString(R.string.selecthomeserver_input_supporting_validating) + SelectHomeserverFieldState.URLInvalid -> LocalContext.current.getString(R.string.selecthomeserver_input_supporting_urlinvalid) + SelectHomeserverFieldState.FlowInvalid -> LocalContext.current.getString(R.string.selecthomeserver_input_supporting_flowinvalid) + SelectHomeserverFieldState.Valid -> LocalContext.current.getString(R.string.selecthomeserver_input_supporting_valid) + } + ) + }, + isError = when(state) { + SelectHomeserverFieldState.URLInvalid -> true + SelectHomeserverFieldState.FlowInvalid -> true + else -> false + } + ) +} \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverFieldState.kt b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverFieldState.kt new file mode 100644 index 0000000..15245b6 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverFieldState.kt @@ -0,0 +1,10 @@ +package eu.steffo.twom.ui.homeserver + +enum class SelectHomeserverFieldState { + Empty, + Waiting, + Validating, + URLInvalid, + FlowInvalid, + Valid, +} diff --git a/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverScaffold.kt b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverScaffold.kt new file mode 100644 index 0000000..cb5bd81 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/ui/homeserver/SelectHomeserverScaffold.kt @@ -0,0 +1,51 @@ +package eu.steffo.twom.ui.homeserver + +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview +import eu.steffo.twom.R +import eu.steffo.twom.ui.theme.TwoMTheme + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +@Preview +fun SelectHomeserverScaffold( + onBack: () -> Unit = {}, + onComplete: (homeserver: String) -> Unit = {}, +) { + TwoMTheme { + Scaffold( + topBar = { + TopAppBar ( + navigationIcon = { + IconButton(onClick = onBack) { + Icon( + imageVector = Icons.Filled.ArrowBack, + contentDescription = LocalContext.current.getString(R.string.back) + ) + } + }, + title = { + Text(LocalContext.current.getString(R.string.homeserver_title)) + }, + ) + } + ) { + SelectHomeserverControl( + modifier = Modifier.padding(it), + onComplete = onComplete + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/ui/input/SelectHomeserverField.kt b/app/src/main/java/eu/steffo/twom/ui/input/SelectHomeserverField.kt deleted file mode 100644 index 8d1c539..0000000 --- a/app/src/main/java/eu/steffo/twom/ui/input/SelectHomeserverField.kt +++ /dev/null @@ -1,67 +0,0 @@ -package eu.steffo.twom.ui.input - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Build -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Create -import androidx.compose.material.icons.filled.Send -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.material3.TextField -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.tooling.preview.Preview -import eu.steffo.twom.R - - -enum class SelectHomeserverFieldState { - Empty, - Waiting, - Validating, - Error, - Done, -} - - -@Composable -@Preview -fun SelectHomeserverField( - modifier: Modifier = Modifier, - value: String = "", - onValueChange: (String) -> Unit = {}, - enabled: Boolean = true, - state: SelectHomeserverFieldState = SelectHomeserverFieldState.Empty, - error: String? = null, -) { - TextField( - modifier = modifier, - value = value, - onValueChange = onValueChange, - enabled = enabled, - singleLine = true, - label = { - Text(LocalContext.current.getString(R.string.homeserver_label)) - }, - placeholder = { - Text(LocalContext.current.getString(R.string.homeserver_placeholder)) - }, - trailingIcon = { - Icon( - when(state) { - SelectHomeserverFieldState.Empty -> Icons.Default.Build - SelectHomeserverFieldState.Waiting -> Icons.Default.Create - SelectHomeserverFieldState.Validating -> Icons.Default.Send - SelectHomeserverFieldState.Error -> Icons.Default.Close - SelectHomeserverFieldState.Done -> Icons.Default.Check - }, - LocalContext.current.getString(R.string.homeserver_trailingicon_validating_description) - ) - }, - supportingText = { - Text(error ?: LocalContext.current.getString(R.string.homeserver_supporting)) - }, - isError = (error != null) - ) -} \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/ui/login/LoginActivity.kt b/app/src/main/java/eu/steffo/twom/ui/login/LoginActivity.kt new file mode 100644 index 0000000..4cbc3f5 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/ui/login/LoginActivity.kt @@ -0,0 +1,63 @@ +package eu.steffo.twom.ui.login + +import android.content.Intent +import android.os.Bundle +import android.util.Log +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import eu.steffo.twom.R +import eu.steffo.twom.ui.homeserver.SelectHomeserverActivity +import eu.steffo.twom.ui.theme.TwoMTheme + + +@OptIn(ExperimentalMaterial3Api::class) +class LoginActivity : ComponentActivity() { + private lateinit var homeserverLauncher: ActivityResultLauncher + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + homeserverLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + Log.i("Garasauto", it.data?.getStringExtra(SelectHomeserverActivity.HOMESERVER_EXTRA_KEY) ?: "Undefined") + } + } + + override fun onStart() { + super.onStart() + + setContent { + TwoMTheme { + Scaffold( + topBar = { + TopAppBar ( + title = { Text(LocalContext.current.getString(R.string.login_title)) } + ) + } + ) { + Row(Modifier.padding(it)) { + Button( + modifier = Modifier.fillMaxWidth(), + onClick = { + homeserverLauncher.launch(Intent(applicationContext, SelectHomeserverActivity::class.java)) + } + ) { + Text("→") + } + } + } + } + } + } +} diff --git a/app/src/main/java/eu/steffo/twom/ui/scaffold/TwoMNavigationDrawer.kt b/app/src/main/java/eu/steffo/twom/ui/scaffold/TwoMNavigationDrawer.kt deleted file mode 100644 index 9e89656..0000000 --- a/app/src/main/java/eu/steffo/twom/ui/scaffold/TwoMNavigationDrawer.kt +++ /dev/null @@ -1,36 +0,0 @@ -package eu.steffo.twom.ui.scaffold - -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.ModalDrawerSheet -import androidx.compose.material3.ModalNavigationDrawer -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - - -@Composable -fun TwoMNavigationDrawer( - modifier: Modifier = Modifier, - content: @Composable () -> Unit = {}, -) { - ModalNavigationDrawer( - drawerContent = { - Drawer() - } - ) { - Surface( - modifier = modifier, - color = MaterialTheme.colorScheme.background - ) { - content() - } - } -} - -@Composable -fun Drawer() { - ModalDrawerSheet { - Text("garasauto") - } -} diff --git a/app/src/main/java/eu/steffo/twom/ui/scaffold/TwoMTopAppBar.kt b/app/src/main/java/eu/steffo/twom/ui/scaffold/TwoMTopAppBar.kt deleted file mode 100644 index 3fc8e74..0000000 --- a/app/src/main/java/eu/steffo/twom/ui/scaffold/TwoMTopAppBar.kt +++ /dev/null @@ -1,26 +0,0 @@ -package eu.steffo.twom.ui.scaffold - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.material3.CenterAlignedTopAppBar -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext -import eu.steffo.twom.R - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun TwoMTopAppBar( - content: @Composable (innerPadding: PaddingValues) -> Unit = {}, -) { - Scaffold( - topBar = { - CenterAlignedTopAppBar( - title = { Text(LocalContext.current.getString(R.string.app_name)) } - ) - } - ) { - content(it) - } -} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1aa21fb..86f634c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,9 +1,9 @@ TwoM - https://candy.steffo.eu - Homeserver - The URL of the homeserver providing you with Matrix access. - The homeserver URL you provided is not a valid URL. + https://candy.steffo.eu + Homeserver + The URL of the homeserver providing you with Matrix access. + The homeserver URL you provided is not a valid URL. Is this even a party? %1$s\'s party %1$s and %2$s\'s party @@ -11,10 +11,13 @@ %1$s, %2$s, %3$s, %4$s\'s party %1$s, %2$s, %3$s and %4$d others\' party Party invite - Continue - Welcome to TwoM! To start using the app, you\'ll need to select the Matrix homeserver you want to use. - The homeserver URL you provided does not point to a Matrix homeserver. - Checking if the URL points to a Matrix homeserver… - Waiting for you to stop writing… - All checks complete. + Continue + Please select the homeserver you would like to log into. + The homeserver URL you provided does not point to a Matrix homeserver. + Checking if the URL points to a Matrix homeserver… + Waiting for you to stop writing… + All checks complete! + Select homeserver + Log into Matrix + Go back \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..045e125 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,3 @@ + + +