diff --git a/app/src/androidTest/java/com/wei/teachlink/ui/NavigationRobot.kt b/app/src/androidTest/java/com/wei/teachlink/ui/NavigationRobot.kt index 8357173c..38c06d4d 100644 --- a/app/src/androidTest/java/com/wei/teachlink/ui/NavigationRobot.kt +++ b/app/src/androidTest/java/com/wei/teachlink/ui/NavigationRobot.kt @@ -33,7 +33,9 @@ internal open class NavigationRobot( private val schedule by composeTestRule.stringResource(R.string.schedule) private val home by composeTestRule.stringResource(R.string.home) private val contactMe by composeTestRule.stringResource(R.string.contact_me) - private val backDescription by composeTestRule.stringResource(FeatureTeacherscheduleR.string.content_description_back) + private val backDescription by composeTestRule.stringResource( + FeatureTeacherscheduleR.string.feature_teacherschedule_content_description_back, + ) private val back by lazy { composeTestRule.onNodeWithContentDescription( diff --git a/app/src/androidTest/java/com/wei/teachlink/ui/robot/HomeEndToEndRobot.kt b/app/src/androidTest/java/com/wei/teachlink/ui/robot/HomeEndToEndRobot.kt index 47113a1c..c9460c15 100644 --- a/app/src/androidTest/java/com/wei/teachlink/ui/robot/HomeEndToEndRobot.kt +++ b/app/src/androidTest/java/com/wei/teachlink/ui/robot/HomeEndToEndRobot.kt @@ -41,7 +41,7 @@ internal open class HomeEndToEndRobot( } // The strings used for matching in these tests - private val menuDescription by composeTestRule.stringResource(FeatureHomeR.string.menu) + private val menuDescription by composeTestRule.stringResource(FeatureHomeR.string.feature_home_menu) private val menuButton by lazy { composeTestRule.onNode( diff --git a/app/src/androidTest/java/com/wei/teachlink/ui/robot/LoginEndToEndRobot.kt b/app/src/androidTest/java/com/wei/teachlink/ui/robot/LoginEndToEndRobot.kt index 48d99f24..e7606269 100644 --- a/app/src/androidTest/java/com/wei/teachlink/ui/robot/LoginEndToEndRobot.kt +++ b/app/src/androidTest/java/com/wei/teachlink/ui/robot/LoginEndToEndRobot.kt @@ -42,7 +42,7 @@ internal open class LoginEndToEndRobotRobot( } // The strings used for matching in these tests - private val loginDescription by composeTestRule.stringResource(FeatureLoginR.string.content_description_login) + private val loginDescription by composeTestRule.stringResource(FeatureLoginR.string.feature_login_content_description_login) private val loginButton by lazy { composeTestRule.onNode( diff --git a/app/src/androidTest/java/com/wei/teachlink/ui/robot/ScheduleEndToEndRobot.kt b/app/src/androidTest/java/com/wei/teachlink/ui/robot/ScheduleEndToEndRobot.kt index 7804e582..fcc4af78 100644 --- a/app/src/androidTest/java/com/wei/teachlink/ui/robot/ScheduleEndToEndRobot.kt +++ b/app/src/androidTest/java/com/wei/teachlink/ui/robot/ScheduleEndToEndRobot.kt @@ -31,7 +31,9 @@ internal open class ScheduleEndToEndRobot( ) = ReadOnlyProperty { _, _ -> activity.getString(resId) } // The strings used for matching in these tests - private val scheduleTopAppBarTag by composeTestRule.stringResource(FeatureTeacherScheduleR.string.tag_schedule_top_app_bar) + private val scheduleTopAppBarTag by composeTestRule.stringResource( + FeatureTeacherScheduleR.string.feature_teacherschedule_tag_schedule_top_app_bar, + ) private val scheduleTopAppBar by lazy { composeTestRule.onNodeWithTag( diff --git a/app/src/androidTest/java/com/wei/teachlink/ui/robot/WelcomeEndToEndRobot.kt b/app/src/androidTest/java/com/wei/teachlink/ui/robot/WelcomeEndToEndRobot.kt index 8f6e7ea0..bf5a9fb1 100644 --- a/app/src/androidTest/java/com/wei/teachlink/ui/robot/WelcomeEndToEndRobot.kt +++ b/app/src/androidTest/java/com/wei/teachlink/ui/robot/WelcomeEndToEndRobot.kt @@ -32,8 +32,8 @@ internal open class WelcomeEndToEndRobot( ) = ReadOnlyProperty { _, _ -> activity.getString(resId) } // The strings used for matching in these tests - private val welcomeTitleString by composeTestRule.stringResource(FeatureLoginR.string.welcome_title) - private val getStartedString by composeTestRule.stringResource(FeatureLoginR.string.get_started) + private val welcomeTitleString by composeTestRule.stringResource(FeatureLoginR.string.feature_login_welcome_title) + private val getStartedString by composeTestRule.stringResource(FeatureLoginR.string.feature_login_get_started) private val welcomeTitle by lazy { composeTestRule.onNodeWithContentDescription( diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 81c7a140..e112b970 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,7 +12,7 @@ android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" - android:label="@string/app_name" + android:label="@string/feature_teacherschedule_app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Tl.Splash" diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 87b2f24a..149bdb43 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -58,6 +58,10 @@ gradlePlugin { id = "tl.android.application.flavors" implementationClass = "AndroidApplicationFlavorsConventionPlugin" } + register("androidLint") { + id = "tl.android.lint" + implementationClass = "AndroidLintConventionPlugin" + } register("jvmLibrary") { id = "tl.jvm.library" implementationClass = "JvmLibraryConventionPlugin" diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index ba334132..3d864caa 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -13,6 +13,7 @@ class AndroidApplicationConventionPlugin : Plugin { with(pluginManager) { apply("com.android.application") apply("org.jetbrains.kotlin.android") + apply("tl.android.lint") } extensions.configure { diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index 3a884934..f06c1975 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -18,6 +18,7 @@ class AndroidLibraryConventionPlugin : Plugin { with(pluginManager) { apply("com.android.library") apply("org.jetbrains.kotlin.android") + apply("tl.android.lint") } extensions.configure { @@ -25,6 +26,11 @@ class AndroidLibraryConventionPlugin : Plugin { defaultConfig.targetSdk = 34 configureFlavors(this) configureGradleManagedDevices(this) + // The resource prefix is derived from the module name, + // so resources inside ":core:module1" must be prefixed with "core_module1_" + resourcePrefix = + path.split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_") + .lowercase() + "_" } extensions.configure { configurePrintApksTask(this) diff --git a/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt new file mode 100644 index 00000000..54246d61 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt @@ -0,0 +1,30 @@ +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.LibraryExtension +import com.android.build.api.dsl.Lint +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +class AndroidLintConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + when { + pluginManager.hasPlugin("com.android.application") -> + configure { lint(Lint::configure) } + + pluginManager.hasPlugin("com.android.library") -> + configure { lint(Lint::configure) } + + else -> { + pluginManager.apply("com.android.lint") + configure(Lint::configure) + } + } + } + } +} + +private fun Lint.configure() { + xmlReport = true + checkDependencies = true +} diff --git a/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt index 2222e4fd..27469192 100644 --- a/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt @@ -7,6 +7,7 @@ class JvmLibraryConventionPlugin : Plugin { with(target) { with(pluginManager) { apply("org.jetbrains.kotlin.jvm") + apply("tl.android.lint") } configureKotlinJvm() } diff --git a/core/common/src/androidTest/java/com/wei/teachlink/core/utils/UiTextTest.kt b/core/common/src/androidTest/java/com/wei/teachlink/core/utils/UiTextTest.kt index 738bd18b..ecfc5ad3 100644 --- a/core/common/src/androidTest/java/com/wei/teachlink/core/utils/UiTextTest.kt +++ b/core/common/src/androidTest/java/com/wei/teachlink/core/utils/UiTextTest.kt @@ -35,9 +35,9 @@ class UiTextTest { ) = ReadOnlyProperty { _, _ -> activity.getString(resId) } // The strings used for matching in these tests - private val testString by composeTestRule.stringResource(R.string.generic_hello) - private val formattedStringSingle by composeTestRule.stringResource(R.string.greeting_with_name) - private val formattedStringMultiple by composeTestRule.stringResource(R.string.greeting_with_name_and_weather) + private val testString by composeTestRule.stringResource(R.string.core_common_generic_hello) + private val formattedStringSingle by composeTestRule.stringResource(R.string.core_common_greeting_with_name) + private val formattedStringMultiple by composeTestRule.stringResource(R.string.core_common_greeting_with_name_and_weather) @Composable fun TestUiTextContent(uiText: UiText): String { @@ -64,7 +64,7 @@ class UiTextTest { */ @Test fun stringResource_returnsExpectedValue_withoutArgs() { - val uiText = UiText.StringResource(R.string.generic_hello) + val uiText = UiText.StringResource(R.string.core_common_generic_hello) composeTestRule.setContent { TestUiTextContent(uiText) @@ -81,7 +81,7 @@ class UiTextTest { val argName = "Alice" val uiText = UiText.StringResource( - R.string.greeting_with_name, + R.string.core_common_greeting_with_name, listOf(UiText.StringResource.Args.DynamicString(argName)), ) @@ -105,7 +105,7 @@ class UiTextTest { val argWeather = "sunny" val uiText = UiText.StringResource( - R.string.greeting_with_name_and_weather, + R.string.core_common_greeting_with_name_and_weather, listOf( UiText.StringResource.Args.DynamicString(argName), UiText.StringResource.Args.DynamicString(argWeather), @@ -133,7 +133,7 @@ class UiTextTest { val argWeather = "sunny" val uiText = UiText.StringResource( - R.string.greeting_with_name_and_weather, + R.string.core_common_greeting_with_name_and_weather, listOf( UiText.StringResource.Args.UiTextArg(argName), UiText.StringResource.Args.DynamicString(argWeather), diff --git a/core/common/src/main/res/values/strings.xml b/core/common/src/main/res/values/strings.xml index 22a6c469..0aa1652a 100644 --- a/core/common/src/main/res/values/strings.xml +++ b/core/common/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ - Hello - Hello, %s! - Hello, %1$s! It\'s a %2$s day today. + Hello + Hello, %s! + Hello, %1$s! It\'s a %2$s day today. \ No newline at end of file diff --git a/core/datastore/src/main/java/com/wei/teachlink/core/datastore/TlPreferencesDataSource.kt b/core/datastore/src/main/java/com/wei/teachlink/core/datastore/TlPreferencesDataSource.kt index 481f645a..abd7d611 100644 --- a/core/datastore/src/main/java/com/wei/teachlink/core/datastore/TlPreferencesDataSource.kt +++ b/core/datastore/src/main/java/com/wei/teachlink/core/datastore/TlPreferencesDataSource.kt @@ -1,12 +1,12 @@ package com.wei.teachlink.core.datastore -import android.util.Log import androidx.datastore.core.DataStore import com.wei.teachlink.core.model.data.DarkThemeConfig import com.wei.teachlink.core.model.data.LanguageConfig import com.wei.teachlink.core.model.data.ThemeBrand import com.wei.teachlink.core.model.data.UserData import kotlinx.coroutines.flow.map +import timber.log.Timber import java.io.IOException import javax.inject.Inject @@ -24,18 +24,33 @@ constructor( useDynamicColor = it.useDynamicColor, themeBrand = when (it.themeBrand) { - null, ThemeBrandProto.THEME_BRAND_UNSPECIFIED, ThemeBrandProto.UNRECOGNIZED, ThemeBrandProto.THEME_BRAND_DEFAULT -> ThemeBrand.DEFAULT + null, + ThemeBrandProto.THEME_BRAND_UNSPECIFIED, + ThemeBrandProto.UNRECOGNIZED, + ThemeBrandProto.THEME_BRAND_DEFAULT, + -> ThemeBrand.DEFAULT + ThemeBrandProto.THEME_BRAND_ANDROID -> ThemeBrand.ANDROID }, darkThemeConfig = when (it.darkThemeConfig) { - null, DarkThemeConfigProto.DARK_THEME_CONFIG_UNSPECIFIED, DarkThemeConfigProto.UNRECOGNIZED, DarkThemeConfigProto.DARK_THEME_CONFIG_FOLLOW_SYSTEM -> DarkThemeConfig.FOLLOW_SYSTEM + null, + DarkThemeConfigProto.DARK_THEME_CONFIG_UNSPECIFIED, + DarkThemeConfigProto.UNRECOGNIZED, + DarkThemeConfigProto.DARK_THEME_CONFIG_FOLLOW_SYSTEM, + -> DarkThemeConfig.FOLLOW_SYSTEM + DarkThemeConfigProto.DARK_THEME_CONFIG_LIGHT -> DarkThemeConfig.LIGHT DarkThemeConfigProto.DARK_THEME_CONFIG_DARK -> DarkThemeConfig.DARK }, languageConfig = when (it.languageConfig) { - null, LanguageConfigProto.LANGUAGE_CONFIG_UNSPECIFIED, LanguageConfigProto.UNRECOGNIZED, LanguageConfigProto.LANGUAGE_CONFIG_FOLLOW_SYSTEM -> LanguageConfig.FOLLOW_SYSTEM + null, + LanguageConfigProto.LANGUAGE_CONFIG_UNSPECIFIED, + LanguageConfigProto.UNRECOGNIZED, + LanguageConfigProto.LANGUAGE_CONFIG_FOLLOW_SYSTEM, + -> LanguageConfig.FOLLOW_SYSTEM + LanguageConfigProto.LANGUAGE_CONFIG_ENGLISH -> LanguageConfig.ENGLISH LanguageConfigProto.LANGUAGE_CONFIG_CHINESE -> LanguageConfig.CHINESE }, @@ -50,7 +65,7 @@ constructor( } } } catch (ioException: IOException) { - Log.e("TlPreferences", "Failed to update user preferences", ioException) + Timber.tag("TlPreferences").e(ioException, "Failed to update user preferences") } } } diff --git a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/component/UiExtras.kt b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/component/UiExtras.kt index 8082e9ca..c705135e 100644 --- a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/component/UiExtras.kt +++ b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/component/UiExtras.kt @@ -16,7 +16,7 @@ fun FunctionalityNotAvailablePopup(onDismiss: () -> Unit) { AlertDialog( onDismissRequest = onDismiss, text = { - val functionalityNotAvailable = stringResource(R.string.functionality_not_available) + val functionalityNotAvailable = stringResource(R.string.core_designsystem_functionality_not_available) Text( text = functionalityNotAvailable, style = MaterialTheme.typography.bodyMedium, @@ -24,7 +24,7 @@ fun FunctionalityNotAvailablePopup(onDismiss: () -> Unit) { ) }, confirmButton = { - val close = stringResource(id = R.string.close) + val close = stringResource(id = R.string.core_designsystem_close) TextButton(onClick = onDismiss) { Text( text = close, diff --git a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/EnterAlwaysCollapsedState.kt b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/EnterAlwaysCollapsedState.kt index 48f84e90..89644c90 100644 --- a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/EnterAlwaysCollapsedState.kt +++ b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/EnterAlwaysCollapsedState.kt @@ -1,19 +1,17 @@ package com.wei.teachlink.core.designsystem.management.states.topappbar.scrollflags import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.saveable.mapSaver import androidx.compose.runtime.setValue -import androidx.compose.runtime.structuralEqualityPolicy import com.wei.teachlink.core.designsystem.management.states.topappbar.ScrollFlagState class EnterAlwaysCollapsedState( heightRange: IntRange, scrollOffset: Float = 0f, ) : ScrollFlagState(heightRange) { - override var mScrollOffset by mutableStateOf( + override var mScrollOffset by mutableFloatStateOf( value = scrollOffset.coerceIn(0f, maxHeight.toFloat()), - policy = structuralEqualityPolicy(), ) override val offset: Float diff --git a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/EnterAlwaysState.kt b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/EnterAlwaysState.kt index f38e6077..8bc96628 100644 --- a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/EnterAlwaysState.kt +++ b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/EnterAlwaysState.kt @@ -1,19 +1,17 @@ package com.wei.teachlink.core.designsystem.management.states.topappbar.scrollflags import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.saveable.mapSaver import androidx.compose.runtime.setValue -import androidx.compose.runtime.structuralEqualityPolicy import com.wei.teachlink.core.designsystem.management.states.topappbar.ScrollFlagState class EnterAlwaysState( heightRange: IntRange, scrollOffset: Float = 0f, ) : ScrollFlagState(heightRange) { - override var mScrollOffset by mutableStateOf( + override var mScrollOffset by mutableFloatStateOf( value = scrollOffset.coerceIn(0f, maxHeight.toFloat()), - policy = structuralEqualityPolicy(), ) override val offset: Float diff --git a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/ExitUntilCollapsedState.kt b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/ExitUntilCollapsedState.kt index 8f3b92f0..ef80da4b 100644 --- a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/ExitUntilCollapsedState.kt +++ b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/ExitUntilCollapsedState.kt @@ -1,19 +1,17 @@ package com.wei.teachlink.core.designsystem.management.states.topappbar.scrollflags import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.saveable.mapSaver import androidx.compose.runtime.setValue -import androidx.compose.runtime.structuralEqualityPolicy import com.wei.teachlink.core.designsystem.management.states.topappbar.FixedScrollFlagState class ExitUntilCollapsedState( heightRange: IntRange, scrollOffset: Float = 0f, ) : FixedScrollFlagState(heightRange) { - override var mScrollOffset by mutableStateOf( + override var mScrollOffset by mutableFloatStateOf( value = scrollOffset.coerceIn(0f, rangeDifference.toFloat()), - policy = structuralEqualityPolicy(), ) override var scrollOffset: Float diff --git a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/ScrollState.kt b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/ScrollState.kt index d8f36f9a..125ccc3a 100644 --- a/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/ScrollState.kt +++ b/core/designsystem/src/main/java/com/wei/teachlink/core/designsystem/management/states/topappbar/scrollflags/ScrollState.kt @@ -1,19 +1,17 @@ package com.wei.teachlink.core.designsystem.management.states.topappbar.scrollflags import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.saveable.mapSaver import androidx.compose.runtime.setValue -import androidx.compose.runtime.structuralEqualityPolicy import com.wei.teachlink.core.designsystem.management.states.topappbar.ScrollFlagState class ScrollState( heightRange: IntRange, scrollOffset: Float = 0f, ) : ScrollFlagState(heightRange) { - override var mScrollOffset by mutableStateOf( + override var mScrollOffset by mutableFloatStateOf( value = scrollOffset.coerceIn(0f, maxHeight.toFloat()), - policy = structuralEqualityPolicy(), ) override val offset: Float diff --git a/core/designsystem/src/main/res/values-zh-rTW/strings.xml b/core/designsystem/src/main/res/values-zh-rTW/strings.xml index b1ff95dd..b320e7e4 100644 --- a/core/designsystem/src/main/res/values-zh-rTW/strings.xml +++ b/core/designsystem/src/main/res/values-zh-rTW/strings.xml @@ -1,5 +1,5 @@ - CLOSE - 功能尚未上線 🙈 + CLOSE + 功能尚未上線 🙈 \ No newline at end of file diff --git a/core/designsystem/src/main/res/values/strings.xml b/core/designsystem/src/main/res/values/strings.xml index be1ea8f3..fa1aeea9 100644 --- a/core/designsystem/src/main/res/values/strings.xml +++ b/core/designsystem/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - CLOSE - Functionality not available 🙈 + CLOSE + Functionality not available 🙈 \ No newline at end of file diff --git a/feature/contactme/src/androidTest/java/com/wei/teachlink/feature/contactme/contactme/ContactMeScreenRobot.kt b/feature/contactme/src/androidTest/java/com/wei/teachlink/feature/contactme/contactme/ContactMeScreenRobot.kt index 70ea9c40..75d6522d 100644 --- a/feature/contactme/src/androidTest/java/com/wei/teachlink/feature/contactme/contactme/ContactMeScreenRobot.kt +++ b/feature/contactme/src/androidTest/java/com/wei/teachlink/feature/contactme/contactme/ContactMeScreenRobot.kt @@ -42,11 +42,11 @@ internal open class ContactMeScreenRobot( @StringRes resId: Int, ) = ReadOnlyProperty { _, _ -> activity.getString(resId) } - private val profilePictureDescription by composeTestRule.stringResource(R.string.profile_picture) - private val linkedinString by composeTestRule.stringResource(R.string.linkedin) - private val emailString by composeTestRule.stringResource(R.string.email) - private val timezoneString by composeTestRule.stringResource(R.string.timezone) - private val callDescription by composeTestRule.stringResource(R.string.call) + private val profilePictureDescription by composeTestRule.stringResource(R.string.feature_contactme_profile_picture) + private val linkedinString by composeTestRule.stringResource(R.string.feature_contactme_linkedin) + private val emailString by composeTestRule.stringResource(R.string.feature_contactme_email) + private val timezoneString by composeTestRule.stringResource(R.string.feature_contactme_timezone) + private val callDescription by composeTestRule.stringResource(R.string.feature_contactme_call) private val profilePicture by lazy { composeTestRule.onNodeWithContentDescription( diff --git a/feature/contactme/src/main/java/com/wei/teachlink/feature/contactme/contactme/ContactMeScreen.kt b/feature/contactme/src/main/java/com/wei/teachlink/feature/contactme/contactme/ContactMeScreen.kt index 23080758..0dbb80a1 100644 --- a/feature/contactme/src/main/java/com/wei/teachlink/feature/contactme/contactme/ContactMeScreen.kt +++ b/feature/contactme/src/main/java/com/wei/teachlink/feature/contactme/contactme/ContactMeScreen.kt @@ -301,10 +301,10 @@ internal fun DisplayHeadShot( name: String, isPreview: Boolean, ) { - val resId = R.drawable.he_wei + val resId = R.drawable.feature_contactme_he_wei val painter = coilImagePainter(resId, isPreview) - val profilePictureDescription = stringResource(R.string.profile_picture).format(name) + val profilePictureDescription = stringResource(R.string.feature_contactme_profile_picture).format(name) Image( painter = painter, contentDescription = profilePictureDescription, @@ -352,17 +352,17 @@ fun ContactMeCard( ) } ProfileProperty( - label = stringResource(id = R.string.linkedin), + label = stringResource(id = R.string.feature_contactme_linkedin), value = uiStates.linkedinUrl, isLink = true, ) ProfileProperty( - label = stringResource(id = R.string.email), + label = stringResource(id = R.string.feature_contactme_email), value = uiStates.email, isLink = true, ) ProfileProperty( - label = stringResource(id = R.string.timezone), + label = stringResource(id = R.string.feature_contactme_timezone), value = uiStates.timeZone, isLink = false, ) @@ -417,7 +417,7 @@ private fun PhoneButton( ) } - val phoneDescription = stringResource(id = R.string.call).format(name) + val phoneDescription = stringResource(id = R.string.feature_contactme_call).format(name) IconButton( onClick = { showPopup.value = true diff --git a/feature/contactme/src/main/res/drawable/he_wei.jpg b/feature/contactme/src/main/res/drawable/feature_contactme_he_wei.jpg similarity index 100% rename from feature/contactme/src/main/res/drawable/he_wei.jpg rename to feature/contactme/src/main/res/drawable/feature_contactme_he_wei.jpg diff --git a/feature/contactme/src/main/res/values-zh-rTW/strings.xml b/feature/contactme/src/main/res/values-zh-rTW/strings.xml index 9fc1d699..da59e52d 100644 --- a/feature/contactme/src/main/res/values-zh-rTW/strings.xml +++ b/feature/contactme/src/main/res/values-zh-rTW/strings.xml @@ -1,8 +1,8 @@ - %s 的大頭貼 - LinkedIn - Email - 時區 - 撥打給 %s + %s 的大頭貼 + LinkedIn + Email + 時區 + 撥打給 %s \ No newline at end of file diff --git a/feature/contactme/src/main/res/values/strings.xml b/feature/contactme/src/main/res/values/strings.xml index b426f46e..19b7ab5a 100644 --- a/feature/contactme/src/main/res/values/strings.xml +++ b/feature/contactme/src/main/res/values/strings.xml @@ -1,8 +1,8 @@ - %s\'s profile picture - LinkedIn - Email - Timezone - Call %s + %s\'s profile picture + LinkedIn + Email + Timezone + Call %s \ No newline at end of file diff --git a/feature/home/src/androidTest/java/com/wei/teachlink/feature/home/home/HomeScreenRobot.kt b/feature/home/src/androidTest/java/com/wei/teachlink/feature/home/home/HomeScreenRobot.kt index ce6f8b14..6efc824e 100644 --- a/feature/home/src/androidTest/java/com/wei/teachlink/feature/home/home/HomeScreenRobot.kt +++ b/feature/home/src/androidTest/java/com/wei/teachlink/feature/home/home/HomeScreenRobot.kt @@ -37,25 +37,25 @@ internal open class HomeScreenRobot( ) = ReadOnlyProperty { _, _ -> activity.getString(resId) } // The strings used for matching in these tests - private val userAvatarTag by composeTestRule.stringResource(R.string.tag_user_avatar) - private val addUserString by composeTestRule.stringResource(R.string.add_user) - private val menuString by composeTestRule.stringResource(R.string.menu) - private val helloUserNameTextTag by composeTestRule.stringResource(R.string.tag_hello_user_name_text) - private val myCoursesString by composeTestRule.stringResource(R.string.my_courses) - private val chatsString by composeTestRule.stringResource(R.string.chats) - private val tutorsString by composeTestRule.stringResource(R.string.tutors) - private val courseProgressCardTag by composeTestRule.stringResource(R.string.tag_course_progress_card) - private val pupilRatingCardTag by composeTestRule.stringResource(R.string.tag_pupil_rating_card) - private val tutorButtonTag by composeTestRule.stringResource(R.string.tag_tutor_button) - private val classNameTag by composeTestRule.stringResource(R.string.tag_class_name) - private val classInfoTag by composeTestRule.stringResource(R.string.tag_class_info) - private val contactCardString by composeTestRule.stringResource(R.string.contact_card) - private val skillNameTag by composeTestRule.stringResource(R.string.tag_skill_name) - private val skillLevelTag by composeTestRule.stringResource(R.string.tag_skill_level) - private val circularProgressTag by composeTestRule.stringResource(R.string.tag_circular_progress) - private val loadingContentTag by composeTestRule.stringResource(R.string.tag_loading_content) - private val loadingErrorContentTag by composeTestRule.stringResource(R.string.tag_loading_error_content) - private val screenNotAvailableString by composeTestRule.stringResource(R.string.screen_not_available) + private val userAvatarTag by composeTestRule.stringResource(R.string.feature_home_tag_user_avatar) + private val addUserString by composeTestRule.stringResource(R.string.feature_home_add_user) + private val menuString by composeTestRule.stringResource(R.string.feature_home_menu) + private val helloUserNameTextTag by composeTestRule.stringResource(R.string.feature_home_tag_hello_user_name_text) + private val myCoursesString by composeTestRule.stringResource(R.string.feature_home_my_courses) + private val chatsString by composeTestRule.stringResource(R.string.feature_home_chats) + private val tutorsString by composeTestRule.stringResource(R.string.feature_home_tutors) + private val courseProgressCardTag by composeTestRule.stringResource(R.string.feature_home_tag_course_progress_card) + private val pupilRatingCardTag by composeTestRule.stringResource(R.string.feature_home_tag_pupil_rating_card) + private val tutorButtonTag by composeTestRule.stringResource(R.string.feature_home_tag_tutor_button) + private val classNameTag by composeTestRule.stringResource(R.string.feature_home_tag_class_name) + private val classInfoTag by composeTestRule.stringResource(R.string.feature_home_tag_class_info) + private val contactCardString by composeTestRule.stringResource(R.string.feature_home_contact_card) + private val skillNameTag by composeTestRule.stringResource(R.string.feature_home_tag_skill_name) + private val skillLevelTag by composeTestRule.stringResource(R.string.feature_home_tag_skill_level) + private val circularProgressTag by composeTestRule.stringResource(R.string.feature_home_tag_circular_progress) + private val loadingContentTag by composeTestRule.stringResource(R.string.feature_home_tag_loading_content) + private val loadingErrorContentTag by composeTestRule.stringResource(R.string.feature_home_tag_loading_error_content) + private val screenNotAvailableString by composeTestRule.stringResource(R.string.feature_home_screen_not_available) private var clickedTab: Tab? = null diff --git a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/HomeScreen.kt b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/HomeScreen.kt index 4594c15e..512240ea 100644 --- a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/HomeScreen.kt +++ b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/HomeScreen.kt @@ -117,7 +117,7 @@ internal fun HomeScreen( HomeTopBar( modifier = horizontalBasePadding, userName = uiStates.userDisplayName, - avatarId = R.drawable.he_wei, + avatarId = R.drawable.feature_home_he_wei, onAddUserClick = { // TODO showPopup.value = true @@ -193,7 +193,7 @@ private fun TabContent( @Composable private fun UnavailableScreenContent() { - val screenNotAvailable = stringResource(R.string.screen_not_available) + val screenNotAvailable = stringResource(R.string.feature_home_screen_not_available) Column { Spacer(modifier = Modifier.weight(1f)) @@ -215,7 +215,7 @@ private fun LoadingErrorContent() { modifier = Modifier .fillMaxSize() - .testTag(stringResource(R.string.tag_loading_error_content)), + .testTag(stringResource(R.string.feature_home_tag_loading_error_content)), ) { // TODO Error Content } @@ -227,7 +227,7 @@ private fun LoadingContent() { modifier = Modifier .fillMaxSize() - .testTag(stringResource(R.string.tag_loading_content)), + .testTag(stringResource(R.string.feature_home_tag_loading_content)), contentAlignment = Alignment.Center, ) { CircularProgressIndicator(modifier = Modifier.size(30.dp)) diff --git a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/MyCoursesContent.kt b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/MyCoursesContent.kt index 9d04413f..1bae48c3 100644 --- a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/MyCoursesContent.kt +++ b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/MyCoursesContent.kt @@ -112,10 +112,10 @@ fun CourseProgressCard( courseCount: Int, onClick: () -> Unit, ) { - val completed = stringResource(id = R.string.completed) + val completed = stringResource(id = R.string.feature_home_completed) val contentCourseProgressCard = stringResource( - R.string.course_progress_card, + R.string.feature_home_course_progress_card, completed, courseProgress, courseCount, @@ -124,7 +124,7 @@ fun CourseProgressCard( StatusCard( modifier = modifier - .testTag(stringResource(R.string.tag_course_progress_card)) + .testTag(stringResource(R.string.feature_home_tag_course_progress_card)) .semantics { contentDescription = contentCourseProgressCard }, @@ -157,14 +157,14 @@ fun PupilRatingCard( pupilRating: Double, onClick: () -> Unit, ) { - val pupil = stringResource(id = R.string.pupil) - val rating = stringResource(id = R.string.rating) + val pupil = stringResource(id = R.string.feature_home_pupil) + val rating = stringResource(id = R.string.feature_home_rating) val contentPupilRatingCard = "$pupil $rating $pupilRating" StatusCard( modifier = modifier - .testTag(stringResource(R.string.tag_pupil_rating_card)) + .testTag(stringResource(R.string.feature_home_tag_pupil_rating_card)) .semantics { contentDescription = contentPupilRatingCard }, @@ -259,9 +259,9 @@ private fun ClassInfo( ratingCount: Double, startedDate: String, ) { - val lessons = stringResource(id = R.string.lessons) - val rating = stringResource(id = R.string.rating) - val started = stringResource(id = R.string.started) + val lessons = stringResource(id = R.string.feature_home_lessons) + val rating = stringResource(id = R.string.feature_home_rating) + val started = stringResource(id = R.string.feature_home_started) val contentClassInfo = "$lessons $lessonsCountDisplay, $rating $ratingCount, $started $startedDate" @@ -269,7 +269,7 @@ private fun ClassInfo( modifier = Modifier .padding(horizontal = SPACING_SMALL.dp) - .testTag(stringResource(R.string.tag_class_info)) + .testTag(stringResource(R.string.feature_home_tag_class_info)) .semantics { contentDescription = contentClassInfo }, @@ -324,7 +324,7 @@ private fun ClassName(className: String) { modifier = Modifier .padding(horizontal = SPACING_SMALL.dp) - .testTag(stringResource(R.string.tag_class_name)) + .testTag(stringResource(R.string.feature_home_tag_class_name)) .semantics { contentDescription = className }, @@ -343,7 +343,7 @@ private fun TutorButton( tutorName: String, onTutorClick: () -> Unit, ) { - val tutor = stringResource(id = R.string.tutor) + val tutor = stringResource(id = R.string.feature_home_tutor) val contentTutorButton = "$tutor $tutorName" Button( @@ -356,7 +356,7 @@ private fun TutorButton( modifier = Modifier .testTag( - stringResource(R.string.tag_tutor_button), + stringResource(R.string.feature_home_tag_tutor_button), ) .semantics { contentDescription = contentTutorButton diff --git a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/ContactListCard.kt b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/ContactListCard.kt index 78698e60..17b3c449 100644 --- a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/ContactListCard.kt +++ b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/ContactListCard.kt @@ -49,7 +49,7 @@ fun ContactCard( val maxDisplayContacts = 4 val contactsPerRow = 2 val spacingSize = SPACING_EXTRA_SMALL.dp - val contactCard = stringResource(R.string.contact_card) + val contactCard = stringResource(R.string.feature_home_contact_card) Card( modifier = @@ -103,7 +103,7 @@ internal fun ContactAvatar( isPreview: Boolean, ) { val painter = coilImagePainter(avatarId, true) - val profilePictureDescription = stringResource(R.string.profile_picture).format(name) + val profilePictureDescription = stringResource(R.string.feature_home_profile_picture).format(name) Box( modifier = diff --git a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/HomeTabRow.kt b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/HomeTabRow.kt index e6011a5d..9a3f6f4e 100644 --- a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/HomeTabRow.kt +++ b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/HomeTabRow.kt @@ -68,7 +68,7 @@ fun MyCoursesTab( isSelected: Boolean, onTabClick: () -> Unit, ) { - val myCourses = stringResource(id = R.string.my_courses) + val myCourses = stringResource(id = R.string.feature_home_my_courses) Tab( selected = isSelected, @@ -94,7 +94,7 @@ fun ChatTab( shouldDisplayChatCount: Boolean, onTabClick: () -> Unit, ) { - val chats = stringResource(R.string.chats) + val chats = stringResource(R.string.feature_home_chats) Tab( selected = isSelected, @@ -143,7 +143,7 @@ fun TutorsTab( isSelected: Boolean, onTabClick: () -> Unit, ) { - val tutors = stringResource(id = R.string.tutors) + val tutors = stringResource(id = R.string.feature_home_tutors) Tab( selected = isSelected, diff --git a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/HomeTopBar.kt b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/HomeTopBar.kt index 0d416a73..44cc1733 100644 --- a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/HomeTopBar.kt +++ b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/HomeTopBar.kt @@ -60,7 +60,7 @@ fun HomeTopBar( MenuButton(onMenuClick = onMenuClick) } Spacer(modifier = Modifier.height(SPACING_SMALL.dp)) - val helloUserName = stringResource(R.string.hello, userName) + val helloUserName = stringResource(R.string.feature_home_hello, userName) Text( text = helloUserName, @@ -68,7 +68,7 @@ fun HomeTopBar( fontWeight = FontWeight.Normal, modifier = Modifier - .testTag(stringResource(R.string.tag_hello_user_name_text)) + .testTag(stringResource(R.string.feature_home_tag_hello_user_name_text)) .semantics { contentDescription = helloUserName }, ) Spacer(modifier = Modifier.height(SPACING_SMALL.dp)) @@ -81,7 +81,7 @@ private fun AddUserButton( onAddUserClick: () -> Unit, ) { Box(modifier = modifier) { - val addUser = stringResource(R.string.add_user) + val addUser = stringResource(R.string.feature_home_add_user) IconButton( onClick = { @@ -110,14 +110,14 @@ internal fun UserAvatar( onUserProfileImageClick: () -> Unit, ) { val painter = coilImagePainter(avatarId, true) - val profilePictureDescription = stringResource(R.string.profile_picture).format(userName) + val profilePictureDescription = stringResource(R.string.feature_home_profile_picture).format(userName) IconButton( onClick = onUserProfileImageClick, modifier = modifier .size(48.dp) - .testTag(stringResource(R.string.tag_user_avatar)) + .testTag(stringResource(R.string.feature_home_tag_user_avatar)) .semantics { contentDescription = profilePictureDescription }, @@ -135,7 +135,7 @@ internal fun UserAvatar( @Composable private fun MenuButton(onMenuClick: () -> Unit) { - val menu = stringResource(R.string.menu) + val menu = stringResource(R.string.feature_home_menu) IconButton( onClick = onMenuClick, @@ -161,7 +161,7 @@ fun HomeTopBarPreview() { HomeTopBar( modifier = Modifier.padding(horizontal = SPACING_LARGE.dp), userName = "TEST_NAME", - avatarId = R.drawable.he_wei, + avatarId = R.drawable.feature_home_he_wei, onUserProfileImageClick = {}, onAddUserClick = {}, onMenuClick = {}, diff --git a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/SkillProgressCard.kt b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/SkillProgressCard.kt index 49a1cc16..b6cd28b4 100644 --- a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/SkillProgressCard.kt +++ b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/ui/SkillProgressCard.kt @@ -40,7 +40,7 @@ fun SkillProgressCard( ) { val contentSkillProgressCard = stringResource( - R.string.skill_progress_card, + R.string.feature_home_skill_progress_card, skillName, skillLevel, progress, @@ -66,7 +66,7 @@ fun SkillProgressCard( style = MaterialTheme.typography.titleLarge, maxLines = 1, overflow = TextOverflow.Ellipsis, - modifier = Modifier.testTag(stringResource(R.string.tag_skill_name)), + modifier = Modifier.testTag(stringResource(R.string.feature_home_tag_skill_name)), ) Text( text = skillLevel, @@ -74,14 +74,14 @@ fun SkillProgressCard( color = MaterialTheme.colorScheme.outlineVariant, maxLines = 1, overflow = TextOverflow.Ellipsis, - modifier = Modifier.testTag(stringResource(R.string.tag_skill_level)), + modifier = Modifier.testTag(stringResource(R.string.feature_home_tag_skill_level)), ) Spacer(modifier = Modifier.height(SPACING_LARGE.dp)) CircularProgress( modifier = Modifier .weight(1f) - .testTag(stringResource(R.string.tag_circular_progress)), + .testTag(stringResource(R.string.feature_home_tag_circular_progress)), progress = progress, ) }, diff --git a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/utilities/Constants.kt b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/utilities/Constants.kt index c8e7866f..0a89f621 100644 --- a/feature/home/src/main/java/com/wei/teachlink/feature/home/home/utilities/Constants.kt +++ b/feature/home/src/main/java/com/wei/teachlink/feature/home/home/utilities/Constants.kt @@ -20,25 +20,26 @@ val OfflineColor = Color(0xFFB6B6B6) const val CONTACT_HEAD_SHOT_SIZE = 64 -val TestContacts = listOf( - Contact( - name = "jamie-coleman", - avatarId = R.drawable.jamie_coleman, - status = OnlineStatus.FREE, - ), - Contact( - name = "contact tutor 1", - avatarId = R.drawable.img_face_01, - status = OnlineStatus.BUSY, - ), - Contact( - name = "contact tutor 2", - avatarId = R.drawable.img_face_02, - status = OnlineStatus.FREE, - ), - Contact( - name = "contact tutor 3", - avatarId = R.drawable.img_face_03, - status = OnlineStatus.OFFLINE, - ), -) +val TestContacts = + listOf( + Contact( + name = "jamie-coleman", + avatarId = R.drawable.feature_home_jamie_coleman, + status = OnlineStatus.FREE, + ), + Contact( + name = "contact tutor 1", + avatarId = R.drawable.feature_home_img_face_01, + status = OnlineStatus.BUSY, + ), + Contact( + name = "contact tutor 2", + avatarId = R.drawable.feature_home_img_face_02, + status = OnlineStatus.FREE, + ), + Contact( + name = "contact tutor 3", + avatarId = R.drawable.feature_home_img_face_03, + status = OnlineStatus.OFFLINE, + ), + ) diff --git a/feature/home/src/main/res/drawable/he_wei.jpg b/feature/home/src/main/res/drawable/feature_home_he_wei.jpg similarity index 100% rename from feature/home/src/main/res/drawable/he_wei.jpg rename to feature/home/src/main/res/drawable/feature_home_he_wei.jpg diff --git a/feature/home/src/main/res/drawable/img_face_01.webp b/feature/home/src/main/res/drawable/feature_home_img_face_01.webp similarity index 100% rename from feature/home/src/main/res/drawable/img_face_01.webp rename to feature/home/src/main/res/drawable/feature_home_img_face_01.webp diff --git a/feature/home/src/main/res/drawable/img_face_02.webp b/feature/home/src/main/res/drawable/feature_home_img_face_02.webp similarity index 100% rename from feature/home/src/main/res/drawable/img_face_02.webp rename to feature/home/src/main/res/drawable/feature_home_img_face_02.webp diff --git a/feature/home/src/main/res/drawable/img_face_03.webp b/feature/home/src/main/res/drawable/feature_home_img_face_03.webp similarity index 100% rename from feature/home/src/main/res/drawable/img_face_03.webp rename to feature/home/src/main/res/drawable/feature_home_img_face_03.webp diff --git a/feature/home/src/main/res/drawable/jamie_coleman.webp b/feature/home/src/main/res/drawable/feature_home_jamie_coleman.webp similarity index 100% rename from feature/home/src/main/res/drawable/jamie_coleman.webp rename to feature/home/src/main/res/drawable/feature_home_jamie_coleman.webp diff --git a/feature/home/src/main/res/values-zh-rTW/strings.xml b/feature/home/src/main/res/values-zh-rTW/strings.xml index a0ff4a7b..4ba6faff 100644 --- a/feature/home/src/main/res/values-zh-rTW/strings.xml +++ b/feature/home/src/main/res/values-zh-rTW/strings.xml @@ -1,21 +1,21 @@ - %s 的大頭貼 - 新增使用者 - 選單 - 教師 - 教師 - 對話 - 我的課程 - 完成 - 學生 - 評價 - 堂數 - 開始時間 - Hello, %1$s - %1$s, 百分比 %2$s, 堂數 %3$s - 聯絡人卡牌 - %1$s %2$s, 百分比 %3$s + %s 的大頭貼 + 新增使用者 + 選單 + 教師 + 教師 + 對話 + 我的課程 + 完成 + 學生 + 評價 + 堂數 + 開始時間 + Hello, %1$s + %1$s, 百分比 %2$s, 堂數 %3$s + 聯絡人卡牌 + %1$s %2$s, 百分比 %3$s diff --git a/feature/home/src/main/res/values/strings.xml b/feature/home/src/main/res/values/strings.xml index f05e65ae..3c67c963 100644 --- a/feature/home/src/main/res/values/strings.xml +++ b/feature/home/src/main/res/values/strings.xml @@ -1,36 +1,36 @@ - %s\'s profile picture - Add User - Menu - Tutor - Tutors - Chats - My Courses - Completed - Pupil - Rating - Lessons - Started - Hello, %1$s - %1$s, percentage %2$s, count %3$s - 聯絡人卡牌 - %1$s %2$s, percentage %3$s - Screen not available 🙈 + %s\'s profile picture + Add User + Menu + Tutor + Tutors + Chats + My Courses + Completed + Pupil + Rating + Lessons + Started + Hello, %1$s + %1$s, percentage %2$s, count %3$s + 聯絡人卡牌 + %1$s %2$s, percentage %3$s + Screen not available 🙈 - UserAvatar - HelloUserNameText - CourseProgressCard - PupilRatingCard - TutorButton - ClassName - ClassInfo - SkillName - SkillLevel - CircularProgress - LoadingContent - LoadingErrorContent + UserAvatar + HelloUserNameText + CourseProgressCard + PupilRatingCard + TutorButton + ClassName + ClassInfo + SkillName + SkillLevel + CircularProgress + LoadingContent + LoadingErrorContent diff --git a/feature/login/src/androidTest/java/com/wei/teachlink/feature/login/login/LoginScreenRobot.kt b/feature/login/src/androidTest/java/com/wei/teachlink/feature/login/login/LoginScreenRobot.kt index 3d4425c7..6cd9a965 100644 --- a/feature/login/src/androidTest/java/com/wei/teachlink/feature/login/login/LoginScreenRobot.kt +++ b/feature/login/src/androidTest/java/com/wei/teachlink/feature/login/login/LoginScreenRobot.kt @@ -50,11 +50,11 @@ internal open class LoginScreenRobot( } // The strings used for matching in these tests - private val accountDescription by composeTestRule.stringResource(R.string.content_description_account) - private val passwordDescription by composeTestRule.stringResource(R.string.content_description_password) - private val forgotPasswordDescription by composeTestRule.stringResource(R.string.forgot_password) - private val loginString by composeTestRule.stringResource(R.string.login) - private val loginDescription by composeTestRule.stringResource(R.string.content_description_login) + private val accountDescription by composeTestRule.stringResource(R.string.feature_login_content_description_account) + private val passwordDescription by composeTestRule.stringResource(R.string.feature_login_content_description_password) + private val forgotPasswordDescription by composeTestRule.stringResource(R.string.feature_login_forgot_password) + private val loginString by composeTestRule.stringResource(R.string.feature_login_login) + private val loginDescription by composeTestRule.stringResource(R.string.feature_login_content_description_login) private val loginTitle by lazy { composeTestRule.onNode( diff --git a/feature/login/src/androidTest/java/com/wei/teachlink/feature/login/welcome/WelcomeScreenRobot.kt b/feature/login/src/androidTest/java/com/wei/teachlink/feature/login/welcome/WelcomeScreenRobot.kt index b5383e68..d1087c10 100644 --- a/feature/login/src/androidTest/java/com/wei/teachlink/feature/login/welcome/WelcomeScreenRobot.kt +++ b/feature/login/src/androidTest/java/com/wei/teachlink/feature/login/welcome/WelcomeScreenRobot.kt @@ -33,11 +33,10 @@ internal open class WelcomeScreenRobot( ) = ReadOnlyProperty { _, _ -> activity.getString(resId) } // The strings used for matching in these tests - private val scheduleListTag by composeTestRule.stringResource(R.string.tag_welcome_graphics) + private val scheduleListTag by composeTestRule.stringResource(R.string.feature_login_tag_welcome_graphics) - private val welcomeTitleString by composeTestRule.stringResource(R.string.welcome_title) - private val welcomeMessageString by composeTestRule.stringResource(R.string.welcome_message) - private val getStartedString by composeTestRule.stringResource(R.string.get_started) + private val welcomeTitleString by composeTestRule.stringResource(R.string.feature_login_welcome_title) + private val getStartedString by composeTestRule.stringResource(R.string.feature_login_get_started) private val welcomeGraphics by lazy { composeTestRule.onNodeWithTag( @@ -51,12 +50,6 @@ internal open class WelcomeScreenRobot( useUnmergedTree = true, ) } - private val welcomeMessage by lazy { - composeTestRule.onNodeWithContentDescription( - welcomeMessageString, - useUnmergedTree = true, - ) - } private val getStarted by lazy { composeTestRule.onNodeWithContentDescription( getStartedString, @@ -84,10 +77,6 @@ internal open class WelcomeScreenRobot( welcomeTitle.assertExists().assertIsDisplayed() } - fun verifyWelcomeMessageDisplayed() { - welcomeMessage.assertExists().assertIsDisplayed() - } - fun verifyGetStartedDisplayed() { getStarted.assertExists().assertIsDisplayed() } diff --git a/feature/login/src/main/java/com/wei/teachlink/feature/login/login/LoginScreen.kt b/feature/login/src/main/java/com/wei/teachlink/feature/login/login/LoginScreen.kt index fdc40e58..d6a6f7fa 100644 --- a/feature/login/src/main/java/com/wei/teachlink/feature/login/login/LoginScreen.kt +++ b/feature/login/src/main/java/com/wei/teachlink/feature/login/login/LoginScreen.kt @@ -147,7 +147,7 @@ internal fun LoginScreen( @Composable private fun Title(modifier: Modifier = Modifier) { - val title = stringResource(R.string.login) + val title = stringResource(R.string.feature_login_login) Text( text = title, @@ -160,8 +160,8 @@ private fun Title(modifier: Modifier = Modifier) { @Composable internal fun AccountTextField(accountState: MutableState) { - val account = stringResource(R.string.account) - val accountDescription = stringResource(R.string.content_description_account) + val account = stringResource(R.string.feature_login_account) + val accountDescription = stringResource(R.string.feature_login_content_description_account) TextField( value = accountState.value, @@ -180,8 +180,8 @@ internal fun AccountTextField(accountState: MutableState) { @Composable internal fun PasswordTextField(passwordState: MutableState) { - val password = stringResource(R.string.password) - val passwordDescription = stringResource(R.string.content_description_password) + val password = stringResource(R.string.feature_login_password) + val passwordDescription = stringResource(R.string.feature_login_content_description_password) TextField( value = passwordState.value, @@ -201,7 +201,7 @@ internal fun PasswordTextField(passwordState: MutableState) { @Composable internal fun ForgotPasswordText(modifier: Modifier = Modifier) { - val forgotPassword = stringResource(R.string.forgot_password) + val forgotPassword = stringResource(R.string.feature_login_forgot_password) Text( text = forgotPassword, @@ -219,8 +219,8 @@ internal fun LoginButton( passwordState: MutableState, login: (String, String) -> Unit, ) { - val loginText = stringResource(R.string.login) - val loginTextDescription = stringResource(R.string.content_description_login) + val loginText = stringResource(R.string.feature_login_login) + val loginTextDescription = stringResource(R.string.feature_login_content_description_login) Button( onClick = { diff --git a/feature/login/src/main/java/com/wei/teachlink/feature/login/welcome/WelcomeScreen.kt b/feature/login/src/main/java/com/wei/teachlink/feature/login/welcome/WelcomeScreen.kt index 9bd488b2..06114643 100644 --- a/feature/login/src/main/java/com/wei/teachlink/feature/login/welcome/WelcomeScreen.kt +++ b/feature/login/src/main/java/com/wei/teachlink/feature/login/welcome/WelcomeScreen.kt @@ -175,7 +175,7 @@ fun TlLogoImg( modifier: Modifier = Modifier, isPreview: Boolean, ) { - val resId = R.drawable.ic_logo + val resId = R.drawable.feature_login_ic_logo val painter = coilImagePainter(resId, isPreview) Image( @@ -190,7 +190,7 @@ fun GetStartedButton( modifier: Modifier = Modifier, onGetStartedButtonClicked: () -> Unit, ) { - val getStarted = stringResource(R.string.get_started) + val getStarted = stringResource(R.string.feature_login_get_started) IconButton( onClick = { onGetStartedButtonClicked() }, ) { @@ -206,7 +206,7 @@ fun WelcomeGraphics( modifier: Modifier = Modifier, isPreview: Boolean, ) { - val resId = R.drawable.welcome_background + val resId = R.drawable.feature_login_welcome_background val painter = coilImagePainter(resId, isPreview) Box(modifier = modifier.fillMaxWidth()) { @@ -216,7 +216,7 @@ fun WelcomeGraphics( modifier = modifier .fillMaxSize() - .testTag(stringResource(R.string.tag_welcome_graphics)), + .testTag(stringResource(R.string.feature_login_tag_welcome_graphics)), contentScale = ContentScale.Crop, ) } @@ -246,7 +246,7 @@ fun WelcomeTitlePortrait( modifier: Modifier = Modifier, style: TextStyle, ) { - val welcomeTitle = stringResource(R.string.welcome_title) + val welcomeTitle = stringResource(R.string.feature_login_welcome_title) Box( modifier = @@ -273,7 +273,7 @@ fun WelcomeTitleLandscape( modifier: Modifier = Modifier, style: TextStyle, ) { - val welcomeTitle = stringResource(R.string.welcome_title) + val welcomeTitle = stringResource(R.string.feature_login_welcome_title) Box( modifier = diff --git a/feature/login/src/main/res/drawable-land/welcome_background.jpg b/feature/login/src/main/res/drawable-land/feature_login_welcome_background.jpg similarity index 100% rename from feature/login/src/main/res/drawable-land/welcome_background.jpg rename to feature/login/src/main/res/drawable-land/feature_login_welcome_background.jpg diff --git a/feature/login/src/main/res/drawable-port/welcome_background.jpg b/feature/login/src/main/res/drawable-port/feature_login_welcome_background.jpg similarity index 100% rename from feature/login/src/main/res/drawable-port/welcome_background.jpg rename to feature/login/src/main/res/drawable-port/feature_login_welcome_background.jpg diff --git a/feature/login/src/main/res/drawable-w600dp-land/welcome_background.jpg b/feature/login/src/main/res/drawable-w600dp-land/feature_login_welcome_background.jpg similarity index 100% rename from feature/login/src/main/res/drawable-w600dp-land/welcome_background.jpg rename to feature/login/src/main/res/drawable-w600dp-land/feature_login_welcome_background.jpg diff --git a/feature/login/src/main/res/drawable-w600dp-port/welcome_background.jpg b/feature/login/src/main/res/drawable-w600dp-port/feature_login_welcome_background.jpg similarity index 100% rename from feature/login/src/main/res/drawable-w600dp-port/welcome_background.jpg rename to feature/login/src/main/res/drawable-w600dp-port/feature_login_welcome_background.jpg diff --git a/feature/login/src/main/res/drawable-w840dp-land/welcome_background.jpg b/feature/login/src/main/res/drawable-w840dp-land/feature_login_welcome_background.jpg similarity index 100% rename from feature/login/src/main/res/drawable-w840dp-land/welcome_background.jpg rename to feature/login/src/main/res/drawable-w840dp-land/feature_login_welcome_background.jpg diff --git a/feature/login/src/main/res/drawable-w840dp-port/welcome_background.jpg b/feature/login/src/main/res/drawable-w840dp-port/feature_login_welcome_background.jpg similarity index 100% rename from feature/login/src/main/res/drawable-w840dp-port/welcome_background.jpg rename to feature/login/src/main/res/drawable-w840dp-port/feature_login_welcome_background.jpg diff --git a/feature/login/src/main/res/drawable/ic_logo.xml b/feature/login/src/main/res/drawable/feature_login_ic_logo.xml similarity index 100% rename from feature/login/src/main/res/drawable/ic_logo.xml rename to feature/login/src/main/res/drawable/feature_login_ic_logo.xml diff --git a/feature/login/src/main/res/drawable/feature_login_welcome_background.jpg b/feature/login/src/main/res/drawable/feature_login_welcome_background.jpg new file mode 100644 index 00000000..c99034a8 Binary files /dev/null and b/feature/login/src/main/res/drawable/feature_login_welcome_background.jpg differ diff --git a/feature/login/src/main/res/values-zh-rTW/strings.xml b/feature/login/src/main/res/values-zh-rTW/strings.xml index 096a38d9..e961c022 100644 --- a/feature/login/src/main/res/values-zh-rTW/strings.xml +++ b/feature/login/src/main/res/values-zh-rTW/strings.xml @@ -2,22 +2,19 @@ - 像好友一樣的 + 像好友一樣的 \n優質教師 - 連接全球的線上家教進行1對1課程。 - \n隨時隨地學習, - \n並根據您的需求定制課程! - Get Started + Get Started - Account - Password - Login - 忘記密碼? + Account + Password + Login + 忘記密碼? - 帳號 - 密碼 - 登入 + 帳號 + 密碼 + 登入 \ No newline at end of file diff --git a/feature/login/src/main/res/values/strings.xml b/feature/login/src/main/res/values/strings.xml index 43d9969d..9a6323ed 100644 --- a/feature/login/src/main/res/values/strings.xml +++ b/feature/login/src/main/res/values/strings.xml @@ -1,24 +1,21 @@ - Quality teachers + Quality teachers \nwho are like friends - Access global online tutors for 1-on-1 sessions - \nLearn anytime, anywhere - \nCourses tailored just for you! - Get Started + Get Started - Account - Password - Login - Forgot Password? + Account + Password + Login + Forgot Password? - Account - Password - Login + Account + Password + Login - tag_welcome_graphics + tag_welcome_graphics \ No newline at end of file diff --git a/feature/teacherschedule/src/androidTest/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleScreenRobot.kt b/feature/teacherschedule/src/androidTest/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleScreenRobot.kt index 4e5012d8..b92a0a13 100644 --- a/feature/teacherschedule/src/androidTest/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleScreenRobot.kt +++ b/feature/teacherschedule/src/androidTest/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleScreenRobot.kt @@ -59,22 +59,28 @@ internal open class ScheduleScreenRobot( ) = ReadOnlyProperty { _, _ -> activity.getString(resId) } // The strings used for matching in these tests - private val morningString by composeTestRule.stringResource(R.string.morning) - private val afternoonString by composeTestRule.stringResource(R.string.afternoon) - private val eveningString by composeTestRule.stringResource(R.string.evening) - private val loadingString by composeTestRule.stringResource(R.string.loading) - private val loadFailedString by composeTestRule.stringResource(R.string.load_failed) - private val yourLocalTimeZoneString by composeTestRule.stringResource(R.string.your_local_time_zone) - - private val previousWeekDescription by composeTestRule.stringResource(R.string.content_description_previous_week) - private val nextWeekDescription by composeTestRule.stringResource(R.string.content_description_next_week) - private val weekDateDescription by composeTestRule.stringResource(R.string.content_description_week_date) - private val availableTimeSlotDescription by composeTestRule.stringResource(R.string.content_description_available_time_slot) - private val unavailableTimeSlotDescription by composeTestRule.stringResource(R.string.content_description_unavailable_time_slot) - - private val scheduleTopAppBarTag by composeTestRule.stringResource(R.string.tag_schedule_top_app_bar) - private val scheduleToolbarTag by composeTestRule.stringResource(R.string.tag_schedule_toolbar) - private val scheduleListTag by composeTestRule.stringResource(R.string.tag_schedule_list) + private val morningString by composeTestRule.stringResource(R.string.feature_teacherschedule_morning) + private val afternoonString by composeTestRule.stringResource(R.string.feature_teacherschedule_afternoon) + private val eveningString by composeTestRule.stringResource(R.string.feature_teacherschedule_evening) + private val loadingString by composeTestRule.stringResource(R.string.feature_teacherschedule_loading) + private val loadFailedString by composeTestRule.stringResource(R.string.feature_teacherschedule_load_failed) + private val yourLocalTimeZoneString by composeTestRule.stringResource(R.string.feature_teacherschedule_your_local_time_zone) + + private val previousWeekDescription by composeTestRule.stringResource( + R.string.feature_teacherschedule_content_description_previous_week, + ) + private val nextWeekDescription by composeTestRule.stringResource(R.string.feature_teacherschedule_content_description_next_week) + private val weekDateDescription by composeTestRule.stringResource(R.string.feature_teacherschedule_content_description_week_date) + private val availableTimeSlotDescription by composeTestRule.stringResource( + R.string.feature_teacherschedule_content_description_available_time_slot, + ) + private val unavailableTimeSlotDescription by composeTestRule.stringResource( + R.string.feature_teacherschedule_content_description_unavailable_time_slot, + ) + + private val scheduleTopAppBarTag by composeTestRule.stringResource(R.string.feature_teacherschedule_tag_schedule_top_app_bar) + private val scheduleToolbarTag by composeTestRule.stringResource(R.string.feature_teacherschedule_tag_schedule_toolbar) + private val scheduleListTag by composeTestRule.stringResource(R.string.feature_teacherschedule_tag_schedule_list) private val scheduleViewState = ScheduleViewState( diff --git a/feature/teacherschedule/src/androidTest/java/com/wei/teachlink/feature/teacherschedule/scheduledetail/ScheduleDetailScreenRobot.kt b/feature/teacherschedule/src/androidTest/java/com/wei/teachlink/feature/teacherschedule/scheduledetail/ScheduleDetailScreenRobot.kt index e1793a96..68262abf 100644 --- a/feature/teacherschedule/src/androidTest/java/com/wei/teachlink/feature/teacherschedule/scheduledetail/ScheduleDetailScreenRobot.kt +++ b/feature/teacherschedule/src/androidTest/java/com/wei/teachlink/feature/teacherschedule/scheduledetail/ScheduleDetailScreenRobot.kt @@ -39,15 +39,15 @@ internal open class ScheduleDetailScreenRobot( ) = ReadOnlyProperty { _, _ -> activity.getString(resId) } // The strings used for matching in these tests - private val startTimeDescription by composeTestRule.stringResource(R.string.content_description_start_time) - private val endTimeDescription by composeTestRule.stringResource(R.string.content_description_end_time) - private val backDescription by composeTestRule.stringResource(R.string.content_description_back) - - private val teacherNameTag by composeTestRule.stringResource(R.string.tag_teacher_name) - private val startTimeTag by composeTestRule.stringResource(R.string.tag_start_time) - private val endTimeTag by composeTestRule.stringResource(R.string.tag_end_time) - private val stateTag by composeTestRule.stringResource(R.string.tag_state) - private val duringDayTypeTag by composeTestRule.stringResource(R.string.tag_during_day_type) + private val startTimeDescription by composeTestRule.stringResource(R.string.feature_teacherschedule_content_description_start_time) + private val endTimeDescription by composeTestRule.stringResource(R.string.feature_teacherschedule_content_description_end_time) + private val backDescription by composeTestRule.stringResource(R.string.feature_teacherschedule_content_description_back) + + private val teacherNameTag by composeTestRule.stringResource(R.string.feature_teacherschedule_tag_teacher_name) + private val startTimeTag by composeTestRule.stringResource(R.string.feature_teacherschedule_tag_start_time) + private val endTimeTag by composeTestRule.stringResource(R.string.feature_teacherschedule_tag_end_time) + private val stateTag by composeTestRule.stringResource(R.string.feature_teacherschedule_tag_state) + private val duringDayTypeTag by composeTestRule.stringResource(R.string.feature_teacherschedule_tag_during_day_type) private val teacherName by lazy { composeTestRule.onNodeWithTag( diff --git a/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleScreen.kt b/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleScreen.kt index b5fef107..a091e2a1 100644 --- a/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleScreen.kt +++ b/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleScreen.kt @@ -243,7 +243,7 @@ internal fun ScheduleScreen( onPress = { scope.coroutineContext.cancelChildren() }, ) } - .testTag(stringResource(R.string.tag_schedule_list)), + .testTag(stringResource(R.string.feature_teacherschedule_tag_schedule_list)), timeListUiState = uiStates.timeListUiState, listState = listState, contentPadding = PaddingValues(bottom = if (toolbarState is FixedScrollFlagState) MinToolbarHeight else 0.dp), @@ -278,7 +278,7 @@ private fun ScheduleTopAppBar(title: String) { text = title, modifier = Modifier - .testTag(stringResource(id = R.string.tag_schedule_top_app_bar)) + .testTag(stringResource(id = R.string.feature_teacherschedule_tag_schedule_top_app_bar)) .semantics { contentDescription = title }, ) }, @@ -346,7 +346,7 @@ internal fun ScheduleList( is TimeListUiState.Loading -> item { - val loading = stringResource(R.string.loading) + val loading = stringResource(R.string.feature_teacherschedule_loading) Text( text = loading, style = MaterialTheme.typography.bodyLarge, @@ -359,9 +359,9 @@ internal fun ScheduleList( is TimeListUiState.LoadFailed -> item { - val loadFailed = stringResource(R.string.load_failed) + val loadFailed = stringResource(R.string.feature_teacherschedule_load_failed) Text( - text = stringResource(R.string.load_failed), + text = stringResource(R.string.feature_teacherschedule_load_failed), style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.error, modifier = @@ -391,7 +391,7 @@ private fun ScheduleToolbar( onTabClick: (Int, OffsetDateTime) -> Unit, ) { Surface( - modifier = modifier.testTag(stringResource(id = R.string.tag_schedule_toolbar)), + modifier = modifier.testTag(stringResource(id = R.string.feature_teacherschedule_tag_schedule_toolbar)), ) { Column { WeekActionBar( @@ -438,7 +438,7 @@ fun WeekActionBar( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, ) { - val previousWeekDescription = stringResource(R.string.content_description_previous_week) + val previousWeekDescription = stringResource(R.string.feature_teacherschedule_content_description_previous_week) IconButton( onClick = { if (uiStates.isAvailablePreviousWeek) { @@ -461,7 +461,7 @@ fun WeekActionBar( val (weekStart, weekEnd) = uiStates.weekDateText val weekDataDescription = - stringResource(R.string.content_description_week_date).format( + stringResource(R.string.feature_teacherschedule_content_description_week_date).format( weekStart, weekEnd, ) @@ -472,7 +472,7 @@ fun WeekActionBar( .weight(1f) .semantics { contentDescription = weekDataDescription }, onClick = { - onWeekDateClick(R.string.clickWeekDate, weekDateText) + onWeekDateClick(R.string.feature_teacherschedule_clickWeekDate, weekDateText) }, ) { Text( @@ -483,7 +483,7 @@ fun WeekActionBar( ) } - val nextWeekDescription = stringResource(R.string.content_description_next_week) + val nextWeekDescription = stringResource(R.string.feature_teacherschedule_content_description_next_week) IconButton( onClick = { onNextWeekClick() diff --git a/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/schedule/ui/TimeList.kt b/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/schedule/ui/TimeList.kt index d9b1af36..0bd58b8c 100644 --- a/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/schedule/ui/TimeList.kt +++ b/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/schedule/ui/TimeList.kt @@ -35,7 +35,7 @@ val timeSlotFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("H:mm") internal fun YourLocalTimeZoneText(clock: Clock = Clock.systemDefaultZone()) { val yourLocalTimeZone = String.format( - stringResource(R.string.your_local_time_zone), + stringResource(R.string.feature_teacherschedule_your_local_time_zone), clock.zone, yourLocalTimeZoneFormatter.format(OffsetDateTime.now(clock).offset), ) @@ -56,10 +56,10 @@ internal fun YourLocalTimeZoneText(clock: Clock = Clock.systemDefaultZone()) { internal fun DuringDay(duringDayType: DuringDayType) { val duringDay = when (duringDayType) { - DuringDayType.Morning -> stringResource(R.string.morning) - DuringDayType.Afternoon -> stringResource(R.string.afternoon) - DuringDayType.Evening -> stringResource(R.string.evening) - else -> stringResource(R.string.morning) + DuringDayType.Morning -> stringResource(R.string.feature_teacherschedule_morning) + DuringDayType.Afternoon -> stringResource(R.string.feature_teacherschedule_afternoon) + DuringDayType.Evening -> stringResource(R.string.feature_teacherschedule_evening) + else -> stringResource(R.string.feature_teacherschedule_morning) } Text( @@ -100,7 +100,7 @@ private fun AvailableTimeSlot( val startTimeText = timeSlotFormatter.format(timeSlot.start) val availableDescription = String.format( - stringResource(R.string.content_description_available_time_slot), + stringResource(R.string.feature_teacherschedule_content_description_available_time_slot), startTimeText, ) @@ -129,7 +129,7 @@ private fun UnavailableTimeSlot( val startTimeText = timeSlotFormatter.format(timeSlot.start) val unavailableDescription = String.format( - stringResource(R.string.content_description_unavailable_time_slot), + stringResource(R.string.feature_teacherschedule_content_description_unavailable_time_slot), startTimeText, ) diff --git a/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/scheduledetail/ScheduleDetailScreen.kt b/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/scheduledetail/ScheduleDetailScreen.kt index d26a27e9..a3cadb66 100644 --- a/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/scheduledetail/ScheduleDetailScreen.kt +++ b/feature/teacherschedule/src/main/java/com/wei/teachlink/feature/teacherschedule/scheduledetail/ScheduleDetailScreen.kt @@ -104,19 +104,19 @@ internal fun ScheduleDetailScreen( val teacherName = uiStates.teacherName.toString() val teacherNameDescription = - stringResource(R.string.content_description_teacher_name).format(teacherName) + stringResource(R.string.feature_teacherschedule_content_description_teacher_name).format(teacherName) Text( text = teacherName, style = MaterialTheme.typography.headlineLarge, modifier = Modifier .padding(horizontal = SPACING_LARGE.dp) - .testTag(stringResource(id = R.string.tag_teacher_name)) + .testTag(stringResource(id = R.string.feature_teacherschedule_tag_teacher_name)) .semantics { contentDescription = teacherNameDescription }, ) val startTimeDescription = - stringResource(R.string.content_description_start_time).format(uiStates.start.toString()) + stringResource(R.string.feature_teacherschedule_content_description_start_time).format(uiStates.start.toString()) Text( text = startTimeDescription, style = MaterialTheme.typography.bodyMedium, @@ -124,12 +124,12 @@ internal fun ScheduleDetailScreen( Modifier .padding(horizontal = SPACING_LARGE.dp) .padding(top = SPACING_MEDIUM.dp) - .testTag(stringResource(id = R.string.tag_start_time)) + .testTag(stringResource(id = R.string.feature_teacherschedule_tag_start_time)) .semantics { contentDescription = startTimeDescription }, ) val endTimeDescription = - stringResource(R.string.content_description_end_time).format(uiStates.end.toString()) + stringResource(R.string.feature_teacherschedule_content_description_end_time).format(uiStates.end.toString()) Text( text = endTimeDescription, style = MaterialTheme.typography.bodyMedium, @@ -137,12 +137,12 @@ internal fun ScheduleDetailScreen( Modifier .padding(horizontal = SPACING_LARGE.dp) .padding(top = SPACING_MEDIUM.dp) - .testTag(stringResource(id = R.string.tag_end_time)) + .testTag(stringResource(id = R.string.feature_teacherschedule_tag_end_time)) .semantics { contentDescription = endTimeDescription }, ) val state = uiStates.state?.name.toString() - val stateDescription = stringResource(R.string.content_description_state).format(state) + val stateDescription = stringResource(R.string.feature_teacherschedule_content_description_state).format(state) Text( text = state, style = MaterialTheme.typography.bodyMedium, @@ -150,13 +150,13 @@ internal fun ScheduleDetailScreen( Modifier .padding(horizontal = SPACING_LARGE.dp) .padding(top = SPACING_MEDIUM.dp) - .testTag(stringResource(id = R.string.tag_state)) + .testTag(stringResource(id = R.string.feature_teacherschedule_tag_state)) .semantics { contentDescription = stateDescription }, ) val duringDayType = uiStates.duringDayType?.name.toString() val duringDayTypeDescription = - stringResource(R.string.content_description_during_day_type).format(duringDayType) + stringResource(R.string.feature_teacherschedule_content_description_during_day_type).format(duringDayType) Text( text = duringDayType, style = MaterialTheme.typography.bodyMedium, @@ -164,7 +164,7 @@ internal fun ScheduleDetailScreen( Modifier .padding(horizontal = SPACING_LARGE.dp) .padding(top = SPACING_MEDIUM.dp) - .testTag(stringResource(id = R.string.tag_during_day_type)) + .testTag(stringResource(id = R.string.feature_teacherschedule_tag_during_day_type)) .semantics { contentDescription = duringDayTypeDescription }, ) } @@ -180,7 +180,7 @@ private fun ScheduleDetailToolbar( verticalAlignment = Alignment.CenterVertically, modifier = modifier.fillMaxWidth(), ) { - val back = stringResource(R.string.content_description_back) + val back = stringResource(R.string.feature_teacherschedule_content_description_back) IconButton( onClick = { onBackClick() }, modifier = Modifier.semantics { contentDescription = back }, diff --git a/feature/teacherschedule/src/main/res/values-zh-rTW/strings.xml b/feature/teacherschedule/src/main/res/values-zh-rTW/strings.xml index 3a3ba66e..d678e408 100644 --- a/feature/teacherschedule/src/main/res/values-zh-rTW/strings.xml +++ b/feature/teacherschedule/src/main/res/values-zh-rTW/strings.xml @@ -1,31 +1,31 @@ - TeachLink + TeachLink - 您當地的時區: %1$s GMT %2$s - 您正在查詢 %1$s 老師 + 您當地的時區: %1$s GMT %2$s + 您正在查詢 %1$s 老師 \n%2$s 的行事曆。 - 開啟日曆: %s - 上午 - 下午 - 晚上 - Loading… - 🛠️ Load failed + 開啟日曆: %s + 上午 + 下午 + 晚上 + Loading… + 🛠️ Load failed - 日期範圍 %1$s 到 %2$s - 上一週 - 下一週 - 可預訂時段 %s - 不可預定時段 %s + 日期範圍 %1$s 到 %2$s + 上一週 + 下一週 + 可預訂時段 %s + 不可預定時段 %s - %s - 開始時間: %s - 結束時間: %s - 狀態 %s - 時間區間 %s - 上一頁 + %s + 開始時間: %s + 結束時間: %s + 狀態 %s + 時間區間 %s + 上一頁 \ No newline at end of file diff --git a/feature/teacherschedule/src/main/res/values/strings.xml b/feature/teacherschedule/src/main/res/values/strings.xml index 35789389..cdb6b9f9 100644 --- a/feature/teacherschedule/src/main/res/values/strings.xml +++ b/feature/teacherschedule/src/main/res/values/strings.xml @@ -1,41 +1,41 @@ - TeachLink + TeachLink - Your local time zone: %1$s GMT %2$s - You are inquiring about %1$s\'s calendar for + Your local time zone: %1$s GMT %2$s + You are inquiring about %1$s\'s calendar for \n%2$s. - Open calendar: %s - Morning - Afternoon - Evening - Loading… - 🛠️ Load failed + Open calendar: %s + Morning + Afternoon + Evening + Loading… + 🛠️ Load failed - The date range is from %1$s to %2$s - Previous Week - Next Week - Available Time Slot %s - Unavailable Time Slot %s + The date range is from %1$s to %2$s + Previous Week + Next Week + Available Time Slot %s + Unavailable Time Slot %s - %s - Start Time: %s - End Time: %s - State %s - During Day %s - Navigate up + %s + Start Time: %s + End Time: %s + State %s + During Day %s + Navigate up - tag_schedule_top_app_bar - tag_schedule_toolbar - tag_schedule_list + tag_schedule_top_app_bar + tag_schedule_toolbar + tag_schedule_list - tag_teacher_name - tag_start_time - tag_end_time - tag_state - tag_during_day_type + tag_teacher_name + tag_start_time + tag_end_time + tag_state + tag_during_day_type \ No newline at end of file diff --git a/feature/teacherschedule/src/test/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleViewModelTest.kt b/feature/teacherschedule/src/test/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleViewModelTest.kt index c1bdd44f..ac7685b1 100644 --- a/feature/teacherschedule/src/test/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleViewModelTest.kt +++ b/feature/teacherschedule/src/test/java/com/wei/teachlink/feature/teacherschedule/schedule/ScheduleViewModelTest.kt @@ -100,7 +100,7 @@ class ScheduleViewModelTest { fun `dispatch showSnackBar action should set correct snackbar when message with single arg`() = runTest { // Arrange - val resId = R.string.clickWeekDate + val resId = R.string.feature_teacherschedule_clickWeekDate val message = listOf(TEST_TEACHER_NAME) val testUiText = UiText.StringResource( @@ -128,7 +128,7 @@ class ScheduleViewModelTest { fun `dispatch showSnackBar action should set correct snackbar when message with multiple args`() = runTest { // Arrange - val resId = R.string.inquirying_teacher_calendar + val resId = R.string.feature_teacherschedule_inquirying_teacher_calendar val message = listOf(TEST_TEACHER_NAME, TEST_WEEK_DATE_TEXT) val testUiText = UiText.StringResource(