Conversation
… metric loading. Added settings panel for auto-load preference and refactored loading logic in StatsDrawer for better performance and user experience.
WalkthroughThis pull request refactors StatsDrawer to support asynchronous, on-demand metric loading with per-metric loading states and user-configurable auto-load preferences. The component API now accepts an extensionAPI parameter. Supporting type definitions (ExtensionAPI, StatMetricKey, TagName, Stats, LoadingState) and utility functions (formatInt, getLoadingKeyForTag, getAutoLoadPreference, runAfterNextPaint) were introduced. A new settings panel tab titled "Stats" with an auto-load toggle was added to the extension configuration. Command palette integration was updated to pass extensionAPI context to toggleStatsDrawer. Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/StatsDrawer.tsx`:
- Around line 543-552: The current onClick returns early when autoLoad is false
and stats.tagCounts?.[tag] is null, causing the first click to only call loadTag
and not navigate; change the onClick handler (make it async) to call loadTag
when needed and then proceed to call
window.roamAlphaAPI.ui.mainWindow.openPage({ page: { title: tag } }) after
loadTag completes (await loadTag if it returns a Promise) so a single click both
loads data and navigates; ensure you remove the early return path and keep the
behavior conditional on autoLoad and stats.tagCounts?.[tag] while preserving
error handling around loadTag.
- Around line 205-226: The loadMetric function uses setTimeout(() =>
runQuery(...), 0) while loadTag uses runAfterNextPaint (which uses
requestAnimationFrame), causing inconsistent scheduling; replace the setTimeout
usage inside loadMetric with runAfterNextPaint to match loadTag (i.e., call
runAfterNextPaint(() => runQuery(STAT_QUERIES[statKey])...)) so both functions
defer work the same way and preserve the existing loading state updates in
loadMetric, loadTag, and their use of setLoadingState, setStats, and loadingRef.
- Around line 260-263: The forEach callbacks in loadAllStats are using concise
arrow bodies which implicitly return the result of loadMetric/loadTag and
violate the Biome rule useIterableCallbackReturn; update the callbacks over
STAT_METRIC_KEYS and TAGS inside loadAllStats to use block bodies (e.g., statKey
=> { loadMetric({ statKey }); } and tag => { loadTag({ tag }); }) so they return
undefined explicitly and satisfy the linter while keeping loadAllStats,
STAT_METRIC_KEYS, TAGS, loadMetric and loadTag unchanged.
In `@src/index.ts`:
- Around line 10-14: getAutoLoadSettingValue duplicates getAutoLoadPreference by
both calling extensionAPI.settings.get(AUTO_LOAD_STATS_SETTING); remove the
duplicate by deleting getAutoLoadSettingValue, import and use
getAutoLoadPreference from ~/utils/stats (or inline the single settings.get(...)
call where used), and update all callers in this file to reference
getAutoLoadPreference (ensuring types match ExtensionAPI where needed).
- Around line 26-40: The settings default is being set after the panel is
created which can cause the switch UI in extensionAPI.settings.panel.create to
render with the wrong initial state; call getAutoLoadSettingValue and, if it is
not a boolean, call await extensionAPI.settings.set(AUTO_LOAD_STATS_SETTING,
true) before invoking extensionAPI.settings.panel.create so the
AUTO_LOAD_STATS_SETTING has a definitive value when the panel (and its switch)
is rendered.
In `@src/utils/stats.ts`:
- Around line 20-31: The function runAfterNextPaint currently calls
requestAnimationFrame directly which runs before paint; change runAfterNextPaint
to schedule the callback after the next paint by using requestAnimationFrame to
schedule a setTimeout(0) (or alternatively a MessageChannel.postMessage) inside
the rAF callback so the provided callback executes after the browser has
painted; update the implementation in runAfterNextPaint to use this nested
scheduling pattern and keep the existing fallback to setTimeout if
requestAnimationFrame is unavailable.
Summary by CodeRabbit
Release Notes