|
|
|
|
@ -39,6 +39,7 @@ fun AvatarViewerScreen(group: String?, owner: Long, name: String, onClose: () ->
|
|
|
|
|
var original by remember { mutableStateOf<Bitmap?>(null) } |
|
|
|
|
var failed by remember { mutableStateOf(false) } |
|
|
|
|
var catalogFailed by remember { mutableStateOf(false) } |
|
|
|
|
var failedPreviews by remember { mutableStateOf(emptySet<String>()) } |
|
|
|
|
var retry by remember { mutableStateOf(0) } |
|
|
|
|
LaunchedEffect(account,revision) { if (account==0L) onClose() } |
|
|
|
|
LaunchedEffect(source?.first,source?.second?.avatarServer,source?.second?.avatarFile,retry) { |
|
|
|
|
@ -74,10 +75,11 @@ fun AvatarViewerScreen(group: String?, owner: Long, name: String, onClose: () ->
|
|
|
|
|
LaunchedEffect(source?.first,source?.second?.avatarServer,visible,retry) { |
|
|
|
|
val (channel,member)=source ?: return@LaunchedEffect |
|
|
|
|
previews=previews.filterKeys { it in visible } |
|
|
|
|
failedPreviews=emptySet() |
|
|
|
|
coroutineScope { visible.filter { it!=selected && it !in previews }.forEach { file -> launch { |
|
|
|
|
try { previews=previews+(file to repository.loadAvatar(channel,member.copy(avatarFile=file),false)) } |
|
|
|
|
catch (e: CancellationException) { throw e } |
|
|
|
|
catch (e: Exception) { LogManager.addLog("WARN","Avatar","Neighbor failed file=$file: ${e.message}") } |
|
|
|
|
catch (e: Exception) { failedPreviews=failedPreviews+file; LogManager.addLog("WARN","Avatar","Neighbor failed file=$file: ${e.message}") } |
|
|
|
|
} } } |
|
|
|
|
} |
|
|
|
|
fun move(delta: Int) { val next=index+delta; if (next in files.indices) selected=files[next] } |
|
|
|
|
@ -93,7 +95,7 @@ fun AvatarViewerScreen(group: String?, owner: Long, name: String, onClose: () ->
|
|
|
|
|
else if (source!=null && !failed) CircularProgressIndicator() |
|
|
|
|
else Text(stringResource(if (source==null) R.string.avatar_none else R.string.avatar_load_failed),color=Color.White) |
|
|
|
|
} |
|
|
|
|
if (failed || catalogFailed) TextButton(onClick={ retry++ },modifier=Modifier.align(Alignment.CenterHorizontally)) { |
|
|
|
|
if (failed || catalogFailed || failedPreviews.isNotEmpty()) TextButton(onClick={ retry++ },modifier=Modifier.align(Alignment.CenterHorizontally)) { |
|
|
|
|
Text(stringResource(R.string.avatar_retry)) |
|
|
|
|
} else if (original==null && source!=null) LinearProgressIndicator(Modifier.fillMaxWidth()) |
|
|
|
|
if (index>=0) Text("${index+1} / ${files.size}",color=Color.White,modifier=Modifier.align(Alignment.CenterHorizontally)) |
|
|
|
|
@ -107,6 +109,10 @@ fun AvatarViewerScreen(group: String?, owner: Long, name: String, onClose: () ->
|
|
|
|
|
.clickable(enabled=file!=null) { if (file!=null) selected=file },contentAlignment=Alignment.Center) { |
|
|
|
|
previews[file]?.let { Image(it.asImageBitmap(),contentDescription=null,contentScale=ContentScale.Crop, |
|
|
|
|
modifier=Modifier.fillMaxSize()) } |
|
|
|
|
if (file!=null && file !in previews) { |
|
|
|
|
if (file in failedPreviews) Text("!",color=Color.White) |
|
|
|
|
else CircularProgressIndicator(Modifier.size(18.dp),strokeWidth=2.dp) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
TextButton(enabled=index>=0 && index+1<files.size,onClick={ move(1) },contentPadding=PaddingValues(4.dp), |
|
|
|
|
|