Skip to content

Conversation

@otukado
Copy link
Contributor

@otukado otukado commented Oct 27, 2025

User description

close: #590


PR Type

Bug fix, Enhancement


Description

  • 画像プレビュー用URLを状態に保持

  • プレビューimgのsrcにpreviewUrlを使用

  • FileSeedへpreviewUrlフィールドを追加


Diagram Walkthrough

flowchart LR
  FileInput["ファイル入力"] -- FileReader.readAsDataURL --> DataURL["reader.result(データURL)"]
  DataURL -- "previewUrlに格納" --> FileSeed["FileSeed.previewUrl"]
  FileSeed -- "img :src へ" --> Preview["プレビュー表示"]
Loading

File Walkthrough

Relevant files
Enhancement
entities.ts
FileSeedにpreviewUrlプロパティを追加                                                           

src/features/file/entities.ts

  • FileSeedにpreviewUrlを追加
  • プレビューURLを保持可能に
+1/-0     
Bug fix
NewApplicationFileForm.vue
プレビューURL保存とimg参照先の修正                                                                         

src/components/newApplication/NewApplicationFileForm.vue

  • FileReader結果をpreviewUrlとして保存
  • imgのsrcをnameからpreviewUrlへ変更
  • プレビュー読み込み失敗を解消
+2/-2     

@otukado otukado requested review from Copilot and reiroop October 27, 2025 04:24
@otukado otukado self-assigned this Oct 27, 2025
Copy link

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

This PR fixes the preview display functionality for uploaded files by properly passing the file's data URL to the image preview component.

Key Changes:

  • Added previewUrl field to the FileSeed interface to store the file's preview URL
  • Updated file upload logic to capture and store the FileReader result as previewUrl
  • Changed image source binding from filename to the actual preview URL

Reviewed Changes

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

File Description
src/features/file/entities.ts Added optional previewUrl property to FileSeed interface
src/components/newApplication/NewApplicationFileForm.vue Updated file handling to store preview URL and corrected image src binding

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

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

590 - Partially compliant

Compliant requirements:

  • FileReaderのreader.resultを用いてプレビュー用URLを状態に保持
  • の src にプレビュー用URLを使用
  • 送信用のFileオブジェクトを引き続き保持

Non-compliant requirements:

  • URL.createObjectURLの利用(データURLで代替しているため必須ではないが、明示はなし)

Requires further human verification:

  • 実ブラウザでPNG/JPEG/GIF等の代表的な画像が正しくプレビュー表示されることの確認
  • 大きいファイルや複数選択時の動作・パフォーマンス確認
⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

型の整合性

reader.resultはstring | ArrayBuffer | nullの可能性があり、previewUrlに割り当てる前に型ガードやnullチェックが必要な可能性があります。template側で未定義/nullの場合のフォールバックも要確認。

reader.onload = () => {
  emit('input', [
    ...props.files,
    { name: file.name, file: file, previewUrl: reader.result } as FileSeed
  ])
メモリ管理

DataURLはファイルサイズに比例してメモリを消費します。大量/大容量ファイルでのパフォーマンスを考慮し、必要に応じてURL.createObjectURLの利用やアンマウント時の解放検討が必要です。

for (const file of Array.from(e.target.files)) {
  const reader = new FileReader()
  reader.readAsDataURL(file)
  reader.onload = () => {
    emit('input', [
      ...props.files,
      { name: file.name, file: file, previewUrl: reader.result } as FileSeed
    ])
  }
}
オプショナル扱い

previewUrlがオプショナルのため、プレビュー描画側でundefined時の表示制御が必要です。現在のテンプレートでundefinedを許容するかを確認してください。

export interface FileSeed {
  file: File
  name: string
  previewUrl?: string
}

@otukado otukado closed this Oct 31, 2025
@otukado otukado force-pushed the fix/file-image-preview branch from 871ca1f to 3fe4144 Compare October 31, 2025 14:31
@otukado otukado reopened this Nov 5, 2025
@otukado otukado requested a review from reiroop November 6, 2025 04:38
const emit = defineEmits<(e: 'input', value: FileSeed[]) => void>()
const inputRef = ref()
const filePreviewUrls = ref<string[]>([])
Copy link
Contributor

Choose a reason for hiding this comment

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

今はなさそうですが、props.filesが親側で変更された場合に追従できない気がします

@otukado otukado force-pushed the fix/file-image-preview branch from c3ab260 to 3366719 Compare November 6, 2025 14:34
@otukado otukado requested a review from reiroop November 6, 2025 14:35
@otukado otukado requested a review from reiroop November 7, 2025 01:06
files,
files => {
filePreviewUrls.value = files.map(({ file }) => {
if (previewUrlCache.has(file)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

previewUrlCache.get(file)を取得してundefinedでなかったらreturnする方が型的には安全そうな気がします

'input',
props.files.filter((_, i) => index !== i)
)
files.value.splice(index, 1)
Copy link
Contributor

@reiroop reiroop Nov 7, 2025

Choose a reason for hiding this comment

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

悩みどころだけどremoveFileでもrevokeObjectURLを呼ばないとユーザーの操作次第では重くなりそうな気がします

@otukado otukado requested a review from reiroop November 18, 2025 08:48
Comment on lines +38 to +39
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return previewUrlCache.get(file)!
Copy link
Contributor

Choose a reason for hiding this comment

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

previewUrlCache.get(file)を取得してundefinedでなかったらreturnする方が型的に保証されていて安全なので、そうする方がいい気がします

Comment on lines +29 to +30
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
URL.revokeObjectURL(previewUrlCache.get(file)!)
Copy link
Contributor

Choose a reason for hiding this comment

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

previewUrlCache.get(file)undefinedでない時だけrevokeObjectURLを呼ぶ、みたいなラフな実装でいいので、null assertionはあんまり使わないようにお願いします
型チェックの恩恵は受けられないより受けられる方がましです

files.value.splice(index, 1)
}
const filePreviewUrls = computed(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

必須ではないんですけど、useFilePreviewUrlsみたいなcomposableをこのコンポーネント内か別ファイルに作って、previewUrlCacheはその中でだけ参照されるようにしつつ、onUnmountedをその中で呼び出すようにすると、特定の役割をしている変数と処理群をまとめられるので可読性と将来的な変更のしやすさが上げられたり、変数の可視範囲を狭められて将来誤った変更をする可能性を減らせたりするので良いんじゃないかなと思います

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

添付ファイルの画像プレビューが機能しない

3 participants