Skip to content

Commit e129535

Browse files
Add global alert bar, dynamic webapp version warning
1 parent 2a94606 commit e129535

File tree

11 files changed

+70
-35
lines changed

11 files changed

+70
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
* Web App
66
* Changed caching rules to ensure that users don't get stuck with old versions of the webapp post update
7-
7+
* Add warning for older versions of the webapp running on newer backends
88

99
## 0.4.10
1010

NEW_RELEASE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ This project follows [Semantic Versioning](https://semver.org/). Here are some e
3131
- [ ] Update the API by running `scripts/create_spec` script.
3232
- [ ] Create & merge a branch/PR off `main` to bump the version in the CHANGELOG and also using `poetry version ${VERSION}`
3333
- [ ] Checkout main & create a detached HEAD: `git checkout main; git pull; git checkout --detach`
34-
- [ ] Build the webapp in `web` with `npm run build` and force add the changes with `git add -f web/dist; git commit -m "Build web app for release"`
34+
- [ ] CD into `web`, Run `echo "VITE_BACKEND_VERSION=$(poetry version -s)" > .env`
35+
- [ ] Still in `web`, build the webapp with `npm run build` and force add the changes with `git add -f web/dist; git commit -m "Build web app for release"`
3536
- [ ] Tag the changes so we can make a release on GitHub: `git tag -as ${VERSION} -m '' && git push origin ${VERSION}`
3637
- [ ] Make a release using the GitHub interface
3738
- [ ] Use the AmpliPi updater to update to the release

scripts/deploy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ poetry version ${git_info}
159159
echo "Building web app"
160160
pushd ../web # Change to web directory
161161
npm install # Install nodejs dependencies
162+
echo "VITE_BACKEND_VERSION=$(poetry version -s)" > .env # Collect the version number and bake it into the frontend
162163
npm run build # Build the web app
163164
popd
164165

web/src/App.jsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import DisconnectedIcon from "./components/DisconnectedIcon/DisconnectedIcon";
1313
import Browse from "@/pages/Browse/Browse";
1414

1515
import PropTypes from "prop-types";
16+
import AlertBar from "./components/StatusBars/AlertBar";
1617

1718
// holds onto the selectedSource state so that it persists between refreshes
1819
export const usePersistentStore = create(
@@ -40,6 +41,7 @@ export const useStatusStore = create((set, get) => ({
4041
skipUpdate: false,
4142
loaded: false, // using this instead of (status === null) because it fixes the re-rendering issue
4243
disconnected: true,
44+
alert: {"open": false, "text": ""},
4345
skipNextUpdate: () => {
4446
set({ skipUpdate: true });
4547
},
@@ -122,6 +124,9 @@ export const useStatusStore = create((set, get) => ({
122124
}
123125
});
124126
},
127+
setAlert: (text) => {
128+
set({alert: {"open": true, "text": text}});
129+
},
125130

126131
getSystemState: () => {
127132
fetch("/api")
@@ -133,6 +138,9 @@ export const useStatusStore = create((set, get) => ({
133138
set({ skipUpdate: false });
134139
} else {
135140
set({ status: s, loaded: true, disconnected: false });
141+
if(s.info.version != import.meta.env.VITE_BACKEND_VERSION){
142+
set({alert: {"open": true, "text": "Frontend/backend version mismatch, please restart your app or refresh your browser cache or face potentially unpredictable consequences"}});
143+
}
136144
}
137145
});
138146
} else if (res.status == 401) {
@@ -225,15 +233,19 @@ Page.propTypes = {
225233
};
226234

227235
const App = ({ selectedPage }) => {
236+
const alert = useStatusStore((s) => s.alert);
228237
return (
229-
<div className="app">
238+
<div className="app">
239+
<div className="alert">
240+
<AlertBar open={alert["open"]} text={alert["text"]} onClose={() => {alert["open"] == false;}}/>
241+
</div>
230242
<DisconnectedIcon />
231-
<div className="background-gradient"></div> {/* Used to make sure the background doesn't stretch or stop prematurely on scrollable pages */}
232-
<div className="app-body">
233-
<Page selectedPage={selectedPage} />
234-
</div>
235-
<MenuBar pageNumber={selectedPage} />
243+
<div className="background-gradient">{/* Used to make sure the background doesn't stretch or stop prematurely on scrollable pages */}</div>
244+
<div className="app-body">
245+
<Page selectedPage={selectedPage} />
236246
</div>
247+
<MenuBar pageNumber={selectedPage} />
248+
</div>
237249
);
238250
};
239251
App.propTypes = {

web/src/App.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
}
2121

2222
// unused
23+
.alert{
24+
z-index: 2;
25+
position: fixed;
26+
// bottom: 5vh;
27+
top: 0;
28+
left: 0;
29+
}
30+
2331
.app-container {
2432
display: flex;
2533
width: 100%;

web/src/components/CreateStreamModal/StreamModal/StreamModal.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ const StreamModal = ({ stream, onClose, apply, del }) => {
251251
renderAnimationState={renderAlertAnimation}
252252
open={hasError}
253253
onClose={() => {setHasError(false);}}
254-
status={false}
255254
text={errorMessage}
256255
/>
257256
}

web/src/components/StatusBars/AlertBar.jsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Alert from "@mui/material/Alert";
77
export default function AlertBar(props) {
88
const {
99
open,
10-
status,
10+
success,
1111
text,
1212
onClose,
1313
renderAnimationState,
@@ -19,34 +19,37 @@ export default function AlertBar(props) {
1919
if(alertRef.current != null){
2020
const alertComp = alertRef.current;
2121
alertComp.classList.remove("error");
22-
if(status == false){
22+
if(!success){
2323
alertComp.offsetWidth;
2424
alertComp.classList.add("error");
2525
}
2626
}
27-
}, [status, renderAnimationState]);
27+
}, [success, renderAnimationState]);
2828

29-
if(open){
29+
const [closedText, setClosedText] = React.useState(""); // If a user has closed a given message, don't show it again until another message tries to appear
30+
31+
if(open && text != closedText){
3032
return(
3133
<Alert
3234
ref={alertRef}
33-
onClose={onClose}
34-
severity={status ? "success" : "error"}
35+
onClose={() => {onClose(); setClosedText(text);}}
36+
severity={success ? "success" : "error"}
3537
variant="filled"
3638
style={{width: "100%",}}
3739
>
3840
{text}
3941
</Alert>
40-
)
42+
);
4143
}
42-
};
44+
}
4345
AlertBar.propTypes = {
4446
open: PropTypes.bool.isRequired,
45-
status: PropTypes.bool.isRequired,
47+
success: PropTypes.bool,
4648
text: PropTypes.string.isRequired,
4749
onClose: PropTypes.func.isRequired,
4850
renderAnimationState: PropTypes.number,
4951
};
5052
AlertBar.defaultProps = {
53+
success: false,
5154
renderAnimationState: 1,
52-
}
55+
};

web/src/components/StatusBars/ResponseBar.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default function ResponseBar(props) {
4141
return(
4242
<StatusBar
4343
open={open}
44-
status={success}
44+
success={success}
4545
text={text.current}
4646
onClose={() => {setOpen(false);}}
4747
/>

web/src/components/StatusBars/StatusBar.jsx

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,50 @@ import PropTypes from "prop-types";
33
import "./StatusBars.scss";
44
import Snackbar from "@mui/material/Snackbar";
55

6-
import Alert from "@mui/material/Alert"
6+
import Alert from "@mui/material/Alert";
77

88
export default function StatusBar(props) {
99
const {
1010
open,
11-
status,
11+
success,
1212
text,
1313
onClose,
14+
anchorOrigin,
15+
autoHideDuration,
1416
} = props;
1517

18+
const [closedText, setClosedText] = React.useState(""); // If a user has closed a given message, don't show it again until another message tries to appear
19+
1620
return(
1721
<Snackbar
1822
className="snackbar"
19-
autoHideDuration={3000}
20-
anchorOrigin={{vertical: "bottom", horizontal: "left"}}
21-
open={open}
22-
onClose={onClose}
23+
autoHideDuration={autoHideDuration != 0 ? autoHideDuration : 999999999999999}
24+
anchorOrigin={anchorOrigin}
25+
open={open && closedText != text}
26+
onClose={() => {onClose(); setClosedText(text);}}
2327
>
2428
<Alert // Cannot be AlertBar due to React rendering throwing errors despite it being the same thing
25-
onClose={onClose}
26-
severity={status ? "success" : "error"}
29+
onClose={() => {onClose(); setClosedText(text);}}
30+
severity={success ? "success" : "error"}
2731
variant="filled"
2832
style={{width: "100%"}}
2933
>
3034
{text}
3135
</Alert>
3236
</Snackbar>
33-
)
34-
};
37+
);
38+
}
3539
StatusBar.propTypes = {
3640
open: PropTypes.bool.isRequired,
37-
status: PropTypes.bool.isRequired,
41+
success: PropTypes.bool,
3842
text: PropTypes.string.isRequired,
3943
onClose: PropTypes.func.isRequired,
44+
autoHideDuration: PropTypes.number,
45+
anchorOrigin: PropTypes.object,
4046
};
47+
StatusBar.defaultProps = {
48+
success: false,
49+
autoHideDuration: 3000,
50+
anchorOrigin: {vertical: "bottom", horizontal: "left"},
51+
};
52+

web/src/pages/Browse/Browse.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ const Browse = () => {
113113
</List>
114114
<StatusBar
115115
open={errorOpen}
116-
status={false}
117116
text={errorText.current}
118117
onClose={()=>{setErrorOpen(false);}}
119118
/>

0 commit comments

Comments
 (0)