tank alarm animation
This commit is contained in:
@@ -4,6 +4,10 @@ import { useTank } from "../../../utils/hooks/use-custom-mqtt"
|
||||
import { useWatermaker } from "../../../utils/hooks/use-watermaker"
|
||||
import { cardBase, cardTitle, cardStatusBadge } from "./cardStyles"
|
||||
|
||||
function AlarmPulseOverlay() {
|
||||
return <div className="absolute inset-0 bg-red-600 animate-alarm-pulse rounded-[inherit]" />
|
||||
}
|
||||
|
||||
function FreshWaterGauge() {
|
||||
const bow = useTank(2)
|
||||
const stern = useTank(3)
|
||||
@@ -11,6 +15,8 @@ function FreshWaterGauge() {
|
||||
const sternLevel = stern.level != null ? Math.round(stern.level) : null
|
||||
const avgLevel =
|
||||
bowLevel != null && sternLevel != null ? Math.round((bowLevel + sternLevel) / 2) : (bowLevel ?? sternLevel)
|
||||
const bowAlarming = bow.lowLevelAlarm === 2
|
||||
const sternAlarming = stern.lowLevelAlarm === 2
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -19,14 +25,21 @@ function FreshWaterGauge() {
|
||||
<span className="text-content-secondary text-xs font-bold">{avgLevel != null ? `${avgLevel}%` : "--"}</span>
|
||||
</div>
|
||||
<div className="h-3 bg-outline-primary rounded-full overflow-hidden flex">
|
||||
<div className="h-full bg-blue-500 transition-all duration-500" style={{ width: `${(bowLevel ?? 0) / 2}%` }} />
|
||||
<div
|
||||
className="relative h-full bg-blue-500 transition-all duration-500"
|
||||
style={{ width: `${(bowLevel ?? 0) / 2}%` }}
|
||||
>
|
||||
{bowAlarming && <AlarmPulseOverlay />}
|
||||
</div>
|
||||
{(bowLevel ?? 0) > 0 && (sternLevel ?? 0) > 0 && (
|
||||
<div className="h-full flex-shrink-0 bg-outline-primary" style={{ width: "4px" }} />
|
||||
)}
|
||||
<div
|
||||
className="h-full bg-blue-500 transition-all duration-500"
|
||||
className="relative h-full bg-blue-500 transition-all duration-500"
|
||||
style={{ width: `${(sternLevel ?? 0) / 2}%` }}
|
||||
/>
|
||||
>
|
||||
{sternAlarming && <AlarmPulseOverlay />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -35,6 +48,7 @@ function FreshWaterGauge() {
|
||||
function BlackWaterGauge() {
|
||||
const tank = useTank(4)
|
||||
const level = tank.level != null ? Math.round(tank.level) : null
|
||||
const alarming = tank.highLevelAlarm === 2
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-baseline justify-between mb-1">
|
||||
@@ -43,9 +57,11 @@ function BlackWaterGauge() {
|
||||
</div>
|
||||
<div className="h-3 bg-outline-primary rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-content-victronYellow transition-all duration-500"
|
||||
className="relative h-full bg-content-victronYellow transition-all duration-500"
|
||||
style={{ width: `${level ?? 0}%` }}
|
||||
/>
|
||||
>
|
||||
{alarming && <AlarmPulseOverlay />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -184,11 +200,26 @@ interface Props {
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
function useAnyTankAlarm(): boolean {
|
||||
const bow = useTank(2)
|
||||
const stern = useTank(3)
|
||||
const black = useTank(4)
|
||||
return bow.lowLevelAlarm === 2 || stern.lowLevelAlarm === 2 || black.highLevelAlarm === 2
|
||||
}
|
||||
|
||||
const CompactTankCard = ({ onClick }: Props) => {
|
||||
const hasAlarm = useAnyTankAlarm()
|
||||
return (
|
||||
<div className={`${cardBase} h-full`} onClick={onClick}>
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
<span className={cardTitle}>Tanks / Watermaker</span>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className={cardTitle}>Tanks / Watermaker</span>
|
||||
{hasAlarm && (
|
||||
<svg className="w-3.5 h-3.5 text-content-victronRed" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" />
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
|
||||
@@ -161,6 +161,15 @@ module.exports = {
|
||||
5: "1.25rem",
|
||||
7: "1.75rem",
|
||||
},
|
||||
keyframes: {
|
||||
"alarm-pulse": {
|
||||
"0%, 100%": { opacity: "0" },
|
||||
"50%": { opacity: "0.85" },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
"alarm-pulse": "alarm-pulse 2.4s ease-in-out infinite",
|
||||
},
|
||||
},
|
||||
},
|
||||
// Garmin and Furuno devices don't support the RGB colors with opacity,
|
||||
|
||||
Reference in New Issue
Block a user