Fix profile avatar emoji fallback and bump TV/mobile app versions.
This commit is contained in:
parent
91e7502d3b
commit
9efcfff484
9 changed files with 113 additions and 73 deletions
|
|
@ -20,8 +20,8 @@ android {
|
||||||
applicationId = "nl.vonas.mediacluster"
|
applicationId = "nl.vonas.mediacluster"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 20
|
versionCode = 21
|
||||||
versionName = "1.0.19"
|
versionName = "1.0.20"
|
||||||
buildConfigField("String", "DEFAULT_API_BASE", "\"https://master.vonas.nl\"")
|
buildConfigField("String", "DEFAULT_API_BASE", "\"https://master.vonas.nl\"")
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters += listOf("arm64-v8a", "armeabi-v7a")
|
abiFilters += listOf("arm64-v8a", "armeabi-v7a")
|
||||||
|
|
|
||||||
|
|
@ -885,14 +885,21 @@ private fun JSONArray?.toProfiles(): List<ViewerProfile> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JSONObject.toProfile(): ViewerProfile = ViewerProfile(
|
private fun JSONObject.toProfile(): ViewerProfile {
|
||||||
|
val hasCustom = optBoolean("hasCustomAvatar")
|
||||||
|
val rawUrl = optString("avatarUrl").takeIf { it.isNotBlank() }
|
||||||
|
return ViewerProfile(
|
||||||
id = getString("id"),
|
id = getString("id"),
|
||||||
name = optString("name"),
|
name = optString("name"),
|
||||||
avatarId = optString("avatarId").ifBlank { "fox" },
|
avatarId = optString("avatarId").ifBlank { "fox" },
|
||||||
isOwner = optBoolean("isOwner"),
|
isOwner = optBoolean("isOwner"),
|
||||||
isKids = optBoolean("isKids"),
|
isKids = optBoolean("isKids"),
|
||||||
hasPin = optBoolean("hasPin"),
|
hasPin = optBoolean("hasPin"),
|
||||||
showAvatar = if (has("showAvatar")) optBoolean("showAvatar") else true,
|
showAvatar = when {
|
||||||
hasCustomAvatar = optBoolean("hasCustomAvatar"),
|
!has("showAvatar") || isNull("showAvatar") -> true
|
||||||
avatarUrl = optString("avatarUrl").ifBlank { null },
|
else -> optBoolean("showAvatar", true)
|
||||||
|
},
|
||||||
|
hasCustomAvatar = hasCustom,
|
||||||
|
avatarUrl = if (hasCustom) rawUrl else null,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,13 +86,12 @@ class SessionStore(private val context: Context) {
|
||||||
if (showAvatar != null) {
|
if (showAvatar != null) {
|
||||||
prefs[profileShowAvatarKey] = if (showAvatar) "1" else "0"
|
prefs[profileShowAvatarKey] = if (showAvatar) "1" else "0"
|
||||||
}
|
}
|
||||||
if (avatarUrl != null) {
|
// Altijd syncen: null/blank = geen custom foto (emoji tonen)
|
||||||
if (avatarUrl.isBlank()) prefs.remove(profileAvatarUrlKey)
|
if (avatarUrl.isNullOrBlank()) prefs.remove(profileAvatarUrlKey)
|
||||||
else prefs[profileAvatarUrlKey] = avatarUrl
|
else prefs[profileAvatarUrlKey] = avatarUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setApiBase(url: String) {
|
suspend fun setApiBase(url: String) {
|
||||||
context.dataStore.edit { it[apiKey] = url.trim().trimEnd('/') }
|
context.dataStore.edit { it[apiKey] = url.trim().trimEnd('/') }
|
||||||
|
|
|
||||||
|
|
@ -1350,7 +1350,10 @@ private fun SettingsScreen(
|
||||||
.background(Color(0xFF2E2E3A)),
|
.background(Color(0xFF2E2E3A)),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
if (profileShowAvatar && !profileAvatarUrl.isNullOrBlank()) {
|
if (profileShowAvatar) {
|
||||||
|
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
|
Text(avatarEmoji(profileAvatarId ?: "fox"), fontSize = 22.sp)
|
||||||
|
if (!profileAvatarUrl.isNullOrBlank()) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = ImageRequest.Builder(LocalContext.current)
|
model = ImageRequest.Builder(LocalContext.current)
|
||||||
.data(profileAvatarUrl)
|
.data(profileAvatarUrl)
|
||||||
|
|
@ -1364,8 +1367,15 @@ private fun SettingsScreen(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Text(avatarEmoji(profileAvatarId ?: "fox"), fontSize = 22.sp)
|
Text(
|
||||||
|
(profileName?.firstOrNull()?.uppercaseChar() ?: '?').toString(),
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 18.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column(Modifier.weight(1f)) {
|
Column(Modifier.weight(1f)) {
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ android {
|
||||||
applicationId = "nl.vonas.mediacluster.tv"
|
applicationId = "nl.vonas.mediacluster.tv"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 106
|
versionCode = 107
|
||||||
versionName = "0.14.43"
|
versionName = "0.14.44"
|
||||||
buildConfigField("String", "DEFAULT_API_BASE", "\"https://master.vonas.nl\"")
|
buildConfigField("String", "DEFAULT_API_BASE", "\"https://master.vonas.nl\"")
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters += listOf("arm64-v8a", "armeabi-v7a")
|
abiFilters += listOf("arm64-v8a", "armeabi-v7a")
|
||||||
|
|
|
||||||
|
|
@ -875,14 +875,21 @@ private fun JSONArray?.toProfiles(): List<ViewerProfile> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JSONObject.toProfile(): ViewerProfile = ViewerProfile(
|
private fun JSONObject.toProfile(): ViewerProfile {
|
||||||
|
val hasCustom = optBoolean("hasCustomAvatar")
|
||||||
|
val rawUrl = optString("avatarUrl").takeIf { it.isNotBlank() }
|
||||||
|
return ViewerProfile(
|
||||||
id = getString("id"),
|
id = getString("id"),
|
||||||
name = optString("name"),
|
name = optString("name"),
|
||||||
avatarId = optString("avatarId").ifBlank { "fox" },
|
avatarId = optString("avatarId").ifBlank { "fox" },
|
||||||
isOwner = optBoolean("isOwner"),
|
isOwner = optBoolean("isOwner"),
|
||||||
isKids = optBoolean("isKids"),
|
isKids = optBoolean("isKids"),
|
||||||
hasPin = optBoolean("hasPin"),
|
hasPin = optBoolean("hasPin"),
|
||||||
showAvatar = if (has("showAvatar")) optBoolean("showAvatar") else true,
|
showAvatar = when {
|
||||||
hasCustomAvatar = optBoolean("hasCustomAvatar"),
|
!has("showAvatar") || isNull("showAvatar") -> true
|
||||||
avatarUrl = optString("avatarUrl").ifBlank { null },
|
else -> optBoolean("showAvatar", true)
|
||||||
|
},
|
||||||
|
hasCustomAvatar = hasCustom,
|
||||||
|
avatarUrl = if (hasCustom) rawUrl else null,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,13 +105,12 @@ class SessionStore(private val context: Context) {
|
||||||
if (showAvatar != null) {
|
if (showAvatar != null) {
|
||||||
prefs[profileShowAvatarKey] = if (showAvatar) "1" else "0"
|
prefs[profileShowAvatarKey] = if (showAvatar) "1" else "0"
|
||||||
}
|
}
|
||||||
if (avatarUrl != null) {
|
// Altijd syncen: null/blank = geen custom foto (emoji tonen)
|
||||||
if (avatarUrl.isBlank()) prefs.remove(profileAvatarUrlKey)
|
if (avatarUrl.isNullOrBlank()) prefs.remove(profileAvatarUrlKey)
|
||||||
else prefs[profileAvatarUrlKey] = avatarUrl
|
else prefs[profileAvatarUrlKey] = avatarUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setApiBase(url: String) {
|
suspend fun setApiBase(url: String) {
|
||||||
context.dataStore.edit { it[apiKey] = url.trim().trimEnd('/') }
|
context.dataStore.edit { it[apiKey] = url.trim().trimEnd('/') }
|
||||||
|
|
|
||||||
|
|
@ -784,6 +784,7 @@ private fun MainHub(
|
||||||
MainTab.Settings -> SettingsScreen(
|
MainTab.Settings -> SettingsScreen(
|
||||||
api = api,
|
api = api,
|
||||||
profileAvatarId = profileAvatarId,
|
profileAvatarId = profileAvatarId,
|
||||||
|
profileShowAvatar = profileShowAvatar,
|
||||||
profileName = profileName,
|
profileName = profileName,
|
||||||
isOwner = isOwner,
|
isOwner = isOwner,
|
||||||
onBack = {
|
onBack = {
|
||||||
|
|
@ -1644,6 +1645,7 @@ private fun ShelfBlock(
|
||||||
private fun SettingsScreen(
|
private fun SettingsScreen(
|
||||||
api: ApiClient,
|
api: ApiClient,
|
||||||
profileAvatarId: String? = null,
|
profileAvatarId: String? = null,
|
||||||
|
profileShowAvatar: Boolean = true,
|
||||||
profileName: String? = null,
|
profileName: String? = null,
|
||||||
isOwner: Boolean = false,
|
isOwner: Boolean = false,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
|
|
@ -1737,12 +1739,21 @@ private fun SettingsScreen(
|
||||||
.background(Color(0xFF2E2E3A)),
|
.background(Color(0xFF2E2E3A)),
|
||||||
contentAlignment = Alignment.Center,
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
|
if (profileShowAvatar) {
|
||||||
Text(
|
Text(
|
||||||
avatarEmoji(profileAvatarId ?: "fox"),
|
avatarEmoji(profileAvatarId ?: "fox"),
|
||||||
fontSize = 30.sp,
|
fontSize = 30.sp,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
Text(
|
||||||
|
(profileName?.firstOrNull()?.uppercaseChar() ?: '?').toString(),
|
||||||
|
color = Color.White,
|
||||||
|
fontSize = 26.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Column(Modifier.weight(1f)) {
|
Column(Modifier.weight(1f)) {
|
||||||
Text(
|
Text(
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,14 @@ fun TopNavBar(
|
||||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||||
) {
|
) {
|
||||||
if (profileShowAvatar) {
|
if (profileShowAvatar) {
|
||||||
|
Box(
|
||||||
|
Modifier.size(22.dp),
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
) {
|
||||||
|
// Emoji altijd als basis; custom foto eroverheen indien beschikbaar
|
||||||
|
if (profileAvatarEmoji != null) {
|
||||||
|
Text(profileAvatarEmoji, fontSize = 15.sp)
|
||||||
|
}
|
||||||
if (!profileAvatarUrl.isNullOrBlank()) {
|
if (!profileAvatarUrl.isNullOrBlank()) {
|
||||||
val ctx = LocalContext.current
|
val ctx = LocalContext.current
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
|
|
@ -338,8 +346,7 @@ fun TopNavBar(
|
||||||
.clip(RoundedCornerShape(50)),
|
.clip(RoundedCornerShape(50)),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
)
|
)
|
||||||
} else if (profileAvatarEmoji != null) {
|
}
|
||||||
Text(profileAvatarEmoji, fontSize = 15.sp)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!profileLabel.isNullOrBlank()) {
|
if (!profileLabel.isNullOrBlank()) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue