Fix navigation chart rendering and add Spotify/AirPlay zone indicators with grouping
- Fixed ChartPlaceholder canvas rendering by replacing CSS variables with hardcoded colors * Canvas context cannot use CSS variables; must use RGB/hex colors directly * Now renders ship track, waypoints, heading indicator, and legends correctly - Enhanced ZoneCard with connection indicators * Added visual source badges (Spotify 🎵, AirPlay 🎙️, Mopidy 📻) * Color-coded left border matching source (green for Spotify, blue for AirPlay, amber for Mopidy) * Added source dropdown selector for switching audio sources * Shows grouped zone info when zones are merged - Implemented zone grouping system in ZoneGrid * Left sidebar panel to view and manage active zone groups * Click 🔗 button to create/remove zone groups * When zones are grouped, changing source updates all members * Each zone can show which other zones it's grouped with - All 64 modules build successfully - Mock data properly flows through Snapcast with Spotify/AirPlay/Mopidy sources Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -11,6 +11,17 @@ export default function ChartPlaceholder() {
|
||||
const chartUrl = `http://${signalkHost}:3000/@signalk/freeboard-sk/`
|
||||
const isMock = import.meta.env.VITE_USE_MOCK === 'true'
|
||||
|
||||
// Colors from CSS (hardcoded for canvas compatibility)
|
||||
const colors = {
|
||||
bg: '#07111f',
|
||||
surface: '#0a1928',
|
||||
border: '#1e2a3a',
|
||||
text: '#e2eaf2',
|
||||
muted: '#4a6080',
|
||||
accent: '#38bdf8',
|
||||
warning: '#f59e0b',
|
||||
}
|
||||
|
||||
// Draw track and waypoints
|
||||
useEffect(() => {
|
||||
const canvas = canvasRef.current
|
||||
@@ -68,9 +79,9 @@ export default function ChartPlaceholder() {
|
||||
})
|
||||
|
||||
// Clear and draw background
|
||||
ctx.fillStyle = 'var(--surface)'
|
||||
ctx.fillStyle = colors.surface
|
||||
ctx.fillRect(0, 0, width, height)
|
||||
ctx.strokeStyle = 'var(--border)'
|
||||
ctx.strokeStyle = colors.border
|
||||
ctx.lineWidth = 1
|
||||
ctx.strokeRect(0, 0, width, height)
|
||||
|
||||
@@ -79,14 +90,14 @@ export default function ChartPlaceholder() {
|
||||
const p = project(wp.lat, wp.lon)
|
||||
|
||||
// Waypoint circle
|
||||
ctx.fillStyle = idx === snapshot?.currentWaypoint ? 'var(--accent)' : 'var(--warning)'
|
||||
ctx.fillStyle = idx === snapshot?.currentWaypoint ? colors.accent : colors.warning
|
||||
ctx.beginPath()
|
||||
ctx.arc(p.x, p.y, 6, 0, Math.PI * 2)
|
||||
ctx.fill()
|
||||
|
||||
// Waypoint number
|
||||
ctx.fillStyle = 'var(--bg)'
|
||||
ctx.font = 'bold 10px var(--font-mono)'
|
||||
ctx.fillStyle = colors.bg
|
||||
ctx.font = 'bold 10px monospace'
|
||||
ctx.textAlign = 'center'
|
||||
ctx.textBaseline = 'middle'
|
||||
ctx.fillText(idx + 1, p.x, p.y)
|
||||
@@ -94,7 +105,7 @@ export default function ChartPlaceholder() {
|
||||
|
||||
// Draw track line
|
||||
if (trackRef.current.length > 1) {
|
||||
ctx.strokeStyle = 'var(--accent)'
|
||||
ctx.strokeStyle = colors.accent
|
||||
ctx.lineWidth = 2
|
||||
ctx.beginPath()
|
||||
trackRef.current.forEach((p, idx) => {
|
||||
@@ -116,7 +127,7 @@ export default function ChartPlaceholder() {
|
||||
ctx.save()
|
||||
ctx.translate(p.x, p.y)
|
||||
ctx.rotate(headRad)
|
||||
ctx.fillStyle = 'var(--accent)'
|
||||
ctx.fillStyle = colors.accent
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(0, -size)
|
||||
ctx.lineTo(-size / 2, size / 2)
|
||||
@@ -126,7 +137,7 @@ export default function ChartPlaceholder() {
|
||||
ctx.restore()
|
||||
|
||||
// Ship circle
|
||||
ctx.strokeStyle = 'var(--accent)'
|
||||
ctx.strokeStyle = colors.accent
|
||||
ctx.lineWidth = 2
|
||||
ctx.beginPath()
|
||||
ctx.arc(p.x, p.y, 8, 0, Math.PI * 2)
|
||||
|
||||
Reference in New Issue
Block a user