Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ internal fun SettingsScreen(
SettingsCategory(stringResource(R.string.general_title)) {
// Upload Media
SettingsSwitchItem(
icon = R.drawable.ic_cloud_upload,
title = stringResource(R.string.upload_media_title),
summary = stringResource(R.string.over_wifi_summary),
checked = settings.shouldUploadPhotosOnWifiOnly,
Expand All @@ -107,6 +108,7 @@ internal fun SettingsScreen(

// Language
SettingsSelectItem(
icon = R.drawable.ic_language,
title = stringResource(R.string.select_language_title),
entriesResId = R.array.language_entries,
entryValues = R.array.language_entry_values,
Expand All @@ -116,6 +118,7 @@ internal fun SettingsScreen(

// Measurement Units
SettingsSelectItem(
icon = R.drawable.ic_measurement,
title = stringResource(R.string.select_length_title),
entriesResId = R.array.length_entries,
entryValues = R.array.length_entry_values,
Expand All @@ -129,6 +132,7 @@ internal fun SettingsScreen(
// Help Section
SettingsCategory(stringResource(R.string.help_title)) {
SettingsItem(
icon = R.drawable.ic_open_in_new,
title = stringResource(R.string.visit_website_title),
summary = stringResource(R.string.ground_website),
onClick = onVisitWebsiteClick,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,59 @@
*/
package org.groundplatform.android.ui.settings.components

import androidx.annotation.DrawableRes
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
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.res.painterResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.groundplatform.android.R
import org.groundplatform.android.ui.common.ExcludeFromJacocoGeneratedReport
import org.groundplatform.ui.theme.AppTheme
import org.groundplatform.ui.theme.sizes

/**
* A reusable UI component representing a single row in a settings screen.
*
* @param modifier The [Modifier] to be applied to the root of this item.
* @param icon Drawable resource for the icon shown next to the title.
* @param title The primary text to be displayed for the setting.
* @param summary Optional secondary text to be displayed below the title, providing more detail.
* @param onClick The callback to be invoked when the item is clicked.
*/
@Composable
internal fun SettingsItem(title: String, summary: String? = null, onClick: () -> Unit) {
internal fun SettingsItem(
modifier: Modifier = Modifier,
@DrawableRes icon: Int,
title: String,
summary: String? = null,
onClick: () -> Unit,
) {
Row(
modifier =
Modifier.fillMaxWidth().clickable(onClick = onClick, role = Role.Button).padding(16.dp),
modifier.fillMaxWidth().clickable(onClick = onClick, role = Role.Button).padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier =
Modifier.padding(end = MaterialTheme.sizes.settingsItemIconEndPadding)
.size(MaterialTheme.sizes.settingsItemIconSize),
painter = painterResource(icon),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
)
Column(modifier = Modifier.weight(1f)) {
Text(text = title, style = MaterialTheme.typography.titleMedium)
if (summary != null) {
Expand All @@ -65,8 +87,14 @@ internal fun SettingsItem(title: String, summary: String? = null, onClick: () ->
private fun Preview() {
AppTheme {
Column(verticalArrangement = Arrangement.SpaceEvenly) {
SettingsItem(title = "Name", summary = "Summary", onClick = {})
SettingsItem(title = "Name", summary = null, onClick = {})
SettingsItem(icon = R.drawable.ic_language, title = "Name", summary = "Summary", onClick = {})
SettingsItem(icon = R.drawable.ic_language, title = "Name", summary = null, onClick = {})
SettingsItem(
icon = R.drawable.ic_language,
title = "Language",
summary = "English",
onClick = {},
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.groundplatform.android.ui.settings.components

import androidx.annotation.ArrayRes
import androidx.annotation.DrawableRes
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.widthIn
Expand All @@ -41,6 +43,7 @@ import org.groundplatform.ui.theme.AppTheme
*
* When clicked, it displays a dropdown menu with options populated from the provided resource IDs.
*
* @param icon Drawable resource for the icon shown next to the title.
* @param title The title of the settings item.
* @param entriesResId The resource ID of the string array containing the display labels.
* @param entryValues The resource ID of the string array containing the underlying values.
Expand All @@ -49,9 +52,10 @@ import org.groundplatform.ui.theme.AppTheme
*/
@Composable
internal fun SettingsSelectItem(
@DrawableRes icon: Int,
title: String,
entriesResId: Int,
entryValues: Int,
@ArrayRes entriesResId: Int,
@ArrayRes entryValues: Int,
currentValue: String,
onValueChanged: (String) -> Unit,
) {
Expand All @@ -70,6 +74,7 @@ internal fun SettingsSelectItem(

Box(modifier = Modifier.fillMaxWidth()) {
SettingsItem(
icon = icon,
title = title,
summary = selectedOption?.label ?: "",
onClick = { expanded = true },
Expand Down Expand Up @@ -102,6 +107,7 @@ internal data class Option(val label: String, val value: String)
private fun PreviewSelectItem() {
AppTheme {
SettingsSelectItem(
icon = R.drawable.ic_language,
title = "Language",
entriesResId = R.array.language_entries,
entryValues = R.array.language_entry_values,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,65 @@
*/
package org.groundplatform.android.ui.settings.components

import androidx.annotation.DrawableRes
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.groundplatform.android.R
import org.groundplatform.android.ui.common.ExcludeFromJacocoGeneratedReport
import org.groundplatform.ui.theme.AppTheme
import org.groundplatform.ui.theme.sizes

/**
* A reusable settings item component with a title, optional summary, and a switch toggle.
*
* @param modifier The [Modifier] to be applied to the root of this item.
* @param icon Drawable resource for the icon shown next to the title.
* @param title The primary text to be displayed for the setting.
* @param summary Optional secondary text providing additional details about the setting.
* @param checked Whether the switch is currently in the "on" position.
* @param onCheckedChange Callback to be invoked when the switch state is toggled.
*/
@Composable
internal fun SettingsSwitchItem(
modifier: Modifier = Modifier,
@DrawableRes icon: Int,
title: String,
summary: String? = null,
checked: Boolean,
onCheckedChange: (Boolean) -> Unit,
) {
Row(
modifier =
Modifier.fillMaxWidth()
modifier
.fillMaxWidth()
.toggleable(value = checked, onValueChange = onCheckedChange, role = Role.Switch)
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
modifier =
Modifier.padding(end = MaterialTheme.sizes.settingsItemIconEndPadding)
.size(MaterialTheme.sizes.settingsItemIconSize),
painter = painterResource(icon),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
)
Column(modifier = Modifier.weight(1f)) {
Text(text = title, style = MaterialTheme.typography.titleMedium)
if (summary != null) {
Expand All @@ -75,8 +94,20 @@ internal fun SettingsSwitchItem(
private fun Preview() {
AppTheme {
Column(verticalArrangement = Arrangement.SpaceEvenly) {
SettingsSwitchItem(title = "Name", summary = "Value", checked = true, onCheckedChange = {})
SettingsSwitchItem(title = "Name", summary = null, checked = false, onCheckedChange = {})
SettingsSwitchItem(
icon = R.drawable.ic_cloud_upload,
title = "Name",
summary = "Value",
checked = true,
onCheckedChange = {},
)
SettingsSwitchItem(
icon = R.drawable.ic_cloud_upload,
title = "Name",
summary = null,
checked = false,
onCheckedChange = {},
)
}
}
}
27 changes: 27 additions & 0 deletions app/src/main/res/drawable/ic_cloud_upload.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>

<!--
~ Copyright 2026 Google LLC
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM14,13v4h-4v-4H7l5,-5 5,5h-3z"/>
</vector>
27 changes: 27 additions & 0 deletions app/src/main/res/drawable/ic_language.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>

<!--
~ Copyright 2026 Google LLC
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M476,880L658,400L742,400L924,880L840,880L797,758L603,758L560,880L476,880ZM160,760L104,704L306,502Q271,467 242.5,422Q214,377 190,320L274,320Q294,359 314,388Q334,417 362,446Q395,413 430.5,353.5Q466,294 484,240L40,240L40,160L320,160L320,80L400,80L400,160L680,160L680,240L564,240Q543,312 501,388Q459,464 418,504L514,602L484,684L362,559L160,760ZM628,688L772,688L700,484L628,688Z"/>
</vector>
27 changes: 27 additions & 0 deletions app/src/main/res/drawable/ic_measurement.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>

<!--
~ Copyright 2026 Google LLC
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M21,6H3C1.9,6 1,6.9 1,8v8c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2V8C23,6.9 22.1,6 21,6zM21,16H3V8h2v4h2V8h2v4h2V8h2v4h2V8h2v4h2V8h2v4h2V8h2V16z"/>
</vector>
28 changes: 28 additions & 0 deletions app/src/main/res/drawable/ic_open_in_new.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>

<!--
~ Copyright 2026 Google LLC
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal"
android:autoMirrored="true">
<path
android:fillColor="@android:color/white"
android:pathData="M200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L480,120L480,200L200,200Q200,200 200,200Q200,200 200,200L200,760Q200,760 200,760Q200,760 200,760L760,760Q760,760 760,760Q760,760 760,760L760,480L840,480L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840ZM388,628L332,572L704,200L560,200L560,120L840,120L840,400L760,400L760,256L388,628Z"/>
</vector>
8 changes: 0 additions & 8 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,6 @@
<string name="text_task_data_character_limit">Máx. 255 caracteres</string>
<string name="area_message">Área: %s</string>

<string name="lang_english">Inglés</string>
<string name="lang_french">Francés</string>
<string name="lang_spanish">Español</string>
<string name="lang_portuguese">Portugués</string>

<string name="lang_vietnamese">Vietnamita</string>
<string name="lang_thai">Tailandés</string>
<string name="lang_lao">Lao</string>
<string name="access_restricted">Restringido</string>
<string name="access_unlisted">No listado</string>
<string name="access_public">Público</string>
Expand Down
8 changes: 1 addition & 7 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,7 @@
<string name="clear">Claire</string>
<string name="text_task_data_character_limit">255 caractères maximum</string>
<string name="area_message">Surface: %s</string>
<string name="lang_english">Anglais</string>
<string name="lang_french">Français</string>
<string name="lang_spanish">Espagnol</string>
<string name="lang_portuguese">Portugais</string>
<string name="lang_vietnamese">Vietnamien</string>
<string name="lang_thai">Thaï</string>
<string name="lang_lao">Lao</string>

<string name="access_restricted">Restreint</string>
<string name="access_unlisted">Non répertorié</string>
<string name="access_public">Public</string>
Expand Down
Loading
Loading