mirror of
https://github.com/Steffo99/twom.git
synced 2024-11-25 17:44:24 +00:00
Load user avatars
This commit is contained in:
parent
9f7df9bfa4
commit
43f4b266aa
5 changed files with 129 additions and 27 deletions
|
@ -24,32 +24,39 @@ class MainActivity : ComponentActivity() {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
TwoMMatrix.ensureMatrix(applicationContext)
|
TwoMMatrix.ensureMatrix(applicationContext)
|
||||||
|
TwoMMatrix.ensureDefaultAvatar(applicationContext)
|
||||||
|
|
||||||
|
fetchLastSession()
|
||||||
|
openSession()
|
||||||
|
|
||||||
loginLauncher =
|
loginLauncher =
|
||||||
registerForActivityResult(
|
registerForActivityResult(
|
||||||
ActivityResultContracts.StartActivityForResult(),
|
ActivityResultContracts.StartActivityForResult(),
|
||||||
this::handleLoginResult
|
this::onLogin
|
||||||
)
|
)
|
||||||
|
|
||||||
// This calls recompose() by itself
|
resetContent()
|
||||||
openLastSession()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = TwoMMatrix.matrix.authenticationService().getLastAuthenticatedSession()
|
||||||
session?.open()
|
|
||||||
recompose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recompose() {
|
private fun openSession() {
|
||||||
Log.d("Main", "Recomposing...")
|
Log.d("Main", "If possible, opening session: $session")
|
||||||
setContent {
|
session?.open()
|
||||||
MatrixActivityScaffold(
|
|
||||||
onClickLogin = this::onClickLogin,
|
|
||||||
onClickLogout = this::onClickLogout,
|
|
||||||
session = session,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun closeSession() {
|
||||||
|
Log.d("Main", "If possible, closing session: $session")
|
||||||
|
session?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onClickLogin() {
|
private fun onClickLogin() {
|
||||||
|
@ -57,14 +64,17 @@ class MainActivity : ComponentActivity() {
|
||||||
loginLauncher.launch(Intent(applicationContext, LoginActivity::class.java))
|
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) {
|
when (result.resultCode) {
|
||||||
RESULT_OK -> {
|
RESULT_OK -> {
|
||||||
Log.d(
|
Log.d(
|
||||||
"Main",
|
"Main",
|
||||||
"Login activity returned a successful result, trying to get session..."
|
"Login activity returned a successful result, trying to get session..."
|
||||||
)
|
)
|
||||||
openLastSession()
|
fetchLastSession()
|
||||||
|
session?.open()
|
||||||
|
resetContent()
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -79,7 +89,18 @@ class MainActivity : ComponentActivity() {
|
||||||
session!!.signOutService().signOut(true)
|
session!!.signOutService().signOut(true)
|
||||||
session = null
|
session = null
|
||||||
Log.d("Main", "Done logging out, recomposing...")
|
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,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ 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.Avatar
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -34,10 +35,18 @@ fun ProfileIconButton(
|
||||||
enabled = (session != null),
|
enabled = (session != null),
|
||||||
onClick = { expanded = true },
|
onClick = { expanded = true },
|
||||||
) {
|
) {
|
||||||
|
if (session == null) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Filled.AccountCircle,
|
imageVector = Icons.Filled.AccountCircle,
|
||||||
LocalContext.current.getString(R.string.account_label)
|
contentDescription = LocalContext.current.getString(R.string.account_label),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
Avatar(
|
||||||
|
session = session,
|
||||||
|
userId = session.myUserId,
|
||||||
|
contentDescription = LocalContext.current.getString(R.string.account_label),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DropdownMenu(
|
DropdownMenu(
|
||||||
expanded = expanded,
|
expanded = expanded,
|
||||||
|
|
47
app/src/main/java/eu/steffo/twom/matrix/Avatar.kt
Normal file
47
app/src/main/java/eu/steffo/twom/matrix/Avatar.kt
Normal 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
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,6 +1,11 @@
|
||||||
package eu.steffo.twom.matrix
|
package eu.steffo.twom.matrix
|
||||||
|
|
||||||
import android.content.Context
|
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.Matrix
|
||||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||||
|
|
||||||
|
@ -16,17 +21,14 @@ object TwoMMatrix {
|
||||||
*/
|
*/
|
||||||
lateinit var matrix: Matrix
|
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.
|
* 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.
|
* 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? {
|
fun ensureMatrix(context: Context): Matrix? {
|
||||||
if (!isMatrixInitialized()) {
|
if (!this::matrix.isInitialized) {
|
||||||
|
Log.d("Matrix", "Initializing Matrix...")
|
||||||
matrix = Matrix(
|
matrix = Matrix(
|
||||||
context = context.applicationContext,
|
context = context.applicationContext,
|
||||||
matrixConfiguration = MatrixConfiguration(
|
matrixConfiguration = MatrixConfiguration(
|
||||||
|
@ -38,4 +40,27 @@ object TwoMMatrix {
|
||||||
}
|
}
|
||||||
return null
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
app/src/main/res/drawable/avatar_default.png
Normal file
BIN
app/src/main/res/drawable/avatar_default.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
Loading…
Reference in a new issue