Skip to content

Commit bc766f1

Browse files
committed
Add redux to explorer
1 parent 2cf5b55 commit bc766f1

File tree

10 files changed

+210
-90
lines changed

10 files changed

+210
-90
lines changed

mithril-explorer/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ clean:
2424
rm yarn.lock || true
2525

2626
upgrade: clean install
27-
yarn upgrade next@latest react@latest react-bootstrap@latest react-dom@latest bootstrap@latest bootstrap-icons@latest eslint@latest eslint-config-next@latest
27+
yarn upgrade next@latest react@latest react-bootstrap@latest react-dom@latest bootstrap@latest \
28+
bootstrap-icons@latest eslint@latest eslint-config-next@latest @reduxjs/toolkit@latest \
29+
next-redux-wrapper@latest react-redux@latest

mithril-explorer/components/EpochSettings/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import React, { useEffect, useState } from 'react';
22
import {Card, ListGroup} from "react-bootstrap";
33
import RawJsonButton from "../RawJsonButton";
4+
import {useSelector} from "react-redux";
45

56
export default function EpochSettings(props) {
67
const [epochSettings, setEpochSettings] = useState({});
8+
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
79

810
useEffect(() => {
9-
if (!props.autoUpdate) {
11+
if (!autoUpdate) {
1012
return;
1113
}
1214

@@ -25,7 +27,7 @@ export default function EpochSettings(props) {
2527

2628
const interval = setInterval(fetchEpochSettings, props.updateInterval);
2729
return () => clearInterval(interval);
28-
}, [props.aggregator, props.updateInterval, props.autoUpdate]);
30+
}, [props.aggregator, props.updateInterval, autoUpdate]);
2931

3032
return (
3133
<div>

mithril-explorer/components/PendingCertificate/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ import React, { useState, useEffect } from 'react';
22
import { Card, CardGroup, ListGroup } from "react-bootstrap";
33
import RawJsonButton from "../RawJsonButton";
44
import VerifiedBadge from '../VerifiedBadge';
5+
import {useSelector} from "react-redux";
56

67
export default function PendingCertificate(props) {
78
const [pendingCertificate, setPendingCertificate] = useState({});
9+
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
810

911
useEffect(() => {
10-
if (!props.autoUpdate) {
12+
if (!autoUpdate) {
1113
return;
1214
}
1315

@@ -26,7 +28,7 @@ export default function PendingCertificate(props) {
2628

2729
const interval = setInterval(fetchPendingCertificate, props.updateInterval);
2830
return () => clearInterval(interval);
29-
}, [props.aggregator, props.updateInterval, props.autoUpdate]);
31+
}, [props.aggregator, props.updateInterval, autoUpdate]);
3032

3133
return (
3234
<div className={props.className}>

mithril-explorer/components/SnapshotsList/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
22
import {Badge, Row, Col, Card, Container, Button, ListGroup, Stack} from "react-bootstrap";
33
import CertificateModal from '../CertificateModal';
44
import RawJsonButton from "../RawJsonButton";
5+
import {useSelector} from "react-redux";
56

67
/*
78
* Code from: https://stackoverflow.com/a/18650828
@@ -21,9 +22,10 @@ function formatBytes(bytes, decimals = 2) {
2122
export default function SnapshotsList(props) {
2223
const [snapshots, setSnapshots] = useState([]);
2324
const [selectedCertificateHash, setSelectedCertificateHash] = useState(undefined);
25+
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
2426

2527
useEffect(() => {
26-
if (!props.autoUpdate) {
28+
if (!autoUpdate) {
2729
return;
2830
}
2931

@@ -42,7 +44,7 @@ export default function SnapshotsList(props) {
4244

4345
const interval = setInterval(fetchSnapshots, props.updateInterval);
4446
return () => clearInterval(interval);
45-
}, [props.aggregator, props.updateInterval, props.autoUpdate]);
47+
}, [props.aggregator, props.updateInterval, autoUpdate]);
4648

4749
function handleCertificateHashChange(hash) {
4850
setSelectedCertificateHash(hash);

mithril-explorer/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12+
"@reduxjs/toolkit": "^1.9.0",
1213
"bootstrap": "^5.2.2",
1314
"bootstrap-icons": "^1.9.1",
1415
"next": "^13.0.2",
16+
"next-redux-wrapper": "^8.0.0",
1517
"react": "^18.2.0",
1618
"react-bootstrap": "^2.6.0",
17-
"react-dom": "^18.2.0"
19+
"react-dom": "^18.2.0",
20+
"react-redux": "^8.0.5"
1821
},
1922
"devDependencies": {
2023
"eslint": "^8.27.0",

mithril-explorer/pages/_app.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@ import 'bootstrap/dist/css/bootstrap.min.css';
22
import 'bootstrap-icons/font/bootstrap-icons.css';
33
import '../styles/globals.css'
44
import Script from "next/script";
5+
import { storeWrapper } from "../store/store";
6+
import {Provider} from "react-redux";
57

6-
function MithrilExplorer({ Component, pageProps }) {
7-
return (
8-
<>
9-
<Script id="plausible"
10-
strategy="afterInteractive"
11-
src="https://plausible.io/js/script.js"
12-
data-domain="mithril.network" />
13-
<Component {...pageProps} />
14-
</>
15-
)
8+
function MithrilExplorer({ Component, ...rest }) {
9+
const {store, pageProps} = storeWrapper.useWrappedStore(rest);
10+
11+
return (
12+
<>
13+
<Script id="plausible"
14+
strategy="afterInteractive"
15+
src="https://plausible.io/js/script.js"
16+
data-domain="mithril.network" />
17+
<Provider store={store}>
18+
<Component {...pageProps} />
19+
</Provider>
20+
</>
21+
);
1622
}
1723

18-
export default MithrilExplorer
24+
export default MithrilExplorer;

mithril-explorer/pages/index.js

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,23 @@ import AggregatorSetter from "../components/AggregatorSetter";
99
import available_aggregators from "../aggregators-list";
1010
import {useRouter} from "next/router";
1111
import EpochSettings from "../components/EpochSettings";
12+
import {useDispatch, useSelector} from "react-redux";
13+
import {toggleAutoUpdate} from "../store/settingsSlice";
1214

1315
function IntervalSetter(props) {
16+
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
17+
const dispatch = useDispatch();
18+
1419
function handleChange(event) {
1520
props.onIntervalChange(parseInt(event.target.value));
1621
}
1722

18-
function handleClick() {
19-
props.onStartStopPress(!props.isStartStopPressed);
20-
}
21-
2223
return (
2324
<Form.Group as={Col} className={props.className}>
2425
<Form.Label>Update Interval:</Form.Label>
2526
<InputGroup>
26-
<Button type="button" onClick={handleClick} variant={props.isStartStopPressed ? "primary" : "success"}>
27-
{props.isStartStopPressed ? "Pause ⏸" : "Resume ▶"}
27+
<Button type="button" onClick={() => dispatch(toggleAutoUpdate())} variant={autoUpdate ? "primary" : "success"}>
28+
{autoUpdate ? "Pause ⏸" : "Resume ▶"}
2829
</Button>
2930
<Form.Select value={props.interval} onChange={handleChange}>
3031
<option value={1000}>1 seconds</option>
@@ -40,15 +41,15 @@ export default function Explorer() {
4041
const router = useRouter();
4142
const [aggregator, setAggregator] = useState(available_aggregators[0]);
4243
const [interval, setInterval] = useState(10000);
43-
const [autoUpdate, setAutoUpdate] = useState(true);
44+
const autoUpdate = useSelector((state) => state.settings.autoUpdate);
4445

4546
useEffect(() => {
4647
if (router.query?.aggregator && router.query?.aggregator !== aggregator) {
47-
const autoUpdateState = autoUpdate;
48+
// const autoUpdateState = autoUpdate;
4849

49-
setAutoUpdate(false);
50+
// setAutoUpdate(false);
5051
setAggregator(router.query.aggregator);
51-
setAutoUpdate(autoUpdateState);
52+
// setAutoUpdate(autoUpdateState);
5253
}
5354
}, [router.query]);
5455

@@ -57,10 +58,6 @@ export default function Explorer() {
5758
router.push({query: {aggregator: api}}).then(() => {});
5859
}
5960

60-
function handleStartStopButtonPress(isPressed) {
61-
setAutoUpdate(isPressed);
62-
}
63-
6461
function handleIntervalChange(interval) {
6562
setInterval(interval);
6663
}
@@ -85,17 +82,15 @@ export default function Explorer() {
8582
defaultAvailableAggregators={available_aggregators} />
8683
<IntervalSetter
8784
interval={interval}
88-
onIntervalChange={handleIntervalChange}
89-
isStartStopPressed={autoUpdate}
90-
onStartStopPress={handleStartStopButtonPress} />
85+
onIntervalChange={handleIntervalChange} />
9186
</Row>
9287
</Form>
9388
<Row>
9489
<Col>
95-
<EpochSettings aggregator={aggregator} updateInterval={interval} autoUpdate={autoUpdate} />
90+
<EpochSettings aggregator={aggregator} updateInterval={interval} />
9691
</Col>
9792
<Col xs={8}>
98-
<PendingCertificate aggregator={aggregator} updateInterval={interval} autoUpdate={autoUpdate} />
93+
<PendingCertificate aggregator={aggregator} updateInterval={interval} />
9994
</Col>
10095
</Row>
10196
<SnapshotsList aggregator={aggregator} updateInterval={interval} autoUpdate={autoUpdate} />
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {createSlice} from "@reduxjs/toolkit";
2+
import available_aggregators from "../aggregators-list";
3+
4+
export const settingsSlice = createSlice({
5+
name: 'settings',
6+
initialState: {
7+
aggregator: available_aggregators[0],
8+
interval: 10000,
9+
autoUpdate: true,
10+
},
11+
reducers: {
12+
setFetchInterval: (state, action) => {
13+
state.interval = state.value;
14+
},
15+
toggleAutoUpdate: (state) => {
16+
state.autoUpdate = !state.autoUpdate;
17+
},
18+
}
19+
});
20+
21+
export const { setFetchInterval, toggleAutoUpdate } = settingsSlice.actions;
22+
23+
export default settingsSlice.reducer;

mithril-explorer/store/store.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { configureStore } from "@reduxjs/toolkit";
2+
import { createWrapper } from "next-redux-wrapper";
3+
import {settingsSlice} from "./settingsSlice";
4+
5+
const makeStore = () => configureStore({
6+
reducer: {
7+
settings: settingsSlice.reducer,
8+
},
9+
})
10+
11+
export const storeWrapper = createWrapper(makeStore);

0 commit comments

Comments
 (0)