auto-sync: 2026-05-05 15:40:01

This commit is contained in:
Stream
2026-05-05 15:40:01 +03:00
parent dd4ed959ab
commit 665baab132
3 changed files with 167 additions and 3 deletions

View File

@@ -552,3 +552,79 @@ body.has-map-mode #sheet-backdrop.visible { pointer-events: none; }
#btn-build-route:active { background: var(--accent-h); }
.search-result-name { font-size: 14px; font-weight: 500; color: var(--text); }
.search-result-detail { font-size: 12px; color: var(--text2); margin-top: 2px; }
/* ── Mini route sheet ─────────────────────────────────────────── */
#sheet-route-mini {
position: fixed;
bottom: 72px; /* above toolbar */
left: 0; right: 0;
height: 80px;
background: var(--surface);
border-top: 1px solid var(--border);
border-radius: 16px 16px 0 0;
z-index: 350;
display: none;
flex-direction: column;
box-shadow: 0 -4px 20px var(--shadow);
}
#sheet-route-mini.visible { display: flex; }
.mini-handle {
width: 36px; height: 4px;
background: var(--border);
border-radius: 2px;
margin: 8px auto 4px;
flex-shrink: 0;
cursor: pointer;
}
.mini-cards-row {
display: flex;
gap: 8px;
overflow-x: auto;
padding: 0 12px 10px;
scrollbar-width: none;
flex: 1;
align-items: center;
}
.mini-cards-row::-webkit-scrollbar { display: none; }
.mini-route-card {
display: flex;
align-items: center;
gap: 8px;
background: var(--surface2);
border: 1.5px solid var(--border);
border-radius: 10px;
padding: 6px 12px;
flex-shrink: 0;
cursor: pointer;
transition: border-color 0.15s;
white-space: nowrap;
}
.mini-route-card.active {
border-color: var(--accent);
background: var(--accent-bg);
}
.mini-route-dot {
width: 10px; height: 10px;
border-radius: 50%;
flex-shrink: 0;
}
.mini-route-label {
font-size: 13px; font-weight: 600;
color: var(--text);
}
.mini-route-stats {
font-size: 11px;
color: var(--text2);
}
@media (min-width: 768px) {
#sheet-route-mini {
left: 72px;
width: 380px;
right: auto;
border-radius: 0 16px 0 0;
}
}

View File

@@ -204,6 +204,9 @@ function closeSheet(id) {
// Close sheet panel but keep the mode active (route stays on map)
function minimizeSheet(id) {
closeSheet(id);
if (id === 'sheet-route' && routeResults.length > 0) {
showMiniRouteSheet();
}
}
function closeAllSheets() {
@@ -399,9 +402,8 @@ function toggleRouteMode() {
closeSheet('sheet-route');
window._map.getCanvas().style.cursor = '';
} else if (routeResults.length > 0) {
// Not in input mode, but route exists on map → clear it and start fresh
clearRoute();
// Now enter input mode
// Route exists — show full panel (hide mini first)
hideMiniRouteSheet();
deactivateAllModes();
routeMode = true;
btn.classList.add('active');
@@ -409,6 +411,7 @@ function toggleRouteMode() {
window._map.getCanvas().style.cursor = 'crosshair';
} else {
// No route, not in mode → enter route input mode
hideMiniRouteSheet();
deactivateAllModes();
routeMode = true;
btn.classList.add('active');
@@ -420,6 +423,7 @@ function toggleRouteMode() {
}
function clearRoute() {
hideMiniRouteSheet();
waypointMarkers.forEach(m => m.remove());
waypointMarkers = [];
routeWaypoints = [];
@@ -618,6 +622,10 @@ function drawRouteResults(routes, activeIdx) {
});
renderRouteCards(routes);
// Update mini sheet if visible
const miniEl = document.getElementById('sheet-route-mini');
if (miniEl && miniEl.classList.contains('visible')) showMiniRouteSheet();
}
function selectRoute(idx) {
@@ -1603,3 +1611,77 @@ document.addEventListener('DOMContentLoaded', () => {
// Apply saved theme immediately (before map loads)
applyTheme();
});
// ─── Mini route sheet ──────────────────────────────────────────────
function showMiniRouteSheet() {
if (routeResults.length === 0) return;
const mini = document.getElementById('sheet-route-mini');
const row = document.getElementById('mini-route-cards');
row.innerHTML = routeResults.map((r, i) => {
const km = (r.distance_m / 1000).toFixed(0);
const dirt = r.stats?.dirt_total_pct ?? '?';
const color = ROUTE_COLORS[i] || '#888888';
const active = i === activeRouteIdx ? 'active' : '';
return `<div class="mini-route-card ${active}" onclick="selectRouteFromMini(${i})">
<div class="mini-route-dot" style="background:${color}"></div>
<div>
<div class="mini-route-label">Вариант ${i + 1}</div>
<div class="mini-route-stats">${km} км · ${dirt}% грунт</div>
</div>
</div>`;
}).join('');
mini.classList.add('visible');
initMiniSheetSwipe();
}
function hideMiniRouteSheet() {
const mini = document.getElementById('sheet-route-mini');
if (mini) mini.classList.remove('visible');
}
function selectRouteFromMini(idx) {
activeRouteIdx = idx;
const map = window._map;
for (let i = 0; i < routeResults.length; i++) {
const isActive = i === idx;
try {
if (map.getLayer('route-line-' + i)) {
map.setPaintProperty('route-line-' + i, 'line-width', isActive ? 5 : 3);
map.setPaintProperty('route-line-' + i, 'line-opacity', isActive ? 0.95 : 0.5);
}
if (map.getLayer('route-line-' + i + '-outline')) {
map.setPaintProperty('route-line-' + i + '-outline', 'line-width', isActive ? 7 : 4);
map.setPaintProperty('route-line-' + i + '-outline', 'line-opacity', isActive ? 0.6 : 0);
}
} catch(e) {}
}
// Update mini cards active state
document.querySelectorAll('.mini-route-card').forEach((c, i) => {
c.classList.toggle('active', i === idx);
});
}
function initMiniSheetSwipe() {
const handle = document.getElementById('mini-route-handle');
if (!handle) return;
// Remove old listeners by cloning
const newHandle = handle.cloneNode(true);
handle.parentNode.replaceChild(newHandle, handle);
let startY = 0;
newHandle.addEventListener('touchstart', e => { startY = e.touches[0].clientY; }, { passive: true });
newHandle.addEventListener('touchend', e => {
const dy = e.changedTouches[0].clientY - startY;
if (dy < -40) {
// Swipe up → expand full sheet
hideMiniRouteSheet();
openSheet('sheet-route');
}
});
// Tap on handle = expand
newHandle.addEventListener('click', () => {
hideMiniRouteSheet();
openSheet('sheet-route');
});
}

View File

@@ -229,6 +229,12 @@
</button>
</nav>
<!-- Mini route sheet -->
<div id="sheet-route-mini">
<div class="mini-handle" id="mini-route-handle"></div>
<div class="mini-cards-row" id="mini-route-cards"></div>
</div>
<!-- Scripts -->
<script src="https://unpkg.com/maplibre-gl@4.7.0/dist/maplibre-gl.js"></script>
<script src="https://unpkg.com/suncalc@1.9.0/suncalc.min.js"></script>