fix: remove success notifications and parse map coordinates safely

This commit is contained in:
2026-06-27 22:28:13 +07:00
parent 0152e7014d
commit 9f60efeb6d
6 changed files with 28 additions and 27 deletions
+1 -1
View File
@@ -21,7 +21,7 @@
<meta name="twitter:title" content="Travel Planner - Lên kế hoạch chuyến đi của bạn" />
<meta name="twitter:description" content="Khám phá những hành trình tuyệt vời và chia sẻ khoảnh khắc đẹp với cộng đồng du lịch." />
<meta name="twitter:image" content="https://yotrip.labz.io.vn/background.avif" />
<script type="module" crossorigin src="/assets/index-C0KfLnj9.js"></script>
<script type="module" crossorigin src="/assets/index-R09P7UbD.js"></script>
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-CMxvf4Kt.js">
<link rel="modulepreload" crossorigin href="/assets/vendor-others-CNhtyHGs.js">
<link rel="modulepreload" crossorigin href="/assets/vendor-editor-BDwQQzB8.js">
@@ -158,11 +158,6 @@ export const AddPhotoModal: React.FC<AddPhotoModalProps> = ({ isOpen, onClose, t
if (!response.ok) throw new Error('Tải lên ảnh thất bại');
}
notify({
title: 'Thành công',
message: `Đã tải lên ${selectedFiles.length} ảnh.`,
type: 'success'
});
// Giải phóng bộ nhớ sau khi hoàn tất
previews.forEach(url => URL.revokeObjectURL(url));
+12 -12
View File
@@ -195,9 +195,9 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onLoginSuccess,
const groups: { [key: string]: any[] } = {};
filteredPhotos.forEach((photo) => {
const lat = photo.metadata?.lat;
const lng = photo.metadata?.lng;
if (typeof lat === 'number' && typeof lng === 'number') {
const lat = typeof photo.metadata?.lat === 'number' ? photo.metadata.lat : parseFloat(photo.metadata?.lat);
const lng = typeof photo.metadata?.lng === 'number' ? photo.metadata.lng : parseFloat(photo.metadata?.lng);
if (typeof lat === 'number' && !isNaN(lat) && typeof lng === 'number' && !isNaN(lng)) {
const key = `${lat.toFixed(5)},${lng.toFixed(5)}`;
if (!groups[key]) {
groups[key] = [];
@@ -629,13 +629,13 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onLoginSuccess,
if (photoId && publicPhotos.length > 0) {
const foundPhoto = publicPhotos.find((p) => p.id === photoId);
if (foundPhoto) {
const lat = foundPhoto.metadata?.lat;
const lng = foundPhoto.metadata?.lng;
if (typeof lat === 'number' && typeof lng === 'number') {
const lat = typeof foundPhoto.metadata?.lat === 'number' ? foundPhoto.metadata.lat : parseFloat(foundPhoto.metadata?.lat);
const lng = typeof foundPhoto.metadata?.lng === 'number' ? foundPhoto.metadata.lng : parseFloat(foundPhoto.metadata?.lng);
if (typeof lat === 'number' && !isNaN(lat) && typeof lng === 'number' && !isNaN(lng)) {
const group = publicPhotos.filter((p) => {
const pLat = p.metadata?.lat;
const pLng = p.metadata?.lng;
return typeof pLat === 'number' && typeof pLng === 'number' &&
const pLat = typeof p.metadata?.lat === 'number' ? p.metadata.lat : parseFloat(p.metadata?.lat);
const pLng = typeof p.metadata?.lng === 'number' ? p.metadata.lng : parseFloat(p.metadata?.lng);
return typeof pLat === 'number' && !isNaN(pLat) && typeof pLng === 'number' && !isNaN(pLng) &&
Math.abs(pLat - lat) < 0.00001 &&
Math.abs(pLng - lng) < 0.00001;
});
@@ -969,9 +969,9 @@ export const ExploreMap = ({ onBack, onLogout, user, onViewTour, onLoginSuccess,
{groupedPhotos.map((photoGroup) => {
const latestPhoto = photoGroup[0];
const lat = latestPhoto.metadata?.lat;
const lng = latestPhoto.metadata?.lng;
if (typeof lat !== 'number' || typeof lng !== 'number') return null;
const lat = typeof latestPhoto.metadata?.lat === 'number' ? latestPhoto.metadata.lat : parseFloat(latestPhoto.metadata?.lat);
const lng = typeof latestPhoto.metadata?.lng === 'number' ? latestPhoto.metadata.lng : parseFloat(latestPhoto.metadata?.lng);
if (typeof lat !== 'number' || isNaN(lat) || typeof lng !== 'number' || isNaN(lng)) return null;
return (
<Marker
-2
View File
@@ -377,8 +377,6 @@ export const LandingPage: React.FC<LandingPageProps> = ({
throw new Error(errorData.message || 'Tải ảnh thất bại.');
}
notify({ title: 'Thành công!', message: 'Ảnh của bạn đã được tải lên.', type: 'success' });
// Xóa pendingInviteToken và parameter token khỏi URL để tránh tự động chuyển sang JoinTourPage
localStorage.removeItem('pendingInviteToken');
const url = new URL(window.location.href);
+15 -7
View File
@@ -7,18 +7,26 @@ interface ProcessedImageResult {
}
export const processAndResizeImage = async (file: File): Promise<ProcessedImageResult> => {
// 1. Read EXIF coordinates first from the original file using exifr
// 1. Read EXIF coordinates first from the original file using exifr via ArrayBuffer
let latitude: number | null = null;
let longitude: number | null = null;
try {
const gps = await exifr.gps(file);
if (gps && typeof gps.latitude === 'number' && typeof gps.longitude === 'number') {
latitude = gps.latitude;
longitude = gps.longitude;
console.log('[imageProcessor] Successfully parsed EXIF coordinates via exifr:', latitude, longitude);
const buffer = await new Promise<ArrayBuffer | null>((resolve) => {
const reader = new FileReader();
reader.onload = (e) => resolve(e.target?.result as ArrayBuffer);
reader.onerror = () => resolve(null);
reader.readAsArrayBuffer(file);
});
if (buffer) {
const gps = await exifr.gps(buffer);
if (gps && typeof gps.latitude === 'number' && typeof gps.longitude === 'number') {
latitude = gps.latitude;
longitude = gps.longitude;
console.log('[imageProcessor] Successfully parsed EXIF coordinates via exifr ArrayBuffer:', latitude, longitude);
}
}
} catch (e) {
console.error('[imageProcessor] Failed to read EXIF GPS using exifr:', e);
console.error('[imageProcessor] Failed to read EXIF GPS using exifr ArrayBuffer:', e);
}
// 2. Perform resizing to maximum 2048px on its longest edge