1
Fork 0
mirror of https://github.com/Steffo99/twom.git synced 2024-11-21 23:54:26 +00:00

Refactor and cleanup things

This commit is contained in:
Steffo 2023-12-01 02:56:07 +01:00
parent d66bbeb277
commit 645e3768ce
Signed by: steffo
GPG key ID: 2A24051445686895
23 changed files with 281 additions and 151 deletions

View file

@ -49,6 +49,10 @@
android:name=".room.RoomActivity"
android:theme="@style/Theme.TwoM" />
<activity
android:name=".create.CreateActivity"
android:theme="@style/Theme.TwoM" />
</application>
</manifest>

View file

@ -0,0 +1,5 @@
package eu.steffo.twom.create
import androidx.activity.ComponentActivity
class CreateActivity : ComponentActivity()

View file

@ -1,24 +1,14 @@
package eu.steffo.twom.login
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.theme.TwoMTheme
import org.matrix.android.sdk.api.session.Session
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Preview
fun LoginActivityScaffold(
@ -28,23 +18,16 @@ fun LoginActivityScaffold(
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.login_title)) }
LoginActivityTopBar(
onBack = onBack,
)
}
) {
LoginActivityControl(
modifier = Modifier.padding(it),
onLogin = onLogin
)
}
},
content = {
LoginActivityControl(
modifier = Modifier.padding(it),
onLogin = onLogin
)
},
)
}
}

View file

@ -0,0 +1,32 @@
package eu.steffo.twom.login
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.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Preview
fun LoginActivityTopBar(
onBack: () -> Unit = {},
) {
TopAppBar(
navigationIcon = {
IconButton(onClick = onBack) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = LocalContext.current.getString(R.string.back)
)
}
},
title = { Text(LocalContext.current.getString(R.string.login_title)) }
)
}

View file

@ -9,6 +9,7 @@ import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.lifecycleScope
import eu.steffo.twom.create.CreateActivity
import eu.steffo.twom.login.LoginActivity
import eu.steffo.twom.matrix.TwoMMatrix
import eu.steffo.twom.room.RoomActivity
@ -19,6 +20,7 @@ import org.matrix.android.sdk.api.session.Session
class MainActivity : ComponentActivity() {
private lateinit var loginLauncher: ActivityResultLauncher<Intent>
private lateinit var roomLauncher: ActivityResultLauncher<Intent>
private lateinit var createLauncher: ActivityResultLauncher<Intent>
private var session: Session? = null
@ -26,7 +28,6 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
TwoMMatrix.ensureMatrix(applicationContext)
TwoMMatrix.ensureDefaultAvatar(applicationContext)
fetchLastSession()
openSession()
@ -43,6 +44,12 @@ class MainActivity : ComponentActivity() {
this::onRoom
)
createLauncher =
registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
this::onCreate
)
resetContent()
}
@ -115,13 +122,23 @@ class MainActivity : ComponentActivity() {
Log.d("Main", "Clicked a room, launching room activity...")
val intent = Intent(applicationContext, RoomActivity::class.java)
intent.putExtra(RoomActivity.ROOM_ID_EXTRA, roomId)
loginLauncher.launch(intent)
roomLauncher.launch(intent)
}
private fun onRoom(result: ActivityResult) {
Log.d("Main", "Received result from room activity: $result")
}
private fun onClickCreate() {
Log.d("Main", "Clicked the New button, launching create activity...")
val intent = Intent(applicationContext, CreateActivity::class.java)
loginLauncher.launch(intent)
}
private fun onCreate(result: ActivityResult) {
Log.d("Main", "Received result from create activity: $result")
}
private fun resetContent() {
Log.d("Main", "Recomposing...")
setContent {
@ -129,6 +146,7 @@ class MainActivity : ComponentActivity() {
onClickLogin = this::onClickLogin,
onClickLogout = this::onClickLogout,
onClickRoom = this::onClickRoom,
onClickCreate = this::onClickCreate,
session = session,
)
}

View file

@ -19,31 +19,31 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.R
import eu.steffo.twom.matrix.LocalSession
import eu.steffo.twom.matrix.UserAvatar
import eu.steffo.twom.matrix.avatar.AvatarFromUserId
@Composable
@Preview(showBackground = true)
fun ProfileIconButton(
fun MainActivityAccountIconButton(
modifier: Modifier = Modifier,
onClickLogin: () -> Unit = {},
onClickLogout: () -> Unit = {},
) {
val session = LocalSession.current
var expanded by remember { mutableStateOf(false) }
Box {
Box(modifier) {
IconButton(
enabled = (session != null),
onClick = { expanded = true },
) {
if (session == null) {
Icon(
imageVector = Icons.Filled.AccountCircle,
contentDescription = LocalContext.current.getString(R.string.account_label),
contentDescription = LocalContext.current.getString(R.string.main_account_label),
)
} else {
UserAvatar(
AvatarFromUserId(
userId = session.myUserId,
contentDescription = LocalContext.current.getString(R.string.account_label),
contentDescription = LocalContext.current.getString(R.string.main_account_label),
)
}
}
@ -51,12 +51,25 @@ fun ProfileIconButton(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
if (session != null) {
if (session == null) {
DropdownMenuItem(
text = {
Text(stringResource(id = R.string.profile_logout_text))
Text(stringResource(id = R.string.main_account_login_text))
},
onClick = onClickLogout
onClick = {
expanded = false
onClickLogin()
}
)
} else {
DropdownMenuItem(
text = {
Text(stringResource(id = R.string.main_account_logout_text))
},
onClick = {
expanded = false
onClickLogout()
}
)
}
}

View file

@ -0,0 +1,24 @@
package eu.steffo.twom.main
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import eu.steffo.twom.matrix.LocalSession
@Composable
fun MainActivityContent(
modifier: Modifier = Modifier,
onClickRoom: (roomId: String) -> Unit = {},
) {
val session = LocalSession.current
if (session == null) {
MainActivityNotLoggedIn(
modifier = modifier,
)
} else {
MainActivityRoomList(
modifier = modifier,
onClickRoom = onClickRoom,
)
}
}

View file

@ -0,0 +1,41 @@
package eu.steffo.twom.main
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.R
import eu.steffo.twom.matrix.LocalSession
@Composable
@Preview
fun MainActivityCreateFAB(
modifier: Modifier = Modifier,
onClickCreate: () -> Unit = {},
) {
val session = LocalSession.current
val shouldDisplay = (session != null || LocalView.current.isInEditMode)
if (shouldDisplay) {
ExtendedFloatingActionButton(
modifier = modifier,
onClick = onClickCreate,
icon = {
Icon(
Icons.Filled.Add,
contentDescription = null
)
},
text = {
Text(stringResource(R.string.main_efab_create_text))
}
)
}
}

View file

@ -2,8 +2,6 @@ package eu.steffo.twom.main
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@ -14,21 +12,16 @@ import eu.steffo.twom.theme.TwoMPadding
@Composable
@Preview(showBackground = true)
fun MatrixActivityNotLoggedInControl(
fun MainActivityNotLoggedIn(
modifier: Modifier = Modifier,
onClickLogin: () -> Unit = {},
) {
Column(modifier) {
Row(TwoMPadding.base) {
Text(LocalContext.current.getString(R.string.notloggedin_text))
Text(LocalContext.current.getString(R.string.main_notloggedin_text_1))
}
Row(TwoMPadding.base) {
Button(
modifier = Modifier.fillMaxWidth(),
onClick = onClickLogin,
) {
Text(LocalContext.current.getString(R.string.notloggedin_login_text))
}
Text(LocalContext.current.getString(R.string.main_notloggedin_text_2))
}
}
}

View file

@ -11,7 +11,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.R
import eu.steffo.twom.matrix.LocalSession
import eu.steffo.twom.theme.TwoMPadding
@ -19,8 +18,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
@Composable
@Preview
fun MainActivityRoomListControl(
fun MainActivityRoomList(
modifier: Modifier = Modifier,
onClickRoom: (roomId: String) -> Unit = {},
) {
@ -47,7 +45,7 @@ fun MainActivityRoomListControl(
} else if (roomSummaries!!.isEmpty()) {
Text(
modifier = TwoMPadding.base,
text = stringResource(R.string.room_list_empty_text)
text = stringResource(R.string.main_roomlist_empty_text)
)
} else {
roomSummaries!!.forEach {

View file

@ -1,57 +1,45 @@
package eu.steffo.twom.main
import androidx.compose.foundation.layout.padding
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.runtime.CompositionLocalProvider
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.matrix.LocalSession
import eu.steffo.twom.theme.TwoMTheme
import org.matrix.android.sdk.api.session.Session
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Preview
fun MatrixActivityScaffold(
onClickLogin: () -> Unit = {},
onClickLogout: () -> Unit = {},
onClickRoom: (roomId: String) -> Unit = {},
onClickCreate: () -> Unit = {},
session: Session? = null,
) {
TwoMTheme {
CompositionLocalProvider(LocalSession provides session) {
Scaffold(
topBar = {
CenterAlignedTopAppBar(
title = {
Text(LocalContext.current.getString(R.string.app_name))
},
actions = {
ProfileIconButton(
onClickLogout = onClickLogout
)
},
)
}
) {
if (session == null) {
MatrixActivityNotLoggedInControl(
modifier = Modifier.padding(it),
MainActivityTopBar(
onClickLogin = onClickLogin,
onClickLogout = onClickLogout,
)
} else {
MainActivityRoomListControl(
},
floatingActionButton = {
MainActivityCreateFAB(
onClickCreate = onClickCreate,
)
},
content = {
MainActivityContent(
modifier = Modifier.padding(it),
onClickRoom = onClickRoom,
)
}
}
)
}
}
}

View file

@ -0,0 +1,33 @@
package eu.steffo.twom.main
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
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 MainActivityTopBar(
modifier: Modifier = Modifier,
onClickLogin: () -> Unit = {},
onClickLogout: () -> Unit = {},
) {
CenterAlignedTopAppBar(
modifier = modifier,
title = {
Text(LocalContext.current.getString(R.string.app_name))
},
actions = {
MainActivityAccountIconButton(
onClickLogin = onClickLogin,
onClickLogout = onClickLogout,
)
},
)
}

View file

@ -10,7 +10,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import eu.steffo.twom.matrix.Avatar
import eu.steffo.twom.matrix.avatar.AvatarFromURL
import org.matrix.android.sdk.api.session.room.model.RoomSummary
@ -32,7 +32,7 @@ fun RoomListItem(
.size(40.dp)
.clip(MaterialTheme.shapes.medium)
) {
Avatar(
AvatarFromURL(
url = roomSummary.avatarUrl,
)
}

View file

@ -1,17 +0,0 @@
package eu.steffo.twom.matrix
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
fun DefaultAvatar(
modifier: Modifier = Modifier,
contentDescription: String = "",
) {
Image(
modifier = Modifier,
bitmap = TwoMMatrix.defaultAvatar,
contentDescription = contentDescription,
)
}

View file

@ -1,11 +1,7 @@
package eu.steffo.twom.matrix
import android.content.Context
import android.graphics.BitmapFactory
import android.util.Log
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import eu.steffo.twom.R
import org.matrix.android.sdk.api.Matrix
import org.matrix.android.sdk.api.MatrixConfiguration
@ -40,27 +36,4 @@ object TwoMMatrix {
}
return null
}
/**
* The avatar to default to when another one is not available.
*
* [Avatar] will expect this to be available.
*/
lateinit var defaultAvatar: ImageBitmap
/**
* Make sure the [matrix] object is available, decoding it if it isn't initialized.
*
* Uses the passed [Context] to access the application resources.
*/
fun ensureDefaultAvatar(context: Context): ImageBitmap? {
if (!this::defaultAvatar.isInitialized) {
Log.d("Matrix", "Initializing default avatar...")
defaultAvatar =
BitmapFactory.decodeResource(context.resources, R.drawable.avatar_default)
.asImageBitmap()
return defaultAvatar
}
return null
}
}

View file

@ -0,0 +1,36 @@
package eu.steffo.twom.matrix.avatar
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
@Composable
@Preview(widthDp = 40, heightDp = 40)
fun AvatarFromDefault(
modifier: Modifier = Modifier,
contentDescription: String = "",
) {
Box(
modifier = modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.tertiary),
) {
Text(
modifier = Modifier
.align(Alignment.Center)
.semantics {
this.contentDescription = ""
},
color = MaterialTheme.colorScheme.onTertiary,
text = "?",
)
}
}

View file

@ -1,4 +1,4 @@
package eu.steffo.twom.matrix
package eu.steffo.twom.matrix.avatar
import android.graphics.BitmapFactory
import android.util.Log
@ -13,10 +13,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.matrix.LocalSession
@Composable
@Preview
fun Avatar(
@Preview(widthDp = 40, heightDp = 40)
fun AvatarFromURL(
modifier: Modifier = Modifier,
url: String? = "",
contentDescription: String = "",
@ -52,7 +53,7 @@ fun Avatar(
}
if (session == null || url == null || avatar == null) {
DefaultAvatar(
AvatarFromDefault(
modifier = modifier,
contentDescription = contentDescription
)

View file

@ -1,4 +1,4 @@
package eu.steffo.twom.matrix
package eu.steffo.twom.matrix.avatar
import android.util.Log
import androidx.compose.runtime.Composable
@ -8,9 +8,12 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.matrix.LocalSession
@Composable
fun UserAvatar(
@Preview(widthDp = 40, heightDp = 40)
fun AvatarFromUserId(
modifier: Modifier = Modifier,
userId: String = "",
contentDescription: String = "",
@ -33,12 +36,12 @@ fun UserAvatar(
}
if (avatarUrl == null) {
DefaultAvatar(
AvatarFromDefault(
modifier = modifier,
contentDescription = contentDescription,
)
} else {
Avatar(
AvatarFromURL(
modifier = modifier,
url = avatarUrl!!,
contentDescription = contentDescription,

View file

@ -6,5 +6,4 @@ class RoomActivity : ComponentActivity() {
companion object {
const val ROOM_ID_EXTRA = "roomId"
}
}

View file

@ -19,12 +19,19 @@ fun TwoMTheme(
content: @Composable () -> Unit
) {
val context = LocalContext.current
val darkTheme = isSystemInDarkTheme()
val colorScheme = if (darkTheme) {
dynamicDarkColorScheme(context)
} else {
dynamicLightColorScheme(context)
val colorScheme = when (darkTheme) {
true -> dynamicDarkColorScheme(context)
false -> dynamicLightColorScheme(context)
}
val typography = Typography()
MaterialTheme(
colorScheme = colorScheme,
typography = typography,
content = content
)
val view = LocalView.current
if (!view.isInEditMode) {
@ -34,12 +41,4 @@ fun TwoMTheme(
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
}
}
val typography = Typography()
MaterialTheme(
colorScheme = colorScheme,
typography = typography,
content = content
)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

View file

@ -19,11 +19,12 @@
<string name="login_password_label">Password</string>
<string name="password_show">Show password</string>
<string name="password_hide">Hide password</string>
<string name="notloggedin_text">To use TwoM, you need to be logged into Matrix.</string>
<string name="notloggedin_login_text">Login</string>
<string name="loggedin_text">You are logged in.</string>
<string name="account_label">My account</string>
<string name="profile_logout_text">Logout</string>
<string name="room_list_empty_text">There are no rooms.</string>
<string name="main_notloggedin_text_1">To use TwoM, you need to select the Matrix account to use.</string>
<string name="main_account_label">My account</string>
<string name="main_account_logout_text">Logout</string>
<string name="main_roomlist_empty_text">There are no rooms.</string>
<string name="loading">Loading...</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_account_login_text">Login</string>
</resources>

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.TwoM" parent="@style/Theme.Material3.DayNight"></style>
<style name="Theme.TwoM" parent="@style/Theme.Material3.DayNight" />
<style name="Theme.TwoM.Dialog" parent="@style/Theme.Material3.DayNight.Dialog" />
</resources>