Skip to content

Commit

Permalink
Merge pull request #231 from SwEnt-Group13/chore/translate-every-ui-s…
Browse files Browse the repository at this point in the history
…tring

Chore: Make the app completely translated to French.
  • Loading branch information
armouldr authored Dec 5, 2024
2 parents 97aa42b + f2f8f68 commit 1211c02
Show file tree
Hide file tree
Showing 13 changed files with 206 additions and 117 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.android.unio.components.explore

import android.content.Context
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.junit4.createComposeRule
Expand Down Expand Up @@ -47,6 +48,7 @@ class ExploreScreenTest : TearDown() {
ConcurrentAssociationUserRepositoryFirestore
@MockK private lateinit var eventRepository: EventRepositoryFirestore
@MockK private lateinit var imageRepository: ImageRepositoryFirebaseStorage
@MockK private lateinit var context: Context
private lateinit var associationViewModel: AssociationViewModel

@get:Rule val composeTestRule = createComposeRule()
Expand All @@ -63,6 +65,9 @@ class ExploreScreenTest : TearDown() {

// Mock the navigation action to do nothing
every { navigationAction.navigateTo(any<String>()) } returns Unit
every { context.getString(AssociationCategory.ARTS.displayNameId) } returns "Arts"
every { context.getString(AssociationCategory.SCIENCE_TECH.displayNameId) } returns
"Science and technology"

associations =
listOf(
Expand All @@ -80,7 +85,7 @@ class ExploreScreenTest : TearDown() {
}

sortedByCategoryAssociations =
getSortedEntriesAssociationsByCategory(associations.groupBy { it.category })
getSortedEntriesAssociationsByCategory(context, associations.groupBy { it.category })

associationViewModel =
AssociationViewModel(
Expand Down Expand Up @@ -127,7 +132,8 @@ class ExploreScreenTest : TearDown() {
fun testGetFilteredAssociationsByCategory() {
val associationsByCategory = associations.groupBy { it.category }
val sortedByCategoryAssociations =
getSortedEntriesAssociationsByCategory(associationsByCategory)
getSortedEntriesAssociationsByCategory(context, associationsByCategory)
println(sortedByCategoryAssociations)

assertEquals(AssociationCategory.ARTS, sortedByCategoryAssociations[0].key)
assertEquals(AssociationCategory.SCIENCE_TECH, sortedByCategoryAssociations[1].key)
Expand Down
17 changes: 17 additions & 0 deletions app/src/main/java/com/android/unio/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
Expand All @@ -29,6 +30,7 @@ import com.android.unio.model.event.EventViewModel
import com.android.unio.model.image.ImageRepositoryFirebaseStorage
import com.android.unio.model.map.MapViewModel
import com.android.unio.model.map.nominatim.NominatimLocationSearchViewModel
import com.android.unio.model.preferences.AppPreferences
import com.android.unio.model.search.SearchViewModel
import com.android.unio.model.user.UserViewModel
import com.android.unio.ui.association.AssociationProfileScreen
Expand Down Expand Up @@ -56,7 +58,9 @@ import com.android.unio.ui.user.UserProfileEditionScreen
import com.android.unio.ui.user.UserProfileScreen
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.HiltAndroidApp
import java.util.Locale
import javax.inject.Inject
import me.zhanghai.compose.preference.LocalPreferenceFlow
import me.zhanghai.compose.preference.ProvidePreferenceLocals

@AndroidEntryPoint
Expand All @@ -82,6 +86,19 @@ class MainActivity : ComponentActivity() {

@Composable
fun UnioApp(imageRepository: ImageRepositoryFirebaseStorage) {
// sets language according to LocalPreferences
val preferences by LocalPreferenceFlow.current.collectAsState()
val context = LocalContext.current
val language = preferences.get<String>(AppPreferences.LANGUAGE) ?: AppPreferences.Language.default
val locale = Locale(language)
Locale.setDefault(locale)

val configuration = context.resources.configuration
configuration.setLocale(locale)
configuration.setLayoutDirection(locale)
context.createConfigurationContext(configuration)
context.resources.updateConfiguration(configuration, context.resources.displayMetrics)

val navController = rememberNavController()

val navigationActions = NavigationAction(navController)
Expand Down
30 changes: 15 additions & 15 deletions app/src/main/java/com/android/unio/model/association/Association.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import androidx.appsearch.annotation.Document.Id
import androidx.appsearch.annotation.Document.Namespace
import androidx.appsearch.annotation.Document.StringProperty
import androidx.appsearch.app.AppSearchSchema.StringPropertyConfig
import com.android.unio.R
import com.android.unio.model.event.Event
import com.android.unio.model.firestore.ReferenceElement
import com.android.unio.model.firestore.ReferenceList
import com.android.unio.model.firestore.UniquelyIdentifiable
import com.android.unio.model.strings.AssociationStrings
import com.android.unio.model.user.User

/**
Expand Down Expand Up @@ -54,20 +54,20 @@ data class Association(
*
* @property displayName A human-readable name for the category.
*/
enum class AssociationCategory(val displayName: String) {
EPFL_BODIES(AssociationStrings.EPFL_BODIES),
REPRESENTATION(AssociationStrings.REPRESENTATION),
PROJECTS(AssociationStrings.PROJECTS),
EPFL_STUDENTS(AssociationStrings.EPFL_STUDENTS),
COUNTRIES(AssociationStrings.COUNTRIES),
SUSTAINABILITY(AssociationStrings.SUSTAINABILITY),
SCIENCE_TECH(AssociationStrings.SCIENCE_TECH),
CULTURE_SOCIETY(AssociationStrings.CULTURE_SOCIETY),
ARTS(AssociationStrings.ARTS),
ENTERTAINMENT(AssociationStrings.ENTERTAINMENT),
SPORTS(AssociationStrings.SPORTS),
GUIDANCE(AssociationStrings.GUIDANCE),
UNKNOWN(AssociationStrings.UNKNOWN)
enum class AssociationCategory(val displayNameId: Int) {
EPFL_BODIES(R.string.association_category_epfl_bodies),
REPRESENTATION(R.string.association_category_representation),
PROJECTS(R.string.association_category_projects),
EPFL_STUDENTS(R.string.association_category_epfl_students),
COUNTRIES(R.string.association_category_countries),
SUSTAINABILITY(R.string.association_category_sustainability),
SCIENCE_TECH(R.string.association_category_science_tech),
CULTURE_SOCIETY(R.string.association_category_culture_society),
ARTS(R.string.association_category_arts),
ENTERTAINMENT(R.string.association_category_entertainment),
SPORTS(R.string.association_category_sports),
GUIDANCE(R.string.association_category_guidance),
UNKNOWN(R.string.association_category_unknown)
}

/**
Expand Down
16 changes: 0 additions & 16 deletions app/src/main/java/com/android/unio/model/strings/Strings.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
package com.android.unio.model.strings

object AssociationStrings {
const val EPFL_BODIES = "EPFL bodies"
const val REPRESENTATION = "Representation"
const val PROJECTS = "Interdisciplinary projects"
const val EPFL_STUDENTS = "EPFL Students"
const val COUNTRIES = "Students by country"
const val SUSTAINABILITY = "Sustainability"
const val SCIENCE_TECH = "Science and technology"
const val CULTURE_SOCIETY = "Culture and society"
const val ARTS = "Arts"
const val ENTERTAINMENT = "Entertainment"
const val SPORTS = "Sports"
const val GUIDANCE = "Vocational guidance"
const val UNKNOWN = "Unknown"
}

object FirestorePathsStrings {
const val ASSOCIATION_PATH = "associations"
const val USER_PATH = "users"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,13 @@ fun EditAssociationScaffold(
onClick = { expanded = true },
modifier =
Modifier.fillMaxWidth().testTag(EditAssociationTestTags.CATEGORY_BUTTON)) {
Text(text = category.displayName)
Text(text = context.getString(category.displayNameId))
}

DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
AssociationCategory.entries.forEach { categoryOption ->
DropdownMenuItem(
text = { Text(text = categoryOption.displayName) },
text = { Text(text = context.getString(categoryOption.displayNameId)) },
onClick = {
category = categoryOption
expanded = false
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/java/com/android/unio/ui/explore/Explore.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.android.unio.ui.explore

import android.content.Context
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -12,7 +13,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -69,7 +69,6 @@ fun ExploreScreen(
* @param padding The padding values to apply to the content.
* @param navigationAction The navigation action to use when an association is clicked.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ExploreScreenContent(
padding: PaddingValues,
Expand Down Expand Up @@ -107,14 +106,14 @@ fun ExploreScreenContent(
contentPadding = PaddingValues(vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
getSortedEntriesAssociationsByCategory(associationsByCategory).forEach {
getSortedEntriesAssociationsByCategory(context, associationsByCategory).forEach {
(category, associations) ->
val alphabeticalAssociations = getFilteredAssociationsByAlphabeticalOrder(associations)

if (alphabeticalAssociations.isNotEmpty()) {
item {
Text(
text = category.displayName,
text = context.getString(category.displayNameId),
style = AppTypography.headlineSmall,
modifier =
Modifier.padding(horizontal = 16.dp)
Expand Down Expand Up @@ -197,7 +196,8 @@ fun getFilteredAssociationsByAlphabeticalOrder(associations: List<Association>):

/** Returns the entries of the association map sorted by the key's display name. */
fun getSortedEntriesAssociationsByCategory(
context: Context,
associationsByCategory: Map<AssociationCategory, List<Association>>
): List<Map.Entry<AssociationCategory, List<Association>>> {
return associationsByCategory.entries.sortedBy { it.key.displayName }
return associationsByCategory.entries.sortedBy { context.getString(it.key.displayNameId) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import com.android.unio.model.strings.test_tags.NavigationActionTestTags

Expand All @@ -19,7 +20,9 @@ fun BottomNavigationMenu(
tabList.map { tld ->
NavigationBarItem(
modifier = Modifier.testTag(tld.textId),
label = { Text(tld.route) },
label = {
Text(Route.toTranslatedString(context = LocalContext.current, route = tld.route))
},
icon = { Icon(tld.icon, tld.textId) },
selected = selectedItem == tld.route,
onClick = { onSelection(tld) })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.android.unio.ui.navigation

import android.content.Context
import android.util.Log
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.FavoriteBorder
import androidx.compose.material.icons.outlined.Home
Expand All @@ -8,6 +10,7 @@ import androidx.compose.material.icons.outlined.Search
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import com.android.unio.R
import com.android.unio.model.strings.test_tags.BottomNavBarTestTags

open class NavigationAction(val navController: NavHostController) {
Expand Down Expand Up @@ -120,6 +123,24 @@ object Route {
const val EXPLORE = "Explore"
const val SAVED = "Saved"
const val MY_PROFILE = "Profile"

fun toTranslatedString(context: Context, route: String): String {

val strId =
when (route) {
HOME -> R.string.bottom_nav_home
SAVED -> R.string.bottom_nav_saved
EXPLORE -> R.string.bottom_nav_explore
MY_PROFILE -> R.string.bottom_nav_profile
AUTH -> R.string.nav_auth
else -> {
Log.e("NavigationAction", "The provided route string does not exist.")
0
}
}

return context.getString(strId)
}
}

object Screen {
Expand Down
20 changes: 4 additions & 16 deletions app/src/main/java/com/android/unio/ui/settings/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import com.android.unio.model.user.UserViewModel
import com.android.unio.ui.navigation.NavigationAction
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import java.util.Locale
import me.zhanghai.compose.preference.LocalPreferenceFlow
import me.zhanghai.compose.preference.ProvidePreferenceLocals
import me.zhanghai.compose.preference.listPreference
Expand Down Expand Up @@ -110,16 +109,6 @@ fun SettingsContainer(onPasswordChange: (() -> Unit) -> Unit) {
}

/** Language * */
val language = preferences.get<String>(AppPreferences.LANGUAGE) ?: AppPreferences.Language.default
val locale = Locale(language)
Locale.setDefault(locale)

val configuration = context.resources.configuration
configuration.setLocale(locale)
configuration.setLayoutDirection(locale)
context.createConfigurationContext(configuration)
context.resources.updateConfiguration(configuration, context.resources.displayMetrics)

ProvidePreferenceLocals(flow = LocalPreferenceFlow.current) {
LazyColumn(
modifier = Modifier.testTag(SettingsTestTags.CONTAINER),
Expand Down Expand Up @@ -201,16 +190,15 @@ fun SettingsContainer(onPasswordChange: (() -> Unit) -> Unit) {
Icon(
imageVector = Icons.Default.Lock,
contentDescription = context.getString(R.string.settings_reset_password))
},
onClick = {
onPasswordChange({
}) {
onPasswordChange {
Toast.makeText(
context,
context.getString(R.string.settings_reset_password_sent),
Toast.LENGTH_SHORT)
.show()
})
})
}
}
}
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/com/android/unio/ui/theme/Theme.kt
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ fun AppTheme(
val preferences by LocalPreferenceFlow.current.collectAsState()

val theme = (preferences.asMap().getOrDefault(AppPreferences.THEME, AppPreferences.Theme.SYSTEM))
val language =
preferences.asMap().getOrDefault(AppPreferences.LANGUAGE, AppPreferences.Language.default)

val colorScheme =
when {
Expand Down
10 changes: 7 additions & 3 deletions app/src/main/java/com/android/unio/ui/user/UserProfile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -261,20 +261,24 @@ fun UserProfileScreenContent(
if (joinedAssociations.isNotEmpty()) {
HorizontalDivider()

Text("Joined", style = AppTypography.headlineSmall)
Text(
context.getString(R.string.user_profile_association_joined),
style = AppTypography.headlineSmall)
Column(
modifier = Modifier.fillMaxWidth().testTag(UserProfileTestTags.JOINED_ASSOCIATIONS),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
joinedAssociations.map { AssociationSmall(it) { onAssociationClick(it.uid) } }
}
} else {
Text("You are not member of any association yet", style = AppTypography.bodySmall)
Text(
context.getString(R.string.user_profile_no_associations),
style = AppTypography.bodySmall)

Button(
onClick = onClaimAssociationClick,
modifier = Modifier.testTag(UserProfileTestTags.CLAIMING_BUTTON)) {
Text("Claim Association")
Text(context.getString(R.string.user_profile_claim_association))
}
}

Expand Down
Loading

0 comments on commit 1211c02

Please sign in to comment.