Skip to content

Commit 6833310

Browse files
pringelmannbackportbot[bot]
authored andcommitted
refactor: simplify dynamic height logic
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
1 parent d338633 commit 6833310

3 files changed

Lines changed: 14 additions & 31 deletions

File tree

core/src/components/AppMenu.vue

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,6 @@ export default defineComponent({
149149
// skidding sign isn't auto-mirrored, so we flip it here. Snapshot
150150
// at init: Nextcloud's language doesn't change at runtime.
151151
popoverSkidding: isRTL() ? 82 : -82,
152-
// Re-fires recomputeGridMaxHeight on layout changes.
153-
gridResizeObserver: null as ResizeObserver | null,
154152
}
155153
},
156154
@@ -180,13 +178,13 @@ export default defineComponent({
180178
},
181179
182180
watch: {
183-
// On open, land the roving stop on the active app rather than index 0.
181+
// On open, land the roving stop on the active app rather than index 0
182+
// and measure the grid as soon as it mounts (before the open
183+
// transition finishes, so the cap is set without a flash).
184184
opened(isOpen: boolean) {
185185
if (isOpen) {
186186
this.focusedIndex = this.activeGridIndex()
187-
this.$nextTick(() => this.attachGridObserver())
188-
} else {
189-
this.detachGridObserver()
187+
this.tryRecomputeGridMaxHeight(5)
190188
}
191189
},
192190
},
@@ -204,7 +202,6 @@ export default defineComponent({
204202
beforeUnmount() {
205203
unsubscribe('nextcloud:app-menu.refresh', this.setApps)
206204
;(this.$refs.popover as { $off: (e: string, fn: () => void) => void } | undefined)?.$off('after-hide', this.onPopoverAfterHide)
207-
this.detachGridObserver()
208205
},
209206
210207
methods: {
@@ -243,27 +240,19 @@ export default defineComponent({
243240
}
244241
},
245242
246-
// NcPopover renders the slot lazily; poll for the grid ref via rAF.
247-
attachGridObserver(retries = 30) {
243+
// Poll briefly for the grid ref (NcPopover renders the slot async)
244+
// then measure once. Bounded so a missing ref can never leak frames.
245+
tryRecomputeGridMaxHeight(retries: number) {
248246
if (!this.opened || retries <= 0) {
249247
return
250248
}
251-
const grid = this.$refs.grid as HTMLElement | undefined
252-
if (!grid) {
253-
requestAnimationFrame(() => this.attachGridObserver(retries - 1))
249+
if (!this.$refs.grid) {
250+
requestAnimationFrame(() => this.tryRecomputeGridMaxHeight(retries - 1))
254251
return
255252
}
256-
this.detachGridObserver()
257-
this.gridResizeObserver = new ResizeObserver(() => this.recomputeGridMaxHeight())
258-
this.gridResizeObserver.observe(grid)
259253
this.recomputeGridMaxHeight()
260254
},
261255
262-
detachGridObserver() {
263-
this.gridResizeObserver?.disconnect()
264-
this.gridResizeObserver = null
265-
},
266-
267256
// Cap = sum of first 6 row heights + baseline × 6, so the peek of
268257
// row 7 stays constant when wraps grow rows.
269258
recomputeGridMaxHeight() {
@@ -274,9 +263,7 @@ export default defineComponent({
274263
const VISIBLE_CELLS = 24 // 4 cols × 6 visible rows
275264
const cells = grid.children
276265
if (cells.length <= VISIBLE_CELLS) {
277-
if (grid.style.maxHeight !== '') {
278-
grid.style.maxHeight = ''
279-
}
266+
grid.style.maxHeight = ''
280267
return
281268
}
282269
const firstHidden = cells[VISIBLE_CELLS] as HTMLElement | undefined
@@ -287,11 +274,7 @@ export default defineComponent({
287274
const sumOfFirstRows = firstHidden.getBoundingClientRect().top
288275
- firstCell.getBoundingClientRect().top
289276
const baseline = parseFloat(getComputedStyle(grid).getPropertyValue('--default-grid-baseline')) || 4
290-
const cap = `${sumOfFirstRows + baseline * 6}px`
291-
// Skip identical writes — they re-fire the ResizeObserver.
292-
if (grid.style.maxHeight !== cap) {
293-
grid.style.maxHeight = cap
294-
}
277+
grid.style.maxHeight = `${sumOfFirstRows + baseline * 6}px`
295278
},
296279
297280
// Index of the active app within `gridItems`, or 0 if none is active.

dist/core-main.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/core-main.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)