Skip to content

feat: Add Paging3 - #146

Open
sirambd wants to merge 19 commits into
mainfrom
paging3
Open

sirambd wants to merge 19 commits into
mainfrom
paging3

Conversation

@sirambd

@sirambd sirambd commented Aug 21, 2026

Copy link
Copy Markdown
Member

No description provided.

sirambd added 17 commits July 27, 2026 15:56
Declare the Paging 3 version and the paging-common / paging-compose libraries in the version catalog, and wire them into the app and the CalendarComponents Planning module, which will consume LazyPagingItems.
Introduce PlanningRow, a flat paged row type (WeekHeader / Event) with a planningRows(week, days) builder that flattens a week into rows. The Planning composable now renders a LazyColumn driven by LazyPagingItems<PlanningRow> (one lazy item per event) instead of a week/day map, keeping per-event virtualization and the sticky day indicator. Each event row carries its day's section keys so the sticky indicator keeps working. Preview data now provides List<PlanningRow>.
Replace PlanningViewModel.planningUiState (which eagerly observed a fixed
+/-250 day range and grouped it into a full EventsByWeekAndDay map) with a
Pager exposing Flow<PagingData<PlanningRow>>, rebuilt from a dynamic initialDay
flow so a jump recenters the window.

PlanningPagingSource pages one ISO week per key and loads a 3-week window
(target week plus its neighbours) on refresh, so a jump can top-align in one
shot and the previous/next weeks are preloaded. It self-invalidates on DB
changes to stay live. groupWeekDays fills every day of a week (empty-day
placeholders kept). Removes the now-unused PlanningUiState and
EventsByWeekAndDayPreviewParameter.
…entering

PlanningScreen collects the pager as LazyPagingItems<PlanningRow>, shows a loader
until the first page and stays mounted afterwards, so a far jump's refresh doesn't
tear down the scroll handling.

- CenterOnVisibleDate positions the planning on the visible date once per screen
  lifetime.
- ProcessJumpRequests turns a jump request into a recenter of the pager on the
  target date (jumpTo now returns whether the center actually changed), waits for
  the rebuilt refresh, then scrolls to the target row.
- ReportVisibleDate reports the first visible day back as the user scrolls, to
  keep the calendar header in sync.
Update the top-level AGENTS.md (Planning component now driven by
LazyPagingItems<PlanningRow>, PlanningRow / planningRows, the paging-compose
dependency) and app/AGENTS.md (PlanningPagingSource in the planning package).
The initial today-centering and jumps used a one-shot scrollToItem that didn't survive Paging's follow-up loads: prefetch prepends and, above all, the initial events sync refreshed the pager (replacing placeholder rows whose keys vanish), so the list slipped onto a date of the previous week.

Replace the "center once" (CenterOnVisibleDate) + "process jumps" (ProcessJumpRequests) pair with a single AlignPlanningToDate coordinator that pins the list to a desired target date and re-scrolls on every content shift until the user drags (which releases the pin); an explicit jump re-pins on its date. The pager window stays centered so re-scrolling converges (no runaway scroll to the start of time).
# Conflicts:
#	AGENTS.md
#	CalendarComponents/Calendar/src/main/kotlin/com/infomaniak/calendar/components/calendar/component/ExpandableCalendar.kt
#	app/AGENTS.md
#	app/src/main/java/com/infomaniak/calendar/ui/previewparameter/EventsByWeekAndDayPreviewParameter.kt
#	app/src/main/java/com/infomaniak/calendar/ui/screen/planning/PlanningScreen.kt
#	app/src/main/java/com/infomaniak/calendar/ui/screen/planning/PlanningViewModel.kt
#	app/src/main/java/com/infomaniak/calendar/ui/screen/planning/ProcessJumpRequests.kt
#	gradle/libs.versions.toml
# Conflicts:
#	AGENTS.md
#	app/src/main/java/com/infomaniak/calendar/ui/previewparameter/EventsByWeekAndDayPreviewParameter.kt
#	gradle/libs.versions.toml

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates the planning timeline to Paging 3 for bounded, bidirectional week loading.

Changes:

  • Adds flat paged planning rows and week-based data loading.
  • Reworks jump alignment, grouping, previews, and loading state.
  • Adds Paging dependencies and updates architecture documentation.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
gradle/libs.versions.toml Adds Paging artifacts.
CalendarComponents/Planning/.../preview/PreviewData.kt Provides paged-row preview data.
CalendarComponents/Planning/.../PlanningRow.kt Defines flat planning rows.
CalendarComponents/Planning/.../Planning.kt Renders LazyPagingItems.
CalendarComponents/Planning/build.gradle.kts Adds Paging Compose.
app/.../planning/ProcessJumpRequests.kt Removes legacy jump handling.
app/.../planning/PlanningViewModel.kt Creates and caches the pager.
app/.../planning/PlanningUiState.kt Removes legacy UI state.
app/.../planning/PlanningScreen.kt Integrates paged rows.
app/.../planning/PlanningPagingSource.kt Loads and observes weekly pages.
app/.../planning/PlanningEventGroupingExt.kt Groups one week at a time.
app/.../planning/AlignPlanningToDate.kt Implements paged jump alignment.
app/.../previewparameter/EventsByWeekAndDayPreviewParameter.kt Removes obsolete preview data.
app/build.gradle.kts Adds app Paging dependencies.
app/AGENTS.md Documents the paging source.
AGENTS.md Updates component architecture documentation.
Suppressed comments (2)

app/src/main/java/com/infomaniak/calendar/ui/screen/planning/AlignPlanningToDate.kt:135

  • todo (non-blocking): Remove the consecutive trailing blank lines.

app/AGENTS.md:126 permits at most one consecutive blank line.
AGENTS.md:109

  • issue (non-blocking): Do not document implementation dependencies as api exports.

CalendarComponents/Planning/build.gradle.kts:57-58 declares Event and Resources with implementation; only Foundation is currently exposed with api. Update this row and the dependency graph to match the build, or change the dependency declarations if re-exporting is intentional.

| `:CalendarComponents:Planning`    | `com.infomaniak.calendar.components.planning`    | `Planning` Composable — a `LazyColumn` driven by `LazyPagingItems<PlanningRow>` (Paging 3), with ISO week headers and one lazy item per event. `PlanningRow` is the flat paged row type (`WeekHeader` / `Event`); `planningRows(week, days)` flattens a week into rows. Also provides the `stickyDayIndicator` `Modifier` extension. Re-exports Event, Foundation, and Resources via `api`. Week header design is a **placeholder**. |

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +108 to +110
fun jumpTo(date: LocalDate): Boolean {
val changed = initialDay.value != date
initialDay.value = date
Comment on lines +61 to +63
// Survives config changes: the initial centering must run only once per process, so a recomposition
// or rotation never re-centers over the user's (or restored) scroll.
var hasCentered by rememberSaveable { mutableStateOf(false) }
Comment on lines +108 to +112
itemKey = row.key,
sectionItemKeys = row.daySectionKeys,
goToEventCreation = goToEventCreation,
modifier = Modifier
.ensureSectionMinHeight(sectionSizing, sectionItemKeys, itemKey)
.padding(bottom = bottomPadding),
.ensureSectionMinHeight(sectionSizing, row.daySectionKeys, row.key)
implementation(libs.compose.material3)
debugImplementation(core.compose.ui.tooling)

implementation(libs.paging.compose)
Comment thread app/build.gradle.kts
Comment on lines +167 to +168
implementation(libs.paging)
implementation(libs.paging.compose)
Comment thread AGENTS.md
| `:CalendarComponents:Resources` | `com.infomaniak.calendar.components.resources` | String-only module: `res/values/strings.xml` (+ translations). No Kotlin code, no Compose. Centralises all CalendarComponents string resources. |
| `:CalendarComponents:Event` | `com.infomaniak.calendar.components.event` | `EventItem` Composable — renders a single event row. Re-exports Foundation via `api`. |
| `:CalendarComponents:Planning` | `com.infomaniak.calendar.components.planning` | `Planning` Composable — a `LazyColumn` with ISO week headers and per-day event lists. Also provides the `stickyWithinItem` `Modifier` extension. Re-exports Event, Foundation, and Resources via `api`. Week header design is a **placeholder**. |
| `:CalendarComponents:Event` | `com.infomaniak.calendar.components.event` | `EventItem` Composable — renders a single event row. Re-exports Foundation via `api`. **Placeholder UI** — visual design is not final. |
Comment on lines +127 to +128
} else {
LoadingPlanning(modifier = Modifier.padding(contentPadding))
Comment on lines +113 to +117
coroutineScope.launch {
runCatching {
slices.collectIndexed { index, value ->
if (index == 0) firstSlices.complete(value) else invalidate()
}
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants