diff --git a/map4.js b/map4.js
index 95f4ae9..4231c1b 100644
--- a/map4.js
+++ b/map4.js
@@ -20,16 +20,11 @@
let map;
let selfMarker = null;
let otherMarkers = [];
-let latestByDevice = {};
+let lastLat, lastLng;
-let lastLat = null;
-let lastLng = null;
+const DEFAULT_LAT = 35.681236;
+const DEFAULT_LNG = 139.767125;
-const DEFAULT_LAT = 35.685175;
-const DEFAULT_LNG = 139.752799;
-
-// ===================================
-// URL 読み込み
// ===================================
function loadParams() {
const p = new URLSearchParams(location.search);
@@ -41,34 +36,29 @@
}
// ===================================
-// アイコン
-// ===================================
function createIcon(type) {
return L.icon({
- iconUrl: type === "self"
- ? "https://maps.gstatic.com/mapfiles/kml/paddle/blu-stars.png"
- : "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-green.png",
+ iconUrl:
+ type === "self"
+ ? "https://maps.gstatic.com/mapfiles/kml/paddle/blu-stars.png"
+ : "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-green.png",
iconSize: [40, 55],
iconAnchor: [20, 50],
});
}
// ===================================
-// GPS
-// ===================================
function getPosition() {
- return new Promise((res, rej) => {
+ return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
- pos => res(pos.coords),
- rej,
+ pos => resolve(pos.coords),
+ reject,
{ enableHighAccuracy: true }
);
});
}
// ===================================
-// 地図初期化
-// ===================================
function initMap(lat, lng) {
map = L.map("map").setView([lat, lng], 15);
@@ -78,29 +68,9 @@
}
// ===================================
-// 自分のピン
-// ===================================
-function renderSelfMarker() {
- if (selfMarker) map.removeLayer(selfMarker);
-
- selfMarker = L.marker([lastLat, lastLng], {
- icon: createIcon("self"),
- }).addTo(map);
-
- selfMarker.bindPopup(`${currentUser}(あなた)`);
-
- // ★ 中心移動は e.latlng を必ず使う
- selfMarker.on("click", (e) => {
- map.panTo(e.latlng, { animate: true, duration: 0.4 });
- selfMarker.openPopup();
- });
-}
-
-// ===================================
-// DB 保存
-// ===================================
async function saveMyLocation(lat, lng) {
- await supa.from("locations")
+ await supa
+ .from("locations")
.delete()
.eq("group_name", currentGroup)
.eq("device_id", deviceId);
@@ -115,32 +85,38 @@
}
// ===================================
-// メンバー一覧
+function renderSelfMarker() {
+ if (selfMarker) map.removeLayer(selfMarker);
+
+ selfMarker = L.marker([lastLat, lastLng], {
+ icon: createIcon("self")
+ }).addTo(map);
+
+ selfMarker.bindPopup(`${currentUser}(あなた)`);
+
+ selfMarker.on("click", () => {
+ map.setView(selfMarker.getLatLng(), 17, { animate: true });
+ selfMarker.openPopup();
+ });
+}
+
// ===================================
-function showMemberList(latestByDevice) {
+function showMemberList(latest) {
const list = document.getElementById("memberList");
list.innerHTML = "";
- Object.values(latestByDevice).forEach(row => {
+ Object.values(latest).forEach(row => {
const li = document.createElement("li");
+ li.textContent = row.user_name;
- const diff = (Date.now() - new Date(row.updated_at)) / 1000;
- li.classList.add(diff < 30 ? "online" : "offline");
-
- const icon = document.createElement("div");
- icon.className = "member-icon";
- li.append(icon);
-
- li.append(row.user_name);
-
- li.addEventListener("click", () => {
+ li.onclick = () => {
if (row.device_id === deviceId) {
- if (selfMarker) selfMarker.fire("click");
- return;
+ selfMarker.fire("click");
+ } else {
+ const mk = otherMarkers.find(m => m._deviceId === row.device_id);
+ if (mk) mk.fire("click");
}
- const mk = otherMarkers.find(m => m._myDeviceId === row.device_id);
- if (mk) mk.fire("click");
- });
+ };
list.appendChild(li);
});
@@ -151,36 +127,29 @@
const { data } = await supa
.from("locations")
.select("*")
- .eq("group_name", currentGroup)
- .order("updated_at", { ascending: false });
+ .eq("group_name", currentGroup);
- latestByDevice = {};
- if (!Array.isArray(data)) return;
+ const latest = {};
+ data.forEach(row => {
+ if (!latest[row.device_id]) latest[row.device_id] = row;
+ });
- for (const row of data) {
- if (!latestByDevice[row.device_id]) {
- latestByDevice[row.device_id] = row;
- }
- }
-
- showMemberList(latestByDevice);
+ showMemberList(latest);
otherMarkers.forEach(m => map.removeLayer(m));
otherMarkers = [];
- Object.values(latestByDevice).forEach(row => {
+ Object.values(latest).forEach(row => {
if (row.device_id === deviceId) return;
const mk = L.marker([row.lat, row.lng], {
- icon: createIcon("other"),
+ icon: createIcon("other")
}).addTo(map);
- mk._myDeviceId = row.device_id;
+ mk._deviceId = row.device_id;
- mk.bindPopup(`${row.user_name}`);
-
- mk.on("click", (e) => {
- map.panTo(e.latlng, { animate: true, duration: 0.4 });
+ mk.on("click", () => {
+ map.setView([row.lat, row.lng], 17, { animate: true });
mk.openPopup();
});
@@ -189,18 +158,14 @@
}
// ===================================
-// main
-// ===================================
async function main() {
loadParams();
- let lat = DEFAULT_LAT;
- let lng = DEFAULT_LNG;
-
+ let lat = DEFAULT_LAT, lng = DEFAULT_LNG;
try {
- const pos = await getPosition();
- lat = pos.latitude;
- lng = pos.longitude;
+ const p = await getPosition();
+ lat = p.latitude;
+ lng = p.longitude;
} catch {}
lastLat = lat;
@@ -209,13 +174,14 @@
initMap(lat, lng);
renderSelfMarker();
await saveMyLocation(lat, lng);
+
await showOtherUsers();
setInterval(async () => {
try {
- const pos = await getPosition();
- lastLat = pos.latitude;
- lastLng = pos.longitude;
+ const p = await getPosition();
+ lastLat = p.latitude;
+ lastLng = p.longitude;
renderSelfMarker();
await saveMyLocation(lastLat, lastLng);
} catch {}
@@ -223,13 +189,10 @@
setInterval(showOtherUsers, 2000);
- document.getElementById("exitBtn").onclick =
- () => (location.href = "index.html");
+ document.getElementById("exitBtn").onclick = () =>
+ (location.href = "index.html");
- // ★ 地図サイズの最終調整(超重要)
- setTimeout(() => {
- map.invalidateSize();
- }, 500);
+ setTimeout(() => map.invalidateSize(), 300);
}
window.addEventListener("DOMContentLoaded", main);