Skip to content

feat(ui): 共通の非同期状態UIを整備する (#579) - #599

Merged
hmjn023 merged 2 commits into
developfrom
fix/issue-579-shared-async-state-ui
Jul 13, 2026
Merged

feat(ui): 共通の非同期状態UIを整備する (#579)#599
hmjn023 merged 2 commits into
developfrom
fix/issue-579-shared-async-state-ui

Conversation

@hmjn023

@hmjn023 hmjn023 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

概要

Issue #579 の共通Skeleton・Empty・Error・Offline・Retry UIを実装し、Server/Tauriの主要6画面へ適用しました。初回loadingだけをSkeletonにし、background fetchでは既存コンテンツと入力・focusを維持します。

変更内容

  • card / list / media grid / detail / manager / config用の共有Skeletonを追加
  • Empty / Error / Offline / Retry / background・cached-offline statusを共有化
  • aria-busy、status/alert、reduced motion、読み上げ通知を整理
  • Sources、Search、Source Media、Media Detail、Manager、Configへ状態UIを適用
  • Server/Tauri Config wrapperを共通化し、Tauriのoffline/error retry経路を修正
  • Web初期表示性能とSelective SSR・Query hydrationを再設計する #594 のFull data SSR / static fallback / ClientOnly境界を維持
  • background DOM保持、retry、empty、offline、network failure、responsive回帰のE2Eを拡充

検証

  • Biome: 変更28ファイル成功
  • 全workspace typecheck: 成功
  • UI unit: 43 tests
  • Server unit: 162 tests
  • Server integration: 67 tests
  • dev loading-recovery E2E: 11 tests
  • fresh production build +主要E2E: 23 tests
  • Tauri Web build: 成功

補足

rootの vp check / vp test は既存のVite+ root解決問題で解析開始前に失敗するため、package別check/testとfresh production buildで検証しています。詳細はIssueのReview Checklistに記録しました。

Closes #579

Summary by CodeRabbit

  • 新機能
    • 設定・検索・メディア・管理画面に、統一された読み込み中/空状態/エラー/オフライン表示を追加しました。
    • 画面ごとのスケルトン表示と、データ準備中の案内を改善しました。
    • エラーや通信停止時に、画面上の「再試行」操作で復旧できるようになりました。
  • アクセシビリティ
    • スクリーンリーダー向けの状態通知を改善し、アニメーション抑制設定にも対応しました。
  • 品質改善
    • 読み込み、再試行、空状態、更新中の表示に関する自動テストを強化しました。

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@hmjn023, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: aef5800b-f6ca-4972-a2ed-dc8228db3389

📥 Commits

Reviewing files that changed from the base of the PR and between 81e3a8f and 9e54a60.

📒 Files selected for processing (3)
  • packages/ui/src/async-state.tsx
  • packages/ui/src/screens/search-screen.tsx
  • packages/ui/src/screens/source-media-screen.tsx
📝 Walkthrough

Walkthrough

変更

共有のスケルトン、Empty/Error/Offline状態、再試行UIを追加し、ServerとTauriの設定・検索・ソース・メディア詳細画面へ適用しました。ルートのpending表示、非同期クエリ状態、アクセシビリティ属性、ローディング回復のE2E検証も更新されています。

共有非同期状態UI

Layer / File(s) Summary
共有スケルトンと状態コンポーネント
packages/ui/src/async-state.tsx, packages/ui/src/skeleton.tsx, packages/ui/src/screen-skeleton.tsx, packages/ui/src/router-status.tsx
画面別スケルトン、Empty/Error/Offline状態、再試行ボタン、QueryStatus、ルートpending/error表示を追加し、aria-busyroleprefers-reduced-motion に対応しました。
画面状態と再試行処理の統合
packages/ui/src/screens/*, packages/ui/src/source-media-grid.tsx, packages/ui/src/hooks/*
各画面の状態分岐を共通コンポーネントへ集約し、検索・管理・フィルターの関連クエリを並列再取得する処理を追加しました。
ServerとTauriのルート適用
apps/server/src/routes/*, apps/tauri/src/routes/*, apps/tauri/src/main.tsx, packages/ui/src/source-media-page.tsx
設定、検索、ソース、メディア詳細ルートのpending表示、データ取得、再試行、設定更新後のクエリ無効化を共通UIへ接続しました。
ローディングと回復フローの検証
apps/server/src/tests/e2e/loading-recovery.spec.ts, packages/ui/src/query-state.test.ts
スケルトン表示、背景更新時の既存結果保持、キーボード操作による再試行、空状態、QueryUiStateの判定を検証するテストを更新・追加しました。

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

Possibly related PRs

  • hmjn023/solid-imager#590: router-status.tsx のpending/error UIと共有ルート状態表示が直接関連します。
  • hmjn023/solid-imager#593: 同じ検索・ソース・メディア詳細ルートのSSR pending表示とデータ取得変更に関連します。
  • hmjn023/solid-imager#598: RouteDataPendingScreen の導入と設定・検索・ソースルートへの適用が直接関連します。
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 主要変更である共通の非同期状態UI整備を簡潔に示しており、変更内容と一致しています。
Linked Issues check ✅ Passed 共通Skeleton/Empty/Error/Offline/Retryの追加と主要6画面への適用、reduced motionや再試行対応まで含み、要件を満たしています。
Out of Scope Changes check ✅ Passed 状態UI共通化、各画面への適用、関連テスト追加に収まっており、明確な逸脱は見当たりません。
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-579-shared-async-state-ui

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/ui/src/screens/search-screen.tsx (1)

107-117: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

フィルター取得失敗バナーのマークアップが2画面で重複しています。 どちらも「警告枠+文言+RetryButton」という同一構造で、共通コンポーネント(例: async-state.tsxへのFilterErrorBanner追加)に切り出せます。

  • packages/ui/src/screens/search-screen.tsx#L107-L117: このブロックを共通のFilterErrorBannerコンポーネントに置き換え、labelonRetryのみを渡す形にする。
  • packages/ui/src/screens/source-media-screen.tsx#L127-L136: 同様に共通のFilterErrorBannerコンポーネントへ差し替え、onRetry={props.onRetryFilters}を渡す形にする。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/screens/search-screen.tsx` around lines 107 - 117,
重複しているフィルター取得失敗バナーを共通化する。`packages/ui/src/screens/search-screen.tsx#L107-L117`と`packages/ui/src/screens/source-media-screen.tsx#L127-L136`の警告マークアップを`async-state.tsx`の`FilterErrorBanner`コンポーネントへ置き換え、各画面から適切な`label`と再試行コールバック(`page().retryFilters`または`props.onRetryFilters`)だけを渡す。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/ui/src/screens/search-screen.tsx`:
- Around line 107-117:
重複しているフィルター取得失敗バナーを共通化する。`packages/ui/src/screens/search-screen.tsx#L107-L117`と`packages/ui/src/screens/source-media-screen.tsx#L127-L136`の警告マークアップを`async-state.tsx`の`FilterErrorBanner`コンポーネントへ置き換え、各画面から適切な`label`と再試行コールバック(`page().retryFilters`または`props.onRetryFilters`)だけを渡す。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 75910c3d-dd98-403b-a1c0-eab8a2438241

📥 Commits

Reviewing files that changed from the base of the PR and between 65787e7 and 81e3a8f.

📒 Files selected for processing (28)
  • apps/server/src/components/api-activity-indicator.tsx
  • apps/server/src/routes/config.tsx
  • apps/server/src/routes/manager.tsx
  • apps/server/src/routes/search.tsx
  • apps/server/src/routes/sources/$mediaSourceId/$mediaId/index.tsx
  • apps/server/src/routes/sources/$mediaSourceId/components/source-media-page.tsx
  • apps/server/src/routes/sources/$mediaSourceId/index.tsx
  • apps/server/src/routes/sources/index.tsx
  • apps/server/src/tests/e2e/loading-recovery.spec.ts
  • apps/tauri/src/main.tsx
  • apps/tauri/src/routes/config.tsx
  • apps/tauri/src/routes/sources/$mediaSourceId/$mediaId/index.tsx
  • apps/tauri/src/routes/sources/index.tsx
  • packages/ui/src/async-state.tsx
  • packages/ui/src/hooks/use-manager-page.ts
  • packages/ui/src/hooks/use-search-page.ts
  • packages/ui/src/query-state.test.ts
  • packages/ui/src/router-status.tsx
  • packages/ui/src/screen-skeleton.tsx
  • packages/ui/src/screens/config-state-screen.tsx
  • packages/ui/src/screens/manager-screen.tsx
  • packages/ui/src/screens/media-detail-screen.tsx
  • packages/ui/src/screens/search-screen.tsx
  • packages/ui/src/screens/source-media-screen.tsx
  • packages/ui/src/screens/sources-screen.tsx
  • packages/ui/src/skeleton.tsx
  • packages/ui/src/source-media-grid.tsx
  • packages/ui/src/source-media-page.tsx

@hmjn023

hmjn023 commented Jul 13, 2026

Copy link
Copy Markdown
Owner Author

CodeRabbit のnitpickに対応しました。Search と Source Media のフィルター取得失敗バナーを packages/ui/src/async-state.tsx の FilterErrorBanner へ共通化し、文言と再試行処理だけを各画面から渡す形にしています。追コミット: 9e54a60。検証: Biome、全workspace typecheck、UI unit 43件、dev loading-recovery E2E 11件。

@hmjn023
hmjn023 merged commit 62c48ac into develop Jul 13, 2026
1 check passed
@hmjn023
hmjn023 deleted the fix/issue-579-shared-async-state-ui branch July 13, 2026 15:01
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.

1 participant