Skip to content

Commit

Permalink
feat(ui): Consumable status progress bars
Browse files Browse the repository at this point in the history
  • Loading branch information
Hypfer committed Mar 16, 2023
1 parent 537f7af commit a427045
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 21 deletions.
12 changes: 11 additions & 1 deletion backend/lib/core/capabilities/ConsumableMonitoringCapability.js
Expand Up @@ -45,7 +45,7 @@ class ConsumableMonitoringCapability extends Capability {

/**
*
* @return {{availableConsumables: Array<{type: ConsumableStateAttribute.TYPE, subType: ConsumableStateAttribute.SUB_TYPE, unit: ConsumableStateAttribute.UNITS}>}}
* @return {{availableConsumables: Array<ConsumableMeta>}}
*/
getProperties() {
return {
Expand All @@ -59,6 +59,16 @@ class ConsumableMonitoringCapability extends Capability {
}
}

/**
* @typedef {object} ConsumableMeta
*
* @property {ConsumableStateAttribute.TYPE} type
* @property {ConsumableStateAttribute.SUB_TYPE} subType
* @property {ConsumableStateAttribute.UNITS} unit
* @property {number} [maxValue]
*
*/


ConsumableMonitoringCapability.TYPE = "ConsumableMonitoringCapability";

Expand Down
Expand Up @@ -187,17 +187,20 @@ class Dreame1CConsumableMonitoringCapability extends ConsumableMonitoringCapabil
{
type: ConsumableStateAttribute.TYPE.BRUSH,
subType: ConsumableStateAttribute.SUB_TYPE.MAIN,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 300 * 60
},
{
type: ConsumableStateAttribute.TYPE.BRUSH,
subType: ConsumableStateAttribute.SUB_TYPE.SIDE_RIGHT,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 200 * 60
},
{
type: ConsumableStateAttribute.TYPE.FILTER,
subType: ConsumableStateAttribute.SUB_TYPE.MAIN,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 150 * 60
}
]
};
Expand Down
Expand Up @@ -325,21 +325,25 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit
}

getProperties() {
/** @type Array<ConsumableMonitoringCapability.ConsumableMeta> **/
const availableConsumables = [
{
type: ConsumableStateAttribute.TYPE.BRUSH,
subType: ConsumableStateAttribute.SUB_TYPE.MAIN,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 300 * 60
},
{
type: ConsumableStateAttribute.TYPE.BRUSH,
subType: ConsumableStateAttribute.SUB_TYPE.SIDE_RIGHT,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 200 * 60
},
{
type: ConsumableStateAttribute.TYPE.FILTER,
subType: ConsumableStateAttribute.SUB_TYPE.MAIN,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 150 * 60
}
];

Expand All @@ -348,7 +352,8 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit
{
type: ConsumableStateAttribute.TYPE.SENSOR,
subType: ConsumableStateAttribute.SUB_TYPE.ALL,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 30 * 60
}
);
}
Expand All @@ -358,7 +363,8 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit
{
type: ConsumableStateAttribute.TYPE.MOP,
subType: ConsumableStateAttribute.SUB_TYPE.ALL,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 80 * 60
}
);
}
Expand All @@ -368,7 +374,8 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit
{
type: ConsumableStateAttribute.TYPE.FILTER,
subType: ConsumableStateAttribute.SUB_TYPE.SECONDARY,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 300 * 60
}
);
}
Expand Down
Expand Up @@ -86,22 +86,26 @@ class RoborockConsumableMonitoringCapability extends ConsumableMonitoringCapabil
{
type: ConsumableStateAttribute.TYPE.BRUSH,
subType: ConsumableStateAttribute.SUB_TYPE.MAIN,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 300 * 60
},
{
type: ConsumableStateAttribute.TYPE.BRUSH,
subType: ConsumableStateAttribute.SUB_TYPE.SIDE_RIGHT,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 200 * 60
},
{
type: ConsumableStateAttribute.TYPE.FILTER,
subType: ConsumableStateAttribute.SUB_TYPE.MAIN,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 150 * 60
},
{
type: ConsumableStateAttribute.TYPE.SENSOR,
subType: ConsumableStateAttribute.SUB_TYPE.ALL,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 30 * 60
}
]
};
Expand Down
Expand Up @@ -114,17 +114,20 @@ class ViomiConsumableMonitoringCapability extends ConsumableMonitoringCapability
{
type: ConsumableStateAttribute.TYPE.BRUSH,
subType: ConsumableStateAttribute.SUB_TYPE.MAIN,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 360 * 60
},
{
type: ConsumableStateAttribute.TYPE.BRUSH,
subType: ConsumableStateAttribute.SUB_TYPE.SIDE_RIGHT,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 180 * 60
},
{
type: ConsumableStateAttribute.TYPE.FILTER,
subType: ConsumableStateAttribute.SUB_TYPE.MAIN,
unit: ConsumableStateAttribute.UNITS.MINUTES
unit: ConsumableStateAttribute.UNITS.MINUTES,
maxValue: 180 * 60
}
]
};
Expand Down
Expand Up @@ -195,6 +195,9 @@
},
"unit": {
"type": "string"
},
"maxValue": {
"type": "number"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/api/types.ts
Expand Up @@ -170,7 +170,8 @@ export interface ConsumableId {
export interface ConsumableMeta {
type: ConsumableType,
subType: ConsumableSubType,
unit: ConsumableUnit
unit: ConsumableUnit,
maxValue?: number
}

export interface ConsumableProperties {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/list_menu/ButtonListMenuItem.tsx
Expand Up @@ -5,7 +5,7 @@ import ConfirmationDialog from "../ConfirmationDialog";

export const ButtonListMenuItem: React.FunctionComponent<{
primaryLabel: string,
secondaryLabel: string,
secondaryLabel: string | JSX.Element,
icon?: JSX.Element,
buttonLabel: string,
buttonColor?: "warning" | "error",
Expand Down
35 changes: 33 additions & 2 deletions frontend/src/robot/Consumables.tsx
Expand Up @@ -8,7 +8,7 @@ import {
useConsumableResetMutation,
useConsumableStateQuery
} from "../api";
import {CircularProgress} from "@mui/material";
import {CircularProgress, LinearProgress} from "@mui/material";
import {ButtonListMenuItem} from "../components/list_menu/ButtonListMenuItem";
import {convertSecondsToHumans, getConsumableName} from "../utils";
import {ConsumablesHelp} from "./res/ConsumablesHelp";
Expand All @@ -27,6 +27,8 @@ const ConsumableButtonListMenuItem: React.FunctionComponent<{

let secondaryLabel = "";
let buttonColor : "warning" | "error" | undefined;
let secondaryLabelElement : JSX.Element | undefined;

if (state) {
secondaryLabel = "Remaining: ";
secondaryLabel += state.remaining.unit === "minutes" ? convertSecondsToHumans(60 * state.remaining.value, false) : `${state.remaining.value} %`;
Expand All @@ -35,12 +37,41 @@ const ConsumableButtonListMenuItem: React.FunctionComponent<{
buttonColor = "warning";
secondaryLabel = "Depleted";
}


let percentRemaining;

if (consumable.unit === "percent") {
percentRemaining = state.remaining.value / 100;
} else if (consumable.maxValue !== undefined) {
percentRemaining = state.remaining.value / consumable.maxValue;
}

if (percentRemaining !== undefined) {
percentRemaining = percentRemaining * 100;
percentRemaining = Math.round(percentRemaining);
percentRemaining = Math.max(percentRemaining, 0);
percentRemaining = Math.min(percentRemaining, 100);

secondaryLabelElement = (
<>
<LinearProgress
variant="determinate"
value={percentRemaining}
style={{marginTop: "0.5rem", marginBottom: "0.5rem"}}
/>
<span>{secondaryLabel}</span>
</>
);
}
}



return (
<ButtonListMenuItem
primaryLabel={getConsumableName(consumable.type, consumable.subType)}
secondaryLabel={secondaryLabel}
secondaryLabel={secondaryLabelElement ?? secondaryLabel}
buttonLabel="Reset"
buttonColor={buttonColor}
confirmationDialog={{
Expand Down

0 comments on commit a427045

Please sign in to comment.