diff options
Diffstat (limited to 'users/ryan/modules/simple-bar/simple-bar-source/index.jsx')
| -rwxr-xr-x | users/ryan/modules/simple-bar/simple-bar-source/index.jsx | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/users/ryan/modules/simple-bar/simple-bar-source/index.jsx b/users/ryan/modules/simple-bar/simple-bar-source/index.jsx new file mode 100755 index 0000000..bc817ab --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/index.jsx | |||
| @@ -0,0 +1,267 @@ | |||
| 1 | import * as Uebersicht from "uebersicht"; | ||
| 2 | import * as Error from "./lib/components/error.jsx"; | ||
| 3 | import SimpleBarContextProvider from "./lib/components/simple-bar-context.jsx"; | ||
| 4 | import UserWidgets from "./lib/components/data/user-widgets.jsx"; | ||
| 5 | // Each simple-bar widgets exports both a "Component" or "Widget" render function | ||
| 6 | // and a "styles" string containing its own CSS | ||
| 7 | import * as Variables from "./lib/styles/core/variables"; | ||
| 8 | import * as Base from "./lib/styles/core/base"; | ||
| 9 | import * as Spaces from "./lib/styles/components/spaces/spaces"; | ||
| 10 | import * as Process from "./lib/styles/components/process"; | ||
| 11 | import * as Zoom from "./lib/components/data/zoom.jsx"; | ||
| 12 | import * as Time from "./lib/components/data/time.jsx"; | ||
| 13 | import * as DateDisplay from "./lib/components/data/date-display.jsx"; | ||
| 14 | import * as GitHub from "./lib/components/data/github.jsx"; | ||
| 15 | import * as Weather from "./lib/components/data/weather.jsx"; | ||
| 16 | import * as Netstats from "./lib/components/data/netstats.jsx"; | ||
| 17 | import * as Cpu from "./lib/components/data/cpu.jsx"; | ||
| 18 | import * as Gpu from "./lib/components/data/gpu.jsx"; | ||
| 19 | import * as Memory from "./lib/components/data/memory.jsx"; | ||
| 20 | import * as Battery from "./lib/components/data/battery.jsx"; | ||
| 21 | import * as Sound from "./lib/components/data/sound.jsx"; | ||
| 22 | import * as Mic from "./lib/components/data/mic.jsx"; | ||
| 23 | import * as Wifi from "./lib/components/data/wifi.jsx"; | ||
| 24 | import * as ViscosityVPN from "./lib/components/data/viscosity-vpn.jsx"; | ||
| 25 | import * as Keyboard from "./lib/components/data/keyboard.jsx"; | ||
| 26 | import * as Spotify from "./lib/components/data/spotify.jsx"; | ||
| 27 | import * as YouTubeMusic from "./lib/components/data/youtube-music.jsx"; | ||
| 28 | import * as Crypto from "./lib/components/data/crypto.jsx"; | ||
| 29 | import * as Stock from "./lib/components/data/stock.jsx"; | ||
| 30 | import * as Music from "./lib/components/data/music.jsx"; | ||
| 31 | import * as Mpd from "./lib/components/data/mpd.jsx"; | ||
| 32 | import * as BrowserTrack from "./lib/components/data/browser-track.jsx"; | ||
| 33 | import * as Notifications from "./lib/components/data/notifications.jsx"; | ||
| 34 | import * as NextMeeting from "./lib/components/data/next-meeting.jsx"; | ||
| 35 | import * as Specter from "./lib/components/data/specter.jsx"; | ||
| 36 | import * as Graph from "./lib/components/data/graph.jsx"; | ||
| 37 | import * as DataWidgetLoader from "./lib/components/data/data-widget-loader.jsx"; | ||
| 38 | import * as DataWidget from "./lib/components/data/data-widget.jsx"; | ||
| 39 | import * as SideIcon from "./lib/components/side-icon.jsx"; | ||
| 40 | import * as Missives from "./lib/components/missives/missives.jsx"; | ||
| 41 | import * as Utils from "./lib/utils"; | ||
| 42 | import * as Settings from "./lib/settings"; | ||
| 43 | |||
| 44 | // Destructure React from Uebersicht in order to make eslint catch hook rules for example | ||
| 45 | const { React } = Uebersicht; | ||
| 46 | |||
| 47 | // Spaces & process components are lazy loaded to avoid loading them when not needed | ||
| 48 | const YabaiContextProvider = React.lazy( | ||
| 49 | () => import("./lib/components/yabai-context.jsx"), | ||
| 50 | ); | ||
| 51 | const AerospaceContextProvider = React.lazy( | ||
| 52 | () => import("./lib/components/aerospace-context.jsx"), | ||
| 53 | ); | ||
| 54 | const YabaiSpaces = React.lazy( | ||
| 55 | () => import("./lib/components/yabai/spaces.jsx"), | ||
| 56 | ); | ||
| 57 | const YabaiProcess = React.lazy( | ||
| 58 | () => import("./lib/components/yabai/process.jsx"), | ||
| 59 | ); | ||
| 60 | const AerospaceSpaces = React.lazy( | ||
| 61 | () => import("./lib/components/aerospace/spaces.jsx"), | ||
| 62 | ); | ||
| 63 | const AerospaceProcess = React.lazy( | ||
| 64 | () => import("./lib/components/aerospace/process.jsx"), | ||
| 65 | ); | ||
| 66 | |||
| 67 | // Set refresh frequency to false | ||
| 68 | // Übersicht auto-refresh system is not required as simple-bar works in sync with | ||
| 69 | // yabai or AeroSpaces for spaces & process widgets and data widgets are refreshed with | ||
| 70 | // their local refresh functions | ||
| 71 | const refreshFrequency = false; | ||
| 72 | |||
| 73 | // Init settings from file if existing | ||
| 74 | Settings.init(); | ||
| 75 | |||
| 76 | // Get settings from the Settings module | ||
| 77 | const settings = Settings.get(); | ||
| 78 | const { | ||
| 79 | // Do not edit the yabaiPath or aerospacePath lines, theses values are simply | ||
| 80 | // a default value used if nothing is defined in settings. | ||
| 81 | // You can setup your custom yabai or AeroSpace path in the settings module (Global tab) : | ||
| 82 | // while on an empty workspace, click on simple-bar then press cmd + , to open it. | ||
| 83 | yabaiPath = "/opt/homebrew/bin/yabai", | ||
| 84 | aerospacePath = "/opt/homebrew/bin/aerospace", | ||
| 85 | windowManager, // Window manager type (yabai or aerospace) | ||
| 86 | shell, // Shell to use for commands | ||
| 87 | enableServer, // Enable server mode | ||
| 88 | yabaiServerRefresh, // Refresh rate for yabai server | ||
| 89 | } = settings.global; | ||
| 90 | const { hideWindowTitle, displayOnlyIcon, displaySkhdMode } = settings.process; | ||
| 91 | |||
| 92 | // Determine if signals should be disabled based on settings | ||
| 93 | const disableSignals = enableServer && yabaiServerRefresh; | ||
| 94 | const enableTitleChangedSignal = !hideWindowTitle && !displayOnlyIcon; | ||
| 95 | |||
| 96 | // Construct command arguments based on window manager type | ||
| 97 | const yabaiArgs = `${yabaiPath} ${displaySkhdMode} ${disableSignals} ${enableTitleChangedSignal}`; | ||
| 98 | const aerospaceArgs = `${aerospacePath}`; | ||
| 99 | const args = getArguments(windowManager, yabaiArgs, aerospaceArgs); | ||
| 100 | const command = `${shell} simple-bar/lib/scripts/init-${windowManager}.sh ${args}`; | ||
| 101 | |||
| 102 | // Inject global styles into the document | ||
| 103 | // I prefer using native CSS instead of Emotion bundled by default in Übersicht | ||
| 104 | Utils.injectStyles("simple-bar-index-styles", [ | ||
| 105 | Variables.styles, | ||
| 106 | Base.styles, | ||
| 107 | Spaces.styles, | ||
| 108 | Process.styles, | ||
| 109 | Settings.styles, | ||
| 110 | DataWidget.styles, | ||
| 111 | DateDisplay.styles, | ||
| 112 | Zoom.styles, | ||
| 113 | Time.styles, | ||
| 114 | GitHub.styles, | ||
| 115 | Weather.styles, | ||
| 116 | Netstats.styles, | ||
| 117 | Cpu.styles, | ||
| 118 | Gpu.styles, | ||
| 119 | Memory.styles, | ||
| 120 | Crypto.styles, | ||
| 121 | Stock.styles, | ||
| 122 | Battery.styles, | ||
| 123 | Wifi.styles, | ||
| 124 | ViscosityVPN.styles, | ||
| 125 | Keyboard.styles, | ||
| 126 | Mic.styles, | ||
| 127 | Sound.styles, | ||
| 128 | Spotify.styles, | ||
| 129 | YouTubeMusic.styles, | ||
| 130 | Music.styles, | ||
| 131 | Mpd.styles, | ||
| 132 | BrowserTrack.styles, | ||
| 133 | Notifications.styles, | ||
| 134 | NextMeeting.styles, | ||
| 135 | Specter.styles, | ||
| 136 | Graph.styles, | ||
| 137 | DataWidgetLoader.styles, | ||
| 138 | settings.customStyles.styles, | ||
| 139 | SideIcon.styles, | ||
| 140 | Missives.styles, | ||
| 141 | ]); | ||
| 142 | |||
| 143 | // Render function to display the bar | ||
| 144 | function render({ output, error }) { | ||
| 145 | // Define base classes for the bar based on settings | ||
| 146 | const baseClasses = Utils.classNames("simple-bar", { | ||
| 147 | "simple-bar--floating": settings.global.floatingBar, | ||
| 148 | "simple-bar--no-bar-background": settings.global.noBarBg, | ||
| 149 | "simple-bar--no-color-in-data": settings.global.noColorInData, | ||
| 150 | "simple-bar--on-bottom": settings.global.bottomBar, | ||
| 151 | "simple-bar--inline-spaces-options": settings.global.inlineSpacesOptions, | ||
| 152 | "simple-bar--animations-disabled": settings.global.disableAnimations, | ||
| 153 | "simple-bar--spaces-background-color-as-foreground": | ||
| 154 | settings.global.spacesBackgroundColorAsForeground, | ||
| 155 | "simple-bar--widgets-background-color-as-foreground": | ||
| 156 | settings.global.widgetsBackgroundColorAsForeground, | ||
| 157 | "simple-bar--process-aligned-to-left": !settings.global.centered, | ||
| 158 | }); | ||
| 159 | |||
| 160 | // Handle errors | ||
| 161 | if (error) { | ||
| 162 | // eslint-disable-next-line no-console | ||
| 163 | console.error("Error in index.jsx", error); | ||
| 164 | return <Error.Component type="error" classes={baseClasses} />; | ||
| 165 | } | ||
| 166 | if (!output) { | ||
| 167 | return <Error.Component type="noOutput" classes={baseClasses} />; | ||
| 168 | } | ||
| 169 | |||
| 170 | // Cleanup the output data | ||
| 171 | const cleanedUpOutput = Utils.cleanupOutput(output); | ||
| 172 | |||
| 173 | // Handle specific errors related to yabai or AeroSpace | ||
| 174 | const errors = ["yabaiError", "aerospaceError"]; | ||
| 175 | if (errors.includes(cleanedUpOutput)) { | ||
| 176 | return <Error.Component type={cleanedUpOutput} classes={baseClasses} />; | ||
| 177 | } | ||
| 178 | |||
| 179 | // Parse the output data | ||
| 180 | const data = Utils.parseJson(cleanedUpOutput); | ||
| 181 | if (!data) return <Error.Component type="noData" classes={baseClasses} />; | ||
| 182 | |||
| 183 | const { displays, shadow, skhdMode, SIP, spaces, windows } = data; | ||
| 184 | |||
| 185 | // Check if SIP (System Integrity Protection) is disabled | ||
| 186 | const SIPDisabled = SIP !== "System Integrity Protection status: enabled."; | ||
| 187 | |||
| 188 | // Define additional classes based on data | ||
| 189 | const classes = Utils.classNames(baseClasses, { | ||
| 190 | "simple-bar--no-shadow": shadow !== "on", | ||
| 191 | }); | ||
| 192 | |||
| 193 | // Handle bar focus ring on click | ||
| 194 | Utils.handleBarFocus(); | ||
| 195 | |||
| 196 | // Render the bar with appropriate components and data | ||
| 197 | return ( | ||
| 198 | <SimpleBarContextProvider | ||
| 199 | initialSettings={settings} | ||
| 200 | displays={displays} | ||
| 201 | SIPDisabled={SIPDisabled} | ||
| 202 | > | ||
| 203 | <div className={classes}> | ||
| 204 | <SideIcon.Component /> | ||
| 205 | <React.Suspense fallback={<React.Fragment />}> | ||
| 206 | {windowManager === "yabai" && ( | ||
| 207 | <YabaiContextProvider | ||
| 208 | spaces={spaces} | ||
| 209 | windows={windows} | ||
| 210 | skhdMode={skhdMode} | ||
| 211 | > | ||
| 212 | <YabaiSpaces /> | ||
| 213 | <YabaiProcess /> | ||
| 214 | </YabaiContextProvider> | ||
| 215 | )} | ||
| 216 | {windowManager === "aerospace" && ( | ||
| 217 | <AerospaceContextProvider> | ||
| 218 | <AerospaceSpaces /> | ||
| 219 | <AerospaceProcess /> | ||
| 220 | </AerospaceContextProvider> | ||
| 221 | )} | ||
| 222 | </React.Suspense> | ||
| 223 | <Settings.Wrapper /> | ||
| 224 | <div className="simple-bar__data"> | ||
| 225 | <UserWidgets /> | ||
| 226 | <Zoom.Widget /> | ||
| 227 | <BrowserTrack.Widget /> | ||
| 228 | <Spotify.Widget /> | ||
| 229 | <YouTubeMusic.Widget /> | ||
| 230 | <Crypto.Widget /> | ||
| 231 | <Stock.Widget /> | ||
| 232 | <Music.Widget /> | ||
| 233 | <Mpd.Widget /> | ||
| 234 | <GitHub.Widget /> | ||
| 235 | <Weather.Widget /> | ||
| 236 | <Netstats.Widget /> | ||
| 237 | <Cpu.Widget /> | ||
| 238 | <Gpu.Widget /> | ||
| 239 | <Memory.Widget /> | ||
| 240 | <Battery.Widget /> | ||
| 241 | <Notifications.Widget /> | ||
| 242 | <NextMeeting.Widget /> | ||
| 243 | <Mic.Widget /> | ||
| 244 | <Sound.Widget /> | ||
| 245 | <ViscosityVPN.Widget /> | ||
| 246 | <Wifi.Widget /> | ||
| 247 | <Keyboard.Widget /> | ||
| 248 | <DateDisplay.Widget /> | ||
| 249 | <Time.Widget /> | ||
| 250 | </div> | ||
| 251 | <Missives.Component /> | ||
| 252 | </div> | ||
| 253 | </SimpleBarContextProvider> | ||
| 254 | ); | ||
| 255 | } | ||
| 256 | |||
| 257 | export { command, refreshFrequency, render }; | ||
| 258 | |||
| 259 | function getArguments(windowManager, yabaiArgs, aerospaceArgs) { | ||
| 260 | if (windowManager === "yabai") { | ||
| 261 | return yabaiArgs; | ||
| 262 | } | ||
| 263 | if (windowManager === "aerospace") { | ||
| 264 | return aerospaceArgs; | ||
| 265 | } | ||
| 266 | return ""; | ||
| 267 | } | ||
