diff --git a/map4.js b/map4.js index 179a882..8712c08 100644 --- a/map4.js +++ b/map4.js @@ -3,7 +3,8 @@ // =================================== const SUPABASE_URL = "https://ogtlmtnjkpsxsqzqlacj.supabase.co"; const SUPABASE_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI...(省略)"; + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9ndGxtdG5qa3BzeHNxenFsYWNqIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjMyOTU3NjUsImV4cCI6MjA3ODg3MTc2NX0.JnCE7oUQwrSgGqiu-QRbwnaLBZrO8JX1_RUb37VIMFI"; + const supa = window.supabase.createClient(SUPABASE_URL, SUPABASE_KEY); // =================================== @@ -23,7 +24,7 @@ let map; let selfMarker = null; let otherMarkers = []; -let latestByDevice = []; +let latestByDevice = {}; // ★ オブジェクトとして利用 let allMembers = []; let lastLat = null; @@ -50,7 +51,7 @@ .eq("group_name", currentGroup) .eq("device_id", deviceId); - showOtherUsers(); + showOtherUsers(); // メンバーリスト更新 } function setupStatusButtons() { @@ -73,6 +74,11 @@ localStorage.setItem("group", currentGroup); localStorage.setItem("userName", currentUser); + + const hostLabel = document.getElementById("hostStatus"); + if (hostLabel) { + hostLabel.textContent = isHost ? "あなたはホストです" : "一般メンバーです"; + } } // =================================== @@ -89,6 +95,18 @@ } // =================================== +// 待ち合わせピン(violet) +// =================================== +const meetIcon = L.icon({ + iconUrl: + "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-violet.png", + shadowUrl: + "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png", + iconSize: [25, 41], + iconAnchor: [12, 41], +}); + +// =================================== // 地図初期化 // =================================== function initMap(lat, lng) { @@ -98,7 +116,7 @@ maxZoom: 19, }).addTo(map); - // ホストのみ待ち合わせを設定 + // ホストだけ待ち合わせを設定 map.on("click", async (e) => { if (!isHost) return; @@ -114,7 +132,9 @@ targetLng = newLng; if (targetMarker) map.removeLayer(targetMarker); - targetMarker = L.marker([targetLat, targetLng], { icon: meetIcon }).addTo(map); + targetMarker = L.marker([targetLat, targetLng], { icon: meetIcon }).addTo( + map + ); await supa.from("shared_target").upsert({ group_name: currentGroup, @@ -128,18 +148,46 @@ } // =================================== -// ピン作成 +// 自分の位置保存(ステータス込み) // =================================== -const meetIcon = L.icon({ - iconUrl: - "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-violet.png", - shadowUrl: - "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png", - iconSize: [25, 41], - iconAnchor: [12, 41], -}); +async function saveMyLocation(lat, lng) { + await supa + .from("locations") + .delete() + .eq("group_name", currentGroup) + .eq("device_id", deviceId); -// 自分のピン色 + await supa.from("locations").insert({ + group_name: currentGroup, + user_name: currentUser, + device_id: deviceId, + lat, + lng, + status: myStatus, + }); +} + +// =================================== +// 自分のピン表示 +// =================================== +function renderSelfMarker() { + if (!map || lastLat === null || lastLng === null) return; + + if (selfMarker) map.removeLayer(selfMarker); + + selfMarker = createLabeledMarker( + lastLat, + lastLng, + currentUser, + true, + myStatus + ); + selfMarker.addTo(map); +} + +// =================================== +// ピン生成(ステータス色ラベル付き) +// =================================== function createLabeledMarker(lat, lng, name, isSelf, status) { const pinUrl = isSelf ? "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-green.png" @@ -178,14 +226,14 @@ } // =================================== -// 距離計算 +// 距離計算(修正版) // =================================== function distanceMeters(lat1, lng1, lat2, lng2) { const R = 6371000; const toRad = (deg) => (deg * Math.PI) / 180; const dLat = toRad(lat2 - lat1); - const dLng = toRad(lat2 - lng1); + const dLng = toRad(lng2 - lng1); // ★ 正しく lng2 - lng1 const a = Math.sin(dLat / 2) ** 2 + @@ -220,7 +268,8 @@ `; const res = await fetch( - "https://overpass-api.de/api/interpreter?data=" + encodeURIComponent(query) + "https://overpass-api.de/api/interpreter?data=" + + encodeURIComponent(query) ); return (await res.json()).elements || []; @@ -234,7 +283,6 @@ const stations = await fetchStationsAround(lastLat, lastLng); - // 前のピンを削除 stationMarkers.forEach((m) => map.removeLayer(m)); stationMarkers = []; @@ -263,6 +311,7 @@ box.textContent = `最寄り駅:${nearest.name}(約 ${(nearestDist / 1000).toFixed(2)} km)`; } + // =================================== // メンバー一覧表示(ステータス付き) // =================================== @@ -297,7 +346,7 @@ const status = row?.status || "移動中"; li.innerHTML = ` -