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