mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-04-28 22:25:31 +00:00
fix: comprehensive mobile responsive fixes for all pages
Live page (priority): - Fix feed panel max-height from 180px to 40vh (was clipping content) - Fix VCR bar: bump breakpoint from 600px to 640px, hide LCD, ensure no wrapping, increase touch targets to 44px min - Remove rogue ≤600px rules that hid feed/legend/toggle entirely - Fix legend toggle: was using inverted logic (legend-mobile-hidden toggled off instead of legend-mobile-visible toggled on) - Header: constrain width to viewport, reduce padding/font on mobile - Feed detail card: add max-height 50vh + overflow-y auto to prevent clipping off screen - Disable feed resize handle on mobile (not practical for touch) - Ensure Leaflet zoom controls clear mobile header Packets page: - panel-left gets min-height 50vh + overflow-x with -webkit touch scrolling - data-table gets min-width 500px so it scrolls horizontally instead of collapsing columns to nothing - panel-right removes max-height 50vh cap (was hiding detail panel) - Filter bar buttons get 44px min touch target - Node filter wrap goes full width Nodes page: - Node count pills wrap properly - Smaller font on count pills for narrow screens Analytics pages: - analytics-grid goes single column on mobile - analytics-page reduces padding Style fixes (global): - Filter bar gap reduced to 4px on mobile - All cache busters updated
This commit is contained in:
+3
-3
@@ -20,9 +20,9 @@
|
||||
<meta name="twitter:title" content="MeshCore Analyzer">
|
||||
<meta name="twitter:description" content="Real-time MeshCore LoRa mesh network analyzer — live packet visualization, node tracking, channel decryption, and route analysis.">
|
||||
<meta name="twitter:image" content="https://raw.githubusercontent.com/Kpa-clawbot/meshcore-analyzer/master/public/og-image.png">
|
||||
<link rel="stylesheet" href="style.css?v=1773963309">
|
||||
<link rel="stylesheet" href="style.css?v=1773963867">
|
||||
<link rel="stylesheet" href="home.css">
|
||||
<link rel="stylesheet" href="live.css?v=1773963702">
|
||||
<link rel="stylesheet" href="live.css?v=1773963867">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||
crossorigin="anonymous">
|
||||
@@ -84,7 +84,7 @@
|
||||
<script src="nodes.js?v=1773961950" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="traces.js?v=1774079160" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="analytics.js?v=1773961035" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="live.js?v=1773963609" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="live.js?v=1773963867" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="observers.js?v=1774079160" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="node-analytics.js?v=1773961276" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
</body>
|
||||
|
||||
+32
-16
@@ -254,14 +254,20 @@
|
||||
|
||||
/* ---- Responsive ---- */
|
||||
@media (max-width: 640px) {
|
||||
.live-feed { width: calc(100vw - 24px); max-height: 180px; }
|
||||
.live-legend { display: none; }
|
||||
.live-legend.legend-mobile-hidden { display: none !important; }
|
||||
.live-feed { width: calc(100vw - 24px); max-height: 40vh; }
|
||||
/* Legend: hidden by default on mobile, toggle button shows it */
|
||||
.live-legend { display: none !important; }
|
||||
.live-legend.legend-mobile-visible { display: flex !important; }
|
||||
.legend-toggle-btn { display: block !important; }
|
||||
.live-legend:not(.legend-mobile-hidden) { display: flex !important; }
|
||||
.live-header { flex-wrap: wrap; gap: 8px; }
|
||||
.live-stats-row { flex-wrap: wrap; }
|
||||
.live-header { flex-wrap: wrap; gap: 6px; }
|
||||
/* Header: compact on mobile */
|
||||
.live-header {
|
||||
flex-wrap: wrap; gap: 6px; padding: 6px 10px;
|
||||
top: 56px; left: 8px; right: 8px; max-width: calc(100vw - 16px);
|
||||
}
|
||||
.live-stats-row { flex-wrap: wrap; gap: 4px; }
|
||||
.live-stat-pill { font-size: 11px; padding: 2px 7px; }
|
||||
.live-toggles { font-size: 10px; gap: 6px; margin-left: 0; }
|
||||
.live-title { font-size: 12px; letter-spacing: 1px; }
|
||||
/* Feed detail card as bottom sheet on mobile (#61) */
|
||||
.feed-detail-card {
|
||||
position: fixed !important;
|
||||
@@ -272,10 +278,20 @@
|
||||
transform: none !important;
|
||||
width: 100% !important;
|
||||
max-width: 100vw !important;
|
||||
max-height: 50vh !important;
|
||||
overflow-y: auto !important;
|
||||
border-radius: 10px 10px 0 0 !important;
|
||||
animation: slideUp 0.2s ease-out !important;
|
||||
}
|
||||
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
|
||||
/* Touch targets */
|
||||
.feed-hide-btn { width: 36px; height: 36px; font-size: 16px; }
|
||||
.feed-show-btn { padding: 10px 12px; min-width: 44px; min-height: 44px; }
|
||||
.legend-toggle-btn { min-width: 44px; min-height: 44px; }
|
||||
/* Feed resize handle: disable on mobile (can't drag easily) */
|
||||
.feed-resize-handle { display: none; }
|
||||
/* Leaflet zoom controls */
|
||||
.live-page .leaflet-top.leaflet-right { top: 56px; }
|
||||
}
|
||||
|
||||
/* Feed item hover */
|
||||
@@ -605,15 +621,15 @@
|
||||
.feed-show-btn { bottom: 68px !important; }
|
||||
|
||||
/* Mobile VCR */
|
||||
@media (max-width: 600px) {
|
||||
.vcr-bar { padding: 4px 6px; overflow-x: auto; flex-wrap: nowrap; }
|
||||
.vcr-btn { padding: 6px 10px; font-size: 0.8rem; min-height: 36px; min-width: 36px; }
|
||||
.vcr-scope-btn { font-size: 0.7rem; padding: 4px 8px; min-height: 36px; }
|
||||
.vcr-lcd { display: flex; }
|
||||
.live-feed { display: none; }
|
||||
.feed-show-btn { display: none !important; }
|
||||
.live-legend { display: none; }
|
||||
.legend-toggle-btn { display: none !important; }
|
||||
@media (max-width: 640px) {
|
||||
.vcr-bar { padding: 4px 6px; overflow: hidden; flex-wrap: nowrap; }
|
||||
.vcr-btn { padding: 6px 8px; font-size: 0.8rem; min-height: 44px; min-width: 44px; }
|
||||
.vcr-scope-btns { gap: 1px; }
|
||||
.vcr-scope-btn { font-size: 0.65rem; padding: 4px 6px; min-height: 36px; }
|
||||
.vcr-lcd { display: none; }
|
||||
.vcr-mode { font-size: 0.65rem; padding: 2px 6px; }
|
||||
.vcr-timeline-container { min-width: 60px; }
|
||||
.vcr-prompt { font-size: 0.7rem; }
|
||||
}
|
||||
|
||||
/* Timeline time tooltip */
|
||||
|
||||
+3
-3
@@ -729,9 +729,9 @@
|
||||
const legendToggleBtn = document.getElementById('legendToggleBtn');
|
||||
if (legendToggleBtn && legendEl) {
|
||||
legendToggleBtn.addEventListener('click', () => {
|
||||
const isHidden = legendEl.classList.toggle('legend-mobile-hidden');
|
||||
legendToggleBtn.setAttribute('aria-label', isHidden ? 'Show legend' : 'Hide legend');
|
||||
legendToggleBtn.textContent = isHidden ? '🎨' : '✕';
|
||||
const isVisible = legendEl.classList.toggle('legend-mobile-visible');
|
||||
legendToggleBtn.setAttribute('aria-label', isVisible ? 'Hide legend' : 'Show legend');
|
||||
legendToggleBtn.textContent = isVisible ? '✕' : '🎨';
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+12
-5
@@ -811,8 +811,8 @@ button.ch-item.selected { background: var(--selected-bg); }
|
||||
|
||||
/* Layouts: stack instead of side-by-side */
|
||||
.split-layout { flex-direction: column; overflow-y: auto; }
|
||||
.panel-left { padding: 10px; }
|
||||
.panel-right { width: 100%; min-width: 0; border-left: none; border-top: 1px solid var(--border); max-height: 50vh; }
|
||||
.panel-left { padding: 10px; flex: none; min-height: 50vh; overflow-x: auto; }
|
||||
.panel-right { width: 100%; min-width: 0; border-left: none; border-top: 1px solid var(--border); max-height: none; flex: none; }
|
||||
|
||||
/* Channels: Discord-style full screen toggle */
|
||||
.ch-layout { flex-direction: row; position: relative; }
|
||||
@@ -834,16 +834,21 @@ button.ch-item.selected { background: var(--selected-bg); }
|
||||
.data-table { font-size: 12px; }
|
||||
.data-table td { padding: 6px 6px; max-width: 120px; }
|
||||
.data-table th { padding: 6px 6px; font-size: 11px; }
|
||||
.panel-left { overflow-x: auto; }
|
||||
.panel-left { overflow-x: auto; -webkit-overflow-scrolling: touch; }
|
||||
.data-table { min-width: 500px; }
|
||||
|
||||
/* Filters: full width */
|
||||
.filter-bar { flex-direction: column; }
|
||||
.filter-bar { flex-direction: column; gap: 4px; }
|
||||
.filter-bar input { width: 100%; }
|
||||
.filter-bar select { width: 100%; }
|
||||
.filter-bar .btn { min-height: 44px; }
|
||||
.node-filter-wrap { width: 100%; }
|
||||
|
||||
/* Nodes */
|
||||
.nodes-topbar { flex-direction: column; gap: 8px; padding: 10px; }
|
||||
.nodes-tabs-bar { flex-direction: column; }
|
||||
.nodes-counts { flex-wrap: wrap; }
|
||||
.node-count-pill { font-size: 11px; padding: 2px 8px; }
|
||||
|
||||
/* Traces */
|
||||
.trace-summary { flex-direction: column; }
|
||||
@@ -854,7 +859,7 @@ button.ch-item.selected { background: var(--selected-bg); }
|
||||
.search-overlay { padding-top: 60px; }
|
||||
|
||||
/* Map controls */
|
||||
.map-controls { width: calc(100vw - 24px); right: 12px; top: 8px; max-height: 200px; }
|
||||
.map-controls { width: calc(100vw - 24px); right: 12px; top: 8px; max-height: 200px; font-size: 12px; padding: 10px 12px; }
|
||||
#leaflet-map { z-index: 0; }
|
||||
#map-wrap { z-index: 0; }
|
||||
|
||||
@@ -1087,6 +1092,8 @@ button.ch-item.ch-item-encrypted .ch-badge { filter: grayscale(0.6); }
|
||||
.stats-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
.repeater-name { min-width: 80px; }
|
||||
.reach-ring { flex-wrap: wrap; }
|
||||
.analytics-page { padding: 12px; }
|
||||
.analytics-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
.observer-selector { display: flex; gap: 4px; margin-bottom: 12px; flex-wrap: wrap; }
|
||||
.node-qr { text-align: center; margin-top: 8px; }
|
||||
|
||||
Reference in New Issue
Block a user