mirror of
https://github.com/mihonapp/mihon.git
synced 2025-08-25 15:41:32 +02:00
Compare commits
5 Commits
acaa12ab3f
...
d4a8c2328a
Author | SHA1 | Date | |
---|---|---|---|
|
d4a8c2328a | ||
|
7a543e56b8 | ||
|
254d800380 | ||
|
c47829ce7b | ||
|
272d3af0fb |
@@ -23,26 +23,31 @@ private val UpcomingItemHeight = 96.dp
|
||||
@Composable
|
||||
fun UpcomingItem(
|
||||
upcoming: Manga,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: (manga: Manga) -> Unit = {},
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.clickable(onClick = { onClick(upcoming) })
|
||||
.clickable(onClick = onClick)
|
||||
.height(UpcomingItemHeight)
|
||||
.padding(horizontal = MaterialTheme.padding.medium, vertical = MaterialTheme.padding.small),
|
||||
.padding(
|
||||
horizontal = MaterialTheme.padding.medium,
|
||||
vertical = MaterialTheme.padding.small,
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
MangaCover.Book(
|
||||
modifier = Modifier.fillMaxHeight(),
|
||||
data = upcoming.asMangaCover(),
|
||||
onClick = { onClick(upcoming) },
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = MaterialTheme.padding.large, end = MaterialTheme.padding.small),
|
||||
.padding(
|
||||
start = MaterialTheme.padding.large,
|
||||
end = MaterialTheme.padding.small,
|
||||
),
|
||||
text = upcoming.title,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
maxLines = 2,
|
||||
|
@@ -44,9 +44,9 @@ import java.time.LocalDate
|
||||
|
||||
@Composable
|
||||
fun UpdateUpcomingScreen(
|
||||
onClickUpcoming: (manga: Manga) -> Unit,
|
||||
state: UpdateUpcomingScreenModel.State,
|
||||
modifier: Modifier = Modifier,
|
||||
onClickUpcoming: (manga: Manga) -> Unit = {},
|
||||
) {
|
||||
if (isTabletUi()) {
|
||||
UpdateUpcomingScreenLargeImpl(
|
||||
@@ -65,9 +65,9 @@ fun UpdateUpcomingScreen(
|
||||
|
||||
@Composable
|
||||
internal fun UpdateUpcomingScreenSmallImpl(
|
||||
onClickUpcoming: (manga: Manga) -> Unit,
|
||||
state: UpdateUpcomingScreenModel.State,
|
||||
modifier: Modifier = Modifier,
|
||||
onClickUpcoming: (manga: Manga) -> Unit = {},
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
@@ -112,11 +112,11 @@ internal fun UpdateUpcomingToolbar(
|
||||
|
||||
@Composable
|
||||
internal fun UpdateUpcomingSmallContent(
|
||||
upcoming: ImmutableList<UpcomingUIModel>,
|
||||
contentPadding: PaddingValues,
|
||||
onClickUpcoming: (manga: Manga) -> Unit,
|
||||
upcoming: ImmutableList<UpcomingUIModel>,
|
||||
modifier: Modifier = Modifier,
|
||||
events: ImmutableMap<LocalDate, Int> = persistentMapOf(),
|
||||
onClickUpcoming: (manga: Manga) -> Unit,
|
||||
) {
|
||||
val listState = rememberLazyListState()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
@@ -161,7 +161,7 @@ internal fun UpdateUpcomingSmallContent(
|
||||
is UpcomingUIModel.Item -> {
|
||||
UpcomingItem(
|
||||
upcoming = item.item,
|
||||
onClick = onClickUpcoming,
|
||||
onClick = { onClickUpcoming(item.item) },
|
||||
)
|
||||
}
|
||||
is UpcomingUIModel.Header -> {
|
||||
@@ -268,7 +268,7 @@ internal fun UpdateUpcomingLargeContent(
|
||||
is UpcomingUIModel.Item -> {
|
||||
UpcomingItem(
|
||||
upcoming = item.item,
|
||||
onClick = onClickUpcoming,
|
||||
onClick = { onClickUpcoming(item.item) },
|
||||
)
|
||||
}
|
||||
is UpcomingUIModel.Header -> {
|
||||
|
@@ -48,6 +48,7 @@ fun UpdateScreen(
|
||||
onClickCover: (UpdatesItem) -> Unit,
|
||||
onSelectAll: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
onCalendarClicked: () -> Unit,
|
||||
onUpdateLibrary: () -> Boolean,
|
||||
onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit,
|
||||
onMultiBookmarkClicked: (List<UpdatesItem>, bookmark: Boolean) -> Unit,
|
||||
@@ -55,15 +56,14 @@ fun UpdateScreen(
|
||||
onMultiDeleteClicked: (List<UpdatesItem>) -> Unit,
|
||||
onUpdateSelected: (UpdatesItem, Boolean, Boolean, Boolean) -> Unit,
|
||||
onOpenChapter: (UpdatesItem) -> Unit,
|
||||
onCalendarClicked: () -> Unit
|
||||
) {
|
||||
BackHandler(enabled = state.selectionMode, onBack = { onSelectAll(false) })
|
||||
|
||||
Scaffold(
|
||||
topBar = { scrollBehavior ->
|
||||
UpdatesAppBar(
|
||||
onUpdateLibrary = { onUpdateLibrary() },
|
||||
onCalendarClicked = { onCalendarClicked() },
|
||||
onUpdateLibrary = { onUpdateLibrary() },
|
||||
actionModeCounter = state.selected.size,
|
||||
onSelectAll = { onSelectAll(true) },
|
||||
onInvertSelection = { onInvertSelection() },
|
||||
@@ -129,8 +129,8 @@ fun UpdateScreen(
|
||||
|
||||
@Composable
|
||||
private fun UpdatesAppBar(
|
||||
onUpdateLibrary: () -> Unit,
|
||||
onCalendarClicked: () -> Unit,
|
||||
onUpdateLibrary: () -> Unit,
|
||||
// For action mode
|
||||
actionModeCounter: Int,
|
||||
onSelectAll: () -> Unit,
|
||||
|
@@ -10,10 +10,13 @@ import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
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.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -25,6 +28,7 @@ import eu.kanade.presentation.util.isTabletUi
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import java.time.DayOfWeek
|
||||
import java.time.LocalDate
|
||||
import java.time.YearMonth
|
||||
@@ -33,7 +37,6 @@ import java.time.temporal.WeekFields
|
||||
import java.util.Locale
|
||||
import kotlin.math.ceil
|
||||
|
||||
private val CalenderPadding = 8.dp
|
||||
private val FontSize = 16.sp
|
||||
private const val ExtendedScale = 0.31f
|
||||
private const val MediumScale = 0.60f
|
||||
@@ -53,7 +56,7 @@ fun Calendar(
|
||||
},
|
||||
onClickDay: (day: LocalDate) -> Unit = {},
|
||||
) {
|
||||
val currentYearMonth = remember { mutableStateOf(YearMonth.now()) }
|
||||
var currentYearMonth by remember { mutableStateOf(YearMonth.now()) }
|
||||
val isTabletUi = isTabletUi()
|
||||
|
||||
val localFirstDayOfWeek = WeekFields.of(Locale.getDefault()).firstDayOfWeek.value
|
||||
@@ -74,13 +77,13 @@ fun Calendar(
|
||||
modifier = modifier
|
||||
.wrapContentHeight()
|
||||
.fillMaxWidth()
|
||||
.padding(all = CalenderPadding),
|
||||
.padding(MaterialTheme.padding.small),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
CalenderHeader(
|
||||
yearMonth = currentYearMonth.value,
|
||||
onPreviousClick = { currentYearMonth.value = currentYearMonth.value.minusMonths(1L) },
|
||||
onNextClick = { currentYearMonth.value = currentYearMonth.value.plusMonths(1L) },
|
||||
yearMonth = currentYearMonth,
|
||||
onPreviousClick = { currentYearMonth = currentYearMonth.minusMonths(1L) },
|
||||
onNextClick = { currentYearMonth = currentYearMonth.plusMonths(1L) },
|
||||
)
|
||||
Spacer(modifier = Modifier.padding(vertical = 4.dp))
|
||||
Row(
|
||||
@@ -89,7 +92,7 @@ fun Calendar(
|
||||
CalendarGrid(
|
||||
weekDays = weekDays,
|
||||
labelFormat = labelFormat,
|
||||
currentYearMonth = currentYearMonth.value,
|
||||
currentYearMonth = currentYearMonth,
|
||||
isTabletUi = isTabletUi,
|
||||
events = events,
|
||||
widthModifier = widthModifier,
|
||||
@@ -111,8 +114,8 @@ private fun CalendarGrid(
|
||||
onClickDay: (day: LocalDate) -> Unit = {},
|
||||
widthModifier: Float = 1.0F,
|
||||
) {
|
||||
val daysInMonth = currentYearMonth.month.length(true)
|
||||
val startDayOfMonth = LocalDate.of(currentYearMonth.year, currentYearMonth.monthValue, 1)
|
||||
val daysInMonth = currentYearMonth.month.length(currentYearMonth.isLeapYear)
|
||||
val startDayOfMonth = currentYearMonth.atDay(1)
|
||||
val firstDayOfMonth = startDayOfMonth.dayOfWeek
|
||||
|
||||
// The lower bound for Calendar Days, between -5 and 1 to provide cell offset
|
||||
@@ -135,7 +138,6 @@ private fun CalendarGrid(
|
||||
) {
|
||||
items(weekDays) { item ->
|
||||
Text(
|
||||
modifier = Modifier,
|
||||
text = labelFormat(item),
|
||||
textAlign = TextAlign.Center,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
@@ -144,10 +146,10 @@ private fun CalendarGrid(
|
||||
}
|
||||
items(dayEntries) {
|
||||
if (it > 0) {
|
||||
val localDate = LocalDate.of(currentYearMonth.year, currentYearMonth.month, it)
|
||||
val localDate = currentYearMonth.atDay(it)
|
||||
CalendarDay(
|
||||
date = localDate,
|
||||
onDayClick = onClickDay,
|
||||
onDayClick = { onClickDay(localDate) },
|
||||
events = events[localDate] ?: 0,
|
||||
)
|
||||
}
|
||||
|
@@ -30,9 +30,9 @@ private const val MaxEvents = 3
|
||||
@Composable
|
||||
fun CalendarDay(
|
||||
date: LocalDate,
|
||||
onDayClick: (LocalDate) -> Unit,
|
||||
events: Int,
|
||||
onDayClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
events: Int = 0,
|
||||
) {
|
||||
val today = remember { LocalDate.now() }
|
||||
|
||||
@@ -48,7 +48,7 @@ fun CalendarDay(
|
||||
)
|
||||
.clip(shape = CircleShape)
|
||||
.background(color = Color.Transparent)
|
||||
.clickable(onClick = { onDayClick(date) })
|
||||
.clickable(onClick = onDayClick)
|
||||
.circleLayout()
|
||||
.wrapContentSize()
|
||||
.defaultMinSize(56.dp),
|
||||
|
@@ -14,9 +14,6 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowLeft
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowRight
|
||||
@@ -28,40 +25,31 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.material.padding
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import java.time.Month
|
||||
import java.time.Year
|
||||
import java.time.YearMonth
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Locale
|
||||
|
||||
private val HEADER_PADDING = 8.dp
|
||||
private const val MonthYearChangeAnimationDuration = 200
|
||||
|
||||
@Composable
|
||||
fun CalenderHeader(
|
||||
yearMonth: YearMonth,
|
||||
onPreviousClick: () -> Unit,
|
||||
onNextClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onPreviousClick: () -> Unit = {},
|
||||
onNextClick: () -> Unit = {},
|
||||
arrowShown: Boolean = true,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.padding(all = HEADER_PADDING),
|
||||
.padding(MaterialTheme.padding.medium, MaterialTheme.padding.small),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = yearMonth,
|
||||
transitionSpec = {
|
||||
getAnimation()
|
||||
},
|
||||
transitionSpec = { getAnimation() },
|
||||
label = "Change Month",
|
||||
) { monthYear ->
|
||||
Text(
|
||||
@@ -69,41 +57,24 @@ fun CalenderHeader(
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
)
|
||||
}
|
||||
|
||||
if (arrowShown) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.align(Alignment.CenterVertically),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
Row {
|
||||
IconButton(
|
||||
onClick = onPreviousClick,
|
||||
) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
onPreviousClick()
|
||||
},
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.clip(CircleShape),
|
||||
) {
|
||||
Icon(Icons.Default.KeyboardArrowLeft, stringResource(MR.strings.upcoming_calendar_prev))
|
||||
}
|
||||
Icon(Icons.Default.KeyboardArrowLeft, stringResource(MR.strings.upcoming_calendar_prev))
|
||||
}
|
||||
|
||||
IconButton(
|
||||
onClick = {
|
||||
onNextClick()
|
||||
},
|
||||
modifier = Modifier
|
||||
.wrapContentSize()
|
||||
.clip(CircleShape),
|
||||
) {
|
||||
Icon(Icons.Default.KeyboardArrowRight, stringResource(MR.strings.upcoming_calendar_next))
|
||||
}
|
||||
IconButton(
|
||||
onClick = onNextClick,
|
||||
) {
|
||||
Icon(Icons.Default.KeyboardArrowRight, stringResource(MR.strings.upcoming_calendar_next))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReadOnlyComposable
|
||||
private const val MonthYearChangeAnimationDuration = 200
|
||||
|
||||
private fun AnimatedContentTransitionScope<YearMonth>.getAnimation(): ContentTransform {
|
||||
val movingForward = targetState > initialState
|
||||
|
||||
@@ -138,6 +109,8 @@ private fun getTitleText(monthYear: YearMonth): String {
|
||||
@Composable
|
||||
private fun CalenderHeaderPreview() {
|
||||
CalenderHeader(
|
||||
YearMonth.of(Year.now().value, Month.APRIL),
|
||||
yearMonth = YearMonth.now(),
|
||||
onNextClick = {},
|
||||
onPreviousClick = {},
|
||||
)
|
||||
}
|
||||
|
@@ -16,9 +16,7 @@ class UpdateUpcomingScreen : Screen() {
|
||||
override fun Content() {
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
|
||||
val screenModel = rememberScreenModel {
|
||||
UpdateUpcomingScreenModel()
|
||||
}
|
||||
val screenModel = rememberScreenModel { UpdateUpcomingScreenModel() }
|
||||
val state by screenModel.state.collectAsState()
|
||||
|
||||
UpdateUpcomingScreen(
|
||||
|
@@ -790,7 +790,6 @@
|
||||
<string name="action_view_upcoming">View Upcoming Updates</string>
|
||||
|
||||
<!-- Upcoming -->
|
||||
<string name="calendar_title_format">%1$s %2$s</string>
|
||||
<string name="upcoming_guide">Upcoming Guide</string>
|
||||
<string name="upcoming_calendar_next">Next Month</string>
|
||||
<string name="upcoming_calendar_prev">Previous Month</string>
|
||||
|
Reference in New Issue
Block a user