Skip to content

アバター・イベントの統合画像アップロード機能実装 #19

@oumelab

Description

@oumelab

概要

#4#18 の画像アップロード機能を同時に実装する

  • Cloudflare R2 セットアップ
  • 共通アップロードシステム
  • アバター + イベント画像対応
  • 既存のURL入力も継続サポート
  • 共通コンポーネント化

実装範囲

  1. Cloudflare R2 統合
  2. 共通アップロードAPI
  3. 統一UI コンポーネント
  4. 画像最適化・リサイズ
  5. プログレス表示
  6. エラーハンドリング
  7. 既存URL入力との共存
  8. アバター + イベント画像対応

メモ

// 共通アップロード機能
functions/api/upload/
├── image.ts           // 汎用画像アップロード
├── avatar.ts          // アバター専用(リサイズ付き)
└── event-image.ts     // イベント画像専用

統合実装のメリット

技術的メリット

共通化できるもの:
✅ Cloudflare R2設定
✅ 画像バリデーション(サイズ・形式)
✅ ファイル名生成ロジック
✅ エラーハンドリング
✅ プレビュー機能
✅ セキュリティチェック

開発効率のメリット

一度の学習で:
✅ R2 SDK の習得
✅ ファイルアップロードパターン
✅ 画像処理ライブラリ
✅ プログレス表示UI
✅ エラー処理パターン

ユーザー体験のメリット

一貫したUX:
✅ 同じアップロード操作
✅ 統一されたプレビュー
✅ 同じエラーメッセージ
✅ 同じプログレス表示

構成案

共通コンポーネント設計

// src/components/ImageUpload.tsx
interface ImageUploadProps {
  type: 'avatar' | 'event';
  currentUrl?: string;
  onUploadComplete: (url: string) => void;
  maxSize?: number;
  aspectRatio?: number;
}

export function ImageUpload({ type, currentUrl, onUploadComplete }: ImageUploadProps) {
  // 共通ロジック:
  // - ドラッグ&ドロップ
  // - ファイル検証
  // - アップロード処理
  // - プレビュー表示
  // - エラーハンドリング
}

バックエンド共通化

// functions/api/utils/image-upload.ts
export async function uploadImage(
  file: File, 
  type: 'avatar' | 'event',
  userId: string,
  env: Env
): Promise<string> {
  
  // 共通処理:
  // - ファイル検証
  // - リサイズ(必要に応じて)
  // - R2アップロード
  // - URL生成
  
  const folder = type === 'avatar' ? 'avatars' : 'events';
  const key = `${folder}/${userId}/${createId()}-${file.name}`;
  
  await env.R2_BUCKET.put(key, file.stream());
  return `https://your-r2-domain.com/${key}`;
}

互換性の維持

// URL入力を残す
interface ImageInputProps {
  mode: 'url' | 'upload' | 'both';
}

// 段階的移行
<ImageInput 
  mode="both"  // URLとアップロード両方対応
  currentUrl={event.image_url}
  onUrlChange={handleUrlChange}
  onFileUpload={handleFileUpload}
/>

パフォーマンス考慮

// 画像の最適化設定
const imageConfig = {
  avatar: {
    maxWidth: 256,
    maxHeight: 256,
    quality: 85
  },
  event: {
    maxWidth: 800,
    maxHeight: 600,
    quality: 80
  }
};

ブランチ

feature/image-upload-integration

Metadata

Metadata

Assignees

No one assigned

    Labels

    blocked他の機能の実装完了後までfeature新機能の追加priority: medium中優先度

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions