1
Fork 0
mirror of https://github.com/Steffo99/twom.git synced 2024-10-16 14:37:33 +00:00

Load user avatars

This commit is contained in:
Steffo 2023-11-29 03:09:49 +01:00
parent 9f7df9bfa4
commit 43f4b266aa
Signed by: steffo
GPG key ID: 2A24051445686895
5 changed files with 129 additions and 27 deletions

View file

@ -24,32 +24,39 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
TwoMMatrix.ensureMatrix(applicationContext)
TwoMMatrix.ensureDefaultAvatar(applicationContext)
fetchLastSession()
openSession()
loginLauncher =
registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
this::handleLoginResult
this::onLogin
)
// This calls recompose() by itself
openLastSession()
resetContent()
}
private fun openLastSession() {
override fun onDestroy() {
super.onDestroy()
closeSession()
}
private fun fetchLastSession() {
Log.d("Main", "Fetching the last successfully authenticated session...")
session = TwoMMatrix.matrix.authenticationService().getLastAuthenticatedSession()
session?.open()
recompose()
}
private fun recompose() {
Log.d("Main", "Recomposing...")
setContent {
MatrixActivityScaffold(
onClickLogin = this::onClickLogin,
onClickLogout = this::onClickLogout,
session = session,
)
}
private fun openSession() {
Log.d("Main", "If possible, opening session: $session")
session?.open()
}
private fun closeSession() {
Log.d("Main", "If possible, closing session: $session")
session?.close()
}
private fun onClickLogin() {
@ -57,14 +64,17 @@ class MainActivity : ComponentActivity() {
loginLauncher.launch(Intent(applicationContext, LoginActivity::class.java))
}
private fun handleLoginResult(result: ActivityResult) {
private fun onLogin(result: ActivityResult) {
Log.d("Main", "Received result from login activity: $result")
when (result.resultCode) {
RESULT_OK -> {
Log.d(
"Main",
"Login activity returned a successful result, trying to get session..."
)
openLastSession()
fetchLastSession()
session?.open()
resetContent()
}
else -> {
@ -79,7 +89,18 @@ class MainActivity : ComponentActivity() {
session!!.signOutService().signOut(true)
session = null
Log.d("Main", "Done logging out, recomposing...")
recompose()
resetContent()
}
}
private fun resetContent() {
Log.d("Main", "Recomposing...")
setContent {
MatrixActivityScaffold(
onClickLogin = this::onClickLogin,
onClickLogout = this::onClickLogout,
session = session,
)
}
}
}

View file

@ -18,6 +18,7 @@ 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.Avatar
import org.matrix.android.sdk.api.session.Session
@Composable
@ -34,10 +35,18 @@ fun ProfileIconButton(
enabled = (session != null),
onClick = { expanded = true },
) {
Icon(
Icons.Filled.AccountCircle,
LocalContext.current.getString(R.string.account_label)
)
if (session == null) {
Icon(
imageVector = Icons.Filled.AccountCircle,
contentDescription = LocalContext.current.getString(R.string.account_label),
)
} else {
Avatar(
session = session,
userId = session.myUserId,
contentDescription = LocalContext.current.getString(R.string.account_label),
)
}
}
DropdownMenu(
expanded = expanded,

View file

@ -0,0 +1,47 @@
package eu.steffo.twom.matrix
import android.graphics.BitmapFactory
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.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import org.matrix.android.sdk.api.session.Session
@Composable
fun Avatar(
session: Session,
userId: String,
contentDescription: String,
) {
var avatar by remember { mutableStateOf<ImageBitmap?>(null) }
var fetched by remember { mutableStateOf(false) }
LaunchedEffect(session, userId) GetAvatar@{
Log.d("Avatar", "Trying to retrieve the avatar url for $userId...")
val avatarUrl = session.profileService().getAvatarUrl(userId)
Log.d("Avatar", "Avatar URL for $userId is: $avatarUrl")
val avatarFile = session.fileService().downloadFile(
fileName = "avatar",
url = avatarUrl.getOrNull(),
mimeType = null,
elementToDecrypt = null,
)
// TODO: Should I check the MIME type? And the size of the image?
Log.d("Avatar", "Avatar file for $userId is: $avatarFile")
val avatarBitmap = BitmapFactory.decodeFile(avatarFile.absolutePath)
Log.d("Avatar", "Avatar bitmap for $userId is: $avatarBitmap")
avatar = avatarBitmap.asImageBitmap()
fetched = true
}
Image(
bitmap = if (fetched && avatar != null) avatar!! else TwoMMatrix.defaultAvatar,
contentDescription = contentDescription
)
}

View file

@ -1,6 +1,11 @@
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
@ -16,17 +21,14 @@ object TwoMMatrix {
*/
lateinit var matrix: Matrix
private fun isMatrixInitialized(): Boolean {
return this::matrix.isInitialized
}
/**
* Make sure the [matrix] object is available, constructing it if it isn't initialized.
*
* Uses the passed [Context] to access the [application context][Context.getApplicationContext], which is required by the SDK provided by the Matrix Foundation.
*/
fun ensureMatrix(context: Context): Matrix? {
if (!isMatrixInitialized()) {
if (!this::matrix.isInitialized) {
Log.d("Matrix", "Initializing Matrix...")
matrix = Matrix(
context = context.applicationContext,
matrixConfiguration = MatrixConfiguration(
@ -38,4 +40,27 @@ 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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB