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 --- users/ryan/modules/simple-bar/default.nix | 7 +- .../simple-bar-source/.github/FUNDING.yml | 1 + .../.github/ISSUE_TEMPLATE/bug_report.md | 32 + .../.github/ISSUE_TEMPLATE/documentation_error.md | 21 + .../.github/ISSUE_TEMPLATE/feature_request.md | 19 + .../.github/pull_request_template.md | 38 + .../simple-bar/simple-bar-source/.gitignore | 4 + .../simple-bar/simple-bar-source/.prettierrc | 1 + .../simple-bar-source/CODE_OF_CONDUCT.md | 128 + .../simple-bar/simple-bar-source/CONTRIBUTING.md | 47 + .../modules/simple-bar/simple-bar-source/LICENSE | 21 + .../modules/simple-bar/simple-bar-source/README.md | 73 + .../simple-bar/simple-bar-source/SECURITY.md | 9 + .../simple-bar/simple-bar-source/eslint.config.mjs | 52 + .../simple-bar-source/images/logo-simple-bar.png | Bin 0 -> 6365 bytes .../simple-bar-source/images/preview.png | Bin 0 -> 417752 bytes .../modules/simple-bar/simple-bar-source/index.jsx | 267 ++ .../simple-bar/simple-bar-source/lib/aerospace.js | 102 + .../simple-bar/simple-bar-source/lib/app-icons.js | 254 ++ .../lib/components/aerospace-context.jsx | 117 + .../lib/components/aerospace/opened-apps.jsx | 33 + .../lib/components/aerospace/process.jsx | 72 + .../lib/components/aerospace/space.jsx | 84 + .../lib/components/aerospace/spaces.jsx | 67 + .../lib/components/aerospace/window.jsx | 99 + .../lib/components/data/battery.jsx | 183 ++ .../lib/components/data/browser-track.jsx | 147 + .../simple-bar-source/lib/components/data/cpu.jsx | 153 + .../lib/components/data/crypto.jsx | 160 + .../lib/components/data/data-widget-loader.jsx | 37 + .../lib/components/data/data-widget.jsx | 136 + .../lib/components/data/date-display.jsx | 118 + .../lib/components/data/github.jsx | 105 + .../simple-bar-source/lib/components/data/gpu.jsx | 128 + .../lib/components/data/graph.jsx | 87 + .../lib/components/data/keyboard.jsx | 108 + .../lib/components/data/memory.jsx | 134 + .../simple-bar-source/lib/components/data/mic.jsx | 152 + .../simple-bar-source/lib/components/data/mpd.jsx | 228 ++ .../lib/components/data/music.jsx | 161 + .../lib/components/data/netstats.jsx | 182 ++ .../lib/components/data/next-meeting.jsx | 310 ++ .../lib/components/data/notifications.jsx | 189 ++ .../lib/components/data/sound.jsx | 154 + .../lib/components/data/specter.jsx | 24 + .../lib/components/data/spotify.jsx | 189 ++ .../lib/components/data/stock.jsx | 211 ++ .../simple-bar-source/lib/components/data/time.jsx | 144 + .../lib/components/data/user-widgets.jsx | 181 ++ .../lib/components/data/viscosity-vpn.jsx | 144 + .../lib/components/data/weather.jsx | 214 ++ .../simple-bar-source/lib/components/data/wifi.jsx | 154 + .../lib/components/data/youtube-music.jsx | 191 ++ .../simple-bar-source/lib/components/data/zoom.jsx | 107 + .../simple-bar-source/lib/components/error.jsx | 42 + .../lib/components/icons/icon.jsx | 40 + .../lib/components/icons/icons.jsx | 337 ++ .../lib/components/icons/library/ableton.jsx | 13 + .../lib/components/icons/library/activity.jsx | 9 + .../lib/components/icons/library/add.jsx | 9 + .../components/icons/library/affinity-designer.jsx | 12 + .../components/icons/library/affinity-photo.jsx | 12 + .../icons/library/affinity-publisher.jsx | 12 + .../lib/components/icons/library/airmail.jsx | 12 + .../lib/components/icons/library/alfred.jsx | 9 + .../components/icons/library/android-messages.jsx | 14 + .../components/icons/library/android-studio.jsx | 9 + .../lib/components/icons/library/anki.jsx | 16 + .../lib/components/icons/library/antigravity.jsx | 9 + .../lib/components/icons/library/anytype.jsx | 9 + .../lib/components/icons/library/app-store.jsx | 9 + .../components/icons/library/apple-simulator.jsx | 16 + .../lib/components/icons/library/apple.jsx | 9 + .../lib/components/icons/library/aqua.jsx | 13 + .../lib/components/icons/library/arc.jsx | 14 + .../lib/components/icons/library/atom.jsx | 14 + .../lib/components/icons/library/audacity.jsx | 9 + .../lib/components/icons/library/bambu-studio.jsx | 9 + .../lib/components/icons/library/bank.jsx | 9 + .../lib/components/icons/library/battle-net.jsx | 9 + .../lib/components/icons/library/bear.jsx | 9 + .../lib/components/icons/library/beekeeper.jsx | 13 + .../lib/components/icons/library/bell-off.jsx | 9 + .../lib/components/icons/library/bell.jsx | 9 + .../lib/components/icons/library/bit-warden.jsx | 9 + .../lib/components/icons/library/bitcoin.jsx | 14 + .../lib/components/icons/library/blender.jsx | 9 + .../lib/components/icons/library/book.jsx | 9 + .../lib/components/icons/library/brave-browser.jsx | 9 + .../lib/components/icons/library/bruno.jsx | 11 + .../lib/components/icons/library/c-lion.jsx | 13 + .../lib/components/icons/library/ca-r-r-o-t.jsx | 10 + .../lib/components/icons/library/calendar.jsx | 10 + .../lib/components/icons/library/camera-off.jsx | 9 + .../lib/components/icons/library/camera.jsx | 9 + .../lib/components/icons/library/cancel.jsx | 9 + .../lib/components/icons/library/caprine.jsx | 9 + .../lib/components/icons/library/celo.jsx | 20 + .../lib/components/icons/library/charging.jsx | 9 + .../lib/components/icons/library/chat-gpt.jsx | 13 + .../lib/components/icons/library/chatterino.jsx | 10 + .../lib/components/icons/library/check-box.jsx | 9 + .../components/icons/library/chevron-bottom.jsx | 9 + .../lib/components/icons/library/chevron-left.jsx | 9 + .../lib/components/icons/library/chevron-right.jsx | 9 + .../lib/components/icons/library/chevron-top.jsx | 9 + .../lib/components/icons/library/claude-code.jsx | 12 + .../lib/components/icons/library/claude.jsx | 9 + .../lib/components/icons/library/click-up.jsx | 9 + .../lib/components/icons/library/cline.jsx | 10 + .../lib/components/icons/library/clock.jsx | 10 + .../lib/components/icons/library/close.jsx | 9 + .../lib/components/icons/library/cloud.jsx | 13 + .../lib/components/icons/library/code.jsx | 9 + .../lib/components/icons/library/codex.jsx | 12 + .../lib/components/icons/library/coffee.jsx | 15 + .../lib/components/icons/library/color-picker.jsx | 9 + .../lib/components/icons/library/comfy-ui.jsx | 9 + .../lib/components/icons/library/copilot.jsx | 9 + .../lib/components/icons/library/cp-u.jsx | 10 + .../lib/components/icons/library/cursor.jsx | 9 + .../lib/components/icons/library/data-grip.jsx | 13 + .../lib/components/icons/library/date.jsx | 10 + .../components/icons/library/de-v-o-nthink3.jsx | 13 + .../lib/components/icons/library/deezer.jsx | 9 + .../lib/components/icons/library/default.jsx | 13 + .../lib/components/icons/library/desktop.jsx | 9 + .../lib/components/icons/library/discord.jsx | 9 + .../lib/components/icons/library/docker.jsx | 11 + .../lib/components/icons/library/dollar.jsx | 9 + .../lib/components/icons/library/down-arrow.jsx | 12 + .../lib/components/icons/library/download.jsx | 14 + .../lib/components/icons/library/drafts.jsx | 9 + .../lib/components/icons/library/dropbox.jsx | 9 + .../lib/components/icons/library/element.jsx | 13 + .../lib/components/icons/library/emacs.jsx | 13 + .../lib/components/icons/library/ethereum.jsx | 34 + .../components/icons/library/evernote-legacy.jsx | 10 + .../lib/components/icons/library/face-time.jsx | 9 + .../lib/components/icons/library/figma.jsx | 10 + .../lib/components/icons/library/final-cut-pro.jsx | 9 + .../lib/components/icons/library/finder.jsx | 9 + .../icons/library/firefox-developer-edition.jsx | 9 + .../lib/components/icons/library/firefox.jsx | 9 + .../lib/components/icons/library/fleet.jsx | 13 + .../lib/components/icons/library/fog.jsx | 20 + .../lib/components/icons/library/folx.jsx | 13 + .../lib/components/icons/library/free-tube.jsx | 16 + .../lib/components/icons/library/gear.jsx | 9 + .../lib/components/icons/library/ghostty.jsx | 13 + .../lib/components/icons/library/git-hub.jsx | 9 + .../lib/components/icons/library/gnu-cash.jsx | 13 + .../lib/components/icons/library/go-land.jsx | 13 + .../lib/components/icons/library/good-notes.jsx | 10 + .../lib/components/icons/library/google-chrome.jsx | 12 + .../lib/components/icons/library/goose.jsx | 12 + .../lib/components/icons/library/grammarly.jsx | 9 + .../lib/components/icons/library/helium.jsx | 11 + .../components/icons/library/home-assistant.jsx | 10 + .../lib/components/icons/library/ht-t-pie.jsx | 9 + .../lib/components/icons/library/idea.jsx | 9 + .../lib/components/icons/library/insomnia.jsx | 9 + .../lib/components/icons/library/iris.jsx | 9 + .../lib/components/icons/library/italic.jsx | 9 + .../lib/components/icons/library/joplin.jsx | 13 + .../lib/components/icons/library/kakoune.jsx | 13 + .../lib/components/icons/library/kee-pass-x-c.jsx | 14 + .../components/icons/library/keyboard-maestro.jsx | 9 + .../lib/components/icons/library/keyboard.jsx | 9 + .../lib/components/icons/library/keynote.jsx | 9 + .../components/icons/library/league-of-legends.jsx | 9 + .../lib/components/icons/library/libre-wolf.jsx | 9 + .../lib/components/icons/library/linear.jsx | 9 + .../lib/components/icons/library/lm-studio.jsx | 13 + .../lib/components/icons/library/maestro-ai.jsx | 11 + .../lib/components/icons/library/mail.jsx | 9 + .../lib/components/icons/library/mamp.jsx | 13 + .../lib/components/icons/library/manus.jsx | 17 + .../lib/components/icons/library/matlab.jsx | 9 + .../lib/components/icons/library/mattermost.jsx | 10 + .../lib/components/icons/library/messages.jsx | 9 + .../lib/components/icons/library/mic-off.jsx | 10 + .../lib/components/icons/library/mic-on.jsx | 10 + .../components/icons/library/microsoft-edge.jsx | 14 + .../components/icons/library/microsoft-excel.jsx | 9 + .../components/icons/library/microsoft-outlook.jsx | 11 + .../icons/library/microsoft-power-point.jsx | 9 + .../components/icons/library/microsoft-word.jsx | 9 + .../lib/components/icons/library/mimestream.jsx | 13 + .../lib/components/icons/library/min-browser.jsx | 13 + .../lib/components/icons/library/miro.jsx | 9 + .../lib/components/icons/library/monero-gui.jsx | 12 + .../lib/components/icons/library/mongo-db.jsx | 13 + .../lib/components/icons/library/moon.jsx | 10 + .../lib/components/icons/library/mpv.jsx | 16 + .../lib/components/icons/library/music.jsx | 13 + .../lib/components/icons/library/n8n.jsx | 12 + .../lib/components/icons/library/net-news-wire.jsx | 9 + .../lib/components/icons/library/netease-music.jsx | 9 + .../lib/components/icons/library/no-volume.jsx | 9 + .../lib/components/icons/library/notability.jsx | 13 + .../lib/components/icons/library/notebook-lm.jsx | 9 + .../lib/components/icons/library/notes.jsx | 9 + .../lib/components/icons/library/notion.jsx | 9 + .../lib/components/icons/library/nova.jsx | 12 + .../lib/components/icons/library/numbers.jsx | 9 + .../lib/components/icons/library/ob-s-studio.jsx | 9 + .../lib/components/icons/library/obsidian.jsx | 33 + .../lib/components/icons/library/ollama.jsx | 13 + .../lib/components/icons/library/omni-focus.jsx | 13 + .../lib/components/icons/library/one-password.jsx | 9 + .../lib/components/icons/library/open-book.jsx | 10 + .../lib/components/icons/library/open-claw.jsx | 16 + .../lib/components/icons/library/opencode.jsx | 9 + .../lib/components/icons/library/orb-stack.jsx | 14 + .../lib/components/icons/library/pages.jsx | 9 + .../lib/components/icons/library/parallels.jsx | 13 + .../lib/components/icons/library/paused.jsx | 9 + .../lib/components/icons/library/pdf.jsx | 10 + .../lib/components/icons/library/perplexity.jsx | 9 + .../lib/components/icons/library/php-storm.jsx | 13 + .../lib/components/icons/library/pihole.jsx | 31 + .../lib/components/icons/library/pine.jsx | 13 + .../lib/components/icons/library/pins.jsx | 9 + .../lib/components/icons/library/playing.jsx | 9 + .../lib/components/icons/library/plex.jsx | 13 + .../lib/components/icons/library/podcasts.jsx | 9 + .../lib/components/icons/library/pomodone.jsx | 10 + .../lib/components/icons/library/postman.jsx | 13 + .../lib/components/icons/library/proton-mail.jsx | 13 + .../lib/components/icons/library/py-charm.jsx | 13 + .../lib/components/icons/library/quip.jsx | 10 + .../lib/components/icons/library/qute-browser.jsx | 13 + .../lib/components/icons/library/radar.jsx | 11 + .../lib/components/icons/library/rain.jsx | 15 + .../lib/components/icons/library/ram.jsx | 9 + .../lib/components/icons/library/redis.jsx | 13 + .../lib/components/icons/library/reeder5.jsx | 13 + .../lib/components/icons/library/reminders.jsx | 9 + .../lib/components/icons/library/remnote.jsx | 14 + .../components/icons/library/remote-desktop.jsx | 15 + .../lib/components/icons/library/remove.jsx | 9 + .../lib/components/icons/library/replit.jsx | 9 + .../lib/components/icons/library/rider.jsx | 13 + .../lib/components/icons/library/rocket-chat.jsx | 10 + .../lib/components/icons/library/roon.jsx | 9 + .../lib/components/icons/library/royal-tsx.jsx | 13 + .../lib/components/icons/library/ruby-mine.jsx | 13 + .../lib/components/icons/library/rust-rover.jsx | 13 + .../lib/components/icons/library/safari.jsx | 9 + .../lib/components/icons/library/screens4.jsx | 12 + .../lib/components/icons/library/sequel-ace.jsx | 13 + .../lib/components/icons/library/sequel-pro.jsx | 14 + .../lib/components/icons/library/setapp.jsx | 9 + .../lib/components/icons/library/signal.jsx | 9 + .../lib/components/icons/library/sketch-up.jsx | 12 + .../lib/components/icons/library/sketch.jsx | 9 + .../lib/components/icons/library/skype.jsx | 9 + .../lib/components/icons/library/slack.jsx | 9 + .../lib/components/icons/library/snow.jsx | 18 + .../lib/components/icons/library/spark.jsx | 13 + .../lib/components/icons/library/spotify.jsx | 13 + .../lib/components/icons/library/spotlight.jsx | 9 + .../lib/components/icons/library/spotube.jsx | 10 + .../lib/components/icons/library/statistics.jsx | 9 + .../lib/components/icons/library/stopped.jsx | 9 + .../lib/components/icons/library/storm.jsx | 18 + .../lib/components/icons/library/sublime-text.jsx | 9 + .../lib/components/icons/library/sun.jsx | 13 + .../icons/library/super-productivity.jsx | 9 + .../lib/components/icons/library/table-plus.jsx | 9 + .../lib/components/icons/library/tailscale.jsx | 9 + .../lib/components/icons/library/team-speak.jsx | 13 + .../lib/components/icons/library/teams.jsx | 14 + .../lib/components/icons/library/telegram.jsx | 9 + .../lib/components/icons/library/terminal.jsx | 9 + .../lib/components/icons/library/text.jsx | 13 + .../lib/components/icons/library/thermostat.jsx | 9 + .../lib/components/icons/library/things.jsx | 12 + .../lib/components/icons/library/thunderbird.jsx | 9 + .../lib/components/icons/library/tick-tick.jsx | 9 + .../lib/components/icons/library/tidal.jsx | 9 + .../lib/components/icons/library/todoist.jsx | 9 + .../lib/components/icons/library/tor-browser.jsx | 15 + .../lib/components/icons/library/tower.jsx | 13 + .../lib/components/icons/library/transmit.jsx | 12 + .../lib/components/icons/library/trello.jsx | 9 + .../lib/components/icons/library/twitter.jsx | 9 + .../lib/components/icons/library/up-arrow.jsx | 12 + .../lib/components/icons/library/upload.jsx | 14 + .../lib/components/icons/library/vim.jsx | 9 + .../lib/components/icons/library/vivaldi.jsx | 14 + .../lib/components/icons/library/vl-c.jsx | 9 + .../lib/components/icons/library/vmware-fusion.jsx | 12 + .../lib/components/icons/library/volume-high.jsx | 9 + .../lib/components/icons/library/volume-low.jsx | 9 + .../lib/components/icons/library/volume-muted.jsx | 10 + .../lib/components/icons/library/vp-n-off.jsx | 9 + .../lib/components/icons/library/vp-n.jsx | 9 + .../lib/components/icons/library/vs-codium.jsx | 9 + .../lib/components/icons/library/warp.jsx | 10 + .../lib/components/icons/library/web-storm.jsx | 9 + .../lib/components/icons/library/wechat.jsx | 9 + .../lib/components/icons/library/whats-app.jsx | 9 + .../lib/components/icons/library/widget.jsx | 9 + .../lib/components/icons/library/wifi-off.jsx | 9 + .../lib/components/icons/library/wifi.jsx | 9 + .../lib/components/icons/library/windows.jsx | 9 + .../lib/components/icons/library/xcode.jsx | 12 + .../lib/components/icons/library/youtube-music.jsx | 13 + .../lib/components/icons/library/zed.jsx | 10 + .../lib/components/icons/library/zen-browser.jsx | 11 + .../lib/components/icons/library/zeplin.jsx | 43 + .../lib/components/icons/library/zoom.jsx | 9 + .../lib/components/icons/library/zotero.jsx | 12 + .../lib/components/icons/library/zulip.jsx | 9 + .../lib/components/missives/missive.jsx | 48 + .../lib/components/missives/missives.jsx | 40 + .../settings/aerospace-display-manager.jsx | 83 + .../lib/components/settings/color-picker.jsx | 109 + .../lib/components/settings/icon-picker.jsx | 130 + .../lib/components/settings/settings-component.jsx | 159 + .../lib/components/settings/settings-inner.jsx | 123 + .../lib/components/settings/settings-item.jsx | 143 + .../lib/components/settings/settings-widgets.jsx | 180 ++ .../lib/components/settings/settings.jsx | 94 + .../components/settings/user-widgets-creator.jsx | 297 ++ .../simple-bar-source/lib/components/side-icon.jsx | 32 + .../lib/components/simple-bar-context.jsx | 131 + .../lib/components/yabai-context.jsx | 112 + .../lib/components/yabai/opened-apps.jsx | 55 + .../lib/components/yabai/process.jsx | 102 + .../lib/components/yabai/space-options.jsx | 84 + .../lib/components/yabai/space.jsx | 194 ++ .../lib/components/yabai/spaces.jsx | 109 + .../lib/components/yabai/stickies.jsx | 56 + .../lib/components/yabai/window.jsx | 119 + .../lib/hooks/use-server-socket.js | 221 ++ .../lib/hooks/use-widget-refresh.js | 37 + .../simple-bar-source/lib/schemas/config.json | 1159 +++++++ .../lib/scripts/browser-audio.applescript | 91 + .../lib/scripts/firefox-audio.applescript | 24 + .../lib/scripts/firefox-dev-audio.applescript | 24 + .../lib/scripts/init-aerospace.sh | 26 + .../simple-bar-source/lib/scripts/init-yabai.sh | 102 + .../simple-bar-source/lib/scripts/netstats.sh | 5 + .../simple-bar-source/lib/scripts/next-meeting.sh | 101 + .../lib/scripts/run-command-in-iterm2.applescript | 9 + .../scripts/run-command-in-terminal.applescript | 7 + .../lib/scripts/yabai-set-mode-server.sh | 38 + .../lib/scripts/yabai-set-mode.sh | 40 + .../lib/scripts/zoom-mute-status.applescript | 17 + .../lib/scripts/zoom-video-status.applescript | 17 + .../simple-bar/simple-bar-source/lib/settings.js | 1184 +++++++ .../simple-bar/simple-bar-source/lib/skhd.js | 17 + .../lib/styles/components/data/battery.js | 134 + .../lib/styles/components/data/browser-track.js | 40 + .../lib/styles/components/data/cpu.js | 16 + .../lib/styles/components/data/crypto.js | 9 + .../styles/components/data/data-widget-loader.js | 32 + .../lib/styles/components/data/data-widget.js | 65 + .../lib/styles/components/data/date-display.js | 10 + .../lib/styles/components/data/github.js | 10 + .../lib/styles/components/data/gpu.js | 15 + .../lib/styles/components/data/graph.js | 49 + .../lib/styles/components/data/keyboard.js | 10 + .../lib/styles/components/data/memory.js | 30 + .../lib/styles/components/data/mic.js | 83 + .../lib/styles/components/data/mpd.js | 80 + .../lib/styles/components/data/music.js | 11 + .../lib/styles/components/data/netstats.js | 48 + .../lib/styles/components/data/next-meeting.js | 71 + .../lib/styles/components/data/notifications.js | 68 + .../lib/styles/components/data/sound.js | 83 + .../lib/styles/components/data/specter.js | 55 + .../lib/styles/components/data/spotify.js | 15 + .../lib/styles/components/data/stock.js | 15 + .../lib/styles/components/data/time.js | 85 + .../lib/styles/components/data/viscosity-vpn.js | 17 + .../lib/styles/components/data/weather.js | 163 + .../lib/styles/components/data/wifi.js | 13 + .../lib/styles/components/data/youtube-music.js | 11 + .../lib/styles/components/data/zoom.js | 26 + .../lib/styles/components/missives.js | 89 + .../lib/styles/components/process.js | 161 + .../settings/aerospace-display-manager.js | 101 + .../lib/styles/components/settings/color-picker.js | 83 + .../lib/styles/components/settings/icon-picker.js | 155 + .../lib/styles/components/settings/settings.js | 408 +++ .../components/settings/user-widgets-creator.js | 170 + .../lib/styles/components/side-icon.js | 15 + .../lib/styles/components/spaces/space-options.js | 137 + .../lib/styles/components/spaces/space.js | 152 + .../lib/styles/components/spaces/spaces.js | 50 + .../simple-bar-source/lib/styles/core/base.js | 120 + .../simple-bar-source/lib/styles/core/variables.js | 107 + .../lib/styles/pywal/pywal-colors.js | 15 + .../lib/styles/pywal/pywal-from-desktop.sh | 9 + .../lib/styles/pywal/pywal-gen.sh | 7 + .../simple-bar-source/lib/styles/pywal/pywal.js | 15 + .../simple-bar-source/lib/styles/theme.js | 21 + .../simple-bar-source/lib/styles/themes.js | 72 + .../simple-bar-source/lib/styles/themes/amarena.js | 32 + .../lib/styles/themes/catppuccin-frappe.js | 32 + .../lib/styles/themes/catppuccin-latte.js | 32 + .../lib/styles/themes/catppuccin-macchiato.js | 32 + .../lib/styles/themes/catppuccin-mocha.js | 32 + .../lib/styles/themes/catppuccin.js | 32 + .../simple-bar-source/lib/styles/themes/cisco.js | 32 + .../lib/styles/themes/cyberdream-dark.js | 32 + .../lib/styles/themes/cyberdream-light.js | 32 + .../simple-bar-source/lib/styles/themes/dracula.js | 32 + .../lib/styles/themes/gruvbox-dark.js | 32 + .../lib/styles/themes/gruvbox-light.js | 32 + .../lib/styles/themes/gruvbox-material.js | 32 + .../lib/styles/themes/mac-os-dark.js | 32 + .../lib/styles/themes/mac-os-light.js | 32 + .../lib/styles/themes/material-ocean.js | 32 + .../lib/styles/themes/midsummer-night-dark.js | 32 + .../lib/styles/themes/night-owl.js | 33 + .../lib/styles/themes/night-shift-dark.js | 32 + .../lib/styles/themes/night-shift-light.js | 32 + .../lib/styles/themes/nightfox-dark.js | 32 + .../lib/styles/themes/nightfox-light.js | 32 + .../simple-bar-source/lib/styles/themes/nord.js | 32 + .../lib/styles/themes/one-dark.js | 32 + .../lib/styles/themes/one-light.js | 32 + .../lib/styles/themes/rose-pine-dawn.js | 32 + .../lib/styles/themes/rose-pine-moon.js | 32 + .../lib/styles/themes/rose-pine.js | 32 + .../lib/styles/themes/solarized-dark.js | 32 + .../lib/styles/themes/solarized-light.js | 32 + .../lib/styles/themes/spaceduck.js | 32 + .../simple-bar-source/lib/styles/themes/sylens.js | 32 + .../lib/styles/themes/tokyo-night.js | 32 + .../lib/styles/themes/vscode-dark-modern.js | 32 + .../simple-bar/simple-bar-source/lib/utils.js | 828 +++++ .../simple-bar/simple-bar-source/lib/yabai.js | 128 + .../simple-bar/simple-bar-source/package-lock.json | 3267 ++++++++++++++++++++ .../simple-bar/simple-bar-source/package.json | 17 + .../ryan/modules/taskwarrior-ubersicht/default.nix | 7 +- .../taskwarrior-widget-source/README.md | 7 + .../taskwarrior-widget-source/style.css | 43 + .../taskwarrior-widget-source/taskwarrior.jsx | 203 ++ .../taskwarrior-widget-source/widget.json | 6 + 445 files changed, 23553 insertions(+), 12 deletions(-) create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/.github/FUNDING.yml create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/bug_report.md create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/documentation_error.md create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/feature_request.md create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/.github/pull_request_template.md create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/.gitignore create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/.prettierrc create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/CODE_OF_CONDUCT.md create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/CONTRIBUTING.md create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/LICENSE create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/README.md create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/SECURITY.md create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/eslint.config.mjs create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/images/logo-simple-bar.png create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/images/preview.png create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/index.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/aerospace.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/app-icons.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace-context.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/opened-apps.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/process.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/space.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/spaces.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/window.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/battery.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/browser-track.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/cpu.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/crypto.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget-loader.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/date-display.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/github.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/gpu.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/graph.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/keyboard.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/mic.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/mpd.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/music.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/next-meeting.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/notifications.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/specter.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/spotify.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/stock.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/time.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/user-widgets.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/viscosity-vpn.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/weather.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/youtube-music.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/zoom.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/error.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/icon.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/icons.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ableton.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/activity.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/add.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-designer.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-photo.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-publisher.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/airmail.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/alfred.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/android-messages.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/android-studio.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/anki.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/antigravity.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/anytype.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/app-store.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/apple-simulator.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/apple.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/aqua.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/arc.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/atom.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/audacity.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bambu-studio.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bank.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/battle-net.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bear.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/beekeeper.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bell-off.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bell.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bit-warden.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bitcoin.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/blender.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/book.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/brave-browser.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bruno.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/c-lion.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ca-r-r-o-t.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/calendar.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/camera-off.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/camera.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cancel.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/caprine.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/celo.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/charging.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chat-gpt.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chatterino.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/check-box.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-bottom.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-left.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-right.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-top.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/claude-code.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/claude.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/click-up.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cline.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/clock.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/close.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cloud.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/code.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/codex.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/coffee.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/color-picker.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/comfy-ui.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/copilot.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cp-u.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cursor.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/data-grip.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/date.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/de-v-o-nthink3.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/deezer.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/default.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/desktop.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/discord.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/docker.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/dollar.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/down-arrow.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/download.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/drafts.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/dropbox.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/element.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/emacs.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ethereum.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/evernote-legacy.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/face-time.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/figma.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/final-cut-pro.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/finder.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/firefox-developer-edition.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/firefox.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/fleet.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/fog.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/folx.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/free-tube.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/gear.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ghostty.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/git-hub.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/gnu-cash.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/go-land.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/good-notes.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/google-chrome.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/goose.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/grammarly.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/helium.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/home-assistant.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ht-t-pie.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/idea.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/insomnia.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/iris.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/italic.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/joplin.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/kakoune.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/kee-pass-x-c.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keyboard-maestro.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keyboard.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keynote.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/league-of-legends.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/libre-wolf.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/linear.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/lm-studio.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/maestro-ai.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mail.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mamp.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/manus.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/matlab.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mattermost.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/messages.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mic-off.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mic-on.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-edge.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-excel.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-outlook.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-power-point.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-word.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mimestream.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/min-browser.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/miro.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/monero-gui.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mongo-db.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/moon.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mpv.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/music.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/n8n.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/net-news-wire.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/netease-music.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/no-volume.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notability.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notebook-lm.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notes.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notion.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/nova.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/numbers.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ob-s-studio.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/obsidian.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ollama.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/omni-focus.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/one-password.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/open-book.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/open-claw.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/opencode.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/orb-stack.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pages.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/parallels.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/paused.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pdf.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/perplexity.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/php-storm.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pihole.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pine.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pins.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/playing.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/plex.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/podcasts.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pomodone.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/postman.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/proton-mail.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/py-charm.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/quip.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/qute-browser.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/radar.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rain.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ram.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/redis.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/reeder5.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/reminders.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remnote.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remote-desktop.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remove.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/replit.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rider.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rocket-chat.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/roon.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/royal-tsx.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ruby-mine.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rust-rover.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/safari.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/screens4.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sequel-ace.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sequel-pro.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/setapp.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/signal.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sketch-up.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sketch.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/skype.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/slack.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/snow.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spark.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotify.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotlight.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotube.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/statistics.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/stopped.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/storm.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sublime-text.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sun.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/super-productivity.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/table-plus.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tailscale.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/team-speak.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/teams.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/telegram.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/terminal.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/text.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/thermostat.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/things.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/thunderbird.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tick-tick.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tidal.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/todoist.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tor-browser.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tower.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/transmit.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/trello.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/twitter.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/up-arrow.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/upload.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vim.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vivaldi.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vl-c.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vmware-fusion.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-high.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-low.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-muted.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vp-n-off.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vp-n.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vs-codium.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/warp.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/web-storm.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wechat.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/whats-app.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/widget.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wifi-off.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wifi.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/windows.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/xcode.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/youtube-music.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zed.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zen-browser.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zeplin.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zoom.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zotero.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zulip.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/missives/missive.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/missives/missives.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/aerospace-display-manager.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/color-picker.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-component.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-inner.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-item.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-widgets.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/user-widgets-creator.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/side-icon.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/simple-bar-context.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai-context.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/opened-apps.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/process.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/space-options.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/space.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/spaces.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/stickies.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/components/yabai/window.jsx create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/hooks/use-server-socket.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/hooks/use-widget-refresh.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/schemas/config.json create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/browser-audio.applescript create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/firefox-audio.applescript create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/firefox-dev-audio.applescript create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/init-aerospace.sh create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/init-yabai.sh create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/netstats.sh create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/next-meeting.sh create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/run-command-in-iterm2.applescript create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/run-command-in-terminal.applescript create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/yabai-set-mode-server.sh create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/yabai-set-mode.sh create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/zoom-mute-status.applescript create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/zoom-video-status.applescript create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/settings.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/skhd.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/battery.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/browser-track.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/cpu.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/crypto.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/data-widget-loader.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/data-widget.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/date-display.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/github.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/gpu.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/graph.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/keyboard.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/memory.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/mic.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/mpd.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/music.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/netstats.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/next-meeting.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/notifications.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/sound.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/specter.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/spotify.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/stock.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/time.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/viscosity-vpn.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/weather.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/wifi.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/youtube-music.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/data/zoom.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/missives.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/process.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/settings/aerospace-display-manager.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/settings/color-picker.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/settings/icon-picker.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/settings/settings.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/settings/user-widgets-creator.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/side-icon.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/spaces/space-options.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/spaces/space.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/components/spaces/spaces.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/core/base.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/core/variables.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/pywal/pywal-colors.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/pywal/pywal-from-desktop.sh create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/pywal/pywal-gen.sh create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/pywal/pywal.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/theme.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/amarena.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/catppuccin-frappe.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/catppuccin-latte.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/catppuccin-macchiato.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/catppuccin-mocha.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/catppuccin.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/cisco.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/cyberdream-dark.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/cyberdream-light.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/dracula.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/gruvbox-dark.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/gruvbox-light.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/gruvbox-material.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/mac-os-dark.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/mac-os-light.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/material-ocean.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/midsummer-night-dark.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/night-owl.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/night-shift-dark.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/night-shift-light.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/nightfox-dark.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/nightfox-light.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/nord.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/one-dark.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/one-light.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/rose-pine-dawn.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/rose-pine-moon.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/rose-pine.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/solarized-dark.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/solarized-light.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/spaceduck.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/sylens.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/tokyo-night.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/styles/themes/vscode-dark-modern.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/utils.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/lib/yabai.js create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/package-lock.json create mode 100755 users/ryan/modules/simple-bar/simple-bar-source/package.json mode change 100644 => 100755 users/ryan/modules/taskwarrior-ubersicht/default.nix create mode 100755 users/ryan/modules/taskwarrior-ubersicht/taskwarrior-widget-source/README.md create mode 100755 users/ryan/modules/taskwarrior-ubersicht/taskwarrior-widget-source/style.css create mode 100755 users/ryan/modules/taskwarrior-ubersicht/taskwarrior-widget-source/taskwarrior.jsx create mode 100755 users/ryan/modules/taskwarrior-ubersicht/taskwarrior-widget-source/widget.json diff --git a/users/ryan/modules/simple-bar/default.nix b/users/ryan/modules/simple-bar/default.nix index 116216f..a309f61 100644 --- a/users/ryan/modules/simple-bar/default.nix +++ b/users/ryan/modules/simple-bar/default.nix @@ -4,12 +4,7 @@ with lib; let cfg = config.ryan.simple-bar; - # Fetch the git repo at a specific rev - "simple-bar-upstream" = builtins.fetchGit { - url = "https://github.com/Jean-Tinland/simple-bar"; - rev = "fb5cada548a05bd01f727772c0a18fd8c7f65b42"; - shallow = true; - }; + "simple-bar-upstream" = ./simple-bar-source in { options.ryan.simple-bar.enable = mkEnableOption "simple-bar"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/.github/FUNDING.yml b/users/ryan/modules/simple-bar/simple-bar-source/.github/FUNDING.yml new file mode 100755 index 0000000..0067695 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [Jean-Tinland] diff --git a/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/bug_report.md b/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100755 index 0000000..07e7338 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "" +labels: bug +assignees: "" +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Information (please complete the following information):** + +- OS version [e.g. Sonoma 14.1.1] +- yabai or AeroSpace version [e.g. yabai-v6.0.1] +- Übersicht version [e.g. Version 1.6 (82)] + +**Additional context** +Add any other context about the problem here. diff --git a/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/documentation_error.md b/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/documentation_error.md new file mode 100755 index 0000000..d0d287b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/documentation_error.md @@ -0,0 +1,21 @@ +--- +name: Documentation error +about: Create a report to help us improve +title: "" +labels: documentation +assignees: "" +--- + +**Describe the bug** +A clear and concise description of what the error is. + +**Where is located the error** + +Link to the documentation page where the error is located. + +**Expected content** + +What should be the correct content. + +**Additional context** +Add any other context about the problem here. diff --git a/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/feature_request.md b/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100755 index 0000000..d883b8f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "" +labels: enhancement +assignees: "" +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/users/ryan/modules/simple-bar/simple-bar-source/.github/pull_request_template.md b/users/ryan/modules/simple-bar/simple-bar-source/.github/pull_request_template.md new file mode 100755 index 0000000..d012be7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/.github/pull_request_template.md @@ -0,0 +1,38 @@ +# Description + +Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes # (issue) + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +# How Has This Been Tested? + +Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration + +- [ ] Test A +- [ ] Test B + +**Test Configuration**: + +- OS version [e.g. Sonoma 14.1.1] +- yabai version [e.g. yabai-v6.0.1] (output of `yabai --version`) +- Übersicht version [e.g. Version 1.6 (82)] + +# Checklist: + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my code +- [ ] I have commented my code, particularly in hard-to-understand areas (make use of JSDoc if necessary) +- [ ] My changes generate no new warnings + +# Changes to make to the documentation + +Please list any changes to the documentation that are required to reflect your changes. diff --git a/users/ryan/modules/simple-bar/simple-bar-source/.gitignore b/users/ryan/modules/simple-bar/simple-bar-source/.gitignore new file mode 100755 index 0000000..7839ca3 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +.idea +/node_modules +yarn.lock diff --git a/users/ryan/modules/simple-bar/simple-bar-source/.prettierrc b/users/ryan/modules/simple-bar/simple-bar-source/.prettierrc new file mode 100755 index 0000000..0967ef4 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/CODE_OF_CONDUCT.md b/users/ryan/modules/simple-bar/simple-bar-source/CODE_OF_CONDUCT.md new file mode 100755 index 0000000..f9218d4 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or + advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email + address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +https://www.jeantinland.com/contact/. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/users/ryan/modules/simple-bar/simple-bar-source/CONTRIBUTING.md b/users/ryan/modules/simple-bar/simple-bar-source/CONTRIBUTING.md new file mode 100755 index 0000000..13ec1f9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/CONTRIBUTING.md @@ -0,0 +1,47 @@ +# Contributor guidelines + +## What do I need to know to help? + +If you are looking to help to with a code contribution our project uses **React** in a mac os application names **Übersicht**. It is build on top of **yabai**. If you don't feel ready to make a code contribution yet, no problem! You can also check out the [documentation issues](https://github.com/Jean-Tinland/simple-bar/issues). + +If you are interested in making a code contribution and would like to learn more about the technologies that we use, check out the list below. + +- [React documentation](https://react.dev/learn) +- [Übersicht documentation](https://github.com/felixhageloh/uebersicht#%C3%BCbersicht) +- [yabai documentation](https://github.com/koekeishiya/yabai) + +## Coding style conventions + +Your PR should: + +- Be formatted with prettier +- Pass the linter (run `yarn lint` to check) + +## How do I make a contribution? + +Never made an open source contribution before? Wondering how contributions work in the in our project? Here's a quick rundown! + +1. Find an issue that you are interested in addressing or a feature that you would like to add. +2. Fork the repository associated with the issue to your local GitHub organization. This means that you will have a copy of the repository under `your-GitHub-username/simple-bar`. +3. Clone the repository to your local machine using `git clone https://github.com/Jean-Tinland/simple-bar.git`. +4. Create a new branch for your fix using `git checkout -b branch-name-here`. +5. Make the appropriate changes for the issue you are trying to address or the feature that you want to add. +6. Use `git add insert-paths-of-changed-files-here` to add the file contents of the changed files to the "snapshot" git uses to manage the state of the project, also known as the index. +7. Use `git commit -m "Insert a short message of the changes made here"` to store the contents of the index with a descriptive message. +8. Push the changes to the remote repository using `git push origin branch-name-here`. +9. Submit a pull request to the upstream repository. +10. Title the pull request with a short description of the changes made and the issue or bug number associated with your change. For example, you can title an issue like so "Added more log outputting to resolve #4352". +11. In the description of the pull request, explain the changes that you made, any issues you think exist with the pull request you made, and any questions you have for the maintainer. It's OK if your pull request is not perfect (no pull request is), the reviewer will be able to help you fix any problems and improve it! +12. Wait for the pull request to be reviewed by a maintainer. +13. Make changes to the pull request if the reviewing maintainer recommends them. +14. Celebrate your success after your pull request is merged! + +## Where can I go for help? + +If you need help, you can ask questions on simple-bar's issue section on GitHub or with the contact form on [my website](https://www.jeantinland.com/en/contact/). + +## What does the Code of Conduct mean for me? + +Our Code of Conduct means that you are responsible for treating everyone on the project with respect and courtesy regardless of their identity. If you are the victim of any inappropriate behavior or comments as described in our Code of Conduct, we are here for you and will do the best to ensure that the abuser is reprimanded appropriately, per our code. + +> This contributor guide is adapted from the [opensource.com guide available here](https://opensource.com/life/16/3/contributor-guidelines-template-and-tips). diff --git a/users/ryan/modules/simple-bar/simple-bar-source/LICENSE b/users/ryan/modules/simple-bar/simple-bar-source/LICENSE new file mode 100755 index 0000000..bb64387 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Jean Tinland (https://www.jeantinland.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/users/ryan/modules/simple-bar/simple-bar-source/README.md b/users/ryan/modules/simple-bar/simple-bar-source/README.md new file mode 100755 index 0000000..e3523b9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/README.md @@ -0,0 +1,73 @@ +# simple-bar + +A [yabai](https://github.com/koekeishiya/yabai) or [AeroSpace](https://github.com/nikitabobko/AeroSpace) status bar widget for [Übersicht](https://github.com/felixhageloh/uebersicht) inspired by [nibar](https://github.com/kkga/nibar), [yabar](https://github.com/AlexNaga/yabar) and [this reddit post](https://www.reddit.com/r/unixporn/comments/chwk89/yabai_yabai_and_gruvbox_with_custom_ubersicht_bar/). + +[Website](https://www.jeantinland.com/toolbox/simple-bar) • [Documentation](https://www.jeantinland.com/toolbox/simple-bar/documentation) + +[`simple-bar-server`](https://github.com/Jean-Tinland/simple-bar-server) is available to trigger refresh and toggle widgets more efficiently with `curl` commands. + +A more "lite" & basic version is available [here](https://github.com/Jean-Tinland/simple-bar-lite). + +**Notice: As I am working simultaneously on a lot of projects, things here may seem to move slowly but they are still in progress. I'm always monitoring my notifications and messages, so if you have any questions or want to chat about anything, feel free [to reach out](https://www.jeantinland.com/contact/)!** + +## Features + +Among the principal features of `simple-bar`, you'll find: + +- **Show all opened apps** in every space +- **Show all opened windows** on the current space and its current layout mode (bsp, stack, float) +- Interactions: **focus window** on click, launch scripts, toggle states +- **Multi-monitor support**: enable individual widget on specific displays +- Add your own custom widgets in settings (it displays scripts outputs) +- **Refresh and toggle parts of simple-bar on the fly** with `curl` commands by installing [simple-bar-server](https://www.jeantinland.com/toolbox/simple-bar-server/documentation/introduction/) and enabling the server in settings. See [widgets](https://www.jeantinland.com/toolbox/simple-bar-server/documentation/widgets/), [yabai](https://www.jeantinland.com/toolbox/simple-bar-server/documentation/yabai/) or [AeroSpace](https://www.jeantinland.com/toolbox/simple-bar-server/documentation/aerospace/) options in its documentation +- **Extensible** themes system with 3 theme behaviors: **dark**, **light**, or **system** +- Numerous customization options, try them out in settings! +- A handfull selection of widgets +- Other features available only with SIP disabled and yabai scripting addition installed (**navigate to workspace**, **create new workspace on "+" click**, **move or destroy workspace on space hover**) + +[See all features in documentation](https://www.jeantinland.com/toolbox/simple-bar/documentation/features/). + +## Preview + +![image](./images/preview.png) + + + +## Installation + +Simply clone this repo in your Übersicht widgets directory with the following command. + +```bash +git clone --depth 1 https://github.com/Jean-Tinland/simple-bar $HOME/Library/Application\ Support/Übersicht/widgets/simple-bar +``` + +You'll find the full installation guide in the [documentation](https://www.jeantinland.com/toolbox/simple-bar/documentation/installation/). + +> [!WARNING]\ +> If you encounter this error: "simple-bar-index.jsx: Something went wrong…", it may be simply due to the fact that the default value for yabai or AeroSpace path is wrong in simple-bar. You can set this path in the settings module.\ +> The default paths are `$(which yabai)` and `$(which aerospace)`. + +> [!NOTE]\ +> `simple-bar` is trying to use yabai by default. If you want to switch to AeroSpace, you'll need to open the settings module (simply click on `simple-bar` then press `cmd` + `,`). You'll find the window manager choice in the "Global" tab. + +> [!TIP]\ +> If you experience some freezing issues with Übersicht or if you simply want to improve `simple-bar` responsiveness & energy consumption, please try to switch to `simple-bar-server` in order to trigger refresh with `curl` commands. You'll find more information about it in the repo [here](https://github.com/Jean-Tinland/simple-bar-server). + +## Roadmap + +Here are the features I'm planning to add in the future: + +- A timer widget ([#474](https://github.com/Jean-Tinland/simple-bar/issues/474)) +- Bars configurator (spawn multiple bars, place widgets anywhere…) [#380](https://github.com/Jean-Tinland/simple-bar/issues/380) +- More accessibility settings like reading direction (LTR or RTL) +- More default themes + +Feel free to open an issue if you have any feature request or if you want me to prioritize one of these features. + +## Special thanks + +I started this project with a simple idea and inspired by similar projects but over the year it has become a real community project. I want to thank everyone who contributed to this project, whether it's by opening issues, suggesting features, or even making pull requests. Furthermore, I also want to thank everyone who is using this project, I'm glad to see that it can be useful to others. + +So thank you, [@Amar1729](https://github.com/Amar1729), [@yorhodes](https://github.com/yorhodes), [@ZhongXiLu](https://github.com/ZhongXiLu), [@jamieweavis](https://github.com/jamieweavis), [@kvndrsslr](https://github.com/kvndrsslr), [@rosenpin](https://github.com/rosenpin), [@MikoMagni](https://github.com/MikoMagni), [@anujc4](https://github.com/anujc4), [@SijanC147](https://github.com/SijanC147), [@donaldguy](https://github.com/donaldguy), [@d-miketa](https://github.com/d-miketa), [@izifortune](https://github.com/izifortune), [@theshortcut](https://github.com/theshortcut), [@jming422](https://github.com/jming422), [@s00500](https://github.com/s00500), [@spwx](https://github.com/spwx), [@basbebe](https://github.com/basbebe), [@is0n](https://github.com/is0n), [@Joroovb](https://github.com/Joroovb), [@Sylenss](https://github.com/Sylenss), [@mrzone64](https://github.com/mrzone64), [@devinbhatt](https://github.com/devinbhatt), [@mdwitr0](https://github.com/mdwitr0), [@wr1159](https://github.com/wr1159), [@ardnep](https://github.com/ardnep), [@kntng](https://github.com/kntng) and every other that are helping me improve this little project by adding icons, fixing what they can, and more… + +I tried to keep track of everyone who contributed to this project in every page of the documentation. If you think I forgot you, please let me know. :) diff --git a/users/ryan/modules/simple-bar/simple-bar-source/SECURITY.md b/users/ryan/modules/simple-bar/simple-bar-source/SECURITY.md new file mode 100755 index 0000000..1779c21 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/SECURITY.md @@ -0,0 +1,9 @@ +# Security Policy + +## Supported Versions + +Only `simple-bar` latest version is supported (latest commit on master branch). + +## Reporting a Vulnerability + +If you think you have detected a vulnerability, please open a new issue in `simple-bar`'s repo, [here](https://github.com/Jean-Tinland/simple-bar/issues). diff --git a/users/ryan/modules/simple-bar/simple-bar-source/eslint.config.mjs b/users/ryan/modules/simple-bar/simple-bar-source/eslint.config.mjs new file mode 100755 index 0000000..378720e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/eslint.config.mjs @@ -0,0 +1,52 @@ +// eslint.config.js +import js from "@eslint/js"; +import globals from "globals"; +import reactPlugin from "eslint-plugin-react"; +import reactHooks from "eslint-plugin-react-hooks"; + +export default [ + { + files: ["**/*.{js,jsx}"], + languageOptions: { + ecmaVersion: 12, + sourceType: "module", + globals: { + ...globals.browser, + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + plugins: { + react: reactPlugin, + "react-hooks": reactHooks, + }, + rules: { + // Base ESLint recommended rules + ...js.configs.recommended.rules, + + // React recommended rules + ...reactPlugin.configs.recommended.rules, + + // React hooks recommended rules + ...reactHooks.configs.recommended.rules, + + // Your custom rules + "no-console": "warn", + "react/prop-types": "off", + "react/react-in-jsx-scope": "off", + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "warn", + "react-hooks/preserve-manual-memoization": "off", + "react-hooks/immutability": "off", + "react/no-unescaped-entities": "off", + }, + settings: { + react: { + version: "18.0", + }, + }, + }, +]; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/images/logo-simple-bar.png b/users/ryan/modules/simple-bar/simple-bar-source/images/logo-simple-bar.png new file mode 100755 index 0000000..4d1f5e4 Binary files /dev/null and b/users/ryan/modules/simple-bar/simple-bar-source/images/logo-simple-bar.png differ diff --git a/users/ryan/modules/simple-bar/simple-bar-source/images/preview.png b/users/ryan/modules/simple-bar/simple-bar-source/images/preview.png new file mode 100755 index 0000000..4c68dae Binary files /dev/null and b/users/ryan/modules/simple-bar/simple-bar-source/images/preview.png differ 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 @@ +import * as Uebersicht from "uebersicht"; +import * as Error from "./lib/components/error.jsx"; +import SimpleBarContextProvider from "./lib/components/simple-bar-context.jsx"; +import UserWidgets from "./lib/components/data/user-widgets.jsx"; +// Each simple-bar widgets exports both a "Component" or "Widget" render function +// and a "styles" string containing its own CSS +import * as Variables from "./lib/styles/core/variables"; +import * as Base from "./lib/styles/core/base"; +import * as Spaces from "./lib/styles/components/spaces/spaces"; +import * as Process from "./lib/styles/components/process"; +import * as Zoom from "./lib/components/data/zoom.jsx"; +import * as Time from "./lib/components/data/time.jsx"; +import * as DateDisplay from "./lib/components/data/date-display.jsx"; +import * as GitHub from "./lib/components/data/github.jsx"; +import * as Weather from "./lib/components/data/weather.jsx"; +import * as Netstats from "./lib/components/data/netstats.jsx"; +import * as Cpu from "./lib/components/data/cpu.jsx"; +import * as Gpu from "./lib/components/data/gpu.jsx"; +import * as Memory from "./lib/components/data/memory.jsx"; +import * as Battery from "./lib/components/data/battery.jsx"; +import * as Sound from "./lib/components/data/sound.jsx"; +import * as Mic from "./lib/components/data/mic.jsx"; +import * as Wifi from "./lib/components/data/wifi.jsx"; +import * as ViscosityVPN from "./lib/components/data/viscosity-vpn.jsx"; +import * as Keyboard from "./lib/components/data/keyboard.jsx"; +import * as Spotify from "./lib/components/data/spotify.jsx"; +import * as YouTubeMusic from "./lib/components/data/youtube-music.jsx"; +import * as Crypto from "./lib/components/data/crypto.jsx"; +import * as Stock from "./lib/components/data/stock.jsx"; +import * as Music from "./lib/components/data/music.jsx"; +import * as Mpd from "./lib/components/data/mpd.jsx"; +import * as BrowserTrack from "./lib/components/data/browser-track.jsx"; +import * as Notifications from "./lib/components/data/notifications.jsx"; +import * as NextMeeting from "./lib/components/data/next-meeting.jsx"; +import * as Specter from "./lib/components/data/specter.jsx"; +import * as Graph from "./lib/components/data/graph.jsx"; +import * as DataWidgetLoader from "./lib/components/data/data-widget-loader.jsx"; +import * as DataWidget from "./lib/components/data/data-widget.jsx"; +import * as SideIcon from "./lib/components/side-icon.jsx"; +import * as Missives from "./lib/components/missives/missives.jsx"; +import * as Utils from "./lib/utils"; +import * as Settings from "./lib/settings"; + +// Destructure React from Uebersicht in order to make eslint catch hook rules for example +const { React } = Uebersicht; + +// Spaces & process components are lazy loaded to avoid loading them when not needed +const YabaiContextProvider = React.lazy( + () => import("./lib/components/yabai-context.jsx"), +); +const AerospaceContextProvider = React.lazy( + () => import("./lib/components/aerospace-context.jsx"), +); +const YabaiSpaces = React.lazy( + () => import("./lib/components/yabai/spaces.jsx"), +); +const YabaiProcess = React.lazy( + () => import("./lib/components/yabai/process.jsx"), +); +const AerospaceSpaces = React.lazy( + () => import("./lib/components/aerospace/spaces.jsx"), +); +const AerospaceProcess = React.lazy( + () => import("./lib/components/aerospace/process.jsx"), +); + +// Set refresh frequency to false +// Übersicht auto-refresh system is not required as simple-bar works in sync with +// yabai or AeroSpaces for spaces & process widgets and data widgets are refreshed with +// their local refresh functions +const refreshFrequency = false; + +// Init settings from file if existing +Settings.init(); + +// Get settings from the Settings module +const settings = Settings.get(); +const { + // Do not edit the yabaiPath or aerospacePath lines, theses values are simply + // a default value used if nothing is defined in settings. + // You can setup your custom yabai or AeroSpace path in the settings module (Global tab) : + // while on an empty workspace, click on simple-bar then press cmd + , to open it. + yabaiPath = "/opt/homebrew/bin/yabai", + aerospacePath = "/opt/homebrew/bin/aerospace", + windowManager, // Window manager type (yabai or aerospace) + shell, // Shell to use for commands + enableServer, // Enable server mode + yabaiServerRefresh, // Refresh rate for yabai server +} = settings.global; +const { hideWindowTitle, displayOnlyIcon, displaySkhdMode } = settings.process; + +// Determine if signals should be disabled based on settings +const disableSignals = enableServer && yabaiServerRefresh; +const enableTitleChangedSignal = !hideWindowTitle && !displayOnlyIcon; + +// Construct command arguments based on window manager type +const yabaiArgs = `${yabaiPath} ${displaySkhdMode} ${disableSignals} ${enableTitleChangedSignal}`; +const aerospaceArgs = `${aerospacePath}`; +const args = getArguments(windowManager, yabaiArgs, aerospaceArgs); +const command = `${shell} simple-bar/lib/scripts/init-${windowManager}.sh ${args}`; + +// Inject global styles into the document +// I prefer using native CSS instead of Emotion bundled by default in Übersicht +Utils.injectStyles("simple-bar-index-styles", [ + Variables.styles, + Base.styles, + Spaces.styles, + Process.styles, + Settings.styles, + DataWidget.styles, + DateDisplay.styles, + Zoom.styles, + Time.styles, + GitHub.styles, + Weather.styles, + Netstats.styles, + Cpu.styles, + Gpu.styles, + Memory.styles, + Crypto.styles, + Stock.styles, + Battery.styles, + Wifi.styles, + ViscosityVPN.styles, + Keyboard.styles, + Mic.styles, + Sound.styles, + Spotify.styles, + YouTubeMusic.styles, + Music.styles, + Mpd.styles, + BrowserTrack.styles, + Notifications.styles, + NextMeeting.styles, + Specter.styles, + Graph.styles, + DataWidgetLoader.styles, + settings.customStyles.styles, + SideIcon.styles, + Missives.styles, +]); + +// Render function to display the bar +function render({ output, error }) { + // Define base classes for the bar based on settings + const baseClasses = Utils.classNames("simple-bar", { + "simple-bar--floating": settings.global.floatingBar, + "simple-bar--no-bar-background": settings.global.noBarBg, + "simple-bar--no-color-in-data": settings.global.noColorInData, + "simple-bar--on-bottom": settings.global.bottomBar, + "simple-bar--inline-spaces-options": settings.global.inlineSpacesOptions, + "simple-bar--animations-disabled": settings.global.disableAnimations, + "simple-bar--spaces-background-color-as-foreground": + settings.global.spacesBackgroundColorAsForeground, + "simple-bar--widgets-background-color-as-foreground": + settings.global.widgetsBackgroundColorAsForeground, + "simple-bar--process-aligned-to-left": !settings.global.centered, + }); + + // Handle errors + if (error) { + // eslint-disable-next-line no-console + console.error("Error in index.jsx", error); + return ; + } + if (!output) { + return ; + } + + // Cleanup the output data + const cleanedUpOutput = Utils.cleanupOutput(output); + + // Handle specific errors related to yabai or AeroSpace + const errors = ["yabaiError", "aerospaceError"]; + if (errors.includes(cleanedUpOutput)) { + return ; + } + + // Parse the output data + const data = Utils.parseJson(cleanedUpOutput); + if (!data) return ; + + const { displays, shadow, skhdMode, SIP, spaces, windows } = data; + + // Check if SIP (System Integrity Protection) is disabled + const SIPDisabled = SIP !== "System Integrity Protection status: enabled."; + + // Define additional classes based on data + const classes = Utils.classNames(baseClasses, { + "simple-bar--no-shadow": shadow !== "on", + }); + + // Handle bar focus ring on click + Utils.handleBarFocus(); + + // Render the bar with appropriate components and data + return ( + +
+ + }> + {windowManager === "yabai" && ( + + + + + )} + {windowManager === "aerospace" && ( + + + + + )} + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ ); +} + +export { command, refreshFrequency, render }; + +function getArguments(windowManager, yabaiArgs, aerospaceArgs) { + if (windowManager === "yabai") { + return yabaiArgs; + } + if (windowManager === "aerospace") { + return aerospaceArgs; + } + return ""; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/aerospace.js b/users/ryan/modules/simple-bar/simple-bar-source/lib/aerospace.js new file mode 100755 index 0000000..5b403b1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/aerospace.js @@ -0,0 +1,102 @@ +import * as Uebersicht from "uebersicht"; +import * as Settings from "./settings"; +import * as Utils from "./utils"; + +/** + * Switches to the specified workspace. + * @param {number} index - The index of the workspace to switch to. + */ +export async function goToSpace(index) { + const settings = Settings.get(); + const { aerospacePath = "/opt/homebrew/bin/aerospace" } = settings.global; + await Uebersicht.run(`${aerospacePath} workspace ${index}`); +} + +/** + * Focuses the window with the specified ID. + * @param {number} id - The ID of the window to focus. + */ +export async function focusWindow(id) { + const settings = Settings.get(); + const { aerospacePath = "/opt/homebrew/bin/aerospace" } = settings.global; + await Uebersicht.run(`${aerospacePath} focus --window-id ${id}`); +} + +/** + * Retrieves the list of workspaces for the specified display. + * @param {number} displayId - The ID of the display. + * @returns {Promise} The list of workspaces. + */ +export async function getSpaces(displayId) { + const settings = Settings.get(); + const { aerospacePath = "/opt/homebrew/bin/aerospace" } = settings.global; + const json = await Uebersicht.run( + `${aerospacePath} list-workspaces --monitor ${displayId} --json --format "%{workspace} %{monitor-appkit-nsscreen-screens-id}"` + ); + return Utils.parseJson(json); +} + +/** + * Retrieves the currently focused workspace. + * @returns {Promise} The focused workspace. + */ +export async function getFocusedSpace() { + const settings = Settings.get(); + const { aerospacePath = "/opt/homebrew/bin/aerospace" } = settings.global; + const json = await Uebersicht.run( + `${aerospacePath} list-workspaces --focused --json` + ); + return Utils.parseJson(json); +} + +/** + * Retrieves the list of windows for the specified workspace. + * @param {number} workspaceId - The ID of the workspace. + * @returns {Promise} The list of windows. + */ +export async function getWindows(workspaceId) { + const settings = Settings.get(); + const { aerospacePath = "/opt/homebrew/bin/aerospace" } = settings.global; + const json = await Uebersicht.run( + `${aerospacePath} list-windows --workspace ${workspaceId} --json` + ); + const cleanedJson = json.replace(/\\\n/g, "").replace(/00000/g, "0"); + return Utils.parseJson(cleanedJson); +} + +/** + * Retrieves the currently focused window. + * @returns {Promise} The focused window. + */ +export async function getFocusedWindow() { + const settings = Settings.get(); + const { aerospacePath = "/opt/homebrew/bin/aerospace" } = settings.global; + const json = await Uebersicht.run( + `${aerospacePath} list-windows --focused --json` + ); + return Utils.parseJson(json); +} + +/** + * Retrieves the list of displays. + * @returns {Promise} The list of displays. + */ +export async function getDisplays() { + const settings = Settings.get(); + const { aerospacePath = "/opt/homebrew/bin/aerospace" } = settings.global; + const json = await Uebersicht.run(`${aerospacePath} list-monitors --json`); + return Utils.parseJson(json); +} + +/** + * Retrieves the custom display index for the specified display. + * @param {Object} display - The display object. + * @returns {number} The custom display index. + */ +export function getDisplayIndex(item) { + const settings = Settings.get(); + const { customAeroSpaceDisplayIndexes } = settings.spacesDisplay; + const nativeId = item["monitor-appkit-nsscreen-screens-id"]; + const customId = customAeroSpaceDisplayIndexes[nativeId]; + return customId || nativeId; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/app-icons.js b/users/ryan/modules/simple-bar/simple-bar-source/lib/app-icons.js new file mode 100755 index 0000000..3eef38d --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/app-icons.js @@ -0,0 +1,254 @@ +import * as Icons from "./components/icons/icons.jsx"; + +// List of supported apps and their corresponding icons +export const apps = { + "1Password 7": Icons.OnePassword, + "1Password": Icons.OnePassword, + "Acrobat Reader": Icons.PDF, + "Activity Monitor": Icons.Activity, + "Affinity Designer": Icons.AffinityDesigner, + "Affinity Photo": Icons.AffinityPhoto, + "Affinity Publisher": Icons.AffinityPublisher, + Airmail: Icons.Airmail, + Alacritty: Icons.Terminal, + Alfred: Icons.Alfred, + "Android Messages": Icons.AndroidMessages, + "Android Studio": Icons.AndroidStudio, + Anki: Icons.Anki, + Antigravity: Icons.Antigravity, + Anytype: Icons.Anytype, + "App Store": Icons.AppStore, + Arc: Icons.Arc, + Atom: Icons.Atom, + "Apple Simulator": Icons.AppleSimulator, + Audacity: Icons.Audacity, + Aqua: Icons.Aqua, + "Battle.net": Icons.BattleNet, + "Bambu Studio": Icons.BambuStudio, + Bear: Icons.Bear, + "Beekeeper Studio": Icons.Beekeeper, + Bitwarden: Icons.BitWarden, + Blender: Icons.Blender, + "Brave Browser": Icons.BraveBrowser, + Bruno: Icons.Bruno, + Claude: Icons.Claude, + ClaudeCode: Icons.ClaudeCode, + Cline: Icons.Cline, + CLion: Icons.CLion, + Calendar: Icons.Calendar, + Calibre: Icons.Book, + "Canary Mail": Icons.Mail, + Caprine: Icons.Caprine, + CARROT: Icons.CARROT, + ChatGPT: Icons.ChatGPT, + Chatterino: Icons.Chatterino, + Chromium: Icons.GoogleChrome, + "CleanMyMac X": Icons.Desktop, + ClickUp: Icons.ClickUp, + "Code - Insiders": Icons.Code, + Code: Icons.Code, + Codex: Icons.Codex, + "Color Picker": Icons.ColorPicker, + ComfyUI: Icons.ComfyUI, + Copilot: Icons.Copilot, + Cursor: Icons.Cursor, + DataGrip: Icons.DataGrip, + Deezer: Icons.Deezer, + Default: Icons.Default, + "DEVONthink 3": Icons.DEVONthink3, + "Discord Canary": Icons.Discord, + "Discord PTB": Icons.Discord, + Discord: Icons.Discord, + "Docker Desktop": Icons.Docker, + Drafts: Icons.Drafts, + Dropbox: Icons.Dropbox, + Element: Icons.Element, + Emacs: Icons.Emacs, + "Evernote Legacy": Icons.EvernoteLegacy, + FaceTime: Icons.FaceTime, + Fantastical: Icons.Calendar, + Figma: Icons.Figma, + "Figma Beta": Icons.Figma, + "Final Cut Pro": Icons.FinalCutPro, + "Find My": Icons.Radar, + Finder: Icons.Finder, + "Firefox Developer Edition": Icons.FirefoxDeveloperEdition, + "Firefox Nightly": Icons.FirefoxDeveloperEdition, + Firefox: Icons.Firefox, + Fleet: Icons.Fleet, + Folx: Icons.Folx, + FreeTube: Icons.FreeTube, + Ghostty: Icons.Ghostty, + "GitHub Desktop": Icons.GitHub, + Gnucash: Icons.GnuCash, + GoLand: Icons.GoLand, + GoodNotes: Icons.GoodNotes, + "Google Chrome Canary": Icons.GoogleChrome, + "Google Chrome": Icons.GoogleChrome, + Goose: Icons.Goose, + "Grammarly Editor": Icons.Grammarly, + GrandTotal: Icons.Dollar, + Helium: Icons.Helium, + HEY: Icons.Mail, + "Home Assistant": Icons.HomeAssistant, + HTTPie: Icons.HTTPie, + Hyper: Icons.Terminal, + Insomnia: Icons.Insomnia, + "IntelliJ IDEA": Icons.Idea, + Iris: Icons.Iris, + iTerm2: Icons.Terminal, + Joplin: Icons.Joplin, + Kakoune: Icons.Kakoune, + KeePassXC: Icons.KeePassXC, + "Keyboard Maestro": Icons.KeyboardMaestro, + Keynote: Icons.Keynote, + kitty: Icons.Terminal, + "League of Legends": Icons.LeagueOfLegends, + LibreWolf: Icons.LibreWolf, + Linear: Icons.Linear, + Live: Icons.Ableton, + "LM Studio": Icons.LMStudio, + MacVim: Icons.Vim, + Mail: Icons.Mail, + MailMate: Icons.Mail, + Mailspring: Icons.Mail, + "MAMP PRO": Icons.Mamp, + MAMP: Icons.Mamp, + Maestro: Icons.MaestroAI, + Manus: Icons.Manus, + Matlab: Icons.Matlab, + Mattermost: Icons.Mattermost, + Messages: Icons.Messages, + "Microsoft Edge": Icons.MicrosoftEdge, + "Microsoft Excel": Icons.MicrosoftExcel, + "Microsoft Outlook": Icons.MicrosoftOutlook, + "Microsoft PowerPoint": Icons.MicrosoftPowerPoint, + "Microsoft Teams": Icons.Teams, + "Microsoft To Do": Icons.Things, + "Microsoft Word": Icons.MicrosoftWord, + Mimestream: Icons.Mimestream, + Min: Icons.MinBrowser, + Miro: Icons.Miro, + "Monero GUI": Icons.MoneroGUI, + "MongoDB Compass": Icons.MongoDB, + MoneyMoney: Icons.Bank, + mpv: Icons.Mpv, + Music: Icons.Music, + n8n: Icons.N8n, + Neovide: Icons.Vim, + NetNewsWire: Icons.NetNewsWire, + Notability: Icons.Notability, + NotebookLM: Icons.NotebookLM, + Notes: Icons.Notes, + Notion: Icons.Notion, + Nova: Icons.Nova, + Numbers: Icons.Numbers, + "OBS Studio": Icons.OBSStudio, + OBS: Icons.OBSStudio, + Obsidian: Icons.Obsidian, + Ollama: Icons.Ollama, + OmniFocus: Icons.OmniFocus, + OpenClaw: Icons.OpenClaw, + opencode: Icons.Opencode, + OrbStack: Icons.OrbStack, + Pages: Icons.Pages, + "Parallels Desktop": Icons.Parallels, + Perplexity: Icons.Perplexity, + "Pi-hole Remote": Icons.Pihole, + Pine: Icons.Pine, + Pins: Icons.Pins, + Podcasts: Icons.Podcasts, + "PomoDone App": Icons.Pomodone, + Postman: Icons.Postman, + "Proton Mail": Icons.ProtonMail, + PyCharm: Icons.PyCharm, + Preview: Icons.PDF, + PHPStorm: Icons.PHPStorm, + Plex: Icons.Plex, + Quip: Icons.Quip, + qutebrowser: Icons.QuteBrowser, + Receipts: Icons.Dollar, + "Redis Insight": Icons.Redis, + Reeder: Icons.Reeder5, + Reminders: Icons.Reminders, + Remnote: Icons.Remnote, + "Remote Desktop": Icons.RemoteDesktop, + Replit: Icons.Replit, + Rider: Icons.Rider, + "Rocket.Chat": Icons.RocketChat, + Roon: Icons.Roon, + "Royal TSX": Icons.RoyalTSX, + RubyMine: Icons.RubyMine, + RustRover: Icons.RustRover, + "Safari Technology Preview": Icons.Safari, + Safari: Icons.Safari, + Screens4: Icons.Screens4, + "Sequel Ace": Icons.SequelAce, + "Sequel Pro": Icons.SequelPro, + Setapp: Icons.Setapp, + Signal: Icons.Signal, + sioyek: Icons.PDF, + Sketch: Icons.Sketch, + SketchUp: Icons.SketchUp, + Skim: Icons.PDF, + Skype: Icons.Skype, + Slack: Icons.Slack, + Spark: Icons.Spark, + Spotify: Icons.Spotify, + Spotlight: Icons.Spotlight, + spotube: Icons.Spotube, + Spotube: Icons.Spotube, + "Sublime Text": Icons.SublimeText, + "Super Productivity": Icons.SuperProductivity, + "System Preferences": Icons.Gear, + "System Settings": Icons.Gear, + TablePlus: Icons.TablePlus, + Tailscale: Icons.Tailscale, + "TeamSpeak 3": Icons.TeamSpeak, + Telegram: Icons.Telegram, + Terminal: Icons.Terminal, + Texts: Icons.Messages, + Things: Icons.Things, + Thunderbird: Icons.Thunderbird, + TickTick: Icons.TickTick, + TIDAL: Icons.Tidal, + Todoist: Icons.Todoist, + "Tor Browser": Icons.TorBrowser, + Tower: Icons.Tower, + Transmit: Icons.Transmit, + Trello: Icons.Trello, + Tweetbot: Icons.Twitter, + Twitter: Icons.Twitter, + Typora: Icons.Text, + Vim: Icons.Vim, + VimR: Icons.Vim, + Vivaldi: Icons.Vivaldi, + VLC: Icons.VLC, + "VMware Fusion": Icons.VMwareFusion, + VSCodium: Icons.VSCodium, + Warp: Icons.Warp, + WebStorm: Icons.WebStorm, + WezTerm: Icons.Terminal, + WhatsApp: Icons.WhatsApp, + "Windows App": Icons.Windows, + Xcode: Icons.Xcode, + "YouTube Music": Icons.YoutubeMusic, + zathura: Icons.PDF, + Zed: Icons.Zed, + Zen: Icons.ZenBrowser, + Zeplin: Icons.Zeplin, + "zoom.us": Icons.Zoom, + Zotero: Icons.Zotero, + Zulip: Icons.Zulip, + + // German app names + Musik: Icons.Music, + Kalender: Icons.Calendar, + Nachrichten: Icons.Messages, + + // Chinese app names + 访达: Icons.Finder, + 邮件: Icons.Mail, + 微信: Icons.Wechat, + 网易云音乐: Icons.NeteaseMusic, +}; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace-context.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace-context.jsx new file mode 100755 index 0000000..f780a71 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace-context.jsx @@ -0,0 +1,117 @@ +import * as Uebersicht from "uebersicht"; +import { useSimpleBarContext } from "./simple-bar-context.jsx"; +import useServerSocket from "../hooks/use-server-socket.js"; +import * as Aerospace from "../aerospace.js"; + +const { React } = Uebersicht; + +// Create a context with default values +const AerospaceContext = React.createContext({ + spaces: [], + windows: [], + mode: "", +}); + +/** + * Custom hook to use the AerospaceContext + * @returns {Object} The context value + */ +export function useAerospaceContext() { + return React.useContext(AerospaceContext); +} + +// Memoized AerospaceContextProvider component +export default React.memo(AerospaceContextProvider); + +/** + * AerospaceContextProvider component + * @param {Object} props - The component props + * @param {React.ReactNode} props.children - The child components + * @returns {JSX.Element} The provider component + */ +function AerospaceContextProvider({ children }) { + // Get settings, displayIndex, and displays from SimpleBarContext + const { settings, displayIndex, displays } = useSimpleBarContext(); + const { enableServer, aerospaceServerRefresh } = settings.global; + const serverEnabled = enableServer && aerospaceServerRefresh; + + // State to store aerospace spaces + const [aerospaceSpaces, setAerospaceSpaces] = React.useState([]); + const latestRequestRef = React.useRef(0); + + // Fetches and sets the aerospace spaces + const getSpaces = React.useCallback(async () => { + const requestId = latestRequestRef.current + 1; + latestRequestRef.current = requestId; + + let focusedWindow = {}; + const [focusedSpace] = await Aerospace.getFocusedSpace(); + try { + [focusedWindow] = await Aerospace.getFocusedWindow(); + // eslint-disable-next-line no-empty + } catch {} + const spaces = await Promise.all( + displays.map(async (display) => { + const id = display["monitor-id"]; + const result = await Aerospace.getSpaces(id); + return Promise.all( + result.map(async (space) => { + const focused = space.workspace === focusedSpace.workspace; + const monitor = Aerospace.getDisplayIndex(space); + const windows = await Aerospace.getWindows(space.workspace); + const formatted = windows.map((window) => { + const focused = + window["window-id"] === focusedWindow["window-id"]; + return { + ...window, + focused, + }; + }); + return { ...space, windows: formatted, focused, monitor }; + }) + ); + }) + ); + if (requestId !== latestRequestRef.current) { + return; + } + setAerospaceSpaces(spaces.flat()); + }, [displays]); + + // Refreshes spaces with the data sent by simple-bar-server if it exists + // in order to speed up the process then refreshes everything in background + // else, simply refreshes everything + const refreshSpaces = React.useCallback( + async (data) => { + if (data) { + const { space } = data; + setAerospaceSpaces((current) => { + return current.map((s) => ({ ...s, focused: s.workspace === space })); + }); + getSpaces(); + } else { + await getSpaces(); + } + }, + [getSpaces] + ); + + // Resets the aerospace spaces state + const resetSpaces = () => { + setAerospaceSpaces([]); + }; + + // Use server socket to fetch and reset spaces + useServerSocket("spaces", serverEnabled, refreshSpaces, resetSpaces); + + // Fetch spaces on component mount and when displayIndex changes + React.useEffect(() => { + refreshSpaces(); + }, [refreshSpaces, displayIndex]); + + return ( + + {children} + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/opened-apps.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/opened-apps.jsx new file mode 100755 index 0000000..5b56966 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/opened-apps.jsx @@ -0,0 +1,33 @@ +import * as Uebersicht from "uebersicht"; +import * as AppIcons from "../../app-icons.js"; +import { SuspenseIcon } from "../icons/icon.jsx"; +import * as Utils from "../../utils.js"; + +const { React } = Uebersicht; + +/** + * OpenedApps component to display icons of opened applications. + * @param {Object} props - The component props. + * @param {Array} props.apps - The list of opened applications. + * @returns {JSX.Element|null} The rendered component or null if no apps are opened. + */ +export default function OpenedApps({ apps }) { + if (!apps.length) return null; + + return apps.map((app, i) => { + const { focused } = app; + const appName = Utils.normalizeAppName(app["app-name"]); + const Icon = AppIcons.apps[appName] || AppIcons.apps.Default; + + // Generate class names for the app icon + const classes = Utils.classNames("space__icon", { + "space__icon--focused": focused, + }); + + return ( + + + + ); + }); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/process.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/process.jsx new file mode 100755 index 0000000..0c461cc --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/process.jsx @@ -0,0 +1,72 @@ +import * as Uebersicht from "uebersicht"; +import Window from "./window.jsx"; +import * as Utils from "../../utils"; +import { useAerospaceContext } from "../aerospace-context.jsx"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; + +export { processStyles as styles } from "../../styles/components/process"; + +const { React } = Uebersicht; + +/** + * Process component to display windows in the current space. + * @returns {JSX.Element|null} The rendered component or null if not visible. + */ +const Component = React.memo(() => { + // Get spaces from aerospace context + const { spaces } = useAerospaceContext(); + // Get settings and display index from simple bar context + const { settings, displayIndex } = useSimpleBarContext(); + const { spacesDisplay, process, widgets } = settings; + const { exclusionsAsRegex } = spacesDisplay; + const { processWidget } = widgets; + const { centered, showOnDisplay } = process; + + // Determine if the component should be visible + const visible = + spaces?.length && + processWidget && + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay); + + if (!visible) return null; + + // Find the focused space on the current display + const { windows = [] } = + spaces.find((space) => space.focused && space.monitor === displayIndex) || + {}; + + if (!windows.length) return null; + + // Get exclusions for filtering windows + const exclusions = exclusionsAsRegex + ? spacesDisplay.exclusions + : spacesDisplay.exclusions.split(", "); + + const titleExclusions = exclusionsAsRegex + ? spacesDisplay.titleExclusions + : spacesDisplay.titleExclusions.split(", "); + + // Generate class names for the component + const classes = Utils.classNames("process", { + "process--centered": centered, + }); + + // Filter windows based on exclusions + const filteredWindows = windows.filter((window) => + Utils.filterApps(window, exclusions, titleExclusions, exclusionsAsRegex), + ); + + return ( +
+
+ {filteredWindows.map((window, i) => ( + + ))} +
+
+ ); +}); + +Component.displayName = "Process"; + +export default Component; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/space.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/space.jsx new file mode 100755 index 0000000..ab91bbb --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/space.jsx @@ -0,0 +1,84 @@ +import * as Uebersicht from "uebersicht"; +import OpenedApps from "./opened-apps.jsx"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Utils from "../../utils.js"; +import * as Aerospace from "../../aerospace.js"; + +const { React } = Uebersicht; + +/** + * Space component to display a single space. + * @param {Object} props - The component props. + * @param {Object} props.space - The space object. + * @param {boolean} props.lastOfSpace - Indicates if this is the last space of the monitor. + * @returns {JSX.Element|null} The rendered component. + */ +export default function Space({ space, lastOfSpace }) { + const { windows } = space; + const { settings } = useSimpleBarContext(); + const { spacesDisplay } = settings; + const { + displayAllSpacesOnAllScreens, + exclusionsAsRegex, + hideDuplicateAppsInSpaces, + } = spacesDisplay; + const { workspace, focused } = space; + + /** + * Handle click event to switch to the clicked space. + * @param {Event} e - The click event. + */ + const onClick = (e) => { + if (focused) return; + Aerospace.goToSpace(workspace); + Utils.clickEffect(e); + }; + + // Determine if the space should be hidden + const hidden = !focused && !windows.length && spacesDisplay.hideEmptySpaces; + + if (hidden) return null; + + // Get exclusions and title exclusions based on settings + const exclusions = exclusionsAsRegex + ? spacesDisplay.exclusions + : spacesDisplay.exclusions.split(", "); + const titleExclusions = exclusionsAsRegex + ? spacesDisplay.titleExclusions + : spacesDisplay.titleExclusions.split(", "); + + // Filter windows based on exclusions + const filteredWindows = windows.filter((window) => + Utils.filterApps(window, exclusions, titleExclusions, exclusionsAsRegex), + ); + + // Remove duplicate apps if the setting is enabled + const displayedWindows = hideDuplicateAppsInSpaces + ? filteredWindows.reduce((acc, window) => { + const isDuplicate = acc.find( + (w) => w["app-name"] === window["app-name"], + ); + return isDuplicate ? acc : [...acc, window]; + }, []) + : filteredWindows; + + // Determine the CSS classes for the space + const classes = Utils.classNames("space", { + "space--focused": focused, + "space--empty": windows.length, + }); + + return ( + + {displayAllSpacesOnAllScreens && lastOfSpace && ( +
+ )} +
+ +
+ + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/spaces.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/spaces.jsx new file mode 100755 index 0000000..d576389 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/spaces.jsx @@ -0,0 +1,67 @@ +import * as Uebersicht from "uebersicht"; +import Space from "./space.jsx"; +import { useAerospaceContext } from "../aerospace-context.jsx"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Utils from "../../utils.js"; +import * as AeroSpace from "../../aerospace.js"; + +export { spacesStyles as styles } from "../../styles/components/spaces/spaces.js"; + +const { React } = Uebersicht; + +/** + * Spaces component to display spaces on the screen. + * @returns {JSX.Element|null} The rendered component. + */ +const Component = React.memo(() => { + // Get spaces from aerospace context + const { spaces } = useAerospaceContext(); + // Get displays, displayIndex, and settings from simple bar context + const { displays, displayIndex, settings } = useSimpleBarContext(); + const { spacesDisplay, process } = settings; + const { displayAllSpacesOnAllScreens, showOnDisplay } = spacesDisplay; + // Determine if the component should be visible on the current display + const visible = Utils.isVisibleOnDisplay(displayIndex, showOnDisplay); + const isProcessVisible = Utils.isVisibleOnDisplay( + displayIndex, + process.showOnDisplay + ); + + // If not visible, return null + if (!visible) return null; + + // If there are no spaces, return an empty div + if (!spaces?.length) { + return
; + } + + // Map through displays and render spaces for the current display + return displays.map((display) => { + const displayId = AeroSpace.getDisplayIndex(display); + if (displayId !== displayIndex) return null; + + // Filter spaces based on display settings + const filteredSpaces = displayAllSpacesOnAllScreens + ? spaces + : spaces.filter((space) => space.monitor === displayId); + + return ( +
+ {filteredSpaces.map((space, i) => { + const { workspace } = space; + const lastOfSpace = + i !== 0 && space.monitor !== spaces[i - 1].monitor; + + return ( + + ); + })} + {isProcessVisible &&
} +
+ ); + }); +}); + +Component.displayName = "Spaces"; + +export default Component; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/window.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/window.jsx new file mode 100755 index 0000000..04b54d6 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/aerospace/window.jsx @@ -0,0 +1,99 @@ +import * as Uebersicht from "uebersicht"; +import * as AppIcons from "../../app-icons"; +import { SuspenseIcon } from "../icons/icon.jsx"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Utils from "../../utils"; +import * as Aerospace from "../../aerospace"; + +const { React } = Uebersicht; + +/** + * Window component to display a window in the process bar. + * @param {Object} props - The component props. + * @param {Object} props.window - The window object. + * @returns {JSX.Element|null} The rendered component. + */ +export default function Window({ window }) { + // Get settings from context + const { settings } = useSimpleBarContext(); + // Create a ref for the button element + const ref = React.useRef(); + // Destructure settings + const { + displayOnlyCurrent, + hideWindowTitle, + displayOnlyIcon, + expandAllProcesses, + } = settings.process; + // Destructure window properties + const { + focused, + "app-name": appName, + "window-title": title, + "window-id": id, + } = window; + + // If displayOnlyCurrent is true and the window is not focused, return null + if (displayOnlyCurrent && !focused) { + return null; + } + + // Get the icon for the app or use the default icon + const Icon = AppIcons.apps[appName] || AppIcons.apps.Default; + + /** + * Handle click event on the window button. + * @param {Event} e - The click event. + */ + const onClick = (e) => { + !displayOnlyCurrent && Utils.clickEffect(e); + Aerospace.focusWindow(id); + }; + + /** + * Handle mouse enter event on the window button. + */ + const onMouseEnter = () => { + Utils.startSliding(ref.current, ".process__inner", ".process__name"); + }; + + /** + * Handle mouse leave event on the window button. + */ + const onMouseLeave = () => { + Utils.stopSliding(ref.current, ".process__name"); + }; + + // Generate class names based on settings and window state + const classes = Utils.classNames("process__window", { + "process__window--expanded": expandAllProcesses, + "process__window--focused": !displayOnlyCurrent && focused, + "process__window--only-current": displayOnlyCurrent, + "process__window--only-icon": displayOnlyIcon, + }); + + // Clean up the window title + const cleanedUpName = + appName !== title && title.length ? `${appName} / ${title}` : appName; + const processName = hideWindowTitle ? appName : cleanedUpName; + + // Render the window button + return ( + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/battery.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/battery.jsx new file mode 100755 index 0000000..1f08af6 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/battery.jsx @@ -0,0 +1,183 @@ +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 { SuspenseIcon } from "../icons/icon.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 { batteryStyles as styles } from "../../styles/components/data/battery"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 10000; + +/** + * Battery widget component + * @returns {JSX.Element|null} The battery widget component + */ +export const Widget = React.memo(() => { + const { displayIndex, settings, pushMissive } = useSimpleBarContext(); + const { widgets, batteryWidgetOptions } = settings; + const { batteryWidget } = widgets; + const { + refreshFrequency, + toggleCaffeinateOnClick, + caffeinateOption, + disableCaffeinateInvertedBackground, + showOnDisplay, + showIcon, + } = batteryWidgetOptions; + + // Determine if the widget should be visible based on display settings + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && batteryWidget; + + // Calculate the refresh frequency for the widget + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + // Reset the widget state + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetch battery information and update the state + */ + const getBattery = React.useCallback(async () => { + if (!visible) return; + // Fetch battery information and parse the results + const [system, percentage, status, caffeinate, lowPowerMode] = + await Promise.all([ + Utils.getSystem(), + Utils.cachedRun( + `pmset -g batt | grep -Eo '[0-9]+%' | head -1 | tr -d '%'`, + refresh, + ), + Utils.cachedRun( + `pmset -g batt | head -1 | grep -q 'AC Power' && echo 'AC' || echo 'Batt'`, + refresh, + ), + Uebersicht.run(`pgrep caffeinate -d`), + Utils.cachedRun( + `pmset -g | awk '/lowpowermode|powermode/ {print $2; exit}'`, + refresh, + ), + ]); + setState({ + system, + percentage: parseInt(percentage, 10), + charging: Utils.cleanupOutput(status) === "AC", + caffeinate: Utils.cleanupOutput(caffeinate), + lowPowerMode: Utils.cleanupOutput(lowPowerMode) === "1", + }); + setLoading(false); + }, [visible, refresh]); + + // Use server socket to fetch battery data + useServerSocket("battery", visible, getBattery, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getBattery, refresh); + + if (loading) return ; + if (!state) return null; + + const { system, percentage, charging, caffeinate, lowPowerMode } = state; + const isLowBattery = !charging && percentage < 20; + + const classes = Utils.classNames("battery", { + "battery--low": isLowBattery, + "battery--low-power-mode": lowPowerMode, + "battery--caffeinate": + !disableCaffeinateInvertedBackground && caffeinate.length > 0, + }); + + const transformValue = getTransform(percentage); + + /** + * Handle click event to toggle caffeinate mode + * @param {React.MouseEvent} e - The click event + */ + const onClick = async (e) => { + Utils.clickEffect(e); + await toggleCaffeinate(system, caffeinate, caffeinateOption, pushMissive); + getBattery(); + }; + + const onClickProp = toggleCaffeinateOnClick ? { onClick } : {}; + + const Icon = () => ( +
+
+
+ {charging && ( + + + + )} +
+
+ ); + + return ( + + {caffeinate.length > 0 && ( + + + + )} + {percentage}% + + ); +}); + +Widget.displayName = "Battery"; + +/** + * Get the transform value for the battery icon based on the percentage + * @param {number} value - The battery percentage + * @returns {string} The transform value + */ +function getTransform(value) { + let transform = `0.${value}`; + if (value === 100) transform = "1"; + if (value < 10) transform = `0.0${value}`; + return `scaleX(${transform})`; +} + +/** + * Toggle caffeinate mode on or off + * @param {string} system - The system architecture + * @param {string} caffeinate - The current caffeinate state + * @param {string} option - The caffeinate option + * @param {function} pushMissive - Function to push notifications + */ +async function toggleCaffeinate(system, caffeinate, option, pushMissive) { + const command = + system === "x86_64" ? "caffeinate" : "arch -arch arm64 caffeinate"; + if (caffeinate.length === 0) { + Uebersicht.run(`${command} ${option} &`); + Utils.notification("Enabling caffeinate...", pushMissive); + } else { + await Uebersicht.run("pkill -f caffeinate"); + Utils.notification("Disabling caffeinate...", pushMissive); + } +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/browser-track.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/browser-track.jsx new file mode 100755 index 0000000..d320e4a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/browser-track.jsx @@ -0,0 +1,147 @@ +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 { SuspenseIcon } from "../icons/icon.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 { browserTrackStyles as styles } from "../../styles/components/data/browser-track"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 10000; + +/** + * BrowserTrack Widget component + * @returns {JSX.Element|null} The BrowserTrack widget + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, browserTrackWidgetOptions } = settings; + const { browserTrackWidget } = widgets; + const { refreshFrequency, showSpecter, showOnDisplay, showIcon } = + browserTrackWidgetOptions; + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && browserTrackWidget; + + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + const ref = React.useRef(); + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + /** + * Resets the widget state + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetches the current browser track information + */ + const getBrowserTrack = React.useCallback(async () => { + if (!visible) return; + const [firefoxStatus, firefoxDevStatus] = await Promise.all([ + Utils.cachedRun( + `pgrep -xq 'Firefox' && echo "true" || echo "false"`, + refresh, + ), + Utils.cachedRun( + `pgrep -xq 'Firefox Developer Edition' && echo "true" || echo "false"`, + refresh, + ), + ]); + const isFirefoxDevRunning = + Utils.cleanupOutput(firefoxDevStatus) === "true"; + const isFirefoxRunning = Utils.cleanupOutput(firefoxStatus) === "true"; + const scriptNamePrefix = isFirefoxDevRunning + ? "firefox-dev" + : isFirefoxRunning + ? "firefox" + : "browser"; + + const [browserTrackOutput, spotifyStatus] = await Promise.all([ + Utils.cachedRun( + `osascript ./simple-bar/lib/scripts/${scriptNamePrefix}-audio.applescript 2>&1`, + refresh, + ), + Utils.cachedRun( + `pgrep -fq '[S]potify Helper' && echo "true" || echo "false"`, + refresh, + ), + ]); + const browserTrack = JSON.parse(browserTrackOutput); + setState({ + ...browserTrack, + isSpotifyRunning: Utils.cleanupOutput(spotifyStatus) === "true", + }); + setLoading(false); + }, [visible, refresh]); + + useServerSocket( + "browser-track", + visible, + getBrowserTrack, + resetWidget, + setLoading, + ); + useWidgetRefresh(visible, getBrowserTrack, refresh); + + if (loading) return ; + if (!state) return null; + const { browser, title, isSpotifyRunning } = state; + + if (!browser?.length || !title?.length || isSpotifyRunning) return null; + + /** + * Icon component for displaying browser and playing icons + * @returns {JSX.Element} The icon component + */ + const Icon = () => { + const BrowserIcon = getIcon(browser); + return ( +
+ + + + +
+ ); + }; + + return ( + + {title} + + ); +}); + +Widget.displayName = "BrowserTrack"; + +/** + * Returns the appropriate icon component based on the browser name + * @param {string} browser - The name of the browser + * @returns {JSX.Element} The icon component for the browser + */ +function getIcon(browser) { + if (browser === "chrome") return Icons.GoogleChrome; + if (browser === "brave") return Icons.BraveBrowser; + if (browser === "safari") return Icons.Safari; + if (browser === "firefox") return Icons.Firefox; + return Icons.Default; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/cpu.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/cpu.jsx new file mode 100755 index 0000000..378b3c9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/cpu.jsx @@ -0,0 +1,153 @@ +import * as Uebersicht from "uebersicht"; +import * as DataWidget from "./data-widget.jsx"; +import * as DataWidgetLoader from "./data-widget-loader.jsx"; +import Graph from "./graph.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 { cpuStyles as styles } from "../../styles/components/data/cpu"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 2000; +const GRAPH_LENGTH = 50; + +/** + * CPU Widget component + * @returns {JSX.Element|null} The CPU widget + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, cpuWidgetOptions } = settings; + const { cpuWidget } = widgets; + const { + refreshFrequency, + showOnDisplay, + displayAsGraph, + cpuMonitorApp, + showIcon, + cpuUsageThreshold, + } = cpuWidgetOptions; + + // Determine if the widget should be visible based on display settings + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && cpuWidget; + + // Set the refresh frequency for the widget + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + const [graph, setGraph] = React.useState([]); + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + /** + * Reset the widget state + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + setGraph([]); + }; + + /** + * Fetch CPU usage data + */ + const getCpu = React.useCallback(async () => { + if (!visible) return; + try { + const usage = await Utils.cachedRun( + `top -l 2 | awk '/CPU usage/ && NR > 10 {gsub(/%/, "", $7); print int(100 - $7); exit}'`, + refresh, + ); + const formattedUsage = { usage: parseInt(usage, 10) }; + setState(formattedUsage); + if (displayAsGraph) { + Utils.addToGraphHistory(formattedUsage, setGraph, GRAPH_LENGTH); + } + setLoading(false); + } catch { + setTimeout(getCpu, 1000); + } + }, [displayAsGraph, setGraph, visible, refresh]); + + // Use server socket to fetch CPU data + useServerSocket("cpu", visible, getCpu, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getCpu, refresh); + + if (loading) return ; + if (!state) return null; + + const { usage } = state; + const threshold = Number(cpuUsageThreshold) || 0; + const usageValue = Number(usage) || 0; + + if (threshold > 0 && usageValue < threshold) return null; + + // Handle click event to open CPU monitor app + const onClick = + cpuMonitorApp === "None" + ? undefined + : (e) => { + Utils.clickEffect(e); + openCpuUsageApp(cpuMonitorApp); + }; + + if (displayAsGraph) { + return ( + + + + ); + } + + return ( + + {usage}% + + ); +}); + +Widget.displayName = "Cpu"; + +/** + * Open the specified CPU usage monitoring application + * @param {string} app - The name of the application to open + */ +function openCpuUsageApp(app) { + switch (app) { + case "Activity Monitor": + Uebersicht.run(`open -a "Activity Monitor"`); + break; + case "Top": + Utils.runInUserTerminal("top"); + break; + } +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/crypto.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/crypto.jsx new file mode 100755 index 0000000..3faf4ea --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/crypto.jsx @@ -0,0 +1,160 @@ +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 { cryptoStyles as styles } from "../../styles/components/data/crypto"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 5 * 60 * 1000; // Default refresh frequency set to 5 minutes + +/** + * Crypto Widget Component + * @returns {JSX.Element|null} The Crypto Widget component + */ +export const Widget = React.memo(() => { + const { displayIndex, settings, pushMissive } = useSimpleBarContext(); + const { widgets, cryptoWidgetOptions } = settings; + const { cryptoWidget } = widgets; + const { + refreshFrequency, + denomination, + identifiers, + precision, + showOnDisplay, + showIcon, + } = cryptoWidgetOptions; + + // Calculate the refresh frequency using the provided or default value + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + // Determine if the widget should be visible on the current display + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && cryptoWidget; + + const ref = React.useRef(); + const denominatorToken = getDenominatorToken(denomination); + + // Memoize cleanedUpIdentifiers to prevent recreation on every render + const cleanedUpIdentifiers = React.useMemo( + () => identifiers.replace(/ /g, ""), + [identifiers], + ); + + // Memoize enumeratedIdentifiers to prevent recreation on every render + const enumeratedIdentifiers = React.useMemo( + () => cleanedUpIdentifiers.replace(/ /g, "").split(","), + [cleanedUpIdentifiers], + ); + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + // Reset the widget state + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetches cryptocurrency prices from the CoinGecko API + */ + const getCrypto = React.useCallback(async () => { + if (!visible) return; + const response = await fetch( + `https://api.coingecko.com/api/v3/simple/price?ids=${cleanedUpIdentifiers}&vs_currencies=${denomination}`, + ); + const result = await response.json(); + + const prices = enumeratedIdentifiers.map((id) => { + const value = parseFloat(result[id][denomination]).toFixed(precision); + return `${denominatorToken}${value}`; + }); + setState(prices); + setLoading(false); + }, [ + visible, + cleanedUpIdentifiers, + denomination, + enumeratedIdentifiers, + precision, + denominatorToken, + ]); + + useServerSocket("crypto", visible, getCrypto, resetWidget, setLoading); + useWidgetRefresh(visible, getCrypto, refresh); + + /** + * Refreshes the cryptocurrency prices + * @param {Event} e - The event object + */ + const refreshCrypto = (e) => { + Utils.clickEffect(e); + setLoading(true); + getCrypto(); + Utils.notification("Refreshing price from coingecko.com...", pushMissive); + }; + + if (loading) return ; + if (!state) return null; + + const classes = Utils.classNames("crypto"); + + return enumeratedIdentifiers.map((id, i) => ( + openCrypto(e, pushMissive)} + onRightClick={refreshCrypto} + > + {state[i]} + + )); +}); + +Widget.displayName = "Crypto"; + +/** + * Returns the icon component for a given cryptocurrency identifier + * @param {string} identifier - The cryptocurrency identifier + * @returns {JSX.Element} The icon component + */ +function getIcon(identifier) { + if (identifier === "celo") return Icons.Celo; + if (identifier === "ethereum") return Icons.Ethereum; + if (identifier === "bitcoin") return Icons.Bitcoin; + return Icons.Moon; +} + +/** + * Returns the symbol for a given denomination + * @param {string} denomination - The denomination (e.g., "usd", "eur") + * @returns {string} The symbol for the denomination + */ +function getDenominatorToken(denomination) { + if (denomination === "usd") return "$"; + if (denomination === "eur") return "€"; + return ""; +} + +/** + * Opens the cryptocurrency price chart + * @param {Event} e - The event object + * @param {Function} pushMissive - The function to push a notification + */ +function openCrypto(e, pushMissive) { + Utils.clickEffect(e); + Utils.notification("Opening price chart from coingecko.com...", pushMissive); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget-loader.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget-loader.jsx new file mode 100755 index 0000000..4115024 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget-loader.jsx @@ -0,0 +1,37 @@ +import * as Uebersicht from "uebersicht"; +import * as Utils from "../../utils"; + +export { dataWidgetLoaderStyles as styles } from "../../styles/components/data/data-widget-loader"; + +const { React } = Uebersicht; + +/** + * A memoized React component that renders a data widget loader. + * + * @param {Object} props - The properties object. + * @param {number} [props.width=14] - The width of the loader. + * @param {number} [props.height=14] - The height of the loader. + * @param {string} [props.className] - Additional class names for the loader. + * @param {Object} [props.style] - Additional styles for the loader. + * @returns {JSX.Element} The rendered data widget loader component. + */ +export const Widget = React.memo( + ({ width = 14, height = 14, className, style }) => { + // Generate class names using the Utils.classNames function + const classes = Utils.classNames("data-widget-loader", "data-widget", { + [className]: className, + }); + + // Return the JSX for the data widget loader + return ( +
+
+
+ ); + }, +); + +Widget.displayName = "DataWidgetLoader"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx new file mode 100755 index 0000000..f5555a1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/data-widget.jsx @@ -0,0 +1,136 @@ +import * as Uebersicht from "uebersicht"; +import * as Specter from "./specter.jsx"; +import * as Utils from "../../utils"; +import { SuspenseIcon } from "../icons/icon.jsx"; +export { dataWidgetStyles as styles } from "../../styles/components/data/data-widget"; + +const { React } = Uebersicht; + +/** + * Widget component that renders a clickable data widget with optional icon and specter. + * @param {Object} props - The properties object. + * @param {React.Component} props.Icon - The icon component to display. + * @param {string} props.classes - Additional classes for the widget. + * @param {string} props.href - The URL to link to. + * @param {function} props.onClick - The click event handler. + * @param {function} props.onRightClick - The right-click event handler. + * @param {function} props.onMiddleClick - The middle-click event handler. + * @param {Object} props.style - The style object. + * @param {boolean} props.disableSlider - Flag to disable the slider effect. + * @param {boolean} props.showSpecter - Flag to show the specter widget. + * @param {boolean} props.useDivForClick - Render a div for click handling instead of a button. + * @param {React.ReactNode} props.children - The child elements to render inside the widget. + * @returns {React.ReactElement} The rendered widget component. + */ +export function Widget({ + Icon, + classes, + href, + onClick, + onRightClick, + onMiddleClick, + style, + disableSlider, + showSpecter, + useDivForClick, + children, +}) { + const ref = React.useRef(); + + let Tag = "div"; + if (href) Tag = "a"; + if (onClick && !href && !useDivForClick) Tag = "button"; + + const renderDivButton = Tag === "div" && Boolean(onClick); + + const dataWidgetClasses = Utils.classNames("data-widget", classes, { + "data-widget--clickable": href || onClick, + }); + + /** + * Handles the click event, determining the appropriate action based on the event. + * @param {MouseEvent} e - The mouse event. + */ + const onClickProp = (e) => { + const { metaKey } = e; + const action = metaKey || isMiddleClick(e) ? onMiddleClick : onClick; + if (action) action(e); + }; + + /** + * Handles the mouse enter event to start the sliding effect. + */ + const onMouseEnter = () => { + Utils.startSliding( + ref.current, + ".data-widget__inner", + ".data-widget__slider", + ); + }; + + /** + * Handles the mouse leave event to stop the sliding effect. + */ + const onMouseLeave = () => { + Utils.stopSliding(ref.current, ".data-widget__slider"); + }; + + /** + * Handles keyboard interaction for div-based clickable widgets. + * @param {KeyboardEvent} e - The keyboard event. + */ + const onKeyDown = (e) => { + if (e.key !== "Enter" && e.key !== " ") return; + e.preventDefault(); + onClickProp(e); + }; + + return ( + + {Icon && ( + + + + )} + {showSpecter && } + {children} + + ); +} + +/** + * Inner component that optionally wraps children with sliding effect elements. + * @param {Object} props - The properties object. + * @param {boolean} props.disableSlider - Flag to disable the slider effect. + * @param {React.ReactNode} props.children - The child elements to render inside the inner component. + * @returns {React.ReactElement} The rendered inner component. + */ +function Inner({ disableSlider, children }) { + if (disableSlider) return children; + return ( +
+
{children}
+
+ ); +} + +/** + * Checks if the event is a middle-click. + * @param {MouseEvent} e - The mouse event. + * @returns {boolean} True if the event is a middle-click, false otherwise. + */ +function isMiddleClick(e) { + return e.button === 1 || e["button&2"] === 1; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/date-display.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/date-display.jsx new file mode 100755 index 0000000..af4c058 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/date-display.jsx @@ -0,0 +1,118 @@ +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 * as Utils from "../../utils"; +import useWidgetRefresh from "../../hooks/use-widget-refresh"; +import useServerSocket from "../../hooks/use-server-socket"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; + +export { dateStyles as styles } from "../../styles/components/data/date-display"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 30000; + +/** + * Date display widget component. + * @returns {JSX.Element} The date display widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, dateWidgetOptions } = settings; + const { dateWidget } = widgets; + const { + refreshFrequency, + shortDateFormat, + locale, + calendarApp, + showOnDisplay, + showIcon, + } = dateWidgetOptions; + + // Determine if the widget should be visible based on display settings + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && dateWidget; + + // Calculate the refresh frequency for the widget + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + const formatOptions = shortDateFormat ? "short" : "long"; + + // Memoize the date format options + const options = React.useMemo( + () => ({ + weekday: formatOptions, + month: formatOptions, + day: "numeric", + }), + [formatOptions], + ); + + // Ensure locale is valid, default to "en-UK" if not + const _locale = locale.length > 4 ? locale : "en-UK"; + + /** + * Reset the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Get the current date and update the state. + */ + const getDate = React.useCallback(() => { + if (!visible) return; + const now = new Date().toLocaleDateString(_locale, options); + setState({ now }); + setLoading(false); + }, [_locale, options, visible]); + + // Use server socket to get date updates + useServerSocket("date-display", visible, getDate, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getDate, refresh); + + if (loading) return ; + if (!state) return null; + const { now } = state; + + /** + * Handle click event to open the calendar application. + * @param {Event} e - The click event. + */ + const onClick = (e) => { + Utils.clickEffect(e); + openCalendarApp(calendarApp); + }; + + return ( + + {now} + + ); +}); + +Widget.displayName = "DateDisplay"; + +/** + * Open the specified calendar application. + * @param {string} calendarApp - The name of the calendar application to open. + */ +function openCalendarApp(calendarApp) { + const appName = calendarApp || "Calendar"; + Uebersicht.run(`open -a "${appName}"`); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/github.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/github.jsx new file mode 100755 index 0000000..89308b5 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/github.jsx @@ -0,0 +1,105 @@ +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.js"; +import useServerSocket from "../../hooks/use-server-socket.js"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Utils from "../../utils.js"; + +export { githubStyles as styles } from "../../styles/components/data/github.js"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 1000 * 60 * 10; + +/** + * GitHub notification widget component + * @returns {JSX.Element|null} The GitHub notification widget component + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, githubWidgetOptions } = settings; + const { githubWidget } = widgets; + const { + refreshFrequency, + showOnDisplay, + hideWhenNoNotification, + notificationUrl, + ghBinaryPath, + showIcon, + } = githubWidgetOptions; + + const isDisabled = React.useRef(false); + + // Calculate 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) && githubWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + /** + * Reset the widget state + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetch GPU data and update the widget state + */ + const getGitHub = React.useCallback(async () => { + if (!visible) return; + setLoading(true); + const result = await Utils.cachedRun( + `${ghBinaryPath} api notifications`, + refresh, + ); + if (!visible || isDisabled.current) { + return setLoading(false); + } + const json = JSON.parse(result); + const count = json.length; + setState({ count: count > 99 ? "99+" : count }); + setLoading(false); + }, [ghBinaryPath, visible, refresh]); + + // Update the disabled state based on visibility + React.useEffect(() => { + isDisabled.current = !visible; + }, [visible]); + + // Use server socket to fetch GPU data + useServerSocket("github", visible, getGitHub, resetWidget, setLoading); + // Use widget refresh hook to periodically refresh the widget + useWidgetRefresh(visible, getGitHub, refresh); + + if (loading) return ; + if (!state) return null; + + const { count } = state; + + if (hideWhenNoNotification && count === 0) return null; + + return ( + + {count} + + ); +}); + +Widget.displayName = "GitHub"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/gpu.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/gpu.jsx new file mode 100755 index 0000000..6ac1dab --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/gpu.jsx @@ -0,0 +1,128 @@ +import * as Uebersicht from "uebersicht"; +import * as DataWidget from "./data-widget.jsx"; +import * as DataWidgetLoader from "./data-widget-loader.jsx"; +import Graph from "./graph.jsx"; +import * as Icons from "../icons/icons.jsx"; +import useWidgetRefresh from "../../hooks/use-widget-refresh.js"; +import useServerSocket from "../../hooks/use-server-socket.js"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Utils from "../../utils.js"; + +export { gpuStyles as styles } from "../../styles/components/data/gpu.js"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 2000; +const GRAPH_LENGTH = 40; + +/** + * GPU Widget component + * @returns {JSX.Element|null} The GPU widget component + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, gpuWidgetOptions } = settings; + const { gpuWidget } = widgets; + const { + refreshFrequency, + showOnDisplay, + displayAsGraph, + gpuMacmonBinaryPath, + showIcon, + } = gpuWidgetOptions; + + const isDisabled = React.useRef(false); + + // Calculate 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) && gpuWidget; + + const [graph, setGraph] = React.useState([]); + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + /** + * Reset the widget state + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + setGraph([]); + }; + + /** + * Fetch GPU data and update the widget state + */ + const getGpu = React.useCallback(async () => { + if (!visible) return; + try { + const result = await Utils.cachedRun( + `${gpuMacmonBinaryPath} pipe -s 1`, + refresh, + ); + if (!visible || isDisabled.current) { + return; + } + const json = JSON.parse(result); + const { gpu_usage } = json; + const formattedUsage = { usage: Math.round(gpu_usage[1] * 100) }; + setState(formattedUsage); + if (displayAsGraph) { + Utils.addToGraphHistory(formattedUsage, setGraph, GRAPH_LENGTH); + } + setLoading(false); + } catch { + setTimeout(getGpu, 1000); + } + }, [displayAsGraph, gpuMacmonBinaryPath, visible, refresh]); + + // Update the disabled state based on visibility + React.useEffect(() => { + isDisabled.current = !visible; + }, [visible]); + + // Use server socket to fetch GPU data + useServerSocket("gpu", visible, getGpu, resetWidget, setLoading); + // Use widget refresh hook to periodically refresh the widget + useWidgetRefresh(visible, getGpu, refresh); + + if (loading) return ; + if (!state) return null; + + const { usage } = state; + + if (displayAsGraph) { + return ( + + + + ); + } + + return ( + + {usage}% + + ); +}); + +Widget.displayName = "Gpu"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/graph.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/graph.jsx new file mode 100755 index 0000000..008e68e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/graph.jsx @@ -0,0 +1,87 @@ +import * as Uebersicht from "uebersicht"; +import * as Utils from "../../utils.js"; +import { SuspenseIcon } from "../icons/icon.jsx"; + +const { React } = Uebersicht; + +export { graphStyles as styles } from "../../styles/components/data/graph"; + +/** + * Graph component to display a bar graph with captions and values. + * + * @param {Object} props - The properties object. + * @param {string} props.className - Additional class names for the graph container. + * @param {Object} props.caption - Caption data containing value, icon, and color for each key. + * @param {Array} props.values - Array of value objects to be displayed as bars. + * @param {number} props.maxLength - Maximum length of the graph. + * @param {number} [props.maxValue] - Maximum value for scaling the bars. + * @returns {JSX.Element|null} The rendered graph component or null if no caption is provided. + */ +export default function Graph({ + className, + caption, + values = [], + maxLength, + maxValue, +}) { + // Return null if no caption is provided + if (!caption) { + return null; + } + + const captionKeys = Object.keys(caption); + + // Calculate maxValue if not provided + if (maxValue === undefined) { + const allValues = values.map((value) => Object.values(value)).flat(); + maxValue = Math.max(...allValues); + } + + const classes = Utils.classNames("graph", className); + + return ( +
+
+ {values.map((value) => { + const keys = Object.keys(value); + return keys.map((key) => { + const height = (value[key] / maxValue) * 100; + const { color: backgroundColor } = caption[key]; + return ( +
+ ); + }); + })} +
+
+ {captionKeys.map((key) => { + const { value, icon: Icon, color } = caption[key]; + return ( +
+ {Icon && ( + + + + )} + +
+ ); + })} +
+
+ ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/keyboard.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/keyboard.jsx new file mode 100755 index 0000000..d6e04f2 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/keyboard.jsx @@ -0,0 +1,108 @@ +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 { keyboardStyles as styles } from "../../styles/components/data/keyboard"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 20000; + +/** + * Keyboard widget component. + * @returns {JSX.Element|null} The rendered widget or null if not visible. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, keyboardWidgetOptions } = settings; + const { keyboardWidget } = widgets; + const { refreshFrequency, showOnDisplay, showIcon, keyboardMaxLength } = + keyboardWidgetOptions; + + // 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 based on display settings + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && keyboardWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + /** + * Resets the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetches the current keyboard layout or input mode. + */ + const getKeyboard = React.useCallback(async () => { + if (!visible) return; + const keyboard = await Utils.cachedRun( + `defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources | awk '/KeyboardLayout Name/ {$1=$2=$3=""; print $0}'`, + refresh, + ); + const layout = Utils.cleanupOutput(keyboard) + .replace(";", "") + .replaceAll('"', ""); + if (layout.length) { + setState({ keyboard: layout }); + setLoading(false); + return; + } + + const inputMode = await Utils.cachedRun( + `defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources | awk '/"Input Mode" =/ {$1=$2=$3=""; print $0}'`, + refresh, + ); + const cleanedInputMode = Utils.cleanupOutput(inputMode) + .replace(/"com.apple.inputmethod.(.*)"/, "$1") + .replace(";", ""); + + if (!cleanedInputMode.length) return setLoading(false); + + const splitedInputMode = cleanedInputMode.split("."); + const inputModeName = splitedInputMode[splitedInputMode.length - 1]; + setState({ keyboard: inputModeName }); + setLoading(false); + }, [visible, refresh]); + + // Use server socket to listen for keyboard events + useServerSocket("keyboard", visible, getKeyboard, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getKeyboard, refresh); + + if (loading) return ; + if (!state) return null; + const { keyboard } = state; + + const maxLength = Number(keyboardMaxLength) || 0; + const displayKeyboard = + maxLength > 0 ? keyboard.slice(0, maxLength) : keyboard; + + if (!displayKeyboard?.length) return null; + + return ( + + {displayKeyboard} + + ); +}); + +Widget.displayName = "Keyboard"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx new file mode 100755 index 0000000..e4361db --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/memory.jsx @@ -0,0 +1,134 @@ +import * as Uebersicht from "uebersicht"; +import * as DataWidget from "./data-widget.jsx"; +import * as DataWidgetLoader from "./data-widget-loader.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 { memoryStyles as styles } from "../../styles/components/data/memory"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 4000; + +/** + * Memory Widget component + * @returns {JSX.Element|null} The memory widget component + */ +export const Widget = () => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, memoryWidgetOptions } = settings; + const { memoryWidget } = widgets; + const { + refreshFrequency, + showOnDisplay, + memoryMonitorApp, + showIcon, + memoryUsageThreshold, + } = memoryWidgetOptions; + + // 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) && memoryWidget; + + const [state, setState] = Uebersicht.React.useState(); + const [loading, setLoading] = Uebersicht.React.useState(visible); + + /** + * Reset the widget state + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetch memory usage data + */ + const getMemory = React.useCallback(async () => { + const output = await Utils.cachedRun( + 'vm_stat | awk \'BEGIN {page_size=4096} /page size of/ {page_size=$8} /Pages free/ {free=$3} /Pages inactive/ {inactive=$3} /Pages speculative/ {spec=$4} /Pages active/ {active=$3} /Pages wired/ {wired=$4} END {gsub(/\\./, "", free); gsub(/\\./, "", inactive); gsub(/\\./, "", spec); gsub(/\\./, "", active); gsub(/\\./, "", wired); available=free+inactive+spec; total=available+active+wired; printf "%.0f", (available/total)*100}\'', + refresh, + ); + const free = parseInt(Utils.cleanupOutput(output), 10); + setState({ free }); + setLoading(false); + }, [setLoading, setState, refresh]); + + // Use server socket to get memory data + useServerSocket("memory", visible, getMemory, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getMemory, refresh); + + if (loading) return ; + if (!state) return null; + + const { free } = state; + const used = 100 - free; + const threshold = Number(memoryUsageThreshold) || 0; + + if (threshold > 0 && used < threshold) return null; + + // Handle click event to open memory usage app + const onClick = + memoryMonitorApp === "None" + ? undefined + : (e) => { + Utils.clickEffect(e); + openMemoryUsageApp(memoryMonitorApp); + }; + + /** + * Pie chart component for memory usage + * @returns {JSX.Element} The pie chart component + */ + const Pie = () => { + return ( +
+ ); + }; + + const classes = Utils.classNames("memory", { + "memory--low": used <= 30, + "memory--medium": used > 30 && used <= 70, + "memory--high": used > 70, + }); + + return ( + +
{used}%
+
+ ); +}; + +/** + * Open the specified memory usage application + * @param {string} app - The name of the application to open + */ +function openMemoryUsageApp(app) { + switch (app) { + case "Activity Monitor": + Uebersicht.run(`open -a "Activity Monitor"`); + break; + case "Top": + Utils.runInUserTerminal("top"); + break; + } +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/mic.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/mic.jsx new file mode 100755 index 0000000..5c071a8 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/mic.jsx @@ -0,0 +1,152 @@ +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 { SuspenseIcon } from "../icons/icon.jsx"; +import useWidgetRefresh from "../../hooks/use-widget-refresh"; +import useServerSocket from "../../hooks/use-server-socket"; +import * as Utils from "../../utils"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; + +const { React } = Uebersicht; + +export { micStyles as styles } from "../../styles/components/data/mic"; + +const DEFAULT_REFRESH_FREQUENCY = 20000; + +/** + * Mic widget component. + * @returns {JSX.Element} The rendered mic widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, micWidgetOptions } = settings; + const { micWidget } = widgets; + const { refreshFrequency, showOnDisplay, showIcon } = micWidgetOptions; + + // 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) && micWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + const { volume: _volume } = state || {}; + const [volume, setVolume] = React.useState(_volume && parseInt(_volume, 10)); + const [dragging, setDragging] = React.useState(false); + + /** + * Reset the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetch the current microphone volume. + */ + const getMic = React.useCallback(async () => { + if (!visible) return; + const volume = await Utils.cachedRun( + `osascript -e 'input volume of (get volume settings)'`, + refresh, + ); + setState({ volume: Utils.cleanupOutput(volume) }); + setLoading(false); + }, [visible, refresh]); + + // Use server socket to get mic data. + useServerSocket("mic", visible, getMic, resetWidget, setLoading); + // Refresh the widget periodically. + useWidgetRefresh(visible, getMic, refresh); + + // Update the mic volume when dragging state changes. + React.useEffect(() => { + if (!dragging) setMic(volume); + }, [dragging, volume]); + + // Update the volume state when the fetched volume changes. + React.useEffect(() => { + setVolume((currentVolume) => { + if (_volume && currentVolume !== parseInt(_volume, 10)) { + return parseInt(_volume, 10); + } + return currentVolume; + }); + }, [_volume]); + + if (loading) return ; + if (!state || volume === undefined || _volume === "missing value") + return null; + + const Icon = !volume ? Icons.MicOff : Icons.MicOn; + + /** + * Handle volume change event. + * @param {React.ChangeEvent} e - The change event. + */ + const onChange = (e) => { + const value = parseInt(e.target.value, 10); + setVolume(value); + }; + + /** + * Handle mouse down event on the slider. + */ + const onMouseDown = () => setDragging(true); + + /** + * Handle mouse up event on the slider. + */ + const onMouseUp = () => setDragging(false); + + const formattedVolume = `${volume.toString().padStart(2, "0")}%`; + + const classes = Utils.classNames("mic", { + "mic--dragging": dragging, + }); + + return ( + +
+ {showIcon && ( + + + + )} + {formattedVolume} +
+
+ +
+
+ ); +}); + +Widget.displayName = "Mic"; + +/** + * Set the microphone volume. + * @param {number} volume - The volume level to set. + */ +function setMic(volume) { + if (volume === undefined) return; + Uebersicht.run(`osascript -e 'set volume input volume ${volume}'`); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/mpd.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/mpd.jsx new file mode 100755 index 0000000..53449b1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/mpd.jsx @@ -0,0 +1,228 @@ +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 { mpdStyles as styles } from "../../styles/components/data/mpd"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 10000; + +/** + * MPD Widget component + * @returns {JSX.Element|null} The MPD widget + */ +export const Widget = React.memo(() => { + const ref = React.useRef(); + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, mpdWidgetOptions } = settings; + const { mpdWidget } = widgets; + const { + refreshFrequency, + showSpecter, + mpdBinaryPath, + mpdHost, + mpdPort, + mpdFormatString, + showOnDisplay, + showIcon, + } = mpdWidgetOptions; + + // 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 on the current display + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && mpdWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + const [isMpdActive, setIsMpdActive] = React.useState(false); + const { volume: _volume } = state || {}; + const defaultVolume = _volume && parseInt(_volume); + const [volume, setVolume] = React.useState(defaultVolume); + const [dragging, setDragging] = React.useState(false); + + /** + * Reset the widget state + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + setIsMpdActive(false); + }; + + /** + * Fetch MPD data + */ + const getMpd = React.useCallback(async () => { + if (!visible) return; + + try { + const mpdProcess = await Utils.cachedRun( + `pgrep -x mpd > /dev/null && echo "true" || echo "false"`, + refresh, + ); + + if (Utils.cleanupOutput(mpdProcess) === "false") { + setLoading(false); + setIsMpdActive(false); + return; + } + + const [playerState, trackInfo, volumeState] = await Promise.all([ + Utils.cachedRun( + `${mpdBinaryPath} --host ${mpdHost} --port ${mpdPort} | head -n 2 | tail -n 1 | awk '{print substr($1,2,length($1)-2)}' 2>/dev/null || echo "stopped"`, + refresh, + ), + Utils.cachedRun( + `${mpdBinaryPath} --host ${mpdHost} --port ${mpdPort} --format "${mpdFormatString}" | head -n 1`, + refresh, + ), + Utils.cachedRun( + `${mpdBinaryPath} --host ${mpdHost} --port ${mpdPort} volume | sed -e 's/volume:[ ]*//g' -e 's/%//g'`, + refresh, + ), + ]); + if (Utils.cleanupOutput(trackInfo) === "") { + setLoading(false); + setIsMpdActive(false); + return; + } + setState({ + playerState: Utils.cleanupOutput(playerState), + trackInfo: Utils.cleanupOutput(trackInfo), + volume: Utils.cleanupOutput(volumeState), + }); + setIsMpdActive(true); + setLoading(false); + } catch { + setLoading(false); + setIsMpdActive(false); + } + }, [visible, mpdBinaryPath, mpdHost, mpdPort, mpdFormatString, refresh]); + + // Update the volume when dragging ends + React.useEffect(() => { + if (!dragging) setSound(mpdBinaryPath, mpdHost, mpdPort, volume); + }, [dragging, mpdBinaryPath, mpdHost, mpdPort, volume]); + + // Set the volume state when dragging ends + React.useEffect(() => { + if (!dragging) setVolume(volume); + }, [dragging, volume]); + + useServerSocket("mpd", visible, getMpd, resetWidget, setLoading); + useWidgetRefresh(visible, getMpd, refresh); + + if (loading) return ; + if (!state || !isMpdActive) return null; + const { playerState, trackInfo } = state; + + if (!trackInfo.length) return null; + + const isPlaying = playerState === "playing"; + const Icon = isPlaying ? Icons.Playing : Icons.Paused; + + /** + * Handle click event to toggle play/pause + * @param {React.MouseEvent} e - The click event + */ + const onClick = async (e) => { + Utils.clickEffect(e); + await togglePlay(mpdBinaryPath, mpdHost, mpdPort); + await getMpd(); + }; + + /** + * Handle volume change event + * @param {React.ChangeEvent} e - The change event + */ + const onChange = (e) => { + const value = parseInt(e.target.value); + setVolume(value); + }; + + const onMouseDown = () => setDragging(true); + + const onMouseUp = () => setDragging(false); + + const stopPropagation = (e) => e.stopPropagation(); + + const onMouseEnter = () => + Utils.startSliding(ref.current, ".mpd__inner", ".mpd__info"); + const onMouseLeave = () => Utils.stopSliding(ref.current, ".mpd__slider"); + + const classes = Utils.classNames("sound", "mpd", { + "mpd--playing": isPlaying, + "mpd--dragging": dragging, + }); + + return ( + +
+
+
{trackInfo}
+
+
+ +
+
+
+ ); +}); + +Widget.displayName = "Mpd"; + +/** + * Toggle play/pause state of MPD + * @param {string} path - The path to the MPD binary + * @param {string} host - The MPD host + * @param {string} port - The MPD port + * @returns {Promise} + */ +async function togglePlay(path, host, port) { + return Uebersicht.run(`${path} --host ${host} --port ${port} toggle`); +} + +/** + * Set the volume of MPD + * @param {string} path - The path to the MPD binary + * @param {string} host - The MPD host + * @param {string} port - The MPD port + * @param {number} volume - The volume level to set + */ +function setSound(path, host, port, volume) { + if (!volume) return; + Uebersicht.run(`${path} --host ${host} --port ${port} volume ${volume}`); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/music.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/music.jsx new file mode 100755 index 0000000..f0fabd6 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/music.jsx @@ -0,0 +1,161 @@ +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 { musicStyles as styles } from "../../styles/components/data/music"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 10000; + +/** + * Music widget component. + * @returns {JSX.Element|null} The music widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, musicWidgetOptions } = settings; + const { musicWidget } = widgets; + const { refreshFrequency, showSpecter, showOnDisplay, showIcon } = + musicWidgetOptions; + + // 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 on the current display + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && musicWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + const [isMusicActive, setIsMusicActive] = React.useState(false); + + /** + * Resets the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + setIsMusicActive(false); + }; + + /** + * Fetches the current music information. + */ + const getMusic = React.useCallback(async () => { + if (!visible) return; + const osVersion = await Utils.cachedRun(`sw_vers -productVersion`, refresh); + const processName = + Utils.cleanupOutput(osVersion) === "10.15" ? "iTunes" : "Music"; + const isRunning = await Utils.cachedRun( + `pgrep -xq "${processName}" && echo "true" || echo "false"`, + refresh, + ); + if (Utils.cleanupOutput(isRunning) === "false") { + setLoading(false); + setIsMusicActive(false); + return; + } + const output = await Utils.cachedRun( + `osascript -e 'tell application "${processName}"' -e 'set output to (player state as string) & "|" & (name of current track as string) & "|" & (artist of current track as string)' -e 'end tell' 2>/dev/null || echo "stopped|unknown track|unknown artist"`, + refresh, + ); + const [playerState, trackName, artistName] = + Utils.cleanupOutput(output).split("|"); + setState({ + playerState, + trackName, + artistName, + processName: Utils.cleanupOutput(processName), + }); + setIsMusicActive(true); + setLoading(false); + }, [visible, refresh]); + + // Use server socket to listen for music events + useServerSocket("music", visible, getMusic, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getMusic, refresh); + + if (loading) return ; + if (!state || !isMusicActive) return null; + const { processName, playerState, trackName, artistName } = state; + + if (!trackName.length) return null; + + const isPlaying = playerState === "playing"; + const Icon = isPlaying ? Icons.Playing : Icons.Paused; + + /** + * Handles click event to toggle play/pause. + * @param {React.MouseEvent} e - The click event. + */ + const onClick = (e) => { + Utils.clickEffect(e); + togglePlay(!isPlaying, processName); + getMusic(); + }; + + /** + * Handles right-click event to skip to the next track. + * @param {React.MouseEvent} e - The right-click event. + */ + const onRightClick = (e) => { + Utils.clickEffect(e); + Uebersicht.run( + `osascript -e 'tell application "${processName}" to Next Track'`, + ); + getMusic(); + }; + + /** + * Handles middle-click event to open the music application. + * @param {React.MouseEvent} e - The middle-click event. + */ + const onMiddleClick = (e) => { + Utils.clickEffect(e); + Uebersicht.run(`open -a '${processName}'`); + getMusic(); + }; + + const classes = Utils.classNames("music", { + "music--playing": isPlaying, + }); + + return ( + + {trackName} - {artistName} + + ); +}); + +Widget.displayName = "Music"; + +/** + * Toggles play/pause state of the music application. + * @param {boolean} isPaused - Whether the music is paused. + * @param {string} processName - The name of the music application process. + */ +function togglePlay(isPaused, processName) { + if (isPaused) { + Uebersicht.run(`osascript -e 'tell application "${processName}" to play'`); + } else { + Uebersicht.run(`osascript -e 'tell application "${processName}" to pause'`); + } +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx new file mode 100755 index 0000000..ef3d7be --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/netstats.jsx @@ -0,0 +1,182 @@ +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 { SuspenseIcon } from "../icons/icon.jsx"; +import Graph from "./graph.jsx"; +import useWidgetRefresh from "../../hooks/use-widget-refresh.js"; +import useServerSocket from "../../hooks/use-server-socket"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Utils from "../../utils.js"; + +export { netstatsStyles as styles } from "../../styles/components/data/netstats"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 2000; +const GRAPH_LENGTH = 30; + +/** + * Netstats widget component. + * @returns {JSX.Element|null} The rendered component. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, netstatsWidgetOptions } = settings; + const { netstatsWidget } = widgets; + const { + refreshFrequency, + showOnDisplay, + displayAsGraph, + showIcon, + netstatsThreshold, + } = netstatsWidgetOptions; + + const isDisabled = React.useRef(false); + + // 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) && netstatsWidget; + + const [graph, setGraph] = React.useState([]); + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + /** + * Resets the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + setGraph([]); + }; + + /** + * Fetches network statistics. + */ + const getNetstats = React.useCallback(async () => { + if (!visible) return; + try { + const output = await Utils.cachedRun( + `bash ./simple-bar/lib/scripts/netstats.sh 2>&1`, + refresh, + ); + if (!visible || isDisabled.current) { + return; + } + const data = Utils.cleanupOutput(output); + const json = JSON.parse(data); + setState(json); + if (displayAsGraph) { + Utils.addToGraphHistory(json, setGraph, GRAPH_LENGTH); + } + setLoading(false); + } catch { + setTimeout(getNetstats, 1000); + } + }, [displayAsGraph, setGraph, visible, refresh]); + + // Update the disabled state based on visibility + React.useEffect(() => { + isDisabled.current = !visible; + }, [visible]); + + // Set up server socket and widget refresh hooks + useServerSocket("netstats", visible, getNetstats, resetWidget, setLoading); + useWidgetRefresh(visible, getNetstats, refresh); + + if (loading) + return ( + + + {!displayAsGraph && } + + ); + + if (!state) { + return null; + } + + const { download, upload } = state; + + if (download === undefined || upload === undefined) { + return null; + } + + const threshold = (Number(netstatsThreshold) || 0) * 1024; + const isBelowThreshold = + threshold > 0 && + Math.abs(download) < threshold && + Math.abs(upload) < threshold; + + if (isBelowThreshold) { + return null; + } + + const formattedDownload = Utils.formatBytes(download); + const formattedUpload = Utils.formatBytes(upload); + + if (displayAsGraph) { + return ( + + + + ); + } + + return ( + + +
+ {showIcon && ( + + + + )} + +
+
+ +
+ {showIcon && ( + + + + )} + +
+
+
+ ); +}); + +Widget.displayName = "Netstats"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/next-meeting.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/next-meeting.jsx new file mode 100755 index 0000000..74f6bf8 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/next-meeting.jsx @@ -0,0 +1,310 @@ +/** + * Next Meeting Widget + * + * Displays the next upcoming calendar event with time until start and optional join button. + * Uses icalBuddy for fast calendar access with proper recurring event support. + * + * Requirements: + * - macOS with Calendar.app or compatible calendar + * - icalBuddy installed (brew install ical-buddy) + * - Calendar access permissions granted + * + * @module next-meeting + */ +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 { nextMeetingStyles as styles } from "../../styles/components/data/next-meeting"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 60000; // 1 minute + +// Timing thresholds (in minutes) +const URGENT_THRESHOLD = 5; // Red pulsing when ≤5 min until meeting +const UPCOMING_THRESHOLD = 15; // Yellow when ≤15 min until meeting + +// Uses icalBuddy for fast calendar access (handles recurring events properly) +// Note: Shell script automatically skips meetings that started more than 15 minutes ago +const BASE_COMMAND = `./simple-bar/lib/scripts/next-meeting.sh`; + +/** + * Builds the shell command with optional custom icalBuddy path and look-ahead hours. + * @param {string} icalBuddyPath - Optional custom path to icalBuddy binary + * @param {number} lookAheadHours - Hours to look ahead for meetings (default: 12) + * @returns {string} Complete shell command + */ +function buildCommand(icalBuddyPath, lookAheadHours) { + const hours = lookAheadHours || 12; + if (icalBuddyPath && icalBuddyPath.trim()) { + // Escape special shell characters to prevent injection + const safePath = icalBuddyPath.replace(/["$`\\]/g, "\\$&"); + return `${BASE_COMMAND} "${safePath}" ${hours}`; + } + return `${BASE_COMMAND} "" ${hours}`; +} + +// Patterns to extract meeting URLs from notes +const MEETING_URL_PATTERNS = [ + /https?:\/\/[\w-]*\.?zoom\.us\/[^\s<>"]+/gi, + /https?:\/\/teams\.microsoft\.com\/l\/meetup-join\/[^\s<>"]+/gi, + /https?:\/\/meet\.google\.com\/[^\s<>"]+/gi, + /https?:\/\/[\w-]*\.?webex\.com\/[^\s<>"]+/gi, +]; + +// SafeLinks pattern (Microsoft Outlook protection wrapper) +const SAFELINKS_PATTERN = + /https?:\/\/[\w.-]*safelinks\.protection\.outlook\.com\/[^\s<>">\]]+/gi; + +/** + * Decode a URL that may be URL-encoded + * @param {string} url - Possibly encoded URL + * @returns {string} Decoded URL + */ +function decodeUrl(url) { + try { + return decodeURIComponent(url); + } catch { + return url; + } +} + +/** + * Extract the real URL from a SafeLink wrapper + * @param {string} safeLink - SafeLink URL + * @returns {string} Extracted real URL or original + */ +function extractFromSafeLink(safeLink) { + const urlParam = safeLink.match(/[?&]url=([^&]+)/i); + if (urlParam && urlParam[1]) { + return decodeUrl(urlParam[1]); + } + return safeLink; +} + +/** + * Extract meeting URL from event URL or notes + * @param {string} url - Event URL + * @param {string} notes - Event notes/description + * @returns {string|null} Meeting URL or null + */ +function extractMeetingUrl(url, notes) { + // First check direct URL + if (url && url.trim() && url !== "missing value") { + for (const pattern of MEETING_URL_PATTERNS) { + pattern.lastIndex = 0; + const match = url.match(pattern); + if (match) return match[0]; + } + if (url.startsWith("http")) return url; + } + + // Check notes for meeting links + if (notes && notes.trim()) { + // First try direct meeting URLs + for (const pattern of MEETING_URL_PATTERNS) { + pattern.lastIndex = 0; + const match = notes.match(pattern); + if (match) return match[0]; + } + + // Check for SafeLinks that contain meeting URLs + SAFELINKS_PATTERN.lastIndex = 0; + const safeLinks = notes.match(SAFELINKS_PATTERN); + if (safeLinks) { + for (const safeLink of safeLinks) { + const realUrl = extractFromSafeLink(safeLink); + for (const pattern of MEETING_URL_PATTERNS) { + pattern.lastIndex = 0; + if (pattern.test(realUrl)) { + return realUrl; + } + } + } + } + } + + return null; +} + +/** + * Format time until meeting + * @param {number} minutes - Minutes until meeting + * @returns {string} Formatted time string + */ +function formatTimeUntil(minutes) { + if (minutes < 0) return "now"; + if (minutes < 1) return "<1m"; + if (minutes < 60) return `${minutes}m`; + const hours = Math.floor(minutes / 60); + const mins = minutes % 60; + if (mins === 0) return `${hours}h`; + return `${hours}h ${mins}m`; +} + +/** + * Parse meeting data from shell script output + * @param {string} output - Raw command output + * @returns {Object|null} Meeting object or null + */ +function parseMeetingData(output) { + if (!output || !output.trim()) return null; + + const parts = output.trim().split("|"); + if (parts.length < 5) return null; + + const [title, startTime, url, notes, minutesUntil] = parts; + if (!title) return null; + + const meetingUrl = extractMeetingUrl(url, notes); + + return { + title: title.trim(), + startTime: startTime, + url: meetingUrl, + minutesUntil: parseInt(minutesUntil, 10) || 0, + }; +} + +/** + * Join button sub-component for meeting URLs. + * @component + * @param {Object} props - Component props + * @param {string} props.url - Meeting URL to open + * @returns {JSX.Element} Join button element + */ +const JoinButton = React.memo(({ url }) => { + /** + * Opens the meeting URL when clicked. + * @param {React.MouseEvent} e - Click event + */ + const handleJoin = async (e) => { + e.stopPropagation(); + Utils.clickEffect(e); + // Escape special shell characters to prevent injection + const safeUrl = url.replace(/["$`\\]/g, "\\$&"); + await Uebersicht.run(`open "${safeUrl}"`); + }; + + return ( + + ); +}); + +JoinButton.displayName = "JoinButton"; + +/** + * Next Meeting widget component + * Shows the next upcoming meeting with optional join button + * @returns {JSX.Element|null} The next meeting widget + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, nextMeetingWidgetOptions, dateWidgetOptions } = settings; + const { nextMeetingWidget } = widgets; + const { + refreshFrequency, + showOnDisplay, + showJoinButton, + showTimeOnly, + icalBuddyPath, + lookAheadHours, + } = nextMeetingWidgetOptions; + + // Calculate the refresh frequency for the widget + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + // Determine if the widget should be visible based on display settings + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && nextMeetingWidget; + + const [state, setState] = React.useState(null); + const [loading, setLoading] = React.useState(visible); + + /** + * Resets the widget state. + */ + const resetWidget = React.useCallback(() => { + setState(null); + setLoading(false); + }, []); + + /** + * Fetches next meeting and updates the state. + */ + const getMeeting = React.useCallback(async () => { + if (!visible) return; + try { + const command = buildCommand(icalBuddyPath, lookAheadHours); + const output = await Uebersicht.run(command); + const meeting = parseMeetingData(output); + setState(meeting); + } catch (error) { + // eslint-disable-next-line no-console + console.error("Error fetching next meeting:", error); + setState(null); + } + setLoading(false); + }, [visible, icalBuddyPath, lookAheadHours]); + + // Server socket for real-time updates + useServerSocket("next-meeting", visible, getMeeting, resetWidget, setLoading); + + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getMeeting, refresh); + + if (loading) return ; + if (!state) return null; + + const { title, minutesUntil, url } = state; + const timeDisplay = formatTimeUntil(minutesUntil); + const isUrgent = minutesUntil <= URGENT_THRESHOLD; // Red pulsing: ≤5 min or in progress (up to 15 min) + const isUpcoming = minutesUntil <= UPCOMING_THRESHOLD; // Yellow: ≤15 min (but not urgent/in-progress) + + const widgetClasses = Utils.classNames("next-meeting", { + "next-meeting--urgent": isUrgent, + "next-meeting--upcoming": isUpcoming && !isUrgent, + }); + + /** + * Handle click event to open the calendar application + * @param {Event} e - The click event + */ + const openCalendar = async (e) => { + Utils.clickEffect(e); + const calendarApp = dateWidgetOptions?.calendarApp || "Calendar"; + await Uebersicht.run(`open -a "${calendarApp}"`); + }; + + return ( + + {!showTimeOnly && {title}} + {timeDisplay} + {showJoinButton && url && } + + ); +}); + +Widget.displayName = "NextMeeting"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/notifications.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/notifications.jsx new file mode 100755 index 0000000..b55e487 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/notifications.jsx @@ -0,0 +1,189 @@ +/** + * Notifications Widget + * + * Displays badge counts from running applications with active notifications. + * Uses macOS lsappinfo to query app status labels (dock badges). + * + * Requirements: + * - macOS (lsappinfo is macOS-specific) + * - No special permissions required + * + * @module notifications + */ +import * as Uebersicht from "uebersicht"; +import * as AppIcons from "../../app-icons.js"; +import { SuspenseIcon } from "../icons/icon.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 { notificationsStyles as styles } from "../../styles/components/data/notifications"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 10000; + +// Shell command to get notification badges from running apps +const COMMAND = `lsappinfo -all list 2>/dev/null | perl -0777 -pe 's/---/\\n---\\n/g' | perl -ne ' + if (/"CFBundleName"="([^"]+)"/) { $app = $1; } + if (/"StatusLabel"=\\{ "label"="([^"]*)"/) { $badge = $1; } + if (/"LSBundlePath"="([^"]+)"/) { $path = $1; } + if (/^---$/ || eof) { + print "$app|$badge|$path\\n" if ($app && $badge); + ($app, $badge, $path) = ("", "", ""); + } +'`; + +/** + * Parses shell command output into notification objects. + * @param {string} output - Raw command output from lsappinfo + * @returns {Array<{name: string, badge: string, bundlePath: string}>} Array of notification objects + */ +function parseNotifications(output) { + if (!output || !output.trim()) return []; + + return output + .trim() + .split("\n") + .filter((line) => line.includes("|")) + .map((line) => { + const [name, badge, bundlePath] = line.split("|"); + return { name, badge, bundlePath }; + }) + .filter((item) => item.name && item.badge); +} + +/** + * Single app notification pill component. + * @component + * @param {Object} props - Component props + * @param {Object} props.app - Application notification data + * @param {string} props.app.name - Application name + * @param {string} props.app.badge - Badge count + * @param {string} props.app.bundlePath - Path to application bundle + * @returns {JSX.Element} Notification pill button + */ +const NotificationPill = React.memo(({ app }) => { + /** + * Opens the application when pill is clicked. + * @param {React.MouseEvent} e - Click event + */ + const openApp = async (e) => { + Utils.clickEffect(e); + // Escape special shell characters to prevent injection + const safePath = app.bundlePath.replace(/["$`\\]/g, "\\$&"); + await Uebersicht.run(`open "${safePath}"`); + }; + + // Get the SVG icon for this app, or use Default + const Icon = AppIcons.apps[app.name] || AppIcons.apps.Default; + + return ( + + ); +}); + +NotificationPill.displayName = "NotificationPill"; + +/** + * Notification Badges widget component. + * Shows each app with notifications as an inline pill. + * @component + * @returns {JSX.Element|null} The notifications widget component or null if no notifications + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, notificationsWidgetOptions } = settings; + const { notificationsWidget } = widgets; + const { refreshFrequency, showOnDisplay, excludedApps } = notificationsWidgetOptions; + + // Determine if the widget should be visible based on display settings + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && + notificationsWidget; + + // Calculate the refresh frequency for the widget + 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 = React.useCallback(() => { + setState([]); + setLoading(false); + }, []); + + // Build the exclusion list from the comma-separated setting + const exclusionList = React.useMemo( + () => + excludedApps + ? excludedApps + .split(",") + .map((s) => s.trim().toLowerCase()) + .filter(Boolean) + : [], + [excludedApps], + ); + + /** + * Fetches notification badges and updates the state. + */ + const getNotifications = React.useCallback(async () => { + if (!visible) return; + try { + const output = await Utils.cachedRun(COMMAND, refresh); + const notifications = parseNotifications(output).filter( + (item) => !exclusionList.includes(item.name.toLowerCase()), + ); + setState(notifications); + } catch (error) { + // eslint-disable-next-line no-console + console.error("Error fetching notifications:", error); + setState([]); + } + setLoading(false); + }, [visible, refresh, exclusionList]); + + // Server socket for real-time updates + useServerSocket( + "notifications", + visible, + getNotifications, + resetWidget, + setLoading, + ); + + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getNotifications, refresh); + + // Don't render anything if loading or no notifications + if (loading || !state.length) return null; + + return ( +
+ {state.map((app) => ( + + ))} +
+ ); +}); + +Widget.displayName = "Notifications"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx new file mode 100755 index 0000000..7301426 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx @@ -0,0 +1,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 { SuspenseIcon } from "../icons/icon.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 { soundStyles as styles } from "../../styles/components/data/sound"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 20000; + +/** + * Sound widget component. + * @returns {JSX.Element|null} The sound widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, soundWidgetOptions } = settings; + const { soundWidget } = widgets; + const { refreshFrequency, showOnDisplay, showIcon } = soundWidgetOptions; + + // 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 on the current display. + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && soundWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + const { volume: _volume } = state || {}; + const [volume, setVolume] = React.useState(_volume && parseInt(_volume, 10)); + const [dragging, setDragging] = React.useState(false); + + /** + * Reset the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetch the current sound settings. + */ + const getSound = React.useCallback(async () => { + if (!visible) return; + const output = await Utils.cachedRun( + `osascript -e 'set v to get volume settings' -e 'output volume of v & output muted of v'`, + refresh, + ); + const parts = Utils.cleanupOutput(output).split(","); + setState({ + volume: parts[0], + muted: parts[1], + }); + setLoading(false); + }, [visible, refresh]); + + // Use server socket to listen for sound updates. + useServerSocket("sound", visible, getSound, resetWidget, setLoading); + // Refresh the widget at the specified interval. + useWidgetRefresh(visible, getSound, refresh); + + // Update the sound settings when dragging ends. + React.useEffect(() => { + if (!dragging) setSound(volume); + }, [dragging, volume]); + + // Update the volume state when the fetched volume changes. + React.useEffect(() => { + setVolume((currentVolume) => { + if (_volume && currentVolume !== parseInt(_volume, 10)) { + return parseInt(_volume, 10); + } + return currentVolume; + }); + }, [_volume]); + + if (loading) return ; + if (!state || volume === undefined) return null; + + const { muted } = state; + if (_volume === "missing value" || muted === "missing value") return null; + + let Icon = Icons.VolumeHigh; + if (volume < 50) Icon = Icons.VolumeLow; + if (volume < 20) Icon = Icons.NoVolume; + if (muted === "true" || !volume) Icon = Icons.VolumeMuted; + + /** + * Handle volume change event. + * @param {React.ChangeEvent} e - The change event. + */ + const onChange = (e) => { + const value = parseInt(e.target.value, 10); + setVolume(value); + }; + + const onMouseDown = () => setDragging(true); + const onMouseUp = () => setDragging(false); + + const formattedVolume = `${volume.toString().padStart(2, "0")}%`; + + const classes = Utils.classNames("sound", { + "sound--dragging": dragging, + }); + + return ( + +
+ {showIcon && ( + + + + )} + {formattedVolume} +
+
+ +
+
+ ); +}); + +Widget.displayName = "Sound"; + +/** + * Set the system volume. + * @param {number} volume - The volume to set. + */ +function setSound(volume) { + if (volume === undefined) return; + Uebersicht.run(`osascript -e 'set volume output volume ${volume}'`); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/specter.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/specter.jsx new file mode 100755 index 0000000..66b0850 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/specter.jsx @@ -0,0 +1,24 @@ +import * as Uebersicht from "uebersicht"; + +export { specterStyles as styles } from "../../styles/components/data/specter"; + +const { React } = Uebersicht; + +/** + * Specter widget component + * + * This component renders a div with six span elements inside it. These are animated in CSS. + * + * @returns {JSX.Element} The rendered widget component + */ +export const Widget = React.memo(() => { + return ( +
+ {[...new Array(6)].map((_, i) => ( + + ))} +
+ ); +}); + +Widget.displayName = "Specter"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/spotify.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/spotify.jsx new file mode 100755 index 0000000..bc9f6e6 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/spotify.jsx @@ -0,0 +1,189 @@ +import * as Uebersicht from "uebersicht"; +import * as DataWidget from "./data-widget.jsx"; +import * as DataWidgetLoader from "./data-widget-loader.jsx"; +import useWidgetRefresh from "../../hooks/use-widget-refresh"; +import useServerSocket from "../../hooks/use-server-socket"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Icons from "../icons/icons.jsx"; +import * as Utils from "../../utils"; + +export { spotifyStyles as styles } from "../../styles/components/data/spotify"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 10000; + +/** + * Spotify widget component. + * @returns {JSX.Element|null} The Spotify widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, spotifyWidgetOptions } = settings; + const { spotifyWidget } = widgets; + const { + refreshFrequency, + showSpecter, + showOnDisplay, + showIcon, + showSpotifyMetadata, + } = spotifyWidgetOptions; + + // 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) && spotifyWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + const [isSpotifyActive, setIsSpotifyActive] = React.useState(false); + + /** + * Resets the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + setIsSpotifyActive(false); + }; + + /** + * Fetches the current Spotify state. + */ + const getSpotify = React.useCallback(async () => { + if (!visible) return; + const isRunning = await Utils.cachedRun( + `pgrep -fq '[S]potify Helper' && echo "true" || echo "false"`, + refresh, + ); + if (Utils.cleanupOutput(isRunning) === "false") { + setLoading(false); + setIsSpotifyActive(false); + setState({ + playerState: "", + trackName: "", + artistName: "", + }); + return; + } + // if showSpotifyMetadata is enabled, retrieves all information + if (showSpotifyMetadata) { + const output = await Utils.cachedRun( + `osascript -e 'tell application "Spotify"' -e 'set output to (player state as string) & "|" & (name of current track as string) & "|" & (artist of current track as string)' -e 'end tell' 2>/dev/null || echo "stopped||"`, + refresh, + ); + const [playerState, trackName, artistName] = + Utils.cleanupOutput(output).split("|"); + setState({ + playerState, + trackName, + artistName, + }); + // else, only playerState + } else { + const playerState = await Utils.cachedRun( + `osascript -e 'tell application "Spotify" to player state as string' 2>/dev/null || echo "stopped"`, + refresh, + ); + setState({ + playerState: Utils.cleanupOutput(playerState), + trackName: "", + artistName: "", + }); + } + + setIsSpotifyActive(true); + setLoading(false); + }, [visible, showSpotifyMetadata, refresh]); + + // Set up server socket and widget refresh hooks + useServerSocket("spotify", visible, getSpotify, resetWidget, setLoading); + useWidgetRefresh(visible, getSpotify, refresh); + + if (loading) return ; + if (!state || !isSpotifyActive) return null; + const { playerState, trackName, artistName } = state; + + if (!trackName.length && showSpotifyMetadata) return null; + + const label = artistName.length ? `${trackName} - ${artistName}` : trackName; + const isPlaying = playerState === "playing"; + const Icon = getIcon(playerState); + + /** + * Handles click event to toggle play/pause. + * @param {React.MouseEvent} e - The click event. + */ + const onClick = (e) => { + Utils.clickEffect(e); + togglePlay(!isPlaying); + getSpotify(); + }; + + /** + * Handles right-click event to skip to the next track. + * @param {React.MouseEvent} e - The right-click event. + */ + const onRightClick = (e) => { + Utils.clickEffect(e); + Uebersicht.run(`osascript -e 'tell application "Spotify" to Next Track'`); + getSpotify(); + }; + + /** + * Handles middle-click event to open Spotify. + * @param {React.MouseEvent} e - The middle-click event. + */ + const onMiddleClick = (e) => { + Utils.clickEffect(e); + Uebersicht.run(`open -a 'Spotify'`); + getSpotify(); + }; + + const classes = Utils.classNames("spotify", { + "spotify--hidden-metadata": !showSpotifyMetadata, + "spotify--playing": isPlaying, + }); + + return ( + + {showSpotifyMetadata && label} + + ); +}); + +Widget.displayName = "Spotify"; + +/** + * Toggles play/pause state of Spotify. + * @param {boolean} isPaused - Whether the player is paused. + */ +function togglePlay(isPaused) { + const state = isPaused ? "play" : "pause"; + Uebersicht.run(`osascript -e 'tell application "Spotify" to ${state}'`); +} + +/** + * Gets the appropriate icon based on the player state. + * @param {string} playerState - The current state of the player. + * @returns {JSX.Element} The icon component. + */ +function getIcon(playerState) { + if (playerState === "stopped") return Icons.Stopped; + if (playerState === "playing") return Icons.Playing; + return Icons.Paused; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/stock.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/stock.jsx new file mode 100755 index 0000000..4327f1c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/stock.jsx @@ -0,0 +1,211 @@ +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 { stockStyles as styles } from "../../styles/components/data/stock"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 15 * 60 * 1000; // 15 min + +/** + * Stock widget component + * @returns {JSX.Element|null} The stock widget + */ +export const Widget = React.memo(() => { + const { displayIndex, settings, pushMissive } = useSimpleBarContext(); + const { widgets, stockWidgetOptions } = settings; + const { stockWidget } = widgets; + const { + refreshFrequency, + yahooFinanceApiKey, + symbols, + showSymbol, + showCurrency, + showMarketPrice, + showMarketChange, + showMarketPercent, + showColor, + showOnDisplay, + showIcon, + } = stockWidgetOptions; + + // Determine the refresh frequency for the widget + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + // Check if the widget should be visible on the current display + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && stockWidget; + + const ref = React.useRef(); + + // Memoize cleanedUpSymbols to prevent recreation on every render + const cleanedUpSymbols = React.useMemo( + () => symbols.replace(/ /g, ""), + [symbols], + ); + + // Memoize enumeratedSymbols to prevent recreation on every render + const enumeratedSymbols = React.useMemo( + () => cleanedUpSymbols.replace(/ /g, "").split(","), + [cleanedUpSymbols], + ); + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + /** + * Reset the widget state + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetch stock data from Yahoo Finance API + */ + const getStocks = React.useCallback(async () => { + if (!visible) return; + const response = await fetch( + `https://yfapi.net/v6/finance/quote?symbols=${cleanedUpSymbols}`, + { + headers: new Headers({ "x-api-key": yahooFinanceApiKey }), + }, + ); + if (response.status === 429) { + // Exceeded daily quota + } else if (response.status === 403) { + Utils.notification("Invalid Yahoo Finance API key", pushMissive); + } else if (response.status === 200) { + const result = await response.json(); + const symbolQuotes = result.quoteResponse.result; + + if (symbolQuotes.length !== enumeratedSymbols.length) { + // One or more symbols is invalid + const receivedSymbols = symbolQuotes.map((s) => s.symbol.toLowerCase()); + const invalidSymbols = enumeratedSymbols.filter( + (s) => !receivedSymbols.includes(s), + ); + Utils.notification("Invalid stock symbol(s): " + invalidSymbols); + } else { + setState({ symbolQuotes }); + } + } else { + // eslint-disable-next-line no-console + console.error("Unexpected response from Yahoo Finance API: ", response); + } + + setLoading(false); + }, [ + visible, + cleanedUpSymbols, + yahooFinanceApiKey, + pushMissive, + enumeratedSymbols, + ]); + + // Use server socket to fetch stock data + useServerSocket("stock", visible, getStocks, resetWidget, setLoading); + // Refresh widget data periodically + useWidgetRefresh(visible, getStocks, refresh); + + /** + * Refresh stock data on user interaction + * @param {Event} e - The event object + */ + const refreshStocks = (e) => { + Utils.clickEffect(e); + setLoading(true); + getStocks(); + }; + + if (loading) return ; + if (!state || !state.symbolQuotes) return null; + + return enumeratedSymbols.map((symbolName, i) => { + const symbolQuote = state.symbolQuotes[i]; + const symbol = symbolQuote.symbol; + const currencySymbol = getCurrencySymbol(symbolQuote.currency); + const marketPrice = Number(symbolQuote.regularMarketPrice).toFixed(2); + const marketChange = Number(symbolQuote.regularMarketChange).toFixed(2); + const marketPercentChange = Number( + symbolQuote.regularMarketChangePercent, + ).toFixed(2); + const stockUp = !marketChange.startsWith("-"); + + return ( + + + {showSymbol && symbol} + {(showCurrency || showMarketPrice) && showSymbol && ( +   + )} + {showCurrency && currencySymbol} + {showMarketPrice && marketPrice} + + + {(showMarketChange || showMarketPercent) &&  } + {showMarketChange && formatPriceChange(marketChange)} + {showMarketPercent && + showMarketChange && + ` (${formatPriceChange(marketPercentChange)}%)`} + {showMarketPercent && + !showMarketChange && + `${formatPriceChange(marketPercentChange)}%`} + + + ); + }); +}); + +Widget.displayName = "Stock"; + +/** + * Handle click event to open stock details + * @param {Event} e - The event object + */ +function openStock(e) { + Utils.clickEffect(e); +} + +/** + * Get the currency symbol for a given currency code + * @param {string} currency - The currency code + * @returns {string} The currency symbol + */ +function getCurrencySymbol(currency) { + if (currency === "EUR") return "€"; + if (currency === "USD") return "$"; + if (currency === "GBP") return "£"; + if (currency === "CNY") return "¥"; + if (currency === "JPY") return "¥"; + return `${currency} `; +} + +/** + * Format the price change with a '+' for positive changes + * @param {string} priceChange - The price change + * @returns {string} The formatted price change + */ +function formatPriceChange(priceChange) { + // Add a '+' for positive changes + return (priceChange.startsWith("-") ? "" : "+") + priceChange; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/time.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/time.jsx new file mode 100755 index 0000000..6890ffb --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/time.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 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 { timeStyles as styles } from "../../styles/components/data/time"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 1000; + +/** + * Time widget component. + * @returns {JSX.Element|null} The rendered widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, timeWidgetOptions } = settings; + const { timeWidget } = widgets; + const { + refreshFrequency, + hour12, + dayProgress, + showSeconds, + showOnDisplay, + showIcon, + } = timeWidgetOptions; + + // Determine if the widget should be visible on the current display + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && timeWidget; + + // Calculate the refresh frequency for the widget + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + // Options for formatting the time string + const options = React.useMemo( + () => ({ + hour: "numeric", + minute: "numeric", + second: showSeconds ? "numeric" : undefined, + hour12, + }), + [hour12, showSeconds], + ); + + /** + * Resets the widget state. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetches the current time and updates the widget state. + */ + const getTime = React.useCallback(() => { + if (!visible) return; + const time = new Date().toLocaleString("en-UK", options); + setState({ time }); + setLoading(false); + }, [visible, options]); + + // Use server socket to get time updates + useServerSocket("time", visible, getTime, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getTime, refresh); + + if (loading) return ; + if (!state) return null; + const { time } = state; + + // Calculate the progress of the current day + const [dayStart, dayEnd] = [new Date(), new Date()]; + dayStart.setHours(0, 0, 0); + dayEnd.setHours(0, 0, 0); + dayEnd.setDate(dayEnd.getDate() + 1); + const range = dayEnd - dayStart; + const diff = Math.max(0, dayEnd - new Date()); + const fillerWidth = (100 - (100 * diff) / range) / 100; + + /** + * Icon component for the time widget. + * @returns {JSX.Element} The rendered icon. + */ + const TimeIcon = () => { + return ; + }; + + return ( + + {time} + {dayProgress && ( +
+ )} + + ); +}); + +Widget.displayName = "Time"; + +/** + * Icon component for displaying the time as a clock. + * @param {Object} props - The component props. + * @param {string} props.time - The current time string. + * @returns {JSX.Element} The rendered icon. + */ +function Icon({ time }) { + const [hours, minutes] = time.split(":"); + + const hoursInDegree = ((parseInt(hours, 10) % 12) / 12) * 360; + const minutesInDegree = (parseInt(minutes, 10) / 60) * 360; + + return ( +
+
+
+
+ ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/user-widgets.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/user-widgets.jsx new file mode 100755 index 0000000..efa9876 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/user-widgets.jsx @@ -0,0 +1,181 @@ +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 Settings from "../../settings"; +import * as Utils from "../../utils"; + +const { React } = Uebersicht; + +export default React.memo(UserWidgets); + +/** + * UserWidgets component that renders a list of user-defined widgets. + * @returns {JSX.Element[]} Array of UserWidget components. + */ +function UserWidgets() { + const { settings } = useSimpleBarContext(); + const { userWidgetsList } = settings.userWidgets; + + // Get the keys of the userWidgetsList object + const keys = Object.keys(userWidgetsList); + + // Map over the keys and render a UserWidget for each key + return keys.map((key) => ( + + )); +} + +UserWidgets.displayName = "UserWidgets"; + +/** + * UserWidget component that renders an individual user-defined widget. + * @param {Object} props - The component props. + * @param {string} props.index - The index of the widget. + * @param {Object} props.widget - The widget configuration object. + * @returns {JSX.Element|null} The rendered UserWidget component or null if not visible. + */ +const UserWidget = React.memo(({ index, widget }) => { + const { displayIndex, settings } = useSimpleBarContext(); + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(true); + const [isWidgetActive, setIsWidgetActive] = React.useState(true); + const { + icon, + backgroundColor, + output, + onClickAction, + onRightClickAction, + onMiddleClickAction, + refreshFrequency, + active, + noIcon, + hideWhenNoOutput = true, + showOnDisplay = "", + } = widget; + + // Determine if the widget should be visible based on display settings and active status + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && active; + + /** + * Resets the widget state and loading status. + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + setIsWidgetActive(true); + }; + + /** + * Fetches the widget output and updates the state. + */ + const getUserWidget = React.useCallback(async () => { + if (!visible) return; + const widgetOutput = await Utils.cachedRun(output, refreshFrequency); + const cleanedOutput = Utils.cleanupOutput(widgetOutput); + + // Hide widget if script returns empty output and hideWhenNoOutput is enabled + if ( + hideWhenNoOutput && + (!cleanedOutput.length || cleanedOutput.trim() === "") + ) { + setLoading(false); + setIsWidgetActive(false); + setState(undefined); + return; + } + + setState(widgetOutput); + setIsWidgetActive(true); + setLoading(false); + }, [visible, output, hideWhenNoOutput, refreshFrequency]); + + // Use server socket to listen for widget updates + useServerSocket( + "user-widget", + visible, + getUserWidget, + resetWidget, + setLoading, + index, + ); + + // Refresh the widget at the specified frequency + useWidgetRefresh(visible, getUserWidget, refreshFrequency); + + // Hide widget if not visible or if script indicates it should be inactive (only when hideWhenNoOutput is enabled) + if (!visible || (hideWhenNoOutput && !isWidgetActive)) return null; + + const isCustomColor = !Settings.userWidgetColors.includes(backgroundColor); + + const property = settings.global.widgetsBackgroundColorAsForeground + ? "color" + : "backgroundColor"; + + const style = settings.global.noColorInData + ? undefined + : { + [property]: isCustomColor ? backgroundColor : `var(${backgroundColor})`, + }; + + if (loading) return ; + + const Icon = !noIcon ? Icons[icon] : null; + + const hasOnClickAction = onClickAction?.trim().length > 0; + const hasRightClickAction = onRightClickAction?.trim().length > 0; + const hasMiddleClickAction = onMiddleClickAction?.trim().length > 0; + + /** + * Handles the click event for the widget. + * @param {Event} e - The click event. + */ + const onClick = async (e) => { + Utils.clickEffect(e); + await Uebersicht.run(onClickAction); + getUserWidget(); + }; + + /** + * Handles the right-click event for the widget. + * @param {Event} e - The right-click event. + */ + const onRightClick = async (e) => { + Utils.clickEffect(e); + await Uebersicht.run(onRightClickAction); + getUserWidget(); + }; + + /** + * Handles the middle-click event for the widget. + * @param {Event} e - The middle-click event. + */ + const onMiddleClick = async (e) => { + Utils.clickEffect(e); + await Uebersicht.run(onMiddleClickAction); + getUserWidget(); + }; + + const onClickProps = { + onClick: hasOnClickAction ? onClick : undefined, + onRightClick: hasRightClickAction ? onRightClick : undefined, + onMiddleClick: hasMiddleClickAction ? onMiddleClick : undefined, + }; + + return ( + + {state} + + ); +}); + +UserWidget.displayName = "UserWidget"; 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, + ); + } +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/weather.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/weather.jsx new file mode 100755 index 0000000..946fda1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/weather.jsx @@ -0,0 +1,214 @@ +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 * as Utils from "../../utils"; +import useWidgetRefresh from "../../hooks/use-widget-refresh"; +import useServerSocket from "../../hooks/use-server-socket"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; + +export { weatherStyles as styles } from "../../styles/components/data/weather"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 1000 * 60 * 30; // Default refresh frequency set to 30 minutes + +/** + * Weather widget component + */ +export const Widget = React.memo(() => { + const { displayIndex, settings, pushMissive } = useSimpleBarContext(); + const { widgets, weatherWidgetOptions } = settings; + const { weatherWidget } = widgets; + const { + refreshFrequency, + customLocation, + unit, + hideLocation, + hideGradient, + showOnDisplay, + showIcon, + } = weatherWidgetOptions; + + const refresh = React.useMemo( + () => + Utils.getRefreshFrequency(refreshFrequency, DEFAULT_REFRESH_FREQUENCY), + [refreshFrequency], + ); + + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && weatherWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + const location = React.useRef( + visible && customLocation.length ? customLocation : undefined, + ); + + /** + * Resets the widget state and loading status + */ + const resetWidget = () => { + setState(undefined); + setLoading(false); + }; + + /** + * Fetches weather data from wttr.in + */ + const getWeather = React.useCallback(async () => { + if (!visible) return; + if (!location.current) { + const position = await Promise.race([getPosition(), Utils.timeout(5000)]); + if (!position) await getWeather(); + const { city, zip } = position?.address || {}; + location.current = zip || city; + if (!location.current) return setLoading(false); + } + try { + const result = await fetch( + `https://wttr.in/${location.current}?format=j1`, + ); + const data = await result.json(); + setState({ location: location.current, data }); + } catch { + // eslint-disable-next-line no-console + console.error("Error while fetching weather") + } + setLoading(false); + }, [visible, location]); + + useServerSocket("weather", visible, getWeather, resetWidget, setLoading); + useWidgetRefresh(visible, getWeather, refresh); + + if (loading) return ; + if (!state || !state.data.current_condition) return null; + + const { + temp_C: tempC, + temp_F: tempF, + weatherDesc, + } = state.data.current_condition[0]; + const temperature = unit === "C" ? tempC : tempF; + const wttrUnitParam = unit === "C" ? "?m" : "?u"; + + const description = weatherDesc[0].value; + + const { astronomy } = state.data.weather[0]; + const sunriseData = astronomy[0].sunrise.replace(" AM", "").split(":"); + const sunsetData = astronomy[0].sunset.replace(" PM", "").split(":"); + + const now = new Date(); + const nowIntervalStart = new Date(); + nowIntervalStart.setHours(nowIntervalStart.getHours() - 1); + const nowIntervalStop = new Date(); + nowIntervalStop.setHours(nowIntervalStop.getHours() + 1); + const sunriseTime = new Date(); + sunriseTime.setHours( + parseInt(sunriseData[0], 10), + parseInt(sunriseData[1], 10), + 0, + 0, + ); + const sunsetTime = new Date(); + sunsetTime.setHours( + parseInt(sunsetData[0], 10) + 12, + parseInt(sunsetData[1], 10), + 0, + 0, + ); + + const atNight = sunriseTime >= now || now >= sunsetTime; + + const Icon = getIcon(description, atNight); + const label = getLabel(state.location, temperature, unit, hideLocation); + + const sunRising = + sunriseTime >= nowIntervalStart && sunriseTime <= nowIntervalStop; + const sunSetting = + sunsetTime >= nowIntervalStart && sunsetTime <= nowIntervalStop; + + /** + * Handles right-click event to refresh weather data + * @param {Event} e - The event object + */ + const onRightClick = (e) => { + Utils.clickEffect(e); + setLoading(true); + getWeather(); + Utils.notification("Refreshing forecast from wttr.in...", pushMissive); + }; + + const classes = Utils.classNames("weather", { + "weather--sunrise": sunRising, + "weather--sunset": sunSetting, + }); + + return ( + openWeather(e, pushMissive)} + onRightClick={onRightClick} + disableSlider + > + {!hideGradient &&
} + {label} + + ); +}); + +Widget.displayName = "Weather"; + +/** + * Returns the appropriate weather icon based on the description and time of day + * @param {string} description - Weather description + * @param {boolean} atNight - Whether it is currently night time + * @returns {JSX.Element} - The weather icon component + */ +function getIcon(description, atNight) { + if (description.includes("fog") || description.includes("mist")) { + return Icons.Fog; + } + if (description.includes("storm")) return Icons.Storm; + if (description.includes("snow")) return Icons.Snow; + if (description.includes("rain")) return Icons.Rain; + if (description.includes("cloud")) return Icons.Cloud; + if (atNight) return Icons.Moon; + return Icons.Sun; +} + +/** + * Returns the label for the weather widget + * @param {string} location - The location name + * @param {string} temperature - The temperature value + * @param {string} unit - The temperature unit (C or F) + * @param {boolean} hideLocation - Whether to hide the location name + * @returns {string} - The label text + */ +function getLabel(location, temperature, unit, hideLocation) { + if (!location) return "Fetching..."; + if (hideLocation) return `${temperature}°${unit}`; + return `${location}, ${temperature}°${unit}`; +} + +/** + * Opens the weather forecast in a new tab + * @param {Event} e - The event object + * @param {Function} pushMissive - Function to push notifications + */ +function openWeather(e, pushMissive) { + Utils.clickEffect(e); + Utils.notification("Opening forecast from wttr.in...", pushMissive); +} + +/** + * Gets the current geographical position of the user + * @returns {Promise} - The position object + */ +async function getPosition() { + return new Promise((resolve) => + navigator.geolocation.getCurrentPosition(resolve), + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx new file mode 100755 index 0000000..c7bedcd --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/wifi.jsx @@ -0,0 +1,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 ; + 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 ( + + {name} + + ); +}); + +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; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/youtube-music.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/youtube-music.jsx new file mode 100755 index 0000000..bf586b1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/youtube-music.jsx @@ -0,0 +1,191 @@ +import * as Uebersicht from "uebersicht"; +import * as DataWidget from "./data-widget.jsx"; +import * as DataWidgetLoader from "./data-widget-loader.jsx"; +import useWidgetRefresh from "../../hooks/use-widget-refresh"; +import useServerSocket from "../../hooks/use-server-socket"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Icons from "../icons/icons.jsx"; +import * as Utils from "../../utils"; + +export { youtubeMusicStyles as styles } from "../../styles/components/data/youtube-music"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 10000; + +/** + * YouTube Music Widget component. + * @returns {JSX.Element} The YouTube Music widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { + widgets: { youtubeMusicWidget }, + youtubeMusicWidgetOptions: { + refreshFrequency, + showSpecter, + showOnDisplay, + youtubeMusicPort, + showIcon, + }, + } = settings; + + // 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 on the current display + const visible = + Utils.isVisibleOnDisplay(displayIndex, showOnDisplay) && youtubeMusicWidget; + + const [state, setState] = React.useState(); + const [cachedAccessToken, setCachedAccessToken] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + const apiUrl = `http://localhost:${youtubeMusicPort}`; + + /** + * Resets the widget state. + */ + const resetWidget = () => { + setState(undefined); + setCachedAccessToken(undefined); + setLoading(false); + }; + + /** + * Fetches the access token for the YouTube Music API. + * @returns {Promise} The access token. + */ + const getAccessToken = React.useCallback(async () => { + // As of 2024/12/01, the generated access tokens don't expire + if (cachedAccessToken) return cachedAccessToken; + + const response = await fetch(`${apiUrl}/auth/simple-bar`, { + method: "POST", + }); + const json = await response.json(); + setCachedAccessToken(json.accessToken); + return json.accessToken; + }, [apiUrl, cachedAccessToken]); + + /** + * Fetches data from a specified route. + * @param {string} route - The API route to fetch data from. + * @param {string} [method="POST"] - The HTTP method to use. + * @returns {Promise} The fetch response. + */ + const fetchRoute = React.useCallback( + async (route, method = "POST") => { + const headers = {}; + const url = new URL(route, apiUrl); + + // All routes under /api are protected + const needsAuthentication = url.pathname.startsWith("/api"); + if (needsAuthentication) { + const accessToken = await getAccessToken(); + if (!accessToken) { + throw new Error("Failed to get access token"); + } + headers.Authorization = `Bearer ${accessToken}`; + } + + return await fetch(url, { method, headers }); + }, + [apiUrl, getAccessToken], + ); + + /** + * Refreshes the widget state by fetching the current song info. + */ + const refreshState = React.useCallback(async () => { + if (!visible) return; + + try { + const response = await fetchRoute("/api/v1/song-info", "GET"); + const json = await response.json(); + setState(json); + } catch { + // most likely due to offline server, reset state + resetWidget(); + } + }, [visible, fetchRoute]); + + // Use server socket to listen for updates + useServerSocket( + "youtube-music", + visible, + refreshState, + resetWidget, + setLoading, + ); + // Use widget refresh hook to periodically refresh the state + useWidgetRefresh(visible, refreshState, refresh); + + if (loading) return ; + + /** + * Handles click event to toggle play/pause. + * @param {React.MouseEvent} e - The click event. + */ + const onClick = async (e) => { + Utils.clickEffect(e); + await fetchRoute("/api/v1/toggle-play"); + await refreshState(); + }; + + /** + * Handles right-click event to skip to the next song. + * @param {React.MouseEvent} e - The right-click event. + */ + const onRightClick = async (e) => { + Utils.clickEffect(e); + await fetchRoute("/api/v1/next"); + await refreshState(); + }; + + /** + * Handles middle-click event to open YouTube Music app. + * @param {React.MouseEvent} e - The middle-click event. + */ + const onMiddleClick = async (e) => { + Utils.clickEffect(e); + Uebersicht.run(`open -a 'YouTube Music'`); + await refreshState(); + }; + + const classes = Utils.classNames("youtube-music", {}); + if (!state) return null; + const { title, artist, isPaused } = state; + if (!title) return null; + + const label = artist.length ? `${title} - ${artist}` : title; + const Icon = getIcon(isPaused); + + return ( + + {label} + + ); +}); + +Widget.displayName = "YouTube Music"; + +/** + * Returns the appropriate icon based on the play/pause state. + * @param {boolean} isPaused - Whether the music is paused. + * @returns {JSX.Element} The icon component. + */ +function getIcon(isPaused) { + return isPaused ? Icons.Paused : Icons.Playing; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/zoom.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/zoom.jsx new file mode 100755 index 0000000..2c123e9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/zoom.jsx @@ -0,0 +1,107 @@ +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 { SuspenseIcon } from "../icons/icon.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 { zoomStyles as styles } from "../../styles/components/data/zoom"; + +const { React } = Uebersicht; + +const DEFAULT_REFRESH_FREQUENCY = 5000; + +/** + * Zoom widget component. + * @returns {JSX.Element|null} The Zoom widget. + */ +export const Widget = React.memo(() => { + const { displayIndex, settings } = useSimpleBarContext(); + const { widgets, zoomWidgetOptions } = settings; + const { zoomWidget } = widgets; + const { refreshFrequency, showVideo, showMic, showOnDisplay } = + zoomWidgetOptions; + + // 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) && zoomWidget; + + const [state, setState] = React.useState(); + const [loading, setLoading] = React.useState(visible); + + /** + * Reset the widget state. + */ + const resetWidget = React.useCallback(() => { + setState(undefined); + setLoading(false); + }, []); + + /** + * Fetch the Zoom status for mic and video. + */ + const getZoom = React.useCallback(async () => { + if (!visible) return; + try { + const [mic, video] = await Promise.all([ + Utils.cachedRun( + `osascript ./simple-bar/lib/scripts/zoom-mute-status.applescript`, + refresh, + ), + Utils.cachedRun( + `osascript ./simple-bar/lib/scripts/zoom-video-status.applescript`, + refresh, + ), + ]); + setState({ + mic: Utils.cleanupOutput(mic), + video: Utils.cleanupOutput(video), + }); + setLoading(false); + } catch (error) { + // eslint-disable-next-line no-console + console.error("Error fetching Zoom status:", error); + setLoading(false); + } + }, [visible, refresh]); + + // Use server socket to listen for Zoom events + useServerSocket("zoom", visible, getZoom, resetWidget, setLoading); + // Refresh the widget at the specified interval + useWidgetRefresh(visible, getZoom, refresh); + + if (loading) return ; + if (!state || (!state.mic.length && !state.video.length)) return null; + + const { mic, video } = state; + + const VideoIcon = video === "off" ? Icons.CameraOff : Icons.Camera; + const MicIcon = mic === "off" ? Icons.MicOff : Icons.MicOn; + + return ( + + {showVideo && ( + + + + )} + {showMic && ( + + + + )} + + ); +}); + +Widget.displayName = "Zoom"; diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/error.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/error.jsx new file mode 100755 index 0000000..135cb29 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/error.jsx @@ -0,0 +1,42 @@ +import * as Settings from "./settings/settings.jsx"; +import * as Utils from "../utils"; + +// Error messages for different types of errors +const message = { + error: "Something went wrong…", + yabaiError: "yabai is not running", + aerospaceError: "AeroSpace is either not running or outdated", + noOutput: "Loading…", + noData: "JSON error…", +}; + +/** + * Component to display error messages based on the type of error. + * @param {Object} props - The properties object. + * @param {string} props.type - The type of error. + * @param {string} props.classes - Additional CSS classes. + * @returns {JSX.Element} The error component. + */ +export function Component({ type, classes }) { + // Combine base class with additional classes and conditional loading class + const errorClasses = Utils.classNames("simple-bar--empty", classes, { + "simple-bar--loading": type === "noOutput", + }); + + // Refresh the component after 2 seconds for general errors and JSON errors + if (type === "error" || type === "noData") { + setTimeout(Utils.softRefresh, 2000); + } + + // Refresh the component after 15 seconds for yabai and aerospace errors + if (type === "yabaiError" || type === "aerospaceError") { + setTimeout(Utils.softRefresh, 15000); + } + + return ( +
+ simple-bar-index.jsx: {message[type]} + +
+ ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/icon.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/icon.jsx new file mode 100755 index 0000000..c46f60c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/icon.jsx @@ -0,0 +1,40 @@ +import * as Uebersicht from "uebersicht"; + +const { React } = Uebersicht; + +/** + * Icon component renders an SVG element. + * + * @param {Object} props - The properties object. + * @param {number} [props.width=24] - The width of the SVG. + * @param {number} [props.height=24] - The height of the SVG. + * @param {React.ReactNode} props.children - The children elements to be rendered inside the SVG. + * @returns {JSX.Element} The SVG element. + */ +export default function Icon({ width = 24, height = 24, children, ...props }) { + return ( + + {children} + + ); +} + +/** + * SuspenseIcon component renders its children within a React.Suspense component. + * + * @param {Object} props - The properties object. + * @param {React.ReactNode} props.children - The children elements to be rendered inside the Suspense component. + * @returns {JSX.Element} The Suspense component with a fallback SVG loader. + */ +export function SuspenseIcon({ children }) { + return ( + }> + {children} + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/icons.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/icons.jsx new file mode 100755 index 0000000..514a2f1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/icons.jsx @@ -0,0 +1,337 @@ +import * as Uebersicht from "uebersicht"; + +const { React } = Uebersicht; + +export const Default = React.lazy(() => import("./library/default.jsx")); +export const Ableton = React.lazy(() => import("./library/ableton.jsx")); +export const Activity = React.lazy(() => import("./library/activity.jsx")); +export const Add = React.lazy(() => import("./library/add.jsx")); +export const AffinityDesigner = React.lazy( + () => import("./library/affinity-designer.jsx"), +); +export const AffinityPhoto = React.lazy( + () => import("./library/affinity-photo.jsx"), +); +export const AffinityPublisher = React.lazy( + () => import("./library/affinity-publisher.jsx"), +); +export const Airmail = React.lazy(() => import("./library/airmail.jsx")); +export const Alfred = React.lazy(() => import("./library/alfred.jsx")); +export const AndroidMessages = React.lazy( + () => import("./library/android-messages.jsx"), +); +export const AndroidStudio = React.lazy( + () => import("./library/android-studio.jsx"), +); +export const Anki = React.lazy(() => import("./library/anki.jsx")); +export const Antigravity = React.lazy( + () => import("./library/antigravity.jsx"), +); +export const Anytype = React.lazy(() => import("./library/anytype.jsx")); +export const AppleSimulator = React.lazy( + () => import("./library/apple-simulator.jsx"), +); +export const AppStore = React.lazy(() => import("./library/app-store.jsx")); +export const Apple = React.lazy(() => import("./library/apple.jsx")); +export const Arc = React.lazy(() => import("./library/arc.jsx")); +export const Atom = React.lazy(() => import("./library/atom.jsx")); +export const Audacity = React.lazy(() => import("./library/audacity.jsx")); +export const Aqua = React.lazy(() => import("./library/aqua.jsx")); +export const Bank = React.lazy(() => import("./library/bank.jsx")); +export const BattleNet = React.lazy(() => import("./library/battle-net.jsx")); +export const BambuStudio = React.lazy( + () => import("./library/bambu-studio.jsx"), +); +export const Bear = React.lazy(() => import("./library/bear.jsx")); +export const Beekeeper = React.lazy(() => import("./library/beekeeper.jsx")); +export const Bell = React.lazy(() => import("./library/bell.jsx")); +export const BellOff = React.lazy(() => import("./library/bell-off.jsx")); +export const Bitcoin = React.lazy(() => import("./library/bitcoin.jsx")); +export const BitWarden = React.lazy(() => import("./library/bit-warden.jsx")); +export const Blender = React.lazy(() => import("./library/blender.jsx")); +export const Book = React.lazy(() => import("./library/book.jsx")); +export const BraveBrowser = React.lazy( + () => import("./library/brave-browser.jsx"), +); +export const Bruno = React.lazy(() => import("./library/bruno.jsx")); +export const CLion = React.lazy(() => import("./library/c-lion.jsx")); +export const Calendar = React.lazy(() => import("./library/calendar.jsx")); +export const Camera = React.lazy(() => import("./library/camera.jsx")); +export const CameraOff = React.lazy(() => import("./library/camera-off.jsx")); +export const Cancel = React.lazy(() => import("./library/cancel.jsx")); +export const Caprine = React.lazy(() => import("./library/caprine.jsx")); +export const CARROT = React.lazy(() => import("./library/ca-r-r-o-t.jsx")); +export const Celo = React.lazy(() => import("./library/celo.jsx")); +export const Charging = React.lazy(() => import("./library/charging.jsx")); +export const ChatGPT = React.lazy(() => import("./library/chat-gpt.jsx")); +export const Chatterino = React.lazy(() => import("./library/chatterino.jsx")); +export const ChevronBottom = React.lazy( + () => import("./library/chevron-bottom.jsx"), +); +export const ChevronLeft = React.lazy( + () => import("./library/chevron-left.jsx"), +); +export const ChevronRight = React.lazy( + () => import("./library/chevron-right.jsx"), +); +export const ChevronTop = React.lazy(() => import("./library/chevron-top.jsx")); +export const CheckBox = React.lazy(() => import("./library/check-box.jsx")); +export const ClickUp = React.lazy(() => import("./library/click-up.jsx")); +export const Claude = React.lazy(() => import("./library/claude.jsx")); +export const ClaudeCode = React.lazy(() => import("./library/claude-code.jsx")); +export const Cline = React.lazy(() => import("./library/cline.jsx")); +export const Clock = React.lazy(() => import("./library/clock.jsx")); +export const Close = React.lazy(() => import("./library/close.jsx")); +export const Cloud = React.lazy(() => import("./library/cloud.jsx")); +export const Codex = React.lazy(() => import("./library/codex.jsx")); +export const Code = React.lazy(() => import("./library/code.jsx")); +export const Coffee = React.lazy(() => import("./library/coffee.jsx")); +export const ColorPicker = React.lazy( + () => import("./library/color-picker.jsx"), +); +export const ComfyUI = React.lazy(() => import("./library/comfy-ui.jsx")); +export const Copilot = React.lazy(() => import("./library/copilot.jsx")); +export const CPU = React.lazy(() => import("./library/cp-u.jsx")); +export const Cursor = React.lazy(() => import("./library/cursor.jsx")); +export const DataGrip = React.lazy(() => import("./library/data-grip.jsx")); +export const Date = React.lazy(() => import("./library/date.jsx")); +export const Deezer = React.lazy(() => import("./library/deezer.jsx")); +export const Desktop = React.lazy(() => import("./library/desktop.jsx")); +export const DEVONthink3 = React.lazy( + () => import("./library/de-v-o-nthink3.jsx"), +); +export const Discord = React.lazy(() => import("./library/discord.jsx")); +export const Docker = React.lazy(() => import("./library/docker.jsx")); +export const Dollar = React.lazy(() => import("./library/dollar.jsx")); +export const DownArrow = React.lazy(() => import("./library/down-arrow.jsx")); +export const Download = React.lazy(() => import("./library/download.jsx")); +export const Drafts = React.lazy(() => import("./library/drafts.jsx")); +export const Dropbox = React.lazy(() => import("./library/dropbox.jsx")); +export const Element = React.lazy(() => import("./library/element.jsx")); +export const Emacs = React.lazy(() => import("./library/emacs.jsx")); +export const Ethereum = React.lazy(() => import("./library/ethereum.jsx")); +export const EvernoteLegacy = React.lazy( + () => import("./library/evernote-legacy.jsx"), +); +export const FaceTime = React.lazy(() => import("./library/face-time.jsx")); +export const Figma = React.lazy(() => import("./library/figma.jsx")); +export const FinalCutPro = React.lazy( + () => import("./library/final-cut-pro.jsx"), +); +export const Finder = React.lazy(() => import("./library/finder.jsx")); +export const Firefox = React.lazy(() => import("./library/firefox.jsx")); +export const FirefoxDeveloperEdition = React.lazy( + () => import("./library/firefox-developer-edition.jsx"), +); +export const Fleet = React.lazy(() => import("./library/fleet.jsx")); +export const Fog = React.lazy(() => import("./library/fog.jsx")); +export const Folx = React.lazy(() => import("./library/folx.jsx")); +export const FreeTube = React.lazy(() => import("./library/free-tube.jsx")); +export const Gear = React.lazy(() => import("./library/gear.jsx")); +export const Ghostty = React.lazy(() => import("./library/ghostty.jsx")); +export const GitHub = React.lazy(() => import("./library/git-hub.jsx")); +export const GoodNotes = React.lazy(() => import("./library/good-notes.jsx")); +export const GoogleChrome = React.lazy( + () => import("./library/google-chrome.jsx"), +); +export const GnuCash = React.lazy(() => import("./library/gnu-cash.jsx")); +export const GoLand = React.lazy(() => import("./library/go-land.jsx")); +export const Goose = React.lazy(() => import("./library/goose.jsx")); +export const Grammarly = React.lazy(() => import("./library/grammarly.jsx")); +export const Helium = React.lazy(() => import("./library/helium.jsx")); +export const HomeAssistant = React.lazy( + () => import("./library/home-assistant.jsx"), +); +export const HTTPie = React.lazy(() => import("./library/ht-t-pie.jsx")); +export const Idea = React.lazy(() => import("./library/idea.jsx")); +export const Insomnia = React.lazy(() => import("./library/insomnia.jsx")); +export const Iris = React.lazy(() => import("./library/iris.jsx")); +export const Italic = React.lazy(() => import("./library/italic.jsx")); +export const Joplin = React.lazy(() => import("./library/joplin.jsx")); +export const Kakoune = React.lazy(() => import("./library/kakoune.jsx")); +export const KeePassXC = React.lazy(() => import("./library/kee-pass-x-c.jsx")); +export const Keyboard = React.lazy(() => import("./library/keyboard.jsx")); +export const KeyboardMaestro = React.lazy( + () => import("./library/keyboard-maestro.jsx"), +); +export const Keynote = React.lazy(() => import("./library/keynote.jsx")); +export const LeagueOfLegends = React.lazy( + () => import("./library/league-of-legends.jsx"), +); +export const LibreWolf = React.lazy(() => import("./library/libre-wolf.jsx")); +export const Linear = React.lazy(() => import("./library/linear.jsx")); +export const LMStudio = React.lazy(() => import("./library/lm-studio.jsx")); +export const MaestroAI = React.lazy(() => import("./library/maestro-ai.jsx")); +export const Mail = React.lazy(() => import("./library/mail.jsx")); +export const Mamp = React.lazy(() => import("./library/mamp.jsx")); +export const Manus = React.lazy(() => import("./library/manus.jsx")); +export const Matlab = React.lazy(() => import("./library/matlab.jsx")); +export const Mattermost = React.lazy(() => import("./library/mattermost.jsx")); +export const Messages = React.lazy(() => import("./library/messages.jsx")); +export const MicOff = React.lazy(() => import("./library/mic-off.jsx")); +export const MicOn = React.lazy(() => import("./library/mic-on.jsx")); +export const MicrosoftEdge = React.lazy( + () => import("./library/microsoft-edge.jsx"), +); +export const MicrosoftExcel = React.lazy( + () => import("./library/microsoft-excel.jsx"), +); +export const MicrosoftOutlook = React.lazy( + () => import("./library/microsoft-outlook.jsx"), +); +export const MicrosoftPowerPoint = React.lazy( + () => import("./library/microsoft-power-point.jsx"), +); +export const MicrosoftWord = React.lazy( + () => import("./library/microsoft-word.jsx"), +); +export const Mimestream = React.lazy(() => import("./library/mimestream.jsx")); +export const MinBrowser = React.lazy(() => import("./library/min-browser.jsx")); +export const Miro = React.lazy(() => import("./library/miro.jsx")); +export const MoneroGUI = React.lazy(() => import("./library/monero-gui.jsx")); +export const MongoDB = React.lazy(() => import("./library/mongo-db.jsx")); +export const Moon = React.lazy(() => import("./library/moon.jsx")); +export const Mpv = React.lazy(() => import("./library/mpv.jsx")); +export const Music = React.lazy(() => import("./library/music.jsx")); +export const N8n = React.lazy(() => import("./library/n8n.jsx")); +export const NeteaseMusic = React.lazy( + () => import("./library/netease-music.jsx"), +); +export const NetNewsWire = React.lazy( + () => import("./library/net-news-wire.jsx"), +); +export const Notability = React.lazy(() => import("./library/notability.jsx")); +export const NotebookLM = React.lazy(() => import("./library/notebook-lm.jsx")); +export const Notes = React.lazy(() => import("./library/notes.jsx")); +export const Notion = React.lazy(() => import("./library/notion.jsx")); +export const Nova = React.lazy(() => import("./library/nova.jsx")); +export const NoVolume = React.lazy(() => import("./library/no-volume.jsx")); +export const Numbers = React.lazy(() => import("./library/numbers.jsx")); +export const Obsidian = React.lazy(() => import("./library/obsidian.jsx")); +export const OBSStudio = React.lazy(() => import("./library/ob-s-studio.jsx")); +export const Ollama = React.lazy(() => import("./library/ollama.jsx")); +export const OmniFocus = React.lazy(() => import("./library/omni-focus.jsx")); +export const OnePassword = React.lazy( + () => import("./library/one-password.jsx"), +); +export const OpenBook = React.lazy(() => import("./library/open-book.jsx")); +export const OpenClaw = React.lazy(() => import("./library/open-claw.jsx")); +export const Opencode = React.lazy(() => import("./library/opencode.jsx")); +export const OrbStack = React.lazy(() => import("./library/orb-stack.jsx")); +export const Pages = React.lazy(() => import("./library/pages.jsx")); +export const Parallels = React.lazy(() => import("./library/parallels.jsx")); +export const Paused = React.lazy(() => import("./library/paused.jsx")); +export const Perplexity = React.lazy(() => import("./library/perplexity.jsx")); +export const PDF = React.lazy(() => import("./library/pdf.jsx")); +export const PHPStorm = React.lazy(() => import("./library/php-storm.jsx")); +export const Pihole = React.lazy(() => import("./library/pihole.jsx")); +export const Pine = React.lazy(() => import("./library/pine.jsx")); +export const Pins = React.lazy(() => import("./library/pins.jsx")); +export const Playing = React.lazy(() => import("./library/playing.jsx")); +export const Plex = React.lazy(() => import("./library/plex.jsx")); +export const Podcasts = React.lazy(() => import("./library/podcasts.jsx")); +export const Pomodone = React.lazy(() => import("./library/pomodone.jsx")); +export const Postman = React.lazy(() => import("./library/postman.jsx")); +export const ProtonMail = React.lazy(() => import("./library/proton-mail.jsx")); +export const PyCharm = React.lazy(() => import("./library/py-charm.jsx")); +export const Quip = React.lazy(() => import("./library/quip.jsx")); +export const QuteBrowser = React.lazy( + () => import("./library/qute-browser.jsx"), +); +export const Radar = React.lazy(() => import("./library/radar.jsx")); +export const Rain = React.lazy(() => import("./library/rain.jsx")); +export const Ram = React.lazy(() => import("./library/ram.jsx")); +export const Redis = React.lazy(() => import("./library/redis.jsx")); +export const Reeder5 = React.lazy(() => import("./library/reeder5.jsx")); +export const Reminders = React.lazy(() => import("./library/reminders.jsx")); +export const Remnote = React.lazy(() => import("./library/remnote.jsx")); +export const RemoteDesktop = React.lazy( + () => import("./library/remote-desktop.jsx"), +); +export const Remove = React.lazy(() => import("./library/remove.jsx")); +export const Replit = React.lazy(() => import("./library/replit.jsx")); +export const Rider = React.lazy(() => import("./library/rider.jsx")); +export const RocketChat = React.lazy(() => import("./library/rocket-chat.jsx")); +export const Roon = React.lazy(() => import("./library/roon.jsx")); +export const RoyalTSX = React.lazy(() => import("./library/royal-tsx.jsx")); +export const RubyMine = React.lazy(() => import("./library/ruby-mine.jsx")); +export const RustRover = React.lazy(() => import("./library/rust-rover.jsx")); +export const Safari = React.lazy(() => import("./library/safari.jsx")); +export const Screens4 = React.lazy(() => import("./library/screens4.jsx")); +export const SequelAce = React.lazy(() => import("./library/sequel-ace.jsx")); +export const SequelPro = React.lazy(() => import("./library/sequel-pro.jsx")); +export const Setapp = React.lazy(() => import("./library/setapp.jsx")); +export const Signal = React.lazy(() => import("./library/signal.jsx")); +export const Sketch = React.lazy(() => import("./library/sketch.jsx")); +export const SketchUp = React.lazy(() => import("./library/sketch-up.jsx")); +export const Skype = React.lazy(() => import("./library/skype.jsx")); +export const Slack = React.lazy(() => import("./library/slack.jsx")); +export const Snow = React.lazy(() => import("./library/snow.jsx")); +export const Spark = React.lazy(() => import("./library/spark.jsx")); +export const Spotify = React.lazy(() => import("./library/spotify.jsx")); +export const Spotlight = React.lazy(() => import("./library/spotlight.jsx")); +export const Spotube = React.lazy(() => import("./library/spotube.jsx")); +export const Statistics = React.lazy(() => import("./library/statistics.jsx")); +export const Stopped = React.lazy(() => import("./library/stopped.jsx")); +export const Storm = React.lazy(() => import("./library/storm.jsx")); +export const SublimeText = React.lazy( + () => import("./library/sublime-text.jsx"), +); +export const Sun = React.lazy(() => import("./library/sun.jsx")); +export const SuperProductivity = React.lazy( + () => import("./library/super-productivity.jsx"), +); +export const TablePlus = React.lazy(() => import("./library/table-plus.jsx")); +export const Tailscale = React.lazy(() => import("./library/tailscale.jsx")); +export const Teams = React.lazy(() => import("./library/teams.jsx")); +export const TeamSpeak = React.lazy(() => import("./library/team-speak.jsx")); +export const Telegram = React.lazy(() => import("./library/telegram.jsx")); +export const Terminal = React.lazy(() => import("./library/terminal.jsx")); +export const Text = React.lazy(() => import("./library/text.jsx")); +export const Thermostat = React.lazy(() => import("./library/thermostat.jsx")); +export const Things = React.lazy(() => import("./library/things.jsx")); +export const Thunderbird = React.lazy( + () => import("./library/thunderbird.jsx"), +); +export const TickTick = React.lazy(() => import("./library/tick-tick.jsx")); +export const Tidal = React.lazy(() => import("./library/tidal.jsx")); +export const Todoist = React.lazy(() => import("./library/todoist.jsx")); +export const TorBrowser = React.lazy(() => import("./library/tor-browser.jsx")); +export const Tower = React.lazy(() => import("./library/tower.jsx")); +export const Transmit = React.lazy(() => import("./library/transmit.jsx")); +export const Trello = React.lazy(() => import("./library/trello.jsx")); +export const Twitter = React.lazy(() => import("./library/twitter.jsx")); +export const UpArrow = React.lazy(() => import("./library/up-arrow.jsx")); +export const Upload = React.lazy(() => import("./library/upload.jsx")); +export const Vim = React.lazy(() => import("./library/vim.jsx")); +export const Vivaldi = React.lazy(() => import("./library/vivaldi.jsx")); +export const VLC = React.lazy(() => import("./library/vl-c.jsx")); +export const VMwareFusion = React.lazy( + () => import("./library/vmware-fusion.jsx"), +); +export const VolumeHigh = React.lazy(() => import("./library/volume-high.jsx")); +export const VolumeLow = React.lazy(() => import("./library/volume-low.jsx")); +export const VolumeMuted = React.lazy( + () => import("./library/volume-muted.jsx"), +); +export const VPN = React.lazy(() => import("./library/vp-n.jsx")); +export const VPNOff = React.lazy(() => import("./library/vp-n-off.jsx")); +export const VSCodium = React.lazy(() => import("./library/vs-codium.jsx")); +export const Warp = React.lazy(() => import("./library/warp.jsx")); +export const WebStorm = React.lazy(() => import("./library/web-storm.jsx")); +export const Wechat = React.lazy(() => import("./library/wechat.jsx")); +export const WhatsApp = React.lazy(() => import("./library/whats-app.jsx")); +export const Widget = React.lazy(() => import("./library/widget.jsx")); +export const Wifi = React.lazy(() => import("./library/wifi.jsx")); +export const WifiOff = React.lazy(() => import("./library/wifi-off.jsx")); +export const Windows = React.lazy(() => import("./library/windows.jsx")); +export const Xcode = React.lazy(() => import("./library/xcode.jsx")); +export const YoutubeMusic = React.lazy( + () => import("./library/youtube-music.jsx"), +); +export const Zed = React.lazy(() => import("./library/zed.jsx")); +export const ZenBrowser = React.lazy(() => import("./library/zen-browser.jsx")); +export const Zeplin = React.lazy(() => import("./library/zeplin.jsx")); +export const Zoom = React.lazy(() => import("./library/zoom.jsx")); +export const Zotero = React.lazy(() => import("./library/zotero.jsx")); +export const Zulip = React.lazy(() => import("./library/zulip.jsx")); diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ableton.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ableton.jsx new file mode 100755 index 0000000..c57cf32 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ableton.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Ableton(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/activity.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/activity.jsx new file mode 100755 index 0000000..502cbc7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/activity.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Activity(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/add.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/add.jsx new file mode 100755 index 0000000..fb2663d --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/add.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Add(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-designer.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-designer.jsx new file mode 100755 index 0000000..4840d80 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-designer.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function AffinityDesigner(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-photo.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-photo.jsx new file mode 100755 index 0000000..d4eb1a0 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-photo.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function AffinityPhoto(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-publisher.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-publisher.jsx new file mode 100755 index 0000000..127ed96 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/affinity-publisher.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function AffinityPublisher(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/airmail.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/airmail.jsx new file mode 100755 index 0000000..bad0d1f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/airmail.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Airmail(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/alfred.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/alfred.jsx new file mode 100755 index 0000000..909dccf --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/alfred.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Alfred(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/android-messages.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/android-messages.jsx new file mode 100755 index 0000000..a074703 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/android-messages.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function AndroidMessages(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/android-studio.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/android-studio.jsx new file mode 100755 index 0000000..25fb85d --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/android-studio.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function AndroidStudio(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/anki.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/anki.jsx new file mode 100755 index 0000000..6a177aa --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/anki.jsx @@ -0,0 +1,16 @@ +import Icon from "../icon.jsx"; + +export default function Anki(props) { + return ( + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/antigravity.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/antigravity.jsx new file mode 100755 index 0000000..0c71174 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/antigravity.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Antigravity(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/anytype.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/anytype.jsx new file mode 100755 index 0000000..a585ecd --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/anytype.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Anytype(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/app-store.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/app-store.jsx new file mode 100755 index 0000000..91ebdc9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/app-store.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function AppStore(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/apple-simulator.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/apple-simulator.jsx new file mode 100755 index 0000000..13abc8f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/apple-simulator.jsx @@ -0,0 +1,16 @@ +import Icon from "../icon.jsx"; + +export default function Ableton(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/apple.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/apple.jsx new file mode 100755 index 0000000..dc8ffe8 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/apple.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Apple(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/aqua.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/aqua.jsx new file mode 100755 index 0000000..8267772 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/aqua.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Aqua(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/arc.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/arc.jsx new file mode 100755 index 0000000..dd7a339 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/arc.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function Arc(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/atom.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/atom.jsx new file mode 100755 index 0000000..104203e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/atom.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function Atom(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/audacity.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/audacity.jsx new file mode 100755 index 0000000..c5b72ea --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/audacity.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Audacity(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bambu-studio.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bambu-studio.jsx new file mode 100755 index 0000000..66c60d0 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bambu-studio.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function BambuStudio(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bank.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bank.jsx new file mode 100755 index 0000000..a777b0a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bank.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Bank(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/battle-net.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/battle-net.jsx new file mode 100755 index 0000000..120d215 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/battle-net.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function BattleNet(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bear.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bear.jsx new file mode 100755 index 0000000..249f1d5 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bear.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Bear(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/beekeeper.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/beekeeper.jsx new file mode 100755 index 0000000..121e00b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/beekeeper.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Beekeeper(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bell-off.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bell-off.jsx new file mode 100755 index 0000000..170e05f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bell-off.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function BellOff(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bell.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bell.jsx new file mode 100755 index 0000000..db84ce4 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bell.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Bell(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bit-warden.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bit-warden.jsx new file mode 100755 index 0000000..88ae754 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bit-warden.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function BitWarden(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bitcoin.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bitcoin.jsx new file mode 100755 index 0000000..116e1af --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bitcoin.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function Bitcoin(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/blender.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/blender.jsx new file mode 100755 index 0000000..5fcb14e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/blender.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Blender(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/book.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/book.jsx new file mode 100755 index 0000000..59c53a5 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/book.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Book(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/brave-browser.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/brave-browser.jsx new file mode 100755 index 0000000..66e72a9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/brave-browser.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function BraveBrowser(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bruno.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bruno.jsx new file mode 100755 index 0000000..a36f8b5 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/bruno.jsx @@ -0,0 +1,11 @@ +import Icon from "../icon.jsx"; + +export default function Bruno(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/c-lion.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/c-lion.jsx new file mode 100755 index 0000000..fb7ff5d --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/c-lion.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function CLion(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ca-r-r-o-t.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ca-r-r-o-t.jsx new file mode 100755 index 0000000..94339d1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ca-r-r-o-t.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function CARROT(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/calendar.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/calendar.jsx new file mode 100755 index 0000000..613f1b0 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/calendar.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Calendar(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/camera-off.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/camera-off.jsx new file mode 100755 index 0000000..a0f3891 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/camera-off.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function CameraOff(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/camera.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/camera.jsx new file mode 100755 index 0000000..e18b0da --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/camera.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Camera(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cancel.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cancel.jsx new file mode 100755 index 0000000..f96294f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cancel.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Cancel(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/caprine.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/caprine.jsx new file mode 100755 index 0000000..6e3c3f2 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/caprine.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Caprine(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/celo.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/celo.jsx new file mode 100755 index 0000000..155c73d --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/celo.jsx @@ -0,0 +1,20 @@ +import Icon from "../icon.jsx"; + +export default function Celo(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/charging.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/charging.jsx new file mode 100755 index 0000000..808f939 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/charging.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Charging(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chat-gpt.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chat-gpt.jsx new file mode 100755 index 0000000..8efbe29 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chat-gpt.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function ChatGPT(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chatterino.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chatterino.jsx new file mode 100755 index 0000000..6970765 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chatterino.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Chatterino(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/check-box.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/check-box.jsx new file mode 100755 index 0000000..cf80ac0 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/check-box.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function CheckBox(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-bottom.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-bottom.jsx new file mode 100755 index 0000000..1ed7678 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-bottom.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function ChevronBottom(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-left.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-left.jsx new file mode 100755 index 0000000..f9da786 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-left.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function ChevronLeft(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-right.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-right.jsx new file mode 100755 index 0000000..028c8b1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-right.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function ChevronRight(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-top.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-top.jsx new file mode 100755 index 0000000..37f5dfc --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/chevron-top.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function ChevronTop(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/claude-code.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/claude-code.jsx new file mode 100755 index 0000000..65babc9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/claude-code.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function ClaudeCode(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/claude.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/claude.jsx new file mode 100755 index 0000000..53f843b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/claude.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Claude(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/click-up.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/click-up.jsx new file mode 100755 index 0000000..467588e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/click-up.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function ClickUp(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cline.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cline.jsx new file mode 100755 index 0000000..11caeb8 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cline.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Cline(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/clock.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/clock.jsx new file mode 100755 index 0000000..ce01a6c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/clock.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Clock(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/close.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/close.jsx new file mode 100755 index 0000000..627ff65 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/close.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Close(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cloud.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cloud.jsx new file mode 100755 index 0000000..4b5b44a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cloud.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; +import * as Utils from "../../../utils"; + +export default function Cloud(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/code.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/code.jsx new file mode 100755 index 0000000..d0bd4cb --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/code.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Code(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/codex.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/codex.jsx new file mode 100755 index 0000000..332ea52 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/codex.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Codex(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/coffee.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/coffee.jsx new file mode 100755 index 0000000..e168da6 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/coffee.jsx @@ -0,0 +1,15 @@ +import Icon from "../icon.jsx"; + +export default function Coffee(props) { + return ( + + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/color-picker.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/color-picker.jsx new file mode 100755 index 0000000..c02fd7a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/color-picker.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function ColorPicker(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/comfy-ui.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/comfy-ui.jsx new file mode 100755 index 0000000..5afa497 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/comfy-ui.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function ComfyUI(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/copilot.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/copilot.jsx new file mode 100755 index 0000000..151595c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/copilot.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Copilot(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cp-u.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cp-u.jsx new file mode 100755 index 0000000..7705607 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cp-u.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function CPU(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cursor.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cursor.jsx new file mode 100755 index 0000000..1b40ec3 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/cursor.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Cursor(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/data-grip.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/data-grip.jsx new file mode 100755 index 0000000..6203fe3 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/data-grip.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function DataGrip(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/date.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/date.jsx new file mode 100755 index 0000000..9e59c84 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/date.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Date(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/de-v-o-nthink3.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/de-v-o-nthink3.jsx new file mode 100755 index 0000000..5f5acd1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/de-v-o-nthink3.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function DEVONthink3(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/deezer.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/deezer.jsx new file mode 100755 index 0000000..ec0b2ae --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/deezer.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Deezer(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/default.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/default.jsx new file mode 100755 index 0000000..6a0902c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/default.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Default(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/desktop.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/desktop.jsx new file mode 100755 index 0000000..c7fae7b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/desktop.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Desktop(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/discord.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/discord.jsx new file mode 100755 index 0000000..7b1a27b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/discord.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Discord(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/docker.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/docker.jsx new file mode 100755 index 0000000..2ed8850 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/docker.jsx @@ -0,0 +1,11 @@ +import Icon from "../icon.jsx"; + +export default function Windows(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/dollar.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/dollar.jsx new file mode 100755 index 0000000..5a24b9f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/dollar.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Dollar(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/down-arrow.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/down-arrow.jsx new file mode 100755 index 0000000..4cfd2e1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/down-arrow.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function DownArrow(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/download.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/download.jsx new file mode 100755 index 0000000..e612225 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/download.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function Download(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/drafts.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/drafts.jsx new file mode 100755 index 0000000..7c4c114 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/drafts.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Drafts(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/dropbox.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/dropbox.jsx new file mode 100755 index 0000000..159fac3 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/dropbox.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Dropbox(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/element.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/element.jsx new file mode 100755 index 0000000..03de2a2 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/element.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Element(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/emacs.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/emacs.jsx new file mode 100755 index 0000000..59dd511 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/emacs.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Emacs(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ethereum.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ethereum.jsx new file mode 100755 index 0000000..7c29401 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ethereum.jsx @@ -0,0 +1,34 @@ +import Icon from "../icon.jsx"; + +export default function Ethereum(props) { + return ( + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/evernote-legacy.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/evernote-legacy.jsx new file mode 100755 index 0000000..fcda973 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/evernote-legacy.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function EvernoteLegacy(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/face-time.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/face-time.jsx new file mode 100755 index 0000000..df94f94 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/face-time.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function FaceTime(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/figma.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/figma.jsx new file mode 100755 index 0000000..af80266 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/figma.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Figma(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/final-cut-pro.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/final-cut-pro.jsx new file mode 100755 index 0000000..6d9800b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/final-cut-pro.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function FinalCutPro(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/finder.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/finder.jsx new file mode 100755 index 0000000..e71536c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/finder.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Finder(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/firefox-developer-edition.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/firefox-developer-edition.jsx new file mode 100755 index 0000000..afd96d2 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/firefox-developer-edition.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function FirefoxDeveloperEdition(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/firefox.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/firefox.jsx new file mode 100755 index 0000000..fca522e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/firefox.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Firefox(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/fleet.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/fleet.jsx new file mode 100755 index 0000000..474d739 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/fleet.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Fleet(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/fog.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/fog.jsx new file mode 100755 index 0000000..f1d9556 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/fog.jsx @@ -0,0 +1,20 @@ +import Icon from "../icon.jsx"; +import * as Utils from "../../../utils"; + +export default function Fog(props) { + return ( + + + + + + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/folx.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/folx.jsx new file mode 100755 index 0000000..4fc7f48 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/folx.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Folx(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/free-tube.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/free-tube.jsx new file mode 100755 index 0000000..849131e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/free-tube.jsx @@ -0,0 +1,16 @@ +import Icon from "../icon.jsx"; + +export default function FreeTube(props) { + return ( + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/gear.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/gear.jsx new file mode 100755 index 0000000..faba81b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/gear.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Gear(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ghostty.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ghostty.jsx new file mode 100755 index 0000000..2a63aa0 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ghostty.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Ghostty(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/git-hub.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/git-hub.jsx new file mode 100755 index 0000000..b2df650 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/git-hub.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function GitHub(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/gnu-cash.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/gnu-cash.jsx new file mode 100755 index 0000000..9059b9a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/gnu-cash.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function GnuCash(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/go-land.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/go-land.jsx new file mode 100755 index 0000000..9f37eed --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/go-land.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function GoLand(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/good-notes.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/good-notes.jsx new file mode 100755 index 0000000..857c7ac --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/good-notes.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function GoodNotes(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/google-chrome.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/google-chrome.jsx new file mode 100755 index 0000000..90cb83f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/google-chrome.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function GoogleChrome(props) { + return ( + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/goose.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/goose.jsx new file mode 100755 index 0000000..740916a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/goose.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Goose(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/grammarly.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/grammarly.jsx new file mode 100755 index 0000000..574fc84 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/grammarly.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Grammarly(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/helium.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/helium.jsx new file mode 100755 index 0000000..141b2ff --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/helium.jsx @@ -0,0 +1,11 @@ +import Icon from "../icon.jsx"; + +export default function Helium(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/home-assistant.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/home-assistant.jsx new file mode 100755 index 0000000..3d94dc2 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/home-assistant.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function HomeAssistant(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ht-t-pie.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ht-t-pie.jsx new file mode 100755 index 0000000..20d99d7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ht-t-pie.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function HTTPie(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/idea.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/idea.jsx new file mode 100755 index 0000000..bdd92cf --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/idea.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Idea(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/insomnia.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/insomnia.jsx new file mode 100755 index 0000000..5d1fc12 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/insomnia.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Insomnia(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/iris.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/iris.jsx new file mode 100755 index 0000000..cb35f76 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/iris.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Iris(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/italic.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/italic.jsx new file mode 100755 index 0000000..cf19e23 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/italic.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Italic(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/joplin.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/joplin.jsx new file mode 100755 index 0000000..980784f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/joplin.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Joplin(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/kakoune.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/kakoune.jsx new file mode 100755 index 0000000..9d8d2ab --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/kakoune.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Kakoune(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/kee-pass-x-c.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/kee-pass-x-c.jsx new file mode 100755 index 0000000..1b73f58 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/kee-pass-x-c.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function KeePassXC(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keyboard-maestro.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keyboard-maestro.jsx new file mode 100755 index 0000000..f171ac7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keyboard-maestro.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function KeyboardMaestro(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keyboard.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keyboard.jsx new file mode 100755 index 0000000..1b5afc8 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keyboard.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Keyboard(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keynote.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keynote.jsx new file mode 100755 index 0000000..73dcd0c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/keynote.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Keynote(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/league-of-legends.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/league-of-legends.jsx new file mode 100755 index 0000000..808cfac --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/league-of-legends.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function LeagueOfLegends(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/libre-wolf.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/libre-wolf.jsx new file mode 100755 index 0000000..b1e856a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/libre-wolf.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function LibreWolf(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/linear.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/linear.jsx new file mode 100755 index 0000000..a71356c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/linear.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Linear(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/lm-studio.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/lm-studio.jsx new file mode 100755 index 0000000..ad2f9be --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/lm-studio.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function LMStudio(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/maestro-ai.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/maestro-ai.jsx new file mode 100755 index 0000000..8ae6ab1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/maestro-ai.jsx @@ -0,0 +1,11 @@ +import Icon from "../icon.jsx"; + +export default function MaestroAI(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mail.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mail.jsx new file mode 100755 index 0000000..5f331f2 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mail.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Mail(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mamp.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mamp.jsx new file mode 100755 index 0000000..bdfadca --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mamp.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Mamp(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/manus.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/manus.jsx new file mode 100755 index 0000000..041df0d --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/manus.jsx @@ -0,0 +1,17 @@ +import Icon from "../icon.jsx"; + +export default function Manus(props) { + return ( + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/matlab.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/matlab.jsx new file mode 100755 index 0000000..7208923 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/matlab.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Matlab(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mattermost.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mattermost.jsx new file mode 100755 index 0000000..eea42a9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mattermost.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Mattermost(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/messages.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/messages.jsx new file mode 100755 index 0000000..afa1565 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/messages.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Messages(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mic-off.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mic-off.jsx new file mode 100755 index 0000000..f71ff3e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mic-off.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function MicOff(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mic-on.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mic-on.jsx new file mode 100755 index 0000000..76524ad --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mic-on.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function MicOn(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-edge.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-edge.jsx new file mode 100755 index 0000000..48e6caf --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-edge.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function MicrosoftEdge(props) { + return ( + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-excel.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-excel.jsx new file mode 100755 index 0000000..6f4df55 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-excel.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function MicrosoftExcel(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-outlook.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-outlook.jsx new file mode 100755 index 0000000..2de1829 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-outlook.jsx @@ -0,0 +1,11 @@ +import Icon from "../icon.jsx"; + +export default function MicrosoftOutlook(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-power-point.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-power-point.jsx new file mode 100755 index 0000000..2cdab52 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-power-point.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function MicrosoftPowerPoint(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-word.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-word.jsx new file mode 100755 index 0000000..7d3165b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/microsoft-word.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function MicrosoftWord(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mimestream.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mimestream.jsx new file mode 100755 index 0000000..1ed0a2b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mimestream.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Mimestream(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/min-browser.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/min-browser.jsx new file mode 100755 index 0000000..ed6060c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/min-browser.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function MinBrowser(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/miro.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/miro.jsx new file mode 100755 index 0000000..678bc73 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/miro.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Miro(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/monero-gui.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/monero-gui.jsx new file mode 100755 index 0000000..a5d95a7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/monero-gui.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function MoneroGUI(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mongo-db.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mongo-db.jsx new file mode 100755 index 0000000..3d57187 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mongo-db.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function MongoDB(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/moon.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/moon.jsx new file mode 100755 index 0000000..d8a5e15 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/moon.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; +import * as Utils from "../../../utils"; + +export default function Moon(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mpv.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mpv.jsx new file mode 100755 index 0000000..eef4479 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/mpv.jsx @@ -0,0 +1,16 @@ +import Icon from "../icon.jsx"; + +export default function Mpv(props) { + return ( + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/music.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/music.jsx new file mode 100755 index 0000000..6deefcc --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/music.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Music(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/n8n.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/n8n.jsx new file mode 100755 index 0000000..ab86385 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/n8n.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function N8n(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/net-news-wire.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/net-news-wire.jsx new file mode 100755 index 0000000..4db43e7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/net-news-wire.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function NetNewsWire(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/netease-music.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/netease-music.jsx new file mode 100755 index 0000000..0a31527 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/netease-music.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function NeteaseMusic(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/no-volume.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/no-volume.jsx new file mode 100755 index 0000000..0a146d1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/no-volume.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function NoVolume(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notability.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notability.jsx new file mode 100755 index 0000000..8a4c560 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notability.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Notability(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notebook-lm.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notebook-lm.jsx new file mode 100755 index 0000000..2be5095 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notebook-lm.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function NotebookLM(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notes.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notes.jsx new file mode 100755 index 0000000..23e8a43 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notes.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Notes(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notion.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notion.jsx new file mode 100755 index 0000000..ff12f11 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/notion.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Notion(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/nova.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/nova.jsx new file mode 100755 index 0000000..ee0bf11 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/nova.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Nova(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/numbers.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/numbers.jsx new file mode 100755 index 0000000..0f98a60 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/numbers.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Numbers(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ob-s-studio.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ob-s-studio.jsx new file mode 100755 index 0000000..e62cd93 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ob-s-studio.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function OBSStudio(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/obsidian.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/obsidian.jsx new file mode 100755 index 0000000..f581eab --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/obsidian.jsx @@ -0,0 +1,33 @@ +import Icon from "../icon.jsx"; + +export default function Obsidian(props) { + return ( + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ollama.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ollama.jsx new file mode 100755 index 0000000..afa63f7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ollama.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Ollama(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/omni-focus.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/omni-focus.jsx new file mode 100755 index 0000000..25b414f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/omni-focus.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function OmniFocus(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/one-password.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/one-password.jsx new file mode 100755 index 0000000..4192696 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/one-password.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function OnePassword(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/open-book.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/open-book.jsx new file mode 100755 index 0000000..2381bbc --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/open-book.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function OpenBook(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/open-claw.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/open-claw.jsx new file mode 100755 index 0000000..d314638 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/open-claw.jsx @@ -0,0 +1,16 @@ +import Icon from "../icon.jsx"; + +export default function OpenClaw(props) { + return ( + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/opencode.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/opencode.jsx new file mode 100755 index 0000000..0e407e0 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/opencode.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Opencode(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/orb-stack.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/orb-stack.jsx new file mode 100755 index 0000000..674c20d --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/orb-stack.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function OrbStack(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pages.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pages.jsx new file mode 100755 index 0000000..1e83114 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pages.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Pages(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/parallels.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/parallels.jsx new file mode 100755 index 0000000..cf4063f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/parallels.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Parallels(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/paused.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/paused.jsx new file mode 100755 index 0000000..fe8ed21 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/paused.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Paused(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pdf.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pdf.jsx new file mode 100755 index 0000000..1fc252e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pdf.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function PDF(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/perplexity.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/perplexity.jsx new file mode 100755 index 0000000..9e095a0 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/perplexity.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Perplexity(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/php-storm.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/php-storm.jsx new file mode 100755 index 0000000..628771f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/php-storm.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function PHPStorm(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pihole.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pihole.jsx new file mode 100755 index 0000000..622efe3 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pihole.jsx @@ -0,0 +1,31 @@ +import Icon from "../icon.jsx"; + +export default function Pihole(props) { + return ( + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pine.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pine.jsx new file mode 100755 index 0000000..0e5e2fd --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pine.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Pine(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pins.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pins.jsx new file mode 100755 index 0000000..5b63d82 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pins.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Pins(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/playing.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/playing.jsx new file mode 100755 index 0000000..cc96548 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/playing.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Playing(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/plex.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/plex.jsx new file mode 100755 index 0000000..ab8a1d0 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/plex.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Plex(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/podcasts.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/podcasts.jsx new file mode 100755 index 0000000..767f73e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/podcasts.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Podcasts(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pomodone.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pomodone.jsx new file mode 100755 index 0000000..48c503b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/pomodone.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Pomodone(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/postman.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/postman.jsx new file mode 100755 index 0000000..79d92e1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/postman.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Postman(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/proton-mail.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/proton-mail.jsx new file mode 100755 index 0000000..61cc2ee --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/proton-mail.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function ProtonMail(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/py-charm.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/py-charm.jsx new file mode 100755 index 0000000..8845a8e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/py-charm.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function PyCharm(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/quip.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/quip.jsx new file mode 100755 index 0000000..b489fb4 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/quip.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Quip(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/qute-browser.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/qute-browser.jsx new file mode 100755 index 0000000..9e5a4a8 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/qute-browser.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function QuteBrowser(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/radar.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/radar.jsx new file mode 100755 index 0000000..3dcbaf1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/radar.jsx @@ -0,0 +1,11 @@ +import Icon from "../icon.jsx"; + +export default function Radar(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rain.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rain.jsx new file mode 100755 index 0000000..4518beb --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rain.jsx @@ -0,0 +1,15 @@ +import Icon from "../icon.jsx"; +import * as Utils from "../../../utils"; + +export default function Rain(props) { + return ( + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ram.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ram.jsx new file mode 100755 index 0000000..c37d116 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ram.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Ram(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/redis.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/redis.jsx new file mode 100755 index 0000000..c1ed1cb --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/redis.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Redis(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/reeder5.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/reeder5.jsx new file mode 100755 index 0000000..7775050 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/reeder5.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Reeder5(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/reminders.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/reminders.jsx new file mode 100755 index 0000000..a01348f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/reminders.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Reminders(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remnote.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remnote.jsx new file mode 100755 index 0000000..8783e44 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remnote.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function Remnote(props) { + return ( + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remote-desktop.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remote-desktop.jsx new file mode 100755 index 0000000..11a0758 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remote-desktop.jsx @@ -0,0 +1,15 @@ +import Icon from "../icon.jsx"; + +export default function RemoteDesktop(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remove.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remove.jsx new file mode 100755 index 0000000..d2ea86f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/remove.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Remove(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/replit.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/replit.jsx new file mode 100755 index 0000000..080e608 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/replit.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Replit(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rider.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rider.jsx new file mode 100755 index 0000000..9ad3e3e --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rider.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Rider(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rocket-chat.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rocket-chat.jsx new file mode 100755 index 0000000..0d30073 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rocket-chat.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function RocketChat(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/roon.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/roon.jsx new file mode 100755 index 0000000..a532846 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/roon.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Roon(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/royal-tsx.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/royal-tsx.jsx new file mode 100755 index 0000000..32b051f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/royal-tsx.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function RoyalTSX(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ruby-mine.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ruby-mine.jsx new file mode 100755 index 0000000..7e00335 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/ruby-mine.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function RubyMine(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rust-rover.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rust-rover.jsx new file mode 100755 index 0000000..ea9423b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/rust-rover.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function RustRover(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/safari.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/safari.jsx new file mode 100755 index 0000000..8a238e1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/safari.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Safari(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/screens4.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/screens4.jsx new file mode 100755 index 0000000..a3d028c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/screens4.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Screens4(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sequel-ace.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sequel-ace.jsx new file mode 100755 index 0000000..e2e5fb7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sequel-ace.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function SequelAce(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sequel-pro.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sequel-pro.jsx new file mode 100755 index 0000000..cc920ae --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sequel-pro.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function SequelPro(props) { + return ( + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/setapp.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/setapp.jsx new file mode 100755 index 0000000..44aad58 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/setapp.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Setapp(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/signal.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/signal.jsx new file mode 100755 index 0000000..c615f9c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/signal.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Signal(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sketch-up.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sketch-up.jsx new file mode 100755 index 0000000..0acb2ed --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sketch-up.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function SketchUp(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sketch.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sketch.jsx new file mode 100755 index 0000000..c35cb07 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sketch.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Sketch(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/skype.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/skype.jsx new file mode 100755 index 0000000..7d7a229 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/skype.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Skype(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/slack.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/slack.jsx new file mode 100755 index 0000000..163fdd9 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/slack.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Slack(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/snow.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/snow.jsx new file mode 100755 index 0000000..1c55afa --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/snow.jsx @@ -0,0 +1,18 @@ +import Icon from "../icon.jsx"; +import * as Utils from "../../../utils"; + +export default function Snow(props) { + return ( + + + + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spark.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spark.jsx new file mode 100755 index 0000000..7655fae --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spark.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Spark(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotify.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotify.jsx new file mode 100755 index 0000000..718a4a8 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotify.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Spotify(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotlight.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotlight.jsx new file mode 100755 index 0000000..4398b47 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotlight.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Spotlight(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotube.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotube.jsx new file mode 100755 index 0000000..f8c0e79 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/spotube.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Spotube(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/statistics.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/statistics.jsx new file mode 100755 index 0000000..5e5911f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/statistics.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Statistics(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/stopped.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/stopped.jsx new file mode 100755 index 0000000..05cb40c --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/stopped.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Stopped(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/storm.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/storm.jsx new file mode 100755 index 0000000..39fb1ad --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/storm.jsx @@ -0,0 +1,18 @@ +import Icon from "../icon.jsx"; +import * as Utils from "../../../utils"; + +export default function Storm(props) { + return ( + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sublime-text.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sublime-text.jsx new file mode 100755 index 0000000..80d2cea --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sublime-text.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function SublimeText(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sun.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sun.jsx new file mode 100755 index 0000000..270a37f --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/sun.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; +import * as Utils from "../../../utils"; + +export default function Sun(props) { + return ( + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/super-productivity.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/super-productivity.jsx new file mode 100755 index 0000000..93ec47a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/super-productivity.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function SuperProductivity(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/table-plus.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/table-plus.jsx new file mode 100755 index 0000000..0083b53 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/table-plus.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function TablePlus(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tailscale.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tailscale.jsx new file mode 100755 index 0000000..98987d7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tailscale.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Tailscale(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/team-speak.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/team-speak.jsx new file mode 100755 index 0000000..7942728 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/team-speak.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function TeamSpeak(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/teams.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/teams.jsx new file mode 100755 index 0000000..c1ea5a4 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/teams.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function Teams(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/telegram.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/telegram.jsx new file mode 100755 index 0000000..798993b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/telegram.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Telegram(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/terminal.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/terminal.jsx new file mode 100755 index 0000000..8a11afd --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/terminal.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Terminal(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/text.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/text.jsx new file mode 100755 index 0000000..6b2054d --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/text.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Text(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/thermostat.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/thermostat.jsx new file mode 100755 index 0000000..77a448a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/thermostat.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Thermostat(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/things.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/things.jsx new file mode 100755 index 0000000..0c8b288 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/things.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Things(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/thunderbird.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/thunderbird.jsx new file mode 100755 index 0000000..020ace1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/thunderbird.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Thunderbird(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tick-tick.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tick-tick.jsx new file mode 100755 index 0000000..6efffcb --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tick-tick.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function TickTick(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tidal.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tidal.jsx new file mode 100755 index 0000000..ae8b104 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tidal.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Tidal(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/todoist.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/todoist.jsx new file mode 100755 index 0000000..c834873 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/todoist.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Todoist(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tor-browser.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tor-browser.jsx new file mode 100755 index 0000000..93408a6 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tor-browser.jsx @@ -0,0 +1,15 @@ +import Icon from "../icon.jsx"; + +export default function TorBrowser(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tower.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tower.jsx new file mode 100755 index 0000000..9ddfd43 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/tower.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function Tower(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/transmit.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/transmit.jsx new file mode 100755 index 0000000..d9b3c53 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/transmit.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Transmit(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/trello.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/trello.jsx new file mode 100755 index 0000000..b999e0b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/trello.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Trello(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/twitter.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/twitter.jsx new file mode 100755 index 0000000..6a6e18b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/twitter.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Twitter(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/up-arrow.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/up-arrow.jsx new file mode 100755 index 0000000..f17cb93 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/up-arrow.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function UpArrow(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/upload.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/upload.jsx new file mode 100755 index 0000000..b3b23a1 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/upload.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function Upload(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vim.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vim.jsx new file mode 100755 index 0000000..29b4434 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vim.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Vim(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vivaldi.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vivaldi.jsx new file mode 100755 index 0000000..7baa302 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vivaldi.jsx @@ -0,0 +1,14 @@ +import Icon from "../icon.jsx"; + +export default function Vivaldi(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vl-c.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vl-c.jsx new file mode 100755 index 0000000..08be0f6 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vl-c.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function VLC(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vmware-fusion.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vmware-fusion.jsx new file mode 100755 index 0000000..3ac1b60 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vmware-fusion.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function VMwareFusion(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-high.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-high.jsx new file mode 100755 index 0000000..b11c5e3 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-high.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function VolumeHigh(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-low.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-low.jsx new file mode 100755 index 0000000..7da65d4 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-low.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function VolumeLow(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-muted.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-muted.jsx new file mode 100755 index 0000000..b7ca410 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/volume-muted.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function VolumeMuted(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vp-n-off.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vp-n-off.jsx new file mode 100755 index 0000000..7c2ae8b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vp-n-off.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function VPNOff(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vp-n.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vp-n.jsx new file mode 100755 index 0000000..a73a27a --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vp-n.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function VPN(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vs-codium.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vs-codium.jsx new file mode 100755 index 0000000..26f51b4 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/vs-codium.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function VSCodium(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/warp.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/warp.jsx new file mode 100755 index 0000000..a3e83e5 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/warp.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Warp(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/web-storm.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/web-storm.jsx new file mode 100755 index 0000000..3d75c80 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/web-storm.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function WebStorm(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wechat.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wechat.jsx new file mode 100755 index 0000000..3f814e8 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wechat.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Wechat(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/whats-app.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/whats-app.jsx new file mode 100755 index 0000000..02bd081 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/whats-app.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function WhatsApp(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/widget.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/widget.jsx new file mode 100755 index 0000000..48611f5 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/widget.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Widget(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wifi-off.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wifi-off.jsx new file mode 100755 index 0000000..d2a4690 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wifi-off.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function WifiOff(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wifi.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wifi.jsx new file mode 100755 index 0000000..cbf2610 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/wifi.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Wifi(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/windows.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/windows.jsx new file mode 100755 index 0000000..b81d452 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/windows.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Windows(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/xcode.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/xcode.jsx new file mode 100755 index 0000000..7c6185b --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/xcode.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Xcode(props) { + return ( + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/youtube-music.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/youtube-music.jsx new file mode 100755 index 0000000..fe7e130 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/youtube-music.jsx @@ -0,0 +1,13 @@ +import Icon from "../icon.jsx"; + +export default function YoutubeMusic(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zed.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zed.jsx new file mode 100755 index 0000000..95e4415 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zed.jsx @@ -0,0 +1,10 @@ +import Icon from "../icon.jsx"; + +export default function Zed(props) { + return ( + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zen-browser.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zen-browser.jsx new file mode 100755 index 0000000..b417df7 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zen-browser.jsx @@ -0,0 +1,11 @@ +import Icon from "../icon.jsx"; + +export default function ZenBrowser(props) { + return ( + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zeplin.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zeplin.jsx new file mode 100755 index 0000000..bf45e51 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zeplin.jsx @@ -0,0 +1,43 @@ +import Icon from "../icon.jsx"; + +export default function Zeplin(props) { + return ( + + + + + + + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zoom.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zoom.jsx new file mode 100755 index 0000000..d0e9610 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zoom.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Zoom(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zotero.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zotero.jsx new file mode 100755 index 0000000..1223d35 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zotero.jsx @@ -0,0 +1,12 @@ +import Icon from "../icon.jsx"; + +export default function Zotero(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zulip.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zulip.jsx new file mode 100755 index 0000000..8b94751 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/icons/library/zulip.jsx @@ -0,0 +1,9 @@ +import Icon from "../icon.jsx"; + +export default function Zulip(props) { + return ( + + + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/missives/missive.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/missives/missive.jsx new file mode 100755 index 0000000..eec0ace --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/missives/missive.jsx @@ -0,0 +1,48 @@ +import * as Uebersicht from "uebersicht"; +import { SuspenseIcon } from "../icons/icon.jsx"; +import * as Icons from "../icons/icons.jsx"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import * as Utils from "../../utils.js"; + +const { React } = Uebersicht; + +/** + * Missive component to display a notification. + * @param {Object} props - The properties object. + * @param {string} props.id - The unique identifier for the missive. + * @param {string} props.side - The side where the missive should appear ('left' or 'right'). + * @param {string} props.content - The content of the missive. + * @param {number} [props.timeout] - The timeout for the missive to auto-close. + * @returns {JSX.Element} The Missive component. + */ +export default function Missive({ id, side, content, timeout }) { + // Get the setMissives function from the context + const { setMissives } = useSimpleBarContext(); + + // Generate class names based on the side prop + const classes = Utils.classNames("missive", { + "missive--left": side === "left", + "missive--right": side === "right", + }); + + // Close the missive by removing it from the context and clearing the timeout. + const closeMissive = () => { + setMissives((current) => { + return current.filter((m) => m.id !== id); + }); + if (timeout) { + clearTimeout(timeout); + } + }; + + return ( +
+
{content}
+ +
+ ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/missives/missives.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/missives/missives.jsx new file mode 100755 index 0000000..3563937 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/missives/missives.jsx @@ -0,0 +1,40 @@ +import * as Uebersicht from "uebersicht"; +import { useSimpleBarContext } from "../simple-bar-context.jsx"; +import Missive from "./missive.jsx"; +import useServerSocket from "../../hooks/use-server-socket.js"; + +export { missivesStyles as styles } from "../../styles/components/missives"; + +const { React } = Uebersicht; + +/** + * Component to display a list of missives. + * It uses the simple-bar context to get settings and missives data. + * It also sets up a server socket to receive new missives. + * + * @returns {JSX.Element} The rendered component. + */ +export function Component() { + // Destructure settings, missives, and pushMissive function from the context + const { settings, missives, pushMissive } = useSimpleBarContext(); + const { enableServer } = settings.global; + + // Set up a server socket to listen for "missive" events and push new missives + useServerSocket("missive", enableServer, pushMissive); + + return ( +
+ {missives.map(({ id, side, content, timeout }) => { + return ( + + ); + })} +
+ ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/aerospace-display-manager.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/aerospace-display-manager.jsx new file mode 100755 index 0000000..8c4fa98 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/aerospace-display-manager.jsx @@ -0,0 +1,83 @@ +import * as Uebersicht from "uebersicht"; +import * as Utils from "../../utils"; +import * as Icons from "../icons/icons.jsx"; + +const { React } = Uebersicht; + +/** + * UserWidgetsCreator component allows users to create and manage custom widgets. + * @param {Object} props - The component props. + * @param {Object} props.defaultValue - The default value for the widgets. + * @param {Function} props.onChange - The function to call when the widgets change. + * @returns {JSX.Element} The UserWidgetsCreator component. + */ +export default function AerospaceDisplayManager({ defaultValue, onChange }) { + const [indexes, setIndexes] = React.useState(defaultValue || {}); + const [displays, setDisplays] = React.useState(Object.keys(defaultValue)); + + const addDisplay = () => { + setDisplays((current) => { + const highest = Math.max(...current, 0); + const newIndex = highest + 1; + setIndexes((current) => { + return { ...current, [newIndex]: Number(current[newIndex]) || 1 }; + }); + return [...current, newIndex]; + }); + }; + + const removeDisplay = (index) => { + setDisplays((current) => { + const newDisplays = current.filter((display) => display !== index); + setIndexes((current) => { + const newIndexes = { ...current }; + delete newIndexes[index]; + return newIndexes; + }); + return newDisplays; + }); + }; + + React.useEffect(() => { + const diffs = Utils.compareObjects(defaultValue, indexes); + const hasDiffs = Object.keys(diffs).length > 0; + if (hasDiffs) onChange({ target: { value: indexes } }); + }, [defaultValue, onChange, indexes]); + + return ( +
+
+ AeroSpace Custom display indexes +
+
+ {displays.map((display) => { + const index = indexes[display] || 1; + + const updateIndex = (e) => { + const value = e.target.value; + setIndexes((current) => { + return { ...current, [display]: Number(value) }; + }); + }; + + return ( +
+ {display}: + + +
+ ); + })} +
+ +
+ ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/color-picker.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/color-picker.jsx new file mode 100755 index 0000000..dbff879 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/color-picker.jsx @@ -0,0 +1,109 @@ +import * as Uebersicht from "uebersicht"; +import * as Settings from "../../settings"; + +const { React } = Uebersicht; + +/** + * ColorPicker component allows users to select a color from predefined options or input a custom color. + * @param {Object} props - The component props. + * @param {Function} props.callback - The callback function to handle color selection. + * @param {number} props.index - The index of the color picker. + * @param {string} props.selectedColor - The initially selected color. + * @returns {JSX.Element} The ColorPicker component. + */ +export default function ColorPicker({ callback, index, selectedColor }) { + // Determine if the selected color is a custom color + const isSelectedCustom = !Settings.userWidgetColors.includes(selectedColor); + // State to manage the open/close status of the color picker + const [open, setOpen] = React.useState(false); + // State to manage the currently selected color + const [selected, setSelected] = React.useState(selectedColor); + // State to manage the custom color input + const [customColor, setCustomColor] = React.useState( + isSelectedCustom ? selectedColor : undefined, + ); + + // Toggle the color picker open/close status + const onClick = () => setOpen(!open); + + /** + * Handle custom color input change. + * @param {Object} e - The event object. + */ + const onCustomColorChange = (e) => { + const value = e.target.value; + setCustomColor(value); + callback?.(index, "backgroundColor", value); + }; + + /** + * Handle custom color submission. + */ + const onCustomColorSubmit = () => { + setSelected(customColor); + setOpen(false); + }; + + return ( +
+ +
+
+ )} +
+ ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx new file mode 100755 index 0000000..ca3bdab --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/icon-picker.jsx @@ -0,0 +1,130 @@ +import * as Uebersicht from "uebersicht"; +import * as Icons from "../icons/icons.jsx"; +import { SuspenseIcon } from "../icons/icon.jsx"; + +const { React } = Uebersicht; + +/** + * IconPicker component allows users to select an icon from a list of available icons. + * + * @param {Object} props - The component props. + * @param {Function} props.callback - The callback function to be called when an icon is selected. + * @param {number} props.index - The index of the icon picker. + * @param {string} props.selectedIcon - The initially selected icon. + * @returns {JSX.Element} The IconPicker component. + */ +export default function IconPicker({ callback, index, selectedIcon }) { + // State to manage the open/close state of the icon picker dropdown + const [open, setOpen] = React.useState(false); + // State to manage the currently selected icon + const [selected, setSelected] = React.useState(selectedIcon); + // State to manage the search term for filtering icons + const [searchTerm, setSearchTerm] = React.useState(""); + + // Get the selected icon component + const Icon = Icons[selected]; + // Get the list of all available icon keys + const keys = Object.keys(Icons); + + // Filter icons based on search term + const filteredKeys = React.useMemo(() => { + if (!searchTerm.trim()) { + return keys; + } + return keys.filter((key) => + key.toLowerCase().includes(searchTerm.toLowerCase()), + ); + }, [keys, searchTerm]); + + /** + * Toggles the open state of the icon picker dropdown. + */ + const onClick = () => setOpen(!open); + + /** + * Handles search input changes. + * + * @param {React.ChangeEvent} e - The input change event. + */ + const onSearchChange = (e) => { + setSearchTerm(e.target.value); + }; + + /** + * Clears the search term. + */ + const clearSearch = () => { + setSearchTerm(""); + }; + + return ( +
+ + {open && ( +
+
e.stopPropagation()} + > + + + {searchTerm && ( + + )} +
+
setOpen(false)}> + {filteredKeys.length > 0 ? ( + filteredKeys.map((key) => { + /** + * Handles the icon selection. + * + * @param {React.MouseEvent} e - The click event. + */ + const onClick = (e) => { + e.stopPropagation(); + setSelected(key); + callback?.(index, "icon", key); + setOpen(false); + }; + const Icon = Icons[key]; + return ( + + ); + }) + ) : ( +
+ No icons found for "{searchTerm}" +
+ )} +
+
+ )} +
+ ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-component.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-component.jsx new file mode 100755 index 0000000..8e48b66 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-component.jsx @@ -0,0 +1,159 @@ +import * as Uebersicht from "uebersicht"; +import * as Utils from "../../utils"; +import SettingsInner from "./settings-inner.jsx"; +import SettingsWidgets from "./settings-widgets.jsx"; +import * as Settings from "../../settings"; + +const { React } = Uebersicht; + +const TABS_STORAGE_KEY = "simple-bar-last-current-settings-tab"; +const TABS = [ + "global", + "themes", + "process", + "spacesDisplay", + "widgets", + "customStyles", +]; + +/** + * Main settings component. + * @param {Object} props - Component properties. + * @param {Function} props.closeSettings - Function to close the settings. + */ +export default function Component({ closeSettings }) { + // State to keep track of the current tab + const [currentTab, setCurrentTab] = React.useState(getLastCurrentTab()); + // State to keep track of pending changes + const [pendingChanges, setPendingChanges] = React.useState(0); + // Get current settings + const settings = Settings.get(); + // State to keep track of new settings + const [newSettings, setNewSettings] = React.useState(settings); + + /** + * Update the current tab and store it in session storage. + * @param {number} tab - The index of the tab to switch to. + */ + const updateTab = (tab) => { + setCurrentTab(tab); + window.sessionStorage.setItem(TABS_STORAGE_KEY, tab); + }; + + /** + * Refresh the simple-bar with new settings. + * @param {Event} e - The event object. + */ + const refreshSimpleBar = async (e) => { + Utils.clickEffect(e); + setPendingChanges(0); + await Settings.set(newSettings); + Utils.hardRefresh(); + }; + + // Effect to calculate the number of pending changes + React.useEffect(() => { + const diffs = Utils.compareObjects(settings, newSettings); + const deepDiffs = Object.keys(diffs).reduce( + (acc, key) => [...acc, ...Object.keys(diffs[key])], + [], + ); + setPendingChanges(deepDiffs.length); + }, [newSettings, settings]); + + return ( +
+
+
+
+
+
+ {Object.keys(Settings.defaultSettings).map((key) => { + const setting = Settings.data[key]; + const hideTab = !TABS.includes(key); + + if (!setting || hideTab) return null; + + const { label } = setting; + const i = TABS.indexOf(key); + const classes = Utils.classNames("settings__tab", { + "settings__tab--current": i === currentTab, + }); + return ( + + ); + })} +
+
+ {Object.keys(Settings.defaultSettings).map((key) => { + const setting = Settings.data[key]; + const hideContent = !TABS.includes(key); + + if (!setting || hideContent) return null; + + const isWidgetsTab = key === "widgets"; + + const { label } = setting; + return ( +
+ {isWidgetsTab ? ( + + ) : ( + +
{label}
+ +
+ )} +
+ ); + })} +
+
+ {pendingChanges !== 0 && ( +
+ {pendingChanges} pending change{pendingChanges > 1 && "s"} +
+ )} + +
+
+
+ ); +} + +/** + * Get the last current tab from session storage. + * @returns {number} The index of the last current tab. + */ +function getLastCurrentTab() { + const storedLastCurrentTab = window.sessionStorage.getItem(TABS_STORAGE_KEY); + if (storedLastCurrentTab) return parseInt(storedLastCurrentTab, 10); + return 0; +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-inner.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-inner.jsx new file mode 100755 index 0000000..e318b25 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-inner.jsx @@ -0,0 +1,123 @@ +import * as Uebersicht from "uebersicht"; +import * as Icons from "../icons/icons.jsx"; +import SettingsItem from "./settings-item.jsx"; +import * as Utils from "../../utils"; +import * as Settings from "../../settings"; + +const { React } = Uebersicht; + +/** + * SettingsInner component to render each setting category. + * @param {Object} props - Component properties. + * @param {string} props.settingKey - Key of current setting. + * @param {Object} props.setting - Contains infos & documentation data. + * @param {string[]} props.setting.infos - Current settings information. + * @param {string} props.setting.documentation - Current setting documentation link. + * @param {Object} props.newSettings - Object containing current modified settings. + * @param {Function} props.setNewSettings - Function allowing to save newly modified settings. + */ +export default function SettingsInner({ + settingKey, + setting, + newSettings, + setNewSettings, +}) { + const { infos, documentation } = setting; + return ( + <> + {Object.keys(Settings.defaultSettings[settingKey]).map((subKey) => { + const subSetting = Settings.data[subKey]; + if (!subSetting) return null; + const { + Component, + fullWidth, + label, + options, + placeholder, + title, + type, + minHeight, + } = subSetting; + + const code = settingKey + subKey; + const defaultValue = newSettings[settingKey][subKey]; + + const classes = Utils.classNames("settings__item", { + "settings__item--radio": type === "radio", + "settings__item--text": + type === "text" || type === "number" || type === "color", + "settings__item--textarea": type === "textarea", + "settings__item--color": type === "color", + "settings__item--full-width": fullWidth, + }); + + const onChange = (e) => { + let value = e.target.value; + if (type === "checkbox") { + value = e.target.checked; + } + if (type === "number") { + value = parseFloat(value); + if (isNaN(value)) { + value = 0; + } + } + + const updatedSettings = { + ...newSettings, + [settingKey]: { ...newSettings[settingKey], [subKey]: value }, + }; + setNewSettings(updatedSettings); + }; + + return ( + + {title &&
{title}
} +
+ +
+
+ ); + })} + {documentation && ( +
+ + + You{"'"}ll find all the information about these settings{" "} + + here on the documentation + {" "} + hosted on jeantinland.com. + +
+ )} + {infos && infos.length && ( +
+
Tips
+ {infos.map((info, i) => ( +
+ ))} +
+ )} + + ); +} diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-item.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-item.jsx new file mode 100755 index 0000000..91c6f54 --- /dev/null +++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/settings/settings-item.jsx @@ -0,0 +1,143 @@ +import * as Uebersicht from "uebersicht"; +import * as Utils from "../../utils"; + +const { React } = Uebersicht; + +/** + * Item component to render different types of settings inputs. + * @param {Object} props - Component properties. + * @param {string} props.code - Unique code for the setting. + * @param {React.Component} props.Component - Custom component for the setting. + * @param {any} props.defaultValue - Default value of the setting. + * @param {string} props.label - Label for the setting. + * @param {string} props.type - Type of the setting input. + * @param {Array} [props.options] - Options for select or radio inputs. + * @param {string} [props.placeholder] - Placeholder for text inputs. + * @param {number} [props.minHeight] - Minimum height for textarea inputs. + * @param {Function} props.onChange - Change handler for the setting input. + */ +export default function SettingsItem({ + code, + Component, + defaultValue, + label, + type, + options, + placeholder, + minHeight, + onChange, +}) { + const onClick = (e) => Utils.clickEffect(e); + if (type === "component") { + return ; + } + if (type === "select") { + return ( + + + ); + } + if (type === "radio") { + return options.map((option) => ( +
+ +
+ )); + } + if (type === "text" || type === "color") { + return ( + +