mirror of
https://github.com/Steffo99/twom.git
synced 2024-11-25 09:34:25 +00:00
Get activity message passing working
This commit is contained in:
parent
c42027be24
commit
395ec102c8
21 changed files with 458 additions and 329 deletions
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
@ -33,7 +32,8 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true">
|
android:exported="true"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
@ -42,8 +42,12 @@
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".HomeserverActivity">
|
android:name=".ui.login.LoginActivity"
|
||||||
</activity>
|
android:theme="@android:style/Theme.NoTitleBar" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".ui.homeserver.SelectHomeserverActivity"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,30 +2,65 @@ package eu.steffo.twom
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
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 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
|
import eu.steffo.twom.ui.theme.TwoMTheme
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
private lateinit var loginLauncher: ActivityResultLauncher<Intent>
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
actionBar?.hide()
|
actionBar?.hide()
|
||||||
|
|
||||||
TwoMMatrix.initMatrix(applicationContext)
|
TwoMMatrix.initMatrix(applicationContext)
|
||||||
TwoMMatrix.initSessionFromStorage()
|
TwoMMatrix.tryInitSessionFromStorage()
|
||||||
|
|
||||||
// Do this in a better way
|
loginLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||||
if(TwoMMatrix.session == null) {
|
Log.i("Garasauto", "Garaso")
|
||||||
val homeserverIntent = Intent(applicationContext, HomeserverActivity::class.java)
|
|
||||||
startActivity(homeserverIntent)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
TwoMTheme {
|
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("→")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package eu.steffo.twom.matrix
|
||||||
|
|
||||||
|
class MatrixAlreadyInitializedError : Exception()
|
|
@ -0,0 +1,3 @@
|
||||||
|
package eu.steffo.twom.matrix
|
||||||
|
|
||||||
|
class SessionAlreadyInitializedError : Exception()
|
|
@ -0,0 +1,3 @@
|
||||||
|
package eu.steffo.twom.matrix
|
||||||
|
|
||||||
|
class SessionNotInitializedError : Exception()
|
56
app/src/main/java/eu/steffo/twom/matrix/TwoMMatrix.kt
Normal file
56
app/src/main/java/eu/steffo/twom/matrix/TwoMMatrix.kt
Normal file
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<Boolean?>(null) }
|
|
||||||
var flowValid by rememberSaveable { mutableStateOf<Boolean?>(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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package eu.steffo.twom.ui.homeserver
|
||||||
|
|
||||||
|
enum class SelectHomeserverFieldState {
|
||||||
|
Empty,
|
||||||
|
Waiting,
|
||||||
|
Validating,
|
||||||
|
URLInvalid,
|
||||||
|
FlowInvalid,
|
||||||
|
Valid,
|
||||||
|
}
|
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
|
||||||
)
|
|
||||||
}
|
|
63
app/src/main/java/eu/steffo/twom/ui/login/LoginActivity.kt
Normal file
63
app/src/main/java/eu/steffo/twom/ui/login/LoginActivity.kt
Normal file
|
@ -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<Intent>
|
||||||
|
|
||||||
|
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("→")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">TwoM</string>
|
<string name="app_name">TwoM</string>
|
||||||
<string name="homeserver_placeholder">https://candy.steffo.eu</string>
|
<string name="selecthomeserver_input_placeholder">https://candy.steffo.eu</string>
|
||||||
<string name="homeserver_label">Homeserver</string>
|
<string name="selecthomeserver_input_label">Homeserver</string>
|
||||||
<string name="homeserver_supporting">The URL of the homeserver providing you with Matrix access.</string>
|
<string name="selecthomeserver_input_supporting_empty">The URL of the homeserver providing you with Matrix access.</string>
|
||||||
<string name="homeserver_error_malformedurl">The homeserver URL you provided is not a valid URL.</string>
|
<string name="selecthomeserver_input_supporting_urlinvalid">The homeserver URL you provided is not a valid URL.</string>
|
||||||
<string name="room_name_fallback_members_0">Is this even a party?</string>
|
<string name="room_name_fallback_members_0">Is this even a party?</string>
|
||||||
<string name="room_name_fallback_members_1">%1$s\'s party</string>
|
<string name="room_name_fallback_members_1">%1$s\'s party</string>
|
||||||
<string name="room_name_fallback_members_2">%1$s and %2$s\'s party</string>
|
<string name="room_name_fallback_members_2">%1$s and %2$s\'s party</string>
|
||||||
|
@ -11,10 +11,13 @@
|
||||||
<string name="room_name_fallback_members_4">%1$s, %2$s, %3$s, %4$s\'s party</string>
|
<string name="room_name_fallback_members_4">%1$s, %2$s, %3$s, %4$s\'s party</string>
|
||||||
<string name="room_name_fallback_members_more">%1$s, %2$s, %3$s and %4$d others\' party</string>
|
<string name="room_name_fallback_members_more">%1$s, %2$s, %3$s and %4$d others\' party</string>
|
||||||
<string name="room_name_fallback_invite">Party invite</string>
|
<string name="room_name_fallback_invite">Party invite</string>
|
||||||
<string name="login_button_continue_text">Continue</string>
|
<string name="selecthomeserver_complete_text">Continue</string>
|
||||||
<string name="login_welcome_text">Welcome to TwoM! To start using the app, you\'ll need to select the Matrix homeserver you want to use.</string>
|
<string name="selecthomeserver_text">Please select the homeserver you would like to log into.</string>
|
||||||
<string name="homeserver_error_notmatrix">The homeserver URL you provided does not point to a Matrix homeserver.</string>
|
<string name="selecthomeserver_input_supporting_flowinvalid">The homeserver URL you provided does not point to a Matrix homeserver.</string>
|
||||||
<string name="homeserver_trailingicon_validating_description">Checking if the URL points to a Matrix homeserver…</string>
|
<string name="selecthomeserver_input_supporting_validating">Checking if the URL points to a Matrix homeserver…</string>
|
||||||
<string name="homeserver_trailingicon_waiting_description">Waiting for you to stop writing…</string>
|
<string name="selecthomeserver_input_supporting_waiting">Waiting for you to stop writing…</string>
|
||||||
<string name="homeserver_trailingicon_waiting_done">All checks complete.</string>
|
<string name="selecthomeserver_input_supporting_valid">All checks complete!</string>
|
||||||
|
<string name="homeserver_title">Select homeserver</string>
|
||||||
|
<string name="login_title">Log into Matrix</string>
|
||||||
|
<string name="back">Go back</string>
|
||||||
</resources>
|
</resources>
|
3
app/src/main/res/values/styles.xml
Normal file
3
app/src/main/res/values/styles.xml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
</resources>
|
Loading…
Reference in a new issue