1
Fork 0
mirror of https://github.com/Steffo99/twom.git synced 2024-11-25 01:24:24 +00:00

Start work on the happening creation activity

This commit is contained in:
Steffo 2023-12-01 05:40:43 +01:00
parent bc41e909c7
commit 19d01e2c40
Signed by: steffo
GPG key ID: 2A24051445686895
10 changed files with 222 additions and 3 deletions

View file

@ -64,7 +64,7 @@ dependencies {
implementation("org.matrix.android:matrix-android-sdk2:1.5.30") implementation("org.matrix.android:matrix-android-sdk2:1.5.30")
implementation("com.squareup.okhttp3:okhttp:4.12.0") implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.8.0") implementation("androidx.activity:activity-compose:1.8.1")
implementation(platform("androidx.compose:compose-bom:2023.03.00")) implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-graphics")

View file

@ -1,5 +1,25 @@
package eu.steffo.twom.create package eu.steffo.twom.create
import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
class CreateActivity : ComponentActivity() class CreateActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CreateActivityScaffold(
onClickBack = {
setResult(RESULT_CANCELED)
finish()
},
onClickCreate = {
setResult(RESULT_OK)
finish()
},
)
}
}
}

View file

@ -0,0 +1,97 @@
package eu.steffo.twom.create
import android.graphics.BitmapFactory
import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import eu.steffo.twom.R
import eu.steffo.twom.matrix.avatar.AvatarFromBitmap
import eu.steffo.twom.theme.TwoMPadding
@Composable
@Preview
fun CreateActivityContent(
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
var name by rememberSaveable { mutableStateOf("") }
var avatarUri by rememberSaveable { mutableStateOf<Uri?>(null) }
var avatarBitmap by remember { mutableStateOf<ImageBitmap?>(null) }
// val avatarBitmap = if(avatarUri != null) BitmapFactory.decodeFile(avatarUri.toString()).asImageBitmap() else null
val avatarSelectLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.PickVisualMedia()) {
avatarUri = it
if (it == null) {
avatarBitmap = null
} else {
val stream = context.contentResolver.openInputStream(it)
if (stream != null) {
avatarBitmap = BitmapFactory.decodeStream(stream).asImageBitmap()
stream.close()
}
}
}
Column(modifier) {
Row(TwoMPadding.base) {
val avatarContentDescription = stringResource(R.string.create_avatar_label)
Box(
modifier = Modifier
.size(60.dp)
.clip(MaterialTheme.shapes.medium)
.clickable {
avatarSelectLauncher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
.semantics {
this.contentDescription = avatarContentDescription
}
) {
AvatarFromBitmap(
bitmap = avatarBitmap,
)
}
TextField(
modifier = Modifier
.height(60.dp)
.padding(start = 10.dp)
.fillMaxWidth(),
label = {
Text(stringResource(R.string.create_name_label))
},
value = name,
onValueChange = { name = it }
)
}
}
}

View file

@ -0,0 +1,28 @@
package eu.steffo.twom.create
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.theme.TwoMTheme
@Composable
@Preview
fun CreateActivityScaffold(
onClickBack: () -> Unit = {},
onClickCreate: () -> Unit = {},
) {
TwoMTheme {
Scaffold(
topBar = {
CreateActivityTopBar()
},
content = {
CreateActivityContent(
modifier = Modifier.padding(it),
)
}
)
}
}

View file

@ -0,0 +1,35 @@
package eu.steffo.twom.create
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.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
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Preview
fun CreateActivityTopBar(
modifier: Modifier = Modifier,
onBack: () -> Unit = {},
) {
TopAppBar(
modifier = modifier,
navigationIcon = {
IconButton(onClick = onBack) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = LocalContext.current.getString(R.string.back)
)
}
},
title = { Text(LocalContext.current.getString(R.string.create_title)) }
)
}

View file

@ -0,0 +1,30 @@
package eu.steffo.twom.matrix.avatar
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.tooling.preview.Preview
@Composable
@Preview(widthDp = 40, heightDp = 40)
fun AvatarFromBitmap(
modifier: Modifier = Modifier,
bitmap: ImageBitmap? = null,
fallbackText: String = "?",
contentDescription: String = "",
) {
if (bitmap == null) {
AvatarFromDefault(
modifier = modifier,
fallbackText = fallbackText,
contentDescription = contentDescription,
)
} else {
Image(
modifier = modifier,
bitmap = bitmap,
contentDescription = contentDescription,
)
}
}

View file

@ -16,6 +16,7 @@ import androidx.compose.ui.tooling.preview.Preview
@Preview(widthDp = 40, heightDp = 40) @Preview(widthDp = 40, heightDp = 40)
fun AvatarFromDefault( fun AvatarFromDefault(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
fallbackText: String = "?",
contentDescription: String = "", contentDescription: String = "",
) { ) {
Box( Box(
@ -30,7 +31,7 @@ fun AvatarFromDefault(
this.contentDescription = "" this.contentDescription = ""
}, },
color = MaterialTheme.colorScheme.onTertiary, color = MaterialTheme.colorScheme.onTertiary,
text = "?", text = fallbackText,
) )
} }
} }

View file

@ -20,6 +20,7 @@ import eu.steffo.twom.matrix.LocalSession
fun AvatarFromURL( fun AvatarFromURL(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
url: String? = "", url: String? = "",
fallbackText: String = "?",
contentDescription: String = "", contentDescription: String = "",
) { ) {
val session = LocalSession.current val session = LocalSession.current
@ -55,6 +56,7 @@ fun AvatarFromURL(
if (session == null || url == null || avatar == null) { if (session == null || url == null || avatar == null) {
AvatarFromDefault( AvatarFromDefault(
modifier = modifier, modifier = modifier,
fallbackText = fallbackText,
contentDescription = contentDescription contentDescription = contentDescription
) )
} else { } else {

View file

@ -16,6 +16,7 @@ import eu.steffo.twom.matrix.LocalSession
fun AvatarFromUserId( fun AvatarFromUserId(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
userId: String = "", userId: String = "",
fallbackText: String = "?",
contentDescription: String = "", contentDescription: String = "",
) { ) {
val session = LocalSession.current val session = LocalSession.current
@ -38,12 +39,14 @@ fun AvatarFromUserId(
if (avatarUrl == null) { if (avatarUrl == null) {
AvatarFromDefault( AvatarFromDefault(
modifier = modifier, modifier = modifier,
fallbackText = fallbackText,
contentDescription = contentDescription, contentDescription = contentDescription,
) )
} else { } else {
AvatarFromURL( AvatarFromURL(
modifier = modifier, modifier = modifier,
url = avatarUrl!!, url = avatarUrl!!,
fallbackText = fallbackText,
contentDescription = contentDescription, contentDescription = contentDescription,
) )
} }

View file

@ -27,4 +27,7 @@
<string name="main_efab_create_text">New</string> <string name="main_efab_create_text">New</string>
<string name="main_notloggedin_text_2">Log into your Matrix account by clicking the icon on the top right of the screen.</string> <string name="main_notloggedin_text_2">Log into your Matrix account by clicking the icon on the top right of the screen.</string>
<string name="main_account_login_text">Login</string> <string name="main_account_login_text">Login</string>
<string name="create_title">Create a new happening</string>
<string name="create_name_label">Name</string>
<string name="create_avatar_label">Select happening avatar</string>
</resources> </resources>