aboutsummaryrefslogtreecommitdiff
path: root/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx')
-rwxr-xr-xusers/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx154
1 files changed, 154 insertions, 0 deletions
diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx
new file mode 100755
index 0000000..c7bedcd
--- /dev/null
+++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx
@@ -0,0 +1,154 @@
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 useWidgetRefresh from "../../hooks/use-widget-refresh";
6import useServerSocket from "../../hooks/use-server-socket";
7import { useSimpleBarContext } from "../simple-bar-context.jsx";
8import * as Utils from "../../utils";
9
10export { wifiStyles as styles } from "../../styles/components/data/wifi";
11
12const { React } = Uebersicht;
13
14const DEFAULT_REFRESH_FREQUENCY = 20000;
15
16/**
17 * Wifi widget component.
18 * @returns {JSX.Element|null} The Wifi widget.
19 */
20export const Widget = React.memo(() => {
21 const { displayIndex, settings, pushMissive } = useSimpleBarContext();
22 const { widgets, networkWidgetOptions } = settings;
23 const { wifiWidget } = widgets;
24 const {
25 refreshFrequency,
26 hideWifiIfDisabled,
27 toggleWifiOnClick,
28 networkDevice,
29 hideNetworkName,
30 showOnDisplay,
31 showIcon,
32 } = networkWidgetOptions;
33 const visible =
34 Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && wifiWidget;
35
36 const refresh = React.useMemo(
37 () =>
38 Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY),
39 [refreshFrequency],
40 );
41
42 const [state, setState] = React.useState();
43 const [loading, setLoading] = React.useState(visible);
44
45 /**
46 * Resets the widget state.
47 */
48 const resetWidget = () => {
49 setState(undefined);
50 setLoading(false);
51 };
52
53 /**
54 * Fetches the wifi status and SSID.
55 */
56 const getWifi = React.useCallback(async () => {
57 if (!visible) return;
58 const [status, ssid] = await Promise.all([
59 Utils.cachedRun(
60 `ifconfig ${networkDevice} | grep status | cut -c 10-`,
61 refresh,
62 ),
63 Utils.cachedRun(
64 `system_profiler SPAirPortDataType | awk '/Current Network/ {getline;$1=$1;print $0 | "tr -d ':'";exit}'`,
65 refresh,
66 ),
67 ]);
68 setState({
69 status: Utils.cleanupOutput(status),
70 ssid: Utils.cleanupOutput(ssid),
71 });
72 setLoading(false);
73 }, [networkDevice, visible, refresh]);
74
75 useServerSocket("wifi", visible, getWifi, resetWidget, setLoading);
76 useWidgetRefresh(visible, getWifi, refresh);
77
78 if (loading) return <DataWidgetLoader.Widget className="wifi" />;
79 if (!state) return null;
80
81 const { status, ssid } = state;
82 const isActive = status === "active";
83 const name = renderName(ssid, hideNetworkName);
84
85 if (hideWifiIfDisabled && !isActive) return null;
86
87 const classes = Utils.classNames("wifi", {
88 "wifi--hidden-name": !name,
89 "wifi--inactive": !isActive,
90 });
91
92 const Icon = isActive ? Icons.Wifi : Icons.WifiOff;
93
94 /**
95 * Handles the click event to toggle wifi.
96 * @param {React.MouseEvent} e - The click event.
97 */
98 const onClick = async (e) => {
99 Utils.clickEffect(e);
100 await toggleWifi(isActive, networkDevice, pushMissive);
101 getWifi();
102 };
103
104 return (
105 <DataWidget.Widget
106 classes={classes}
107 Icon={showIcon ? Icon : null}
108 onClick={toggleWifiOnClick ? onClick : undefined}
109 onRightClick={openWifiPreferences}
110 >
111 {name}
112 </DataWidget.Widget>
113 );
114});
115
116Widget.displayName = "Wifi";
117
118/**
119 * Toggles the wifi on or off.
120 * @param {boolean} isActive - Whether the wifi is currently active.
121 * @param {string} networkDevice - The network device name.
122 * @param {function} pushMissive - Function to push notifications.
123 */
124async function toggleWifi(isActive, networkDevice, pushMissive) {
125 if (isActive) {
126 await Uebersicht.run(`networksetup -setairportpower ${networkDevice} off`);
127 Utils.notification("Disabling network...", pushMissive);
128 } else {
129 await Uebersicht.run(`networksetup -setairportpower ${networkDevice} on`);
130 Utils.notification("Enabling network...", pushMissive);
131 }
132}
133
134/**
135 * Opens the wifi preferences pane.
136 * @param {React.MouseEvent} e - The click event.
137 */
138function openWifiPreferences(e) {
139 Utils.clickEffect(e);
140 Uebersicht.run(`open /System/Library/PreferencePanes/Network.prefPane/`);
141}
142
143/**
144 * Renders the wifi network name.
145 * @param {string} name - The network name.
146 * @param {boolean} hideNetworkName - Whether to hide the network name.
147 * @returns {string} The rendered network name.
148 */
149function renderName(name, hideNetworkName) {
150 if (!name || hideNetworkName) return "";
151 if (name === "with an AirPort network.y off.") return "Disabled";
152 if (name === "with an AirPort network.") return "Searching...";
153 return name;
154}