aboutsummaryrefslogtreecommitdiff
path: root/users/ryan/modules/simple-bar/simple-bar-source/lib/settings.js
diff options
context:
space:
mode:
Diffstat (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/settings.js')
-rwxr-xr-xusers/ryan/modules/simple-bar/simple-bar-source/lib/settings.js1184
1 files changed, 1184 insertions, 0 deletions
diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/settings.js b/users/ryan/modules/simple-bar/simple-bar-source/lib/settings.js
new file mode 100755
index 0000000..55c53ff
--- /dev/null
+++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/settings.js
@@ -0,0 +1,1184 @@
1import * as Uebersicht from "uebersicht";
2import * as Themes from "./styles/themes";
3import * as Utils from "./utils";
4import UserWidgetsCreator from "./components/settings/user-widgets-creator.jsx";
5import AerospaceDisplayManager from "./components/settings/aerospace-display-manager.jsx";
6
7export { Component, styles, Wrapper } from "./components/settings/settings.jsx";
8
9const SETTINGS_STORAGE_KEY = "simple-bar-settings";
10
11// The available themes are retrieved from the Themes collection
12// They are then split into dark and light themes
13const availableThemes = Object.keys(Themes.collection).map((key) => {
14 const theme = Themes.collection[key];
15 return { code: key, name: theme.name, kind: theme.kind };
16});
17const darkThemes = availableThemes.filter((theme) => theme.kind === "dark");
18const lightThemes = availableThemes.filter((theme) => theme.kind === "light");
19
20// These are all the information displayed in the settings module
21export const data = {
22 global: {
23 label: "Global",
24 documentation: "/global-settings/",
25 infos: [
26 '- "<b>No bar background</b>" is visually better with the "Floating bar" option activated',
27 '- The higher the "<b>Sliding animation pace</b>" value, the faster the texts slides (must be > 0, default is set to 4)',
28 "<br/>",
29 '<b>"Use background color as foreground"</b>:',
30 "This setting will remove all background colors and use the removed color for all the foreground texts",
31 ],
32 },
33 theme: {
34 label: "theme",
35 type: "radio",
36 options: ["auto", "dark", "light"],
37 title: "Appearance & tweaks",
38 },
39 floatingBar: { label: "Floating bar", type: "checkbox" },
40 noBarBg: { label: "No bar background", type: "checkbox" },
41 noColorInData: { label: "No colors in data", type: "checkbox" },
42 bottomBar: { label: "Bottom bar", type: "checkbox" },
43 sideDecoration: { label: "Apple logo", type: "checkbox" },
44 inlineSpacesOptions: { label: "Inline spaces options", type: "checkbox" },
45 disableAnimations: {
46 label: "Disable persistent animations",
47 type: "checkbox",
48 },
49 enableMissives: {
50 label: "Use internal notification system (missives)",
51 type: "checkbox",
52 fullWidth: true,
53 },
54 disableNotifications: { label: "Disable notifications", type: "checkbox" },
55 compactMode: { label: "Compact mode", type: "checkbox" },
56 widgetMaxWidth: { label: "Widget max width", type: "text" },
57 widgetsBackgroundColorAsForeground: {
58 label: "Use background color as foreground for widgets",
59 type: "checkbox",
60 fullWidth: true,
61 },
62 spacesBackgroundColorAsForeground: {
63 label: "Use background color as foreground for spaces & process",
64 type: "checkbox",
65 fullWidth: true,
66 },
67 font: {
68 label: "Global font",
69 type: "text",
70 placeholder: "default: JetBrains Mono",
71 fullWidth: false,
72 },
73 fontSize: {
74 label: "Font size",
75 type: "text",
76 placeholder: "default: 11px",
77 fullWidth: false,
78 },
79 yabaiPath: {
80 label: "yabai path",
81 type: "text",
82 placeholder: "default: $(which yabai)",
83 fullWidth: true,
84 title: "Configuration",
85 },
86 aerospacePath: {
87 label: "Aerospace path",
88 type: "text",
89 placeholder: "default: $(which aerospace)",
90 fullWidth: true,
91 },
92 windowManager: {
93 title: "Which window or space manager are you using?",
94 label: "",
95 type: "radio",
96 options: ["yabai", "aerospace"],
97 },
98 shell: {
99 title: "With which shell do you want to execute simple-bar scripts?",
100 label: "",
101 type: "radio",
102 options: ["sh", "bash", "dash"],
103 },
104 terminal: {
105 title: "Which terminal should user facing commands be run in?",
106 label: "",
107 type: "radio",
108 options: ["Terminal", "iTerm2"],
109 },
110 slidingAnimationPace: {
111 label: "Sliding animation speed",
112 type: "number",
113 placeholder: "Default: 4",
114 fullWidth: true,
115 },
116 enableServer: {
117 label: "Enable simple-bar-server connection",
118 type: "checkbox",
119 fullWidth: true,
120 title: "simple-bar-server",
121 },
122 serverHttpPort: {
123 label: "simple-bar-server http port",
124 type: "number",
125 placeholder: "Default: 7776",
126 fullWidth: true,
127 },
128 serverSocketPort: {
129 label: "simple-bar-server socket port",
130 type: "number",
131 placeholder: "Default: 7777",
132 fullWidth: true,
133 },
134 yabaiServerRefresh: {
135 label: "Refresh yabai spaces & process with simple-bar-server",
136 type: "checkbox",
137 fullWidth: true,
138 },
139 aerospaceServerRefresh: {
140 label: "Refresh AeroSpace spaces with simple-bar-server",
141 type: "checkbox",
142 fullWidth: true,
143 },
144
145 themes: {
146 label: "Themes",
147 documentation: "/themes-settings/",
148 infos: [
149 "Colors defined here will override the selected theme. Leave it empty to use the theme colors.",
150 "<br/>",
151 "<b>You can use any valid CSS color:</b>",
152 "- named-color",
153 "- hex-color",
154 "- rgb()",
155 "- hsl()",
156 "- hwb()",
157 "<br/>",
158 "<b>Styles are applied in this order:</b>",
159 "- Theme",
160 "- Color overrides",
161 "- Custom styles",
162 "<br/>",
163 "The last one overrides the previous ones.",
164 ],
165 },
166 darkTheme: { label: "Dark theme", type: "select", options: darkThemes },
167 lightTheme: { label: "Light theme", type: "select", options: lightThemes },
168 colorMain: { label: "Main", type: "color", title: "Color overrides" },
169 colorMainAlt: { label: "Main alternative", type: "color" },
170 colorMinor: { label: "Minor", type: "color" },
171 colorAccent: { label: "Accent", type: "color" },
172 colorRed: { label: "Red", type: "color" },
173 colorGreen: { label: "Green", type: "color" },
174 colorYellow: { label: "Yellow", type: "color" },
175 colorOrange: { label: "Orange", type: "color" },
176 colorBlue: { label: "Blue", type: "color" },
177 colorMagenta: { label: "Magenta", type: "color" },
178 colorCyan: { label: "Cyan", type: "color" },
179 colorBlack: { label: "Black", type: "color" },
180 colorWhite: { label: "White", type: "color" },
181 colorForeground: { label: "Foreground", type: "color" },
182 colorBackground: { label: "Background", type: "color" },
183
184 process: {
185 label: "Process",
186 documentation: "/process-settings/",
187 },
188 displayForFocusedSpace: {
189 label:
190 "<em>yabai</em> Display for focused space instead of current display space (usefull when you have simple-bar on one display in multi-monitor setup)",
191 type: "checkbox",
192 fullWidth: true,
193 },
194 displayOnlyCurrent: {
195 label:
196 "<em>yabai</em> <em>AeroSpace</em> Display only current process name",
197 type: "checkbox",
198 fullWidth: true,
199 },
200 centered: {
201 label: "<em>yabai</em> <em>AeroSpace</em> Center process widget",
202 type: "checkbox",
203 },
204 showCurrentSpaceMode: {
205 label: "<em>yabai</em> Show current space mode (BSP, Stack, Float)",
206 type: "checkbox",
207 fullWidth: true,
208 },
209 hideWindowTitle: {
210 label:
211 "<em>yabai</em> <em>AeroSpace</em> Hide window titles (show only app name for each process)",
212 type: "checkbox",
213 fullWidth: true,
214 },
215 displayOnlyIcon: {
216 label: "<em>yabai</em> <em>AeroSpace</em> Display only process icon",
217 type: "checkbox",
218 fullWidth: true,
219 },
220 expandAllProcesses: {
221 label: "<em>yabai</em> <em>AeroSpace</em> Expand all processes",
222 type: "checkbox",
223 fullWidth: true,
224 },
225 displaySkhdMode: {
226 label:
227 "<em>yabai</em> Display current skhd mode (requires some configuration, see readme file)",
228 type: "checkbox",
229 fullWidth: true,
230 },
231 displayStackIndex: {
232 label:
233 "<em>yabai</em> Display stack-index for all processes in space (if greater than 0)",
234 type: "checkbox",
235 fullWidth: true,
236 },
237 displayOnlyCurrentStack: {
238 label: "<em>yabai</em> Display stack-index only for focused process",
239 type: "checkbox",
240 fullWidth: true,
241 },
242
243 spacesDisplay: {
244 label: "Spaces",
245 documentation: "/spaces-settings/",
246 infos: [
247 "You can declare here which apps to exclude from the spaces display",
248 'Each exclusion must be separated by a comma and a space ", "',
249 "These exclusions will also be applied on the process name display",
250 ],
251 },
252 exclusions: {
253 label: "<em>yabai</em> <em>AeroSpace</em> Exclusions by app name",
254 type: "text",
255 placeholder: "example: Finder, iTerm2",
256 fullWidth: true,
257 },
258 titleExclusions: {
259 label: "<em>yabai</em> <em>AeroSpace</em> Exclusions by window title name",
260 type: "text",
261 placeholder: "example: Preferences",
262 fullWidth: true,
263 },
264 spacesExclusions: {
265 label: "<em>yabai</em> <em>AeroSpace</em> Exclude spaces by space name",
266 type: "text",
267 placeholder: "example: Preferences",
268 fullWidth: true,
269 },
270 exclusionsAsRegex: {
271 label:
272 "<em>yabai</em> <em>AeroSpace</em> Use regex syntax in all exclusions fields",
273 type: "checkbox",
274 fullWidth: true,
275 },
276 displayAllSpacesOnAllScreens: {
277 label:
278 "<em>yabai</em> <em>AeroSpace</em> Display all spaces on all screens",
279 type: "checkbox",
280 fullWidth: true,
281 },
282 hideEmptySpaces: {
283 label: "<em>yabai</em> <em>AeroSpace</em> Hide empty spaces",
284 type: "checkbox",
285 },
286 showOptionsOnHover: {
287 label: "<em>yabai</em> Show space options on hover",
288 type: "checkbox",
289 fullWidth: true,
290 },
291 switchSpacesWithoutYabai: {
292 label: "<em>yabai</em> Switch spaces with ^â­ /^â­¢ instead of yabai",
293 type: "checkbox",
294 fullWidth: true,
295 },
296 hideDuplicateAppsInSpaces: {
297 label:
298 "<em>yabai</em> <em>AeroSpace</em> Hide duplicate app icons in same space",
299 type: "checkbox",
300 fullWidth: true,
301 },
302 displayStickyWindowsSeparately: {
303 label: "<em>yabai</em> Display sticky windows separately",
304 type: "checkbox",
305 fullWidth: true,
306 },
307 hideCreateSpaceButton: {
308 label: "<em>yabai</em> Hide create space button",
309 type: "checkbox",
310 fullWidth: true,
311 },
312 customAeroSpaceDisplayIndexes: {
313 label: "<em>AeroSpace</em> Custom AeroSpace display indexes",
314 type: "component",
315 Component: AerospaceDisplayManager,
316 },
317
318 widgets: {
319 label: "Widgets",
320 documentation: "/widgets/",
321 },
322 processWidget: { label: "Process name", type: "checkbox" },
323 zoomWidget: { label: "Zoom", type: "checkbox" },
324 timeWidget: { label: "Time", type: "checkbox" },
325 dateWidget: { label: "Date", type: "checkbox" },
326 wifiWidget: { label: "Network", type: "checkbox" },
327 vpnWidget: { label: "Viscosity VPN", type: "checkbox" },
328 micWidget: { label: "Microphone", type: "checkbox" },
329 soundWidget: { label: "Sound", type: "checkbox" },
330 githubWidget: { label: "GitHub", type: "checkbox" },
331 weatherWidget: { label: "Weather", type: "checkbox" },
332 netstatsWidget: { label: "Network stats", type: "checkbox" },
333 cpuWidget: { label: "CPU", type: "checkbox" },
334 gpuWidget: { label: "GPU", type: "checkbox" },
335 memoryWidget: { label: "Memory", type: "checkbox" },
336 batteryWidget: { label: "Battery", type: "checkbox" },
337 keyboardWidget: { label: "Keyboard", type: "checkbox" },
338 spotifyWidget: { label: "Spotify", type: "checkbox" },
339 youtubeMusicWidget: { label: "YouTube Music", type: "checkbox" },
340 cryptoWidget: { label: "Crypto", type: "checkbox" },
341 stockWidget: { label: "Stock", type: "checkbox" },
342 musicWidget: { label: "Music/iTunes", type: "checkbox" },
343 mpdWidget: { label: "MPD state via mpc", type: "checkbox" },
344 browserTrackWidget: { label: "Browser track", type: "checkbox" },
345 notificationsWidget: { label: "Notification badges", type: "checkbox" },
346 nextMeetingWidget: { label: "Next meeting", type: "checkbox" },
347
348 showOnDisplay: {
349 label: "Show on display n°",
350 type: "text",
351 placeholder: "example: 1,2 (leave blank to show on all displays)",
352 fullWidth: true,
353 },
354
355 githubWidgetOptions: {
356 label: "GitHub",
357 documentation: "/github/",
358 },
359 hideWhenNoNotification: {
360 label: "Hide widget when no notification",
361 type: "checkbox",
362 },
363 notificationUrl: {
364 label: "The URL opened on click",
365 type: "text",
366 placeholder: "example: https://github.com/notifications",
367 fullWidth: true,
368 },
369 ghBinaryPath: {
370 label: "Path to gh binary",
371 type: "text",
372 placeholder: "example: /opt/homebrew/bin/gh",
373 fullWidth: true,
374 },
375
376 weatherWidgetOptions: {
377 label: "Weather",
378 documentation: "/weather/",
379 infos: [
380 'Leave "Your location" blank in order to let simple-bar use your geolocation.',
381 "Doing so, you need to allow Übersicht access to your location: a popup should appear on first use.",
382 ],
383 },
384 showIcon: { label: "Show icon", type: "checkbox" },
385 unit: {
386 title: "Temperature unit",
387 label: "",
388 type: "radio",
389 options: ["C", "F"],
390 },
391 hideLocation: { label: "Hide location", type: "checkbox" },
392 hideGradient: { label: "Hide gradient", type: "checkbox" },
393 customLocation: {
394 label: "Your location",
395 type: "text",
396 placeholder: "example: Paris",
397 fullWidth: true,
398 },
399
400 netstatsWidgetOptions: {
401 label: "Network stats",
402 documentation: "/network-stats/",
403 infos: [
404 "Here you can set the refresh frequency of the widget.",
405 "The default value is set to 2000 ms (2 seconds).",
406 ],
407 },
408 netstatsThreshold: {
409 label: "Hide below (kb/s)",
410 type: "number",
411 placeholder: "0 to always show",
412 },
413
414 cpuWidgetOptions: {
415 label: "CPU usage",
416 documentation: "/cpu/",
417 infos: [
418 "Here you can set the refresh frequency of the widget.",
419 "The default value is set to 2000 ms (2 seconds).",
420 ],
421 },
422 cpuUsageThreshold: {
423 label: "Hide below (%)",
424 type: "number",
425 placeholder: "0 to always show",
426 },
427
428 gpuWidgetOptions: {
429 label: "GPU usage",
430 documentation: "/gpu/",
431 infos: [
432 "Here you can set the refresh frequency of the widget.",
433 "The default value is set to 2000 ms (2 seconds).",
434 ],
435 },
436
437 gpuMacmonBinaryPath: {
438 label: "Path to macmon binary",
439 type: "text",
440 placeholder: "example: /opt/homebrew/bin/macmon",
441 fullWidth: true,
442 },
443
444 memoryWidgetOptions: {
445 label: "Memory pressure",
446 documentation: "/memory-pressure/",
447 infos: [
448 "Here you can set the refresh frequency of the widget.",
449 "The default value is set to 4000 ms (4 seconds).",
450 ],
451 },
452 memoryUsageThreshold: {
453 label: "Hide below (%)",
454 type: "number",
455 placeholder: "0 to always show",
456 },
457
458 displayAsGraph: {
459 label: "Display as graph",
460 type: "checkbox",
461 fullWidth: true,
462 },
463
464 cpuMonitorApp: {
465 title: "Cpu monitor app",
466 label: "",
467 type: "radio",
468 options: ["Top", "Activity Monitor", "None"],
469 },
470
471 memoryMonitorApp: {
472 title: " app",
473 label: "",
474 type: "radio",
475 options: ["Top", "Activity Monitor", "None"],
476 },
477
478 batteryWidgetOptions: {
479 label: "Battery",
480 documentation: "/battery/",
481 infos: [
482 "no option (default) — Prevent the system from sleeping, not the display",
483 "-d — Prevent the display from sleeping.",
484 "-i — Prevent the system from idle sleeping.",
485 "-s — Prevent the system from sleeping. This is valid only when system is running on AC power.",
486 "-u — Declare that a user is active. If the display is off, this option turns the display on and prevents the display from going into idle sleep.",
487 "-t 60 — Specifies the timeout value in seconds for which the command is valid.",
488 ],
489 },
490
491 toggleCaffeinateOnClick: {
492 label: "Toggle caffeinate on click",
493 type: "checkbox",
494 fullWidth: true,
495 },
496 disableCaffeinateInvertedBackground: {
497 label: "Disable caffeinate inverted background",
498 type: "checkbox",
499 fullWidth: true,
500 },
501 caffeinateOption: {
502 label: "Caffeinate options",
503 type: "text",
504 placeholder: "example: -d",
505 },
506
507 networkWidgetOptions: {
508 label: "Network",
509 documentation: "/network/",
510 infos: [
511 "Here you can override the default displayed network source.",
512 "And also turn Wifi on / off when clicking the Wifi icon.",
513 "Additionally, you can choose to hide the network name for privacy.",
514 ],
515 },
516
517 networkDevice: {
518 label: "Network device source name",
519 type: "text",
520 placeholder: "example: en0",
521 },
522 hideWifiIfDisabled: { label: "Hide if disabled", type: "checkbox" },
523 toggleWifiOnClick: { label: "Toggle Wifi onclick", type: "checkbox" },
524 hideNetworkName: { label: "Hide network name", type: "checkbox" },
525
526 vpnWidgetOptions: {
527 label: "Viscosity VPN",
528 documentation: "/viscosity-vpn/",
529 infos: ["Here you can set your Viscosity vpn connection name."],
530 },
531
532 vpnConnectionName: {
533 label: "Viscosity connection name",
534 type: "text",
535 fullWidth: true,
536 },
537 vpnShowConnectionName: {
538 label: "Display the connection name in the widget",
539 type: "checkbox",
540 fullWidth: true,
541 },
542
543 zoomWidgetOptions: {
544 label: "Zoom status",
545 documentation: "/zoom/",
546 },
547
548 showVideo: { label: "Show video status", type: "checkbox" },
549 showMic: { label: "Show mic status", type: "checkbox" },
550
551 soundWidgetOptions: {
552 label: "Sound",
553 documentation: "/sound/",
554 },
555
556 micWidgetOptions: {
557 label: "Mic",
558 documentation: "/microphone/",
559 },
560
561 keyboardWidgetOptions: {
562 label: "Keyboard",
563 documentation: "/keyboard/",
564 },
565 keyboardMaxLength: {
566 label: "Characters to display",
567 type: "number",
568 placeholder: "0 to show full name",
569 },
570
571 timeWidgetOptions: {
572 label: "Time",
573 documentation: "/time/",
574 },
575
576 hour12: { label: "12h time format", type: "checkbox" },
577 dayProgress: { label: "Day progress", type: "checkbox" },
578 showSeconds: { label: "Show seconds", type: "checkbox" },
579
580 dateWidgetOptions: {
581 label: "Date",
582 documentation: "/date/",
583 },
584
585 shortDateFormat: { label: "Short format", type: "checkbox" },
586 locale: { label: "Locale", type: "text", placeholder: "example: en-UK" },
587 calendarApp: {
588 label: "Calendar App",
589 type: "text",
590 placeholder: "example: Fantastical",
591 fullWidth: true,
592 },
593
594 youtubeMusicWidgetOptions: {
595 label: "YouTube Music",
596 },
597
598 spotifyWidgetOptions: {
599 label: "Spotify",
600 documentation: "/spotify/",
601 },
602
603 cryptoWidgetOptions: {
604 label: "Crypto",
605 documentation: "/crypto/",
606 },
607
608 stockWidgetOptions: {
609 label: "Stock",
610 documentation: "/stocks/",
611 infos: [
612 "Here you can configure your API key for the Yahoo Finance API.",
613 "If you haven't gotten one yet, go to https://www.yahoofinanceapi.com/.",
614 "You can register for free and use the Basic tier (100 requests/day).",
615 ],
616 },
617
618 musicWidgetOptions: {
619 label: "Music/iTunes",
620 documentation: "/music-itunes/",
621 },
622
623 mpdWidgetOptions: {
624 label: "MPD via mpc",
625 documentation: "/mpd-state-via-mpc/",
626 },
627
628 mpdBinaryPath: {
629 label: "Path to mpc binary",
630 type: "text",
631 placeholder: "example: /opt/homebrew/bin/mpc",
632 fullWidth: true,
633 },
634 mpdHost: {
635 label: "Host",
636 type: "text",
637 placeholder: "example: 127.0.0.1",
638 },
639 mpdPort: {
640 label: "Port",
641 type: "text",
642 placeholder: "example: 6600",
643 },
644 mpdFormatString: {
645 label: "Format String (see `man mpc`)",
646 type: "text",
647 placeholder: "example: %title%[ - %artist%]|[%file%]",
648 fullWidth: true,
649 },
650
651 browserTrackWidgetOptions: {
652 label: "Browser",
653 documentation: "/browser-track/",
654 },
655 excludedApps: {
656 label: "Excluded apps (comma-separated app names)",
657 type: "text",
658 placeholder: "example: BetterTouchTool, Xcode",
659 fullWidth: true,
660 },
661 notificationsWidgetOptions: {
662 label: "Notification badges",
663 documentation: "/notifications/",
664 infos: [
665 "Shows notification badge counts from running macOS apps.",
666 "Click any badge to open that application.",
667 'Each app exclusion must be separated by a comma and a space ", "',
668 ],
669 },
670 nextMeetingWidgetOptions: {
671 label: "Next meeting",
672 documentation: "/next-meeting/",
673 infos: [
674 "Shows your next upcoming calendar event with time until start.",
675 "Supports one-click join for Zoom, Teams, Google Meet, and Webex.",
676 "Handles Microsoft SafeLinks (Outlook URL protection) automatically.",
677 "<br/>",
678 "<b>Requires icalBuddy:</b> brew install ical-buddy",
679 "Grant calendar access when prompted.",
680 ],
681 },
682 icalBuddyPath: {
683 label: "Path to icalBuddy binary",
684 type: "text",
685 placeholder: "default: auto-detect (Homebrew)",
686 fullWidth: true,
687 },
688 lookAheadHours: {
689 label: "Look ahead (hours)",
690 type: "number",
691 placeholder: "default: 12",
692 },
693 showJoinButton: { label: "Show join button", type: "checkbox" },
694 showTimeOnly: { label: "Show time only (hide title)", type: "checkbox" },
695 showSpecter: { label: "Show animated specter", type: "checkbox" },
696 showSpotifyMetadata: { label: "Show Spotify metadata", type: "checkbox" },
697 youtubeMusicPort: { label: "Port", type: "text", placeholder: "26538" },
698
699 denomination: { label: "Denomination", type: "text", placeholder: "usd" },
700 identifiers: {
701 label: "Identifiers",
702 type: "text",
703 placeholder: "celo,bitcoin,ethereum",
704 },
705 precision: { label: "Decimals rounding", type: "text", placeholder: 5 },
706
707 symbols: {
708 label: "Symbols for your stocks, ETFs, mutual funds, ...",
709 type: "text",
710 placeholder: "AAPL,TSLA",
711 fullWidth: true,
712 },
713 yahooFinanceApiKey: {
714 label: "Your API key for Yahoo Finance",
715 type: "text",
716 placeholder: "YOUR_API_KEY",
717 fullWidth: true,
718 },
719 showSymbol: { label: "Show symbol", type: "checkbox" },
720 showCurrency: { label: "Show currency", type: "checkbox" },
721 showMarketPrice: { label: "Show market price", type: "checkbox" },
722 showMarketChange: { label: "Show market change", type: "checkbox" },
723 showMarketPercent: { label: "Show market change percent", type: "checkbox" },
724 showColor: {
725 label: "Show colored output for market change",
726 type: "checkbox",
727 },
728
729 userWidgets: {
730 label: "User widgets",
731 documentation: "/custom-widgets/",
732 },
733 userWidgetsList: { type: "component", Component: UserWidgetsCreator },
734
735 refreshFrequency: { label: "Refresh frequency (in ms)", type: "number" },
736
737 customStyles: {
738 label: "Custom styles",
739 documentation: "/custom-styles/",
740 },
741 styles: {
742 label: "Styles",
743 type: "textarea",
744 fullWidth: true,
745 minHeight: 240,
746 },
747};
748
749// Default settings are defined here
750export const defaultSettings = {
751 global: {
752 theme: "auto",
753 compactMode: false,
754 floatingBar: false,
755 noBarBg: false,
756 noColorInData: false,
757 bottomBar: false,
758 sideDecoration: false,
759 inlineSpacesOptions: false,
760 disableAnimations: false,
761 spacesBackgroundColorAsForeground: false,
762 widgetsBackgroundColorAsForeground: false,
763 widgetMaxWidth: "160px",
764 slidingAnimationPace: 4,
765 font: "JetBrains Mono, Monaco, Menlo, monospace",
766 fontSize: "11px",
767 yabaiPath: "$(which yabai)",
768 aerospacePath: "$(which aerospace)",
769 windowManager: "yabai",
770 shell: "sh",
771 terminal: "Terminal",
772 disableNotifications: false,
773 enableMissives: false,
774 enableServer: false,
775 serverSocketPort: 7777,
776 yabaiServerRefresh: false,
777 aerospaceServerRefresh: false,
778 },
779 themes: {
780 lightTheme: "NightShiftLight",
781 darkTheme: "NightShiftDark",
782 colorMain: "",
783 colorMainAlt: "",
784 colorMinor: "",
785 colorAccent: "",
786 colorRed: "",
787 colorGreen: "",
788 colorYellow: "",
789 colorOrange: "",
790 colorBlue: "",
791 colorMagenta: "",
792 colorCyan: "",
793 colorBlack: "",
794 colorWhite: "",
795 colorForeground: "",
796 colorBackground: "",
797 },
798 process: {
799 showOnDisplay: "",
800 displayForFocusedSpace: false,
801 displayOnlyCurrent: false,
802 centered: false,
803 showCurrentSpaceMode: false,
804 hideWindowTitle: false,
805 displayOnlyIcon: false,
806 expandAllProcesses: false,
807 displaySkhdMode: false,
808 displayStackIndex: true,
809 displayOnlyCurrentStack: false,
810 },
811 spacesDisplay: {
812 showOnDisplay: "",
813 exclusions: "",
814 titleExclusions: "",
815 spacesExclusions: "",
816 exclusionsAsRegex: false,
817 displayAllSpacesOnAllScreens: false,
818 hideDuplicateAppsInSpaces: false,
819 displayStickyWindowsSeparately: false,
820 hideCreateSpaceButton: false,
821 hideEmptySpaces: false,
822 showOptionsOnHover: true,
823 switchSpacesWithoutYabai: false,
824 customAeroSpaceDisplayIndexes: {},
825 },
826 widgets: {
827 processWidget: true,
828 githubWidget: false,
829 weatherWidget: false,
830 netstatsWidget: false,
831 cpuWidget: false,
832 gpuWidget: false,
833 memoryWidget: false,
834 batteryWidget: true,
835 wifiWidget: true,
836 vpnWidget: false,
837 zoomWidget: false,
838 soundWidget: true,
839 micWidget: false,
840 dateWidget: true,
841 timeWidget: true,
842 keyboardWidget: false,
843 spotifyWidget: true,
844 cryptoWidget: false,
845 stockWidget: false,
846 youtubeMusicWidget: false,
847 musicWidget: true,
848 mpdWidget: false,
849 browserTrackWidget: false,
850 notificationsWidget: false,
851 nextMeetingWidget: false,
852 },
853 githubWidgetOptions: {
854 refreshFrequency: 1000 * 60 * 10,
855 showOnDisplay: "",
856 showIcon: true,
857 hideWhenNoNotification: false,
858 notificationUrl: "https://github.com/notifications",
859 ghBinaryPath: "/opt/homebrew/bin/gh",
860 },
861 weatherWidgetOptions: {
862 refreshFrequency: 1000 * 60 * 30,
863 showOnDisplay: "",
864 showIcon: true,
865 unit: "C",
866 hideLocation: false,
867 hideGradient: false,
868 customLocation: "",
869 },
870 netstatsWidgetOptions: {
871 refreshFrequency: 2000,
872 showOnDisplay: "",
873 showIcon: true,
874 displayAsGraph: false,
875 netstatsThreshold: 0,
876 },
877 cpuWidgetOptions: {
878 refreshFrequency: 2000,
879 showOnDisplay: "",
880 showIcon: true,
881 displayAsGraph: false,
882 cpuUsageThreshold: 0,
883 cpuMonitorApp: "Activity Monitor",
884 },
885 gpuWidgetOptions: {
886 refreshFrequency: 3000,
887 showOnDisplay: "",
888 showIcon: true,
889 displayAsGraph: false,
890 gpuMacmonBinaryPath: "/opt/homebrew/bin/macmon",
891 },
892 memoryWidgetOptions: {
893 refreshFrequency: 4000,
894 showOnDisplay: "",
895 showIcon: true,
896 memoryUsageThreshold: 0,
897 memoryMonitorApp: "Activity Monitor",
898 },
899 batteryWidgetOptions: {
900 refreshFrequency: 10000,
901 showOnDisplay: "",
902 showIcon: true,
903 toggleCaffeinateOnClick: true,
904 disableCaffeinateInvertedBackground: false,
905 caffeinateOption: "",
906 },
907 networkWidgetOptions: {
908 refreshFrequency: 20000,
909 showOnDisplay: "",
910 showIcon: true,
911 networkDevice: "en0",
912 hideWifiIfDisabled: false,
913 toggleWifiOnClick: false,
914 hideNetworkName: false,
915 },
916 vpnWidgetOptions: {
917 refreshFrequency: 8000,
918 showOnDisplay: "",
919 showIcon: true,
920 vpnConnectionName: "",
921 vpnShowConnectionName: false,
922 },
923 zoomWidgetOptions: {
924 refreshFrequency: 5000,
925 showOnDisplay: "",
926 showVideo: true,
927 showMic: true,
928 },
929 soundWidgetOptions: {
930 refreshFrequency: 20000,
931 showOnDisplay: "",
932 showIcon: true,
933 },
934 micWidgetOptions: {
935 refreshFrequency: 20000,
936 showOnDisplay: "",
937 showIcon: true,
938 },
939 dateWidgetOptions: {
940 refreshFrequency: 30000,
941 showOnDisplay: "",
942 showIcon: true,
943 shortDateFormat: true,
944 locale: "en-UK",
945 calendarApp: "",
946 },
947 timeWidgetOptions: {
948 refreshFrequency: 1000,
949 showOnDisplay: "",
950 showIcon: true,
951 hour12: false,
952 dayProgress: true,
953 showSeconds: false,
954 },
955 keyboardWidgetOptions: {
956 refreshFrequency: 20000,
957 showOnDisplay: "",
958 showIcon: true,
959 keyboardMaxLength: 0,
960 },
961 cryptoWidgetOptions: {
962 refreshFrequency: 5 * 60 * 1000,
963 showOnDisplay: "",
964 showIcon: true,
965 denomination: "usd",
966 identifiers: "bitcoin,ethereum,celo",
967 precision: 5,
968 },
969 stockWidgetOptions: {
970 refreshFrequency: 15 * 60 * 1000,
971 showOnDisplay: "",
972 showIcon: true,
973 yahooFinanceApiKey: "YOUR_API_KEY",
974 symbols: "AAPL,TSLA",
975 showSymbol: true,
976 showCurrency: true,
977 showMarketPrice: true,
978 showMarketChange: false,
979 showMarketPercent: true,
980 showColor: true,
981 },
982 spotifyWidgetOptions: {
983 refreshFrequency: 10000,
984 showOnDisplay: "",
985 showIcon: true,
986 showSpecter: true,
987 showSpotifyMetadata: true,
988 },
989 youtubeMusicWidgetOptions: {
990 refreshFrequency: 10000,
991 showOnDisplay: "",
992 showIcon: true,
993 showSpecter: true,
994 youtubeMusicPort: 26538,
995 },
996 musicWidgetOptions: {
997 refreshFrequency: 10000,
998 showOnDisplay: "",
999 showIcon: true,
1000 showSpecter: true,
1001 },
1002 mpdWidgetOptions: {
1003 refreshFrequency: 10000,
1004 showOnDisplay: "",
1005 showIcon: true,
1006 showSpecter: true,
1007 mpdBinaryPath: "/opt/homebrew/bin/mpc",
1008 mpdPort: "6600",
1009 mpdHost: "127.0.0.1",
1010 mpdFormatString: "%title%[ - %artist%]|[%file%]",
1011 },
1012 browserTrackWidgetOptions: {
1013 refreshFrequency: 10000,
1014 showOnDisplay: "",
1015 showIcon: true,
1016 showSpecter: true,
1017 },
1018 notificationsWidgetOptions: {
1019 refreshFrequency: 10000,
1020 showOnDisplay: "",
1021 excludedApps: "",
1022 },
1023 nextMeetingWidgetOptions: {
1024 refreshFrequency: 60000,
1025 showOnDisplay: "",
1026 showJoinButton: true,
1027 showTimeOnly: false,
1028 icalBuddyPath: "",
1029 lookAheadHours: 12,
1030 },
1031 userWidgets: {
1032 userWidgetsList: {},
1033 },
1034 customStyles: {
1035 styles: "/* your custom css styles here */",
1036 },
1037};
1038
1039// User widget default settings
1040export const userWidgetDefault = {
1041 title: "Your widget name",
1042 icon: "Widget",
1043 backgroundColor: "--main-alt",
1044 output: 'echo "Hello world!"',
1045 onClickAction: "",
1046 onRightClickAction: "",
1047 onMiddleClickAction: "",
1048 refreshFrequency: 10000,
1049 showOnDisplay: "",
1050 active: true,
1051 noIcon: false,
1052 hideWhenNoOutput: true,
1053};
1054
1055// Colors available for user widgets
1056export const userWidgetColors = [
1057 "--main",
1058 "--main-alt",
1059 "--minor",
1060 "--accent",
1061 "--red",
1062 "--green",
1063 "--yellow",
1064 "--orange",
1065 "--blue",
1066 "--magenta",
1067 "--cyan",
1068];
1069
1070/**
1071 * Retrieves the application settings from local storage.
1072 * If no settings are found, the default settings are used.
1073 * The settings schema is removed before returning the settings.
1074 *
1075 * @returns {Object} The application settings.
1076 */
1077export function get() {
1078 const storedSettings = window.localStorage.getItem(SETTINGS_STORAGE_KEY);
1079 const settings = storedSettings
1080 ? Utils.mergeDeep(defaultSettings, JSON.parse(storedSettings))
1081 : defaultSettings;
1082 delete settings.$schema;
1083 return settings;
1084}
1085
1086/**
1087 * Updates the settings by merging them with the schema, saving them to a config file,
1088 * and storing them in the local storage.
1089 *
1090 * @param {Object} newSettings - The new settings to be applied.
1091 * @returns {Promise<void>} A promise that resolves when the settings have been saved.
1092 */
1093export async function set(newSettings) {
1094 pruneObsoleteSettings(newSettings);
1095 const settingsWithSchema = {
1096 $schema:
1097 "https://raw.githubusercontent.com/Jean-Tinland/simple-bar/refs/heads/master/lib/schemas/config.json",
1098 ...newSettings,
1099 };
1100 await saveToConfigFile(settingsWithSchema);
1101 window.localStorage.setItem(
1102 SETTINGS_STORAGE_KEY,
1103 JSON.stringify(settingsWithSchema),
1104 );
1105}
1106
1107/**
1108 * Saves the provided settings to the configuration file.
1109 *
1110 * @param {Object} newSettings - The new settings to be saved.
1111 * @returns {Promise<void>} A promise that resolves when the settings have been saved.
1112 * @throws Will throw an error if the settings cannot be saved.
1113 */
1114async function saveToConfigFile(newSettings) {
1115 try {
1116 const settings = JSON.stringify(newSettings, undefined, 2);
1117 const cleanSettings = settings.replace(/'/g, "'\"'\"'");
1118 await Uebersicht.run(`echo '${cleanSettings}' | tee ~/.simplebarrc`);
1119 } catch (e) {
1120 // eslint-disable-next-line no-console
1121 console.error(e);
1122 }
1123}
1124
1125/**
1126 * Checks if the configuration file for simple-bar exists.
1127 *
1128 * This function runs a shell command to check for the presence of the
1129 * configuration file located at `~/.simplebarrc`. If the file exists,
1130 * the function returns `true`; otherwise, it returns `false`.
1131 *
1132 * @returns {Promise<boolean>} A promise that resolves to `true` if the
1133 * configuration file exists, and `false` otherwise.
1134 */
1135export async function checkIfConfigFileExists() {
1136 let exists = false;
1137 try {
1138 exists = Boolean(await Uebersicht.run(`ls ~/.simplebarrc`));
1139 } catch (e) {
1140 // eslint-disable-next-line no-console
1141 console.error(e);
1142 }
1143 return exists;
1144}
1145
1146/**
1147 * Removes obsolete settings from the provided settings object.
1148 *
1149 * @param {Object} settings - The settings object to prune.
1150 * @param {Object} settings.global - The global settings object.
1151 * @param {string} settings.global.externalConfigFile - The external configuration file setting to be removed.
1152 * @param {Object} settings.widgets - The widgets settings object.
1153 * @param {Object} settings.widgets.dndWidget - The dndWidget setting to be removed.
1154 * @param {Object} settings.widgets.undefined - The undefined widget setting to be removed.
1155 */
1156function pruneObsoleteSettings(settings) {
1157 delete settings.global.externalConfigFile;
1158 delete settings.widgets.dndWidget;
1159 delete settings.widgets.undefined;
1160}
1161
1162/**
1163 * Loads the external configuration file for simple-bar.
1164 */
1165export async function loadExternalConfig() {
1166 const configFileExists = await checkIfConfigFileExists();
1167 if (!configFileExists) return;
1168 try {
1169 const config = JSON.parse(await Uebersicht.run(`cat ~/.simplebarrc`));
1170 const settings = Utils.mergeDeep(defaultSettings, config);
1171 return settings;
1172 } catch (e) {
1173 // eslint-disable-next-line no-console
1174 console.error("Error loading external config:", e);
1175 }
1176}
1177
1178/** */
1179export async function init() {
1180 const externalConfig = await loadExternalConfig();
1181 if (externalConfig) {
1182 set(externalConfig);
1183 }
1184}