mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-30 05:02:58 +00:00
The reset countdown floored to one unit, so a weekly window read "resets 2d"
from 2d 23h down to 2d 0h and looked stuck for a day; the session window had
the same problem with hours. Countdowns now use two units ("2d 23h", "4h 59m"),
and every row also shows the clock time it resets ("7:20 AM", "Sat 8:00 AM",
"Oct 31, 3:00 PM"), so users can plan work around a reset without hovering.
Rows now put the window name and percent on one line, the bar under it, and the
reset on its own full-width line, so the exact time fits at phone width in
longer languages. The pinned-row background is gone; the pin glyph, drawn in
the foreground colour when pinned, is the only pinned signal. Bars are 6px.
75 lines
1.8 KiB
TypeScript
75 lines
1.8 KiB
TypeScript
import { useMemo } from "react";
|
|
import { View, type StyleProp, type ViewStyle } from "react-native";
|
|
import { StyleSheet } from "react-native-unistyles";
|
|
import { clampPct } from "./format";
|
|
import type { UsageTone } from "./types";
|
|
|
|
function fillToneStyle(tone: UsageTone) {
|
|
switch (tone) {
|
|
case "ok":
|
|
return styles.fillOk;
|
|
case "warning":
|
|
return styles.fillWarning;
|
|
case "danger":
|
|
return styles.fillDanger;
|
|
default:
|
|
return styles.fillDefault;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A window's share as a bar, coloured by its tone. `quiet` fills it with a surface colour instead,
|
|
* for summaries where a row of coloured bars would be noise. The caller sizes the track.
|
|
*/
|
|
export function UsageMeter({
|
|
percent,
|
|
tone,
|
|
quiet = false,
|
|
style,
|
|
}: {
|
|
percent: number;
|
|
tone: UsageTone;
|
|
quiet?: boolean;
|
|
style?: StyleProp<ViewStyle>;
|
|
}) {
|
|
const fillWidth = clampPct(percent);
|
|
const fillStyle = useMemo<StyleProp<ViewStyle>>(
|
|
() => [styles.fill, quiet ? styles.fillQuiet : fillToneStyle(tone), { width: `${fillWidth}%` }],
|
|
[fillWidth, quiet, tone],
|
|
);
|
|
return (
|
|
<View style={[styles.track, style]}>
|
|
<View style={fillStyle} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create((theme) => ({
|
|
track: {
|
|
height: 6,
|
|
borderRadius: 3,
|
|
backgroundColor: theme.colors.surface3,
|
|
overflow: "hidden",
|
|
},
|
|
// Follows the track, so a caller that sizes the track sizes the bar.
|
|
fill: {
|
|
height: "100%",
|
|
borderRadius: theme.borderRadius.full,
|
|
},
|
|
fillQuiet: {
|
|
backgroundColor: theme.colors.surface4,
|
|
},
|
|
fillDefault: {
|
|
backgroundColor: theme.colors.foregroundMuted,
|
|
},
|
|
fillOk: {
|
|
backgroundColor: theme.colors.statusSuccess,
|
|
},
|
|
fillWarning: {
|
|
backgroundColor: theme.colors.statusWarning,
|
|
},
|
|
fillDanger: {
|
|
backgroundColor: theme.colors.statusDanger,
|
|
},
|
|
}));
|