Skip to content

feat(#248): 壁紙ローディングインジケータを回転する金のジオデシック球体に刷新#286

Merged
GeneralD merged 3 commits into
mainfrom
feat/248/wallpaper-loading-indicator
Jun 14, 2026
Merged

feat(#248): 壁紙ローディングインジケータを回転する金のジオデシック球体に刷新#286
GeneralD merged 3 commits into
mainfrom
feat/248/wallpaper-loading-indicator

Conversation

@GeneralD

@GeneralD GeneralD commented Jun 14, 2026

Copy link
Copy Markdown
Owner

type breaking scope platform diff files tests review

Closes #248

壁紙ローディングインジケータを、ゆっくり回転する金のジオデシック球体へ刷新しました。Goldberg 多面体(正五角形 12 + 正六角形 30 — 「サッカーボールに面をちょっと足した」形、freq-2 アイコスフィアの双対)を細い金のワイヤーフレームで描き、奥行きに応じて線幅と明度を変化させています。

採用デザイン

実機(UTM macOS ゲスト)で、実際の壁紙 DL 中に表示させたところ:

採用デザイン — 金のジオデシック球体 + Downloading wallpaper キャプション(実機 UTM)

  • 金のアイデンティティ: 線の金は歌詞ハイライトのグラデーション(#B8942D → #EDCF73 → #FFEB99 → #CCA64D → #A68038)と同系。Lyra の世界観に揃えています。
  • 囲い無しでも明暗どちらの壁紙でも視認可能: 各ストラットを「暗いハロー → 金の線」の二度描きにすることで、背景に依存しないコントラストを確保(フロスト円盤を廃止)。
  • Downloading wallpaper キャプション: 球体の下に金の細字・トラッキング広め・暗い影で、何を待っているかを伝えつつミニマルさは維持。

動きはこちら(回転ループ):

回転ループ

実機(UTM)動作確認

UTM macOS ゲストでのフルスクリーンショット

ヘッダーの曲情報("The Quiet Call" / David Arkenstone)と球体 + キャプションが、デスクトップ壁紙の上にデスクトップレベルのオーバーレイとして描画されているのが確認できます。トリクルサーバで壁紙 DL を永続的に「進行中」に保ち、インジケータを画面に留めて撮影しています(通常は DL 中のみ表示)。

UTM macOS ゲストのフルスクリーンショット

没になった候補たち(慰霊)

採用に至るまでの試行錯誤の記録です。

散っていったデザイン案を見る

元祖案 — Sonar rings(最初の没案)

金のソナーリングが核から広がるデザイン。「もっとかっこいいのがいい」で却下。

元祖案 — Sonar rings

初期4案 — A/B/C/D

A: Orbit dots / B: Equalizer / C: Conic ring / D: Mesh sphere。D(メッシュ球体) が選ばれ、A・B・C は散りました。

初期4案 A/B/C/D

球体の試行錯誤

D を磨く過程。緯度経度メッシュ → Goldberg(太線)→ 採用(細線)。

緯度経度メッシュ(「四角をつなぐメッシュじゃない方がいい」で却下):

緯度経度メッシュ球体(没)

Goldberg だが線が太い版(「軸を細く」で却下):

Goldberg 太線版(没)

技術メモ

テスト

  • 新規 GeodesicGeometryTests: 双対エッジがちょうど 120 本、全端点が単位球面上、退化ストラット無し、を検証。
  • swift test942 tests green。make format 済み。

GeneralD added 3 commits June 14, 2026 23:13
プレーンな Progress(.circular) を、Lyra の ripple と歌詞ハイライトの
ゴールドグラデーションを踏襲した「ソナーリング」インジケータに置き換え。

- Canvas + TimelineView(.animation) で GPU 駆動描画(RippleView と同方式)
- 同心リングが core から rim へ拡散しながらフェード(明滅は sin で対称)
- ダークハロー + ゴールドグラデの二重ストローク、frosted disc 背景 +
  影で、明るい壁紙でも暗い壁紙でも視認可能
- #252 の条件付きツリー除去(showLoadingIndicator==false で完全に消す)を維持。
  accessibilityIdentifier / allowsHitTesting(false) も維持
- 中央配置で top-leading の歌詞領域を侵さない
- 出現/消滅は scale+opacity でフェード
- 明暗 2 背景の #Preview を追加
Replace the gold sonar rings with a slowly rotating gold geodesic sphere — a
Goldberg polyhedron (12 pentagons + 30 hexagons, "a soccer ball with a few
extra faces"), the dual of a freq-2 icosphere. The thin gold wireframe is
depth-cued (near struts brighter/thicker, far ones fainter/thinner) and each
strut carries a soft dark halo so it reads over both bright and dark wallpapers
WITHOUT any backing disc.

A subtle "Downloading wallpaper" caption sits below the sphere — thin,
letter-spaced gold with a dark shadow, telling the user what the wait is for
without pulling focus from the wireframe.

The wireframe geometry is rotation-independent, so it is built once
(GeodesicGeometry.edges) and only the per-frame projection changes (#252
spirit). Conditional inclusion (not .opacity(0)) is preserved so no idle
TimelineView burns GPU when not loading.

GeodesicGeometry / Vertex3D are exposed as internal (not private) so the pure
geometry is unit-tested via @testable import Views: exactly 120 dual edges,
every endpoint on the unit sphere, no degenerate struts.
Copilot AI review requested due to automatic review settings June 14, 2026 15:45
@GeneralD GeneralD self-assigned this Jun 14, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Replaces the plain ProgressView wallpaper loading spinner in WallpaperLoadingOverlay with a custom animated wireframe geodesic sphere (GeodesicLoadingIndicator) rendered via TimelineView and Canvas. New internal geometry types (Vertex3D, GeodesicGeometry) build the Goldberg-polyhedron edge set, validated by a new GeodesicGeometryTests suite. The version is bumped to 2.14.0.

Changes

Geodesic Loading Indicator

Layer / File(s) Summary
Geometry types, rendering constants, and tests
Sources/Views/Overlay/OverlayContentView.swift, Tests/ViewsTests/GeodesicGeometryTests.swift
Vertex3D and GeodesicGeometry produce undirected wireframe edges by subdividing an icosahedron dual. GeodesicMetrics and GeodesicGold define sizing, tilt, spin rate, line widths, and near/far gold colors. GeodesicGeometryTests asserts exactly 120 edges, all endpoints on the unit sphere, and no degenerate edges.
GeodesicLoadingIndicator Canvas renderer
Sources/Views/Overlay/OverlayContentView.swift
GeodesicLoadingIndicator uses TimelineView(.animation) and Canvas; each tick rotates the polyhedron, projects Vertex3D coordinates to 2D, depth-sorts edges, and draws halo + depth-blended gold strokes via drawEdge. import Foundation is added to support the math.
LoadingIndicatorContent, LoadingCaption, and WallpaperLoadingOverlay wiring
Sources/Views/Overlay/OverlayContentView.swift
LoadingIndicatorContent stacks GeodesicLoadingIndicator with a LoadingCaption ("Downloading wallpaper") using gold styling and shadow. WallpaperLoadingOverlay now conditionally inserts LoadingIndicatorContent in a ZStack with a scale+opacity transition driven by presenter.showLoadingIndicator. The #DEBUG preview is updated to show the indicator over both bright and dark gradient backgrounds.

Version Bump

Layer / File(s) Summary
version.txt bump to 2.14.0
Sources/VersionHandler/Resources/version.txt
Single-line version string updated from 2.13.20 to 2.14.0.

Sequence Diagram(s)

sequenceDiagram
  participant WallpaperPresenter
  participant WallpaperLoadingOverlay
  participant LoadingIndicatorContent
  participant GeodesicLoadingIndicator
  participant GeodesicGeometry
  participant Canvas

  WallpaperPresenter-->>WallpaperLoadingOverlay: showLoadingIndicator = true
  WallpaperLoadingOverlay->>LoadingIndicatorContent: insert into ZStack (scale+opacity transition)
  LoadingIndicatorContent->>GeodesicLoadingIndicator: render
  GeodesicLoadingIndicator->>GeodesicGeometry: buildEdges()
  GeodesicGeometry-->>GeodesicLoadingIndicator: [(Vertex3D, Vertex3D)] × 120
  loop TimelineView tick
    GeodesicLoadingIndicator->>GeodesicLoadingIndicator: rotate + project vertices
    GeodesicLoadingIndicator->>Canvas: drawEdge (depth-sorted, GeodesicGold halo+stroke)
  end
  WallpaperPresenter-->>WallpaperLoadingOverlay: showLoadingIndicator = false
  WallpaperLoadingOverlay->>LoadingIndicatorContent: remove from ZStack (fade+scale out)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • GeneralD/lyra#246: Introduced WallpaperPresenter.showLoadingIndicator and the original ProgressView-based spinner inside WallpaperLoadingOverlay that this PR directly replaces.
  • GeneralD/lyra#253: Also modifies WallpaperLoadingOverlay in OverlayContentView.swift to change how presenter.showLoadingIndicator controls the loading indicator's visibility.
  • GeneralD/lyra#254: Modifies the same WallpaperLoadingOverlay conditional insertion pattern in OverlayContentView.swift that this PR builds on.

Poem

🐇 A sphere of gold begins to spin,
Wireframe edges, thin and bright,
No more spinner, dull and plain —
A geodesic takes its reign!
Hop hop, the wallpaper downloads right. ✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately describes the main change: replacing wallpaper loading indicator with rotating gold geodesic sphere design.
Linked Issues check ✅ Passed All requirements from issue #248 are met: custom loading indicator with geodesic sphere design (not plain ProgressView), visible on bright and dark wallpapers (depth-cueing and dark halos), non-interfering with lyrics area, clear animation (rotating wireframe), and debounce/fade behavior preserved.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #248: OverlayContentView updated with new LoadingIndicatorContent, GeodesicGeometry/Vertex3D types added for wireframe construction, and comprehensive tests added. Version bump (2.13.20→2.14.0) is appropriate for feature addition.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/248/wallpaper-loading-indicator

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 and usage tips.

@codecov

codecov Bot commented Jun 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@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)
Sources/Views/Overlay/OverlayContentView.swift (1)

171-268: ⚡ Quick win

Extract geometry-generation feature logic from OverlayContentView.swift.

GeodesicGeometry/Vertex3D and related construction logic are substantial feature logic in a *View.swift file. Please move them to dedicated non-view source files (keeping GeodesicLoadingIndicator as the view layer) so the view file stays composition-focused.

As per coding guidelines, **/*View.swift: “Views do not own business logic... do not add feature logic to SwiftUI views.”

🤖 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 `@Sources/Views/Overlay/OverlayContentView.swift` around lines 171 - 268, Move
the geometric construction logic out of the view file to maintain separation of
concerns. Extract GeodesicGeometry, Vertex3D, GeodesicMetrics, and GeodesicGold
to a dedicated non-view source file (e.g., GeodesicGeometry.swift), keeping only
the GeodesicLoadingIndicator view component and any view-specific code in
OverlayContentView.swift. Update imports in OverlayContentView.swift to
reference the moved types from their new location.

Source: Coding guidelines

🤖 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 `@Sources/Views/Overlay/OverlayContentView.swift`:
- Around line 171-268: Move the geometric construction logic out of the view
file to maintain separation of concerns. Extract GeodesicGeometry, Vertex3D,
GeodesicMetrics, and GeodesicGold to a dedicated non-view source file (e.g.,
GeodesicGeometry.swift), keeping only the GeodesicLoadingIndicator view
component and any view-specific code in OverlayContentView.swift. Update imports
in OverlayContentView.swift to reference the moved types from their new
location.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 98ef545f-1ba9-4905-ac67-b99739da2153

📥 Commits

Reviewing files that changed from the base of the PR and between c7a0d04 and 228ddac.

📒 Files selected for processing (3)
  • Sources/VersionHandler/Resources/version.txt
  • Sources/Views/Overlay/OverlayContentView.swift
  • Tests/ViewsTests/GeodesicGeometryTests.swift

@GeneralD GeneralD merged commit ea31624 into main Jun 14, 2026
4 checks passed
@GeneralD GeneralD deleted the feat/248/wallpaper-loading-indicator branch June 14, 2026 15:51
@GeneralD

Copy link
Copy Markdown
Owner Author

action

CodeRabbit の nitpick(OverlayContentView.swift 171-268 — geometry-generation feature logic の抽出)に後続 PR #287対応しました。

  • Vertex3D + GeodesicGeometry を専用ファイル GeodesicGeometry.swift移動(70604a54f9)
  • .coderabbit.yaml**/*View.swift ガイドライン("Views do not own business logic")に準拠
  • 描画専用の GeodesicMetrics/GeodesicGoldprivate のまま View 側に残置(access control を広げない)
  • GeodesicGeometryinternal 維持GeodesicGeometryTests が引き続き到達可能。942 tests 全合格

GeneralD added a commit that referenced this pull request Jun 14, 2026
#287)

![type](https://img.shields.io/badge/type-refactor-blue)
![breaking](https://img.shields.io/badge/breaking-no-green)
![scope](https://img.shields.io/badge/scope-ui-blue)
![diff](https://img.shields.io/badge/diff-+82%20--81-yellow)
![files](https://img.shields.io/badge/files-3%20files-green)
![tests](https://img.shields.io/badge/tests-passing-green)
![review](https://img.shields.io/badge/review-quick%20look-green)

## 概要

`#286`(#248)
で導入したジオデシック球体ローディングインジケータの**幾何生成ロジック**を、`OverlayContentView.swift`(`*View.swift`)から専用ファイル
`GeodesicGeometry.swift` へ抽出する。

CodeRabbit が `#286` で残した nitpick への後続対応:

> **Extract geometry-generation feature logic from
`OverlayContentView.swift`.**
> `GeodesicGeometry`/`Vertex3D` and related construction logic are
substantial feature logic in a `*View.swift` file.

リポジトリの `.coderabbit.yaml` ガイドライン(`**/*View.swift`: "Views do not own
business logic")に沿い、View ファイルを SwiftUI View 型のみに保つ。

## 変更点

| 種別 | 内容 |
|---|---|
| 移動 | `Vertex3D`(unit-sphere 頂点)+ `GeodesicGeometry`(Goldberg
多面体のエッジ生成)→ `GeodesicGeometry.swift` |
| 残置 | `GeodesicMetrics` / `GeodesicGold` は描画専用の `private` 定数 → Canvas
描画のみが参照するため View 側に残し、access control を不必要に広げない |
| 保持 | `GeodesicGeometry` は `internal` のまま → `GeodesicGeometryTests` が
`@testable import Views` で到達可能 |

## 動作・テスト

- 振る舞い変更なし(純粋なファイル分割)
- `swift build` 成功
- `GeodesicGeometryTests`(120 edges / unit-sphere / 非退化)3件合格
- フルスイート **942 tests** 全合格

Refs #248
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