Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 7 additions & 29 deletions src/plugins/layers/addMinimizeToggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export function addMinimizeToggle(element, storageKey, options = {}) {
const {
contentClassName = 'panel-content',
buttonClassName = 'panel-minimize-btn',
titleColor = '#00b4ff',
getIsMinimized,
onToggle,
persist = true,
Expand All @@ -25,17 +24,9 @@ export function addMinimizeToggle(element, storageKey, options = {}) {
const header = element.firstElementChild;
if (!header) return;

const existingTitle = header.querySelector('[data-drag-handle="true"]');
const existingButton = header.querySelector(`.${buttonClassName}`);
const existingWrapper = element.querySelector(`.${contentClassName}`);

if (existingTitle) {
existingTitle.style.fontFamily = "'JetBrains Mono', monospace";
existingTitle.style.fontSize = '13px';
existingTitle.style.fontWeight = '700';
existingTitle.style.color = titleColor;
}

const readState = () => {
if (typeof getIsMinimized === 'function') return !!getIsMinimized();
return localStorage.getItem(minimizeKey) === 'true';
Expand All @@ -49,7 +40,8 @@ export function addMinimizeToggle(element, storageKey, options = {}) {
const syncState = (button, wrapper) => {
const isMinimized = readState();
wrapper.style.display = isMinimized ? 'none' : 'block';
button.innerHTML = isMinimized ? '▶' : '▼';
button.innerHTML = '▶';
button.style.transform = isMinimized ? 'rotate(0deg)' : 'rotate(90deg)';
element.style.cursor = isMinimized ? 'pointer' : 'default';
};

Expand All @@ -68,7 +60,8 @@ export function addMinimizeToggle(element, storageKey, options = {}) {
e.stopPropagation();
const next = existingWrapper.style.display !== 'none';
existingWrapper.style.display = next ? 'none' : 'block';
existingButton.innerHTML = next ? '▶' : '▼';
existingButton.innerHTML = '▶';
existingButton.style.transform = next ? 'rotate(90deg)' : 'rotate(0deg)';
element.style.cursor = next ? 'pointer' : 'default';
writeState(next);
},
Expand All @@ -87,23 +80,14 @@ export function addMinimizeToggle(element, storageKey, options = {}) {

const minimizeBtn = document.createElement('button');
minimizeBtn.className = buttonClassName;
minimizeBtn.innerHTML = '';
minimizeBtn.innerHTML = '';
minimizeBtn.style.cssText = `
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
min-width: 16px;
height: 16px;
background: none;
border: none;
color: #888;
cursor: pointer;
user-select: none;
padding: 2px 4px;
margin: 0;
font-size: 10px;
line-height: 1;
transform: rotate(0deg);
`;
minimizeBtn.title = 'Minimize/Maximize';
minimizeBtn.addEventListener(
Expand All @@ -122,12 +106,6 @@ export function addMinimizeToggle(element, storageKey, options = {}) {
title.textContent = header.textContent.replace(/[▼▶]/g, '').trim();
title.dataset.dragHandle = 'true';
title.style.flex = '1';
title.style.cursor = 'grab';
title.style.userSelect = 'none';
title.style.fontFamily = "'JetBrains Mono', monospace";
title.style.fontSize = '13px';
title.style.fontWeight = '700';
title.style.color = titleColor;

header.textContent = '';
header.appendChild(title);
Expand All @@ -141,7 +119,7 @@ export function addMinimizeToggle(element, storageKey, options = {}) {
e.stopPropagation();
const hidden = contentWrapper.style.display === 'none';
contentWrapper.style.display = hidden ? 'block' : 'none';
minimizeBtn.innerHTML = hidden ? '' : '';
minimizeBtn.style.transform = hidden ? 'rotate(90deg)' : 'rotate(0deg)';
element.style.cursor = hidden ? 'default' : 'pointer';
writeState(!hidden);
},
Expand Down
39 changes: 34 additions & 5 deletions src/plugins/layers/makeDraggable.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,22 @@ function clampToViewport(el, margin = 40) {
el.style.top = top + 'px';
}

export function makeDraggable(el, storageKey, skipPositionLoad = false) {
/**
* Helper for snapping to a grid
*/
function snapToGrid(value, gridSize) {
if (!gridSize) return value;
return Math.round(value / gridSize) * gridSize;
}

export function makeDraggable(
el,
storageKey,
{
skipPositionLoad = false,
snap = 0, // pixels; 0 disables snapping
} = {},
) {
if (!el) return;

// Cancel any previous listeners for this storageKey (e.g. after layout change)
Expand Down Expand Up @@ -142,6 +157,7 @@ export function makeDraggable(el, storageKey, skipPositionLoad = false) {
(e) => {
if (e.button !== 0) return;
isDragging = true;
updateCursor();
didDrag = false;
startX = e.clientX;
startY = e.clientY;
Expand All @@ -162,27 +178,40 @@ export function makeDraggable(el, storageKey, skipPositionLoad = false) {
'mousemove',
(e) => {
if (!isDragging) return;

if (!didDrag && (Math.abs(e.clientX - startX) > 2 || Math.abs(e.clientY - startY) > 2)) {
didDrag = true;
}
el.style.left = startLeft + (e.clientX - startX) + 'px';
el.style.top = startTop + (e.clientY - startY) + 'px';

let nextLeft = startLeft + (e.clientX - startX);
let nextTop = startTop + (e.clientY - startY);

// Snap to grid if enabled
nextLeft = snapToGrid(nextLeft, snap);
nextTop = snapToGrid(nextTop, snap);

el.style.left = nextLeft + 'px';
el.style.top = nextTop + 'px';
},
{ signal },
);

// --- Mouseup: stop drag, clamp, save ---
document.addEventListener(
'mouseup',
() => {
(e) => {
if (!isDragging) return;
isDragging = false;
el.style.opacity = '1';
el.style.transition = previousTransition;
updateCursor();
suppressClick = didDrag;

// Clamp so element can't be lost off-screen
if (snap) {
el.style.left = snapToGrid(el.offsetLeft, snap) + 'px';
el.style.top = snapToGrid(el.offsetTop, snap) + 'px';
}

clampToViewport(el);

const topPercent = (el.offsetTop / window.innerHeight) * 100;
Expand Down
20 changes: 5 additions & 15 deletions src/plugins/layers/useGrayLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,24 +286,14 @@ export function useLayer({ enabled = false, opacity = 0.5, map = null }) {
const GrayLineControl = L.Control.extend({
options: { position: 'topright' },
onAdd: function () {
const container = L.DomUtil.create('div', 'grayline-control');
container.style.cssText = `
background: var(--bg-panel);
padding: 12px;
border-radius: 5px;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
color: var(--text-primary);
border: 1px solid var(--border-color);
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
min-width: 200px;
`;
const panelWrapper = L.DomUtil.create('div', 'panel-wrapper');
const container = L.DomUtil.create('div', 'grayline-control', panelWrapper);

const now = new Date();
const timeStr = now.toUTCString();

container.innerHTML = `
<div style="font-family: 'JetBrains Mono', monospace; font-weight: 700; margin-bottom: 8px; font-size: 13px; color: #00b4ff;">🌅 Gray Line</div>
<div class="floating-panel-header">🌅 Gray Line</div>

<div style="margin-bottom: 8px; padding: 8px; background: var(--bg-tertiary); border-radius: 3px;">
<div style="font-size: 9px; opacity: 0.7; margin-bottom: 2px;">UTC TIME</div>
Expand Down Expand Up @@ -338,7 +328,7 @@ export function useLayer({ enabled = false, opacity = 0.5, map = null }) {
L.DomEvent.disableClickPropagation(container);
L.DomEvent.disableScrollPropagation(container);

return container;
return panelWrapper;
},
});

Expand All @@ -362,7 +352,7 @@ export function useLayer({ enabled = false, opacity = 0.5, map = null }) {
} catch (e) {}
}

makeDraggable(container, 'grayline-position');
makeDraggable(container, 'grayline-position', { snap: 5 });
addMinimizeToggle(container, 'grayline-position', {
contentClassName: 'grayline-panel-content',
buttonClassName: 'grayline-minimize-btn',
Expand Down
56 changes: 18 additions & 38 deletions src/plugins/layers/useLightning.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,19 +444,11 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null, lowMemory
options: { position: 'topright' },
onAdd: function () {
console.log('[Lightning] StatsControl onAdd called');
const div = L.DomUtil.create('div', 'lightning-stats');
div.style.cssText = `
background: var(--bg-panel);
padding: 10px;
border-radius: 8px;
border: 1px solid var(--border-color);
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
color: var(--text-primary);
min-width: 180px;
`;
const panelWrapper = L.DomUtil.create('div', 'panel-wrapper');
const div = L.DomUtil.create('div', 'lightning-stats', panelWrapper);

div.innerHTML = `
<div data-drag-handle="true" style="font-family: 'JetBrains Mono', monospace; font-weight: 700; font-size: 13px; margin-bottom: 8px; cursor: grab; user-select: none; color: #00b4ff;">⚡️ Lightning Activity</div>
<div class="floating-panel-header">⚡️ Lightning Activity</div>
<div style="opacity: 0.7; font-size: 10px;">Connecting...</div>
`;

Expand All @@ -465,7 +457,7 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null, lowMemory
L.DomEvent.disableScrollPropagation(div);

console.log('[Lightning] Stats panel div created');
return div;
return panelWrapper;
},
});

Expand Down Expand Up @@ -495,7 +487,7 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null, lowMemory
}
}

makeDraggable(container, 'lightning-stats-position');
makeDraggable(container, 'lightning-stats-position', { snap: 5 });
addMinimizeToggle(container, 'lightning-stats-position', {
contentClassName: 'lightning-panel-content',
buttonClassName: 'lightning-minimize-btn',
Expand Down Expand Up @@ -692,28 +684,17 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null, lowMemory
const ProximityControl = L.Control.extend({
options: { position: 'bottomright' },
onAdd: function () {
const div = L.DomUtil.create('div', 'lightning-proximity');
div.style.cssText = `
background: var(--bg-panel);
padding: 10px;
border-radius: 8px;
border: 1px solid var(--border-color);
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
color: var(--text-primary);
min-width: 200px;
max-width: 280px;
`;
div.innerHTML = `
<div data-drag-handle="true" style="font-family: 'JetBrains Mono', monospace; font-weight: 700; font-size: 13px; margin-bottom: 8px; cursor: grab; user-select: none; color: #00b4ff;">📍 Nearby Strikes (30km)</div>
<div style="opacity: 0.7; font-size: 10px;">No recent strikes</div>
`;
const panelWrapper = L.DomUtil.create('div', 'panel-wrapper');
const div = L.DomUtil.create('div', 'lightning-proximity', panelWrapper);

div.innerHTML =
'<div class="floating-panel-header">📍 Nearby Strikes (30km)</div><div style="opacity: 0.7; font-size: 10px; text-align: center;">No recent strikes</div>';

// Prevent map interaction
L.DomEvent.disableClickPropagation(div);
L.DomEvent.disableScrollPropagation(div);

return div;
return panelWrapper;
},
});

Expand All @@ -737,9 +718,8 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null, lowMemory

// Default to CENTER of screen (not corner!)
container.style.position = 'fixed';
container.style.top = '50%';
container.style.left = '50%';
container.style.transform = 'translate(-50%, -50%)';
container.style.top = '45%'; // NOTE: using 45% instead of 50% with transform: translateX/Y due to dragging issues
container.style.left = '45%';
container.style.right = 'auto';
container.style.bottom = 'auto';
container.style.zIndex = '1001'; // Ensure it's on top
Expand Down Expand Up @@ -780,7 +760,7 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null, lowMemory
positionLoaded = true;
console.log('[Lightning] Proximity: Converted pixel to percentage:', { topPercent, leftPercent });
} else {
console.log('[Lightning] Proximity: Saved pixel position off-screen, using center');
console.log('[Lightning] Proximity: Saved pixel position off-screen, using default');
localStorage.removeItem('lightning-proximity-position');
}
}
Expand All @@ -790,7 +770,7 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null, lowMemory
}

// Make draggable - pass flag to skip position loading since we already did it
makeDraggable(container, 'lightning-proximity-position', positionLoaded);
makeDraggable(container, 'lightning-proximity-position', { skipPositionLoad: positionLoaded, snap: 5 });
addMinimizeToggle(container, 'lightning-proximity-position', {
contentClassName: 'lightning-panel-content',
buttonClassName: 'lightning-minimize-btn',
Expand Down Expand Up @@ -858,8 +838,8 @@ export function useLayer({ enabled = false, opacity = 0.9, map = null, lowMemory

if (nearbyStrikes.length === 0) {
contentHTML = `
<div style="opacity: 0.7; font-size: 10px; text-align: center; padding: 10px 0;">
✅ No strikes within 30km<br>
<div style="font-size: 10px; text-align: center;">
✅ No strikes within 30km<br/>
<span style="font-size: 9px; color: var(--text-muted);">All clear</span>
</div>
`;
Expand Down
Loading