Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Kotlinify codebase (ktlint v.1.0.1) #91

Merged
merged 1 commit into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
[*.{kt,kts}]
ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true
ktlint_function_naming_ignore_when_annotated_with=Composable, Test
368 changes: 197 additions & 171 deletions app/src/androidTest/java/com/wei/amazingtalker/ui/AtAppStateTest.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.rules.ActivityScenarioRule
import com.wei.amazingtalker.MainActivity
import com.wei.amazingtalker.R
import kotlin.properties.ReadOnlyProperty
import com.wei.amazingtalker.feature.teacherschedule.R as FeatureTeacherscheduleR

/**
* Robot for [NavigationTest].
Expand All @@ -23,14 +25,15 @@ internal fun navigationRobot(
internal open class NavigationRobot(
private val composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>,
) {
private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) =
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }
private fun AndroidComposeTestRule<*, *>.stringResource(
@StringRes resId: Int,
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

// The strings used for matching in these tests
private val schedule by composeTestRule.stringResource(com.wei.amazingtalker.R.string.schedule)
private val home by composeTestRule.stringResource(com.wei.amazingtalker.R.string.home)
private val contactMe by composeTestRule.stringResource(com.wei.amazingtalker.R.string.contact_me)
private val backDescription by composeTestRule.stringResource(com.wei.amazingtalker.feature.teacherschedule.R.string.content_description_back)
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 back by lazy {
composeTestRule.onNodeWithContentDescription(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ class NavigationTest {
}

/*
* When pressing back from any top level destination except "Home", the app navigates back
* to the "Home" destination, no matter which destinations you visited in between.
*/
* When pressing back from any top level destination except "Home", the app navigates back
* to the "Home" destination, no matter which destinations you visited in between.
*/
@Test
fun navigationBar_backFromAnyDestination_returnsToHome() {
welcomeEndToEndRobot(composeTestRule) {
Expand All @@ -96,8 +96,8 @@ class NavigationTest {
}

/*
* There should always be at most one instance of a top-level destination at the same time.
*/
* There should always be at most one instance of a top-level destination at the same time.
*/
@Test(expected = NoActivityResumedException::class)
fun topDestination_back_quitsApp() {
welcomeEndToEndRobot(composeTestRule) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ internal fun navigationUiRobot(
internal open class NavigationUiRobot(
private val composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<HiltComponentActivity>, HiltComponentActivity>,
) {
private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) =
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }
private fun AndroidComposeTestRule<*, *>.stringResource(
@StringRes resId: Int,
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

// The strings used for matching in these tests
private val atBottomBarTag by composeTestRule.stringResource(R.string.tag_at_bottom_bar)
Expand Down Expand Up @@ -73,12 +74,13 @@ internal open class NavigationUiRobot(
composeTestRule.setContent {
TestHarness(dpSize) {
BoxWithConstraints {
val displayFeatures = if (foldingState != null) {
val foldBounds = FoldingDeviceUtil.getFoldBounds(dpSize)
listOf(FoldingDeviceUtil.getFoldingFeature(foldBounds, foldingState))
} else {
emptyList()
}
val displayFeatures =
if (foldingState != null) {
val foldBounds = FoldingDeviceUtil.getFoldBounds(dpSize)
listOf(FoldingDeviceUtil.getFoldingFeature(foldBounds, foldingState))
} else {
emptyList()
}

AtApp(
windowSizeClass = WindowSizeClass.calculateFromSize(dpSize),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import javax.inject.Inject
*/
@HiltAndroidTest
class NavigationUiTest {

/**
* Manages the components' state and is used to perform injection on your test
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ internal fun homeEndToEndRobot(
internal open class HomeEndToEndRobot(
private val composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>,
) {
private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) =
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }
private fun AndroidComposeTestRule<*, *>.stringResource(
@StringRes resId: Int,
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

private fun withRole(role: Role) = SemanticsMatcher("${SemanticsProperties.Role.name} contains '$role'") {
val roleProperty = it.config.getOrNull(SemanticsProperties.Role) ?: false
roleProperty == role
}
private fun withRole(role: Role) =
SemanticsMatcher("${SemanticsProperties.Role.name} contains '$role'") {
val roleProperty = it.config.getOrNull(SemanticsProperties.Role) ?: false
roleProperty == role
}

// The strings used for matching in these tests
private val menuDescription by composeTestRule.stringResource(FeatureHomeR.string.menu)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,15 @@ internal fun loginEndToEndRobot(
internal open class LoginEndToEndRobotRobot(
private val composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>,
) {
private fun AndroidComposeTestRule<*, *>.stringResource(
@StringRes resId: Int,
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) =
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

private fun withRole(role: Role) = SemanticsMatcher("${SemanticsProperties.Role.name} contains '$role'") {
val roleProperty = it.config.getOrNull(SemanticsProperties.Role) ?: false
roleProperty == role
}
private fun withRole(role: Role) =
SemanticsMatcher("${SemanticsProperties.Role.name} contains '$role'") {
val roleProperty = it.config.getOrNull(SemanticsProperties.Role) ?: false
roleProperty == role
}

// The strings used for matching in these tests
private val loginDescription by composeTestRule.stringResource(FeatureLoginR.string.content_description_login)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ internal fun scheduleEndToEndRobot(
internal open class ScheduleEndToEndRobot(
private val composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>,
) {
private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) =
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }
private fun AndroidComposeTestRule<*, *>.stringResource(
@StringRes resId: Int,
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

// The strings used for matching in these tests
private val scheduleTopAppBarTag by composeTestRule.stringResource(FeatureTeacherScheduleR.string.tag_schedule_top_app_bar)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ internal fun welcomeEndToEndRobot(
internal open class WelcomeEndToEndRobot(
private val composeTestRule: AndroidComposeTestRule<ActivityScenarioRule<MainActivity>, MainActivity>,
) {
private fun AndroidComposeTestRule<*, *>.stringResource(@StringRes resId: Int) =
ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }
private fun AndroidComposeTestRule<*, *>.stringResource(
@StringRes resId: Int,
) = ReadOnlyProperty<Any?, String> { _, _ -> activity.getString(resId) }

// The strings used for matching in these tests
private val welcomeTitleString by composeTestRule.stringResource(FeatureLoginR.string.welcome_title)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.compose.ui.unit.DpSize
import androidx.window.layout.FoldingFeature

object FoldingDeviceUtil {

fun getFoldBounds(dpSize: DpSize): Rect {
val middleWidth = (dpSize.width / 2f).value.toInt()
return Rect(
Expand All @@ -16,12 +15,17 @@ object FoldingDeviceUtil {
)
}

fun getFoldingFeature(foldBounds: Rect, state: FoldingFeature.State): FoldingFeature {
fun getFoldingFeature(
foldBounds: Rect,
state: FoldingFeature.State,
): FoldingFeature {
return object : FoldingFeature {
override val bounds: Rect = foldBounds
override val isSeparating: Boolean = true
override val occlusionType: FoldingFeature.OcclusionType = FoldingFeature.OcclusionType.NONE
override val orientation: FoldingFeature.Orientation = FoldingFeature.Orientation.VERTICAL
override val occlusionType: FoldingFeature.OcclusionType =
FoldingFeature.OcclusionType.NONE
override val orientation: FoldingFeature.Orientation =
FoldingFeature.Orientation.VERTICAL
override val state: FoldingFeature.State = state
}
}
Expand Down
1 change: 0 additions & 1 deletion app/src/main/java/com/wei/amazingtalker/AtApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import timber.log.Timber

@HiltAndroidApp
class AtApplication : Application() {

override fun onCreate() {
super.onCreate()

Expand Down
27 changes: 14 additions & 13 deletions app/src/main/java/com/wei/amazingtalker/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ private const val TAG = "MainActivity"
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@AndroidEntryPoint
class MainActivity : ComponentActivity() {

@Inject
lateinit var snackbarManager: SnackbarManager

Expand Down Expand Up @@ -95,19 +94,21 @@ class MainActivity : ComponentActivity() {
// than the configuration's dark theme value based on the user preference.
DisposableEffect(darkTheme) {
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.auto(
statusBarStyle =
SystemBarStyle.auto(
android.graphics.Color.TRANSPARENT,
android.graphics.Color.TRANSPARENT,
) { darkTheme },
navigationBarStyle = SystemBarStyle.auto(
navigationBarStyle =
SystemBarStyle.auto(
lightScrim,
darkScrim,
) { darkTheme },
)
onDispose {}
}

CompositionLocalProvider() {
CompositionLocalProvider {
AtTheme(darkTheme = darkTheme) {
AtApp(
networkMonitor = networkMonitor,
Expand All @@ -131,16 +132,16 @@ class MainActivity : ComponentActivity() {
* current system context.
*/
@Composable
private fun shouldUseDarkTheme(
uiState: MainActivityUiState,
): Boolean = when (uiState) {
Loading -> isSystemInDarkTheme()
is Success -> when (uiState.userData.darkThemeConfig) {
DarkThemeConfig.FOLLOW_SYSTEM -> isSystemInDarkTheme()
DarkThemeConfig.LIGHT -> false
DarkThemeConfig.DARK -> true
private fun shouldUseDarkTheme(uiState: MainActivityUiState): Boolean =
when (uiState) {
Loading -> isSystemInDarkTheme()
is Success ->
when (uiState.userData.darkThemeConfig) {
DarkThemeConfig.FOLLOW_SYSTEM -> isSystemInDarkTheme()
DarkThemeConfig.LIGHT -> false
DarkThemeConfig.DARK -> true
}
}
}

/**
* The default light scrim, as defined by androidx and the platform:
Expand Down
21 changes: 12 additions & 9 deletions app/src/main/java/com/wei/amazingtalker/MainActivityViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,23 @@ import kotlinx.coroutines.flow.stateIn
import javax.inject.Inject

@HiltViewModel
class MainActivityViewModel @Inject constructor(
class MainActivityViewModel
@Inject
constructor(
userDataRepository: UserDataRepository,
) : ViewModel() {

val uiState: StateFlow<MainActivityUiState> = userDataRepository.userData.map {
Success(it)
}.stateIn(
scope = viewModelScope,
initialValue = Loading,
started = SharingStarted.WhileSubscribed(5_000),
)
val uiState: StateFlow<MainActivityUiState> =
userDataRepository.userData.map {
Success(it)
}.stateIn(
scope = viewModelScope,
initialValue = Loading,
started = SharingStarted.WhileSubscribed(5_000),
)
}

sealed interface MainActivityUiState {
object Loading : MainActivityUiState

data class Success(val userData: UserData) : MainActivityUiState
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import androidx.navigation.compose.NavHost
import androidx.window.layout.DisplayFeature
import com.wei.amazingtalker.core.designsystem.ui.DeviceOrientation
import com.wei.amazingtalker.feature.contactme.contactme.navigation.contactMeGraph
import com.wei.amazingtalker.feature.home.home.navigation.HOME_ROUTE
import com.wei.amazingtalker.feature.home.home.navigation.homeGraph
import com.wei.amazingtalker.feature.home.home.navigation.homeRoute
import com.wei.amazingtalker.feature.login.login.navigation.loginScreen
import com.wei.amazingtalker.feature.login.welcome.navigation.WELCOME_ROUTE
import com.wei.amazingtalker.feature.login.welcome.navigation.welcomeGraph
import com.wei.amazingtalker.feature.login.welcome.navigation.welcomeRoute
import com.wei.amazingtalker.feature.teacherschedule.schedule.navigation.scheduleGraph
import com.wei.amazingtalker.feature.teacherschedule.scheduledetail.navigation.scheduleDetailScreen
import com.wei.amazingtalker.ui.AtAppState
Expand All @@ -28,7 +28,7 @@ fun AtNavHost(
appState: AtAppState,
isTokenValid: Boolean,
displayFeatures: List<DisplayFeature>,
startDestination: String = if (isTokenValid) homeRoute else welcomeRoute,
startDestination: String = if (isTokenValid) HOME_ROUTE else WELCOME_ROUTE,
) {
val navController = appState.navController
val navigationType = appState.navigationType
Expand Down
Loading