feat: contributors activity and create SettingsLazyGroup

This commit is contained in:
FunkyMuse 2023-08-07 17:06:11 +02:00
parent 0a87df80f9
commit bafce3b065
11 changed files with 487 additions and 335 deletions

View file

@ -1,121 +1,77 @@
package com.simplemobiletools.commons.activities
import android.os.Bundle
import android.text.Html
import android.text.method.LinkMovementMethod
import android.view.LayoutInflater
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.remember
import androidx.core.view.WindowCompat
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.databinding.ActivityContributorsBinding
import com.simplemobiletools.commons.databinding.ItemLanguageContributorBinding
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.APP_ICON_IDS
import com.simplemobiletools.commons.helpers.APP_LAUNCHER_NAME
import com.simplemobiletools.commons.helpers.NavigationIcon
import com.simplemobiletools.commons.compose.extensions.TransparentSystemBars
import com.simplemobiletools.commons.compose.screens.ContributorsScreen
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.models.LanguageContributor
import kotlinx.collections.immutable.toImmutableList
class ContributorsActivity : BaseSimpleActivity() {
override fun getAppIconIDs() = intent.getIntegerArrayListExtra(APP_ICON_IDS) ?: ArrayList()
override fun getAppLauncherName() = intent.getStringExtra(APP_LAUNCHER_NAME) ?: ""
private val binding by viewBinding(ActivityContributorsBinding::inflate)
class ContributorsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true
super.onCreate(savedInstanceState)
setContentView(binding.root)
updateTextColors(binding.contributorsHolder)
updateMaterialActivityViews(binding.contributorsCoordinator, binding.contributorsHolder, useTransparentNavigation = true, useTopSearchMenu = false)
setupMaterialScrollListener(binding.contributorsNestedScrollview, binding.contributorsToolbar)
val primaryColor = getProperPrimaryColor()
binding.contributorsDevelopmentLabel.setTextColor(primaryColor)
binding.contributorsTranslationLabel.setTextColor(primaryColor)
val inflater = LayoutInflater.from(this)
val languages = arrayListOf<LanguageContributor>()
languages.addAll(
arrayListOf(
LanguageContributor(R.drawable.ic_flag_arabic_vector, R.string.translation_arabic, R.string.translators_arabic),
LanguageContributor(R.drawable.ic_flag_azerbaijani_vector, R.string.translation_azerbaijani, R.string.translators_azerbaijani),
LanguageContributor(R.drawable.ic_flag_bengali_vector, R.string.translation_bengali, R.string.translators_bengali),
LanguageContributor(R.drawable.ic_flag_catalan_vector, R.string.translation_catalan, R.string.translators_catalan),
LanguageContributor(R.drawable.ic_flag_czech_vector, R.string.translation_czech, R.string.translators_czech),
LanguageContributor(R.drawable.ic_flag_welsh_vector, R.string.translation_welsh, R.string.translators_welsh),
LanguageContributor(R.drawable.ic_flag_danish_vector, R.string.translation_danish, R.string.translators_danish),
LanguageContributor(R.drawable.ic_flag_german_vector, R.string.translation_german, R.string.translators_german),
LanguageContributor(R.drawable.ic_flag_greek_vector, R.string.translation_greek, R.string.translators_greek),
LanguageContributor(R.drawable.ic_flag_spanish_vector, R.string.translation_spanish, R.string.translators_spanish),
LanguageContributor(R.drawable.ic_flag_basque_vector, R.string.translation_basque, R.string.translators_basque),
LanguageContributor(R.drawable.ic_flag_persian_vector, R.string.translation_persian, R.string.translators_persian),
LanguageContributor(R.drawable.ic_flag_finnish_vector, R.string.translation_finnish, R.string.translators_finnish),
LanguageContributor(R.drawable.ic_flag_french_vector, R.string.translation_french, R.string.translators_french),
LanguageContributor(R.drawable.ic_flag_galician_vector, R.string.translation_galician, R.string.translators_galician),
LanguageContributor(R.drawable.ic_flag_hindi_vector, R.string.translation_hindi, R.string.translators_hindi),
LanguageContributor(R.drawable.ic_flag_croatian_vector, R.string.translation_croatian, R.string.translators_croatian),
LanguageContributor(R.drawable.ic_flag_hungarian_vector, R.string.translation_hungarian, R.string.translators_hungarian),
LanguageContributor(R.drawable.ic_flag_indonesian_vector, R.string.translation_indonesian, R.string.translators_indonesian),
LanguageContributor(R.drawable.ic_flag_italian_vector, R.string.translation_italian, R.string.translators_italian),
LanguageContributor(R.drawable.ic_flag_hebrew_vector, R.string.translation_hebrew, R.string.translators_hebrew),
LanguageContributor(R.drawable.ic_flag_japanese_vector, R.string.translation_japanese, R.string.translators_japanese),
LanguageContributor(R.drawable.ic_flag_korean_vector, R.string.translation_korean, R.string.translators_korean),
LanguageContributor(R.drawable.ic_flag_lithuanian_vector, R.string.translation_lithuanian, R.string.translators_lithuanian),
LanguageContributor(R.drawable.ic_flag_nepali_vector, R.string.translation_nepali, R.string.translators_nepali),
LanguageContributor(R.drawable.ic_flag_norwegian_vector, R.string.translation_norwegian, R.string.translators_norwegian),
LanguageContributor(R.drawable.ic_flag_dutch_vector, R.string.translation_dutch, R.string.translators_dutch),
LanguageContributor(R.drawable.ic_flag_polish_vector, R.string.translation_polish, R.string.translators_polish),
LanguageContributor(R.drawable.ic_flag_portuguese_vector, R.string.translation_portuguese, R.string.translators_portuguese),
LanguageContributor(R.drawable.ic_flag_romanian_vector, R.string.translation_romanian, R.string.translators_romanian),
LanguageContributor(R.drawable.ic_flag_russian_vector, R.string.translation_russian, R.string.translators_russian),
LanguageContributor(R.drawable.ic_flag_slovak_vector, R.string.translation_slovak, R.string.translators_slovak),
LanguageContributor(R.drawable.ic_flag_slovenian_vector, R.string.translation_slovenian, R.string.translators_slovenian),
LanguageContributor(R.drawable.ic_flag_swedish_vector, R.string.translation_swedish, R.string.translators_swedish),
LanguageContributor(R.drawable.ic_flag_tamil_vector, R.string.translation_tamil, R.string.translators_tamil),
LanguageContributor(R.drawable.ic_flag_turkish_vector, R.string.translation_turkish, R.string.translators_turkish),
LanguageContributor(R.drawable.ic_flag_ukrainian_vector, R.string.translation_ukrainian, R.string.translators_ukrainian),
LanguageContributor(R.drawable.ic_flag_chinese_hk_vector, R.string.translation_chinese_hk, R.string.translators_chinese_hk),
LanguageContributor(R.drawable.ic_flag_chinese_cn_vector, R.string.translation_chinese_cn, R.string.translators_chinese_cn),
LanguageContributor(R.drawable.ic_flag_chinese_tw_vector, R.string.translation_chinese_tw, R.string.translators_chinese_tw)
)
)
val textColor = getProperTextColor()
languages.forEach { language ->
ItemLanguageContributorBinding.inflate(inflater).apply {
languageIcon.setImageDrawable(getDrawable(language.iconId))
languageLabel.apply {
text = getString(language.labelId)
setTextColor(textColor)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
TransparentSystemBars()
AppThemeSurface {
val contributors = remember {
listOf(
LanguageContributor(R.drawable.ic_flag_arabic_vector, R.string.translation_arabic, R.string.translators_arabic),
LanguageContributor(R.drawable.ic_flag_azerbaijani_vector, R.string.translation_azerbaijani, R.string.translators_azerbaijani),
LanguageContributor(R.drawable.ic_flag_bengali_vector, R.string.translation_bengali, R.string.translators_bengali),
LanguageContributor(R.drawable.ic_flag_catalan_vector, R.string.translation_catalan, R.string.translators_catalan),
LanguageContributor(R.drawable.ic_flag_czech_vector, R.string.translation_czech, R.string.translators_czech),
LanguageContributor(R.drawable.ic_flag_welsh_vector, R.string.translation_welsh, R.string.translators_welsh),
LanguageContributor(R.drawable.ic_flag_danish_vector, R.string.translation_danish, R.string.translators_danish),
LanguageContributor(R.drawable.ic_flag_german_vector, R.string.translation_german, R.string.translators_german),
LanguageContributor(R.drawable.ic_flag_greek_vector, R.string.translation_greek, R.string.translators_greek),
LanguageContributor(R.drawable.ic_flag_spanish_vector, R.string.translation_spanish, R.string.translators_spanish),
LanguageContributor(R.drawable.ic_flag_basque_vector, R.string.translation_basque, R.string.translators_basque),
LanguageContributor(R.drawable.ic_flag_persian_vector, R.string.translation_persian, R.string.translators_persian),
LanguageContributor(R.drawable.ic_flag_finnish_vector, R.string.translation_finnish, R.string.translators_finnish),
LanguageContributor(R.drawable.ic_flag_french_vector, R.string.translation_french, R.string.translators_french),
LanguageContributor(R.drawable.ic_flag_galician_vector, R.string.translation_galician, R.string.translators_galician),
LanguageContributor(R.drawable.ic_flag_hindi_vector, R.string.translation_hindi, R.string.translators_hindi),
LanguageContributor(R.drawable.ic_flag_croatian_vector, R.string.translation_croatian, R.string.translators_croatian),
LanguageContributor(R.drawable.ic_flag_hungarian_vector, R.string.translation_hungarian, R.string.translators_hungarian),
LanguageContributor(R.drawable.ic_flag_indonesian_vector, R.string.translation_indonesian, R.string.translators_indonesian),
LanguageContributor(R.drawable.ic_flag_italian_vector, R.string.translation_italian, R.string.translators_italian),
LanguageContributor(R.drawable.ic_flag_hebrew_vector, R.string.translation_hebrew, R.string.translators_hebrew),
LanguageContributor(R.drawable.ic_flag_japanese_vector, R.string.translation_japanese, R.string.translators_japanese),
LanguageContributor(R.drawable.ic_flag_korean_vector, R.string.translation_korean, R.string.translators_korean),
LanguageContributor(R.drawable.ic_flag_lithuanian_vector, R.string.translation_lithuanian, R.string.translators_lithuanian),
LanguageContributor(R.drawable.ic_flag_nepali_vector, R.string.translation_nepali, R.string.translators_nepali),
LanguageContributor(R.drawable.ic_flag_norwegian_vector, R.string.translation_norwegian, R.string.translators_norwegian),
LanguageContributor(R.drawable.ic_flag_dutch_vector, R.string.translation_dutch, R.string.translators_dutch),
LanguageContributor(R.drawable.ic_flag_polish_vector, R.string.translation_polish, R.string.translators_polish),
LanguageContributor(R.drawable.ic_flag_portuguese_vector, R.string.translation_portuguese, R.string.translators_portuguese),
LanguageContributor(R.drawable.ic_flag_romanian_vector, R.string.translation_romanian, R.string.translators_romanian),
LanguageContributor(R.drawable.ic_flag_russian_vector, R.string.translation_russian, R.string.translators_russian),
LanguageContributor(R.drawable.ic_flag_slovak_vector, R.string.translation_slovak, R.string.translators_slovak),
LanguageContributor(R.drawable.ic_flag_slovenian_vector, R.string.translation_slovenian, R.string.translators_slovenian),
LanguageContributor(R.drawable.ic_flag_swedish_vector, R.string.translation_swedish, R.string.translators_swedish),
LanguageContributor(R.drawable.ic_flag_tamil_vector, R.string.translation_tamil, R.string.translators_tamil),
LanguageContributor(R.drawable.ic_flag_turkish_vector, R.string.translation_turkish, R.string.translators_turkish),
LanguageContributor(R.drawable.ic_flag_ukrainian_vector, R.string.translation_ukrainian, R.string.translators_ukrainian),
LanguageContributor(R.drawable.ic_flag_chinese_hk_vector, R.string.translation_chinese_hk, R.string.translators_chinese_hk),
LanguageContributor(R.drawable.ic_flag_chinese_cn_vector, R.string.translation_chinese_cn, R.string.translators_chinese_cn),
LanguageContributor(R.drawable.ic_flag_chinese_tw_vector, R.string.translation_chinese_tw, R.string.translators_chinese_tw)
).toImmutableList()
}
languageContributors.apply {
text = getString(language.contributorsId)
setTextColor(textColor)
val showContributorsLabel = remember {
!resources.getBoolean(R.bool.hide_all_external_links)
}
binding.contributorsLanguagesHolder.addView(root)
ContributorsScreen(
goBack = ::finish,
showContributorsLabel = showContributorsLabel,
contributors = contributors
)
}
}
binding.contributorsLabel.apply {
setTextColor(textColor)
text = Html.fromHtml(getString(R.string.contributors_label))
setLinkTextColor(primaryColor)
movementMethod = LinkMovementMethod.getInstance()
removeUnderlines()
}
binding.contributorsDevelopmentIcon.applyColorFilter(textColor)
binding.contributorsFooterIcon.applyColorFilter(textColor)
if (resources.getBoolean(R.bool.hide_all_external_links)) {
binding.contributorsFooterLayout.beGone()
}
}
override fun onResume() {
super.onResume()
setupToolbar(binding.contributorsToolbar, NavigationIcon.Arrow)
}
}

View file

@ -32,31 +32,11 @@ internal fun AboutScreen(
helpUsSection()
socialSection()
otherSection()
MadeWithLove()
SettingsListItem(text = stringResource(id = R.string.about_footer))
Spacer(modifier = Modifier.padding(bottom = 8.dp))
}
}
@Composable
private fun MadeWithLove() {
ListItem(
headlineContent = {
Text(
text = stringResource(id = R.string.about_footer),
modifier = Modifier
.fillMaxWidth()
)
},
leadingContent = {
Box(
modifier = Modifier
.size(48.dp)
.padding(8.dp),
)
}
)
}
@Composable
internal fun HelpUsSection(
onRateUsClick: () -> Unit,

View file

@ -0,0 +1,148 @@
package com.simplemobiletools.commons.compose.screens
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.compose.extensions.MyDevices
import com.simplemobiletools.commons.compose.settings.SettingsGroupTitle
import com.simplemobiletools.commons.compose.settings.SettingsHorizontalDivider
import com.simplemobiletools.commons.compose.settings.SettingsListItem
import com.simplemobiletools.commons.compose.settings.SettingsTitleTextComponent
import com.simplemobiletools.commons.compose.settings.scaffold.SettingsLazyScaffold
import com.simplemobiletools.commons.compose.theme.AppThemeSurface
import com.simplemobiletools.commons.models.LanguageContributor
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
private val startingPadding = Modifier.padding(start = 62.dp)
@Composable
internal fun ContributorsScreen(
goBack: () -> Unit,
showContributorsLabel: Boolean,
contributors: ImmutableList<LanguageContributor>
) {
SettingsLazyScaffold(
title = { scrolledColor ->
Text(
text = stringResource(id = R.string.contributors),
modifier = Modifier
.padding(start = 28.dp)
.fillMaxWidth(),
color = scrolledColor
)
},
goBack = goBack,
lazyContent = {
item {
SettingsGroupTitle {
SettingsTitleTextComponent(text = stringResource(id = R.string.development), modifier = startingPadding)
}
}
item {
SettingsListItem(
text = stringResource(id = R.string.contributors_developers),
icon = R.drawable.ic_code_vector,
tint = MaterialTheme.colorScheme.onSurface
)
}
item {
Spacer(modifier = Modifier.padding(vertical = 8.dp))
}
item {
SettingsHorizontalDivider()
}
item {
SettingsGroupTitle {
SettingsTitleTextComponent(text = stringResource(id = R.string.translation), modifier = startingPadding)
}
}
items(contributors, key = { it.contributorsId.plus(it.iconId).plus(it.labelId) }) {
ContributorItem(
languageContributor = it
)
}
if (showContributorsLabel) {
item {
SettingsListItem(
icon = R.drawable.ic_heart_vector,
text = {
val source = stringResource(id = R.string.contributors_label)
LinkifyText {
stringFromHTML(source)
}
},
tint = MaterialTheme.colorScheme.onSurface
)
}
item {
Spacer(modifier = Modifier.padding(bottom = 8.dp))
}
}
})
}
@Composable
private fun ContributorItem(
modifier: Modifier = Modifier,
languageContributor: LanguageContributor
) {
ListItem(
headlineContent = {
Text(
text = stringResource(id = languageContributor.labelId),
modifier = Modifier
.fillMaxWidth()
.then(modifier)
)
},
leadingContent = {
val imageSize = Modifier
.size(48.dp)
.padding(8.dp)
Image(
modifier = imageSize,
painter = painterResource(id = languageContributor.iconId),
contentDescription = stringResource(id = languageContributor.contributorsId),
)
},
modifier = Modifier
.fillMaxWidth(),
supportingContent = {
Text(
text = stringResource(id = languageContributor.contributorsId),
modifier = Modifier
.fillMaxWidth()
)
}
)
}
@Composable
@MyDevices
private fun ContributorsScreenPreview() {
AppThemeSurface {
ContributorsScreen(
goBack = {},
contributors = listOf(
LanguageContributor(R.drawable.ic_flag_arabic_vector, R.string.translation_arabic, R.string.translators_arabic),
LanguageContributor(R.drawable.ic_flag_azerbaijani_vector, R.string.translation_azerbaijani, R.string.translators_azerbaijani),
LanguageContributor(R.drawable.ic_flag_bengali_vector, R.string.translation_bengali, R.string.translators_bengali),
LanguageContributor(R.drawable.ic_flag_catalan_vector, R.string.translation_catalan, R.string.translators_catalan),
).toImmutableList(),
showContributorsLabel = true
)
}
}

View file

@ -53,14 +53,14 @@ internal fun FAQScreen(
.fillMaxWidth()
.padding(bottom = 6.dp),
color = MaterialTheme.colorScheme.primary,
lineHeight = 18.sp,
fontSize = 18.sp,
lineHeight = 16.sp,
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
},
supportingContent = {
if (faqItem.text is Int) {
val text = fromHtml(stringResource(id = faqItem.text))
val text = stringFromHTML(stringResource(id = faqItem.text))
LinkifyText(
text = { text },
modifier = Modifier.fillMaxWidth(),
@ -86,7 +86,7 @@ internal fun FAQScreen(
}
@Suppress("deprecation")
private fun fromHtml(source: String): Spanned {
fun stringFromHTML(source: String): Spanned {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY)
} else {
@ -95,7 +95,7 @@ private fun fromHtml(source: String): Spanned {
}
@Composable
private fun LinkifyText(modifier: Modifier = Modifier, fontSize: TextUnit, text: () -> Spanned) {
fun LinkifyText(modifier: Modifier = Modifier, fontSize: TextUnit = 14.sp, text: () -> Spanned) {
val context = LocalContext.current
val customLinkifyTextView = remember {
TextView(context)

View file

@ -0,0 +1,68 @@
package com.simplemobiletools.commons.compose.settings
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.ScrollableDefaults
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.simplemobiletools.commons.compose.extensions.MyDevices
@Composable
fun SettingsLazyGroup(
modifier: Modifier = Modifier,
title: @Composable (() -> Unit)? = null,
state: LazyListState = rememberLazyListState(),
contentPadding: PaddingValues = PaddingValues(0.dp),
reverseLayout: Boolean = false,
verticalArrangement: Arrangement.Vertical =
if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
userScrollEnabled: Boolean = true,
content: LazyListScope.() -> Unit
) {
LazyColumn(
modifier,
state = state,
contentPadding = contentPadding,
reverseLayout = reverseLayout,
verticalArrangement = verticalArrangement,
horizontalAlignment = horizontalAlignment,
flingBehavior = flingBehavior,
userScrollEnabled = userScrollEnabled
) {
if (title != null) {
item(key = "SettingsLazyGroupTitle") { SettingsGroupTitle(title = title) }
}
content()
}
}
@MyDevices
@Composable
private fun SettingsLazyGroupPreview() {
MaterialTheme {
SettingsLazyGroup(
title = { Text(text = "Title") }
) {
item {
Box(
modifier = Modifier
.height(64.dp)
.fillMaxWidth(),
contentAlignment = Alignment.Center,
) {
Text(text = "Settings group")
}
}
}
}
}

View file

@ -3,6 +3,7 @@ package com.simplemobiletools.commons.compose.settings
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@ -25,7 +26,7 @@ import com.simplemobiletools.commons.compose.theme.AppThemeSurface
fun SettingsListItem(
modifier: Modifier = Modifier,
text: String,
@DrawableRes icon: Int,
@DrawableRes icon: Int? = null,
isImage: Boolean = false,
click: (() -> Unit)? = null,
tint: Color? = null
@ -40,38 +41,39 @@ fun SettingsListItem(
)
},
leadingContent = {
val imageSize = Modifier.size(48.dp)
val imageSize = Modifier
.size(48.dp)
.padding(8.dp)
if (isImage) {
if (tint != null) {
Image(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = text,
colorFilter = ColorFilter.tint(tint)
)
} else {
Image(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = text,
)
}
} else {
if (tint != null) {
Icon(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = text,
tint = tint
)
} else {
Icon(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = text,
)
}
when {
icon != null && isImage && tint != null -> Image(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = text,
colorFilter = ColorFilter.tint(tint)
)
icon != null && isImage && tint == null -> Image(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = text,
)
icon != null && !isImage && tint == null -> Icon(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = text,
)
icon != null && !isImage && tint != null -> Icon(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = text,
tint = tint
)
else -> Box(
modifier = imageSize,
)
}
},
modifier = Modifier
@ -80,6 +82,63 @@ fun SettingsListItem(
)
}
@Composable
fun SettingsListItem(
modifier: Modifier = Modifier,
text: @Composable () -> Unit,
@DrawableRes icon: Int? = null,
isImage: Boolean = false,
click: (() -> Unit)? = null,
tint: Color? = null
) {
ListItem(
headlineContent = {
text()
},
leadingContent = {
val imageSize = Modifier
.size(48.dp)
.padding(8.dp)
when {
icon != null && isImage && tint != null -> Image(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = null,
colorFilter = ColorFilter.tint(tint)
)
icon != null && isImage && tint == null -> Image(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = null,
)
icon != null && !isImage && tint == null -> Icon(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = null,
)
icon != null && !isImage && tint != null -> Icon(
modifier = imageSize,
painter = painterResource(id = icon),
contentDescription = null,
tint = tint
)
else -> Box(
modifier = imageSize,
)
}
},
modifier = modifier
.fillMaxWidth()
.clickable(enabled = click != null) { click?.invoke() }
)
}
@MyDevices
@Composable
private fun SettingsListItem(@PreviewParameter(BooleanPreviewParameterProvider::class) isImage: Boolean) {

View file

@ -17,6 +17,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
@ -81,6 +82,65 @@ fun SettingsLazyScaffold(
}
}
@Composable
fun SettingsLazyScaffold(
modifier: Modifier = Modifier,
title: @Composable (scrolledColor: Color) -> Unit,
goBack: () -> Unit,
state: LazyListState = rememberLazyListState(),
contentPadding: PaddingValues = PaddingValues(0.dp),
reverseLayout: Boolean = false,
verticalArrangement: Arrangement.Vertical =
if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
userScrollEnabled: Boolean = true,
lazyContent: LazyListScope.() -> Unit
) {
val context = LocalContext.current
val (statusBarColor, contrastColor) = statusBarAndContrastColor(context)
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val (colorTransitionFraction, scrolledColor) = transitionFractionAndScrolledColor(scrollBehavior, contrastColor)
SystemUISettingsScaffoldStatusBarColor(scrolledColor)
val navigationIconInteractionSource = remember { MutableInteractionSource() }
Scaffold(
modifier = modifier
.fillMaxSize()
.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
SettingsScaffoldTopBar(
title = title,
scrolledColor = scrolledColor,
navigationIconInteractionSource = navigationIconInteractionSource,
goBack = goBack,
scrollBehavior = scrollBehavior,
statusBarColor = statusBarColor,
colorTransitionFraction = colorTransitionFraction,
contrastColor = contrastColor
)
}
) { paddingValues ->
ScreenBoxSettingsScaffold(paddingValues) {
LazyColumn(
modifier = Modifier
.matchParentSize(),
state = state,
contentPadding = contentPadding,
reverseLayout = reverseLayout,
verticalArrangement = verticalArrangement,
horizontalAlignment = horizontalAlignment,
flingBehavior = flingBehavior,
userScrollEnabled = userScrollEnabled
) {
lazyContent()
}
}
}
}
@MyDevices
@Composable
private fun SettingsLazyScaffoldPreview() {

View file

@ -71,6 +71,51 @@ internal fun SettingsScaffoldTopBar(
)
}
@Composable
internal fun SettingsScaffoldTopBar(
title: @Composable (scrolledColor : Color) -> Unit,
scrolledColor: Color,
navigationIconInteractionSource: MutableInteractionSource,
scrollBehavior: TopAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()),
statusBarColor: Int,
colorTransitionFraction: Float,
contrastColor: Color,
goBack: () -> Unit,
) {
TopAppBar(
title = {
title(scrolledColor)
},
navigationIcon = {
Box(
Modifier
.padding(start = 8.dp)
.clip(RoundedCornerShape(50))
.clickable(
navigationIconInteractionSource, rememberRipple(
color = MaterialTheme.colorScheme.onSurface,
bounded = true
)
) { goBack() }
) {
Icon(
imageVector = Icons.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back),
tint = scrolledColor,
modifier = Modifier.padding(4.dp)
)
}
},
scrollBehavior = scrollBehavior,
colors = TopAppBarDefaults.largeTopAppBarColors(
scrolledContainerColor = Color(statusBarColor),
containerColor = if (colorTransitionFraction == 1f) contrastColor else MaterialTheme.colorScheme.surface,
navigationIconContentColor = if (colorTransitionFraction == 1f) contrastColor else MaterialTheme.colorScheme.surface
),
)
}
@Composable
@MyDevices
private fun SettingsScaffoldTopBarPreview() {

View file

@ -1,3 +1,8 @@
package com.simplemobiletools.commons.models
data class LanguageContributor(val iconId: Int, val labelId: Int, val contributorsId: Int)
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.runtime.Immutable
@Immutable
data class LanguageContributor(@DrawableRes val iconId: Int, @StringRes val labelId: Int, @StringRes val contributorsId: Int)

View file

@ -1,125 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/contributors_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/contributors_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/color_primary"
app:title="@string/contributors"
app:titleTextAppearance="@style/AppTheme.ActionBar.TitleTextStyle" />
<androidx.core.widget.NestedScrollView
android:id="@+id/contributors_nested_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:fillViewport="true"
android:scrollbars="none">
<LinearLayout
android:id="@+id/contributors_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/development_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/contributors_development_label"
style="@style/MaterialSectionLabelStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/development"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/contributors_development_icon"
android:layout_width="@dimen/normal_icon_size"
android:layout_height="@dimen/normal_icon_size"
android:layout_marginStart="@dimen/medium_margin"
android:layout_marginTop="@dimen/medium_margin"
android:contentDescription="@null"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_code_vector"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contributors_development_label" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contributors_development"
style="@style/MaterialListTextStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/big_margin"
android:text="@string/contributors_developers"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/contributors_development_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/contributors_divider"
android:layout_width="match_parent"
android:layout_height="@dimen/divider_height"
android:background="@color/divider_grey"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/development_layout" />
<TextView
android:id="@+id/contributors_translation_label"
style="@style/MaterialSectionLabelStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/translation"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contributors_divider" />
<LinearLayout
android:id="@+id/contributors_languages_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/medium_margin"
android:orientation="vertical" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/contributors_footer_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/small_margin"
android:paddingBottom="@dimen/activity_margin">
<ImageView
android:id="@+id/contributors_footer_icon"
android:layout_width="@dimen/normal_icon_size"
android:layout_height="@dimen/normal_icon_size"
android:layout_marginStart="@dimen/medium_margin"
android:contentDescription="@null"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_heart_vector"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/contributors_label"
style="@style/MaterialListTextStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/contributors_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/contributors_footer_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/contributor_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/bigger_margin">
<ImageView
android:id="@+id/language_icon"
android:layout_width="@dimen/normal_icon_size"
android:layout_height="@dimen/normal_icon_size"
android:layout_marginStart="@dimen/medium_margin"
android:contentDescription="@null"
android:padding="@dimen/medium_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_flag_arabic_vector" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/language_label"
style="@style/MaterialListTextStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/language_icon"
android:layout_toEndOf="@+id/language_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/language_icon"
tools:text="@string/translation_arabic" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/language_contributors"
style="@style/MaterialListTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="0.95"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/language_label"
tools:text="@string/translators_arabic" />
</androidx.constraintlayout.widget.ConstraintLayout>