mirror of
https://github.com/revanced/revanced-manager-compose.git
synced 2025-04-30 06:14:25 +02:00
feat: contributors screen (#42)
* Contributors page - https://github.com/revanced/revanced-manager-compose/issues/34 * feat: adding ContributorScreen as clickable icons like the website * feat: adding ContributorScreen - Made changes that were asked for in prev PR - Currently just waiting on a git merge to get ArrowButton in * feat: adding ContributorScreen - Made changes that were asked for in prev PR - ArrowButton is also in use * feat: adding ContributorScreen - Made changes that were asked for in prev PR - ArrowButton is also in use - Fixed other PR comment changes * Apply suggestions from code review * Remove unused string resources --------- Co-authored-by: Ax333l <main@axelen.xyz>
This commit is contained in:
parent
59a99c83a5
commit
99ddea270f
@ -13,4 +13,5 @@ val viewModelModule = module {
|
|||||||
viewModelOf(::InstallerViewModel)
|
viewModelOf(::InstallerViewModel)
|
||||||
viewModelOf(::UpdateSettingsViewModel)
|
viewModelOf(::UpdateSettingsViewModel)
|
||||||
viewModelOf(::ImportExportViewModel)
|
viewModelOf(::ImportExportViewModel)
|
||||||
|
viewModelOf(::ContributorViewModel)
|
||||||
}
|
}
|
||||||
|
@ -26,4 +26,7 @@ sealed interface SettingsDestination : Parcelable {
|
|||||||
@Parcelize
|
@Parcelize
|
||||||
object UpdateProgress : SettingsDestination
|
object UpdateProgress : SettingsDestination
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
object Contributors: SettingsDestination
|
||||||
|
|
||||||
}
|
}
|
@ -110,13 +110,18 @@ fun SettingsScreen(
|
|||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.About -> AboutSettingsScreen(
|
is SettingsDestination.About -> AboutSettingsScreen(
|
||||||
onBackClick = { navController.pop() }
|
onBackClick = { navController.pop() },
|
||||||
|
onContributorsClick = { navController.navigate(SettingsDestination.Contributors) }
|
||||||
)
|
)
|
||||||
|
|
||||||
is SettingsDestination.UpdateProgress -> UpdateProgressScreen(
|
is SettingsDestination.UpdateProgress -> UpdateProgressScreen(
|
||||||
{ navController.pop() },
|
{ navController.pop() },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
is SettingsDestination.Contributors -> ContributorScreen(
|
||||||
|
onBackClick = { navController.pop() },
|
||||||
|
)
|
||||||
|
|
||||||
is SettingsDestination.Settings -> {
|
is SettingsDestination.Settings -> {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
|
@ -22,13 +22,17 @@ import androidx.compose.ui.unit.dp
|
|||||||
import app.revanced.manager.BuildConfig
|
import app.revanced.manager.BuildConfig
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.ui.component.AppTopBar
|
import app.revanced.manager.ui.component.AppTopBar
|
||||||
|
import app.revanced.manager.ui.destination.SettingsDestination
|
||||||
import app.revanced.manager.util.openUrl
|
import app.revanced.manager.util.openUrl
|
||||||
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
||||||
|
import dev.olshevski.navigation.reimagined.NavController
|
||||||
|
import dev.olshevski.navigation.reimagined.navigate
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AboutSettingsScreen(
|
fun AboutSettingsScreen(
|
||||||
onBackClick: () -> Unit
|
onBackClick: () -> Unit,
|
||||||
|
onContributorsClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val icon = rememberDrawablePainter(context.packageManager.getApplicationIcon(context.packageName))
|
val icon = rememberDrawablePainter(context.packageManager.getApplicationIcon(context.packageName))
|
||||||
@ -52,9 +56,12 @@ fun AboutSettingsScreen(
|
|||||||
)
|
)
|
||||||
|
|
||||||
val listItems = listOf(
|
val listItems = listOf(
|
||||||
Triple(stringResource(R.string.submit_feedback), stringResource(R.string.submit_feedback_description), third = { /*TODO*/ }),
|
Triple(stringResource(R.string.submit_feedback), stringResource(R.string.submit_feedback_description),
|
||||||
Triple(stringResource(R.string.contributors), stringResource(R.string.contributors_description), third = { /*TODO*/ }),
|
third = { /*TODO*/ }),
|
||||||
Triple(stringResource(R.string.developer_options), stringResource(R.string.developer_options_description), third = { /*TODO*/ }),
|
Triple(stringResource(R.string.contributors), stringResource(R.string.contributors_description),
|
||||||
|
third = onContributorsClick),
|
||||||
|
Triple(stringResource(R.string.developer_options), stringResource(R.string.developer_options_description),
|
||||||
|
third = { /*TODO*/ }),
|
||||||
)
|
)
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
@ -0,0 +1,136 @@
|
|||||||
|
package app.revanced.manager.ui.screen.settings
|
||||||
|
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.ArrowDropDown
|
||||||
|
import androidx.compose.material.icons.outlined.ArrowDropUp
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.network.dto.ReVancedContributor
|
||||||
|
import app.revanced.manager.ui.component.AppTopBar
|
||||||
|
import app.revanced.manager.ui.component.ArrowButton
|
||||||
|
import app.revanced.manager.ui.component.LoadingIndicator
|
||||||
|
import app.revanced.manager.ui.viewmodel.ContributorViewModel
|
||||||
|
import coil.compose.AsyncImage
|
||||||
|
import org.koin.androidx.compose.getViewModel
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun ContributorScreen(
|
||||||
|
onBackClick: () -> Unit,
|
||||||
|
viewModel: ContributorViewModel = getViewModel()
|
||||||
|
) {
|
||||||
|
val repositories = viewModel.repositories
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
AppTopBar(
|
||||||
|
title = stringResource(R.string.contributors),
|
||||||
|
onBackClick = onBackClick
|
||||||
|
)
|
||||||
|
},
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxHeight()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
) {
|
||||||
|
if(repositories.isEmpty()) {
|
||||||
|
LoadingIndicator()
|
||||||
|
}
|
||||||
|
repositories.forEach {
|
||||||
|
ExpandableListCard(
|
||||||
|
title = it.name,
|
||||||
|
contributors = it.contributors
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
|
@Composable
|
||||||
|
fun ExpandableListCard(
|
||||||
|
title: String,
|
||||||
|
contributors: List<ReVancedContributor>
|
||||||
|
) {
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
Card(
|
||||||
|
shape = RoundedCornerShape(30.dp),
|
||||||
|
elevation = CardDefaults.outlinedCardElevation(),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp)
|
||||||
|
.border(
|
||||||
|
width = 2.dp,
|
||||||
|
color = MaterialTheme.colorScheme.outline,
|
||||||
|
shape = MaterialTheme.shapes.medium
|
||||||
|
),
|
||||||
|
colors = CardDefaults.outlinedCardColors(),
|
||||||
|
) {
|
||||||
|
Column() {
|
||||||
|
Row() {
|
||||||
|
ListItem(
|
||||||
|
headlineContent = {
|
||||||
|
Text(
|
||||||
|
text = processHeadlineText(title),
|
||||||
|
style = MaterialTheme.typography.titleMedium
|
||||||
|
)
|
||||||
|
},
|
||||||
|
trailingContent = {
|
||||||
|
if (contributors.isNotEmpty()) {
|
||||||
|
ArrowButton(
|
||||||
|
expanded = expanded,
|
||||||
|
onClick = { expanded = !expanded }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (expanded) {
|
||||||
|
FlowRow(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.padding(8.dp),
|
||||||
|
) {
|
||||||
|
contributors.forEach {
|
||||||
|
AsyncImage(
|
||||||
|
model = it.avatarUrl,
|
||||||
|
contentDescription = it.avatarUrl,
|
||||||
|
contentScale = ContentScale.Crop,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(16.dp)
|
||||||
|
.size(45.dp)
|
||||||
|
.clip(CircleShape)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun processHeadlineText(repositoryName: String): String {
|
||||||
|
return "Revanced " + repositoryName.replace("revanced/revanced-", "")
|
||||||
|
.replace("-", " ")
|
||||||
|
.split(" ")
|
||||||
|
.map { if (it.length > 3) it else it.uppercase() }
|
||||||
|
.joinToString(" ")
|
||||||
|
.replaceFirstChar { it.uppercase() }
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package app.revanced.manager.ui.viewmodel
|
||||||
|
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import app.revanced.manager.domain.repository.ReVancedRepository
|
||||||
|
import app.revanced.manager.network.utils.getOrNull
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class ContributorViewModel(private val repository: ReVancedRepository): ViewModel() {
|
||||||
|
val repositories = mutableStateListOf<app.revanced.manager.network.dto.ReVancedRepository>()
|
||||||
|
init {
|
||||||
|
viewModelScope.launch {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
val repos = repository.getContributors().getOrNull()?.repositories
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (repos != null) { repositories.addAll(repos) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user