auto-sync: 2026-05-06 11:10:01
This commit is contained in:
@@ -725,6 +725,12 @@ body.has-map-mode #sheet-backdrop.visible { pointer-events: none; }
|
||||
}
|
||||
.mini-add-btn:active { opacity: 0.8; transform: scale(0.94); }
|
||||
|
||||
/* ── Route onboarding mini-bar ───────────────── */
|
||||
#mini-onboard-pin svg {
|
||||
width: 22px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
#sheet-route-mini { left: 72px; width: 380px; right: auto; border-radius: 0 14px 0 0; }
|
||||
}
|
||||
|
||||
124
tasks/enduro-trails/prototype/static/app.js
vendored
124
tasks/enduro-trails/prototype/static/app.js
vendored
@@ -411,13 +411,13 @@ function toggleRouteMode() {
|
||||
clearRoute();
|
||||
window._map.getCanvas().style.cursor = '';
|
||||
} else {
|
||||
// Enter route mode - do NOT open sheet
|
||||
// Enter route mode - show onboarding mini-bar instead of full sheet
|
||||
deactivateAllModes();
|
||||
routeMode = true;
|
||||
btn.classList.add('active');
|
||||
clearRoute();
|
||||
window._map.getCanvas().style.cursor = 'crosshair';
|
||||
openSheet('sheet-route');
|
||||
showRouteOnboardingMini();
|
||||
}
|
||||
updateMapModeClass();
|
||||
}
|
||||
@@ -442,6 +442,7 @@ function clearRoute() {
|
||||
document.getElementById('route-cards').innerHTML = '';
|
||||
document.getElementById('waypoints-list').innerHTML = '';
|
||||
if (routeMode && map) map.getCanvas().style.cursor = 'crosshair';
|
||||
hideMiniOnboard();
|
||||
}
|
||||
|
||||
function addWaypointMode() {
|
||||
@@ -1487,9 +1488,11 @@ function initRouteClicks(map) {
|
||||
routeWaypoints.push({ lon: lng, lat: lat });
|
||||
rebuildWaypointMarkers(); renderWaypointsList();
|
||||
document.getElementById('route-status').textContent = 'Тапни точку финиша';
|
||||
showRouteOnboardingMini(); // switch to finish prompt
|
||||
} else if (routeWaypoints.length === 1) {
|
||||
routeWaypoints.push({ lon: lng, lat: lat });
|
||||
rebuildWaypointMarkers(); renderWaypointsList();
|
||||
hideMiniOnboard();
|
||||
buildRoute();
|
||||
}
|
||||
});
|
||||
@@ -2321,6 +2324,123 @@ function miniAddWaypoint() {
|
||||
if (statsEl) statsEl.textContent = 'Тапни на карте для добавления точки';
|
||||
}
|
||||
|
||||
function showRouteOnboardingMini() {
|
||||
if (routeWaypoints.length >= 2) {
|
||||
hideMiniOnboard();
|
||||
showMiniRouteSheet();
|
||||
return;
|
||||
}
|
||||
const isStart = routeWaypoints.length === 0;
|
||||
const label = isStart ? 'S' : 'F';
|
||||
const color = isStart ? '#2EA043' : '#FF3B1F';
|
||||
const hint = isStart ? 'Тапни на карте — старт' : 'Тапни на карте — финиш';
|
||||
|
||||
// Show onboarding div, hide normal mini-bar content
|
||||
document.getElementById('mini-onboard').style.display = 'flex';
|
||||
document.getElementById('mini-dot').style.display = 'none';
|
||||
document.getElementById('mini-label').style.display = 'none';
|
||||
document.getElementById('mini-stats').style.display = 'none';
|
||||
document.getElementById('mini-wheel').style.display = 'none';
|
||||
const arrows = document.querySelector('.mini-route-arrows');
|
||||
if (arrows) arrows.style.display = 'none';
|
||||
const addBtn = document.getElementById('mini-add-btn');
|
||||
if (addBtn) addBtn.style.display = 'none';
|
||||
|
||||
// Set pin and hint
|
||||
document.getElementById('mini-onboard-pin').innerHTML = waypointPinSvg(label, color);
|
||||
document.getElementById('mini-onboard-hint').textContent = hint;
|
||||
|
||||
// Show mini-bar and raise map controls
|
||||
document.getElementById('sheet-route-mini').classList.add('visible');
|
||||
const ctrl = document.getElementById('map-controls-r');
|
||||
if (ctrl) ctrl.style.bottom = '148px';
|
||||
|
||||
// Search button handler
|
||||
const searchBtn = document.getElementById('mini-onboard-search-btn');
|
||||
searchBtn.onclick = () => toggleMiniOnboardSearch(isStart ? 'start' : 'finish');
|
||||
}
|
||||
|
||||
function hideMiniOnboard() {
|
||||
document.getElementById('mini-onboard').style.display = 'none';
|
||||
document.getElementById('mini-onboard-search-panel').style.display = 'none';
|
||||
// Restore normal mini-bar elements
|
||||
document.getElementById('mini-dot').style.display = '';
|
||||
document.getElementById('mini-label').style.display = '';
|
||||
document.getElementById('mini-stats').style.display = '';
|
||||
document.getElementById('mini-wheel').style.display = '';
|
||||
const arrows = document.querySelector('.mini-route-arrows');
|
||||
if (arrows) arrows.style.display = '';
|
||||
const addBtn = document.getElementById('mini-add-btn');
|
||||
if (addBtn) addBtn.style.display = '';
|
||||
}
|
||||
|
||||
function toggleMiniOnboardSearch(type) {
|
||||
const panel = document.getElementById('mini-onboard-search-panel');
|
||||
const isVisible = panel.style.display !== 'none';
|
||||
if (isVisible) {
|
||||
panel.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
panel.style.display = 'block';
|
||||
const input = document.getElementById('mini-onboard-search-input');
|
||||
input.value = '';
|
||||
document.getElementById('mini-onboard-search-results').innerHTML = '';
|
||||
setTimeout(() => input.focus(), 50);
|
||||
|
||||
let timeout = null;
|
||||
input.oninput = () => {
|
||||
clearTimeout(timeout);
|
||||
const q = input.value.trim();
|
||||
const resultsEl = document.getElementById('mini-onboard-search-results');
|
||||
if (q.length < 2) { resultsEl.innerHTML = ''; return; }
|
||||
timeout = setTimeout(() => _doMiniOnboardSearch(type, q, resultsEl), 400);
|
||||
};
|
||||
}
|
||||
|
||||
async function _doMiniOnboardSearch(type, query, resultsEl) {
|
||||
resultsEl.innerHTML = '<div class="wl-search-result-item"><span style="color:var(--text3)">Поиск...</span></div>';
|
||||
try {
|
||||
const url = `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(query)}&format=json&limit=5&accept-language=ru`;
|
||||
const resp = await fetch(url);
|
||||
const data = await resp.json();
|
||||
if (!data.length) {
|
||||
resultsEl.innerHTML = '<div class="wl-search-result-item"><span style="color:var(--text3)">Ничего не найдено</span></div>';
|
||||
return;
|
||||
}
|
||||
resultsEl.innerHTML = data.map(item => {
|
||||
const parts = (item.display_name || '').split(', ');
|
||||
const name = parts[0];
|
||||
const sub = parts.slice(1, 3).join(', ');
|
||||
return `<div class="wl-search-result-item" onclick="_selectMiniOnboardResult('${type}', ${item.lat}, ${item.lon}, '${name.replace(/'/g, "\\'")}')">
|
||||
<div class="wl-search-result-name">${name}</div>
|
||||
${sub ? `<div class="wl-search-result-sub">${sub}</div>` : ''}
|
||||
</div>`;
|
||||
}).join('');
|
||||
} catch(e) {
|
||||
resultsEl.innerHTML = '<div class="wl-search-result-item"><span style="color:var(--red)">Ошибка</span></div>';
|
||||
}
|
||||
}
|
||||
|
||||
function _selectMiniOnboardResult(type, lat, lon, name) {
|
||||
const wp = { lat: parseFloat(lat), lon: parseFloat(lon) };
|
||||
if (type === 'start') {
|
||||
routeWaypoints.unshift(wp);
|
||||
} else {
|
||||
routeWaypoints.push(wp);
|
||||
}
|
||||
document.getElementById('mini-onboard-search-panel').style.display = 'none';
|
||||
rebuildWaypointMarkers();
|
||||
window._map.flyTo({ center: [parseFloat(lon), parseFloat(lat)], zoom: 12, duration: 600 });
|
||||
|
||||
if (routeWaypoints.length >= 2) {
|
||||
hideMiniOnboard();
|
||||
debounceBuildRoute();
|
||||
} else {
|
||||
showRouteOnboardingMini(); // update to finish prompt
|
||||
}
|
||||
updateMiniRouteCard();
|
||||
}
|
||||
|
||||
function showMiniRouteSheet() {
|
||||
if (!routeResults || routeResults.length === 0) return;
|
||||
updateMiniRouteCard();
|
||||
|
||||
@@ -229,6 +229,20 @@
|
||||
<div id="sheet-route-mini">
|
||||
<div class="mini-handle" id="mini-route-handle"></div>
|
||||
<div class="mini-route-info">
|
||||
<!-- Onboarding panel (shown before both waypoints are set) -->
|
||||
<div id="mini-onboard" style="display:none; align-items:center; gap:8px; width:100%;">
|
||||
<div id="mini-onboard-pin"></div>
|
||||
<span id="mini-onboard-hint" style="flex:1; font-size:13px; color:var(--text2);"></span>
|
||||
<button id="mini-onboard-search-btn" style="background:none;border:none;padding:4px 8px;cursor:pointer;color:var(--text2);">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Inline search panel for onboarding -->
|
||||
<div id="mini-onboard-search-panel" style="display:none; position:absolute; bottom:100%; left:0; right:0; background:var(--surface); border:1px solid var(--border); border-radius:8px 8px 0 0; padding:8px; z-index:300;">
|
||||
<input id="mini-onboard-search-input" type="text" placeholder="Поиск места..." autocomplete="off" autocorrect="off"
|
||||
style="width:100%; box-sizing:border-box; padding:8px 10px; border:1px solid var(--border); border-radius:6px; background:var(--surface2); color:var(--text); font-size:14px;">
|
||||
<div id="mini-onboard-search-results" style="max-height:200px; overflow-y:auto; margin-top:4px;"></div>
|
||||
</div>
|
||||
<!-- Moto wheel loading indicator -->
|
||||
<svg id="mini-wheel" class="moto-wheel" width="22" height="22" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- Обод -->
|
||||
|
||||
Reference in New Issue
Block a user