Compare commits
1 Commits
release/v2
...
renovate/g
| Author | SHA1 | Date | |
|---|---|---|---|
| c1fc13e091 |
@@ -7,13 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- Month-view event titles no longer end in an ellipsis. The "…" took the width
|
||||
of a couple of characters and told you nothing you couldn't already see, so
|
||||
the title now simply runs to the edge of its chip — a few more letters per
|
||||
cell, which is often the difference between two events you can tell apart and
|
||||
two you can't ([#164]).
|
||||
|
||||
## [2.19.1] — 2026-08-11
|
||||
|
||||
### Added
|
||||
@@ -1421,4 +1414,3 @@ automatically, with zero telemetry and no internet permission.
|
||||
[#123]: https://codeberg.org/jlmakiola/calendula/issues/123
|
||||
[#163]: https://codeberg.org/jlmakiola/calendula/issues/163
|
||||
[#173]: https://codeberg.org/jlmakiola/calendula/issues/173
|
||||
[#164]: https://codeberg.org/jlmakiola/calendula/issues/164
|
||||
|
||||
@@ -135,7 +135,6 @@ fun AgendaScreen(
|
||||
AgendaTopBar(
|
||||
selectedView = selectedView,
|
||||
onCycleView = { onSelectView(selectedView.next(quickSwitchViews)) },
|
||||
quickSwitchViews = quickSwitchViews,
|
||||
onOpenDrawer = { scope.launch { drawerState.open() } },
|
||||
onOpenSearch = onOpenSearch,
|
||||
showTodayButton = todayInToolbar,
|
||||
@@ -410,7 +409,6 @@ private fun AgendaEmpty(modifier: Modifier = Modifier) {
|
||||
private fun AgendaTopBar(
|
||||
selectedView: CalendarView,
|
||||
onCycleView: () -> Unit,
|
||||
quickSwitchViews: List<CalendarView>,
|
||||
onOpenDrawer: () -> Unit,
|
||||
onOpenSearch: () -> Unit,
|
||||
showTodayButton: Boolean,
|
||||
@@ -442,7 +440,6 @@ private fun AgendaTopBar(
|
||||
}
|
||||
ViewSwitcherPill(
|
||||
current = selectedView,
|
||||
cycle = quickSwitchViews,
|
||||
onCycle = onCycleView,
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
)
|
||||
|
||||
@@ -57,8 +57,7 @@ fun CalendarView.next(available: List<CalendarView> = IMPLEMENTED_VIEWS): Calend
|
||||
* implemented view — the settings screen reorders the whole set — while [cycle]
|
||||
* is the subset the pill actually steps through, in [order]. The navigation
|
||||
* drawer keeps its own separate order and always lists every view, so a view
|
||||
* disabled here stays reachable there — including when [cycle] is emptied and
|
||||
* the pill disappears altogether.
|
||||
* disabled here stays reachable there.
|
||||
*/
|
||||
data class QuickSwitchConfig(
|
||||
val order: List<CalendarView>,
|
||||
@@ -68,15 +67,14 @@ data class QuickSwitchConfig(
|
||||
val cycle: List<CalendarView> get() = order.filter { it in enabled }
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Fewest views that keep the switch meaningful. A single target is not a
|
||||
* switch, so below this the pill is hidden rather than special-cased (#150);
|
||||
* the drawer still reaches every view.
|
||||
*/
|
||||
const val MIN_CYCLE = 2
|
||||
|
||||
/** All views, in default order, all enabled. */
|
||||
val Default = QuickSwitchConfig(IMPLEMENTED_VIEWS, IMPLEMENTED_VIEWS.toSet())
|
||||
|
||||
/**
|
||||
* Fewest views that keep the switch meaningful — a "switch" needs at
|
||||
* least two targets, so the settings screen blocks disabling below this.
|
||||
*/
|
||||
const val MIN_ENABLED = 2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package de.jeanlucmakiola.calendula.ui.common
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
|
||||
/** How an event chip's title should overflow: what to pass to `Text`. */
|
||||
data class EventTitleOverflow(val overflow: TextOverflow, val softWrap: Boolean)
|
||||
|
||||
/**
|
||||
* Overflow for an event chip's title (#164). Chips are narrow enough that the
|
||||
* "…" costs a couple of readable characters, so the title runs to the chip's
|
||||
* edge and clips mid-glyph instead.
|
||||
*
|
||||
* Two cases keep the ellipsis:
|
||||
*
|
||||
* - **[rtl].** With `softWrap` off Compose lays the line out at its full
|
||||
* intrinsic width and clips to the node's left edge, which in RTL is the *end*
|
||||
* of the string — an Arabic title would lose its beginning. The ellipsis
|
||||
* truncates at the logical end in both directions.
|
||||
* - **More than one line** ([singleLine] false). Wrapping needs `softWrap` on,
|
||||
* and clipping with it on breaks the last line at the last whole word — less
|
||||
* title than the ellipsis showed, not more.
|
||||
*/
|
||||
fun eventTitleOverflowFor(rtl: Boolean, singleLine: Boolean): EventTitleOverflow =
|
||||
if (rtl || !singleLine) {
|
||||
EventTitleOverflow(TextOverflow.Ellipsis, softWrap = true)
|
||||
} else {
|
||||
EventTitleOverflow(TextOverflow.Clip, softWrap = false)
|
||||
}
|
||||
|
||||
/** [eventTitleOverflowFor] against the current layout direction. */
|
||||
@Composable
|
||||
fun eventTitleOverflow(singleLine: Boolean = true): EventTitleOverflow =
|
||||
eventTitleOverflowFor(
|
||||
rtl = LocalLayoutDirection.current == LayoutDirection.Rtl,
|
||||
singleLine = singleLine,
|
||||
)
|
||||
@@ -464,13 +464,11 @@ fun TimelineDragOverlay(controller: TimelineDragController, modifier: Modifier =
|
||||
.padding(horizontal = 4.dp, vertical = 2.dp),
|
||||
) {
|
||||
Column {
|
||||
val titleOverflow = eventTitleOverflow()
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
maxLines = 1,
|
||||
overflow = titleOverflow.overflow,
|
||||
softWrap = titleOverflow.softWrap,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = eventInk(fill, alpha = 0.85f),
|
||||
)
|
||||
Text(
|
||||
|
||||
@@ -10,19 +10,13 @@ import androidx.compose.ui.res.stringResource
|
||||
/**
|
||||
* Top-bar pill that shows the current view and cycles to the next one on tap
|
||||
* (spec M1: Month → Week → Day → Month, restricted to [IMPLEMENTED_VIEWS]).
|
||||
*
|
||||
* Renders nothing when [cycle] holds fewer than [QuickSwitchConfig.MIN_CYCLE]
|
||||
* views (#150), so it drops straight into an app bar's `actions` slot without a
|
||||
* wrapping condition — the same way [TodayAction] handles being turned off.
|
||||
*/
|
||||
@Composable
|
||||
fun ViewSwitcherPill(
|
||||
current: CalendarView,
|
||||
cycle: List<CalendarView>,
|
||||
onCycle: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (cycle.size < QuickSwitchConfig.MIN_CYCLE) return
|
||||
FilledTonalButton(
|
||||
onClick = onCycle,
|
||||
shape = MaterialTheme.shapes.large,
|
||||
|
||||
@@ -65,6 +65,7 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.customActions
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -93,7 +94,6 @@ import de.jeanlucmakiola.calendula.ui.common.TimelineDrop
|
||||
import de.jeanlucmakiola.calendula.ui.common.beginsOn
|
||||
import de.jeanlucmakiola.calendula.ui.common.eventDragAllowed
|
||||
import de.jeanlucmakiola.calendula.ui.common.eventMoveAction
|
||||
import de.jeanlucmakiola.calendula.ui.common.eventTitleOverflow
|
||||
import de.jeanlucmakiola.calendula.ui.common.rememberEventDragSource
|
||||
import de.jeanlucmakiola.calendula.ui.common.rememberTimelineDragController
|
||||
import de.jeanlucmakiola.calendula.ui.common.startInstant
|
||||
@@ -243,7 +243,6 @@ fun DayScreen(
|
||||
currentYear = currentYear,
|
||||
selectedView = selectedView,
|
||||
onCycleView = { onSelectView(selectedView.next(quickSwitchViews)) },
|
||||
quickSwitchViews = quickSwitchViews,
|
||||
onOpenDrawer = { scope.launch { drawerState.open() } },
|
||||
onOpenSearch = onOpenSearch,
|
||||
onJumpToDate = jumpToDate,
|
||||
@@ -412,7 +411,6 @@ private fun DayTopBar(
|
||||
currentYear: Int,
|
||||
selectedView: CalendarView,
|
||||
onCycleView: () -> Unit,
|
||||
quickSwitchViews: List<CalendarView>,
|
||||
onOpenDrawer: () -> Unit,
|
||||
onOpenSearch: () -> Unit,
|
||||
onJumpToDate: (LocalDate) -> Unit,
|
||||
@@ -447,7 +445,6 @@ private fun DayTopBar(
|
||||
}
|
||||
ViewSwitcherPill(
|
||||
current = selectedView,
|
||||
cycle = quickSwitchViews,
|
||||
onCycle = onCycleView,
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
)
|
||||
@@ -522,13 +519,11 @@ private fun AllDayBar(
|
||||
.semantics { contentDescription = title },
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
val titleOverflow = eventTitleOverflow()
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
maxLines = 1,
|
||||
overflow = titleOverflow.overflow,
|
||||
softWrap = titleOverflow.softWrap,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = eventInk(fill),
|
||||
)
|
||||
}
|
||||
@@ -771,13 +766,11 @@ private fun EventBlock(
|
||||
) {
|
||||
Column {
|
||||
if (showTitle) {
|
||||
val titleOverflow = eventTitleOverflow(singleLine = showTime)
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
maxLines = if (showTime) 1 else 2,
|
||||
overflow = titleOverflow.overflow,
|
||||
softWrap = titleOverflow.softWrap,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = eventInk(fill, alpha = 0.85f),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -89,7 +89,6 @@ import androidx.compose.ui.geometry.Offset
|
||||
import kotlin.math.roundToInt
|
||||
import de.jeanlucmakiola.calendula.ui.common.rememberDragSurface
|
||||
import de.jeanlucmakiola.calendula.ui.common.eventMoveAction
|
||||
import de.jeanlucmakiola.calendula.ui.common.eventTitleOverflow
|
||||
import de.jeanlucmakiola.calendula.ui.common.MoveTarget
|
||||
import de.jeanlucmakiola.calendula.ui.common.MoveRequest
|
||||
import de.jeanlucmakiola.calendula.ui.common.LocalEventMove
|
||||
@@ -387,7 +386,6 @@ fun MonthScreen(
|
||||
titleDate = LocalDate(titleMonth.year, titleMonth.month, 1),
|
||||
selectedView = selectedView,
|
||||
onCycleView = { onSelectView(selectedView.next(quickSwitchViews)) },
|
||||
quickSwitchViews = quickSwitchViews,
|
||||
onOpenDrawer = { scope.launch { drawerState.open() } },
|
||||
onOpenSearch = onOpenSearch,
|
||||
onJumpToDate = jumpToDate,
|
||||
@@ -652,7 +650,6 @@ private fun MonthTopBar(
|
||||
titleDate: LocalDate,
|
||||
selectedView: CalendarView,
|
||||
onCycleView: () -> Unit,
|
||||
quickSwitchViews: List<CalendarView>,
|
||||
onOpenDrawer: () -> Unit,
|
||||
onOpenSearch: () -> Unit,
|
||||
onJumpToDate: (LocalDate) -> Unit,
|
||||
@@ -686,7 +683,6 @@ private fun MonthTopBar(
|
||||
}
|
||||
ViewSwitcherPill(
|
||||
current = selectedView,
|
||||
cycle = quickSwitchViews,
|
||||
onCycle = onCycleView,
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
)
|
||||
@@ -2356,13 +2352,11 @@ private fun MonthBar(
|
||||
},
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
val titleOverflow = eventTitleOverflow()
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
maxLines = 1,
|
||||
overflow = titleOverflow.overflow,
|
||||
softWrap = titleOverflow.softWrap,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = eventInk(fill),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -591,15 +591,15 @@ class SettingsViewModel @Inject constructor(
|
||||
|
||||
/**
|
||||
* Enable or disable [view] in the quick-switch cycle, via an atomic
|
||||
* read-modify-write so a concurrent reorder can't clobber it. Any number of
|
||||
* views may be turned off; below two the pill hides itself (#150).
|
||||
* read-modify-write so a concurrent reorder can't clobber it. The
|
||||
* MIN_ENABLED floor is re-checked inside the transform, because the screen's
|
||||
* own guard reads an async-echoed snapshot.
|
||||
*/
|
||||
fun setQuickSwitchViewEnabled(view: CalendarView, enabled: Boolean) {
|
||||
viewModelScope.launch {
|
||||
prefs.updateQuickSwitch { config ->
|
||||
config.copy(
|
||||
enabled = if (enabled) config.enabled + view else config.enabled - view,
|
||||
)
|
||||
val next = if (enabled) config.enabled + view else config.enabled - view
|
||||
if (next.size < QuickSwitchConfig.MIN_ENABLED) config else config.copy(enabled = next)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import de.jeanlucmakiola.calendula.ui.common.AgendaRangePicker
|
||||
import de.jeanlucmakiola.calendula.ui.common.CalendarView
|
||||
import de.jeanlucmakiola.calendula.ui.common.IMPLEMENTED_VIEWS
|
||||
import de.jeanlucmakiola.calendula.ui.common.PickerDescription
|
||||
import de.jeanlucmakiola.calendula.ui.common.QuickSwitchConfig
|
||||
import de.jeanlucmakiola.calendula.ui.common.TimelineScale
|
||||
import de.jeanlucmakiola.calendula.ui.common.agendaRangeLabel
|
||||
import de.jeanlucmakiola.calendula.ui.common.descriptionRes
|
||||
@@ -54,8 +55,8 @@ import java.time.format.TextStyle as JavaTextStyle
|
||||
* it belongs to, plus the two cross-view ordering lists (#24, #69).
|
||||
*
|
||||
* The quick-switch cycle and the drawer list are independent orders — a view
|
||||
* off in the cycle is still reachable from the drawer, including when the cycle
|
||||
* is emptied and the pill disappears (#150).
|
||||
* off in the cycle is still reachable from the drawer. The cycle needs at least
|
||||
* [QuickSwitchConfig.MIN_ENABLED] targets.
|
||||
*/
|
||||
@Composable
|
||||
internal fun ViewsScreen(
|
||||
@@ -220,6 +221,8 @@ internal fun ViewsScreen(
|
||||
SectionHeader(stringResource(R.string.settings_quick_switch_header))
|
||||
SettingsHint(stringResource(R.string.settings_quick_switch_hint))
|
||||
Spacer(Modifier.height(8.dp))
|
||||
// Turning a view off is blocked once only the minimum remain enabled.
|
||||
val canDisable = config.enabled.size > QuickSwitchConfig.MIN_ENABLED
|
||||
ReorderableColumn(
|
||||
items = config.order,
|
||||
keyOf = { it },
|
||||
@@ -235,6 +238,8 @@ internal fun ViewsScreen(
|
||||
trailing = {
|
||||
Switch(
|
||||
checked = checked,
|
||||
// Keep the last two on: with fewer, the pill can't switch.
|
||||
enabled = !checked || canDisable,
|
||||
onCheckedChange = { on -> viewModel.setQuickSwitchViewEnabled(view, on) },
|
||||
)
|
||||
},
|
||||
|
||||
@@ -72,6 +72,7 @@ import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.customActions
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -101,7 +102,6 @@ import de.jeanlucmakiola.calendula.ui.common.TimelineDrop
|
||||
import de.jeanlucmakiola.calendula.ui.common.beginsOn
|
||||
import de.jeanlucmakiola.calendula.ui.common.eventDragAllowed
|
||||
import de.jeanlucmakiola.calendula.ui.common.eventMoveAction
|
||||
import de.jeanlucmakiola.calendula.ui.common.eventTitleOverflow
|
||||
import de.jeanlucmakiola.calendula.ui.common.rememberEventDragSource
|
||||
import de.jeanlucmakiola.calendula.ui.common.rememberTimelineDragController
|
||||
import de.jeanlucmakiola.calendula.ui.common.startInstant
|
||||
@@ -266,7 +266,6 @@ fun WeekScreen(
|
||||
currentYear = currentYear,
|
||||
selectedView = selectedView,
|
||||
onCycleView = { onSelectView(selectedView.next(quickSwitchViews)) },
|
||||
quickSwitchViews = quickSwitchViews,
|
||||
onOpenDrawer = { scope.launch { drawerState.open() } },
|
||||
onOpenSearch = onOpenSearch,
|
||||
onJumpToDate = jumpToDate,
|
||||
@@ -447,7 +446,6 @@ private fun WeekTopBar(
|
||||
currentYear: Int,
|
||||
selectedView: CalendarView,
|
||||
onCycleView: () -> Unit,
|
||||
quickSwitchViews: List<CalendarView>,
|
||||
onOpenDrawer: () -> Unit,
|
||||
onOpenSearch: () -> Unit,
|
||||
onJumpToDate: (LocalDate) -> Unit,
|
||||
@@ -482,7 +480,6 @@ private fun WeekTopBar(
|
||||
}
|
||||
ViewSwitcherPill(
|
||||
current = selectedView,
|
||||
cycle = quickSwitchViews,
|
||||
onCycle = onCycleView,
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
)
|
||||
@@ -659,13 +656,11 @@ private fun AllDayBar(
|
||||
.semantics { contentDescription = title },
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
val titleOverflow = eventTitleOverflow()
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
maxLines = 1,
|
||||
overflow = titleOverflow.overflow,
|
||||
softWrap = titleOverflow.softWrap,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = eventInk(fill),
|
||||
)
|
||||
}
|
||||
@@ -939,13 +934,11 @@ private fun EventBlock(
|
||||
) {
|
||||
Column {
|
||||
if (showTitle) {
|
||||
val titleOverflow = eventTitleOverflow(singleLine = titleMaxLines == 1)
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
maxLines = titleMaxLines,
|
||||
overflow = titleOverflow.overflow,
|
||||
softWrap = titleOverflow.softWrap,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = eventInk(fill, alpha = 0.85f),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@
|
||||
<string name="month_split_expand">Show the whole month</string>
|
||||
<string name="month_split_collapse">Show the day\'s events</string>
|
||||
<string name="settings_quick_switch_header">Quick-switch button</string>
|
||||
<string name="settings_quick_switch_hint">Choose which views the top-right button cycles through, and drag to reorder them. With fewer than two views turned on the button is hidden. Turned-off views stay reachable from the navigation menu.</string>
|
||||
<string name="settings_quick_switch_hint">Choose which views the top-right button cycles through, and drag to reorder them. Turned-off views stay reachable from the navigation menu.</string>
|
||||
<string name="settings_drawer_order_header">Navigation menu</string>
|
||||
<string name="settings_drawer_order_hint">Drag to reorder the views listed in the navigation menu.</string>
|
||||
<string name="reorder_drag_handle">Drag to reorder</string>
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package de.jeanlucmakiola.calendula.ui.common
|
||||
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class EventTitleOverflowTest {
|
||||
|
||||
@Test
|
||||
fun `a single LTR line clips, so the title runs to the chip's edge`() {
|
||||
val result = eventTitleOverflowFor(rtl = false, singleLine = true)
|
||||
assertThat(result.overflow).isEqualTo(TextOverflow.Clip)
|
||||
// Load-bearing: with softWrap on, a clipped line breaks at the last
|
||||
// whole word and shows less title than the ellipsis did (#164).
|
||||
assertThat(result.softWrap).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `RTL keeps the ellipsis, which truncates at the logical end`() {
|
||||
// Clipping with softWrap off cuts at the node's left edge, which in RTL
|
||||
// is the end of the string — the title would lose its beginning.
|
||||
val result = eventTitleOverflowFor(rtl = true, singleLine = true)
|
||||
assertThat(result.overflow).isEqualTo(TextOverflow.Ellipsis)
|
||||
assertThat(result.softWrap).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a multi-line block keeps the ellipsis, since wrapping needs softWrap`() {
|
||||
val result = eventTitleOverflowFor(rtl = false, singleLine = false)
|
||||
assertThat(result.overflow).isEqualTo(TextOverflow.Ellipsis)
|
||||
assertThat(result.softWrap).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multi-line in RTL keeps the ellipsis too`() {
|
||||
val result = eventTitleOverflowFor(rtl = true, singleLine = false)
|
||||
assertThat(result.overflow).isEqualTo(TextOverflow.Ellipsis)
|
||||
assertThat(result.softWrap).isTrue()
|
||||
}
|
||||
}
|
||||
@@ -120,30 +120,4 @@ class ViewBackStackTest {
|
||||
)
|
||||
assertThat(config.cycle).containsExactly(CalendarView.Agenda, CalendarView.Month).inOrder()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a cycle can be emptied down to no views at all`() {
|
||||
// #150: the settings screen no longer holds a floor, so every view may go.
|
||||
val config = QuickSwitchConfig(order = IMPLEMENTED_VIEWS, enabled = emptySet())
|
||||
assertThat(config.cycle).isEmpty()
|
||||
assertThat(config.cycle.size).isLessThan(QuickSwitchConfig.MIN_CYCLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `one enabled view is below the cycle minimum, so the pill hides`() {
|
||||
// A single target is not a switch — it hides rather than becoming a
|
||||
// jump-to-one-view button, which would be dead once you were there.
|
||||
val config = QuickSwitchConfig(order = IMPLEMENTED_VIEWS, enabled = setOf(CalendarView.Day))
|
||||
assertThat(config.cycle).containsExactly(CalendarView.Day)
|
||||
assertThat(config.cycle.size).isLessThan(QuickSwitchConfig.MIN_CYCLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `two enabled views are enough to show the pill`() {
|
||||
val config = QuickSwitchConfig(
|
||||
order = IMPLEMENTED_VIEWS,
|
||||
enabled = setOf(CalendarView.Day, CalendarView.Month),
|
||||
)
|
||||
assertThat(config.cycle.size).isAtLeast(QuickSwitchConfig.MIN_CYCLE)
|
||||
}
|
||||
}
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
|
||||
distributionSha256Sum=bafc141b619ad6350fd975fc903156dd5c151998cc8b058e8c1044ab5f7b031f
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
|
||||
Reference in New Issue
Block a user