Skip to content

Commit

Permalink
Merge branch 'main' into fix/top-bar-text-break-in-large-font-size
Browse files Browse the repository at this point in the history
  • Loading branch information
takahirom authored Sep 2, 2024
2 parents 4572700 + 4eeb9c3 commit 0337e14
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package io.github.droidkaigi.confsched.droidkaigiui.component

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.fadeIn
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons.AutoMirrored.Filled
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MediumTopAppBar
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarColors
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AnimatedMediumTopAppBar(
title: String,
onBackClick: () -> Unit,
navIconContentDescription: String?,
modifier: Modifier = Modifier,
actions: @Composable RowScope.() -> Unit = {},
windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
colors: TopAppBarColors = TopAppBarDefaults.largeTopAppBarColors().copy(
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer,
),
scrollBehavior: TopAppBarScrollBehavior? = null,
) {
val density = LocalDensity.current.density
var navigationIconWidthDp by remember { mutableStateOf(0f) }
val isCenterTitle = remember(scrollBehavior?.state?.collapsedFraction) {
if (scrollBehavior == null) {
// Always left-align when scrollBehavior is not present
false
} else {
// Hide title position because it doesn't look smooth if it is displayed when collapsing
when (scrollBehavior.state.collapsedFraction) {
in 0.7f..1.0f -> true
in 0.0f..0.5f -> false
else -> null // Don't display while on the move.
}
}
}

MediumTopAppBar(
title = {
AnimatedVisibility(
visible = isCenterTitle != null,
enter = fadeIn(),
// No animation required as it is erased with alpha
exit = ExitTransition.None,
) {
Text(
text = title,
modifier = Modifier.then(
when (isCenterTitle) {
true -> {
Modifier
.padding(end = navigationIconWidthDp.dp)
.fillMaxWidth()
}
false -> Modifier
null -> Modifier.alpha(0f)
},
),
textAlign = TextAlign.Center,
)
}
},
modifier = modifier,
navigationIcon = {
IconButton(
modifier = Modifier
.onGloballyPositioned {
navigationIconWidthDp = it.size.width / density
},
onClick = onBackClick,
) {
Icon(
imageVector = Filled.ArrowBack,
contentDescription = navIconContentDescription,
)
}
},
actions = actions,
windowInsets = windowInsets,
colors = colors,
scrollBehavior = scrollBehavior,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ class SponsorsScreenRobot @Inject constructor(
)
}

fun scrollBottom() {
composeTestRule
.onNode(hasTestTag(SponsorsListLazyVerticalGridTestTag))
.performScrollToNode(
hasTestTag(SponsorsListSponsorItemTestTagPrefix.plus(Sponsor.fakes().last().name)),
)
}

fun checkDisplayPlatinumSponsors() {
checkSponsorItemsDisplayedByRangeAndSponsorType(
sponsorType = SponsorType.Platinum,
Expand All @@ -92,7 +100,8 @@ class SponsorsScreenRobot @Inject constructor(
sponsorType: SponsorType,
fromTo: IntRange,
) {
val sponsorList = Sponsor.fakes().filter { it.plan.toSponsorType() == sponsorType }.subList(fromTo.first, fromTo.last)
val sponsorList = Sponsor.fakes().filter { it.plan.toSponsorType() == sponsorType }
.subList(fromTo.first, fromTo.last)
sponsorList.forEach { sponsor ->
composeTestRule
.onNode(hasTestTag(SponsorsListSponsorItemTestTagPrefix.plus(sponsor.name)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import io.github.droidkaigi.confsched.compose.rememberEventFlow
import io.github.droidkaigi.confsched.contributors.component.ContributorsItem
import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect
import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder
import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedLargeTopAppBar
import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedMediumTopAppBar
import io.github.droidkaigi.confsched.model.Contributor
import kotlinx.collections.immutable.PersistentList
import org.jetbrains.compose.resources.stringResource
Expand Down Expand Up @@ -100,7 +100,7 @@ fun ContributorsScreen(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
topBar = {
if (!isTopAppBarHidden) {
AnimatedLargeTopAppBar(
AnimatedMediumTopAppBar(
title = stringResource(ContributorsRes.string.contributor_title),
onBackClick = onBackClick,
scrollBehavior = scrollBehavior,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<string name="language_title">対応言語</string>
<string name="category_title">カテゴリ</string>
<string name="empty_search_result">「%1$s」と一致する検索結果がありません</string>
<string name="empty_search_result_no_input">一致する検索結果がありません</string>
<string name="filter_chip_day">開催日</string>
<string name="filter_chip_category">カテゴリ</string>
<string name="filter_chip_session_type">セッション種別</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<string name="language_title">Supported Languages</string>
<string name="category_title">Category</string>
<string name="empty_search_result">Nothing matched your search criteria "%1$s"</string>
<string name="empty_search_result_no_input">Nothing matched your search criteria</string>
<string name="filter_chip_day">Day</string>
<string name="filter_chip_category">Category</string>
<string name="filter_chip_session_type">Session type</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ fun searchScreenPresenter(
val sessions by rememberUpdatedState(sessionsRepository.timetable())

var searchWord by rememberRetained { mutableStateOf("") }
var hasSearched by rememberRetained { mutableStateOf(false) }
val selectedDays = rememberRetained { mutableStateListOf<DroidKaigi2024Day>() }
val selectedSessionTypes = rememberRetained { mutableStateListOf<TimetableSessionType>() }
val selectedCategories = rememberRetained { mutableStateListOf<TimetableCategory>() }
Expand Down Expand Up @@ -109,6 +110,7 @@ fun searchScreenPresenter(

is UpdateSearchWord -> {
searchWord = event.word
hasSearched = true
}

is ClearSearchWord -> {
Expand Down Expand Up @@ -150,7 +152,7 @@ fun searchScreenPresenter(
}

when {
filters.isNotEmpty() && filteredSessions.isEmpty() -> {
(filters.isNotEmpty() || hasSearched) && filteredSessions.isEmpty() -> {
SearchScreenUiState.Empty(
searchWord = searchWord,
searchFilterDayUiState = searchFilterDayUiState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import conference_app_2024.feature.sessions.generated.resources.Res
import conference_app_2024.feature.sessions.generated.resources.empty_search_result
import conference_app_2024.feature.sessions.generated.resources.empty_search_result_no_input
import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource
Expand All @@ -24,6 +25,12 @@ fun EmptySearchResultBody(
searchWord: String,
modifier: Modifier = Modifier,
) {
val message = if (searchWord.isEmpty()) {
stringResource(Res.string.empty_search_result_no_input)
} else {
stringResource(Res.string.empty_search_result, searchWord)
}

Column(
modifier = modifier
.fillMaxSize()
Expand All @@ -36,7 +43,7 @@ fun EmptySearchResultBody(
contentDescription = null,
)
Text(
text = stringResource(Res.string.empty_search_result, searchWord),
text = message,
style = MaterialTheme.typography.titleMedium,
textAlign = TextAlign.Center,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect
import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder
import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolderImpl
import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedLargeTopAppBar
import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedMediumTopAppBar
import io.github.droidkaigi.confsched.droidkaigiui.plus
import io.github.droidkaigi.confsched.model.FontFamily
import io.github.droidkaigi.confsched.settings.section.accessibility
Expand Down Expand Up @@ -96,7 +96,7 @@ fun SettingsScreen(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
topBar = {
if (!isTopAppBarHidden) {
AnimatedLargeTopAppBar(
AnimatedMediumTopAppBar(
title = stringResource(SettingsRes.string.settings_title),
onBackClick = onBackClick,
scrollBehavior = scrollBehavior,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ class SponsorsScreenTest(
}
}

describe("when scroll to supporters header") {
describe("when scroll to scroll Bottom") {
doIt {
scrollToSupportersSponsorsHeader()
scrollBottom()
}
itShould("display supporters sponsors") {
captureScreenWithChecks {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect
import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder
import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolderImpl
import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedLargeTopAppBar
import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedMediumTopAppBar
import io.github.droidkaigi.confsched.model.Plan.GOLD
import io.github.droidkaigi.confsched.model.Plan.PLATINUM
import io.github.droidkaigi.confsched.model.Plan.SUPPORTER
Expand Down Expand Up @@ -106,7 +106,7 @@ fun SponsorsScreen(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
topBar = {
if (!isTopAppBarHidden) {
AnimatedLargeTopAppBar(
AnimatedMediumTopAppBar(
title = stringResource(SponsorsRes.string.sponsor),
onBackClick = onBackClick,
scrollBehavior = scrollBehavior,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect
import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder
import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolderImpl
import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedLargeTopAppBar
import io.github.droidkaigi.confsched.droidkaigiui.component.AnimatedMediumTopAppBar
import io.github.droidkaigi.confsched.model.Staff
import io.github.droidkaigi.confsched.model.fakes
import io.github.droidkaigi.confsched.staff.component.StaffItem
Expand Down Expand Up @@ -103,7 +103,7 @@ fun StaffScreen(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
topBar = {
if (!isTopAppBarHidden) {
AnimatedLargeTopAppBar(
AnimatedMediumTopAppBar(
title = stringResource(StaffRes.string.staff_title),
onBackClick = onBackClick,
scrollBehavior = scrollBehavior,
Expand Down

0 comments on commit 0337e14

Please sign in to comment.