feat(rcal): docked map layout + theme-aware tiles; emoji tab badges
- rCal: default map to docked (side-by-side) layout instead of floating overlay - rCal: switch map tiles between Voyager (light) and dark_all (dark) based on theme - rCal: boost dark mode map brightness/contrast for readability - rCal: watch for theme changes via MutationObserver for live tile swapping - Tab bar: replace text badges with emoji icons, fix badge colors for light themes - App switcher: fix badge text color to dark for gradient backgrounds Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2131d79f38
commit
53af7fc057
|
|
@ -130,7 +130,8 @@ class FolkCalendarView extends HTMLElement {
|
|||
private zoomCoupled = true;
|
||||
|
||||
// Map panel state (replaces old tab system)
|
||||
private mapPanelState: "minimized" | "floating" | "docked" = "floating";
|
||||
private mapPanelState: "minimized" | "floating" | "docked" = "docked";
|
||||
private currentTileLayer: any = null;
|
||||
private lunarOverlayExpanded = false;
|
||||
private _wheelTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
|
|
@ -2000,11 +2001,11 @@ class FolkCalendarView extends HTMLElement {
|
|||
center, zoom, zoomControl: false,
|
||||
});
|
||||
|
||||
L.tileLayer("https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png", {
|
||||
attribution: '\u00A9 <a href="https://www.openstreetmap.org/copyright">OSM</a> \u00A9 <a href="https://carto.com/">CARTO</a>',
|
||||
subdomains: "abcd",
|
||||
maxZoom: 19,
|
||||
}).addTo(this.leafletMap);
|
||||
this.applyMapTileLayer();
|
||||
|
||||
// Watch for theme changes
|
||||
const observer = new MutationObserver(() => this.applyMapTileLayer());
|
||||
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
|
||||
|
||||
this.mapMarkerLayer = L.layerGroup().addTo(this.leafletMap);
|
||||
this.transitLineLayer = L.layerGroup().addTo(this.leafletMap);
|
||||
|
|
@ -2028,6 +2029,39 @@ class FolkCalendarView extends HTMLElement {
|
|||
this.updateTransitLines();
|
||||
}
|
||||
|
||||
private isDarkTheme(): boolean {
|
||||
const theme = document.documentElement.getAttribute("data-theme");
|
||||
if (theme) return theme === "dark";
|
||||
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
}
|
||||
|
||||
private applyMapTileLayer() {
|
||||
const L = (window as any).L;
|
||||
if (!L || !this.leafletMap) return;
|
||||
|
||||
if (this.currentTileLayer) {
|
||||
this.leafletMap.removeLayer(this.currentTileLayer);
|
||||
}
|
||||
|
||||
const dark = this.isDarkTheme();
|
||||
const tileUrl = dark
|
||||
? "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png"
|
||||
: "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png";
|
||||
|
||||
this.currentTileLayer = L.tileLayer(tileUrl, {
|
||||
attribution: '\u00A9 <a href="https://www.openstreetmap.org/copyright">OSM</a> \u00A9 <a href="https://carto.com/">CARTO</a>',
|
||||
subdomains: "abcd",
|
||||
maxZoom: 19,
|
||||
}).addTo(this.leafletMap);
|
||||
|
||||
// Apply brightness filter for dark mode to improve contrast
|
||||
const container = this.leafletMap.getContainer();
|
||||
const tilePane = container?.querySelector(".leaflet-tile-pane") as HTMLElement;
|
||||
if (tilePane) {
|
||||
tilePane.style.filter = dark ? "brightness(1.4) contrast(1.15)" : "none";
|
||||
}
|
||||
}
|
||||
|
||||
private updateMapMarkers() {
|
||||
const L = (window as any).L;
|
||||
if (!L || !this.mapMarkerLayer) return;
|
||||
|
|
|
|||
|
|
@ -390,7 +390,7 @@ const STYLES = `
|
|||
.trigger-badge {
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 22px; height: 22px; border-radius: 5px;
|
||||
font-size: 0.65rem; font-weight: 900; color: var(--rs-text-inverse);
|
||||
font-size: 0.65rem; font-weight: 900; color: #1e293b;
|
||||
line-height: 1; flex-shrink: 0; white-space: nowrap;
|
||||
}
|
||||
.trigger-badge.rstack-gradient {
|
||||
|
|
@ -448,7 +448,7 @@ a.rstack-header:hover { background: var(--rs-bg-hover); }
|
|||
display: flex; align-items: center; justify-content: center;
|
||||
width: 28px; height: 28px; border-radius: 8px;
|
||||
background: linear-gradient(135deg, #67e8f9, #c4b5fd, #fda4af);
|
||||
font-size: 0.7rem; font-weight: 900; color: var(--rs-text-inverse); line-height: 1;
|
||||
font-size: 0.7rem; font-weight: 900; color: #1e293b; line-height: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.rstack-info { display: flex; flex-direction: column; }
|
||||
|
|
@ -493,7 +493,7 @@ a.rstack-header:hover { background: var(--rs-bg-hover); }
|
|||
.item-badge {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
width: 28px; height: 28px; border-radius: 6px;
|
||||
font-size: 0.7rem; font-weight: 900; color: var(--rs-text-inverse);
|
||||
font-size: 0.7rem; font-weight: 900; color: #1e293b;
|
||||
line-height: 1; flex-shrink: 0; white-space: nowrap;
|
||||
}
|
||||
.item-icon { font-size: 1.3rem; width: 28px; text-align: center; flex-shrink: 0; }
|
||||
|
|
|
|||
|
|
@ -25,32 +25,36 @@ import { FLOW_COLORS, FLOW_LABELS } from "../../lib/layer-types";
|
|||
|
||||
// Badge info for tab display
|
||||
const MODULE_BADGES: Record<string, { badge: string; color: string }> = {
|
||||
rspace: { badge: "rS", color: "#5eead4" },
|
||||
rnotes: { badge: "rN", color: "#fcd34d" },
|
||||
rpubs: { badge: "rP", color: "#fda4af" },
|
||||
rswag: { badge: "rSw", color: "#fda4af" },
|
||||
rsplat: { badge: "r3", color: "#d8b4fe" },
|
||||
rcal: { badge: "rC", color: "#7dd3fc" },
|
||||
rtrips: { badge: "rT", color: "#6ee7b7" },
|
||||
rmaps: { badge: "rM", color: "#86efac" },
|
||||
rchats: { badge: "rCh", color: "#6ee7b7" },
|
||||
rinbox: { badge: "rI", color: "#a5b4fc" },
|
||||
rmail: { badge: "rMa", color: "#93c5fd" },
|
||||
rforum: { badge: "rFo", color: "#fcd34d" },
|
||||
rchoices: { badge: "rCo", color: "#f0abfc" },
|
||||
rvote: { badge: "rV", color: "#c4b5fd" },
|
||||
rflows: { badge: "rFl", color: "#bef264" },
|
||||
rwallet: { badge: "rW", color: "#fde047" },
|
||||
rcart: { badge: "rCt", color: "#fdba74" },
|
||||
rauctions: { badge: "rA", color: "#fca5a5" },
|
||||
rtube: { badge: "rTu", color: "#f9a8d4" },
|
||||
rphotos: { badge: "rPh", color: "#f9a8d4" },
|
||||
rnetwork: { badge: "rNe", color: "#93c5fd" },
|
||||
rsocials: { badge: "rSo", color: "#7dd3fc" },
|
||||
rfiles: { badge: "rFi", color: "#67e8f9" },
|
||||
rbooks: { badge: "rB", color: "#fda4af" },
|
||||
rdata: { badge: "rD", color: "#d8b4fe" },
|
||||
rwork: { badge: "rWo", color: "#cbd5e1" },
|
||||
rspace: { badge: "r🎨", color: "#5eead4" },
|
||||
rnotes: { badge: "r📝", color: "#fcd34d" },
|
||||
rpubs: { badge: "r📖", color: "#fda4af" },
|
||||
rswag: { badge: "r👕", color: "#fda4af" },
|
||||
rsplat: { badge: "r🔮", color: "#d8b4fe" },
|
||||
rcal: { badge: "r📅", color: "#7dd3fc" },
|
||||
rtrips: { badge: "r✈️", color: "#6ee7b7" },
|
||||
rmaps: { badge: "r🗺", color: "#86efac" },
|
||||
rchats: { badge: "r🗨", color: "#6ee7b7" },
|
||||
rinbox: { badge: "r📨", color: "#a5b4fc" },
|
||||
rmail: { badge: "r✉️", color: "#93c5fd" },
|
||||
rforum: { badge: "r💬", color: "#fcd34d" },
|
||||
rmeets: { badge: "r📹", color: "#67e8f9" },
|
||||
rchoices: { badge: "r☑️", color: "#f0abfc" },
|
||||
rvote: { badge: "r🗳", color: "#c4b5fd" },
|
||||
rflows: { badge: "r🌊", color: "#bef264" },
|
||||
rwallet: { badge: "r💰", color: "#fde047" },
|
||||
rcart: { badge: "r🛒", color: "#fdba74" },
|
||||
rauctions: { badge: "r🏛", color: "#fca5a5" },
|
||||
rtube: { badge: "r🎬", color: "#f9a8d4" },
|
||||
rphotos: { badge: "r📸", color: "#f9a8d4" },
|
||||
rnetwork: { badge: "r🌐", color: "#93c5fd" },
|
||||
rsocials: { badge: "r📢", color: "#7dd3fc" },
|
||||
rfiles: { badge: "r📁", color: "#67e8f9" },
|
||||
rbooks: { badge: "r📚", color: "#fda4af" },
|
||||
rdata: { badge: "r📊", color: "#d8b4fe" },
|
||||
rwork: { badge: "r📋", color: "#cbd5e1" },
|
||||
rschedule: { badge: "r⏱", color: "#a5b4fc" },
|
||||
rids: { badge: "r🪪", color: "#6ee7b7" },
|
||||
rstack: { badge: "r✨", color: "" },
|
||||
};
|
||||
|
||||
// Category definitions for the + menu dropdown grouping
|
||||
|
|
@ -1431,14 +1435,16 @@ const STYLES = `
|
|||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 20px;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.55rem;
|
||||
font-size: 0.6rem;
|
||||
font-weight: 900;
|
||||
color: var(--rs-text-inverse);
|
||||
color: #1e293b;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.tab-label {
|
||||
|
|
@ -1589,13 +1595,15 @@ const STYLES = `
|
|||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
min-width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 5px;
|
||||
font-size: 0.55rem;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 900;
|
||||
color: var(--rs-text-inverse);
|
||||
color: #1e293b;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
.add-menu-icon {
|
||||
|
|
@ -1847,13 +1855,15 @@ const STYLES = `
|
|||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
min-width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 5px;
|
||||
font-size: 0.55rem;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 900;
|
||||
color: var(--rs-text-inverse);
|
||||
color: #1e293b;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
.layer-name {
|
||||
|
|
@ -2154,9 +2164,10 @@ const STYLES = `
|
|||
justify-content: center;
|
||||
padding: 3px 8px;
|
||||
border-radius: 5px;
|
||||
font-size: 0.6rem;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 900;
|
||||
color: var(--rs-text-inverse);
|
||||
color: #1e293b;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.flow-dialog-arrow {
|
||||
|
|
|
|||
Loading…
Reference in New Issue