mirror of
https://github.com/Steffo99/twom.git
synced 2024-11-22 16:14:25 +00:00
Allow changes to the room configuration
This commit is contained in:
parent
fb45b3ea06
commit
395709cc28
11 changed files with 231 additions and 102 deletions
|
@ -17,32 +17,68 @@ class ConfigureRoomActivity : ComponentActivity() {
|
||||||
const val AVATAR_EXTRA = "avatar"
|
const val AVATAR_EXTRA = "avatar"
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Result(
|
data class Configuration(
|
||||||
val name: String,
|
val name: String,
|
||||||
val description: String,
|
val description: String,
|
||||||
val avatarUri: Uri?,
|
val avatarUri: Uri?,
|
||||||
)
|
) {
|
||||||
|
fun toIntent(): Intent {
|
||||||
|
val intent = Intent()
|
||||||
|
intent.putExtra(NAME_EXTRA, this.name)
|
||||||
|
intent.putExtra(DESCRIPTION_EXTRA, this.description)
|
||||||
|
if (this.avatarUri != null) {
|
||||||
|
intent.putExtra(AVATAR_EXTRA, this.avatarUri.toString())
|
||||||
|
}
|
||||||
|
return intent
|
||||||
|
}
|
||||||
|
|
||||||
class Contract : ActivityResultContract<Unit, Result?>() {
|
fun <A> toIntent(context: Context, klass: Class<A>): Intent {
|
||||||
|
val intent = Intent(context, klass)
|
||||||
|
intent.putExtra(NAME_EXTRA, this.name)
|
||||||
|
intent.putExtra(DESCRIPTION_EXTRA, this.description)
|
||||||
|
if (this.avatarUri != null) {
|
||||||
|
intent.putExtra(AVATAR_EXTRA, this.avatarUri.toString())
|
||||||
|
}
|
||||||
|
return intent
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromIntent(intent: Intent): Configuration? {
|
||||||
|
val name = intent.getStringExtra(NAME_EXTRA) ?: return null
|
||||||
|
val description = intent.getStringExtra(DESCRIPTION_EXTRA) ?: return null
|
||||||
|
val avatarString = intent.getStringExtra(AVATAR_EXTRA)
|
||||||
|
val avatarUri = if (avatarString != null) Uri.parse(avatarString) else null
|
||||||
|
|
||||||
|
return Configuration(
|
||||||
|
name = name,
|
||||||
|
description = description,
|
||||||
|
avatarUri = avatarUri,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CreateContract : ActivityResultContract<Unit, Configuration?>() {
|
||||||
override fun createIntent(context: Context, input: Unit): Intent {
|
override fun createIntent(context: Context, input: Unit): Intent {
|
||||||
return Intent(context, ConfigureRoomActivity::class.java)
|
return Intent(context, ConfigureRoomActivity::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parseResult(resultCode: Int, intent: Intent?): Result? {
|
override fun parseResult(resultCode: Int, intent: Intent?): Configuration? {
|
||||||
return when (resultCode) {
|
return when (resultCode) {
|
||||||
RESULT_OK -> {
|
RESULT_OK -> Configuration.fromIntent(intent!!)
|
||||||
intent!!
|
else -> null
|
||||||
val name = intent.getStringExtra(NAME_EXTRA)!!
|
}
|
||||||
val description = intent.getStringExtra(DESCRIPTION_EXTRA)!!
|
}
|
||||||
val avatar = intent.getStringExtra(AVATAR_EXTRA)
|
|
||||||
|
|
||||||
Result(
|
|
||||||
name = name,
|
|
||||||
description = description,
|
|
||||||
avatarUri = if (avatar != null) Uri.parse(avatar) else null,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EditContract : ActivityResultContract<Configuration, Configuration?>() {
|
||||||
|
override fun createIntent(context: Context, input: Configuration): Intent {
|
||||||
|
return input.toIntent(context, ConfigureRoomActivity::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parseResult(resultCode: Int, intent: Intent?): Configuration? {
|
||||||
|
return when (resultCode) {
|
||||||
|
RESULT_OK -> Configuration.fromIntent(intent!!)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +87,12 @@ class ConfigureRoomActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
setContent { ConfigureRoomScaffold() }
|
val configuration = Configuration.fromIntent(intent)
|
||||||
|
|
||||||
|
setContent {
|
||||||
|
ConfigureRoomScaffold(
|
||||||
|
initialConfiguration = configuration,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -100,8 +100,12 @@ class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
Log.d("Main", "Done logging out!")
|
Log.d("Main", "Done logging out!")
|
||||||
},
|
},
|
||||||
processCreate = { name, description, avatarUri ->
|
processCreate = {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
|
val name = it.name
|
||||||
|
val description = it.description
|
||||||
|
val avatarUri = it.avatarUri
|
||||||
|
|
||||||
val currentSession = session
|
val currentSession = session
|
||||||
|
|
||||||
val createRoomParams = CreateRoomParams()
|
val createRoomParams = CreateRoomParams()
|
||||||
|
|
|
@ -4,32 +4,29 @@ import android.graphics.Bitmap
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.PickVisualMediaRequest
|
import androidx.activity.result.PickVisualMediaRequest
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import eu.steffo.twom.utils.BitmapUtilities
|
import eu.steffo.twom.utils.BitmapUtilities
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
@Preview(widthDp = 40, heightDp = 40)
|
@Preview(widthDp = 40, heightDp = 40)
|
||||||
fun AvatarPicker(
|
fun AvatarPicker(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
fallbackText: String = "?",
|
fallbackText: String = "?",
|
||||||
onPick: (bitmap: Bitmap) -> Unit = {},
|
value: Bitmap? = null,
|
||||||
|
onPick: (bitmap: Bitmap?) -> Unit = {},
|
||||||
alpha: Float = 1.0f,
|
alpha: Float = 1.0f,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val resolver = context.contentResolver
|
val resolver = context.contentResolver
|
||||||
|
|
||||||
var selection by remember { mutableStateOf<Bitmap?>(null) }
|
|
||||||
|
|
||||||
val launcher =
|
val launcher =
|
||||||
rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) ImageSelect@{
|
rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) ImageSelect@{
|
||||||
it ?: return@ImageSelect
|
it ?: return@ImageSelect
|
||||||
|
@ -39,18 +36,18 @@ fun AvatarPicker(
|
||||||
|
|
||||||
val correctedBitmap = BitmapUtilities.squareAndOrient(rawBitmap, orientation)
|
val correctedBitmap = BitmapUtilities.squareAndOrient(rawBitmap, orientation)
|
||||||
|
|
||||||
selection = correctedBitmap
|
|
||||||
onPick(correctedBitmap)
|
onPick(correctedBitmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.clickable {
|
.combinedClickable(
|
||||||
launcher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
|
onClick = { launcher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) },
|
||||||
}
|
onLongClick = { onPick(null) },
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
AvatarImage(
|
AvatarImage(
|
||||||
bitmap = selection?.asImageBitmap(),
|
bitmap = value?.asImageBitmap(),
|
||||||
fallbackText = fallbackText,
|
fallbackText = fallbackText,
|
||||||
alpha = alpha,
|
alpha = alpha,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package eu.steffo.twom.composables.configureroom
|
package eu.steffo.twom.composables.configureroom
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
@ -14,16 +17,19 @@ import androidx.compose.material3.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import eu.steffo.twom.R
|
import eu.steffo.twom.R
|
||||||
|
import eu.steffo.twom.activities.ConfigureRoomActivity
|
||||||
import eu.steffo.twom.composables.avatar.AvatarPicker
|
import eu.steffo.twom.composables.avatar.AvatarPicker
|
||||||
import eu.steffo.twom.composables.theme.basePadding
|
import eu.steffo.twom.composables.theme.basePadding
|
||||||
import eu.steffo.twom.utils.BitmapUtilities
|
import eu.steffo.twom.utils.BitmapUtilities
|
||||||
|
@ -32,11 +38,16 @@ import eu.steffo.twom.utils.BitmapUtilities
|
||||||
@Preview(showBackground = true)
|
@Preview(showBackground = true)
|
||||||
fun ConfigureRoomForm(
|
fun ConfigureRoomForm(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onSubmit: (name: String, description: String, avatarUri: String?) -> Unit = { _, _, _ -> },
|
initialConfiguration: ConfigureRoomActivity.Configuration? = null,
|
||||||
|
onSubmit: (ConfigureRoomActivity.Configuration) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
var name by rememberSaveable { mutableStateOf("") }
|
var name by rememberSaveable { mutableStateOf(initialConfiguration?.name ?: "") }
|
||||||
var description by rememberSaveable { mutableStateOf("") }
|
var description by rememberSaveable { mutableStateOf(initialConfiguration?.description ?: "") }
|
||||||
var avatarUri by rememberSaveable { mutableStateOf<Uri?>(null) }
|
// TODO: How to load the original avatar from the URL?
|
||||||
|
var avatarBitmap by remember { mutableStateOf<Bitmap?>(null) }
|
||||||
|
|
||||||
|
val context = LocalContext.current
|
||||||
|
val activity = context as Activity
|
||||||
|
|
||||||
Column(modifier) {
|
Column(modifier) {
|
||||||
Row(Modifier.basePadding()) {
|
Row(Modifier.basePadding()) {
|
||||||
|
@ -48,10 +59,8 @@ fun ConfigureRoomForm(
|
||||||
.semantics {
|
.semantics {
|
||||||
this.contentDescription = avatarContentDescription
|
this.contentDescription = avatarContentDescription
|
||||||
},
|
},
|
||||||
onPick = {
|
value = avatarBitmap,
|
||||||
val cache = BitmapUtilities.bitmapToCache("createAvatar", it)
|
onPick = { avatarBitmap = it },
|
||||||
avatarUri = Uri.fromFile(cache)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
TextField(
|
TextField(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -85,7 +94,19 @@ fun ConfigureRoomForm(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
onClick = {
|
onClick = {
|
||||||
onSubmit(name, description, avatarUri.toString())
|
val result = ConfigureRoomActivity.Configuration(
|
||||||
|
name = name,
|
||||||
|
description = description,
|
||||||
|
avatarUri = if (avatarBitmap != null) {
|
||||||
|
Uri.fromFile(
|
||||||
|
BitmapUtilities.bitmapToCache("createAvatar", avatarBitmap!!)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
},
|
||||||
|
)
|
||||||
|
activity.setResult(ComponentActivity.RESULT_OK, result.toIntent())
|
||||||
|
activity.finish()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.create_complete_text))
|
Text(stringResource(R.string.create_complete_text))
|
||||||
|
|
|
@ -1,46 +1,29 @@
|
||||||
package eu.steffo.twom.composables.configureroom
|
package eu.steffo.twom.composables.configureroom
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import eu.steffo.twom.activities.ConfigureRoomActivity
|
import eu.steffo.twom.activities.ConfigureRoomActivity
|
||||||
import eu.steffo.twom.composables.theme.TwoMTheme
|
import eu.steffo.twom.composables.theme.TwoMTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Preview
|
@Preview
|
||||||
fun ConfigureRoomScaffold() {
|
fun ConfigureRoomScaffold(
|
||||||
val context = LocalContext.current
|
initialConfiguration: ConfigureRoomActivity.Configuration? = null,
|
||||||
val activity = context as Activity
|
) {
|
||||||
|
|
||||||
fun submitActivity(name: String, description: String, avatarUri: String?) {
|
|
||||||
val resultIntent = Intent()
|
|
||||||
resultIntent.putExtra(ConfigureRoomActivity.NAME_EXTRA, name)
|
|
||||||
resultIntent.putExtra(ConfigureRoomActivity.DESCRIPTION_EXTRA, description)
|
|
||||||
// Kotlin cannot use nullable types in Java interop generics
|
|
||||||
if (avatarUri != null) {
|
|
||||||
resultIntent.putExtra(ConfigureRoomActivity.AVATAR_EXTRA, avatarUri)
|
|
||||||
}
|
|
||||||
activity.setResult(ComponentActivity.RESULT_OK, resultIntent)
|
|
||||||
activity.finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
TwoMTheme {
|
TwoMTheme {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
ConfigureActivityTopBar()
|
ConfigureActivityTopBar(
|
||||||
|
initialName = initialConfiguration?.name,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
content = {
|
content = {
|
||||||
ConfigureRoomForm(
|
ConfigureRoomForm(
|
||||||
modifier = Modifier.padding(it),
|
modifier = Modifier.padding(it),
|
||||||
onSubmit = { name: String, description: String, avatarUri: String? ->
|
initialConfiguration = initialConfiguration,
|
||||||
submitActivity(name, description, avatarUri)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import eu.steffo.twom.R
|
import eu.steffo.twom.R
|
||||||
import eu.steffo.twom.composables.navigation.BackIconButton
|
import eu.steffo.twom.composables.navigation.BackIconButton
|
||||||
|
@ -15,10 +15,19 @@ import eu.steffo.twom.composables.navigation.BackIconButton
|
||||||
@Preview
|
@Preview
|
||||||
fun ConfigureActivityTopBar(
|
fun ConfigureActivityTopBar(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
initialName: String? = null,
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
navigationIcon = { BackIconButton() },
|
navigationIcon = { BackIconButton() },
|
||||||
title = { Text(LocalContext.current.getString(R.string.create_title)) }
|
title = {
|
||||||
|
Text(
|
||||||
|
text = if (initialName == null) {
|
||||||
|
stringResource(R.string.create_title)
|
||||||
|
} else {
|
||||||
|
stringResource(R.string.edit_title, initialName)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package eu.steffo.twom.composables.main
|
package eu.steffo.twom.composables.main
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.launch
|
import androidx.activity.result.launch
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
@ -19,12 +18,12 @@ import eu.steffo.twom.activities.ConfigureRoomActivity
|
||||||
@Preview
|
@Preview
|
||||||
fun CreateRoomFAB(
|
fun CreateRoomFAB(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onCreateParamsSelected: (name: String, description: String, avatarUri: Uri?) -> Unit = { _, _, _ -> },
|
onCreateConfigured: (configuration: ConfigureRoomActivity.Configuration) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val launcher =
|
val launcher =
|
||||||
rememberLauncherForActivityResult(ConfigureRoomActivity.Contract()) {
|
rememberLauncherForActivityResult(ConfigureRoomActivity.CreateContract()) {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
onCreateParamsSelected(it.name, it.description, it.avatarUri)
|
onCreateConfigured(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package eu.steffo.twom.composables.main
|
package eu.steffo.twom.composables.main
|
||||||
|
|
||||||
import android.net.Uri
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import eu.steffo.twom.activities.ConfigureRoomActivity
|
||||||
import eu.steffo.twom.composables.matrix.LocalSession
|
import eu.steffo.twom.composables.matrix.LocalSession
|
||||||
import eu.steffo.twom.composables.theme.TwoMTheme
|
import eu.steffo.twom.composables.theme.TwoMTheme
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
@ -16,7 +16,7 @@ import org.matrix.android.sdk.api.session.Session
|
||||||
fun MainScaffold(
|
fun MainScaffold(
|
||||||
processLogin: () -> Unit = {},
|
processLogin: () -> Unit = {},
|
||||||
processLogout: () -> Unit = {},
|
processLogout: () -> Unit = {},
|
||||||
processCreate: (name: String, description: String, avatarUri: Uri?) -> Unit = { _, _, _ -> },
|
processCreate: (it: ConfigureRoomActivity.Configuration) -> Unit = {},
|
||||||
session: Session? = null,
|
session: Session? = null,
|
||||||
) {
|
) {
|
||||||
TwoMTheme {
|
TwoMTheme {
|
||||||
|
@ -31,7 +31,7 @@ fun MainScaffold(
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
CreateRoomFAB(
|
CreateRoomFAB(
|
||||||
onCreateParamsSelected = processCreate,
|
onCreateConfigured = processCreate,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package eu.steffo.twom.composables.viewroom
|
package eu.steffo.twom.composables.viewroom
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
@ -9,27 +13,115 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.core.net.toFile
|
||||||
import eu.steffo.twom.R
|
import eu.steffo.twom.R
|
||||||
|
import eu.steffo.twom.activities.ConfigureRoomActivity
|
||||||
import eu.steffo.twom.composables.avatar.AvatarURL
|
import eu.steffo.twom.composables.avatar.AvatarURL
|
||||||
|
import eu.steffo.twom.composables.errorhandling.ErrorIconButton
|
||||||
|
import eu.steffo.twom.composables.matrix.LocalSession
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RoomIconButton(
|
fun RoomIconButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
avatarUrl: String? = null,
|
|
||||||
canEdit: Boolean = true,
|
canEdit: Boolean = true,
|
||||||
) {
|
) {
|
||||||
var expanded by remember { mutableStateOf(false) }
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val session = LocalSession.current
|
||||||
|
if (session == null) {
|
||||||
|
ErrorIconButton(
|
||||||
|
message = stringResource(R.string.error_session_missing)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val roomSummaryRequest = LocalRoomSummary.current
|
||||||
|
if (roomSummaryRequest == null) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val roomSummary = roomSummaryRequest.getOrNull()
|
||||||
|
if (roomSummary == null) {
|
||||||
|
ErrorIconButton(
|
||||||
|
message = stringResource(R.string.room_error_roomsummary_notfound)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val roomRequest = LocalRoom.current
|
||||||
|
if (roomRequest == null) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val room = roomRequest.getOrNull()
|
||||||
|
if (room == null) {
|
||||||
|
ErrorIconButton(
|
||||||
|
message = stringResource(R.string.room_error_room_notfound)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
val launcher =
|
||||||
|
rememberLauncherForActivityResult(
|
||||||
|
ConfigureRoomActivity.EditContract()
|
||||||
|
) {
|
||||||
|
if (it != null) {
|
||||||
|
scope.launch {
|
||||||
|
|
||||||
|
val name = it.name
|
||||||
|
Log.d("RoomIconButton", "Updating room name to `$name`")
|
||||||
|
room.stateService().updateName(it.name)
|
||||||
|
|
||||||
|
val description = it.description
|
||||||
|
Log.d("RoomIconButton", "Updating room description to `$description`")
|
||||||
|
room.stateService().updateTopic(it.description)
|
||||||
|
|
||||||
|
val avatarUri = it.avatarUri
|
||||||
|
val avatarFile = avatarUri?.toFile()
|
||||||
|
when (avatarFile?.isFile) {
|
||||||
|
false -> {
|
||||||
|
Log.e(
|
||||||
|
"RoomIconButton",
|
||||||
|
"Avatar has been deleted from cache before room could possibly be updated, ignoring..."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
true -> {
|
||||||
|
Log.d(
|
||||||
|
"RoomIconButton",
|
||||||
|
"Avatar seems to exist at: $avatarUri"
|
||||||
|
)
|
||||||
|
room.stateService().updateAvatar(avatarUri, avatarFile.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
null -> {
|
||||||
|
Log.d(
|
||||||
|
"RoomIconButton",
|
||||||
|
"Avatar was not set, ignoring..."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Box(modifier) {
|
Box(modifier) {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { expanded = true },
|
onClick = { expanded = true },
|
||||||
) {
|
) {
|
||||||
AvatarURL(
|
AvatarURL(
|
||||||
url = avatarUrl,
|
url = roomSummary.avatarUrl,
|
||||||
contentDescription = LocalContext.current.getString(R.string.room_options_label),
|
contentDescription = LocalContext.current.getString(R.string.room_options_label),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -37,28 +129,23 @@ fun RoomIconButton(
|
||||||
expanded = expanded,
|
expanded = expanded,
|
||||||
onDismissRequest = { expanded = false },
|
onDismissRequest = { expanded = false },
|
||||||
) {
|
) {
|
||||||
DropdownMenuItem(
|
|
||||||
text = {
|
|
||||||
Text(stringResource(R.string.room_options_zoom_text))
|
|
||||||
},
|
|
||||||
onClick = {
|
|
||||||
// TODO
|
|
||||||
expanded = false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (canEdit) {
|
if (canEdit) {
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = {
|
text = {
|
||||||
Text(stringResource(R.string.room_options_edit_text))
|
Text(stringResource(R.string.room_options_edit_text))
|
||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
// TODO
|
|
||||||
expanded = false
|
expanded = false
|
||||||
|
launcher.launch(
|
||||||
|
ConfigureRoomActivity.Configuration(
|
||||||
|
name = roomSummary.name,
|
||||||
|
description = roomSummary.topic,
|
||||||
|
avatarUri = Uri.parse(roomSummary.avatarUrl),
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,16 +1,12 @@
|
||||||
package eu.steffo.twom.composables.viewroom
|
package eu.steffo.twom.composables.viewroom
|
||||||
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import eu.steffo.twom.R
|
|
||||||
import eu.steffo.twom.composables.errorhandling.ErrorIconButton
|
|
||||||
import eu.steffo.twom.composables.errorhandling.ErrorText
|
import eu.steffo.twom.composables.errorhandling.ErrorText
|
||||||
import eu.steffo.twom.composables.errorhandling.LoadingText
|
import eu.steffo.twom.composables.errorhandling.LoadingText
|
||||||
import eu.steffo.twom.composables.navigation.BackIconButton
|
import eu.steffo.twom.composables.navigation.BackIconButton
|
||||||
|
@ -47,17 +43,7 @@ fun ViewRoomTopBar(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (roomSummaryRequest == null) {
|
RoomIconButton()
|
||||||
CircularProgressIndicator()
|
|
||||||
} else if (roomSummary == null) {
|
|
||||||
ErrorIconButton(
|
|
||||||
message = stringResource(R.string.room_error_roomsummary_notfound)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
RoomIconButton(
|
|
||||||
avatarUrl = roomSummary.avatarUrl,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,4 +84,5 @@
|
||||||
<string name="room_error_redact_generic">Your response has been updated, but something went wrong while attempting to remove your previous one: %1$s</string>
|
<string name="room_error_redact_generic">Your response has been updated, but something went wrong while attempting to remove your previous one: %1$s</string>
|
||||||
<string name="room_error_self_notfound">You have been removed from the room.</string>
|
<string name="room_error_self_notfound">You have been removed from the room.</string>
|
||||||
<string name="room_error_invite_generic">Something went wrong while sending the invite: %1$s</string>
|
<string name="room_error_invite_generic">Something went wrong while sending the invite: %1$s</string>
|
||||||
|
<string name="edit_title">Editing %1$s</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in a new issue