GPS Geschwindigkeitsanzeige
Test and publish container images / test (push) Successful in 2m25s
Test and publish container images / publish (push) Failing after 4s

This commit is contained in:
BuTzZ
2026-07-28 16:39:35 +02:00
parent 593dbd5f85
commit 2e84f4eae4
5 changed files with 70 additions and 45 deletions
+55 -25
View File
@@ -18,6 +18,13 @@ type StatusBarProps = {
} | null;
};
type StatusItemData = {
icon?: ReactNode;
label: string;
value: string;
speed?: boolean;
};
export function StatusBar({
gps,
forecast,
@@ -39,7 +46,7 @@ export function StatusBar({
? "Position aktiv"
: `±${gps.accuracyM} m`
: gpsStatusLabel(gps.status);
const speedValue = gps.speedKn === null ? "-- kn" : `${gps.speedKn.toFixed(1)} kn`;
const speedValue = formatGpsSpeed(gps.speedKn);
const tideValue = tide?.nextHigh
? `HW ${new Date(tide.nextHigh.time).toLocaleTimeString("de-DE", {
hour: "2-digit",
@@ -48,7 +55,7 @@ export function StatusBar({
: "Keine Daten";
const conditionsValue = formatConditions(forecast);
const items =
const items: StatusItemData[] =
resolvedMode === "anchor"
? [
{
@@ -95,9 +102,9 @@ export function StatusBar({
value: `${routeWarningCount} offen`
}
: {
icon: <Activity size={15} aria-hidden="true" />,
label: "SOG",
value: speedValue
icon: <Navigation2 size={15} aria-hidden="true" />,
label: "GPS",
value: gpsValue
}
]
: resolvedMode === "route"
@@ -115,17 +122,11 @@ export function StatusBar({
label: "GPS",
value: gpsValue
},
gps.position
? {
icon: <Activity size={15} aria-hidden="true" />,
label: "SOG",
value: speedValue
}
: {
icon: <Waves size={15} aria-hidden="true" />,
label: "Tide",
value: tideValue
}
{
icon: <Waves size={15} aria-hidden="true" />,
label: "Tide",
value: tideValue
}
]
: [
{
@@ -144,23 +145,44 @@ export function StatusBar({
value: tideValue
}
];
const statusItems: StatusItemData[] = [
...items,
{
icon: <Activity size={15} aria-hidden="true" />,
label: "GPS-Geschwindigkeit",
value: speedValue,
speed: true
}
];
return (
<footer
className="status-bar"
aria-label="Navigationsstatus"
style={{ gridTemplateColumns: "repeat(3, minmax(0, 1fr))" }}
>
{items.map((item) => (
<StatusItem key={item.label} icon={item.icon} label={item.label} value={item.value} />
<footer className="status-bar" aria-label="Navigationsstatus">
{statusItems.map((item) => (
<StatusItem
key={item.label}
icon={item.icon}
label={item.label}
value={item.value}
speed={item.speed}
/>
))}
</footer>
);
}
function StatusItem({ icon, label, value }: { icon?: ReactNode; label: string; value: string }) {
function StatusItem({
icon,
label,
value,
speed = false
}: {
icon?: ReactNode;
label: string;
value: string;
speed?: boolean;
}) {
return (
<span className="status-item">
<span className="status-item" data-kind={speed ? "speed" : undefined}>
{icon}
<span className="status-label">{label}</span>
<strong>{value}</strong>
@@ -168,6 +190,14 @@ function StatusItem({ icon, label, value }: { icon?: ReactNode; label: string; v
);
}
function formatGpsSpeed(speedKn: number | null): string {
if (speedKn === null || !Number.isFinite(speedKn) || speedKn < 0) {
return "-- km/h · -- kn";
}
const format = (value: number) => value.toFixed(1).replace(".", ",");
return `${format(speedKn * 1.852)} km/h · ${format(speedKn)} kn`;
}
function gpsStatusLabel(status: GpsState["status"]): string {
switch (status) {
case "idle":
+7 -2
View File
@@ -1128,7 +1128,7 @@ button:disabled {
.route-weather-metrics {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(118px, 1.35fr);
gap: 6px;
}
@@ -1681,6 +1681,11 @@ button:disabled {
white-space: nowrap;
}
.status-item[data-kind="speed"] strong {
overflow: visible;
text-overflow: clip;
}
.status-label {
grid-column: 2;
font-size: 10px;
@@ -1778,7 +1783,7 @@ button:disabled {
}
.status-bar {
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(118px, 1.35fr);
}
}