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/simple-bar-context.jsx | 131 +++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/simple-bar-context.jsx (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components/simple-bar-context.jsx') diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/simple-bar-context.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/simple-bar-context.jsx new file mode 100755 index 0000000..7cab27a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/simple-bar-context.jsx @@ -0,0 +1,131 @@ +import * as Uebersicht from "uebersicht"; +import * as Aerospace from "../aerospace.js"; + +const { React } = Uebersicht; + +// Create a context with default values +const SimpleBarContext = React.createContext({ + display: 1, + SIPDisabled: false, + settings: {}, + setSettings: () => {}, +}); + +/** + * Custom hook to use the SimpleBarContext + * @returns {Object} The context value + */ +export function useSimpleBarContext() { + return React.useContext(SimpleBarContext); +} + +/** + * Provides context for simple-bar. + * + * @param {Object} props - The properties object. + * @param {Object} props.initialSettings - The initial settings for the application. + * @param {Array} props.displays - The initial displays configuration. + * @param {boolean} props.SIPDisabled - Indicates if SIP (System Integrity Protection) is disabled. + * @param {React.ReactNode} props.children - The child components to be wrapped by the provider. + * + * @returns {JSX.Element} The context provider component. + */ +export default function SimpleBarContextProvider({ + initialSettings, + displays, + SIPDisabled, + children, +}) { + const [settings, setSettings] = React.useState(initialSettings); + const [_displays, setDisplays] = React.useState(displays); + const [missives, setMissives] = React.useState([]); + const [ubersichtScreens, setUbersichtScreens] = React.useState([]); + + const { windowManager, enableServer, yabaiServerRefresh } = settings.global; + const serverEnabled = enableServer && yabaiServerRefresh; + const isYabai = windowManager === "yabai"; + + const currentDisplays = serverEnabled && isYabai ? _displays : displays; + + const ubersichtDisplayId = parseInt( + window.location.pathname.replace("/", ""), + 10, + ); + + // Fetch Übersicht's active screen list from /state/ + React.useEffect(() => { + if (isYabai) return undefined; + + const controller = new AbortController(); + + const loadScreens = async () => { + try { + const response = await fetch("/state/", { signal: controller.signal }); + if (!response.ok) throw new Error("Failed to load /state/"); + const state = await response.json(); + setUbersichtScreens(Array.isArray(state?.screens) ? state.screens : []); + } catch (error) { + if (error?.name !== "AbortError") { + setUbersichtScreens([]); + } + } + }; + + loadScreens(); + return () => controller.abort(); + }, [displays, isYabai]); + + // Derive the current display rank from the active Übersicht screen order. + // This handles phantom displays (closed lid, previously connected monitors) + // that Übersicht still counts but AeroSpace doesn't report. + const currentScreenRank = ubersichtScreens.indexOf(ubersichtDisplayId) + 1; + + // Match the current display using either the yabai display ID or AeroSpace's custom display index logic. + const currentDisplay = + currentDisplays?.find((display) => + isYabai + ? display.id === ubersichtDisplayId + : Aerospace.getDisplayIndex(display) === currentScreenRank, + ) || {}; + + // Determine the display index for context value + // currentDisplay.index is from yabai + // Aerospace.getDisplayIndex is from AeroSpace with custom logic + // Fallback to AeroSpace monitor-appkit-nsscreen-screens-id or default to 1 + const displayIndex = + currentDisplay.index ?? Aerospace.getDisplayIndex(currentDisplay) ?? 1; + + const pushMissive = (newMissive) => { + const now = Date.now(); + const { content, side = "right", delay = 5000 } = newMissive; + const timeout = + typeof delay === "number" && delay !== 0 + ? setTimeout(() => { + setMissives((current) => { + return current.filter((m) => m.id !== now); + }); + }, delay) + : undefined; + setMissives((current) => { + return [...current, { id: now, content, side, timeout }]; + }); + }; + + return ( + + {children} + + ); +} -- cgit v1.3