mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Make "File usages" items clickable with correct URLs #6307 (#6405)
Some checks failed
Android CI / Run tests and generate APK (push) Has been cancelled
Some checks failed
Android CI / Run tests and generate APK (push) Has been cancelled
* Fix: URL generation for GlobalFileUsage in FileUsagesUiModel.kt for issue #6307 * Add clickable functionality to 'Usages on Other Wikis' in FileUsagesContainer for issue #6307 --------- Co-authored-by: Nicolas Raoul <nicolas.raoul@gmail.com>
This commit is contained in:
parent
dd96c64182
commit
e2c8f85a5b
2 changed files with 47 additions and 31 deletions
|
|
@ -1,7 +1,10 @@
|
||||||
package fr.free.nrw.commons.fileusages
|
package fr.free.nrw.commons.fileusages
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show where file is being used on Commons and oher wikis.
|
* shows where file is being used on Commons and other wikis.
|
||||||
*/
|
*/
|
||||||
data class FileUsagesUiModel(
|
data class FileUsagesUiModel(
|
||||||
val title: String,
|
val title: String,
|
||||||
|
|
@ -9,10 +12,37 @@ data class FileUsagesUiModel(
|
||||||
)
|
)
|
||||||
|
|
||||||
fun FileUsage.toUiModel(): FileUsagesUiModel {
|
fun FileUsage.toUiModel(): FileUsagesUiModel {
|
||||||
return FileUsagesUiModel(title = title, link = "https://commons.wikimedia.org/wiki/$title")
|
return FileUsagesUiModel(
|
||||||
|
title = title,
|
||||||
|
link = "https://commons.wikimedia.org/wiki/${Uri.encode(title.replace(" ", "_"))}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun GlobalFileUsage.toUiModel(): FileUsagesUiModel {
|
fun GlobalFileUsage.toUiModel(): FileUsagesUiModel {
|
||||||
// link is associated with sub items under wiki group (which is not used ATM)
|
Timber.d("GlobalFileUsage: wiki=%s, title=%s", wiki, title)
|
||||||
return FileUsagesUiModel(title = wiki, link = null)
|
|
||||||
}
|
// handles the empty or invalid wiki/title
|
||||||
|
if (wiki.isEmpty() || title.isEmpty()) {
|
||||||
|
Timber.w("Invalid GlobalFileUsage: wiki=%s, title=%s", wiki, title)
|
||||||
|
return FileUsagesUiModel(title = title, link = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// determines the domain
|
||||||
|
val domain = when {
|
||||||
|
wiki.contains(".") -> wiki // Already a full domain like "en.wikipedia.org"
|
||||||
|
wiki == "commonswiki" -> "commons.wikimedia.org"
|
||||||
|
wiki.endsWith("wiki") -> {
|
||||||
|
val code = wiki.removeSuffix("wiki")
|
||||||
|
"$code.wikipedia.org"
|
||||||
|
}
|
||||||
|
else -> "$wiki.wikipedia.org" // fallback for codes like "en"
|
||||||
|
}
|
||||||
|
|
||||||
|
val normalizedTitle = Uri.encode(title.replace(" ", "_"))
|
||||||
|
|
||||||
|
// construct full URL
|
||||||
|
val url = "https://$domain/wiki/$normalizedTitle"
|
||||||
|
Timber.d("Generated URL for GlobalFileUsage: %s", url)
|
||||||
|
|
||||||
|
return FileUsagesUiModel(title = title, link = url)
|
||||||
|
}
|
||||||
|
|
@ -2128,22 +2128,17 @@ fun FileUsagesContainer(
|
||||||
val uriHandle = LocalUriHandler.current
|
val uriHandle = LocalUriHandler.current
|
||||||
|
|
||||||
Column(modifier = modifier) {
|
Column(modifier = modifier) {
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.usages_on_commons_heading),
|
text = stringResource(R.string.usages_on_commons_heading),
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
style = MaterialTheme.typography.titleSmall
|
style = MaterialTheme.typography.titleSmall
|
||||||
)
|
)
|
||||||
|
IconButton(onClick = { isCommonsListExpanded = !isCommonsListExpanded }) {
|
||||||
IconButton(onClick = {
|
|
||||||
isCommonsListExpanded = !isCommonsListExpanded
|
|
||||||
}) {
|
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = if (isCommonsListExpanded) Icons.Default.KeyboardArrowUp
|
imageVector = if (isCommonsListExpanded) Icons.Default.KeyboardArrowUp
|
||||||
else Icons.Default.KeyboardArrowDown,
|
else Icons.Default.KeyboardArrowDown,
|
||||||
|
|
@ -2157,11 +2152,8 @@ fun FileUsagesContainer(
|
||||||
MediaDetailViewModel.FileUsagesContainerState.Loading -> {
|
MediaDetailViewModel.FileUsagesContainerState.Loading -> {
|
||||||
LinearProgressIndicator()
|
LinearProgressIndicator()
|
||||||
}
|
}
|
||||||
|
|
||||||
is MediaDetailViewModel.FileUsagesContainerState.Success -> {
|
is MediaDetailViewModel.FileUsagesContainerState.Success -> {
|
||||||
|
|
||||||
val data = commonsContainerState.data
|
val data = commonsContainerState.data
|
||||||
|
|
||||||
if (data.isNullOrEmpty()) {
|
if (data.isNullOrEmpty()) {
|
||||||
ListItem(headlineContent = {
|
ListItem(headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -2181,7 +2173,7 @@ fun FileUsagesContainer(
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.clickable {
|
modifier = Modifier.clickable {
|
||||||
uriHandle.openUri(usage.link!!)
|
usage.link?.let { uriHandle.openUri(it) }
|
||||||
},
|
},
|
||||||
text = usage.title,
|
text = usage.title,
|
||||||
style = MaterialTheme.typography.titleSmall.copy(
|
style = MaterialTheme.typography.titleSmall.copy(
|
||||||
|
|
@ -2189,11 +2181,11 @@ fun FileUsagesContainer(
|
||||||
textDecoration = TextDecoration.Underline
|
textDecoration = TextDecoration.Underline
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is MediaDetailViewModel.FileUsagesContainerState.Error -> {
|
is MediaDetailViewModel.FileUsagesContainerState.Error -> {
|
||||||
ListItem(headlineContent = {
|
ListItem(headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -2203,12 +2195,10 @@ fun FileUsagesContainer(
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaDetailViewModel.FileUsagesContainerState.Initial -> {}
|
MediaDetailViewModel.FileUsagesContainerState.Initial -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
|
@ -2219,10 +2209,7 @@ fun FileUsagesContainer(
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
style = MaterialTheme.typography.titleSmall
|
style = MaterialTheme.typography.titleSmall
|
||||||
)
|
)
|
||||||
|
IconButton(onClick = { isOtherWikisListExpanded = !isOtherWikisListExpanded }) {
|
||||||
IconButton(onClick = {
|
|
||||||
isOtherWikisListExpanded = !isOtherWikisListExpanded
|
|
||||||
}) {
|
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = if (isOtherWikisListExpanded) Icons.Default.KeyboardArrowUp
|
imageVector = if (isOtherWikisListExpanded) Icons.Default.KeyboardArrowUp
|
||||||
else Icons.Default.KeyboardArrowDown,
|
else Icons.Default.KeyboardArrowDown,
|
||||||
|
|
@ -2236,11 +2223,8 @@ fun FileUsagesContainer(
|
||||||
MediaDetailViewModel.FileUsagesContainerState.Loading -> {
|
MediaDetailViewModel.FileUsagesContainerState.Loading -> {
|
||||||
LinearProgressIndicator()
|
LinearProgressIndicator()
|
||||||
}
|
}
|
||||||
|
|
||||||
is MediaDetailViewModel.FileUsagesContainerState.Success -> {
|
is MediaDetailViewModel.FileUsagesContainerState.Success -> {
|
||||||
|
|
||||||
val data = globalContainerState.data
|
val data = globalContainerState.data
|
||||||
|
|
||||||
if (data.isNullOrEmpty()) {
|
if (data.isNullOrEmpty()) {
|
||||||
ListItem(headlineContent = {
|
ListItem(headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -2259,16 +2243,20 @@ fun FileUsagesContainer(
|
||||||
},
|
},
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
|
modifier = Modifier.clickable {
|
||||||
|
usage.link?.let { uriHandle.openUri(it) }
|
||||||
|
},
|
||||||
text = usage.title,
|
text = usage.title,
|
||||||
style = MaterialTheme.typography.titleSmall.copy(
|
style = MaterialTheme.typography.titleSmall.copy(
|
||||||
|
color = Color(0xFF5A6AEC),
|
||||||
textDecoration = TextDecoration.Underline
|
textDecoration = TextDecoration.Underline
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is MediaDetailViewModel.FileUsagesContainerState.Error -> {
|
is MediaDetailViewModel.FileUsagesContainerState.Error -> {
|
||||||
ListItem(headlineContent = {
|
ListItem(headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -2278,10 +2266,8 @@ fun FileUsagesContainer(
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaDetailViewModel.FileUsagesContainerState.Initial -> {}
|
MediaDetailViewModel.FileUsagesContainerState.Initial -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue