Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76cdc1c535 | ||
|
|
68c0a262fa | ||
|
|
39e13e86d2 | ||
|
|
1cc7f40f7e | ||
|
|
8a15325fdc | ||
|
|
7f977971ed | ||
|
|
632155c016 | ||
|
|
8834884d4e | ||
|
|
236372d740 | ||
|
|
678a526cb9 | ||
|
|
84fd51baf6 | ||
|
|
450b8b0107 | ||
|
|
8078fb4f10 | ||
|
|
46b88cc03e | ||
|
|
6afcfd49f1 | ||
|
|
5f77cac7ea |
@@ -15,7 +15,7 @@ jobs:
|
||||
detect:
|
||||
# Gitea only; see the same guard in release.yaml.
|
||||
if: github.repository_owner == 'makiolaj'
|
||||
runs-on: docker
|
||||
runs-on: light
|
||||
outputs:
|
||||
is_beta: ${{ steps.v.outputs.is_beta }}
|
||||
version: ${{ steps.v.outputs.version }}
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
beta:
|
||||
needs: detect
|
||||
if: needs.detect.outputs.is_beta == 'true'
|
||||
runs-on: docker
|
||||
runs-on: gradle
|
||||
env:
|
||||
ANDROID_HOME: /opt/android-sdk
|
||||
ANDROID_SDK_ROOT: /opt/android-sdk
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
# secrets. repository_owner differs between the two forges regardless of
|
||||
# URL, proxy or instance rename, so this closes it permanently.
|
||||
if: github.repository_owner == 'makiolaj'
|
||||
runs-on: docker
|
||||
runs-on: light
|
||||
outputs:
|
||||
is_release: ${{ steps.v.outputs.is_release }}
|
||||
version: ${{ steps.v.outputs.version }}
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
release:
|
||||
needs: detect
|
||||
if: needs.detect.outputs.is_release == 'true' || github.event_name == 'workflow_dispatch'
|
||||
runs-on: docker
|
||||
runs-on: gradle
|
||||
env:
|
||||
ANDROID_HOME: /opt/android-sdk
|
||||
ANDROID_SDK_ROOT: /opt/android-sdk
|
||||
|
||||
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2.22.5] — 2026-10-07
|
||||
|
||||
### Fixed
|
||||
- **Reopening the app the next morning shows the right day.** The month view used to mark yesterday as today and keep the day you picked the evening before selected, so you had to tap today to see its events. Every view now moves on to the new day at midnight and when you come back to the app. A view you browsed to another date stays where it is ([#373]).
|
||||
|
||||
## [2.22.4] — 2026-10-07
|
||||
|
||||
### Fixed
|
||||
@@ -1843,3 +1848,4 @@ automatically, with zero telemetry and no internet permission.
|
||||
[#361]: https://codeberg.org/jlmakiola/calendula/issues/361
|
||||
[#363]: https://codeberg.org/jlmakiola/calendula/issues/363
|
||||
[#364]: https://codeberg.org/jlmakiola/calendula/issues/364
|
||||
[#373]: https://codeberg.org/jlmakiola/calendula/issues/373
|
||||
|
||||
@@ -32,8 +32,8 @@ android {
|
||||
// (up to 2.22.3: 2.22.3 -> 22203; from 2.22.4: 2.23.0-beta.1 -> 2230001,
|
||||
// 2.22.4 -> 2220499), and CI fails if the committed one doesn't match.
|
||||
// See docs/RELEASING.md.
|
||||
versionCode = 2220499
|
||||
versionName = "2.22.4"
|
||||
versionCode = 2220599
|
||||
versionName = "2.22.5"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import de.jeanlucmakiola.calendula.data.contacts.ContactSpecialDatesDataSource
|
||||
import de.jeanlucmakiola.calendula.data.contacts.SpecialDatesCalendarSpec
|
||||
import de.jeanlucmakiola.calendula.data.reminders.ProviderReminderInstanceSource
|
||||
import de.jeanlucmakiola.calendula.data.reminders.ReminderInstanceSource
|
||||
import de.jeanlucmakiola.calendula.data.time.AndroidTodaySource
|
||||
import de.jeanlucmakiola.calendula.data.time.TodaySource
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import javax.inject.Singleton
|
||||
@@ -61,6 +63,12 @@ abstract class DataBindModule {
|
||||
abstract fun bindSpecialDatesCalendarSpec(
|
||||
impl: AndroidSpecialDatesCalendarSpec,
|
||||
): SpecialDatesCalendarSpec
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
abstract fun bindTodaySource(
|
||||
impl: AndroidTodaySource,
|
||||
): TodaySource
|
||||
}
|
||||
|
||||
@Module
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package de.jeanlucmakiola.calendula.data.time
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import androidx.core.content.ContextCompat
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Clock
|
||||
|
||||
/** The current local date, re-emitted whenever it changes (#373). */
|
||||
interface TodaySource {
|
||||
val today: Flow<LocalDate>
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-reads the date on every minute boundary while collected, and at once on the
|
||||
* system's date, time and zone broadcasts, which can arrive late or not at all.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class AndroidTodaySource @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
) : TodaySource {
|
||||
|
||||
override val today: Flow<LocalDate> = callbackFlow {
|
||||
val receiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
trySend(Unit)
|
||||
}
|
||||
}
|
||||
val filter = IntentFilter().apply {
|
||||
addAction(Intent.ACTION_DATE_CHANGED)
|
||||
addAction(Intent.ACTION_TIME_CHANGED)
|
||||
addAction(Intent.ACTION_TIMEZONE_CHANGED)
|
||||
}
|
||||
ContextCompat.registerReceiver(context, receiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED)
|
||||
awaitClose { context.unregisterReceiver(receiver) }
|
||||
}
|
||||
.onStart { emit(Unit) }
|
||||
.transformLatest {
|
||||
while (true) {
|
||||
emit(currentDate())
|
||||
delay(MINUTE_MILLIS - Clock.System.now().toEpochMilliseconds() % MINUTE_MILLIS)
|
||||
}
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
private const val MINUTE_MILLIS = 60_000L
|
||||
|
||||
fun currentDate(): LocalDate = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date
|
||||
@@ -150,6 +150,15 @@ fun CalendarHost(
|
||||
// The date every view opens on and carries along (#184); tapping a day
|
||||
// anywhere focuses it and opens the day view there.
|
||||
val focus = rememberSaveable(saver = ViewFocusSaver) { ViewFocus(localToday()) }
|
||||
// A focus still on yesterday follows the date over, so the next view opened
|
||||
// doesn't land on the old day (#373); one moved elsewhere stays put.
|
||||
val today = viewModel.today.collectAsStateWithLifecycle().value
|
||||
var focusToday by rememberSaveable { mutableStateOf(today.toString()) }
|
||||
LaunchedEffect(today) {
|
||||
val old = LocalDate.parse(focusToday)
|
||||
if (old != today && focus.date == old) focus.date = today
|
||||
focusToday = today.toString()
|
||||
}
|
||||
|
||||
val switchScope = rememberCoroutineScope()
|
||||
val switchTo: ((List<CalendarView>) -> List<CalendarView>) -> Unit = { move ->
|
||||
|
||||
@@ -4,12 +4,15 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import de.jeanlucmakiola.calendula.data.prefs.SettingsPrefs
|
||||
import de.jeanlucmakiola.calendula.data.time.TodaySource
|
||||
import de.jeanlucmakiola.calendula.data.time.currentDate
|
||||
import de.jeanlucmakiola.calendula.ui.common.CalendarView
|
||||
import de.jeanlucmakiola.calendula.ui.common.IMPLEMENTED_VIEWS
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.datetime.LocalDate
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@@ -21,8 +24,16 @@ import javax.inject.Inject
|
||||
@HiltViewModel
|
||||
class CalendarHostViewModel @Inject constructor(
|
||||
prefs: SettingsPrefs,
|
||||
todaySource: TodaySource,
|
||||
) : ViewModel() {
|
||||
|
||||
/** Today, kept current across midnight so the shared focus can follow it (#373). */
|
||||
val today: StateFlow<LocalDate> = todaySource.today.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5_000L),
|
||||
initialValue = currentDate(),
|
||||
)
|
||||
|
||||
val defaultView: StateFlow<CalendarView?> = prefs.defaultView.stateIn(
|
||||
scope = viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5_000L),
|
||||
|
||||
@@ -8,6 +8,8 @@ import de.jeanlucmakiola.calendula.data.di.IoDispatcher
|
||||
import de.jeanlucmakiola.calendula.data.prefs.PastEventDisplay
|
||||
import de.jeanlucmakiola.calendula.data.prefs.SettingsPrefs
|
||||
import de.jeanlucmakiola.calendula.data.prefs.firstDayOfWeek
|
||||
import de.jeanlucmakiola.calendula.data.time.TodaySource
|
||||
import de.jeanlucmakiola.calendula.data.time.currentDate
|
||||
import de.jeanlucmakiola.calendula.domain.CalendarSource
|
||||
import de.jeanlucmakiola.calendula.domain.EventInstance
|
||||
import de.jeanlucmakiola.calendula.domain.FailureReason
|
||||
@@ -21,6 +23,7 @@ import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.datetime.DateTimeUnit
|
||||
import kotlinx.datetime.DayOfWeek
|
||||
@@ -30,8 +33,6 @@ import kotlinx.datetime.atStartOfDayIn
|
||||
import kotlinx.datetime.atTime
|
||||
import kotlinx.datetime.plus
|
||||
import kotlinx.datetime.toInstant
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -40,6 +41,7 @@ import javax.inject.Inject
|
||||
class AgendaViewModel @Inject constructor(
|
||||
private val repository: CalendarRepository,
|
||||
settingsPrefs: SettingsPrefs,
|
||||
todaySource: TodaySource,
|
||||
@IoDispatcher private val io: CoroutineDispatcher,
|
||||
) : ViewModel() {
|
||||
|
||||
@@ -84,11 +86,25 @@ class AgendaViewModel @Inject constructor(
|
||||
private val zone = TimeZone.currentSystemDefault()
|
||||
|
||||
private val todayDate: LocalDate
|
||||
get() = Clock.System.now().toLocalDateTime(zone).date
|
||||
get() = currentDate()
|
||||
|
||||
private val _anchor = MutableStateFlow(todayDate)
|
||||
val anchor: StateFlow<LocalDate> = _anchor
|
||||
|
||||
private var lastToday = todayDate
|
||||
|
||||
/**
|
||||
* Today, kept current across midnight (#373). An agenda still starting on
|
||||
* yesterday moves on to the new day; one jumped elsewhere stays put.
|
||||
*/
|
||||
private val today: StateFlow<LocalDate> = todaySource.today
|
||||
.onEach { date ->
|
||||
val old = lastToday
|
||||
lastToday = date
|
||||
if (old != date && _anchor.value == old) _anchor.value = date
|
||||
}
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000L), todayDate)
|
||||
|
||||
// A transient, in-view override of the saved agenda range. Held in memory
|
||||
// (not persisted), so it survives view switches and rotation within the
|
||||
// session but resets to the saved default when the app is relaunched.
|
||||
@@ -113,8 +129,9 @@ class AgendaViewModel @Inject constructor(
|
||||
combine(
|
||||
repository.calendars(),
|
||||
repository.instances(window),
|
||||
) { calendars, instances ->
|
||||
buildState(params, calendars, instances)
|
||||
today,
|
||||
) { calendars, instances, today ->
|
||||
buildState(params, calendars, instances, today)
|
||||
}
|
||||
}
|
||||
.catch { emit(AgendaUiState.Failure(FailureReason.ProviderUnavailable)) }
|
||||
@@ -156,6 +173,7 @@ class AgendaViewModel @Inject constructor(
|
||||
params: AgendaParams,
|
||||
calendars: List<CalendarSource>,
|
||||
instances: List<EventInstance>,
|
||||
today: LocalDate,
|
||||
): AgendaUiState {
|
||||
calendarListFailure(calendars)?.let { return AgendaUiState.Failure(it) }
|
||||
val anchor = params.anchor
|
||||
@@ -166,7 +184,7 @@ class AgendaViewModel @Inject constructor(
|
||||
val days = groupAgendaDays(anchor, rangeEnd, instances, zone)
|
||||
return AgendaUiState.Success(
|
||||
anchor = anchor,
|
||||
today = todayDate,
|
||||
today = today,
|
||||
days = days,
|
||||
range = params.range,
|
||||
rangeIsOverride = params.rangeIsOverride,
|
||||
|
||||
@@ -87,6 +87,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -197,13 +198,17 @@ import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.plus
|
||||
import kotlinx.datetime.YearMonth
|
||||
import kotlinx.datetime.toJavaLocalDate
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
import java.time.format.TextStyle as JavaTextStyle
|
||||
import java.util.Locale
|
||||
|
||||
private val LocalTodayPulse = staticCompositionLocalOf { 0 }
|
||||
|
||||
/** Live today for the pages, whose cached states may have been built before midnight (#373). */
|
||||
private val LocalMonthToday = compositionLocalOf<LocalDate?> { null }
|
||||
|
||||
private fun MonthUiState.Success.withToday(today: LocalDate?): MonthUiState.Success =
|
||||
if (today == null || today == this.today) this else copy(today = today)
|
||||
private val LocalOpenWeek = staticCompositionLocalOf<((LocalDate) -> Unit)?> { null }
|
||||
|
||||
/** A brief push from today's full cell into its immediate neighbours. */
|
||||
@@ -319,12 +324,7 @@ fun MonthScreen(
|
||||
}
|
||||
val dense = viewStyle == MonthViewStyle.Dense
|
||||
|
||||
// Today, from whichever state is driving; the clock only covers the first
|
||||
// frame, before either has loaded.
|
||||
val today = when {
|
||||
scrolling -> (continuousState as? ContinuousMonthUiState.Success)?.today
|
||||
else -> (state as? MonthUiState.Success)?.today
|
||||
} ?: Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date
|
||||
val today by viewModel.today.collectAsStateWithLifecycle()
|
||||
|
||||
// The two scrolling styles index their items differently — Continuous by
|
||||
// month (which the week start can't move), Dense by week (which it can) — so
|
||||
@@ -520,6 +520,7 @@ fun MonthScreen(
|
||||
LocalDimCutoff provides dimCutoff,
|
||||
LocalMonthDrag provides chipDrag,
|
||||
LocalTodayPulse provides todayPulse,
|
||||
LocalMonthToday provides today,
|
||||
LocalOpenWeek provides onOpenWeek,
|
||||
) {
|
||||
if (scrolling) {
|
||||
@@ -773,6 +774,7 @@ private fun MonthPage(
|
||||
) {
|
||||
val ym = yearMonthForIndex(index)
|
||||
val state by remember(ym, weekStart) { monthState(ym, weekStart) }.collectAsStateWithLifecycle()
|
||||
val today = LocalMonthToday.current
|
||||
val chipDrag = LocalMonthDrag.current
|
||||
val morph = LocalMonthMorph.current
|
||||
val viewMorph = LocalViewMorph.current
|
||||
@@ -782,7 +784,7 @@ private fun MonthPage(
|
||||
LocalViewMorph provides viewMorph.takeIf { morphActive },
|
||||
) {
|
||||
when (val s = state) {
|
||||
is MonthUiState.Success -> page(index, s)
|
||||
is MonthUiState.Success -> page(index, s.withToday(today))
|
||||
else -> loading()
|
||||
}
|
||||
}
|
||||
@@ -1388,7 +1390,8 @@ private fun SplitMonthContent(
|
||||
val ym = yearMonthForIndex(index)
|
||||
val pageState by remember(ym, weekStart) { monthState(ym, weekStart) }
|
||||
.collectAsStateWithLifecycle()
|
||||
val page = pageState as? MonthUiState.Success ?: return@HorizontalPager
|
||||
val page = (pageState as? MonthUiState.Success)?.withToday(LocalMonthToday.current)
|
||||
?: return@HorizontalPager
|
||||
// Only the settled page carries the drag and the morph tags: its
|
||||
// neighbours repeat some of its dates and would claim them.
|
||||
val active = index == pagerState.settledPage
|
||||
|
||||
@@ -7,6 +7,8 @@ import de.jeanlucmakiola.calendula.data.calendar.CalendarRepository
|
||||
import de.jeanlucmakiola.calendula.data.di.IoDispatcher
|
||||
import de.jeanlucmakiola.calendula.data.prefs.SettingsPrefs
|
||||
import de.jeanlucmakiola.calendula.data.prefs.firstDayOfWeek
|
||||
import de.jeanlucmakiola.calendula.data.time.TodaySource
|
||||
import de.jeanlucmakiola.calendula.data.time.currentDate
|
||||
import de.jeanlucmakiola.calendula.domain.CalendarSource
|
||||
import de.jeanlucmakiola.calendula.domain.EventInstance
|
||||
import de.jeanlucmakiola.calendula.domain.FailureReason
|
||||
@@ -45,7 +47,6 @@ import kotlinx.datetime.minus
|
||||
import kotlinx.datetime.plus
|
||||
import kotlinx.datetime.toInstant
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -57,6 +58,7 @@ private const val MONTH_CACHE_SPAN = 2
|
||||
class MonthViewModel @Inject constructor(
|
||||
private val repository: CalendarRepository,
|
||||
settingsPrefs: SettingsPrefs,
|
||||
todaySource: TodaySource,
|
||||
@IoDispatcher private val io: CoroutineDispatcher,
|
||||
) : ViewModel() {
|
||||
|
||||
@@ -90,7 +92,18 @@ class MonthViewModel @Inject constructor(
|
||||
)
|
||||
|
||||
private val todayDate: LocalDate
|
||||
get() = Clock.System.now().toLocalDateTime(zone).date
|
||||
get() = currentDate()
|
||||
|
||||
private var lastToday = todayDate
|
||||
|
||||
/** Today, kept current across midnight so a grid left open doesn't mark yesterday (#373). */
|
||||
val today: StateFlow<LocalDate> = todaySource.today
|
||||
.onEach { date ->
|
||||
val old = lastToday
|
||||
lastToday = date
|
||||
if (old != date) followToday(old, date)
|
||||
}
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000L), todayDate)
|
||||
|
||||
private val _month = MutableStateFlow(YearMonth(todayDate.year, todayDate.month))
|
||||
val month: StateFlow<YearMonth> = _month
|
||||
@@ -139,8 +152,9 @@ class MonthViewModel @Inject constructor(
|
||||
combine(
|
||||
repository.calendars(),
|
||||
repository.instances(monthGridRange(ym, ws, zone)),
|
||||
) { calendars, instances ->
|
||||
buildState(ym, ws, calendars, instances)
|
||||
today,
|
||||
) { calendars, instances, today ->
|
||||
buildState(ym, ws, calendars, instances, today)
|
||||
}
|
||||
.catch { emit(MonthUiState.Failure(FailureReason.ProviderUnavailable)) }
|
||||
.flowOn(io)
|
||||
@@ -211,8 +225,9 @@ class MonthViewModel @Inject constructor(
|
||||
combine(
|
||||
repository.calendars(),
|
||||
repository.instances(range),
|
||||
) { calendars, instances ->
|
||||
buildContinuousState(window, ws, style, calendars, instances)
|
||||
today,
|
||||
) { calendars, instances, today ->
|
||||
buildContinuousState(window, ws, style, calendars, instances, today)
|
||||
}
|
||||
}
|
||||
// A load landing is the cue to reach further out. Widening from here
|
||||
@@ -257,6 +272,7 @@ class MonthViewModel @Inject constructor(
|
||||
style: MonthViewStyle,
|
||||
calendars: List<CalendarSource>,
|
||||
instances: List<EventInstance>,
|
||||
today: LocalDate,
|
||||
): ContinuousMonthUiState {
|
||||
calendarListFailure(calendars)?.let { return ContinuousMonthUiState.Failure(it) }
|
||||
// Bucketed once for the whole window: a row then takes the handful of
|
||||
@@ -283,7 +299,7 @@ class MonthViewModel @Inject constructor(
|
||||
emptyMap()
|
||||
}
|
||||
return ContinuousMonthUiState.Success(
|
||||
today = todayDate,
|
||||
today = today,
|
||||
monthsByIndex = months,
|
||||
weeksByIndex = weeks,
|
||||
weekStart = weekStart,
|
||||
@@ -333,6 +349,18 @@ class MonthViewModel @Inject constructor(
|
||||
_selectedDate.value = null
|
||||
}
|
||||
|
||||
/**
|
||||
* The date rolled over from [old] to [new]. A paged grid still on [old]'s
|
||||
* month moves on to [new]'s and drops the day picked yesterday; one browsed
|
||||
* elsewhere stays put. The scrolling styles only repaint the today marker.
|
||||
*/
|
||||
private fun followToday(old: LocalDate, new: LocalDate) {
|
||||
if (viewStyle.value.isScrolling) return
|
||||
if (_month.value != YearMonth(old.year, old.month)) return
|
||||
_month.value = YearMonth(new.year, new.month)
|
||||
_selectedDate.value = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Track [_month] to the month a scrolling style is showing. Those styles
|
||||
* navigate by scroll position and never set [_month] themselves, so it would
|
||||
@@ -358,12 +386,13 @@ class MonthViewModel @Inject constructor(
|
||||
weekStart: DayOfWeek,
|
||||
calendars: List<CalendarSource>,
|
||||
instances: List<EventInstance>,
|
||||
today: LocalDate,
|
||||
): MonthUiState {
|
||||
calendarListFailure(calendars)?.let { return MonthUiState.Failure(it) }
|
||||
val weeks = layoutMonthWeeks(ym, weekStart, instances, zone)
|
||||
return MonthUiState.Success(
|
||||
month = ym,
|
||||
today = todayDate,
|
||||
today = today,
|
||||
weeks = weeks,
|
||||
instancesByDay = instancesByDay(weeks.flatMap { it.days }, instances, zone),
|
||||
zone = zone,
|
||||
|
||||
@@ -461,6 +461,7 @@ private fun PagedTimelineScreen(
|
||||
CompositionLocalProvider(LocalDimCutoff provides dimCutoff) {
|
||||
WeekContent(
|
||||
state = state,
|
||||
today = today,
|
||||
pagerState = pagerState,
|
||||
grid = grid,
|
||||
kind = kind,
|
||||
@@ -482,6 +483,7 @@ private fun PagedTimelineScreen(
|
||||
@Composable
|
||||
private fun WeekContent(
|
||||
state: WeekUiState,
|
||||
today: LocalDate,
|
||||
pagerState: PagerState,
|
||||
grid: PageGrid,
|
||||
kind: TimelineKind,
|
||||
@@ -536,7 +538,7 @@ private fun WeekContent(
|
||||
is WeekUiState.Success -> if (morph != null) {
|
||||
TimelineMorphFrame(
|
||||
morph = morph,
|
||||
today = s.today,
|
||||
today = today,
|
||||
scrollState = scrollState,
|
||||
dragController = dragController,
|
||||
onEventClick = onEventClick,
|
||||
@@ -549,7 +551,7 @@ private fun WeekContent(
|
||||
grid = grid,
|
||||
kind = kind,
|
||||
span = span,
|
||||
today = s.today,
|
||||
today = today,
|
||||
initialStripHeight = handoffStrip ?: s.allDayStripHeight(),
|
||||
scrollState = scrollState,
|
||||
dragController = dragController,
|
||||
@@ -618,7 +620,10 @@ private fun WeekPager(
|
||||
}
|
||||
ViewMorphPage(active = morphPageActive(page, pagerState.settledPage)) {
|
||||
WeekPage(
|
||||
state = loaded ?: empty,
|
||||
// A cached page may predate midnight; today comes off the clock (#373).
|
||||
state = remember(loaded, empty, today) {
|
||||
loaded?.takeIf { it.today != today }?.copy(today = today) ?: loaded ?: empty
|
||||
},
|
||||
headerBias = kind.headerBias,
|
||||
allDayHeight = allDayHeight,
|
||||
scrollState = scrollState,
|
||||
|
||||
@@ -7,6 +7,8 @@ import de.jeanlucmakiola.calendula.data.calendar.CalendarRepository
|
||||
import de.jeanlucmakiola.calendula.data.di.IoDispatcher
|
||||
import de.jeanlucmakiola.calendula.data.prefs.SettingsPrefs
|
||||
import de.jeanlucmakiola.calendula.data.prefs.resolveFirstDay
|
||||
import de.jeanlucmakiola.calendula.data.time.TodaySource
|
||||
import de.jeanlucmakiola.calendula.data.time.currentDate
|
||||
import de.jeanlucmakiola.calendula.domain.CalendarSource
|
||||
import de.jeanlucmakiola.calendula.domain.EventInstance
|
||||
import de.jeanlucmakiola.calendula.domain.displayPriority
|
||||
@@ -27,6 +29,7 @@ import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.datetime.DateTimeUnit
|
||||
import kotlinx.datetime.DayOfWeek
|
||||
@@ -40,7 +43,6 @@ import kotlinx.datetime.plus
|
||||
import kotlinx.datetime.toInstant
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import java.util.Locale
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
@@ -73,6 +75,7 @@ fun positionOf(anchor: LocalDate, rule: (LocalDate) -> PageGrid): PagerPosition
|
||||
abstract class PagedTimelineViewModel(
|
||||
private val repository: CalendarRepository,
|
||||
settingsPrefs: SettingsPrefs,
|
||||
todaySource: TodaySource,
|
||||
private val io: CoroutineDispatcher,
|
||||
gridRule: Flow<(LocalDate) -> PageGrid>,
|
||||
initialRule: (LocalDate) -> PageGrid,
|
||||
@@ -89,7 +92,7 @@ abstract class PagedTimelineViewModel(
|
||||
)
|
||||
|
||||
private val todayDate: LocalDate
|
||||
get() = Clock.System.now().toLocalDateTime(zone).date
|
||||
get() = currentDate()
|
||||
|
||||
// A day on the visible page; the page itself comes from the grid, so a
|
||||
// settings change re-frames the same days instead of jumping.
|
||||
@@ -103,6 +106,17 @@ abstract class PagedTimelineViewModel(
|
||||
val rule: StateFlow<(LocalDate) -> PageGrid> =
|
||||
gridRule.stateIn(viewModelScope, SharingStarted.Eagerly, initialRule)
|
||||
|
||||
private var lastToday = todayDate
|
||||
|
||||
/** Today, kept current across midnight so a page left open doesn't mark yesterday (#373). */
|
||||
private val today: StateFlow<LocalDate> = todaySource.today
|
||||
.onEach { date ->
|
||||
val old = lastToday
|
||||
lastToday = date
|
||||
if (old != date) followToday(old, date)
|
||||
}
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000L), todayDate)
|
||||
|
||||
private val position: StateFlow<PagerPosition> =
|
||||
combine(_anchor, rule) { anchor, rule -> positionOf(anchor, rule) }
|
||||
.distinctUntilChanged()
|
||||
@@ -141,8 +155,9 @@ abstract class PagedTimelineViewModel(
|
||||
combine(
|
||||
repository.calendars(),
|
||||
repository.instances(spanRange(span.start, span.count, zone)),
|
||||
) { calendars, instances ->
|
||||
buildState(span, calendars, instances)
|
||||
today,
|
||||
) { calendars, instances, today ->
|
||||
buildState(span, calendars, instances, today)
|
||||
}
|
||||
.catch { emit(WeekUiState.Failure(FailureReason.ProviderUnavailable)) }
|
||||
.flowOn(io)
|
||||
@@ -163,12 +178,20 @@ abstract class PagedTimelineViewModel(
|
||||
}
|
||||
|
||||
fun goToToday() = jumpTo(todayDate)
|
||||
|
||||
/** The date rolled over; a page still showing [old] follows on to [new], one browsed elsewhere stays. */
|
||||
private fun followToday(old: LocalDate, new: LocalDate) {
|
||||
val anchor = _anchor.value
|
||||
val grid = rule.value(anchor)
|
||||
if (grid.pageFor(anchor) == grid.pageFor(old)) _anchor.value = new
|
||||
}
|
||||
fun goToDate(date: LocalDate) = jumpTo(date)
|
||||
|
||||
private fun buildState(
|
||||
span: DaySpan,
|
||||
calendars: List<CalendarSource>,
|
||||
instances: List<EventInstance>,
|
||||
today: LocalDate,
|
||||
): WeekUiState {
|
||||
calendarListFailure(calendars)?.let { return WeekUiState.Failure(it) }
|
||||
val days = (0 until span.count).map { span.start.plus(it, DateTimeUnit.DAY) }
|
||||
@@ -176,7 +199,7 @@ abstract class PagedTimelineViewModel(
|
||||
val timed = instances.filterNot { it.isAllDay }
|
||||
return WeekUiState.Success(
|
||||
weekStart = span.start,
|
||||
today = todayDate,
|
||||
today = today,
|
||||
days = days,
|
||||
allDaySpans = layoutAllDay(allDay, days, zone),
|
||||
timedByDay = days.associateWith { day -> layoutDay(timed, day, zone) },
|
||||
@@ -189,10 +212,12 @@ abstract class PagedTimelineViewModel(
|
||||
class WeekViewModel @Inject constructor(
|
||||
repository: CalendarRepository,
|
||||
settingsPrefs: SettingsPrefs,
|
||||
todaySource: TodaySource,
|
||||
@IoDispatcher io: CoroutineDispatcher,
|
||||
) : PagedTimelineViewModel(
|
||||
repository = repository,
|
||||
settingsPrefs = settingsPrefs,
|
||||
todaySource = todaySource,
|
||||
io = io,
|
||||
gridRule = settingsPrefs.weekStart.map { pref ->
|
||||
val grid = WeekGrid(pref.resolveFirstDay(Locale.getDefault()))
|
||||
@@ -211,10 +236,12 @@ class WeekViewModel @Inject constructor(
|
||||
class MultiDayViewModel @Inject constructor(
|
||||
repository: CalendarRepository,
|
||||
settingsPrefs: SettingsPrefs,
|
||||
todaySource: TodaySource,
|
||||
@IoDispatcher io: CoroutineDispatcher,
|
||||
) : PagedTimelineViewModel(
|
||||
repository = repository,
|
||||
settingsPrefs = settingsPrefs,
|
||||
todaySource = todaySource,
|
||||
io = io,
|
||||
gridRule = settingsPrefs.multiDayCount.map { count ->
|
||||
{ anchor: LocalDate -> DaysGrid.startingAt(anchor, count) }
|
||||
@@ -227,10 +254,12 @@ class MultiDayViewModel @Inject constructor(
|
||||
class DayViewModel @Inject constructor(
|
||||
repository: CalendarRepository,
|
||||
settingsPrefs: SettingsPrefs,
|
||||
todaySource: TodaySource,
|
||||
@IoDispatcher io: CoroutineDispatcher,
|
||||
) : PagedTimelineViewModel(
|
||||
repository = repository,
|
||||
settingsPrefs = settingsPrefs,
|
||||
todaySource = todaySource,
|
||||
io = io,
|
||||
gridRule = flowOf { _: LocalDate -> DayGrid },
|
||||
initialRule = { DayGrid },
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
<string name="agenda_range_month">٣٠ يومًا القادمة</string>
|
||||
<string name="settings_month_view_style">نمط عرض الشهر</string>
|
||||
<string name="month_style_paged">صفحات</string>
|
||||
<string name="month_style_paged_summary">الشهر الواحد يملأ الشاشة. اسحب لليسار أو لليمين لتغيير الشهر.</string>
|
||||
<string name="month_style_paged_summary">الشهر الواحد يملأ الشاشة. اسحب لليسار أو لليمين لتغيير الشهر، أو اسحب للأعلى لعرض جدول الشهر.</string>
|
||||
<string name="month_style_split">تقسيم</string>
|
||||
<string name="settings_color_unsupported">السماح بالألوان في التقويمات غير المدعومة</string>
|
||||
<string name="settings_color_unsupported_hint">بعض التقويمات (مثل البعض من CalDAV) لا تنشر أي مجموعة ألوان؛ لون حدث مخصص قد يزال أو يستبدل في مزامنته التالية. هذا قيد على تلك التقويمات، وليس شيئًا يمكن لـ Calendula إصلاحه.</string>
|
||||
@@ -732,7 +732,7 @@
|
||||
<string name="event_detail_title">العنوان</string>
|
||||
<string name="settings_licences">تراخيص مفتوحة المصدر</string>
|
||||
<string name="settings_licences_subtitle">المشاريع التي بنيت Calendula عليها</string>
|
||||
<string name="licences_title">تراخيص مفتوحة المصدر</string>
|
||||
<string name="licences_title">التراخيص مفتوحة المصدر</string>
|
||||
<string name="licences_intro">يتضمن Calendula العمل أدناه. اضغط على أي إدخال للحصول على شفرة المصدر الخاصة به.</string>
|
||||
<string name="licences_footer">يتم تضمين كل مشروع هنا دون تعديل، بموجب الترخيص الموضح.</string>
|
||||
<string name="state_failure_permission_body">يقرأ Calendula أحداثك مباشرةً من تقويم النظام، لذلك فأنه يحتاج للوصول إلى التقويم لعرض أي شيء.</string>
|
||||
@@ -778,4 +778,30 @@
|
||||
<string name="color_name_amber">أصفر كهرماني</string>
|
||||
<string name="calendars_restore_unavailable">لا تقويم يمكنه استيعاب الأحداث المستوردة بعد.</string>
|
||||
<string name="calendars_description_label">الوصف</string>
|
||||
<string name="app_name_calendar_alias">التقويم</string>
|
||||
<plurals name="view_multi_day">
|
||||
<item quantity="zero">%d يوم</item>
|
||||
<item quantity="one">%d يوم</item>
|
||||
<item quantity="two">%d يومان</item>
|
||||
<item quantity="few">%d أيام</item>
|
||||
<item quantity="many">%d يوم</item>
|
||||
<item quantity="other">%d يوم</item>
|
||||
</plurals>
|
||||
<string name="settings_visible_hours_start">من</string>
|
||||
<string name="settings_visible_hours_end">حتى</string>
|
||||
<string name="settings_multi_day_count">عرض الأيام المتعدّدة</string>
|
||||
<string name="settings_multi_day_count_hint">كم عدد الأيام التي يعرضها طريقة العرض متعدد الأيام جنبًا إلى جنب. اليوم يُفتح في العمود الأول.</string>
|
||||
<string name="settings_visible_hours">الساعات الظاهرة</string>
|
||||
<string name="settings_visible_hours_summary">حدّد مدى من الساعات للشاشة عند فتح طريقة عرض الأسبوع، متعددة الأيام أو اليوم</string>
|
||||
<string name="settings_visible_hours_on_summary">%1$s – %2$s يملأ الشاشة عند فتح طريقة عرض</string>
|
||||
<string name="settings_visible_hours_start_hint">الساعة في أعلى الشاشة عند فتح طريقة عرض الأسبوع، متعددة الأيام أو اليوم. لا تزال الساعات السابقة على بُعد تمرير.</string>
|
||||
<string name="settings_visible_hours_end_hint">الساعة في أسفل الشاشة عند فتح طريقة عرض. لا تزال الساعات اللاحقة على بُعد تمرير، و عمليات التكبير بالضّم حتى يتم فتح طريقة العرض مرة أخرى.</string>
|
||||
<string name="month_open_week">فتح الأسبوع %1$d</string>
|
||||
<string name="settings_timeline_scale_by_visible_hours">ضبط بواسطة الساعات الظاهرة</string>
|
||||
<string name="month_split_clear_filter">إظهار جدول الشهر كامل</string>
|
||||
<string name="timeline_earlier_events">أحداث سابقة</string>
|
||||
<string name="timeline_later_events">أحداث لاحقة</string>
|
||||
<string name="reminder_day_today">اليوم</string>
|
||||
<string name="event_detail_open_in_maps">فتح في الخرائط</string>
|
||||
<string name="link_open_failed">لا تطبيق يمكنه فتح هذا الرابط</string>
|
||||
</resources>
|
||||
|
||||
@@ -671,4 +671,5 @@
|
||||
<string name="state_failure_all_hidden_action">Кіраваньне календарамі</string>
|
||||
<string name="state_failure_no_import_target">Ніводны з календароў ня можа прымаць новыя падзеі.</string>
|
||||
<string name="state_failure_no_import_target_body">Календары адключаныя, у рэжыме «толькі чытаньне», знаходзяцца пад кіраваньнем іншай праграмы, або не сынхранізуюцца на гэтай прыладзе. Уключэце каляндар, які можа прымаць падзеі, або дадайце лякальны.</string>
|
||||
<string name="app_name_calendar_alias">Каляндар</string>
|
||||
</resources>
|
||||
|
||||
@@ -719,7 +719,7 @@
|
||||
<string name="onboarding_hidden_title">Vaše kalendáře jsou vypnuté</string>
|
||||
<string name="onboarding_hidden_body">Calendula zobrazuje kalendáře, které má tento telefon zapnuté, což není momentálně žádný. Zapněte si kalendáře, které chcete vidět – vaše ostatní aplikace kalendáře je pak také zobrazí.</string>
|
||||
<string name="onboarding_hidden_switch_all_button">Zapnout všechny kalendáře</string>
|
||||
<string name="onboarding_hidden_skip_button">Teď ne</string>
|
||||
<string name="onboarding_hidden_skip_button">Později</string>
|
||||
<string name="onboarding_hidden_failed">To se nepodařilo zapnout. V Nastavení → Kalendáře jsou stejné přepínače.</string>
|
||||
<string name="onboarding_calendars_create_failed">Kalendář se nepodařilo vytvořit. Úložiště kalendáře ve vašem telefonu jej odmítlo vytvořit.</string>
|
||||
<string name="calendars_description_label">Popis</string>
|
||||
@@ -736,4 +736,21 @@
|
||||
<string name="color_name_purple">Purpurová</string>
|
||||
<string name="color_name_pink">Růžová</string>
|
||||
<string name="calendars_restore_unavailable">Žádný z kalendářů zatím nedokáže importované události přijmout.</string>
|
||||
<string name="app_name_calendar_alias">Kalendář</string>
|
||||
<string name="month_open_week">Otevřít týden %1$d</string>
|
||||
<string name="month_split_clear_filter">Zobrazit celou měsíční agendu</string>
|
||||
<string name="timeline_earlier_events">Dřívější události</string>
|
||||
<string name="timeline_later_events">Pozdější události</string>
|
||||
<string name="event_detail_open_in_maps">Otevřít na mapě</string>
|
||||
<string name="link_open_failed">Žádná aplikace nemůže tento odkaz otevřít</string>
|
||||
<string name="reminder_day_today">Dnes</string>
|
||||
<plurals name="view_multi_day">
|
||||
<item quantity="one">%d den</item>
|
||||
<item quantity="few">%d dny</item>
|
||||
<item quantity="many">%d dnů</item>
|
||||
<item quantity="other">%d dnů</item>
|
||||
</plurals>
|
||||
<string name="settings_multi_day_count">Vícedenní zobrazení</string>
|
||||
<string name="settings_multi_day_count_hint">Počet dní zobrazujících se ve vícedenním přehledu vedle sebe. Dnešek se otevírá v prvním sloupci.</string>
|
||||
<string name="settings_timeline_scale_by_visible_hours">Nastaveno v části Viditelné hodiny</string>
|
||||
</resources>
|
||||
|
||||
@@ -715,4 +715,16 @@
|
||||
<item quantity="one">%d Termin konnte nicht hinzugefügt werden.</item>
|
||||
<item quantity="other">%d Termine konnten nicht hinzugefügt werden.</item>
|
||||
</plurals>
|
||||
<string name="app_name_calendar_alias">Kalender</string>
|
||||
<string name="timeline_earlier_events">Frühere Termine</string>
|
||||
<string name="timeline_later_events">Spätere Termine</string>
|
||||
<string name="link_open_failed">Keine App kann diesen Link öffnen</string>
|
||||
<string name="reminder_day_today">Heute</string>
|
||||
<plurals name="view_multi_day">
|
||||
<item quantity="one">%d Tag</item>
|
||||
<item quantity="other">%d Tage</item>
|
||||
</plurals>
|
||||
<string name="settings_visible_hours">Sichtbare Stunden</string>
|
||||
<string name="settings_visible_hours_start">Von</string>
|
||||
<string name="settings_visible_hours_end">Bis</string>
|
||||
</resources>
|
||||
|
||||
@@ -672,4 +672,5 @@
|
||||
<item quantity="many">Les événements %d n\'ont pas pu être ajoutés.</item>
|
||||
<item quantity="other">Les événements %d n\'ont pas pu être ajoutés.</item>
|
||||
</plurals>
|
||||
<string name="app_name_calendar_alias">Calendrier</string>
|
||||
</resources>
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
<string name="settings_time_format_auto">Automatico</string>
|
||||
<string name="settings_time_format_12h">12 ore</string>
|
||||
<string name="settings_time_format_24h">24 ore</string>
|
||||
<string name="settings_hour_lines">Righe per le ore</string>
|
||||
<string name="settings_hour_lines">Grglia oraria</string>
|
||||
<string name="settings_hour_lines_summary">Mostra una riga separatrice per ogni ora nella vista Settimana e Giorno</string>
|
||||
<string name="settings_dim_completed">Attenua gli eventi completati</string>
|
||||
<string name="settings_dim_completed_summary">Attenua gli eventi conclusi nella vista Mese e Settimana</string>
|
||||
@@ -413,7 +413,7 @@
|
||||
<string name="settings_default_reminder">Promemoria per eventi standard</string>
|
||||
<string name="settings_notifications_subtitle">Promemoria</string>
|
||||
<string name="shortcut_new_event_short">Nuovo evento</string>
|
||||
<string name="event_edit_managed_hint">Gestito da “%1$s” - titolo, data e ripetizioni sono sincronizzate dai tuoi contatti. Promemoria e note sono modificabili dall\'utente.</string>
|
||||
<string name="event_edit_managed_hint">Gestito da “%1$s” — titolo, data e ripetizioni sono sincronizzate dai tuoi contatti. Promemoria e note sono modificabili dall\'utente.</string>
|
||||
<string name="settings_font_headings">Carattere del titolo</string>
|
||||
<string name="settings_font_body">Carattere del corpo</string>
|
||||
<string name="settings_font_system">Lingua di sistema</string>
|
||||
@@ -503,7 +503,7 @@
|
||||
<string name="event_move_undone">Ripianificazione annullata</string>
|
||||
<string name="event_move_failed">Impossibile ripianificare l\'evento</string>
|
||||
<string name="event_move_write_denied">Calendula ha bisogno dei permessi di scrittura per ripianificare gli eventi</string>
|
||||
<string name="event_move_gone">Questo evento è stato eliminato.</string>
|
||||
<string name="event_move_gone">Questo evento è stato eliminato</string>
|
||||
<string name="event_move_blocked_series_end">Non è possibile ripianificare un evento oltre la data di fine della sua serie</string>
|
||||
<string name="event_edit_timezone_device">Fuso orario del dispositivo</string>
|
||||
<string name="event_edit_timezone_device_summary">Segue il fuso orario in cui ti trovi</string>
|
||||
@@ -657,4 +657,83 @@
|
||||
<string name="import_done_failed_label">Non aggiunto</string>
|
||||
<string name="import_done_failed_note">Alcuni eventi non possono essere aggiunti e sono stati esclusi.</string>
|
||||
<string name="import_done_stopped_title">Importazione interrotta</string>
|
||||
<string name="app_name_calendar_alias">Calendario</string>
|
||||
<string name="state_failure_permission_body">Calendula legge i tuoi eventi direttamente dal calendario di sistema, per questo ha bisogno dell\'accesso al calendario per poterli visualizzare.</string>
|
||||
<string name="state_failure_no_calendars_body">Aggiungi un account a questo dispositivo e i relativi calendari verranno visualizzati qui.</string>
|
||||
<string name="state_failure_all_hidden">Tutti i tuoi calendari sono disattivati.</string>
|
||||
<string name="state_failure_all_hidden_body">Riattiva almeno un calendario per visualizzarne gli eventi.</string>
|
||||
<string name="state_failure_no_import_target">Nessun calendario può accettare nuovi eventi.</string>
|
||||
<string name="state_failure_no_import_target_body">I calendari attivi sono di sola lettura, gestiti da un\'altra app o non sincronizzati con questo dispositivo. Attiva un calendario in cui è possibile inserire eventi oppure aggiungine uno locale.</string>
|
||||
<string name="state_failure_event_not_found">Questo evento non è più disponibile.</string>
|
||||
<string name="state_failure_event_not_found_body">Potrebbe essere stato cancellato oppure spostato in un calendario disattivato.</string>
|
||||
<string name="state_failure_provider_body">Il calendario di sistema non ha risposto. Riprova a breve.</string>
|
||||
<string name="timeline_earlier_events">Eventi precedenti</string>
|
||||
<string name="timeline_later_events">Eventi successivi</string>
|
||||
<string name="month_open_week">Settimana aperta %1$d</string>
|
||||
<string name="month_split_clear_filter">Visualizza il calendario completo del mese</string>
|
||||
<string name="event_detail_open_in_maps">Apri su Maps</string>
|
||||
<string name="link_open_failed">Nessuna app è in grado di aprire questo link</string>
|
||||
<string name="calendar_unnamed">(Senza nome)</string>
|
||||
<string name="onboarding_calendars_title">Un posto dove inserire i tuoi eventi</string>
|
||||
<string name="onboarding_calendars_body">Questo dispositivo non ha ancora un calendario. Calendula scrive sui calendari già presenti sul telefono — ne serve almeno uno.</string>
|
||||
<string name="onboarding_calendars_local_button">Crea un calendario su questo dispositivo</string>
|
||||
<string name="onboarding_calendars_caldav_button">Sincronizzazione con un server CalDAV</string>
|
||||
<string name="onboarding_calendars_skip_button">Non ora</string>
|
||||
<string name="onboarding_calendars_benefit_local_title">Rimane su questo telefono</string>
|
||||
<string name="onboarding_calendars_benefit_local_body">Il calendario del dispositivo non si sincronizza con nessun altro dispositivo, quindi esegui un backup se gli eventi sono importanti.</string>
|
||||
<string name="onboarding_calendars_benefit_sync_title">Oppure sincronizza da un account</string>
|
||||
<string name="onboarding_calendars_benefit_sync_body">Calendula mostra quali account sono già sincronizzati. I server CalDAV necessitano di DAVx⁵ per eseguire la sincronizzazione.</string>
|
||||
<string name="onboarding_calendars_created_title">“%1$s” è pronto</string>
|
||||
<string name="onboarding_calendars_created_body">Si trova su questo dispositivo e gli eventi nuovi vengono inseriti lì, a meno che non si scelga un altro calendario.</string>
|
||||
<string name="onboarding_calendars_created_more_title">C\'è spazio per altro</string>
|
||||
<string name="onboarding_calendars_created_more_body">Da Impostazioni → Calendari puoi crearne quanti ne vuoi e rinominare o cambiare il colore di quelli già presenti.</string>
|
||||
<string name="onboarding_calendars_created_continue">Continua</string>
|
||||
<string name="onboarding_hidden_title">I vostri calendari sono disattivati</string>
|
||||
<string name="onboarding_hidden_body">Calendula mostra i calendari attivi su questo telefono e, al momento, non ce n’è nessuno. Attiva quelli che desideri visualizzare: anche le altre app di calendario li mostreranno nuovamente.</string>
|
||||
<string name="onboarding_hidden_switch_all_button">Attivali tutti</string>
|
||||
<string name="onboarding_hidden_skip_button">Non ora</string>
|
||||
<string name="onboarding_hidden_failed">Non sono riuscito ad attivarlo. In Impostazioni → Calendari ci sono gli stessi pulsanti di attivazione.</string>
|
||||
<string name="onboarding_calendars_create_failed">Impossibile creare il calendario. La memoria del calendario del tuo telefono non lo ha accettato.</string>
|
||||
<string name="reminder_day_today">Oggi</string>
|
||||
<plurals name="view_multi_day">
|
||||
<item quantity="one">Giorno</item>
|
||||
<item quantity="many">Giorni</item>
|
||||
<item quantity="other">Giorno</item>
|
||||
</plurals>
|
||||
<string name="settings_multi_day_count">Visualizzazione su più giorni</string>
|
||||
<string name="settings_multi_day_count_hint">La vista più giorni mostra, affiancati, i giorni. La data odierna è visualizzata nella prima colonna.</string>
|
||||
<string name="settings_timeline_scale_by_visible_hours">Imposta in base alle ore di visibilità</string>
|
||||
<string name="settings_visible_hours">Orari di apertura</string>
|
||||
<string name="settings_visible_hours_summary">Adatta la gamma di ore alla schermata all\'apertura della visualizzazione settimanale, plurigiornaliera o giornaliera</string>
|
||||
<string name="settings_visible_hours_on_summary">%1$s – %2$s riempie lo schermo all’apertura di una vista</string>
|
||||
<string name="settings_visible_hours_start">Da</string>
|
||||
<string name="settings_visible_hours_end">Fino a</string>
|
||||
<string name="settings_visible_hours_start_hint">L\'ora visualizzata nella parte superiore dello schermo quando si apre la vista settimanale, plurigiornaliera o giornaliera. Le ore precedenti sono comunque accessibili scorrendo la schermata.</string>
|
||||
<string name="settings_visible_hours_end_hint">L\'ora visualizzata nella parte inferiore dello schermo quando si apre una schermata. Le ore successive sono ancora raggiungibili scorrendo lo schermo, mentre pizzicando lo schermo si esegue lo zoom fino a quando la schermata non viene riaperta.</string>
|
||||
<string name="settings_licences">Licenze open source</string>
|
||||
<string name="settings_licences_subtitle">I progetti su cui si basa Calendula</string>
|
||||
<string name="calendars_description_label">Descrizione</string>
|
||||
<string name="color_name_mauve">Rosa malva</string>
|
||||
<string name="color_name_red">Rosso</string>
|
||||
<string name="color_name_orange">Arancione</string>
|
||||
<string name="color_name_amber">Ambra</string>
|
||||
<string name="color_name_olive">Oliva</string>
|
||||
<string name="color_name_green">Verde</string>
|
||||
<string name="color_name_teal">Verde acqua</string>
|
||||
<string name="color_name_cyan">Ciano</string>
|
||||
<string name="color_name_blue">Blu</string>
|
||||
<string name="color_name_indigo">Indaco</string>
|
||||
<string name="color_name_purple">Viola</string>
|
||||
<string name="color_name_pink">Rosa</string>
|
||||
<string name="calendars_restore_unavailable">Al momento nessun calendario è in grado di gestire gli eventi importati.</string>
|
||||
<plurals name="import_done_stopped">
|
||||
<item quantity="one">Il calendario ha smesso di accettare eventi a metà dell\'operazione. L\'evento %d presente nel file non è stato aggiunto.</item>
|
||||
<item quantity="many">Il calendari hanno smesso di accettare eventi a metà dell\'operazione. Gli eventi %d presenti nel file non sono stati aggiunti.</item>
|
||||
<item quantity="other">Il calendario ha smesso di accettare eventi a metà dell\'operazione. L\'evento %d presente nel file non è stato aggiunto.</item>
|
||||
</plurals>
|
||||
<plurals name="import_done_failed">
|
||||
<item quantity="one">Non è stato possibile aggiungere l\'evento %d.</item>
|
||||
<item quantity="many">Non è stato possibile aggiungere gli eventi %d.</item>
|
||||
<item quantity="other">Non è stato possibile aggiungere l\'evento %d.</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
@@ -377,7 +377,7 @@
|
||||
<string name="settings_today_toolbar">Knop Vandaag in werkbalk</string>
|
||||
<string name="settings_today_toolbar_summary">Een knop om naar vandaag te gaan tonen in de werkbalk, in plaats van een zwevende knop</string>
|
||||
<string name="settings_app_name">Appnaam</string>
|
||||
<string name="settings_app_name_summary">Calendula als “Calendar” tonen in je launcher. Alleen de naam in de launcher verandert; het pictogram kan na het wisselen op een andere plek komen te staan.</string>
|
||||
<string name="settings_app_name_summary">Calendula als “Agenda” tonen in je launcher. Alleen de naam in de launcher verandert; het pictogram kan na het wisselen op een andere plek komen te staan.</string>
|
||||
<string name="settings_time_format">Tijdnotatie</string>
|
||||
<string name="settings_time_format_auto">Automatisch</string>
|
||||
<string name="settings_time_format_12h">12-uursnotatie (2:00 PM)</string>
|
||||
@@ -441,7 +441,7 @@
|
||||
<string name="settings_month_header">Maandweergave</string>
|
||||
<string name="settings_month_view_style">Stijl van maandweergave</string>
|
||||
<string name="month_style_paged">Pagina\'s</string>
|
||||
<string name="month_style_paged_summary">Eén maand vult het scherm. Veeg naar links of rechts om van maand te wisselen.</string>
|
||||
<string name="month_style_paged_summary">Eén maand vult het scherm. Veeg naar links of rechts om van maand te wisselen, of veeg omhoog om de agenda van deze maand te tonen.</string>
|
||||
<string name="month_style_continuous">Doorlopende maanden</string>
|
||||
<string name="month_style_continuous_summary">Elke maand staat onder een eigen kop, met wat ruimte tot de volgende maand.</string>
|
||||
<string name="month_style_dense">Naadloze weken</string>
|
||||
@@ -694,4 +694,26 @@
|
||||
<string name="special_dates_default_title_birthday">Verjaardag van {name} ({year})</string>
|
||||
<string name="special_dates_default_title_anniversary">Jubileum van {name} ({year})</string>
|
||||
<string name="special_dates_default_title_custom">{name}</string>
|
||||
<string name="app_name_calendar_alias">Agenda</string>
|
||||
<string name="month_open_week">Week %1$d openen</string>
|
||||
<string name="month_split_clear_filter">Agenda van de hele maand tonen</string>
|
||||
<string name="timeline_earlier_events">Eerdere gebeurtenissen</string>
|
||||
<string name="timeline_later_events">Latere gebeurtenissen</string>
|
||||
<string name="event_detail_open_in_maps">Op kaart tonen</string>
|
||||
<string name="link_open_failed">Er is geen app die deze link kan openen</string>
|
||||
<string name="reminder_day_today">Vandaag</string>
|
||||
<plurals name="view_multi_day">
|
||||
<item quantity="one">%d dag</item>
|
||||
<item quantity="other">%d dagen</item>
|
||||
</plurals>
|
||||
<string name="settings_multi_day_count">Meerdaagse weergave</string>
|
||||
<string name="settings_multi_day_count_hint">Hoeveel dagen de meerdaagse weergave naast elkaar toont. Vandaag staat in de eerste kolom.</string>
|
||||
<string name="settings_timeline_scale_by_visible_hours">Ingesteld via Zichtbare uren</string>
|
||||
<string name="settings_visible_hours">Zichtbare uren</string>
|
||||
<string name="settings_visible_hours_summary">Een reeks uren passend op het scherm tonen bij het openen van de week-, meerdaagse of dagweergave</string>
|
||||
<string name="settings_visible_hours_on_summary">%1$s – %2$s vult het scherm bij het openen van een weergave</string>
|
||||
<string name="settings_visible_hours_start">Van</string>
|
||||
<string name="settings_visible_hours_end">Tot</string>
|
||||
<string name="settings_visible_hours_start_hint">Het uur bovenaan het scherm bij het openen van de week-, meerdaagse of dagweergave. Eerdere uren blijven bereikbaar door te scrollen.</string>
|
||||
<string name="settings_visible_hours_end_hint">Het uur onderaan het scherm bij het openen van een weergave. Latere uren blijven bereikbaar door te scrollen, en in- of uitzoomen met twee vingers geldt totdat de weergave opnieuw wordt geopend.</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
إصلاحات
|
||||
• عند فتح التطبيق في صباح اليوم التالي يظهر اليوم الصحيح. كان عرض الشهر يعلّم الأمس على أنه اليوم ويُبقي اليوم الذي اخترته في المساء السابق محددًا. الآن تنتقل كل العروض إلى اليوم الجديد.
|
||||
@@ -0,0 +1,2 @@
|
||||
Выпраўлена
|
||||
• Калі адкрыць праграму наступнай раніцай, яна паказвае правільны дзень. Раней месяц адзначаў учорашні дзень як сённяшні і пакідаў выбраным дзень, які вы абралі ўвечары. Цяпер усе віды пераходзяць на новы дзень.
|
||||
@@ -0,0 +1,2 @@
|
||||
Opraveno
|
||||
• Když aplikaci otevřete druhý den ráno, ukáže správný den. Měsíc dřív označoval včerejšek jako dnešek a nechával vybraný den, který jste zvolili večer předtím. Všechna zobrazení teď přejdou na nový den.
|
||||
@@ -0,0 +1,2 @@
|
||||
Behoben
|
||||
• Wird die App am nächsten Morgen geöffnet, zeigt sie den richtigen Tag. Die Monatsansicht markierte bisher gestern als heute und ließ den am Vorabend gewählten Tag ausgewählt. Jetzt wechseln alle Ansichten auf den neuen Tag.
|
||||
@@ -0,0 +1,2 @@
|
||||
Fixed
|
||||
• Reopening the app the next morning shows the right day. The month view used to mark yesterday as today and keep the day you picked the evening before selected. All views now move on to the new day.
|
||||
@@ -0,0 +1,2 @@
|
||||
Corregido
|
||||
• Al abrir la app a la mañana siguiente, se muestra el día correcto. La vista de mes marcaba ayer como hoy y dejaba seleccionado el día que elegiste la noche anterior. Ahora todas las vistas pasan al nuevo día.
|
||||
@@ -0,0 +1,2 @@
|
||||
Corrigé
|
||||
• En ouvrant l'app le lendemain matin, vous voyez le bon jour. La vue mois marquait la veille comme aujourd'hui et gardait sélectionné le jour choisi la veille au soir. Toutes les vues passent maintenant au nouveau jour.
|
||||
@@ -0,0 +1,2 @@
|
||||
Javítva
|
||||
• Ha másnap reggel megnyitod az alkalmazást, a helyes napot mutatja. A havi nézet eddig a tegnapot jelölte mai napként, és kijelölve hagyta az előző este választott napot. Most minden nézet átvált az új napra.
|
||||
@@ -0,0 +1,2 @@
|
||||
Corretto
|
||||
• Aprendo l'app la mattina dopo, viene mostrato il giorno giusto. La vista mese segnava ieri come oggi e lasciava selezionato il giorno scelto la sera prima. Ora tutte le viste passano al nuovo giorno.
|
||||
@@ -0,0 +1,2 @@
|
||||
修正
|
||||
• 翌朝アプリを開くと、正しい日が表示されるようになりました。これまで月表示では前日が今日として表示され、前の晩に選んだ日も選択されたままでした。今はすべての表示が新しい日に切り替わります。
|
||||
@@ -0,0 +1,2 @@
|
||||
Opgelost
|
||||
• Open je de app de volgende ochtend, dan zie je de juiste dag. De maandweergave markeerde gisteren als vandaag en hield de dag die je de avond ervoor koos geselecteerd. Alle weergaven gaan nu mee naar de nieuwe dag.
|
||||
@@ -0,0 +1,2 @@
|
||||
Poprawki
|
||||
• Po otwarciu aplikacji następnego ranka widać właściwy dzień. Widok miesiąca oznaczał wczoraj jako dziś i zostawiał zaznaczony dzień wybrany poprzedniego wieczoru. Teraz wszystkie widoki przechodzą na nowy dzień.
|
||||
@@ -0,0 +1,2 @@
|
||||
Corrigido
|
||||
• Ao abrir o app na manhã seguinte, aparece o dia certo. A visualização do mês marcava ontem como hoje e deixava selecionado o dia escolhido na noite anterior. Agora todas as visualizações passam para o novo dia.
|
||||
@@ -0,0 +1,2 @@
|
||||
Corrigido
|
||||
• Ao abrir a app na manhã seguinte, aparece o dia certo. A vista do mês marcava ontem como hoje e deixava selecionado o dia escolhido na noite anterior. Agora todas as vistas passam para o novo dia.
|
||||
@@ -0,0 +1,2 @@
|
||||
Исправлено
|
||||
• Если открыть приложение на следующее утро, оно показывает правильный день. Раньше месяц отмечал вчерашний день как сегодняшний и не снимал выделение с дня, выбранного накануне вечером. Теперь все виды переходят на новый день.
|
||||
@@ -0,0 +1,2 @@
|
||||
Opravené
|
||||
• Keď aplikáciu otvoríte na druhý deň ráno, ukáže správny deň. Mesiac predtým označoval včerajšok ako dnešok a nechával vybraný deň, ktorý ste zvolili večer predtým. Všetky zobrazenia teraz prejdú na nový deň.
|
||||
@@ -0,0 +1,2 @@
|
||||
修复
|
||||
• 第二天早上打开应用时,会显示正确的日期。以前月视图会把昨天标为今天,并保留前一天晚上选中的日期。现在所有视图都会切换到新的一天。
|
||||
+1
-1
Submodule floret-kit updated: b7e73ee880...8b33635a85
@@ -1,6 +1,6 @@
|
||||
[versions]
|
||||
agp = "9.2.1"
|
||||
kotlin = "2.3.21"
|
||||
agp = "9.4.1"
|
||||
kotlin = "2.4.20"
|
||||
ksp = "2.3.11"
|
||||
hilt = "2.60.1"
|
||||
coreKtx = "1.19.0"
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+4
-2
@@ -1,8 +1,10 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
|
||||
distributionSha256Sum=bafc141b619ad6350fd975fc903156dd5c151998cc8b058e8c1044ab5f7b031f
|
||||
distributionSha256Sum=bafd5ce9cfaea0fbccfdc8439a1ac42fbd4cd9c89dc9a988228d8a2639a58e6c
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.0-bin.zip
|
||||
networkTimeout=10000
|
||||
retries=0
|
||||
retryBackOffMs=500
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
# gradlew start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
@@ -29,7 +29,7 @@
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
# ksh gradlew
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
@@ -57,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -172,7 +171,6 @@ fi
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
|
||||
Vendored
+52
-34
@@ -19,12 +19,39 @@
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem gradlew startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
@rem Set local scope for the variables, and ensure extensions are enabled
|
||||
setlocal EnableExtensions
|
||||
|
||||
@rem Catch executions from older scripts and ensure they exit cleanly.
|
||||
@rem This can be removed once we can be reasonably confident that few people
|
||||
@rem will be migrating directly to this new wrapper.
|
||||
goto afterSafetyNet
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
goto exitWithErrorLevel
|
||||
:afterSafetyNet
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@@ -45,13 +72,14 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
1>&2 echo.
|
||||
1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
1>&2 echo.
|
||||
1>&2 echo Please set the JAVA_HOME variable in your environment to match the
|
||||
1>&2 echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
"%COMSPEC%" /c exit 1
|
||||
goto exitWithErrorLevel
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
@@ -59,36 +87,26 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
1>&2 echo.
|
||||
1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
1>&2 echo.
|
||||
1>&2 echo Please set the JAVA_HOME variable in your environment to match the
|
||||
1>&2 echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
"%COMSPEC%" /c exit 1
|
||||
goto exitWithErrorLevel
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
@rem Execute gradlew
|
||||
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
|
||||
@rem which allows us to clear the local environment before executing the java command
|
||||
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel & goto exitWithErrorLevel
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem This label must not be changed. We rely on old scripts being able to jump to this point.
|
||||
:exitWithErrorLevel
|
||||
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
|
||||
"%COMSPEC%" /c exit %ERRORLEVEL%
|
||||
|
||||
Reference in New Issue
Block a user