aboutsummaryrefslogtreecommitdiff
path: root/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx')
-rwxr-xr-xusers/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx182
1 files changed, 182 insertions, 0 deletions
diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx
new file mode 100755
index 0000000..ef3d7be
--- /dev/null
+++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx
@@ -0,0 +1,182 @@
1import * as Uebersicht from "uebersicht";
2import * as DataWidget from "./data-widget.jsx";
3import * as DataWidgetLoader from "./data-widget-loader.jsx";
4import * as Icons from "../icons/icons.jsx";
5import { SuspenseIcon } from "../icons/icon.jsx";
6import Graph from "./graph.jsx";
7import useWidgetRefresh from "../../hooks/use-widget-refresh.js";
8import useServerSocket from "../../hooks/use-server-socket";
9import { useSimpleBarContext } from "../simple-bar-context.jsx";
10import * as Utils from "../../utils.js";
11
12export { netstatsStyles as styles } from "../../styles/components/data/netstats";
13
14const { React } = Uebersicht;
15
16const DEFAULT_REFRESH_FREQUENCY = 2000;
17const GRAPH_LENGTH = 30;
18
19/**
20 * Netstats widget component.
21 * @returns {JSX.Element|null} The rendered component.
22 */
23export const Widget = React.memo(() => {
24 const { displayIndex, settings } = useSimpleBarContext();
25 const { widgets, netstatsWidgetOptions } = settings;
26 const { netstatsWidget } = widgets;
27 const {
28 refreshFrequency,
29 showOnDisplay,
30 displayAsGraph,
31 showIcon,
32 netstatsThreshold,
33 } = netstatsWidgetOptions;
34
35 const isDisabled = React.useRef(false);
36
37 // Determine the refresh frequency for the widget
38 const refresh = React.useMemo(
39 () =>
40 Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY),
41 [refreshFrequency],
42 );
43
44 // Determine if the widget should be visible
45 const visible =
46 Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && netstatsWidget;
47
48 const [graph, setGraph] = React.useState([]);
49 const [state, setState] = React.useState();
50 const [loading, setLoading] = React.useState(visible);
51
52 /**
53 * Resets the widget state.
54 */
55 const resetWidget = () => {
56 setState(undefined);
57 setLoading(false);
58 setGraph([]);
59 };
60
61 /**
62 * Fetches network statistics.
63 */
64 const getNetstats = React.useCallback(async () => {
65 if (!visible) return;
66 try {
67 const output = await Utils.cachedRun(
68 `bash ./simple-bar/lib/scripts/netstats.sh 2>&1`,
69 refresh,
70 );
71 if (!visible || isDisabled.current) {
72 return;
73 }
74 const data = Utils.cleanupOutput(output);
75 const json = JSON.parse(data);
76 setState(json);
77 if (displayAsGraph) {
78 Utils.addToGraphHistory(json, setGraph, GRAPH_LENGTH);
79 }
80 setLoading(false);
81 } catch {
82 setTimeout(getNetstats, 1000);
83 }
84 }, [displayAsGraph, setGraph, visible, refresh]);
85
86 // Update the disabled state based on visibility
87 React.useEffect(() => {
88 isDisabled.current = !visible;
89 }, [visible]);
90
91 // Set up server socket and widget refresh hooks
92 useServerSocket("netstats", visible, getNetstats, resetWidget, setLoading);
93 useWidgetRefresh(visible, getNetstats, refresh);
94
95 if (loading)
96 return (
97 <React.Fragment>
98 <DataWidgetLoader.Widget className="netstats" />
99 {!displayAsGraph && <DataWidgetLoader.Widget className="netstats" />}
100 </React.Fragment>
101 );
102
103 if (!state) {
104 return null;
105 }
106
107 const { download, upload } = state;
108
109 if (download === undefined || upload === undefined) {
110 return null;
111 }
112
113 const threshold = (Number(netstatsThreshold) || 0) * 1024;
114 const isBelowThreshold =
115 threshold > 0 &&
116 Math.abs(download) < threshold &&
117 Math.abs(upload) < threshold;
118
119 if (isBelowThreshold) {
120 return null;
121 }
122
123 const formattedDownload = Utils.formatBytes(download);
124 const formattedUpload = Utils.formatBytes(upload);
125
126 if (displayAsGraph) {
127 return (
128 <DataWidget.Widget classes="netstats netstats--graph" disableSlider>
129 <Graph
130 className="netstats__graph"
131 caption={{
132 download: {
133 value: formattedDownload,
134 icon: showIcon ? Icons.Download : null,
135 color: "var(--magenta)",
136 },
137 upload: {
138 value: formattedUpload,
139 icon: showIcon ? Icons.Upload : null,
140 color: "var(--blue)",
141 },
142 }}
143 values={graph}
144 maxLength={GRAPH_LENGTH}
145 />
146 </DataWidget.Widget>
147 );
148 }
149
150 return (
151 <React.Fragment>
152 <DataWidget.Widget classes="netstats" disableSlider>
153 <div className="netstats__item">
154 {showIcon && (
155 <SuspenseIcon>
156 <Icons.Download className="netstats__icon netstats__icon--download" />
157 </SuspenseIcon>
158 )}
159 <span
160 className="netstats__value"
161 dangerouslySetInnerHTML={{ __html: formattedDownload }}
162 />
163 </div>
164 </DataWidget.Widget>
165 <DataWidget.Widget classes="netstats" disableSlider>
166 <div className="netstats__item">
167 {showIcon && (
168 <SuspenseIcon>
169 <Icons.Upload className="netstats__icon netstats__icon--upload" />
170 </SuspenseIcon>
171 )}
172 <span
173 className="netstats__value"
174 dangerouslySetInnerHTML={{ __html: formattedUpload }}
175 />
176 </div>
177 </DataWidget.Widget>
178 </React.Fragment>
179 );
180});
181
182Widget.displayName = "Netstats";