diff --git a/app/src/main/java/chat/revolt/api/routes/user/User.kt b/app/src/main/java/chat/revolt/api/routes/user/User.kt index 6b3f5de0..4b17a531 100644 --- a/app/src/main/java/chat/revolt/api/routes/user/User.kt +++ b/app/src/main/java/chat/revolt/api/routes/user/User.kt @@ -4,6 +4,7 @@ import chat.revolt.api.RevoltAPI import chat.revolt.api.RevoltError import chat.revolt.api.RevoltHttp import chat.revolt.api.RevoltJson +import chat.revolt.api.schemas.Profile import chat.revolt.api.schemas.User import io.ktor.client.request.get import io.ktor.client.statement.bodyAsText @@ -69,4 +70,21 @@ suspend fun addUserIfUnknown(id: String) { if (RevoltAPI.userCache[id] == null) { RevoltAPI.userCache[id] = fetchUser(id) } +} + +suspend fun fetchUserProfile(id: String): Profile { + val res = RevoltHttp.get("/users/$id/profile") { + headers.append(RevoltAPI.TOKEN_HEADER_NAME, RevoltAPI.sessionToken) + } + + val response = res.bodyAsText() + + try { + val error = RevoltJson.decodeFromString(RevoltError.serializer(), response) + throw Error(error.type) + } catch (e: SerializationException) { + // Not an error + } + + return RevoltJson.decodeFromString(Profile.serializer(), response) } \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/components/screens/settings/SelfUserOverview.kt b/app/src/main/java/chat/revolt/components/screens/settings/SelfUserOverview.kt new file mode 100644 index 00000000..b0ee331c --- /dev/null +++ b/app/src/main/java/chat/revolt/components/screens/settings/SelfUserOverview.kt @@ -0,0 +1,105 @@ +package chat.revolt.components.screens.settings + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +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.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import chat.revolt.R +import chat.revolt.api.REVOLT_FILES +import chat.revolt.api.RevoltAPI +import chat.revolt.api.internals.ULID +import chat.revolt.api.routes.user.fetchUserProfile +import chat.revolt.api.schemas.Profile +import chat.revolt.components.generic.RemoteImage +import chat.revolt.components.generic.UserAvatar +import chat.revolt.components.generic.presenceFromStatus + +@Composable +fun SelfUserOverview() { + val selfUser = RevoltAPI.userCache[RevoltAPI.selfId] ?: return + var profile by remember { mutableStateOf(null) } + + LaunchedEffect(selfUser) { + profile = fetchUserProfile(selfUser.id ?: ULID.makeSpecial(0)) + } + + Box( + contentAlignment = Alignment.BottomStart, + ) { + profile?.background?.let { background -> + RemoteImage( + url = "$REVOLT_FILES/backgrounds/${background.id}", + description = null, + modifier = Modifier + .height(128.dp) + .fillMaxWidth(), + contentScale = ContentScale.FillWidth + ) + + Box( + modifier = Modifier + .background( + Brush.verticalGradient( + listOf( + Color.Transparent, + Color.Black.copy(alpha = 0.7f) + ) + ) + ) + .height(128.dp) + .fillMaxWidth() + ) + } + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .padding(16.dp) + .fillMaxWidth() + ) { + UserAvatar( + username = selfUser.displayName ?: stringResource(id = R.string.unknown), + userId = selfUser.id ?: ULID.makeSpecial(0), + avatar = selfUser.avatar, + size = 48.dp, + presence = presenceFromStatus(selfUser.status?.presence ?: "offline"), + ) + + Spacer(modifier = Modifier.width(12.dp)) + + Text(text = AnnotatedString.Builder().apply { + if (selfUser.displayName != null) { + pushStyle(SpanStyle(fontWeight = FontWeight.Bold)) + append(selfUser.displayName) + pop() + append("\n") + } + append("${selfUser.username}") + pushStyle(SpanStyle(fontWeight = FontWeight.ExtraLight)) + append("#${selfUser.discriminator}") + pop() + }.toAnnotatedString()) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt b/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt index e1adf80c..159bf6c9 100644 --- a/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt @@ -26,6 +26,7 @@ import chat.revolt.BuildConfig import chat.revolt.R import chat.revolt.components.generic.PageHeader import chat.revolt.components.generic.SheetClickable +import chat.revolt.components.screens.settings.SelfUserOverview @Composable fun SettingsScreen( @@ -43,6 +44,8 @@ fun SettingsScreen( navController.popBackStack() }) + SelfUserOverview() + Column( modifier = Modifier .fillMaxSize()