Compare commits

..
Author SHA1 Message Date
makiolaj 984da3c61c Share side-inset padding, fix keyboard gap on detail and edit (#152) 2026-11-12 16:07:32 +01:00
makiolaj d562cf85f2 Keep home and task list clear of the navigation bar (#152) 2026-11-12 15:58:31 +01:00
Jean-Luc Makiolaandmakiolaj 3e34c60577 Release 1.3.1 (#146)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 18s
Renovate / renovate (push) Successful in 2m30s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Successful in 21m13s
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Successful in 1m28s
Beta — Codeberg pre-release / detect (push) Successful in 5s
Beta — Codeberg pre-release / beta (push) Skipped
Bumps to 1.3.1 (1030199), dates the changelog and adds the What's New for all eight store locales.

- Ticking a repeating task moves the series on (#137, #144)
- Recurring tasks keep their rule with tasks.org and OpenTasks (#135, #142)
- Keep the list order with tasks.org and OpenTasks (#136, #143)

Closes #135, closes #136, closes #137

Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de>
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/146
2026-11-09 20:02:41 +01:00
Jean-Luc Makiola caf4357cee Translations update from Weblate (#138)
Release — F-Droid repo + Gitea/Codeberg release + Play / detect (push) Successful in 10s
Release — F-Droid repo + Gitea/Codeberg release + Play / release (push) Skipped
Release — F-Droid repo + Gitea/Codeberg release + Play / play (push) Skipped
Renovate / renovate (push) Successful in 2m21s
Reviewed-on: https://codeberg.org/jlmakiola/agendula/pulls/138
2026-11-09 19:15:30 +01:00
Weblate 97164feb39 Translated using Weblate (Arabic)
Currently translated at 87.5% (613 of 700 strings)

Translation: Agendula/agendula
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/agendula/agendula/ar/
2026-11-08 01:42:41 +00:00
Sup99999 8a521d32f9 Translated using Weblate (Arabic)
Currently translated at 87.5% (613 of 700 strings)

Translation: Agendula/agendula
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/agendula/agendula/ar/
2026-11-08 01:42:41 +00:00
Савелий b68582177b Translated using Weblate (Russian)
Currently translated at 5.8% (41 of 700 strings)

Translation: Agendula/agendula
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/agendula/agendula/ru/
2026-11-07 15:27:54 +00:00
Sup99999 05f43d6f76 Translated using Weblate (Arabic)
Currently translated at 80.0% (560 of 700 strings)

Translation: Agendula/agendula
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/agendula/agendula/ar/
2026-11-05 04:12:37 +00:00
Knee8811 7498ffb37e Translated using Weblate (Czech)
Currently translated at 39.3% (266 of 676 strings)

Translation: Agendula/agendula
Translate-URL: https://weblate.dev.jeanlucmakiola.de/projects/agendula/agendula/cs/
2026-11-04 22:18:19 +00:00
9 changed files with 182 additions and 6 deletions

No files matched your search

+6
View File
@@ -7,6 +7,12 @@ All notable changes to this project are documented here. The format follows
## [Unreleased]
### Fixed
- With 3-button navigation, the navigation bar no longer covers the last home
search results, and in landscape it no longer covers the home screen, the
task list or the home top bar's buttons. The task details and editor no
longer leave an empty gap between the open keyboard and the text (#152).
## [1.3.1] - 2026-11-09
### Changed
@@ -0,0 +1,27 @@
package de.jeanlucmakiola.agendula.ui.common
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.dp
/**
* Pads by the start/end of a scaffold's [inner] padding and consumes it, so a
* side navigation bar or cutout (3-button nav in landscape) is cleared once.
*/
@Composable
fun Modifier.sideInsetsPadding(inner: PaddingValues): Modifier {
val layoutDirection = LocalLayoutDirection.current
val sides = PaddingValues(
start = inner.calculateStartPadding(layoutDirection),
top = 0.dp,
end = inner.calculateEndPadding(layoutDirection),
bottom = 0.dp,
)
return this.padding(sides).consumeWindowInsets(sides)
}
@@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -268,6 +269,9 @@ private fun DetailBody(
modifier = Modifier
.fillMaxSize()
.padding(inner)
// Consume the bar insets so imePadding adds only what the keyboard
// covers beyond them.
.consumeWindowInsets(inner)
// Shrink the scroll viewport by the keyboard so the focused add-subtask
// field scrolls into view above the IME instead of being hidden.
.imePadding()
@@ -57,6 +57,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -219,7 +220,9 @@ fun TaskEditScreen(
viewModel = viewModel,
scroll = scroll,
onTitleBottom = { titleBottom = it },
modifier = Modifier.padding(inner),
// Consumed so EditContent's imePadding adds only what the keyboard
// covers beyond the bars.
modifier = Modifier.padding(inner).consumeWindowInsets(inner),
)
}
@@ -29,7 +29,16 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.displayCutout
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
@@ -99,6 +108,7 @@ import de.jeanlucmakiola.agendula.ui.common.LocalUse24HourFormat
import de.jeanlucmakiola.agendula.ui.common.ShapedActionButton
import de.jeanlucmakiola.agendula.ui.common.SyncPullBox
import de.jeanlucmakiola.agendula.ui.common.priorityAccent
import de.jeanlucmakiola.agendula.ui.common.sideInsetsPadding
import de.jeanlucmakiola.agendula.ui.tasklist.priorityLabel
import de.jeanlucmakiola.floret.components.positionOf
import de.jeanlucmakiola.floret.time.formatDateTimeCompact
@@ -180,7 +190,10 @@ fun ListsScreen(
available = syncAvailable && !searchActive,
syncing = syncing,
onSync = viewModel::syncAll,
modifier = Modifier.fillMaxSize().padding(top = inner.calculateTopPadding()),
modifier = Modifier
.fillMaxSize()
.padding(top = inner.calculateTopPadding())
.sideInsetsPadding(inner),
) {
when (val s = state) {
ListsUiState.Loading -> Unit // brief; avoids a flash before first emission
@@ -513,7 +526,10 @@ private fun HomeTopBar(
Row(
modifier = Modifier
.fillMaxWidth()
.statusBarsPadding()
.windowInsetsPadding(
WindowInsets.systemBars.union(WindowInsets.displayCutout)
.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal),
)
.height(72.dp)
.padding(horizontal = 12.dp),
verticalAlignment = Alignment.CenterVertically,
@@ -672,10 +688,14 @@ private fun SearchResults(
)
}
} else {
// The last result scrolls clear of the navigation bar and the keyboard.
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(results, key = { it.occurrenceKey }) { task ->
UpcomingRow(task = task, onClick = { onOpenTask(task) })
}
item(key = "bottom-inset") {
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars.union(WindowInsets.ime)))
}
}
}
}
@@ -115,6 +115,7 @@ import de.jeanlucmakiola.agendula.ui.common.LocalUse24HourFormat
import de.jeanlucmakiola.agendula.ui.common.SyncPullBox
import de.jeanlucmakiola.agendula.ui.common.ignoringEdgeSwipes
import de.jeanlucmakiola.agendula.ui.common.priorityAccent
import de.jeanlucmakiola.agendula.ui.common.sideInsetsPadding
import de.jeanlucmakiola.agendula.ui.lists.ListEditorSheet
import de.jeanlucmakiola.agendula.ui.lists.listWriteFailureMessage
import de.jeanlucmakiola.agendula.ui.lists.ListWriteFailure
@@ -250,7 +251,7 @@ fun TaskListScreen(
}
},
) { inner ->
Box(modifier = Modifier.fillMaxSize()) {
Box(modifier = Modifier.fillMaxSize().sideInsetsPadding(inner)) {
SyncPullBox(
available = syncAvailable,
syncing = syncing,
@@ -260,7 +261,10 @@ fun TaskListScreen(
) {
when (val s = state) {
TaskListUiState.Loading -> Unit // brief; avoids a flash before first emission
TaskListUiState.Failure -> CenteredMessage(stringResource(R.string.task_list_failure), inner)
TaskListUiState.Failure -> CenteredMessage(
stringResource(R.string.task_list_failure),
PaddingValues(top = inner.calculateTopPadding(), bottom = inner.calculateBottomPadding()),
)
is TaskListUiState.Content -> TaskListBody(
s, filter, inner, onOpenTask, onRequestDelete, viewModel,
onClearCompleted = if (listId != null && list?.isReadOnly != true) ({ confirmClear = true }) else null,
+91
View File
@@ -763,4 +763,95 @@
<string name="widget_config_background">الخلفية</string>
<string name="widget_config_background_solid">سادة</string>
<string name="widget_config_theme">السمة</string>
<string name="app_name_tasks_alias">مهام</string>
<string name="list_where">أين</string>
<string name="settings_backup_subtitle">التصدير و الاستيراد</string>
<string name="error_reminder_without_date">اضبط تاريخ بدء أو استحقاق لاستخدام تذكير.</string>
<string name="reminder_at_start">في وقت البدء</string>
<string name="reminder_at_due_time">في وقت الاستحقاق</string>
<string name="reminder_on_start_date">عند موعد البدء</string>
<string name="reminder_on_due_date">عند موعد الاستحقاق</string>
<string name="reminder_at_time">%1$s عند %2$s</string>
<string name="reminder_anchor_start">من البدء</string>
<string name="reminder_anchor_due">من تاريخ الاستحقاق</string>
<string name="reminder_time">الوقت</string>
<string name="reminder_benefit_delivery_title">تنبيه عندما يكون الأمر مهمًا</string>
<string name="reminder_benefit_reversible_title">يمكنك تغييره في أي وقت</string>
<string name="settings_app_name_hint">اعرض Agendula كـ ”مهام“ في مشغّل التطبيقات الخاص بك. فقط الاسم في المشغّل يتغير؛ وقد ينتقل الرمز إلى مكان جديد. يُغلَق Agendula عندما تقوم بالتبديل، لذا أعِد فتحه من المشغّل.</string>
<string name="settings_allday_reminder_time_summary">العد التنازلي لمهام التي تستمر طوال اليوم عند %1$s</string>
<string name="settings_store_permission_denied_hint">مهام التطبيق الآخر تبقى غير قابلة للوصول حتى تسمح بالوصول. اضغط لفتح إعدادات التطبيق.</string>
<string name="settings_copy_counting">جارٍ حساب ما هناك لنسخه…</string>
<string name="settings_copy_confirm_empty">%1$s لا يحتوي على مهام لنسخها.</string>
<string name="settings_copy_nothing">لم يكن هناك شيء للنسخ</string>
<string name="export_hint">ملف .ics واحد لكل قائمة، قابل للقراءة بواسطة تطبيقات المهام والتقويم الأخرى. القوائم الموضوع عليها بعلامة صح تذهب إلى مجلد تختاره أنت، أو إلى ملف مضغوط (zip) واحد.</string>
<string name="export_no_lists">لا توجد قوائم للتصدير</string>
<string name="export_to_folder">الحفظ إلى مجلد</string>
<string name="export_to_zip">حفظ كملف مضغوط (zip)</string>
<plurals name="export_done">
<item quantity="zero">تم تصدير (%1$d) لا قوائم</item>
<item quantity="one">تم تصدير قائمة واحدة (%1$d)</item>
<item quantity="two">تم تصدير قائمتان (%1$d)</item>
<item quantity="few">تم تصدير %1$d قوائم</item>
<item quantity="many">تم تصدير %1$d قائمة</item>
<item quantity="other">تم تصدير %1$d قائمة</item>
</plurals>
<plurals name="reminder_minutes_before_start">
<item quantity="zero">(%1$d) لا دقائق قبل البدء</item>
<item quantity="one">%1$d دقيقة واحده قبل البدء</item>
<item quantity="two">%1$d دقيقتان قبل البدء</item>
<item quantity="few">%1$d دقائق قبل البدء</item>
<item quantity="many">%1$d دقيقة قبل البدء</item>
<item quantity="other">%1$d دقيقة قبل البدء</item>
</plurals>
<plurals name="reminder_hours_before_start">
<item quantity="zero">(%1$d) لا ساعات قبل البدء</item>
<item quantity="one">%1$d ساعة واحده قبل البدء</item>
<item quantity="two">%1$d ساعتان قبل البدء</item>
<item quantity="few">%1$d ساعات قبل البدء</item>
<item quantity="many">%1$d ساعة قبل البدء</item>
<item quantity="other">%1$d ساعة قبل البدء</item>
</plurals>
<plurals name="reminder_days_before_start">
<item quantity="zero">(%1$d) لا أيام قبل البدء</item>
<item quantity="one">%1$d يوم واحد قبل البدء</item>
<item quantity="two">%1$d يومان قبل البدء</item>
<item quantity="few">%1$d أيام قبل البدء</item>
<item quantity="many">%1$d يوم قبل البدء</item>
<item quantity="other">%1$d يوم قبل البدء</item>
</plurals>
<plurals name="reminder_weeks_before_start">
<item quantity="zero">(%1$d) لا أسابيع قبل البدء</item>
<item quantity="one">%1$d أسبوع واحد قبل البدء</item>
<item quantity="two">%1$d أسبوعان قبل البدء</item>
<item quantity="few">%1$d أسابيع قبل البدء</item>
<item quantity="many">%1$d أسبوع قبل البدء</item>
<item quantity="other">%1$d أسبوع قبل البدء</item>
</plurals>
<string name="settings_accounts_subtitle">مزامنة مهامك مع خادم CalDAV</string>
<string name="accounts_add">إضافة حسابًا</string>
<string name="accounts_sync_interval">المزامنة تلقائيًا</string>
<string name="accounts_sync_interval_manual">فقط عند تقوم بالمزامنة</string>
<string name="accounts_push_via">تصل التغييرات فورًا، عبر %1$s</string>
<string name="widget_unavailable">افتح Agendula لإنهاء الإعداد</string>
<string name="widget_today_all_done">انتهى كل شيء</string>
<string name="widget_config_title">إظهار في الأداة المصغرة</string>
<string name="widget_config_group_by_list">تجميع حسب القائمة</string>
<string name="widget_config_group_by_list_hint">إظهار مهام كل قائمة ضمن عنوانها الخاص</string>
<string name="widget_config_background_solid_hint">يملأ الأداة المصغّرة بلون سطح السمة</string>
<string name="widget_config_background_tinted_hint">أكثر نعومة، تعبئة لونية متناغمة</string>
<string name="widget_config_background_transparent">شفافة</string>
<string name="widget_config_background_transparent_hint">لا تعبئة — تبقى المهام قابلة للقراءة في حاوياتها الخاصة</string>
<string name="widget_config_row_color_neutral_hint">يستخدم كل صف نفس التعبئة اللونية المتناغمة</string>
<string name="widget_config_row_color_by_list">حسب القائمة</string>
<string name="widget_config_row_color_by_list_hint">كل صف متناغم باللون الخاص بقائمته</string>
<string name="widget_today_description">حلقة تقدم لمهام اليوم</string>
<string name="widget_up_next_description">مهمتك الوحيدة الأقرب لموعد الاستحقاق</string>
<string name="widget_lists_label">قوائم</string>
<string name="widget_lists_description">مربع اختصار لكل قائمة، مع عدد مرّات فتحه</string>
<string name="widget_week_label">أسبوع</string>
<string name="widget_week_description">شريط من سبعة أيام لعدد المهام</string>
<string name="widget_config_background_tinted">ملونة</string>
<string name="settings_theme_black">أسود</string>
<string name="settings_theme_black_summary">داكن مع خلفيات سوداء نقية، لشاشات AMOLED</string>
<string name="settings_app_name">اسم التطبيق</string>
</resources>
+14
View File
@@ -320,4 +320,18 @@
<string name="reminder_at_due">V čase úkolu</string>
<string name="reminder_on_the_day">V daný den</string>
<string name="settings_list_reminders_title">Upozornění pro jednotlivé seznamy</string>
<string name="shortcut_new_task">Nový úkol</string>
<string name="shortcut_today">Dnes</string>
<string name="qs_tile_new_task">Nový úkol</string>
<string name="sort_title">Seřadit podle</string>
<string name="view_options_title">Řazení a filtrování</string>
<string name="view_filter_tags">Filtrovat podle štítku</string>
<string name="view_filter_clear">Zrušit filtr</string>
<string name="sort_due">Termín splnění</string>
<string name="sort_title_alpha">Název</string>
<string name="sort_created">Nedávno přidané</string>
<string name="clear_completed_action">Zrušit</string>
<string name="undo">Zpět</string>
<string name="section_today">Dnes</string>
<string name="section_upcoming">Nadcházející</string>
</resources>
+7
View File
@@ -28,4 +28,11 @@
<string name="qs_tile_new_task">Новая задача</string>
<string name="lists_reorder">Переопределить список</string>
<string name="lists_reorder_done">Завершить переопределение</string>
<string name="app_name_tasks_alias">Задачи</string>
<string name="lists_reorder_handle">Перетащите, чтобы изменить порядок</string>
<string name="sort_title">Сортировать по</string>
<string name="view_options_title">Сортировать и фильтровать</string>
<string name="view_filter_tags">Фильтр по тегу</string>
<string name="view_filter_clear">Очистить фильтр</string>
<string name="sort_due">Срок выполнения</string>
</resources>