Coverage Summary for Class: TransactionsListPeriodPagerKt (com.georgeci.moneysurfer.feature.transaction.list)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| TransactionsListPeriodPagerKt |
45.5%
(5/11)
|
52.4%
(11/21)
|
60.3%
(35/58)
|
76.2%
(607/797)
|
| TransactionsListPeriodPagerKt$WhenMappings |
|
| Total |
45.5%
(5/11)
|
52.4%
(11/21)
|
60.3%
(35/58)
|
76.2%
(607/797)
|
package com.georgeci.moneysurfer.feature.transaction.list
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Text
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 com.georgeci.moneysurfer.domain.preferences.TransactionPeriodMode
import com.georgeci.moneysurfer.uikit.components.base.SurferPeriodArrow
import com.georgeci.moneysurfer.uikit.components.base.SurferPeriodPager
import kotlinx.datetime.LocalDate
import kotlinx.datetime.number
import moneysurfer.feature.transaction.generated.resources.Res
import moneysurfer.feature.transaction.generated.resources.transactions_list_months
import moneysurfer.feature.transaction.generated.resources.transactions_list_months_short
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_all_time
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_all_time_sub
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_mode_all_time
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_mode_month
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_mode_week
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_next
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_previous
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_week_range
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_week_range_cross_month
import moneysurfer.feature.transaction.generated.resources.transactions_list_period_week_sub
import org.jetbrains.compose.resources.stringArrayResource
import org.jetbrains.compose.resources.stringResource
/**
* The design's `PeriodPager`, plus a menu on the label: the design never drew a mode switcher, and
* the pill is the only place on the screen where the period is already the subject.
*
* In all-time mode the arrows are disabled rather than the pager hidden (the design's
* `All time · arrows disabled` variant) — hiding it would strand the user with no way back.
*/
@Composable
internal fun PeriodPager(
state: TransactionsByAccountState.Content,
onEvent: (TransactionsByAccountEvent) -> Unit,
modifier: Modifier = Modifier,
) {
var menuExpanded by remember { mutableStateOf(false) }
Box(modifier = modifier) {
SurferPeriodPager(
label = state.period.label(),
sublabel = state.period.sublabel(),
previous = SurferPeriodArrow(
onClick = { onEvent(TransactionsByAccountEvent.OnPreviousPeriodClick) },
enabled = state.canGoToPreviousPeriod,
contentDescription = stringResource(Res.string.transactions_list_period_previous),
),
next = SurferPeriodArrow(
onClick = { onEvent(TransactionsByAccountEvent.OnNextPeriodClick) },
enabled = state.canGoToNextPeriod,
contentDescription = stringResource(Res.string.transactions_list_period_next),
),
onLabelClick = { menuExpanded = true },
)
DropdownMenu(
expanded = menuExpanded,
onDismissRequest = { menuExpanded = false },
) {
TransactionPeriodMode.entries.forEach { mode ->
DropdownMenuItem(
text = { Text(mode.label()) },
onClick = {
menuExpanded = false
onEvent(TransactionsByAccountEvent.OnPeriodModeChanged(mode))
},
)
}
}
}
}
@Composable
private fun TransactionPeriodMode.label(): String = stringResource(
when (this) {
TransactionPeriodMode.Month -> Res.string.transactions_list_period_mode_month
TransactionPeriodMode.Week -> Res.string.transactions_list_period_mode_week
TransactionPeriodMode.AllTime -> Res.string.transactions_list_period_mode_all_time
},
)
@Composable
private fun TransactionPeriodUi.label(): String = when (this) {
is TransactionPeriodUi.Month -> monthNames()[monthNumber - 1]
is TransactionPeriodUi.Week -> weekRangeLabel(from, to)
TransactionPeriodUi.AllTime -> stringResource(Res.string.transactions_list_period_all_time)
}
@Composable
private fun TransactionPeriodUi.sublabel(): String = when (this) {
is TransactionPeriodUi.Month -> year.toString()
is TransactionPeriodUi.Week ->
stringResource(Res.string.transactions_list_period_week_sub, weekNumber, weekYear)
TransactionPeriodUi.AllTime -> stringResource(Res.string.transactions_list_period_all_time_sub)
}
/** `Mar 25 – 31`, or `Mar 30 – Apr 5` when the week straddles two months. */
@Composable
private fun weekRangeLabel(from: LocalDate, to: LocalDate): String {
val shortMonths = stringArrayResource(Res.array.transactions_list_months_short)
val fromMonth = shortMonths[from.month.number - 1]
return if (from.month == to.month) {
stringResource(Res.string.transactions_list_period_week_range, fromMonth, from.day, to.day)
} else {
stringResource(
Res.string.transactions_list_period_week_range_cross_month,
fromMonth,
from.day,
shortMonths[to.month.number - 1],
to.day,
)
}
}
/** Standalone month names — the pager label is a sentence of its own. */
@Composable
private fun monthNames(): List<String> = stringArrayResource(Res.array.transactions_list_months)