From d06784958d73159b5e4abafe5114804662114ed7 Mon Sep 17 00:00:00 2001 From: Ryan Schanzenbacher Date: Thu, 9 Jul 2026 22:15:53 -0400 Subject: move ubersicht modules in tree --- .../lib/components/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 ++++++++ 318 files changed, 10624 insertions(+) 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 (limited to 'users/ryan/modules/simple-bar/simple-bar-source/lib/components') 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 ( + +