2.19.1 — drag to reschedule can be turned off (#176)
All checks were successful
Renovate / renovate (push) Successful in 3m1s
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 16m19s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 2m29s
All checks were successful
Renovate / renovate (push) Successful in 3m1s
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 6s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 16m19s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 2m29s
Release branch for 2.19.1. Merging this cuts the release — versionName is bumped to 2.19.1 (versionCode 21901), which is what release.yaml picks up. ### What's in it - **Drag to reschedule can be turned off** (#173). Settings → Views → *Drag to reschedule*, on by default. Turned off, no event block in the month, week or day view registers a drag gesture. The gate is `EventMoveScope.dragEnabled` rather than the scope itself, so the screen-reader "Move event" action — which only opens the edit form — stays available either way. The setting reads as off until the stored value has actually loaded, so a cold start can't hand out a drag before the preference is known. ### Release prep - CHANGELOG 2.19.1 section written. - Per-version "What's New" hand-written for all 12 store locales (`ar`, `de-DE`, `en-GB`, `en-US`, `es-ES`, `fr-FR`, `it-IT`, `pl-PL`, `pt-BR`, `pt-PT`, `ru-RU`, `zh-CN`). - `lint test assembleDebug` and `check_translations.py` green locally. - main is one commit ahead (Weblate #175, translations only) and merges clean — not merged into the branch, it comes along with this one. Closes #173 Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de> Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/176
This commit is contained in:
25
CHANGELOG.md
25
CHANGELOG.md
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2.19.1] — 2026-08-11
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- **Drag to reschedule can be turned off.** Settings → Views → *Drag to
|
||||||
|
reschedule*, on by default. Off, no event can be picked up in the month, week
|
||||||
|
or day view — for anyone who kept moving appointments by accident while
|
||||||
|
scrolling ([#173]).
|
||||||
|
- An early Brazilian Portuguese translation. Calendula has started speaking
|
||||||
|
Brazilian Portuguese, contributed as a community translation through
|
||||||
|
[Calendula's Weblate](https://weblate.dev.jeanlucmakiola.de/projects/calendula/).
|
||||||
|
About a third of the app is covered, so the rest still shows in English — you
|
||||||
|
can pick it under Settings → Language or in Android's per-app language
|
||||||
|
settings. Thanks to
|
||||||
|
[bkrz](https://weblate.dev.jeanlucmakiola.de/user/bkrz/) for getting it
|
||||||
|
started; help finishing it is very welcome.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **The language picker forgot which language was picked.** Android hands the
|
||||||
|
applied language back with its script filled in — Simplified Chinese goes in
|
||||||
|
as `zh-CN` and comes out as `zh-Hans-CN` — so after a restart no entry in
|
||||||
|
Settings → Language showed as selected, and the row above it named the
|
||||||
|
language the long way round. Only languages that imply a script were
|
||||||
|
affected.
|
||||||
|
|
||||||
## [2.19.0] — 2026-08-10
|
## [2.19.0] — 2026-08-10
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -1389,3 +1413,4 @@ automatically, with zero telemetry and no internet permission.
|
|||||||
[#80]: https://codeberg.org/jlmakiola/calendula/issues/80
|
[#80]: https://codeberg.org/jlmakiola/calendula/issues/80
|
||||||
[#123]: https://codeberg.org/jlmakiola/calendula/issues/123
|
[#123]: https://codeberg.org/jlmakiola/calendula/issues/123
|
||||||
[#163]: https://codeberg.org/jlmakiola/calendula/issues/163
|
[#163]: https://codeberg.org/jlmakiola/calendula/issues/163
|
||||||
|
[#173]: https://codeberg.org/jlmakiola/calendula/issues/173
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ android {
|
|||||||
// which builds this version and then creates the matching vX.Y.Z tag +
|
// which builds this version and then creates the matching vX.Y.Z tag +
|
||||||
// release itself (versionCode is pinned to MAJOR*10000 + MINOR*100 +
|
// release itself (versionCode is pinned to MAJOR*10000 + MINOR*100 +
|
||||||
// PATCH from versionName, e.g. 2.7.2 -> 20702). See docs/RELEASING.md.
|
// PATCH from versionName, e.g. 2.7.2 -> 20702). See docs/RELEASING.md.
|
||||||
versionCode = 21900
|
versionCode = 21901
|
||||||
versionName = "2.19.0"
|
versionName = "2.19.1"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -301,6 +301,19 @@ class SettingsPrefs @Inject constructor(
|
|||||||
store.edit { it[TODAY_BUTTON_IN_TOOLBAR_KEY] = enabled }
|
store.edit { it[TODAY_BUTTON_IN_TOOLBAR_KEY] = enabled }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether events can be dragged to another slot in the calendar views (#68,
|
||||||
|
* #173). Defaults to ON. Off means no block registers a drag gesture at all;
|
||||||
|
* rescheduling then goes through the edit form.
|
||||||
|
*/
|
||||||
|
val dragToReschedule: Flow<Boolean> = store.data.map { prefs ->
|
||||||
|
prefs[DRAG_TO_RESCHEDULE_KEY] ?: true
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun setDragToReschedule(enabled: Boolean) {
|
||||||
|
store.edit { it[DRAG_TO_RESCHEDULE_KEY] = enabled }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How far ahead the in-app Agenda screen shows events (v2.11). Defaults to
|
* How far ahead the in-app Agenda screen shows events (v2.11). Defaults to
|
||||||
* [AgendaRange.Month] — a month of upcoming events. Independent of the
|
* [AgendaRange.Month] — a month of upcoming events. Independent of the
|
||||||
@@ -945,6 +958,7 @@ class SettingsPrefs @Inject constructor(
|
|||||||
internal val MONTH_VIEW_STYLE_KEY = stringPreferencesKey("month_view_style")
|
internal val MONTH_VIEW_STYLE_KEY = stringPreferencesKey("month_view_style")
|
||||||
internal val TIMELINE_SCALE_KEY = stringPreferencesKey("timeline_scale")
|
internal val TIMELINE_SCALE_KEY = stringPreferencesKey("timeline_scale")
|
||||||
internal val TODAY_BUTTON_IN_TOOLBAR_KEY = booleanPreferencesKey("today_button_in_toolbar")
|
internal val TODAY_BUTTON_IN_TOOLBAR_KEY = booleanPreferencesKey("today_button_in_toolbar")
|
||||||
|
internal val DRAG_TO_RESCHEDULE_KEY = booleanPreferencesKey("drag_to_reschedule")
|
||||||
internal val DEFAULT_VIEW_KEY = stringPreferencesKey("default_view")
|
internal val DEFAULT_VIEW_KEY = stringPreferencesKey("default_view")
|
||||||
internal val QUICK_SWITCH_VIEWS_KEY = stringPreferencesKey("quick_switch_views")
|
internal val QUICK_SWITCH_VIEWS_KEY = stringPreferencesKey("quick_switch_views")
|
||||||
internal val DRAWER_VIEW_ORDER_KEY = stringPreferencesKey("drawer_view_order")
|
internal val DRAWER_VIEW_ORDER_KEY = stringPreferencesKey("drawer_view_order")
|
||||||
|
|||||||
@@ -312,9 +312,13 @@ fun CalendarHost(
|
|||||||
heldEditKey = key
|
heldEditKey = key
|
||||||
editKey = key
|
editKey = key
|
||||||
}
|
}
|
||||||
val moveScope = remember(movableCalendarIds, reschedule) {
|
// Off by preference (#173) switches off the gesture, not the scope: blocks
|
||||||
|
// register no drag, while the edit form and its TalkBack action stay put.
|
||||||
|
val dragToReschedule = viewModel.dragToReschedule.collectAsStateWithLifecycle().value
|
||||||
|
val moveScope = remember(movableCalendarIds, reschedule, dragToReschedule) {
|
||||||
EventMoveScope(
|
EventMoveScope(
|
||||||
movableCalendarIds = movableCalendarIds,
|
movableCalendarIds = movableCalendarIds,
|
||||||
|
dragEnabled = dragToReschedule,
|
||||||
move = reschedule::move,
|
move = reschedule::move,
|
||||||
inFlight = reschedule.inFlight,
|
inFlight = reschedule.inFlight,
|
||||||
undoStarted = reschedule.undoStarted,
|
undoStarted = reschedule.undoStarted,
|
||||||
|
|||||||
@@ -53,4 +53,18 @@ class CalendarHostViewModel @Inject constructor(
|
|||||||
started = SharingStarted.WhileSubscribed(5_000L),
|
started = SharingStarted.WhileSubscribed(5_000L),
|
||||||
initialValue = false,
|
initialValue = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether events may be dragged to another slot to reschedule them (#68, #173).
|
||||||
|
* Off until the stored value arrives, even though the preference itself defaults
|
||||||
|
* on: the wrong guess costs an enabled user a gesture for the few frames a cold
|
||||||
|
* start takes to read DataStore, but re-arms the one thing a disabled user
|
||||||
|
* switched off to be rid of.
|
||||||
|
*/
|
||||||
|
val dragToReschedule: StateFlow<Boolean> = prefs.dragToReschedule
|
||||||
|
.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = SharingStarted.WhileSubscribed(5_000L),
|
||||||
|
initialValue = false,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ class EventMoveScope(
|
|||||||
* the repository writes whatever it is handed — so this gate is load-bearing.
|
* the repository writes whatever it is handed — so this gate is load-bearing.
|
||||||
*/
|
*/
|
||||||
val movableCalendarIds: Set<Long>,
|
val movableCalendarIds: Set<Long>,
|
||||||
|
/**
|
||||||
|
* Whether the *gesture* is on (#173). Off gates the drag alone: [edit] and the
|
||||||
|
* TalkBack action below stay, since invoking a menu item can't cause the
|
||||||
|
* accidental drags the setting exists to stop.
|
||||||
|
*/
|
||||||
|
val dragEnabled: Boolean,
|
||||||
/** False when the drop was refused outright, so nothing will be written. */
|
/** False when the drop was refused outright, so nothing will be written. */
|
||||||
val move: (MoveRequest) -> Boolean,
|
val move: (MoveRequest) -> Boolean,
|
||||||
/**
|
/**
|
||||||
@@ -91,6 +97,17 @@ fun ghostAlpha(lifted: Boolean): Float = animateFloatAsState(
|
|||||||
label = "ghost-alpha",
|
label = "ghost-alpha",
|
||||||
).value
|
).value
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether [event] can be picked up and dragged — its calendar allows moving and
|
||||||
|
* the gesture is switched on. Not the same question as [eventMoveAction], which
|
||||||
|
* survives the setting.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun eventDragAllowed(event: EventInstance): Boolean {
|
||||||
|
val move = LocalEventMove.current ?: return false
|
||||||
|
return move.dragEnabled && move.allows(event)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A TalkBack action that opens [event] in the edit form, so rescheduling isn't
|
* A TalkBack action that opens [event] in the edit form, so rescheduling isn't
|
||||||
* pointer-only. Null when this event can't be moved.
|
* pointer-only. Null when this event can't be moved.
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ import de.jeanlucmakiola.calendula.ui.common.TimelineDragController
|
|||||||
import de.jeanlucmakiola.calendula.ui.common.TimelineDragOverlay
|
import de.jeanlucmakiola.calendula.ui.common.TimelineDragOverlay
|
||||||
import de.jeanlucmakiola.calendula.ui.common.TimelineDrop
|
import de.jeanlucmakiola.calendula.ui.common.TimelineDrop
|
||||||
import de.jeanlucmakiola.calendula.ui.common.beginsOn
|
import de.jeanlucmakiola.calendula.ui.common.beginsOn
|
||||||
|
import de.jeanlucmakiola.calendula.ui.common.eventDragAllowed
|
||||||
import de.jeanlucmakiola.calendula.ui.common.eventMoveAction
|
import de.jeanlucmakiola.calendula.ui.common.eventMoveAction
|
||||||
import de.jeanlucmakiola.calendula.ui.common.rememberEventDragSource
|
import de.jeanlucmakiola.calendula.ui.common.rememberEventDragSource
|
||||||
import de.jeanlucmakiola.calendula.ui.common.rememberTimelineDragController
|
import de.jeanlucmakiola.calendula.ui.common.rememberTimelineDragController
|
||||||
@@ -737,7 +738,7 @@ private fun EventBlock(
|
|||||||
val moveAction = eventMoveAction(block.event)
|
val moveAction = eventMoveAction(block.event)
|
||||||
// A block clipped at the top continues from the previous day: its top edge
|
// A block clipped at the top continues from the previous day: its top edge
|
||||||
// is midnight, not the event's start, so dragging it would invent a time.
|
// is midnight, not the event's start, so dragging it would invent a time.
|
||||||
val draggable = moveAction != null && block.beginsOn(date, zone)
|
val draggable = eventDragAllowed(block.event) && block.beginsOn(date, zone)
|
||||||
val dragModifier = rememberEventDragSource(
|
val dragModifier = rememberEventDragSource(
|
||||||
enabled = draggable,
|
enabled = draggable,
|
||||||
key = block.event.instanceId,
|
key = block.event.instanceId,
|
||||||
|
|||||||
@@ -2172,7 +2172,7 @@ private fun monthChipDragModifier(
|
|||||||
rowHeightPx: Float,
|
rowHeightPx: Float,
|
||||||
isRtl: Boolean,
|
isRtl: Boolean,
|
||||||
): Modifier = rememberDragSurface(
|
): Modifier = rememberDragSurface(
|
||||||
enabled = moveScope != null && controller != null,
|
enabled = moveScope?.dragEnabled == true && controller != null,
|
||||||
key = week.days.first(),
|
key = week.days.first(),
|
||||||
onPickUp = { local, pointerInRoot, nodeInRoot, size ->
|
onPickUp = { local, pointerInRoot, nodeInRoot, size ->
|
||||||
val bandTop = band[0]?.takeIf { it.isAttached }?.positionInRoot()?.y
|
val bandTop = band[0]?.takeIf { it.isAttached }?.positionInRoot()?.y
|
||||||
|
|||||||
@@ -302,13 +302,14 @@ private fun ReportProblemRow(position: Position) {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun LanguageRow(position: Position) {
|
private fun LanguageRow(position: Position) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
val supported = remember { AppLanguage.supportedTags(context, R.xml.locales_config) }
|
||||||
// Setting a locale recreates the activity; mirror the choice locally so the
|
// Setting a locale recreates the activity; mirror the choice locally so the
|
||||||
// row updates instantly even before the recreation lands.
|
// row updates instantly even before the recreation lands.
|
||||||
var current by remember { mutableStateOf(AppLanguage.currentTag()) }
|
var current by remember { mutableStateOf(AppLanguage.currentTag(supported)) }
|
||||||
var showDialog by remember { mutableStateOf(false) }
|
var showDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
// null = follow the system; the rest are BCP-47 tags from locales_config.xml.
|
// null = follow the system; the rest are BCP-47 tags from locales_config.xml.
|
||||||
val options = remember { listOf<String?>(null) + AppLanguage.supportedTags(context, R.xml.locales_config) }
|
val options = remember(supported) { listOf<String?>(null) + supported }
|
||||||
|
|
||||||
GroupedRow(
|
GroupedRow(
|
||||||
title = stringResource(R.string.settings_language),
|
title = stringResource(R.string.settings_language),
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ data class SettingsUiState(
|
|||||||
val showWeekNumbers: Boolean = false,
|
val showWeekNumbers: Boolean = false,
|
||||||
/** Whether the jump-to-today control sits in the top bar instead of the FAB (#60). */
|
/** Whether the jump-to-today control sits in the top bar instead of the FAB (#60). */
|
||||||
val todayButtonInToolbar: Boolean = false,
|
val todayButtonInToolbar: Boolean = false,
|
||||||
|
/** Whether events can be dragged to another slot to reschedule them (#68, #173). */
|
||||||
|
val dragToReschedule: Boolean = true,
|
||||||
/** How far ahead the in-app Agenda screen shows events (v2.11). */
|
/** How far ahead the in-app Agenda screen shows events (v2.11). */
|
||||||
val agendaScreenRange: AgendaRange = AgendaRange.Month,
|
val agendaScreenRange: AgendaRange = AgendaRange.Month,
|
||||||
/** How far ahead the agenda widget shows events (v2.11). */
|
/** How far ahead the agenda widget shows events (v2.11). */
|
||||||
|
|||||||
@@ -145,9 +145,15 @@ class SettingsViewModel @Inject constructor(
|
|||||||
prefs.showWeekNumbers,
|
prefs.showWeekNumbers,
|
||||||
prefs.agendaShowToday,
|
prefs.agendaShowToday,
|
||||||
prefs.softenCalendarColors,
|
prefs.softenCalendarColors,
|
||||||
|
combine(
|
||||||
prefs.todayButtonInToolbar,
|
prefs.todayButtonInToolbar,
|
||||||
) { hourLines, weekNumbers, showToday, soften, todayInToolbar ->
|
prefs.dragToReschedule,
|
||||||
DisplayToggles(hourLines, weekNumbers, showToday, soften, todayInToolbar)
|
::Pair,
|
||||||
|
),
|
||||||
|
) { hourLines, weekNumbers, showToday, soften, (todayInToolbar, dragToMove) ->
|
||||||
|
DisplayToggles(
|
||||||
|
hourLines, weekNumbers, showToday, soften, todayInToolbar, dragToMove,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
) { view, screenRange, widgetRange, timeFormat, toggles ->
|
) { view, screenRange, widgetRange, timeFormat, toggles ->
|
||||||
ViewSettings(
|
ViewSettings(
|
||||||
@@ -157,6 +163,7 @@ class SettingsViewModel @Inject constructor(
|
|||||||
agendaShowToday = toggles.agendaShowToday,
|
agendaShowToday = toggles.agendaShowToday,
|
||||||
softenColors = toggles.softenColors,
|
softenColors = toggles.softenColors,
|
||||||
todayButtonInToolbar = toggles.todayButtonInToolbar,
|
todayButtonInToolbar = toggles.todayButtonInToolbar,
|
||||||
|
dragToReschedule = toggles.dragToReschedule,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
combine(
|
combine(
|
||||||
@@ -189,6 +196,7 @@ class SettingsViewModel @Inject constructor(
|
|||||||
agendaShowToday = views.agendaShowToday,
|
agendaShowToday = views.agendaShowToday,
|
||||||
softenColors = views.softenColors,
|
softenColors = views.softenColors,
|
||||||
todayButtonInToolbar = views.todayButtonInToolbar,
|
todayButtonInToolbar = views.todayButtonInToolbar,
|
||||||
|
dragToReschedule = views.dragToReschedule,
|
||||||
agendaShowRangeBar = misc.showRangeBar,
|
agendaShowRangeBar = misc.showRangeBar,
|
||||||
autofocusEventTitle = misc.autofocusEventTitle,
|
autofocusEventTitle = misc.autofocusEventTitle,
|
||||||
pastEventDisplay = misc.pastEventDisplay,
|
pastEventDisplay = misc.pastEventDisplay,
|
||||||
@@ -289,6 +297,7 @@ class SettingsViewModel @Inject constructor(
|
|||||||
val agendaShowToday: Boolean,
|
val agendaShowToday: Boolean,
|
||||||
val softenColors: Boolean,
|
val softenColors: Boolean,
|
||||||
val todayButtonInToolbar: Boolean,
|
val todayButtonInToolbar: Boolean,
|
||||||
|
val dragToReschedule: Boolean,
|
||||||
)
|
)
|
||||||
|
|
||||||
private data class DisplayToggles(
|
private data class DisplayToggles(
|
||||||
@@ -297,6 +306,7 @@ class SettingsViewModel @Inject constructor(
|
|||||||
val agendaShowToday: Boolean,
|
val agendaShowToday: Boolean,
|
||||||
val softenColors: Boolean,
|
val softenColors: Boolean,
|
||||||
val todayButtonInToolbar: Boolean,
|
val todayButtonInToolbar: Boolean,
|
||||||
|
val dragToReschedule: Boolean,
|
||||||
)
|
)
|
||||||
|
|
||||||
private data class MiscSettings(
|
private data class MiscSettings(
|
||||||
@@ -534,6 +544,10 @@ class SettingsViewModel @Inject constructor(
|
|||||||
viewModelScope.launch { prefs.setTodayButtonInToolbar(enabled) }
|
viewModelScope.launch { prefs.setTodayButtonInToolbar(enabled) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setDragToReschedule(enabled: Boolean) {
|
||||||
|
viewModelScope.launch { prefs.setDragToReschedule(enabled) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch the launcher label (#44). The card highlights at once, then settles
|
* Switch the launcher label (#44). The card highlights at once, then settles
|
||||||
* on what the component state reports; the writes are binder round-trips and
|
* on what the component state reports; the writes are binder round-trips and
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ internal fun ViewsScreen(
|
|||||||
GroupedRow(
|
GroupedRow(
|
||||||
title = stringResource(R.string.settings_dim_completed),
|
title = stringResource(R.string.settings_dim_completed),
|
||||||
summary = stringResource(R.string.settings_dim_completed_summary),
|
summary = stringResource(R.string.settings_dim_completed_summary),
|
||||||
position = Position.Bottom,
|
position = Position.Middle,
|
||||||
trailing = {
|
trailing = {
|
||||||
Switch(
|
Switch(
|
||||||
checked = state.dimCompletedEvents,
|
checked = state.dimCompletedEvents,
|
||||||
@@ -123,6 +123,18 @@ internal fun ViewsScreen(
|
|||||||
},
|
},
|
||||||
onClick = { viewModel.setDimCompletedEvents(!state.dimCompletedEvents) },
|
onClick = { viewModel.setDimCompletedEvents(!state.dimCompletedEvents) },
|
||||||
)
|
)
|
||||||
|
GroupedRow(
|
||||||
|
title = stringResource(R.string.settings_drag_to_reschedule),
|
||||||
|
summary = stringResource(R.string.settings_drag_to_reschedule_summary),
|
||||||
|
position = Position.Bottom,
|
||||||
|
trailing = {
|
||||||
|
Switch(
|
||||||
|
checked = state.dragToReschedule,
|
||||||
|
onCheckedChange = viewModel::setDragToReschedule,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick = { viewModel.setDragToReschedule(!state.dragToReschedule) },
|
||||||
|
)
|
||||||
|
|
||||||
Spacer(Modifier.height(8.dp))
|
Spacer(Modifier.height(8.dp))
|
||||||
SectionHeader(stringResource(R.string.settings_month_header))
|
SectionHeader(stringResource(R.string.settings_month_header))
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ import de.jeanlucmakiola.calendula.ui.common.TimelineDragController
|
|||||||
import de.jeanlucmakiola.calendula.ui.common.TimelineDragOverlay
|
import de.jeanlucmakiola.calendula.ui.common.TimelineDragOverlay
|
||||||
import de.jeanlucmakiola.calendula.ui.common.TimelineDrop
|
import de.jeanlucmakiola.calendula.ui.common.TimelineDrop
|
||||||
import de.jeanlucmakiola.calendula.ui.common.beginsOn
|
import de.jeanlucmakiola.calendula.ui.common.beginsOn
|
||||||
|
import de.jeanlucmakiola.calendula.ui.common.eventDragAllowed
|
||||||
import de.jeanlucmakiola.calendula.ui.common.eventMoveAction
|
import de.jeanlucmakiola.calendula.ui.common.eventMoveAction
|
||||||
import de.jeanlucmakiola.calendula.ui.common.rememberEventDragSource
|
import de.jeanlucmakiola.calendula.ui.common.rememberEventDragSource
|
||||||
import de.jeanlucmakiola.calendula.ui.common.rememberTimelineDragController
|
import de.jeanlucmakiola.calendula.ui.common.rememberTimelineDragController
|
||||||
@@ -905,7 +906,7 @@ private fun EventBlock(
|
|||||||
val moveAction = eventMoveAction(block.event)
|
val moveAction = eventMoveAction(block.event)
|
||||||
// A block clipped at the top continues from the previous day: its top edge
|
// A block clipped at the top continues from the previous day: its top edge
|
||||||
// is midnight, not the event's start, so dragging it would invent a time.
|
// is midnight, not the event's start, so dragging it would invent a time.
|
||||||
val draggable = moveAction != null && block.beginsOn(date, zone)
|
val draggable = eventDragAllowed(block.event) && block.beginsOn(date, zone)
|
||||||
val dragModifier = rememberEventDragSource(
|
val dragModifier = rememberEventDragSource(
|
||||||
enabled = draggable,
|
enabled = draggable,
|
||||||
key = block.event.instanceId,
|
key = block.event.instanceId,
|
||||||
|
|||||||
@@ -439,6 +439,8 @@
|
|||||||
<string name="timeline_scale_custom_summary">The height you pinched the timeline to</string>
|
<string name="timeline_scale_custom_summary">The height you pinched the timeline to</string>
|
||||||
<string name="settings_dim_completed">Dim completed events</string>
|
<string name="settings_dim_completed">Dim completed events</string>
|
||||||
<string name="settings_dim_completed_summary">Fade events that have already ended in month and week view</string>
|
<string name="settings_dim_completed_summary">Fade events that have already ended in month and week view</string>
|
||||||
|
<string name="settings_drag_to_reschedule">Drag to reschedule</string>
|
||||||
|
<string name="settings_drag_to_reschedule_summary">Move an event by dragging it to another day or time</string>
|
||||||
<string name="settings_past_events">Past events</string>
|
<string name="settings_past_events">Past events</string>
|
||||||
<string name="settings_past_events_show">Show</string>
|
<string name="settings_past_events_show">Show</string>
|
||||||
<string name="settings_past_events_dim">Dim</string>
|
<string name="settings_past_events_dim">Dim</string>
|
||||||
|
|||||||
@@ -15,5 +15,6 @@
|
|||||||
<locale android:name="fr" />
|
<locale android:name="fr" />
|
||||||
<locale android:name="it" />
|
<locale android:name="it" />
|
||||||
<locale android:name="pl" />
|
<locale android:name="pl" />
|
||||||
|
<locale android:name="pt-BR" />
|
||||||
<locale android:name="zh-CN" />
|
<locale android:name="zh-CN" />
|
||||||
</locale-config>
|
</locale-config>
|
||||||
|
|||||||
3
fastlane/metadata/android/ar/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/ar/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
جديد
|
||||||
|
• صار بالإمكان إيقاف السحب لتغيير الموعد: الإعدادات ← العروض ← «السحب لتغيير الموعد». يبقى مفعّلاً افتراضياً؛ وعند إيقافه لا يمكن سحب الأحداث في عرض الشهر أو الأسبوع أو اليوم.
|
||||||
|
• صار Calendula يتحدّث البرتغالية البرازيلية بفضل ترجمة من المجتمع. اخترها من الإعدادات ← اللغة.
|
||||||
3
fastlane/metadata/android/de-DE/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/de-DE/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Neu
|
||||||
|
• Verschieben per Drag & Drop lässt sich abschalten: Einstellungen → Ansichten → „Per Ziehen verschieben“. Standardmäßig bleibt es an; abgeschaltet lassen sich Termine in der Monats-, Wochen- und Tagesansicht nicht mehr aufnehmen.
|
||||||
|
• Calendula spricht jetzt brasilianisches Portugiesisch – dank einer Community-Übersetzung. Auswählbar unter Einstellungen → Sprache.
|
||||||
3
fastlane/metadata/android/en-GB/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/en-GB/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Added
|
||||||
|
• Drag to reschedule can now be turned off: Settings → Views → “Drag to reschedule”. It stays on by default; switched off, events can no longer be picked up in the month, week or day view.
|
||||||
|
• Calendula now speaks Brazilian Portuguese, thanks to a community translation. Pick it under Settings → Language.
|
||||||
3
fastlane/metadata/android/en-US/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Added
|
||||||
|
• Drag to reschedule can now be turned off: Settings → Views → “Drag to reschedule”. It stays on by default; switched off, events can no longer be picked up in the month, week or day view.
|
||||||
|
• Calendula now speaks Brazilian Portuguese, thanks to a community translation. Pick it under Settings → Language.
|
||||||
3
fastlane/metadata/android/es-ES/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/es-ES/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Novedades
|
||||||
|
• Ahora se puede desactivar el mover eventos arrastrando: Ajustes → Vistas → «Arrastrar para reprogramar». Sigue activado por defecto; desactivado, los eventos ya no se pueden arrastrar en las vistas de mes, semana y día.
|
||||||
|
• Calendula ya habla portugués de Brasil, gracias a una traducción de la comunidad. Elígelo en Ajustes → Idioma.
|
||||||
3
fastlane/metadata/android/fr-FR/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/fr-FR/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Nouveautés
|
||||||
|
• Le déplacement par glisser-déposer peut désormais être désactivé : Réglages → Vues → « Glisser pour déplacer ». Il reste activé par défaut ; désactivé, les événements ne peuvent plus être saisis en vue mois, semaine ou jour.
|
||||||
|
• Calendula parle désormais le portugais brésilien, grâce à une traduction de la communauté. À choisir dans Réglages → Langue.
|
||||||
3
fastlane/metadata/android/it-IT/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/it-IT/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Novità
|
||||||
|
• Ora lo spostamento con il trascinamento si può disattivare: Impostazioni → Viste → «Trascina per spostare». Resta attivo di default; disattivato, gli eventi non si possono più trascinare nelle viste mese, settimana e giorno.
|
||||||
|
• Calendula ora parla portoghese brasiliano, grazie a una traduzione della comunità. Si sceglie in Impostazioni → Lingua.
|
||||||
3
fastlane/metadata/android/pl-PL/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/pl-PL/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Nowości
|
||||||
|
• Przenoszenie wydarzeń przeciąganiem można teraz wyłączyć: Ustawienia → Widoki → „Przeciągnij, aby przenieść”. Domyślnie pozostaje włączone; po wyłączeniu wydarzeń nie da się już chwycić w widoku miesiąca, tygodnia i dnia.
|
||||||
|
• Calendula mówi teraz po portugalsku (Brazylia) dzięki tłumaczeniu społeczności. Wybierzesz je w Ustawienia → Język.
|
||||||
3
fastlane/metadata/android/pt-BR/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/pt-BR/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Novidades
|
||||||
|
• Agora é possível desativar o mover eventos arrastando: Configurações → Visualizações → “Arrastar para reagendar”. Continua ativo por padrão; desativado, os eventos não podem mais ser arrastados nas visualizações de mês, semana e dia.
|
||||||
|
• O Calendula agora fala português do Brasil, graças a uma tradução da comunidade. Escolha em Configurações → Idioma.
|
||||||
3
fastlane/metadata/android/pt-PT/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/pt-PT/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Novidades
|
||||||
|
• Já é possível desativar o mover eventos arrastando: Definições → Vistas → «Arrastar para reagendar». Continua ativo por predefinição; desativado, os eventos deixam de poder ser arrastados nas vistas de mês, semana e dia.
|
||||||
|
• O Calendula fala agora português do Brasil, graças a uma tradução da comunidade. Escolha em Definições → Idioma.
|
||||||
3
fastlane/metadata/android/ru-RU/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/ru-RU/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Новое
|
||||||
|
• Перенос событий перетаскиванием теперь можно отключить: Настройки → Виды → «Перетаскивание для переноса». По умолчанию включён; при отключении события больше нельзя подхватить в видах месяца, недели и дня.
|
||||||
|
• Calendula теперь говорит на бразильском португальском — благодаря переводу сообщества. Выбрать можно в Настройки → Язык.
|
||||||
3
fastlane/metadata/android/zh-CN/changelogs/21901.txt
Normal file
3
fastlane/metadata/android/zh-CN/changelogs/21901.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
新增
|
||||||
|
• 现在可以关闭拖动改期:设置 → 视图 → “拖动改期”。默认保持开启;关闭后,月、周、日视图中的事件将无法再被拖起。
|
||||||
|
• Calendula 现已支持巴西葡萄牙语,感谢社区翻译。可在设置 → 语言中选择。
|
||||||
Submodule floret-kit updated: 05c79f2afc...ad440e8cac
Reference in New Issue
Block a user