Skip to content

Commit

Permalink
storageにアップロードする画像のメタデータを削除
Browse files Browse the repository at this point in the history
  • Loading branch information
MurakawaTakuya committed Dec 29, 2024
1 parent ecc2e76 commit 6d10172
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 33 deletions.
4 changes: 3 additions & 1 deletion src/Components/Account/LoggedInView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ export default function LoggedInView() {
return (
<>
{user.loginType === "Guest" ? (
<>ゲストとしてログイン中</>
<Typography sx={{ textAlign: "center" }}>
ゲストとしてログイン中
</Typography>
) : (
<>
<Typography sx={{ textAlign: "center" }}>
Expand Down
5 changes: 2 additions & 3 deletions src/Components/Loader/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ export const Loader = ({ children }: LoaderProps) => {
redirect("/account");
}

// 10秒経ったらボタンを表示
setTimeout(() => {
setShowErrorButton(true);
}, 6000);
}, 10000);

return (
<>
Expand Down Expand Up @@ -54,7 +53,7 @@ export const Loader = ({ children }: LoaderProps) => {
>
<Typography
color="warning"
sx={{ textAlign: "center", width: "90vw" }}
sx={{ textAlign: "center", width: "90vw", maxWidth: "500px" }}
>
認証エラーが発生した可能性があります。
<br />
Expand Down
7 changes: 4 additions & 3 deletions src/Components/PostModal/PostModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { showSnackBar } from "@/Components/SnackBar/SnackBar";
import { PostWithGoalId } from "@/types/types";
import { createPost, handleCreatePostError } from "@/utils/API/Post/createPost";
import { uploadImage } from "@/utils/Uploader";
import { removeImageMetadata, uploadImage } from "@/utils/Uploader";
import { useUser } from "@/utils/UserContext";
import { Add } from "@mui/icons-material";
import AddAPhotoIcon from "@mui/icons-material/AddAPhoto";
Expand Down Expand Up @@ -43,7 +43,7 @@ export default function PostModal({
setText(event.target.value);
};

const handleImageChange = (event: ChangeEvent<HTMLInputElement>) => {
const handleImageChange = async (event: ChangeEvent<HTMLInputElement>) => {
const selectedFile = event.target.files?.[0];

if (!selectedFile) {
Expand All @@ -56,7 +56,8 @@ export default function PostModal({

// ファイルサイズの上限を設定
const maxSize = 8; // 上限8MB
const fileSizeMB = selectedFile.size / (1024 * 1024);
const fileWithoutMetadata = await removeImageMetadata(selectedFile); // モーションフォトの動画を除いたサイズを取得
const fileSizeMB = fileWithoutMetadata.size / (1024 * 1024);
if (fileSizeMB > maxSize) {
showSnackBar({
message: `最大ファイルサイズは${maxSize}MBです。`,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/API/User/fetchUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const handleFetchUserError = (error: unknown) => {
if (error instanceof Error) {
console.error("Fetch error:", error.message);
if (error.message.includes("404")) {
snackBarMessage = "ユーザーが見つかりませんでした";
snackBarMessage = "ユーザー情報が登録されていません";
}
if (error.message.includes("500")) {
snackBarMessage = "サーバーエラーが発生しました";
Expand Down
88 changes: 69 additions & 19 deletions src/utils/Uploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,74 @@ export const uploadImage = (
throw new Error("ファイルが選択されていません");
}

// cryptoモジュールを使用してユニークなIDを生成
const uniqueId = crypto.randomUUID();
const storageRef = ref(storage, `post/${uniqueId}`);
const uploadTask = uploadBytesResumable(storageRef, file);
// メタデータを削除してからFirebaseにアップロード
removeImageMetadata(file)
.then((cleanFile) => {
const uniqueId = crypto.randomUUID();
const storageRef = ref(storage, `post/${uniqueId}`);
const uploadTask = uploadBytesResumable(storageRef, cleanFile);

uploadTask.on(
"state_changed",
(snapshot) => {
const percent = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
onProgress(percent);
},
(error) => {
throw new Error("ファイルアップに失敗しました。エラー: " + error.message);
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
onSuccess(downloadURL, uniqueId); // 完了時にURLとIDを返す
});
}
);
uploadTask.on(
"state_changed",
(snapshot) => {
const percent =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
onProgress(percent);
},
(error) => {
throw new Error(
"ファイルアップに失敗しました。エラー: " + error.message
);
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
onSuccess(downloadURL, uniqueId); // 完了時にURLとIDを返す
});
}
);
})
.catch((error) => {
throw new Error(
"画像のメタデータ削除に失敗しました。エラー: " + error.message
);
});
};

// 画像のメタデータを削除する関数
// モーションフォトの動画も削除できる
export const removeImageMetadata = (file: File): Promise<File> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;

const ctx = canvas.getContext("2d");
if (ctx) {
ctx.drawImage(img, 0, 0);

canvas.toBlob((blob) => {
if (blob) {
const cleanFile = new File([blob], file.name, {
type: file.type,
});
resolve(cleanFile);
} else {
reject(new Error("画像処理に失敗しました。"));
}
}, file.type);
} else {
reject(new Error("Canvas のコンテキストを取得できません。"));
}
};
img.src = event.target?.result as string;
};
reader.onerror = () => {
reject(new Error("画像を読み込めませんでした。"));
};
reader.readAsDataURL(file);
});
};
16 changes: 10 additions & 6 deletions src/utils/UserContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
"use client";
import { auth } from "@/app/firebase";
import { showSnackBar } from "@/Components/SnackBar/SnackBar";
import { LoginType, User } from "@/types/types";
import { fetchUserById } from "@/utils/API/User/fetchUser";
import {
fetchUserById,
handleFetchUserError,
} from "@/utils/API/User/fetchUser";
import { User as FirebaseUser, onAuthStateChanged } from "firebase/auth";
import {
createContext,
Expand Down Expand Up @@ -96,11 +100,11 @@ export const UserProvider = ({ children }: Props) => {
}
} catch (error: unknown) {
console.error("ユーザーデータの取得に失敗しました:", error);
// const message = handleFetchUserError(error);
// showSnackBar({
// message,
// type: "warning",
// });
const message = handleFetchUserError(error);
showSnackBar({
message,
type: "warning",
});
}
}
);
Expand Down

0 comments on commit 6d10172

Please sign in to comment.