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

Progress but also no progress

This commit is contained in:
Steffo 2023-11-30 05:15:42 +01:00
parent 51d2a83ee6
commit d66bbeb277
Signed by: steffo
GPG key ID: 2A24051445686895
14 changed files with 203 additions and 74 deletions

View file

@ -33,7 +33,7 @@
<activity <activity
android:name=".main.MainActivity" android:name=".main.MainActivity"
android:exported="true" android:exported="true"
android:theme="@android:style/Theme.NoTitleBar"> android:theme="@style/Theme.TwoM">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -43,11 +43,11 @@
<activity <activity
android:name=".login.LoginActivity" android:name=".login.LoginActivity"
android:theme="@android:style/Theme.NoTitleBar" /> android:theme="@style/Theme.TwoM" />
<activity <activity
android:name=".homeserver.SelectHomeserverActivity" android:name=".room.RoomActivity"
android:theme="@android:style/Theme.NoTitleBar" /> android:theme="@style/Theme.TwoM" />
</application> </application>

View file

@ -11,12 +11,14 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import eu.steffo.twom.login.LoginActivity import eu.steffo.twom.login.LoginActivity
import eu.steffo.twom.matrix.TwoMMatrix import eu.steffo.twom.matrix.TwoMMatrix
import eu.steffo.twom.room.RoomActivity
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
private lateinit var loginLauncher: ActivityResultLauncher<Intent> private lateinit var loginLauncher: ActivityResultLauncher<Intent>
private lateinit var roomLauncher: ActivityResultLauncher<Intent>
private var session: Session? = null private var session: Session? = null
@ -35,6 +37,12 @@ class MainActivity : ComponentActivity() {
this::onLogin this::onLogin
) )
roomLauncher =
registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
this::onRoom
)
resetContent() resetContent()
} }
@ -70,7 +78,8 @@ class MainActivity : ComponentActivity() {
private fun onClickLogin() { private fun onClickLogin() {
Log.d("Main", "Clicked login, launching login activity...") 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) { 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() { private fun resetContent() {
Log.d("Main", "Recomposing...") Log.d("Main", "Recomposing...")
setContent { setContent {
MatrixActivityScaffold( MatrixActivityScaffold(
onClickLogin = this::onClickLogin, onClickLogin = this::onClickLogin,
onClickLogout = this::onClickLogout, onClickLogout = this::onClickLogout,
onClickRoom = this::onClickRoom,
session = session, session = session,
) )
} }

View file

@ -2,8 +2,6 @@ package eu.steffo.twom.main
import android.util.Log import android.util.Log
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Divider
import androidx.compose.material3.ListItem
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@ -13,28 +11,31 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.R import eu.steffo.twom.R
import eu.steffo.twom.matrix.Avatar import eu.steffo.twom.matrix.LocalSession
import eu.steffo.twom.theme.TwoMPadding 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.model.RoomSummary
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
@Composable @Composable
@Preview
fun MainActivityRoomListControl( fun MainActivityRoomListControl(
session: Session,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onClickRoom: (roomId: String) -> Unit = {},
) { ) {
val session = LocalSession.current
var roomSummaries by remember { mutableStateOf<List<RoomSummary>?>(null) } var roomSummaries by remember { mutableStateOf<List<RoomSummary>?>(null) }
LaunchedEffect(session) GetRoomSummaries@{ LaunchedEffect(session) GetRoomSummaries@{
if (session == null) {
Log.d("RoomList", "Not doing anything, session is null.")
return@GetRoomSummaries
}
Log.d("RoomList", "Getting room summaries...") Log.d("RoomList", "Getting room summaries...")
val queryParamsBuilder = roomSummaryQueryParams() val queryParamsBuilder = roomSummaryQueryParams()
roomSummaries = session.roomService().getRoomSummaries(queryParamsBuilder) roomSummaries = session.roomService().getRoomSummaries(queryParamsBuilder)
Log.d("RoomList", "Obtained room summaries: $roomSummaries") Log.d("RoomList", "Obtained room summaries: $roomSummaries")
val sanityCheck = session.roomService().getRoom("!MdYm4p7umKo4DYX71m:candy.steffo.eu")
Log.d("RoomList", "Sanity check: $sanityCheck")
} }
Column(modifier) { Column(modifier) {
@ -50,19 +51,10 @@ fun MainActivityRoomListControl(
) )
} else { } else {
roomSummaries!!.forEach { roomSummaries!!.forEach {
ListItem( RoomListItem(
headlineContent = { onClickRoom = onClickRoom,
Text(it.name) roomSummary = it,
},
leadingContent = {
Avatar(
session = session,
url = it.avatarUrl,
contentDescription = "" // TODO: Is this correct?
)
}
) )
Divider()
} }
} }
} }

View file

@ -6,10 +6,12 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
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.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import eu.steffo.twom.R import eu.steffo.twom.R
import eu.steffo.twom.matrix.LocalSession
import eu.steffo.twom.theme.TwoMTheme import eu.steffo.twom.theme.TwoMTheme
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
@ -19,34 +21,36 @@ import org.matrix.android.sdk.api.session.Session
fun MatrixActivityScaffold( fun MatrixActivityScaffold(
onClickLogin: () -> Unit = {}, onClickLogin: () -> Unit = {},
onClickLogout: () -> Unit = {}, onClickLogout: () -> Unit = {},
onClickRoom: (roomId: String) -> Unit = {},
session: Session? = null, session: Session? = null,
) { ) {
TwoMTheme { TwoMTheme {
Scaffold( CompositionLocalProvider(LocalSession provides session) {
topBar = { Scaffold(
CenterAlignedTopAppBar( topBar = {
title = { CenterAlignedTopAppBar(
Text(LocalContext.current.getString(R.string.app_name)) title = {
}, Text(LocalContext.current.getString(R.string.app_name))
actions = { },
ProfileIconButton( actions = {
session = session, ProfileIconButton(
onClickLogout = onClickLogout onClickLogout = onClickLogout
) )
}, },
) )
} }
) { ) {
if (session == null) { if (session == null) {
MatrixActivityNotLoggedInControl( MatrixActivityNotLoggedInControl(
modifier = Modifier.padding(it), modifier = Modifier.padding(it),
onClickLogin = onClickLogin, onClickLogin = onClickLogin,
) )
} else { } else {
MainActivityRoomListControl( MainActivityRoomListControl(
modifier = Modifier.padding(it), modifier = Modifier.padding(it),
session = session, onClickRoom = onClickRoom,
) )
}
} }
} }
} }

View file

@ -18,16 +18,16 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource 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.matrix.LocalSession
import eu.steffo.twom.matrix.UserAvatar import eu.steffo.twom.matrix.UserAvatar
import org.matrix.android.sdk.api.session.Session
@Composable @Composable
@Preview(showBackground = true) @Preview(showBackground = true)
fun ProfileIconButton( fun ProfileIconButton(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
session: Session? = null,
onClickLogout: () -> Unit = {}, onClickLogout: () -> Unit = {},
) { ) {
val session = LocalSession.current
var expanded by remember { mutableStateOf(false) } var expanded by remember { mutableStateOf(false) }
Box { Box {
@ -42,7 +42,6 @@ fun ProfileIconButton(
) )
} else { } else {
UserAvatar( UserAvatar(
session = session,
userId = session.myUserId, userId = session.myUserId,
contentDescription = LocalContext.current.getString(R.string.account_label), contentDescription = LocalContext.current.getString(R.string.account_label),
) )

View file

@ -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)
}
},
)
}

View file

@ -9,19 +9,34 @@ 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.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.asImageBitmap
import org.matrix.android.sdk.api.session.Session import androidx.compose.ui.tooling.preview.Preview
@Composable @Composable
@Preview
fun Avatar( fun Avatar(
session: Session, modifier: Modifier = Modifier,
url: String, url: String? = "",
contentDescription: String, contentDescription: String = "",
) { ) {
val session = LocalSession.current
var avatar by remember { mutableStateOf<ImageBitmap?>(null) } var avatar by remember { mutableStateOf<ImageBitmap?>(null) }
LaunchedEffect(session, url) GetAvatar@{ 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") Log.d("Avatar", "Downloading avatar at: $url")
val avatarFile = session.fileService().downloadFile( val avatarFile = session.fileService().downloadFile(
fileName = "avatar", fileName = "avatar",
@ -36,8 +51,16 @@ fun Avatar(
avatar = avatarBitmap.asImageBitmap() avatar = avatarBitmap.asImageBitmap()
} }
Image( if (session == null || url == null || avatar == null) {
bitmap = if (avatar != null) avatar!! else TwoMMatrix.defaultAvatar, DefaultAvatar(
contentDescription = contentDescription modifier = modifier,
) contentDescription = contentDescription
)
} else {
Image(
modifier = modifier,
bitmap = avatar!!,
contentDescription = contentDescription,
)
}
} }

View file

@ -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,
)
}

View file

@ -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<Session?> { null }

View file

@ -1,37 +1,45 @@
package eu.steffo.twom.matrix package eu.steffo.twom.matrix
import android.util.Log import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import org.matrix.android.sdk.api.session.Session import androidx.compose.ui.Modifier
@Composable @Composable
fun UserAvatar( fun UserAvatar(
session: Session, modifier: Modifier = Modifier,
userId: String, userId: String = "",
contentDescription: String, contentDescription: String = "",
) { ) {
val session = LocalSession.current
var avatarUrl by rememberSaveable { mutableStateOf<String?>(null) } var avatarUrl by rememberSaveable { mutableStateOf<String?>(null) }
LaunchedEffect(session, userId) GetAvatarUrl@{ 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...") Log.d("UserAvatar", "Retrieving avatar url for: $userId...")
avatarUrl = session.profileService().getAvatarUrl(userId).getOrNull() avatarUrl = session.profileService().getAvatarUrl(userId).getOrNull()
Log.d("UserAvatar", "Retrieved avatar url for $userId: $avatarUrl") Log.d("UserAvatar", "Retrieved avatar url for $userId: $avatarUrl")
} }
if (avatarUrl == null) { if (avatarUrl == null) {
Image( DefaultAvatar(
bitmap = TwoMMatrix.defaultAvatar, modifier = modifier,
contentDescription = contentDescription, contentDescription = contentDescription,
) )
} else { } else {
Avatar( Avatar(
session = session, modifier = modifier,
url = avatarUrl!!, url = avatarUrl!!,
contentDescription = contentDescription, contentDescription = contentDescription,
) )

View file

@ -0,0 +1,10 @@
package eu.steffo.twom.room
import androidx.activity.ComponentActivity
class RoomActivity : ComponentActivity() {
companion object {
const val ROOM_ID_EXTRA = "roomId"
}
}

View file

@ -30,8 +30,8 @@ fun TwoMTheme(
if (!view.isInEditMode) { if (!view.isInEditMode) {
SideEffect { SideEffect {
val window = (view.context as Activity).window val window = (view.context as Activity).window
window.statusBarColor = colorScheme.primary.toArgb() window.statusBarColor = colorScheme.surface.toArgb()
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
} }
} }

View file

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View file

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