auto-sync: 2026-05-05 19:40:01
This commit is contained in:
@@ -409,6 +409,41 @@ body.has-map-mode #sheet-backdrop.visible { pointer-events: none; }
|
||||
#no-data-warning { display: none; position: fixed; bottom: 80px; left: 12px; right: 12px; background: var(--red-bg); border: 1px solid var(--red); border-radius: 12px; padding: 10px 14px; font-size: 13px; color: var(--red); z-index: 200; }
|
||||
#no-data-warning.visible { display: block; }
|
||||
|
||||
/* ── Share Dialog (bottom sheet style) ────────── */
|
||||
#share-dialog { position: fixed; inset: 0; z-index: 600; display: flex; align-items: flex-end; justify-content: center; }
|
||||
.share-dialog-backdrop { position: fixed; inset: 0; background: var(--overlay); }
|
||||
.share-dialog {
|
||||
position: relative; width: 100%; max-width: 420px;
|
||||
background: var(--surface);
|
||||
border-radius: 20px 20px 0 0;
|
||||
padding: 0 16px calc(20px + env(safe-area-inset-bottom, 0px));
|
||||
z-index: 1;
|
||||
box-shadow: 0 -4px 24px var(--shadow);
|
||||
animation: shareSheetUp 0.25s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
@keyframes shareSheetUp {
|
||||
from { transform: translateY(100%); } to { transform: translateY(0); }
|
||||
}
|
||||
.share-dialog .sd-handle { width: 36px; height: 4px; background: var(--border); border-radius: 2px; margin: 12px auto 12px; }
|
||||
.share-dialog .sd-title { font-size: 16px; font-weight: 700; color: var(--text); text-align: center; margin-bottom: 4px; }
|
||||
.share-dialog .sd-desc { font-size: 13px; color: var(--text2); text-align: center; margin-bottom: 14px; }
|
||||
.share-dialog .sd-row { display: flex; gap: 8px; margin-bottom: 8px; }
|
||||
.share-dialog .sd-btn {
|
||||
flex: 1; height: 48px; border: none; border-radius: 14px;
|
||||
background: var(--surface2); color: var(--text);
|
||||
font-size: 14px; font-weight: 600; cursor: pointer;
|
||||
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
|
||||
transition: background 0.15s, transform 0.1s;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.share-dialog .sd-btn:active { transform: scale(0.97); background: var(--surface3); }
|
||||
.share-dialog .sd-btn .sd-icon { font-size: 20px; line-height: 1; }
|
||||
.share-dialog .sd-btn-primary { background: var(--accent); color: #fff; }
|
||||
.share-dialog .sd-btn-primary:active { background: var(--accent-hover); }
|
||||
.share-dialog .sd-btn-full { width: 100%; flex: none; margin-bottom: 8px; }
|
||||
.share-dialog .sd-cancel { background: var(--surface2); color: var(--text2); }
|
||||
.share-dialog .sd-cancel:active { background: var(--surface3); }
|
||||
|
||||
/* ── Skeleton Loading ────────────────────────── */
|
||||
.skeleton {
|
||||
background: linear-gradient(90deg, var(--surface2) 0%, var(--surface3) 50%, var(--surface2) 100%);
|
||||
|
||||
66
tasks/enduro-trails/prototype/static/app.js
vendored
66
tasks/enduro-trails/prototype/static/app.js
vendored
@@ -802,30 +802,52 @@ async function shareRoute() {
|
||||
|
||||
const distKm = (route.distance_m / 1000).toFixed(0);
|
||||
const dirtPct = route.stats ? route.stats.dirt_total_pct : 0;
|
||||
const shareText = `Маршрут: ${distKm} км, ${dirtPct}% грунт`;
|
||||
const gpx = generateGPX();
|
||||
const blob = new Blob([gpx], { type: 'application/gpx+xml' });
|
||||
const file = new File([blob], 'enduro-route.gpx', { type: 'application/gpx+xml' });
|
||||
const shareText = `Эндуро маршрут: ${distKm} км, ${dirtPct}% грунт`;
|
||||
|
||||
// 1. File share (HTTPS only)
|
||||
if (navigator.share && location.protocol === 'https:') {
|
||||
try {
|
||||
const canShare = navigator.canShare && navigator.canShare({ files: [file] });
|
||||
if (canShare) {
|
||||
await navigator.share({ title: 'Enduro Route', text: shareText, files: [file] });
|
||||
return;
|
||||
}
|
||||
// canShare rejected files → share text only
|
||||
await navigator.share({ title: 'Enduro Route', text: shareText });
|
||||
return;
|
||||
} catch(e) {
|
||||
if (e.name === 'AbortError') return;
|
||||
console.warn('Share failed, falling back to download:', e);
|
||||
}
|
||||
const dialog = document.getElementById('share-dialog');
|
||||
if (dialog) dialog.remove();
|
||||
|
||||
const d = document.createElement('div');
|
||||
d.id = 'share-dialog';
|
||||
d.innerHTML = `
|
||||
<div class="sd-backdrop" onclick="closeShareDialog()"></div>
|
||||
<div class="sd-sheet">
|
||||
<div class="sd-handle"></div>
|
||||
<div class="sd-title">Поделиться маршрутом</div>
|
||||
<div class="sd-desc">${shareText}</div>
|
||||
<div class="sd-btn-row">
|
||||
<button class="sd-btn sd-btn-primary" onclick="shareTelegram()"><span class="sd-icon">✈️</span> Telegram</button>
|
||||
<button class="sd-btn sd-btn-primary" onclick="shareWhatsApp()"><span class="sd-icon">💬</span> WhatsApp</button>
|
||||
</div>
|
||||
<button class="sd-btn sd-btn-full" onclick="downloadGPX(); closeShareDialog();"><span class="sd-icon">⬇️</span> Скачать GPX файл</button>
|
||||
<button class="sd-btn sd-cancel" onclick="closeShareDialog()">Отмена</button>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(d);
|
||||
}
|
||||
|
||||
function closeShareDialog() {
|
||||
const el = document.getElementById('share-dialog');
|
||||
if (el) el.remove();
|
||||
}
|
||||
|
||||
function shareTelegram() {
|
||||
const url = 'https://t.me/share/url?url=' + encodeURIComponent(window.location.href) + '&text=' + encodeURIComponent('Маршрут эндуро: ' + window.location.href);
|
||||
window.open(url, '_blank');
|
||||
closeShareDialog();
|
||||
}
|
||||
|
||||
function shareWhatsApp() {
|
||||
const url = 'https://wa.me/?text=' + encodeURIComponent('Маршрут эндуро: ' + window.location.href);
|
||||
window.open(url, '_blank');
|
||||
closeShareDialog();
|
||||
}
|
||||
|
||||
function shareNative() {
|
||||
closeShareDialog();
|
||||
if (navigator.share) {
|
||||
navigator.share({ title: 'Enduro Route', text: window.location.href }).catch(() => {});
|
||||
}
|
||||
|
||||
// 2. HTTPS unavailable → download GPX directly
|
||||
downloadGPX();
|
||||
}
|
||||
|
||||
// ─── Флажки / именованные метки ────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user