From d06784958d73159b5e4abafe5114804662114ed7 Mon Sep 17 00:00:00 2001 From: Ryan Schanzenbacher Date: Thu, 9 Jul 2026 22:15:53 -0400 Subject: move ubersicht modules in tree --- .../lib/components/data/viscosity-vpn.jsx | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/viscosity-vpn.jsx (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/viscosity-vpn.jsx') diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/viscosity-vpn.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/viscosity-vpn.jsx new file mode 100755 index 0000000..340c59b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/viscosity-vpn.jsx @@ -0,0 +1,144 @@ +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 { viscosityVPNStyles as styles } from "../../styles/components/data/viscosity-vpn"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 8000; + +/** + * Viscosity VPN Widget component. + * @returns {JSX.Element|null} The Viscosity VPN widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings, pushMissive } = useSimpleBarContext(); + const { widgets, vpnWidgetOptions } = settings; + const { vpnWidget } = widgets; + const { + refreshFrequency, + vpnConnectionName, + vpnShowConnectionName, + showOnDisplay, + showIcon, + } = vpnWidgetOptions; + + // Determine the refresh frequency for the widget + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + // Determine if the widget should be visible + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && vpnWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + const [isViscosityActive, setIsViscosityActive] = React.useState(false); + + /** + * Reset the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + setIsViscosityActive(false); + }; + + /** + * Fetch the current VPN status. + */ + const getVPN = React.useCallback(async () => { + if (!visible) return; + const isRunning = await Utils.cachedRun( + `pgrep -xq 'Viscosity' && echo "true" || echo "false"`, + refresh, + ); + if (Utils.cleanupOutput(isRunning) === "false") { + setLoading(false); + setIsViscosityActive(false); + return; + } + const status = await Utils.cachedRun( + `osascript -e "tell application \\"Viscosity\\" to return state of the first connection where name is equal to \\"${vpnConnectionName}\\"" 2>/dev/null`, + refresh, + ); + if (!status.length) return; + setState({ status: Utils.cleanupOutput(status) }); + setIsViscosityActive(true); + setLoading(false); + }, [visible, vpnConnectionName, refresh]); + + // Use server socket to listen for VPN status updates + useServerSocket("viscosity-vpn", visible, getVPN, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getVPN, refresh); + + if (loading) return ; + if (!state || !vpnConnectionName.length || !isViscosityActive) return null; + + const { status } = state; + const isConnected = status === "Connected"; + + const classes = Utils.classNames("viscosity-vpn", { + "viscosity-vpn--disconnected": !isConnected, + }); + + const Icon = isConnected ? Icons.VPN : Icons.VPNOff; + + /** + * Handle click event to toggle VPN connection. + * @param {Event} e - The click event. + */ + const clicked = (e) => { + Utils.clickEffect(e); + toggleVPN(isConnected, vpnConnectionName, pushMissive); + setTimeout(getVPN, refreshFrequency / 2); + }; + + return ( + + {vpnShowConnectionName ? vpnConnectionName : status} + + ); +}); + +Widget.displayName = "ViscosityVPN"; + +/** + * Toggle the VPN connection. + * @param {boolean} isConnected - Whether the VPN is currently connected. + * @param {string} vpnConnectionName - The name of the VPN connection. + * @param {function} pushMissive - Function to push notifications. + */ +function toggleVPN(isConnected, vpnConnectionName, pushMissive) { + if (isConnected) { + Uebersicht.run( + `osascript -e 'tell application "Viscosity" to disconnect "${vpnConnectionName}"'`, + ); + Utils.notification( + `Disabling Viscosity ${vpnConnectionName} network...`, + pushMissive, + ); + } else { + Uebersicht.run( + `osascript -e 'tell application "Viscosity" to connect "${vpnConnectionName}"'`, + ); + Utils.notification( + `Enabling Viscosity ${vpnConnectionName} network...`, + pushMissive, + ); + } +} -- cgit v1.3