Skip to content

Feat/UI#12

Merged
amemya merged 4 commits into
mainfrom
feat/ui
May 1, 2026
Merged

Feat/UI#12
amemya merged 4 commits into
mainfrom
feat/ui

Conversation

@amemya
Copy link
Copy Markdown
Owner

@amemya amemya commented Apr 27, 2026

Mac向けにUIを強化
前回のPR #11 に続く更新

@amemya amemya self-assigned this Apr 27, 2026
Copilot AI review requested due to automatic review settings April 27, 2026 14:28
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6a426b00-e218-45a2-b175-1897d463a778

📥 Commits

Reviewing files that changed from the base of the PR and between 33b0d0a and cae5c78.

📒 Files selected for processing (1)
  • frontend/src/App.tsx

📝 Walkthrough

Summary by CodeRabbit

  • 新機能

    • 画像を開いた際、ファイルパスをトップバーにブレッドクラム形式で表示します(長いパスは省略表示)
  • 改善

    • アプリ起動時にウィンドウが自動的に最大化されます
    • macOS ネイティブ UI に対応しました
    • タイトルバーのダブルクリックでウィンドウの最大化/復元が可能になりました
    • テキスト選択とドラッグ挙動、トップバーの表示やレイアウトを調整しました

Walkthrough

選択した画像のファイルパスをバックエンドからフロントエンドへ伝搬して表示する機能が追加され、macOS 検出に基づく CSS クラス適用とトップバーの挙動(ダブルクリック最大化など)やウィンドウの初期最大化設定が導入されました。ExifResult に filePath フィールドが追加されています。

Changes

Cohort / File(s) Summary
バックエンド → モデル
app.go, frontend/wailsjs/go/models.ts
ExifResultfilePath フィールドを追加。バックエンドで選択したパスを ExifResult.FilePath に設定し、生成された TS/JS モデルでも受け取るように更新。
フロントエンド UI 実装
frontend/src/App.tsx, frontend/src/App.css
macOS 検出(Environment)を追加してルートに mac-os クラスを付与。OpenImage() の応答から受け取った filePath を state に保持し、画像 decode(img.onload)完了後に EXIF state を更新するよう制御変更。トップバーのダブルクリックで最大化トグルを呼ぶ処理と表示用ブレッドクラム(ファイルパス短縮)を追加。CSS に選択制御、ドラッグ設定、ファイルパス表示用スタイルなどを追加/調整。
アプリ起動設定
main.go
アプリ起動時にウィンドウを初期最大化するオプションを追加(Mac タイトルバー設定も追加)。

Sequence Diagram(s)

sequenceDiagram
    participant UI as Frontend (UI)
    participant Backend as Backend (Wails)
    participant FS as File Picker / OS
    participant Decoder as Image Element (Browser)

    UI->>Backend: OpenImage()
    Backend->>FS: show file picker / read file
    FS-->>Backend: file content, path
    Backend-->>UI: ExifResult { imageBase64, metadata, filePath }
    UI->>Decoder: set src = imageBase64
    Decoder-->>UI: onload
    UI->>UI: set EXIF state and filePath (display breadcrumbs)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Feat/UI #11: フロントエンドの App.tsx / App.css に関する UI/top-bar 挙動および画像読み込み・EXIF 状態セットの変更点が類似しているため、コードレベルで関連しています。
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive PRのタイトル「Feat/UI」は非常に曖昧で、具体的な変更内容を伝えていません。説明がないため、どの機能が追加または改善されたのかが不明確です。 タイトルをより具体的にしてください。例えば「Add macOS UI enhancements and file path display」などの詳細なタイトルが望まれます。
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed PR説明は「Mac向けにUIを強化。前回のPR #11 に続く更新」と記載されており、実装内容に関連しています。詳細度は低いですが、変更の目的を示しています。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/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
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Mac向けのUI強化(タイトルバー周りの挙動/見た目改善と選択中画像のパス表示)を行うPRです。前回PR #11 の続きとして、Mac特有のウィンドウ/ドラッグ領域調整を追加しています。

Changes:

  • WailsのMacタイトルバー設定(HiddenInset)と起動時最大化を追加
  • 画像選択結果に filePath を追加し、トップバーにパス(breadcrumb風)表示を追加
  • トップバーのドラッグ領域/ボタンのno-drag、Mac向け余白などのCSS調整を追加

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
main.go Mac用TitleBar設定と起動時最大化を追加
app.go ExifResultfilePath を追加してフロントへ返す
frontend/wailsjs/go/models.ts 生成モデルに filePath を反映
frontend/src/App.tsx Environment判定、トップバーのダブルクリック最大化、ファイルパス表示を追加
frontend/src/App.css Mac向けトップバー余白、ドラッグ/no-drag、選択不可制御などを追加

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frontend/src/App.tsx Outdated
Comment on lines 60 to 69
iso: result.iso || ""
});
setFilePath(result.filePath || "");

Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

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

setFilePath is updated before the image has successfully decoded/loaded. If the selected image is corrupted or fails to decode in the img.onerror path, the UI will still show the new file path (and updated EXIF) even though no image was loaded. Consider only updating filePath/exif after img.onload succeeds, or explicitly reverting/clearing them in the img.onerror/catch path so the UI state stays consistent with what is actually rendered.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/src/App.tsx (2)

60-68: ⚠️ Potential issue | 🟠 Major

新しい画像の読み込み成功前に exif / filePath を反映しないでください

ここで先に状態を更新すると、既に画像が表示されている状態で別ファイルを選んだ際に、useEffect([imageObj, exif]) が古い imageObj を新しいメタデータで再描画します。さらに decode に失敗すると、その不整合が残ります。新しい ImageonloadimageObj / imageLoaded / exif / filePath をまとめて反映した方が安全です。

修正例
-            // Update EXIF state (leave empty if not found)
-            setExif({
+            const nextExif = {
                 camera: result.camera || "",
                 lens: result.lens || "",
                 focalLength: result.focalLength || "",
                 aperture: result.aperture || "",
                 shutterSpeed: result.shutterSpeed || "",
                 iso: result.iso || ""
-            });
-            setFilePath(result.filePath || "");
+            };
+            const nextFilePath = result.filePath || "";
 
             // Load the Base64 image and await its decoding
             await new Promise<void>((resolve, reject) => {
                 const img = new Image();
                 img.onload = () => {
                     setImageObj(img);
                     setImageLoaded(true);
+                    setExif(nextExif);
+                    setFilePath(nextFilePath);
                     resolve();
                 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/App.tsx` around lines 60 - 68, 現在の実装は先に setExif と setFilePath
を呼んでしまい、古い imageObj と新しいメタデータが混在して再描画や decode 失敗時に不整合を生むため、Exif と filePath の更新を
Image オブジェクトの onload ハンドラでまとめて行うよう修正してください: 具体的には setExif と setFilePath
の呼び出しを削除し、Image を作成して imageObj の onload 内で imageObj/imageLoaded/exif/filePath
を一度に更新する(useEffect([imageObj, exif]) が古い imageObj
を参照して再描画しないようにする)ように実装を移動してください(参照する識別子: setExif, setFilePath, imageObj,
imageLoaded, useEffect([imageObj, exif]))。

207-217: ⚠️ Potential issue | 🟠 Major

ヘッダーの onDoubleClick がボタン操作にも伝播します

.btn--wails-draggable: no-drag はドラッグ判定だけで、React のイベント伝播は止めません。Open Photo / Export をダブルクリックすると、ボタン操作と同時にウィンドウの最大化/復元も走ります。インタラクティブ要素からのイベントは除外してください。

修正例
-            <header className="top-bar" onDoubleClick={WindowToggleMaximise}>
+            <header
+                className="top-bar"
+                onDoubleClick={(e) => {
+                    if ((e.target as HTMLElement).closest('button')) return;
+                    WindowToggleMaximise();
+                }}
+            >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/App.tsx` around lines 207 - 217, The header's
onDoubleClick={WindowToggleMaximise} is firing even when interactive buttons are
double-clicked; stop the propagation from those buttons by adding onDoubleClick
handlers that call event.stopPropagation() before invoking the existing handlers
(e.g. change <button ... onClick={handleSelectImage}> to <button ...
onDoubleClick={(e) => { e.stopPropagation(); handleSelectImageDoubleClick?
handleSelectImageDoubleClick(): null }} or simply <button ... onDoubleClick={(e)
=> e.stopPropagation()} onClick={handleSelectImage}>, and do the same for the
export/download button that uses downloadImage) so double-clicks on .btn do not
bubble up to WindowToggleMaximise; alternatively modify WindowToggleMaximise to
ignore events whose target is a button/input by checking event.target (e.g.
tagName === 'BUTTON' or classList.contains('btn')) before toggling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/App.css`:
- Around line 64-79: The .top-bar-left rule sets user-select: none which
prevents nested .file-path from being selectable; update the .file-path CSS to
explicitly allow selection and disable dragging by adding user-select: text plus
vendor prefixes (-webkit-user-select: text) and also disable drag behavior with
-webkit-user-drag: none (and any needed vendor equivalents), so the path text
becomes selectable/copiable while keeping the surrounding .top-bar-left
behavior.

---

Outside diff comments:
In `@frontend/src/App.tsx`:
- Around line 60-68: 現在の実装は先に setExif と setFilePath を呼んでしまい、古い imageObj
と新しいメタデータが混在して再描画や decode 失敗時に不整合を生むため、Exif と filePath の更新を Image オブジェクトの onload
ハンドラでまとめて行うよう修正してください: 具体的には setExif と setFilePath の呼び出しを削除し、Image を作成して
imageObj の onload 内で imageObj/imageLoaded/exif/filePath
を一度に更新する(useEffect([imageObj, exif]) が古い imageObj
を参照して再描画しないようにする)ように実装を移動してください(参照する識別子: setExif, setFilePath, imageObj,
imageLoaded, useEffect([imageObj, exif]))。
- Around line 207-217: The header's onDoubleClick={WindowToggleMaximise} is
firing even when interactive buttons are double-clicked; stop the propagation
from those buttons by adding onDoubleClick handlers that call
event.stopPropagation() before invoking the existing handlers (e.g. change
<button ... onClick={handleSelectImage}> to <button ... onDoubleClick={(e) => {
e.stopPropagation(); handleSelectImageDoubleClick?
handleSelectImageDoubleClick(): null }} or simply <button ... onDoubleClick={(e)
=> e.stopPropagation()} onClick={handleSelectImage}>, and do the same for the
export/download button that uses downloadImage) so double-clicks on .btn do not
bubble up to WindowToggleMaximise; alternatively modify WindowToggleMaximise to
ignore events whose target is a button/input by checking event.target (e.g.
tagName === 'BUTTON' or classList.contains('btn')) before toggling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b663fa4a-93e1-44ba-9be1-991bdd5eee5b

📥 Commits

Reviewing files that changed from the base of the PR and between 598547a and 33b0d0a.

📒 Files selected for processing (5)
  • app.go
  • frontend/src/App.css
  • frontend/src/App.tsx
  • frontend/wailsjs/go/models.ts
  • main.go

Comment thread frontend/src/App.css
Comment on lines +64 to +79
.top-bar-left {
display: flex;
align-items: center;
gap: 1.5rem;
user-select: none;
-webkit-user-select: none;
}

.file-path {
font-size: 0.75rem;
color: var(--text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 50vw;
}
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Apr 27, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's check if App.css exists and examine its content
if [ -f "frontend/src/App.css" ]; then
    echo "=== App.css content (lines 1-100) ==="
    head -100 "frontend/src/App.css" | cat -n
else
    echo "App.css not found at expected location"
    # Search for it
    find . -name "App.css" -type f
fi

Repository: amemya/ExifFrame

Length of output: 2923


🏁 Script executed:

# Search for .file-path and .top-bar-left class definitions
rg -n "\.top-bar-left|\.file-path|user-select" frontend/src/App.css -B 2 -A 5

Repository: amemya/ExifFrame

Length of output: 833


🏁 Script executed:

# Check App.tsx for the file path display around line 210
if [ -f "frontend/src/App.tsx" ]; then
    echo "=== App.tsx around line 210 ==="
    sed -n '200,220p' "frontend/src/App.tsx" | cat -n
fi

Repository: amemya/ExifFrame

Length of output: 1233


🏁 Script executed:

# Search for --wails-draggable property usage in the codebase
rg -r "wails-draggable" . --type css --type tsx --type ts -B 2 -A 2

Repository: amemya/ExifFrame

Length of output: 88


表示中のファイルパスが選択・コピーできません

.top-bar-leftuser-select: none を設定しているため、ネストされた .file-path がその制約を継承しており、表示されたパスが選択不可になっています。パス表示機能の利便性を高めるには、.file-path で明示的に選択可能にし、ドラッグ動作を無効化する必要があります。

修正例
 .file-path {
     font-size: 0.75rem;
     color: var(--text-secondary);
     white-space: nowrap;
     overflow: hidden;
     text-overflow: ellipsis;
     max-width: 50vw;
+    user-select: text;
+    -webkit-user-select: text;
+    --wails-draggable: no-drag;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.top-bar-left {
display: flex;
align-items: center;
gap: 1.5rem;
user-select: none;
-webkit-user-select: none;
}
.file-path {
font-size: 0.75rem;
color: var(--text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 50vw;
}
.top-bar-left {
display: flex;
align-items: center;
gap: 1.5rem;
user-select: none;
-webkit-user-select: none;
}
.file-path {
font-size: 0.75rem;
color: var(--text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 50vw;
user-select: text;
-webkit-user-select: text;
--wails-draggable: no-drag;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/App.css` around lines 64 - 79, The .top-bar-left rule sets
user-select: none which prevents nested .file-path from being selectable; update
the .file-path CSS to explicitly allow selection and disable dragging by adding
user-select: text plus vendor prefixes (-webkit-user-select: text) and also
disable drag behavior with -webkit-user-drag: none (and any needed vendor
equivalents), so the path text becomes selectable/copiable while keeping the
surrounding .top-bar-left behavior.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

パスはあくまで確認用として表示させているだけであり,選択できる必要性はありません(Lightroom等でもパスをドラッグして文字列を選択することはできません)

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.

@amemya、ご説明ありがとうございます。ファイルパスを確認用の表示専用として扱うのは理にかなったデザイン判断ですね。Lightroom のような参照用途のUIにおいて、パス文字列を選択不可にするのは一般的なアプローチです。ご指摘の通り、変更の必要はありません。


✏️ Learnings added
Learnt from: amemya
Repo: amemya/ExifFrame PR: 12
File: frontend/src/App.css:64-79
Timestamp: 2026-05-01T01:45:07.294Z
Learning: In the ExifFrame project (frontend/src/App.css, App.tsx), the `.file-path` element in the top bar is intentionally display-only (for reference/confirmation). The file path text does not need to be selectable or copyable by design — this is a deliberate UX decision, similar to how Lightroom displays paths without allowing text selection.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@amemya amemya merged commit db983dc into main May 1, 2026
1 check passed
@amemya amemya deleted the feat/ui branch May 1, 2026 03:18
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