라이브 체류중 누적 배지 표시
This commit is contained in:
+109
@@ -433,6 +433,9 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
|
||||
trackLines: [],
|
||||
smallMarkers: [],
|
||||
stayMarkers: [],
|
||||
currentStayMarker: null,
|
||||
currentStayTimer: null,
|
||||
currentStayState: null,
|
||||
historyStartMarker: null,
|
||||
historyEndMarker: null,
|
||||
playbackMarker: null,
|
||||
@@ -2233,6 +2236,103 @@ function createFaceMarkerIcon(size = 60) {
|
||||
};
|
||||
}
|
||||
|
||||
function createCurrentStayIcon(text) {
|
||||
return {
|
||||
content: `<div class="current-stay-badge-wrap"><div class="current-stay-badge">${text}</div></div>`,
|
||||
anchor: new naver.maps.Point(0, 0)
|
||||
};
|
||||
}
|
||||
|
||||
function currentStayText(seconds) {
|
||||
const duration = formatDuration(Math.round(seconds));
|
||||
return langCode === 'ko' ? `누적 ${duration} 체류중` : `${duration} staying`;
|
||||
}
|
||||
|
||||
function stopCurrentStayBadge() {
|
||||
if (mapState.currentStayTimer) {
|
||||
clearInterval(mapState.currentStayTimer);
|
||||
mapState.currentStayTimer = null;
|
||||
}
|
||||
if (mapState.currentStayMarker) {
|
||||
mapState.currentStayMarker.setMap(null);
|
||||
}
|
||||
mapState.currentStayState = null;
|
||||
}
|
||||
|
||||
function currentStaySegmentStart(stay, currentPoint) {
|
||||
const points = mapState.historyPoints || [];
|
||||
let startTime = currentPoint.time || new Date().toISOString();
|
||||
for (let i = points.length - 1; i >= 0; i--) {
|
||||
const point = points[i];
|
||||
if (distanceMeters(stay, point) > STAY_GROUP_RADIUS_M) {
|
||||
break;
|
||||
}
|
||||
startTime = point.time || startTime;
|
||||
}
|
||||
return startTime;
|
||||
}
|
||||
|
||||
function currentStayStateFor(point) {
|
||||
if (!mapState.map || !hasValidCoords(point.lat, point.lng) || !mapState.stayPoints?.length) return null;
|
||||
const stay = mapState.stayPoints.find(item => distanceMeters(item, point) <= STAY_GROUP_RADIUS_M);
|
||||
if (!stay) return null;
|
||||
|
||||
const visits = Array.isArray(stay.visits) ? stay.visits : [];
|
||||
const segmentStart = currentStaySegmentStart(stay, point);
|
||||
const segmentStartTs = toTimestamp(segmentStart) || toTimestamp(point.time) || Date.now();
|
||||
const pointTs = toTimestamp(point.time) || Date.now();
|
||||
const lastVisit = visits.at(-1);
|
||||
const latestVisitIsCurrent = lastVisit
|
||||
&& Math.abs((toTimestamp(lastVisit.endTime) || 0) - pointTs) <= 60000
|
||||
&& distanceMeters(stay, point) <= STAY_GROUP_RADIUS_M;
|
||||
const baseDuration = Math.max(0, Number(stay.duration) || 0) - (latestVisitIsCurrent ? Math.max(0, Number(lastVisit.duration) || 0) : 0);
|
||||
|
||||
return {
|
||||
latlng: point.latlng || new naver.maps.LatLng(point.lat, point.lng),
|
||||
baseDuration,
|
||||
startedAt: segmentStartTs,
|
||||
};
|
||||
}
|
||||
|
||||
function renderCurrentStayBadge() {
|
||||
const state = mapState.currentStayState;
|
||||
if (!state || !mapState.currentStayMarker) return;
|
||||
const elapsed = Math.max(0, (Date.now() - state.startedAt) / 1000);
|
||||
const text = currentStayText(state.baseDuration + elapsed);
|
||||
mapState.currentStayMarker.setIcon(createCurrentStayIcon(text));
|
||||
}
|
||||
|
||||
function updateCurrentStayBadge(point) {
|
||||
if (mapState.playbackTimer || _overrideRange) {
|
||||
stopCurrentStayBadge();
|
||||
return;
|
||||
}
|
||||
|
||||
const state = currentStayStateFor(point);
|
||||
if (!state) {
|
||||
stopCurrentStayBadge();
|
||||
return;
|
||||
}
|
||||
|
||||
mapState.currentStayState = state;
|
||||
if (!mapState.currentStayMarker) {
|
||||
mapState.currentStayMarker = new naver.maps.Marker({
|
||||
position: state.latlng,
|
||||
map: mapState.map,
|
||||
zIndex: 130,
|
||||
icon: createCurrentStayIcon(currentStayText(state.baseDuration))
|
||||
});
|
||||
} else {
|
||||
mapState.currentStayMarker.setMap(mapState.map);
|
||||
mapState.currentStayMarker.setPosition(state.latlng);
|
||||
}
|
||||
|
||||
renderCurrentStayBadge();
|
||||
if (!mapState.currentStayTimer) {
|
||||
mapState.currentStayTimer = setInterval(renderCurrentStayBadge, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function createMainMarker(latlng) {
|
||||
mapState.marker = new naver.maps.Marker({
|
||||
position: latlng,
|
||||
@@ -2266,6 +2366,7 @@ function setCurrentLocationVisible(visible) {
|
||||
const map = visible ? mapState.map : null;
|
||||
mapState.marker?.setMap?.(map);
|
||||
mapState.circle?.setMap?.(map);
|
||||
if (!visible) stopCurrentStayBadge();
|
||||
}
|
||||
|
||||
function applyMarkerEffects(marker) {
|
||||
@@ -2321,6 +2422,7 @@ function bounceMarker(marker) {
|
||||
|
||||
function resetHistoryLayer() {
|
||||
stopHistoryPlayback();
|
||||
stopCurrentStayBadge();
|
||||
clearTrackLines();
|
||||
if (mapState.smallMarkers?.length) {
|
||||
mapState.smallMarkers.forEach(m => m.setMap?.(null));
|
||||
@@ -2479,6 +2581,7 @@ function updateDOMWithData(data) {
|
||||
}
|
||||
updateConfiguredHome(data) || updateHomeCenter(data.latitude, data.longitude);
|
||||
setCurrentLocationVisible(false);
|
||||
stopCurrentStayBadge();
|
||||
clearCurrentRangeCircles();
|
||||
|
||||
// 히스토리 궤적/포인트 업데이트
|
||||
@@ -2530,6 +2633,12 @@ function updateDOMWithData(data) {
|
||||
lastLat = data.latitude;
|
||||
lastLng = data.longitude;
|
||||
lastUpdateISOTime = data.updated;
|
||||
updateCurrentStayBadge({
|
||||
lat: data.latitude,
|
||||
lng: data.longitude,
|
||||
latlng,
|
||||
time: data.updated || new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
function animateCircleRadius(targetRadius) {
|
||||
|
||||
Reference in New Issue
Block a user