Коммит cfa103e8 создал по автору Radch-enko's avatar Radch-enko
Просмотр файлов

Feature: add update event functionality and refactor event management in Main module

- Implemented `UpdateEventComponent` with structured state and intent handling for updating events.
- Added `UpdateBookingUseCase` and `DeleteBookingUseCase` for managing booking changes.
- Introduced mapper utilities (`EventInfoMapper`, `UpdateEventComponentStateToEventInfoMapper`) for transforming state and domain models.
- Enhanced `MainComponent` with `onDeleteEvent`, `onBooking`, and `onUpdateEvent` logic.
- Integrated `Calf-UI` library for improved date picker functionality.
- Replaced `EpicDatePicker` with `AdaptiveDatePicker` for streamlined UI.
- Refactored Gradle dependencies and removed unused `epic-calendar-compose` library.
- Updated `BusyRoomInfoComponent` to use `toFormattedString` for better time display.
- Added reusable `FailureSelectRoomView` for handling room selection errors.
владелец 837136b0
......@@ -22,6 +22,7 @@ kotlin {
implementation(libs.findLibrary("kotlin.coroutines.core").get())
implementation(libs.findBundle("koin").get())
implementation(libs.findLibrary("kotlinx-datetime").get())
}
androidMain.dependencies {
implementation(libs.findLibrary("koin-android").get())
......
......@@ -17,6 +17,7 @@ kotlin {
implementation(compose.components.uiToolingPreview)
implementation(libs.findLibrary("coil").get())
implementation(libs.findLibrary("coil.network.ktor").get())
api("com.mohamedrejeb.calf:calf-ui:0.8.0")
}
androidMain.dependencies {
......
package band.effective.office.tablet.core.domain.model
import band.effective.office.tablet.core.domain.util.asInstant
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
sealed class Slot {
abstract val start: LocalDateTime
abstract val finish: LocalDateTime
fun minuteDuration(): Int {
val startMillis = start.toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds()
val finishMillis = finish.toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds()
val startMillis = start.asInstant.toEpochMilliseconds()
val finishMillis = finish.asInstant.toEpochMilliseconds()
return ((finishMillis - startMillis) / 60000).toInt()
}
......
package band.effective.office.tablet.core.domain.util
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.LocalTime
import kotlinx.datetime.format.FormatStringsInDatetimeFormats
import kotlinx.datetime.format.byUnicodePattern
......@@ -21,3 +22,11 @@ fun LocalDateTime.toFormattedString(pattern: String): String {
}
return formatter.format(this)
}
@OptIn(FormatStringsInDatetimeFormats::class)
fun LocalTime.toFormattedString(pattern: String): String {
val formatter = LocalTime.Format {
byUnicodePattern(pattern)
}
return formatter.format(this)
}
......@@ -4,6 +4,7 @@ import kotlin.time.Clock
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Instant
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.LocalTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime
......@@ -25,4 +26,41 @@ fun roundUpToNextQuarter(dateTime: LocalDateTime): LocalDateTime {
}
val LocalDateTime.asInstant get() = toInstant(defaultTimeZone)
val Instant.asLocalDateTime get() = this.toLocalDateTime(defaultTimeZone)
\ Нет новой строки в конце файла
val Instant.asLocalDateTime get() = this.toLocalDateTime(defaultTimeZone)
val LocalTime.Companion.Max
get() = LocalTime(
hour = 23,
minute = 59,
second = 59,
nanosecond = 999999999
)
val LocalTime.Companion.Min
get() = LocalTime(
hour = 0,
minute = 0,
second = 0,
nanosecond = 0
)
fun LocalTime.Companion.of(
hour: Int,
minute: Int
) = LocalTime(hour = hour, minute = minute, second = 0, nanosecond = 0)
fun LocalTime.truncatedToMinute() = LocalTime.of(
hour = hour,
minute = minute
)
fun LocalTime.withHour(hour: Int) =
LocalTime(hour = hour, minute = minute, second = second, nanosecond = nanosecond)
fun LocalTime.withMinute(minute: Int) =
LocalTime(hour = hour, minute = minute, second = second, nanosecond = nanosecond)
fun LocalTime.isBefore(other: LocalTime) = this < other
fun LocalTime.isAfter(other: LocalTime) = this > other
\ Нет новой строки в конце файла
......@@ -5,7 +5,6 @@ plugins {
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.epicarchitect:epic-calendar-compose:1.0.8")
implementation(libs.kotlinx.datetime)
implementation(libs.decompose)
implementation(libs.decompose.compose.jetbrains)
......
package band.effective.office.tablet.core.ui.date
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import band.effective.office.tablet.core.ui.Res
import band.effective.office.tablet.core.ui.arrow_left
import band.effective.office.tablet.core.ui.theme.LocalCustomColorsPalette
import band.effective.office.tablet.core.ui.theme.header6
import epicarchitect.calendar.compose.basis.BasisDayOfMonthContent
import epicarchitect.calendar.compose.basis.BasisDayOfWeekContent
import epicarchitect.calendar.compose.basis.config.LocalBasisEpicCalendarConfig
import epicarchitect.calendar.compose.basis.contains
import epicarchitect.calendar.compose.basis.localizedBySystem
import epicarchitect.calendar.compose.basis.state.LocalBasisEpicCalendarState
import epicarchitect.calendar.compose.datepicker.EpicDatePicker
import epicarchitect.calendar.compose.datepicker.state.EpicDatePickerState
import epicarchitect.calendar.compose.datepicker.state.LocalEpicDatePickerState
import epicarchitect.calendar.compose.pager.state.EpicCalendarPagerState
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.datetime.LocalDate
import org.jetbrains.compose.resources.painterResource
@Composable
fun DatePickerView(
modifier: Modifier = Modifier,
epicDatePickerState: EpicDatePickerState,
) {
val coroutineScope = rememberCoroutineScope()
Column(modifier = modifier) {
DatePickerTitleView(
epicDatePickerState = epicDatePickerState,
onClickNextMonth = {
scrollMonth(
coroutineScope = coroutineScope,
pagerState = epicDatePickerState.pagerState,
amount = 1
)
},
onClickPreviousMonth = {
scrollMonth(
coroutineScope = coroutineScope,
pagerState = epicDatePickerState.pagerState,
amount = -1
)
}
)
EpicDatePicker(
state = epicDatePickerState,
dayOfWeekContent = CustomDayOfWeekContent,
dayOfMonthContent = CustomDayOfMonthContent,
modifier = Modifier.background(Color.Transparent),
)
}
}
@Composable
private fun DatePickerTitleView(
epicDatePickerState: EpicDatePickerState,
onClickNextMonth: () -> Unit,
onClickPreviousMonth: () -> Unit
) {
Row(
modifier = Modifier
.background(
LocalCustomColorsPalette.current.mountainBackground,
RoundedCornerShape(12.dp)
)
.fillMaxWidth().fillMaxHeight(0.15f)
.clip(RoundedCornerShape(12.dp)),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Button(
modifier = Modifier.fillMaxHeight(),
onClick = { onClickPreviousMonth() },
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
)
) {
Image(
modifier = Modifier,
painter = painterResource(Res.drawable.arrow_left),
contentDescription = null
)
}
Text(
text = if (epicDatePickerState.selectedDates.isNotEmpty()) {
stringFormat(epicDatePickerState.selectedDates.firstOrNull())
} else {
epicDatePickerState.pagerState.currentMonth.month.toString() // TODO
},
style = header6,
color = LocalCustomColorsPalette.current.primaryTextAndIcon,
)
Button(
modifier = Modifier.fillMaxHeight(),
onClick = { onClickNextMonth() },
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
)
) {
Image(
modifier = Modifier,
painter = painterResource(Res.drawable.arrow_left),
contentDescription = null
)
}
}
}
private fun scrollMonth(
coroutineScope: CoroutineScope,
pagerState: EpicCalendarPagerState,
amount: Int
) {
coroutineScope.launch {
pagerState.scrollMonths(amount)
}
}
private val CustomDayOfWeekContent: BasisDayOfWeekContent = { dayOfWeek ->
val config = LocalBasisEpicCalendarConfig.current
Text(
text = dayOfWeek.localizedBySystem(),
textAlign = TextAlign.Center,
color = config.contentColor,
style = header6,
maxLines = 1
)
}
private val CustomDayOfMonthContent: BasisDayOfMonthContent = { date ->
val basisState = LocalBasisEpicCalendarState.current!!
val pickerState = LocalEpicDatePickerState.current!!
val selectedDays = pickerState.selectedDates
val selectionMode = pickerState.selectionMode
val isSelected = remember(selectionMode, selectedDays, date) {
when (selectionMode) {
is EpicDatePickerState.SelectionMode.Range -> {
if (selectedDays.isEmpty()) false
else date in selectedDays.min()..selectedDays.max()
}
is EpicDatePickerState.SelectionMode.Single -> {
date in selectedDays
}
}
}
Text(
modifier = Modifier.alpha(
if (date in basisState.currentMonth) 1.0f
else 0.5f
),
text = date.dayOfMonth.toString(),
textAlign = TextAlign.Center,
style = header6,
maxLines = 1,
color = if (isSelected) pickerState.config.selectionContentColor
else pickerState.config.pagerConfig.basisConfig.contentColor
)
}
private fun stringFormat(date: LocalDate?): String {
val monthName = date?.month
return "${date?.dayOfMonth} $monthName".lowercase()
}
\ Нет новой строки в конце файла
......@@ -2,14 +2,6 @@ plugins {
id("band.effective.office.client.kmp.feature")
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.epicarchitect:epic-calendar-compose:1.0.8")
}
}
}
compose.resources {
publicResClass = false
packageOfResClass = "band.effective.office.tablet.feature.main"
......
......@@ -20,7 +20,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import band.effective.office.tablet.core.domain.model.EventInfo
import band.effective.office.tablet.core.domain.util.timeFormatter
import band.effective.office.tablet.core.domain.util.toFormattedString
import band.effective.office.tablet.core.ui.theme.LocalCustomColorsPalette
import band.effective.office.tablet.core.ui.theme.h5
import band.effective.office.tablet.core.ui.theme.roomInfoColor
......@@ -62,7 +62,7 @@ fun BusyRoomInfoComponent(
isError = isError
) {
Text(
text = stringResource(Res.string.room_occupancy_date, timeFormatter.format(event.finishTime)) +
text = stringResource(Res.string.room_occupancy_date, event.finishTime.toFormattedString("HH:mm")) +
" " + if (timeToFinish > 0) stringResource(Res.string.room_occupancy_time, timeToFinish.getDuration()) else "",
style = MaterialTheme.typography.h5,
color = roomInfoColor
......
......@@ -40,6 +40,7 @@ fun RoomInfoLeftPanel(
onCancelEventRequest: () -> Unit,
timeToNextEvent: Int,
isDisconnect: Boolean,
onOpenDateTimePickerModal: () -> Unit,
) {
val slotState by slotComponent.state.collectAsState()
Box(
......@@ -64,7 +65,7 @@ fun RoomInfoLeftPanel(
selectDate = selectedDate,
increment = onIncrementData,
decrement = onDecrementData,
onOpenDateTimePickerModal = { },
onOpenDateTimePickerModal = onOpenDateTimePickerModal,
currentDate = Clock.System.now(),
back = onResetDate,
)
......
package band.effective.office.tablet.feature.main.di
import band.effective.office.tablet.feature.main.domain.CreateFastBookingUseCase
import band.effective.office.tablet.feature.main.domain.CreateBookingUseCase
import band.effective.office.tablet.feature.main.domain.DeleteBookingUseCase
import band.effective.office.tablet.feature.main.domain.FreeUpRoomUseCase
import band.effective.office.tablet.feature.main.domain.GetRoomIndexUseCase
import band.effective.office.tablet.feature.main.domain.GetSlotsByRoomUseCase
import band.effective.office.tablet.feature.main.domain.GetTimeToNextEventUseCase
import band.effective.office.tablet.feature.main.domain.RemoveFastBookingUseCase
import band.effective.office.tablet.feature.main.domain.mapper.SlotUiMapper
import band.effective.office.tablet.feature.main.domain.UpdateBookingUseCase
import band.effective.office.tablet.feature.main.domain.mapper.EventInfoMapper
import band.effective.office.tablet.feature.main.domain.mapper.UpdateEventComponentStateToEventInfoMapper
import band.effective.office.tablet.feature.main.presentation.mapper.SlotUiMapper
import org.koin.dsl.module
val mainScreenModule = module {
......@@ -14,8 +17,11 @@ val mainScreenModule = module {
single { GetTimeToNextEventUseCase() }
single { GetSlotsByRoomUseCase(get()) }
single { FreeUpRoomUseCase(get()) }
single { CreateFastBookingUseCase(get()) }
single { RemoveFastBookingUseCase(get()) }
single { CreateBookingUseCase(get()) }
single { DeleteBookingUseCase(get()) }
single { UpdateBookingUseCase(get()) }
single { SlotUiMapper() }
single { EventInfoMapper() }
single { UpdateEventComponentStateToEventInfoMapper() }
}
\ Нет новой строки в конце файла
......@@ -3,7 +3,7 @@ package band.effective.office.tablet.feature.main.domain
import band.effective.office.tablet.core.domain.model.EventInfo
import band.effective.office.tablet.core.domain.repository.EventManagerRepository
class CreateFastBookingUseCase(
class CreateBookingUseCase(
private val eventManagerRepository: EventManagerRepository,
) {
suspend operator fun invoke(roomName: String, eventInfo: EventInfo) =
......
......@@ -3,7 +3,7 @@ package band.effective.office.tablet.feature.main.domain
import band.effective.office.tablet.core.domain.model.EventInfo
import band.effective.office.tablet.core.domain.repository.EventManagerRepository
class RemoveFastBookingUseCase(
class DeleteBookingUseCase(
private val eventManagerRepository: EventManagerRepository,
) {
......
package band.effective.office.tablet.feature.main.domain
import band.effective.office.tablet.core.domain.model.EventInfo
import band.effective.office.tablet.core.domain.repository.EventManagerRepository
class UpdateBookingUseCase(
private val eventManagerRepository: EventManagerRepository,
) {
suspend operator fun invoke(
roomName: String,
eventInfo: EventInfo,
) = eventManagerRepository.updateBooking(
roomName = roomName,
eventInfo = eventInfo,
)
}
\ Нет новой строки в конце файла
package band.effective.office.tablet.feature.main.domain.mapper
import band.effective.office.tablet.core.domain.model.EventInfo
import band.effective.office.tablet.core.domain.model.Slot
import band.effective.office.tablet.core.domain.util.asInstant
import band.effective.office.tablet.feature.main.presentation.updateEvent.State
class EventInfoMapper {
fun mapToSlot(eventInfo: EventInfo): Slot =
Slot.EventSlot(start = eventInfo.startTime, finish = eventInfo.finishTime, eventInfo = eventInfo)
fun mapToUpdateBookingState(eventInfo: EventInfo): State {
val duration = eventInfo.finishTime.asInstant.minus(eventInfo.startTime.asInstant).inWholeMinutes.toInt()
return State.defaultValue.copy(
date = eventInfo.startTime,
duration = duration,
selectOrganizer = eventInfo.organizer,
inputText = eventInfo.organizer.fullName,
event = eventInfo
)
}
}
\ Нет новой строки в конце файла
package band.effective.office.tablet.feature.main.domain.mapper
import band.effective.office.tablet.core.domain.model.EventInfo
import band.effective.office.tablet.core.domain.util.asInstant
import band.effective.office.tablet.core.domain.util.asLocalDateTime
import band.effective.office.tablet.feature.main.presentation.updateEvent.State
import kotlin.time.Duration.Companion.minutes
class UpdateEventComponentStateToEventInfoMapper {
fun map(state: State): EventInfo = EventInfo(
startTime = state.date,
finishTime = state.date.asInstant.plus(state.duration.minutes).asLocalDateTime,
organizer = state.selectOrganizer,
id = state.event.id,
isLoading = false,
)
}
\ Нет новой строки в конце файла
package band.effective.office.tablet.feature.main.presentation.common
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun AlertButton(
modifier: Modifier = Modifier,
onClick: () -> Unit,
content: @Composable RowScope.() -> Unit
) {
Button(
modifier = modifier
.clip(RoundedCornerShape(100.dp)).border(
width = 3.dp,
shape = RoundedCornerShape(100.dp),
color = MaterialTheme.colorScheme.onPrimary
),
colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent),
onClick = { onClick() }
) {
content()
}
}
\ Нет новой строки в конце файла
package band.effective.office.tablet.feature.main.presentation.common
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import band.effective.office.tablet.core.ui.common.Loader
import band.effective.office.tablet.core.ui.theme.CustomDarkColors
import band.effective.office.tablet.core.ui.theme.LocalCustomColorsPalette
import band.effective.office.tablet.core.ui.theme.h6_button
@Composable
fun BookingButtonView(
modifier: Modifier,
shape: RoundedCornerShape,
text: String,
onClick: () -> Unit,
isLoading: Boolean,
) {
val isPressed = remember { mutableStateOf(false) }
val colorButton =
if (isPressed.value) LocalCustomColorsPalette.current.pressedPrimaryButton else MaterialTheme.colorScheme.primary
Button(
modifier = modifier,
elevation = ButtonDefaults.elevatedButtonElevation(0.dp),
colors = ButtonDefaults.buttonColors(colorButton),
shape = shape,
onClick = {
isPressed.value = !isPressed.value
onClick()
}) {
Box(contentAlignment = Alignment.Center) {
if (isLoading) Loader()
else Text(
text = text,
style = MaterialTheme.typography.h6_button,
color = when (LocalCustomColorsPalette.current) {
CustomDarkColors -> LocalCustomColorsPalette.current.primaryTextAndIcon
else -> MaterialTheme.colorScheme.background
}
)
}
}
}
\ Нет новой строки в конце файла
package band.effective.office.tablet.feature.main.presentation.common
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import band.effective.office.tablet.core.domain.model.EventInfo
import band.effective.office.tablet.core.domain.util.timeFormatter
import band.effective.office.tablet.core.ui.theme.LocalCustomColorsPalette
import band.effective.office.tablet.core.ui.theme.h5
import band.effective.office.tablet.feature.main.Res
import band.effective.office.tablet.feature.main.date_booking
import kotlinx.datetime.format
import org.jetbrains.compose.resources.stringResource
@Composable
fun DateTimeView(modifier: Modifier, eventInfo: EventInfo) {
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
Text(
text = stringResource(
Res.string.date_booking,
eventInfo.startTime,
eventInfo.startTime.format(timeFormatter),
eventInfo.finishTime.format(timeFormatter)
),
style = MaterialTheme.typography.h5,
color = LocalCustomColorsPalette.current.primaryTextAndIcon
)
}
}
\ Нет новой строки в конце файла
package band.effective.office.tablet.feature.main.presentation.common
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import band.effective.office.tablet.core.ui.Res
import band.effective.office.tablet.core.ui.minus_date_button_string
import band.effective.office.tablet.core.ui.plus_date_button_string
import band.effective.office.tablet.core.ui.select_length_title
import band.effective.office.tablet.core.ui.short_hours
import band.effective.office.tablet.core.ui.short_minuets
import band.effective.office.tablet.core.ui.theme.LocalCustomColorsPalette
import band.effective.office.tablet.core.ui.theme.h4
import band.effective.office.tablet.core.ui.theme.h6
import band.effective.office.tablet.core.ui.theme.h8
import org.jetbrains.compose.resources.stringResource
@Composable
fun EventDurationView(
modifier: Modifier = Modifier,
currentDuration: Int,
increment: () -> Unit,
decrement: () -> Unit
) {
Column(modifier = modifier) {
Text(
text = stringResource(Res.string.select_length_title),
color = LocalCustomColorsPalette.current.secondaryTextAndIcon,
style = MaterialTheme.typography.h8
)
Spacer(modifier = Modifier.height(10.dp))
Row(
modifier = Modifier.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(
modifier = Modifier.fillMaxHeight().weight(1f).clip(RoundedCornerShape(15.dp)),
onClick = { decrement() },
colors = ButtonDefaults.buttonColors(
containerColor = LocalCustomColorsPalette.current.elevationBackground
)
) {
Text(
text = stringResource(Res.string.minus_date_button_string),
style = MaterialTheme.typography.h6
)
}
Text(
modifier = Modifier.weight(1f),
text = currentDuration.getDurationString(),
color = MaterialTheme.colorScheme.onPrimary,
style = MaterialTheme.typography.h4,
textAlign = TextAlign.Center
)
Button(
modifier = Modifier.fillMaxHeight().weight(1f).clip(RoundedCornerShape(15.dp)),
onClick = {
increment()
},
colors = ButtonDefaults.buttonColors(
containerColor = LocalCustomColorsPalette.current.elevationBackground
)
) {
Text(
text = stringResource(Res.string.plus_date_button_string),
style = MaterialTheme.typography.h6
)
}
}
}
}
@Composable
private fun Int.getDurationString(): String {
val hours = this / 60
val minutes = this % 60
return when {
hours == 0 -> "$minutes${stringResource(Res.string.short_minuets)}"
minutes == 0 -> "$hours${stringResource(Res.string.short_hours)}"
else -> "$hours${Res.string.short_hours} $minutes${Res.string.short_minuets}"
}
}
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать