Skip to content
Closed
208 changes: 208 additions & 0 deletions app/src/main/java/org/groundplatform/android/ui/home/HomeDrawer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package org.groundplatform.android.ui.home

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ExitToApp
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Divider
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The Divider import is not used in this file. Please remove unused imports to keep the codebase clean.

import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.NavigationDrawerItemDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color

import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.groundplatform.android.R
import org.groundplatform.android.model.Survey
import org.groundplatform.android.model.User

@Composable
fun HomeDrawer(
user: User?,
survey: Survey?,
onSwitchSurvey: () -> Unit,
onNavigateToOfflineAreas: () -> Unit,
onNavigateToSyncStatus: () -> Unit,
onNavigateToSettings: () -> Unit,
onNavigateToAbout: () -> Unit,
onNavigateToTerms: () -> Unit,
onSignOut: () -> Unit,
offlineAreasEnabled: Boolean = true
) {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
) {
// App Info Header
Column(
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.surfaceVariant)
.padding(vertical = 24.dp, horizontal = 16.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Image(
painter = painterResource(R.drawable.ground_logo),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
Spacer(Modifier.width(8.dp))
Column(modifier = Modifier.weight(1f)) {
Text(
text = stringResource(R.string.app_name),
fontSize = 18.sp,
fontWeight = FontWeight.Medium
)
}
if (user?.photoUrl != null) {
androidx.compose.ui.viewinterop.AndroidView(
factory = { context ->
android.widget.ImageView(context).apply {
scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
}
},
update = { imageView ->
com.bumptech.glide.Glide.with(imageView)
.load(user.photoUrl)
.circleCrop()
.into(imageView)
},
modifier = Modifier
.size(32.dp)
.clip(CircleShape)
)
}
}
}

// Survey Info
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
painter = painterResource(R.drawable.ic_content_paste), // Ensure this drawable exists or use Vector
contentDescription = null, // stringResource(R.string.current_survey)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The contentDescription for this Icon is set to null, which is an accessibility issue. Screen readers will not be able to convey the purpose of this icon. Please provide a meaningful string resource for the contentDescription.

For example, you could use stringResource(R.string.current_survey) as suggested in the commented-out code.

Suggested change
painter = painterResource(R.drawable.ic_content_paste), // Ensure this drawable exists or use Vector
contentDescription = null, // stringResource(R.string.current_survey)
contentDescription = stringResource(R.string.current_survey),

modifier = Modifier.size(14.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(Modifier.width(4.dp))
Text(
text = stringResource(R.string.current_survey),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
Spacer(Modifier.height(8.dp))

if (survey == null) {
Text(stringResource(R.string.no_survey_selected))
} else {
Text(
text = survey.title,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
maxLines = 3,
overflow = TextOverflow.Ellipsis
)
if (survey.description.isNotEmpty()) {
Text(
text = survey.description,
style = MaterialTheme.typography.bodyMedium,
maxLines = 4,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 8.dp)
)
}
}

Spacer(Modifier.height(16.dp))

Text(
text = stringResource(R.string.switch_survey),
style = MaterialTheme.typography.labelLarge,
color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Bold,
modifier = Modifier
.clickable(onClick = onSwitchSurvey)
.padding(vertical = 8.dp)
)
}

HorizontalDivider()

// Navigation Items
NavigationDrawerItem(
label = { Text(stringResource(R.string.offline_map_imagery)) },
selected = false,
onClick = onNavigateToOfflineAreas,
icon = { Icon(painterResource(R.drawable.ic_offline_pin), contentDescription = null) },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The contentDescription for this Icon is set to null. This is an accessibility issue. Please provide a meaningful string resource for the contentDescription that describes the 'Offline map imagery' icon.

Suggested change
icon = { Icon(painterResource(R.drawable.ic_offline_pin), contentDescription = null) },
icon = { Icon(painterResource(R.drawable.ic_offline_pin), contentDescription = stringResource(R.string.offline_map_imagery)) },

modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
NavigationDrawerItem(
label = { Text(stringResource(R.string.sync_status)) },
selected = false,
onClick = onNavigateToSyncStatus,
icon = { Icon(painterResource(R.drawable.ic_sync), contentDescription = null) },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The contentDescription for this Icon is set to null. This is an accessibility issue. Please provide a meaningful string resource for the contentDescription that describes the 'Sync status' icon.

Suggested change
icon = { Icon(painterResource(R.drawable.ic_sync), contentDescription = null) },
icon = { Icon(painterResource(R.drawable.ic_sync), contentDescription = stringResource(R.string.sync_status)) },

modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
NavigationDrawerItem(
label = { Text(stringResource(R.string.settings)) },
selected = false,
onClick = onNavigateToSettings,
icon = { Icon(Icons.Default.Settings, contentDescription = null) },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The contentDescription for this Icon is set to null. This is an accessibility issue. Please provide a meaningful string resource for the contentDescription that describes the 'Settings' icon.

Suggested change
icon = { Icon(Icons.Default.Settings, contentDescription = null) },
icon = { Icon(Icons.Default.Settings, contentDescription = stringResource(R.string.settings)) },

modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
NavigationDrawerItem(
label = { Text(stringResource(R.string.about)) },
selected = false,
onClick = onNavigateToAbout,
icon = { Icon(painterResource(R.drawable.info_outline), contentDescription = null) },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The contentDescription for this Icon is set to null. This is an accessibility issue. Please provide a meaningful string resource for the contentDescription that describes the 'About' icon.

Suggested change
icon = { Icon(painterResource(R.drawable.info_outline), contentDescription = null) },
icon = { Icon(painterResource(R.drawable.info_outline), contentDescription = stringResource(R.string.about)) },

modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
NavigationDrawerItem(
label = { Text(stringResource(R.string.terms_of_service)) },
selected = false,
onClick = onNavigateToTerms,
icon = { Icon(painterResource(R.drawable.feed), contentDescription = null) },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The contentDescription for this Icon is set to null. This is an accessibility issue. Please provide a meaningful string resource for the contentDescription that describes the 'Terms of service' icon.

Suggested change
icon = { Icon(painterResource(R.drawable.feed), contentDescription = null) },
icon = { Icon(painterResource(R.drawable.feed), contentDescription = stringResource(R.string.terms_of_service)) },

modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
NavigationDrawerItem(
label = { Text(stringResource(R.string.sign_out)) },
selected = false,
onClick = onSignOut,
icon = { Icon(Icons.AutoMirrored.Filled.ExitToApp, contentDescription = null) },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The contentDescription for this Icon is set to null. This is an accessibility issue. Please provide a meaningful string resource for the contentDescription that describes the 'Sign out' icon.

Suggested change
icon = { Icon(Icons.AutoMirrored.Filled.ExitToApp, contentDescription = null) },
icon = { Icon(Icons.AutoMirrored.Filled.ExitToApp, contentDescription = stringResource(R.string.sign_out)) },

modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
)
}
}
25 changes: 25 additions & 0 deletions app/src/main/java/org/groundplatform/android/ui/home/HomeScreen.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.groundplatform.android.ui.home

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.DrawerState
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier

@Composable
fun HomeScreen(
drawerState: DrawerState,
drawerContent: @Composable () -> Unit,
content: @Composable () -> Unit
) {
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
ModalDrawerSheet {
drawerContent()
}
},
content = content
)
}
Loading
Loading