diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8022ad1..d61fd79 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,7 +33,7 @@ + android:theme="@style/Theme.TwoM"> @@ -43,11 +43,11 @@ + android:theme="@style/Theme.TwoM" /> + android:name=".room.RoomActivity" + android:theme="@style/Theme.TwoM" /> diff --git a/app/src/main/java/eu/steffo/twom/main/MainActivity.kt b/app/src/main/java/eu/steffo/twom/main/MainActivity.kt index f239fd2..ec50553 100644 --- a/app/src/main/java/eu/steffo/twom/main/MainActivity.kt +++ b/app/src/main/java/eu/steffo/twom/main/MainActivity.kt @@ -11,12 +11,14 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.lifecycleScope import eu.steffo.twom.login.LoginActivity import eu.steffo.twom.matrix.TwoMMatrix +import eu.steffo.twom.room.RoomActivity import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session class MainActivity : ComponentActivity() { private lateinit var loginLauncher: ActivityResultLauncher + private lateinit var roomLauncher: ActivityResultLauncher private var session: Session? = null @@ -35,6 +37,12 @@ class MainActivity : ComponentActivity() { this::onLogin ) + roomLauncher = + registerForActivityResult( + ActivityResultContracts.StartActivityForResult(), + this::onRoom + ) + resetContent() } @@ -70,7 +78,8 @@ class MainActivity : ComponentActivity() { private fun onClickLogin() { Log.d("Main", "Clicked login, launching login activity...") - loginLauncher.launch(Intent(applicationContext, LoginActivity::class.java)) + val intent = Intent(applicationContext, LoginActivity::class.java) + loginLauncher.launch(intent) } private fun onLogin(result: ActivityResult) { @@ -102,12 +111,24 @@ class MainActivity : ComponentActivity() { } } + private fun onClickRoom(roomId: String) { + 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) + } + + private fun onRoom(result: ActivityResult) { + Log.d("Main", "Received result from room activity: $result") + } + private fun resetContent() { Log.d("Main", "Recomposing...") setContent { MatrixActivityScaffold( onClickLogin = this::onClickLogin, onClickLogout = this::onClickLogout, + onClickRoom = this::onClickRoom, session = session, ) } diff --git a/app/src/main/java/eu/steffo/twom/main/MainActivityRoomListControl.kt b/app/src/main/java/eu/steffo/twom/main/MainActivityRoomListControl.kt index a30c6dc..41b956e 100644 --- a/app/src/main/java/eu/steffo/twom/main/MainActivityRoomListControl.kt +++ b/app/src/main/java/eu/steffo/twom/main/MainActivityRoomListControl.kt @@ -2,8 +2,6 @@ package eu.steffo.twom.main import android.util.Log import androidx.compose.foundation.layout.Column -import androidx.compose.material3.Divider -import androidx.compose.material3.ListItem import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -13,28 +11,31 @@ 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.Avatar +import eu.steffo.twom.matrix.LocalSession import eu.steffo.twom.theme.TwoMPadding -import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams @Composable +@Preview fun MainActivityRoomListControl( - session: Session, modifier: Modifier = Modifier, + onClickRoom: (roomId: String) -> Unit = {}, ) { + val session = LocalSession.current var roomSummaries by remember { mutableStateOf?>(null) } LaunchedEffect(session) GetRoomSummaries@{ + if (session == null) { + Log.d("RoomList", "Not doing anything, session is null.") + return@GetRoomSummaries + } Log.d("RoomList", "Getting room summaries...") val queryParamsBuilder = roomSummaryQueryParams() roomSummaries = session.roomService().getRoomSummaries(queryParamsBuilder) Log.d("RoomList", "Obtained room summaries: $roomSummaries") - - val sanityCheck = session.roomService().getRoom("!MdYm4p7umKo4DYX71m:candy.steffo.eu") - Log.d("RoomList", "Sanity check: $sanityCheck") } Column(modifier) { @@ -50,19 +51,10 @@ fun MainActivityRoomListControl( ) } else { roomSummaries!!.forEach { - ListItem( - headlineContent = { - Text(it.name) - }, - leadingContent = { - Avatar( - session = session, - url = it.avatarUrl, - contentDescription = "" // TODO: Is this correct? - ) - } + RoomListItem( + onClickRoom = onClickRoom, + roomSummary = it, ) - Divider() } } } diff --git a/app/src/main/java/eu/steffo/twom/main/MainActivityScaffold.kt b/app/src/main/java/eu/steffo/twom/main/MainActivityScaffold.kt index 448f441..5e81df9 100644 --- a/app/src/main/java/eu/steffo/twom/main/MainActivityScaffold.kt +++ b/app/src/main/java/eu/steffo/twom/main/MainActivityScaffold.kt @@ -6,10 +6,12 @@ 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 @@ -19,34 +21,36 @@ import org.matrix.android.sdk.api.session.Session fun MatrixActivityScaffold( onClickLogin: () -> Unit = {}, onClickLogout: () -> Unit = {}, + onClickRoom: (roomId: String) -> Unit = {}, session: Session? = null, ) { TwoMTheme { - Scaffold( - topBar = { - CenterAlignedTopAppBar( - title = { - Text(LocalContext.current.getString(R.string.app_name)) - }, - actions = { - ProfileIconButton( - session = session, - onClickLogout = onClickLogout - ) - }, - ) - } - ) { - if (session == null) { - MatrixActivityNotLoggedInControl( - modifier = Modifier.padding(it), - onClickLogin = onClickLogin, - ) - } else { - MainActivityRoomListControl( - modifier = Modifier.padding(it), - session = session, - ) + 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), + onClickLogin = onClickLogin, + ) + } else { + MainActivityRoomListControl( + modifier = Modifier.padding(it), + onClickRoom = onClickRoom, + ) + } } } } diff --git a/app/src/main/java/eu/steffo/twom/main/ProfileIconButton.kt b/app/src/main/java/eu/steffo/twom/main/ProfileIconButton.kt index 322aa17..3b1446d 100644 --- a/app/src/main/java/eu/steffo/twom/main/ProfileIconButton.kt +++ b/app/src/main/java/eu/steffo/twom/main/ProfileIconButton.kt @@ -18,16 +18,16 @@ import androidx.compose.ui.platform.LocalContext 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 org.matrix.android.sdk.api.session.Session @Composable @Preview(showBackground = true) fun ProfileIconButton( modifier: Modifier = Modifier, - session: Session? = null, onClickLogout: () -> Unit = {}, ) { + val session = LocalSession.current var expanded by remember { mutableStateOf(false) } Box { @@ -42,7 +42,6 @@ fun ProfileIconButton( ) } else { UserAvatar( - session = session, userId = session.myUserId, contentDescription = LocalContext.current.getString(R.string.account_label), ) diff --git a/app/src/main/java/eu/steffo/twom/main/RoomListItem.kt b/app/src/main/java/eu/steffo/twom/main/RoomListItem.kt new file mode 100644 index 0000000..4cdf2c0 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/main/RoomListItem.kt @@ -0,0 +1,47 @@ +package eu.steffo.twom.main + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.material3.ListItem +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +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 org.matrix.android.sdk.api.session.room.model.RoomSummary + + +@Composable +fun RoomListItem( + roomSummary: RoomSummary, + onClickRoom: (roomId: String) -> Unit, +) { + ListItem( + modifier = Modifier.clickable { + onClickRoom(roomSummary.roomId) + }, + headlineContent = { + Text(roomSummary.name) + }, + leadingContent = { + Box( + modifier = Modifier + .size(40.dp) + .clip(MaterialTheme.shapes.medium) + ) { + Avatar( + url = roomSummary.avatarUrl, + ) + } + }, + supportingContent = { + val canonicalAlias = roomSummary.canonicalAlias + if (canonicalAlias != null) { + Text(canonicalAlias) + } + }, + ) +} \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/matrix/Avatar.kt b/app/src/main/java/eu/steffo/twom/matrix/Avatar.kt index db86aa6..25bb70f 100644 --- a/app/src/main/java/eu/steffo/twom/matrix/Avatar.kt +++ b/app/src/main/java/eu/steffo/twom/matrix/Avatar.kt @@ -9,19 +9,34 @@ 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.graphics.ImageBitmap import androidx.compose.ui.graphics.asImageBitmap -import org.matrix.android.sdk.api.session.Session +import androidx.compose.ui.tooling.preview.Preview @Composable +@Preview fun Avatar( - session: Session, - url: String, - contentDescription: String, + modifier: Modifier = Modifier, + url: String? = "", + contentDescription: String = "", ) { + val session = LocalSession.current var avatar by remember { mutableStateOf(null) } LaunchedEffect(session, url) GetAvatar@{ + if (session == null) { + Log.d("Avatar", "Not doing anything, session is null.") + return@GetAvatar + } + if (url == null) { + Log.d("Avatar", "URL is null, not downloading anything.") + return@GetAvatar + } + if (url.isEmpty()) { + Log.d("Avatar", "URL is a zero-length string, not downloading anything.") + return@GetAvatar + } Log.d("Avatar", "Downloading avatar at: $url") val avatarFile = session.fileService().downloadFile( fileName = "avatar", @@ -36,8 +51,16 @@ fun Avatar( avatar = avatarBitmap.asImageBitmap() } - Image( - bitmap = if (avatar != null) avatar!! else TwoMMatrix.defaultAvatar, - contentDescription = contentDescription - ) + if (session == null || url == null || avatar == null) { + DefaultAvatar( + modifier = modifier, + contentDescription = contentDescription + ) + } else { + Image( + modifier = modifier, + bitmap = avatar!!, + contentDescription = contentDescription, + ) + } } \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/matrix/DefaultAvatar.kt b/app/src/main/java/eu/steffo/twom/matrix/DefaultAvatar.kt new file mode 100644 index 0000000..945f90c --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/matrix/DefaultAvatar.kt @@ -0,0 +1,17 @@ +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, + ) +} \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/matrix/LocalSession.kt b/app/src/main/java/eu/steffo/twom/matrix/LocalSession.kt new file mode 100644 index 0000000..0441c04 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/matrix/LocalSession.kt @@ -0,0 +1,6 @@ +package eu.steffo.twom.matrix + +import androidx.compose.runtime.staticCompositionLocalOf +import org.matrix.android.sdk.api.session.Session + +val LocalSession = staticCompositionLocalOf { null } diff --git a/app/src/main/java/eu/steffo/twom/matrix/UserAvatar.kt b/app/src/main/java/eu/steffo/twom/matrix/UserAvatar.kt index abbfea1..b81312a 100644 --- a/app/src/main/java/eu/steffo/twom/matrix/UserAvatar.kt +++ b/app/src/main/java/eu/steffo/twom/matrix/UserAvatar.kt @@ -1,37 +1,45 @@ package eu.steffo.twom.matrix import android.util.Log -import androidx.compose.foundation.Image import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue -import org.matrix.android.sdk.api.session.Session +import androidx.compose.ui.Modifier @Composable fun UserAvatar( - session: Session, - userId: String, - contentDescription: String, + modifier: Modifier = Modifier, + userId: String = "", + contentDescription: String = "", ) { + val session = LocalSession.current var avatarUrl by rememberSaveable { mutableStateOf(null) } LaunchedEffect(session, userId) GetAvatarUrl@{ + if (session == null) { + Log.d("UserAvatar", "Not doing anything, session is null.") + return@GetAvatarUrl + } + if (userId.isEmpty()) { + Log.d("UserAvatar", "Not doing anything, userId is empty.") + return@GetAvatarUrl + } Log.d("UserAvatar", "Retrieving avatar url for: $userId...") avatarUrl = session.profileService().getAvatarUrl(userId).getOrNull() Log.d("UserAvatar", "Retrieved avatar url for $userId: $avatarUrl") } if (avatarUrl == null) { - Image( - bitmap = TwoMMatrix.defaultAvatar, + DefaultAvatar( + modifier = modifier, contentDescription = contentDescription, ) } else { Avatar( - session = session, + modifier = modifier, url = avatarUrl!!, contentDescription = contentDescription, ) diff --git a/app/src/main/java/eu/steffo/twom/room/RoomActivity.kt b/app/src/main/java/eu/steffo/twom/room/RoomActivity.kt new file mode 100644 index 0000000..3b78e72 --- /dev/null +++ b/app/src/main/java/eu/steffo/twom/room/RoomActivity.kt @@ -0,0 +1,10 @@ +package eu.steffo.twom.room + +import androidx.activity.ComponentActivity + +class RoomActivity : ComponentActivity() { + companion object { + const val ROOM_ID_EXTRA = "roomId" + } + +} \ No newline at end of file diff --git a/app/src/main/java/eu/steffo/twom/theme/TwoMTheme.kt b/app/src/main/java/eu/steffo/twom/theme/TwoMTheme.kt index cba9cb2..cba4fb6 100644 --- a/app/src/main/java/eu/steffo/twom/theme/TwoMTheme.kt +++ b/app/src/main/java/eu/steffo/twom/theme/TwoMTheme.kt @@ -30,8 +30,8 @@ fun TwoMTheme( if (!view.isInEditMode) { SideEffect { val window = (view.context as Activity).window - window.statusBarColor = colorScheme.primary.toArgb() - WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + window.statusBarColor = colorScheme.surface.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme } } diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml deleted file mode 100644 index 045e125..0000000 --- a/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..070e498 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file