summaryrefslogtreecommitdiff
path: root/dots/sketchybar/.config/sketchybar/items
diff options
context:
space:
mode:
authorHunt <lizhunt@amazon.com>2025-06-27 14:25:22 -0700
committerHunt <lizhunt@amazon.com>2025-06-27 14:44:54 -0700
commit0ba773cb8cb5162019d42c511f2580d601ab65d1 (patch)
tree7224f2e249df760213216a97ee73220e83a04b9f /dots/sketchybar/.config/sketchybar/items
parentdccdc3326cea3ad1e951438e6d38170d84d186d8 (diff)
downloaddotfiles-0ba773cb8cb5162019d42c511f2580d601ab65d1.tar.gz
dotfiles-0ba773cb8cb5162019d42c511f2580d601ab65d1.zip
Add sketchybar
Diffstat (limited to 'dots/sketchybar/.config/sketchybar/items')
-rw-r--r--dots/sketchybar/.config/sketchybar/items/apple.lua7
-rw-r--r--dots/sketchybar/.config/sketchybar/items/front_apps.lua71
-rw-r--r--dots/sketchybar/.config/sketchybar/items/init.lua12
-rw-r--r--dots/sketchybar/.config/sketchybar/items/media.lua118
-rw-r--r--dots/sketchybar/.config/sketchybar/items/menu_spaces_toggle.lua71
-rw-r--r--dots/sketchybar/.config/sketchybar/items/menus.lua74
-rwxr-xr-xdots/sketchybar/.config/sketchybar/items/menus/bin/menusbin0 -> 36920 bytes
-rw-r--r--dots/sketchybar/.config/sketchybar/items/message.lua55
-rw-r--r--dots/sketchybar/.config/sketchybar/items/spaces.lua.j299
-rw-r--r--dots/sketchybar/.config/sketchybar/items/widgets/battery.lua91
-rw-r--r--dots/sketchybar/.config/sketchybar/items/widgets/calendar.lua17
-rw-r--r--dots/sketchybar/.config/sketchybar/items/widgets/init.lua4
-rw-r--r--dots/sketchybar/.config/sketchybar/items/widgets/volume.lua128
-rw-r--r--dots/sketchybar/.config/sketchybar/items/widgets/wifi.lua261
14 files changed, 1008 insertions, 0 deletions
diff --git a/dots/sketchybar/.config/sketchybar/items/apple.lua b/dots/sketchybar/.config/sketchybar/items/apple.lua
new file mode 100644
index 0000000..001f348
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/apple.lua
@@ -0,0 +1,7 @@
+local settings = require("config.settings")
+
+local apple = sbar.add("item", "apple", {
+ icon = { string = settings.icons.text.apple },
+ label = { drawing = false },
+ click_script = "$CONFIG_DIR/items/menus/bin/menus -s 0"
+})
diff --git a/dots/sketchybar/.config/sketchybar/items/front_apps.lua b/dots/sketchybar/.config/sketchybar/items/front_apps.lua
new file mode 100644
index 0000000..dc0d606
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/front_apps.lua
@@ -0,0 +1,71 @@
+local constants = require("constants")
+local settings = require("config.settings")
+
+local frontApps = {}
+
+sbar.add("bracket", constants.items.FRONT_APPS, {}, { position = "left" })
+
+local frontAppWatcher = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+
+local function selectFocusedWindow(frontAppName)
+ for appName, app in pairs(frontApps) do
+ local isSelected = appName == frontAppName
+ local color = isSelected and settings.colors.orange or settings.colors.white
+ app:set(
+ {
+ label = { color = color },
+ icon = { color = color },
+ }
+ )
+ end
+end
+
+local function updateWindows(windows)
+ sbar.remove("/" .. constants.items.FRONT_APPS .. "\\.*/")
+
+ frontApps = {}
+ local foundWindows = string.gmatch(windows, "[^\n]+")
+ for window in foundWindows do
+ local parsedWindow = {}
+ for key, value in string.gmatch(window, "(%w+)=([%w%s]+)") do
+ parsedWindow[key] = value
+ end
+
+ local windowId = parsedWindow["id"]
+ local windowName = parsedWindow["name"]
+ local icon = settings.icons.apps[windowName] or settings.icons.apps["default"]
+
+ frontApps[windowName] = sbar.add("item", constants.items.FRONT_APPS .. "." .. windowName, {
+ label = {
+ padding_left = 0,
+ string = windowName,
+ },
+ icon = {
+ string = icon,
+ font = settings.fonts.icons(),
+ },
+ click_script = "aerospace focus --window-id " .. windowId,
+ })
+
+ frontApps[windowName]:subscribe(constants.events.FRONT_APP_SWITCHED, function(env)
+ selectFocusedWindow(env.INFO)
+ end)
+ end
+
+ sbar.exec(constants.aerospace.GET_CURRENT_WINDOW, function(frontAppName)
+ selectFocusedWindow(frontAppName:gsub("[\n\r]", ""))
+ end)
+end
+
+local function getWindows()
+ sbar.exec(constants.aerospace.LIST_WINDOWS, updateWindows)
+end
+
+frontAppWatcher:subscribe(constants.events.UPDATE_WINDOWS, function()
+ getWindows()
+end)
+
+getWindows()
diff --git a/dots/sketchybar/.config/sketchybar/items/init.lua b/dots/sketchybar/.config/sketchybar/items/init.lua
new file mode 100644
index 0000000..30625e3
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/init.lua
@@ -0,0 +1,12 @@
+-- Left items
+require("items.apple")
+require("items.menu_spaces_toggle")
+require("items.menus")
+require("items.spaces")
+require("items.front_apps")
+
+-- Right items
+require("items.message")
+require("items.widgets")
+
+-- require("items.media")
diff --git a/dots/sketchybar/.config/sketchybar/items/media.lua b/dots/sketchybar/.config/sketchybar/items/media.lua
new file mode 100644
index 0000000..1d34084
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/media.lua
@@ -0,0 +1,118 @@
+local colors = require("config.colors")
+
+local whitelist = {
+ ["Psst"] = true,
+};
+
+local media_cover = sbar.add("item", {
+ position = "left",
+ background = {
+ image = {
+ string = "media.artwork",
+ scale = 0.80,
+ },
+ color = colors.transparent,
+ },
+ label = { drawing = false },
+ icon = { drawing = false },
+ drawing = false,
+ updates = true,
+ popup = {
+ align = "center",
+ horizontal = true,
+ }
+})
+
+local media_artist = sbar.add("item", {
+ position = "left",
+ drawing = false,
+ padding_left = 3,
+ padding_right = 0,
+ width = 0,
+ icon = { drawing = false },
+ label = {
+ width = 0,
+ font = { size = 9 },
+ color = colors.with_alpha(colors.white, 0.6),
+ max_chars = 24,
+ y_offset = 6,
+ },
+})
+
+local media_title = sbar.add("item", {
+ position = "left",
+ drawing = false,
+ padding_left = 3,
+ padding_right = 0,
+ icon = { drawing = false },
+ label = {
+ font = { size = 11 },
+ width = 0,
+ max_chars = 35,
+ y_offset = -5,
+ },
+})
+
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.back },
+ label = { drawing = false },
+ click_script = "nowplaying-cli previous",
+})
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.play_pause },
+ label = { drawing = false },
+ click_script = "nowplaying-cli togglePlayPause",
+})
+sbar.add("item", {
+ position = "popup." .. media_cover.name,
+ icon = { string = icons.media.forward },
+ label = { drawing = false },
+ click_script = "nowplaying-cli next",
+})
+
+local interrupt = 0
+local function animate_detail(detail)
+ if (not detail) then interrupt = interrupt - 1 end
+ if interrupt > 0 and (not detail) then return end
+
+ sbar.animate("tanh", 30, function()
+ media_artist:set({ label = { width = detail and "dynamic" or 0 } })
+ media_title:set({ label = { width = detail and "dynamic" or 0 } })
+ end)
+end
+
+media_cover:subscribe("media_change", function(env)
+ if whitelist[env.INFO.app] then
+ local drawing = (env.INFO.state == "playing")
+ media_artist:set({ drawing = drawing, label = env.INFO.artist, })
+ media_title:set({ drawing = drawing, label = env.INFO.title, })
+ media_cover:set({ drawing = drawing })
+
+ if drawing then
+ animate_detail(true)
+ interrupt = interrupt + 1
+ sbar.delay(5, animate_detail)
+ else
+ media_cover:set({ popup = { drawing = false } })
+ end
+ end
+end)
+
+media_cover:subscribe("mouse.entered", function(env)
+ interrupt = interrupt + 1
+ animate_detail(true)
+end)
+
+media_cover:subscribe("mouse.exited", function(env)
+ animate_detail(false)
+end)
+
+media_cover:subscribe("mouse.clicked", function(env)
+ media_cover:set({ popup = { drawing = "toggle" } })
+end)
+
+media_title:subscribe("mouse.exited.global", function(env)
+ media_cover:set({ popup = { drawing = false } })
+end)
diff --git a/dots/sketchybar/.config/sketchybar/items/menu_spaces_toggle.lua b/dots/sketchybar/.config/sketchybar/items/menu_spaces_toggle.lua
new file mode 100644
index 0000000..bed73d5
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/menu_spaces_toggle.lua
@@ -0,0 +1,71 @@
+local constants = require("constants")
+local settings = require("config.settings")
+
+sbar.add("event", constants.events.SWAP_MENU_AND_SPACES)
+
+local function switchToggle(menuToggle)
+ local isShowingMenu = menuToggle:query().icon.value == settings.icons.text.switch.on
+
+ menuToggle:set({
+ icon = isShowingMenu and settings.icons.text.switch.off or settings.icons.text.switch.on,
+ label = isShowingMenu and "Menus" or "Spaces",
+ })
+
+ sbar.trigger(constants.events.SWAP_MENU_AND_SPACES, { isShowingMenu = isShowingMenu })
+end
+
+local function addToggle()
+ local menuToggle = sbar.add("item", constants.items.MENU_TOGGLE, {
+ icon = {
+ string = settings.icons.text.switch.on
+ },
+ label = {
+ width = 0,
+ color = settings.colors.bg1,
+ string = "Spaces",
+ },
+ background = {
+ color = settings.colors.with_alpha(settings.colors.dirty_white, 0.0),
+ }
+ })
+
+ sbar.add("item", constants.items.MENU_TOGGLE .. ".padding", {
+ width = settings.dimens.padding.label
+ })
+
+ menuToggle:subscribe("mouse.entered", function(env)
+ sbar.animate("tanh", 30, function()
+ menuToggle:set({
+ background = {
+ color = { alpha = 1.0 },
+ border_color = { alpha = 0.5 },
+ },
+ icon = { color = settings.colors.bg1 },
+ label = { width = "dynamic" }
+ })
+ end)
+ end)
+
+ menuToggle:subscribe("mouse.exited", function(env)
+ sbar.animate("tanh", 30, function()
+ menuToggle:set({
+ background = {
+ color = { alpha = 0.0 },
+ border_color = { alpha = 0.0 },
+ },
+ icon = { color = settings.colors.white },
+ label = { width = 0 }
+ })
+ end)
+ end)
+
+ menuToggle:subscribe("mouse.clicked", function(env)
+ switchToggle(menuToggle)
+ end)
+
+ menuToggle:subscribe(constants.events.AEROSPACE_SWITCH, function(env)
+ switchToggle(menuToggle)
+ end)
+end
+
+addToggle()
diff --git a/dots/sketchybar/.config/sketchybar/items/menus.lua b/dots/sketchybar/.config/sketchybar/items/menus.lua
new file mode 100644
index 0000000..674963a
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/menus.lua
@@ -0,0 +1,74 @@
+local constants = require("constants")
+local settings = require("config.settings")
+
+local maxItems <const> = 15
+local menuItems = {}
+local isShowingMenu = false
+
+local frontAppWatcher = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+
+local swapWatcher = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+
+local function createPlaceholders()
+ for index = 1, maxItems, 1 do
+ local menu = sbar.add("item", constants.items.MENU .. "." .. index, {
+ drawing = false,
+ icon = { drawing = false },
+ width = "dynamic",
+ label = {
+ font = {
+ style = index == 1 and settings.fonts.styles.bold or settings.fonts.styles.regular,
+ },
+ },
+ click_script = "$CONFIG_DIR/bridge/menus/bin/menus -s " .. index,
+ })
+ menuItems[index] = menu
+ end
+
+ sbar.add("bracket", { "/" .. constants.items.MENU .. "\\..*/" }, {
+ background = {
+ color = settings.colors.bg1,
+ padding_left = settings.dimens.padding.item,
+ padding_right = settings.dimens.padding.item,
+ },
+ })
+end
+
+local function updateMenus()
+ sbar.set("/" .. constants.items.MENU .. "\\..*/", { drawing = false })
+
+ sbar.exec("$CONFIG_DIR/bridge/menus/bin/menus -l", function(menus)
+ local index = 1
+ for menu in string.gmatch(menus, '[^\r\n]+') do
+ if index < maxItems then
+ menuItems[index]:set(
+ {
+ width = "dynamic",
+ label = menu,
+ drawing = isShowingMenu
+ }
+ )
+ else
+ break
+ end
+ index = index + 1
+ end
+ end)
+
+ sbar.set(constants.items.MENU .. ".padding", { drawing = isShowingMenu })
+end
+
+frontAppWatcher:subscribe(constants.events.FRONT_APP_SWITCHED, updateMenus)
+
+swapWatcher:subscribe(constants.events.SWAP_MENU_AND_SPACES, function(env)
+ isShowingMenu = env.isShowingMenu == "on"
+ updateMenus()
+end)
+
+createPlaceholders()
diff --git a/dots/sketchybar/.config/sketchybar/items/menus/bin/menus b/dots/sketchybar/.config/sketchybar/items/menus/bin/menus
new file mode 100755
index 0000000..4d92744
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/menus/bin/menus
Binary files differ
diff --git a/dots/sketchybar/.config/sketchybar/items/message.lua b/dots/sketchybar/.config/sketchybar/items/message.lua
new file mode 100644
index 0000000..1be586a
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/message.lua
@@ -0,0 +1,55 @@
+local constants = require("constants")
+local settings = require("config.settings")
+
+local message = sbar.add("item", constants.items.MESSAGE, {
+ width = 0,
+ position = "center",
+ popup = { align = "center" },
+ label = {
+ padding_left = 0,
+ padding_right = 0,
+ },
+ background = {
+ padding_left = 0,
+ padding_right = 0,
+ }
+})
+
+local messagePopup = sbar.add("item", {
+ position = "popup." .. message.name,
+ width = "dynamic",
+ label = {
+ padding_right = settings.dimens.padding.label,
+ padding_left = settings.dimens.padding.label,
+ },
+ icon = {
+ padding_left = 0,
+ padding_right = 0,
+ },
+})
+
+local function hideMessage()
+ message:set({ popup = { drawing = false } })
+end
+
+local function showMessage(content, hold)
+ hideMessage()
+
+ message:set({ popup = { drawing = true } })
+ messagePopup:set({ label = { string = content } })
+
+ if hold == false then
+ sbar.delay(5, function()
+ if hold then return end
+ hideMessage()
+ end)
+ end
+end
+
+message:subscribe(constants.events.SEND_MESSAGE, function(env)
+ local content = env.MESSAGE
+ local hold = env.HOLD ~= nil and env.HOLD == "true" or false
+ showMessage(content, hold)
+end)
+
+message:subscribe(constants.events.HIDE_MESSAGE, hideMessage)
diff --git a/dots/sketchybar/.config/sketchybar/items/spaces.lua.j2 b/dots/sketchybar/.config/sketchybar/items/spaces.lua.j2
new file mode 100644
index 0000000..6d1d6a9
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/spaces.lua.j2
@@ -0,0 +1,99 @@
+local constants = require("constants")
+local settings = require("config.settings")
+
+local spaces = {}
+
+local swapWatcher = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+
+local currentWorkspaceWatcher = sbar.add("item", {
+ drawing = false,
+ updates = true,
+})
+
+local spaceConfigs <const> = {
+{% for name, ws in window_manager.workspaces.items() %}
+ ["{{ name }}"] = { icon = "{{ ws.icon }}", name = "{{ name }}" },
+{% endfor %}
+}
+
+local function selectCurrentWorkspace(focusedWorkspaceName)
+ for sid, item in pairs(spaces) do
+ if item ~= nil then
+ local isSelected = sid == constants.items.SPACES .. "." .. focusedWorkspaceName
+ item:set({
+ icon = { color = isSelected and settings.colors.bg1 or settings.colors.white },
+ label = { color = isSelected and settings.colors.bg1 or settings.colors.white },
+ background = { color = isSelected and settings.colors.white or settings.colors.bg1 },
+ })
+ end
+ end
+
+ sbar.trigger(constants.events.UPDATE_WINDOWS)
+end
+
+local function findAndSelectCurrentWorkspace()
+ sbar.exec(constants.aerospace.GET_CURRENT_WORKSPACE, function(focusedWorkspaceOutput)
+ local focusedWorkspaceName = focusedWorkspaceOutput:match("[^\r\n]+")
+ selectCurrentWorkspace(focusedWorkspaceName)
+ end)
+end
+
+local function addWorkspaceItem(workspaceName)
+ local spaceName = constants.items.SPACES .. "." .. workspaceName
+ local spaceConfig = spaceConfigs[workspaceName]
+
+ spaces[spaceName] = sbar.add("item", spaceName, {
+ label = {
+ width = 0,
+ padding_left = 0,
+ string = spaceConfig.name,
+ },
+ icon = {
+ string = spaceConfig.icon or settings.icons.apps["default"],
+ color = settings.colors.white,
+ },
+ background = {
+ color = settings.colors.bg1,
+ },
+ click_script = "aerospace workspace " .. workspaceName,
+ })
+
+ spaces[spaceName]:subscribe("mouse.entered", function(env)
+ sbar.animate("tanh", 30, function()
+ spaces[spaceName]:set({ label = { width = "dynamic" } })
+ end)
+ end)
+
+ spaces[spaceName]:subscribe("mouse.exited", function(env)
+ sbar.animate("tanh", 30, function()
+ spaces[spaceName]:set({ label = { width = 0 } })
+ end)
+ end)
+
+ sbar.add("item", spaceName .. ".padding", {
+ width = settings.dimens.padding.label
+ })
+end
+
+local function createWorkspaces()
+ {% for name, ws in window_manager.workspaces.items() | sort(attribute='1.order') %}
+ addWorkspaceItem("{{ name }}")
+ {% endfor %}
+
+ findAndSelectCurrentWorkspace()
+end
+
+swapWatcher:subscribe(constants.events.SWAP_MENU_AND_SPACES, function(env)
+ local isShowingSpaces = env.isShowingMenu == "off" and true or false
+ sbar.set("/" .. constants.items.SPACES .. "\\..*/", { drawing = isShowingSpaces })
+end)
+
+currentWorkspaceWatcher:subscribe(constants.events.AEROSPACE_WORKSPACE_CHANGED, function(env)
+ selectCurrentWorkspace(env.FOCUSED_WORKSPACE)
+ sbar.trigger(constants.events.UPDATE_WINDOWS)
+end)
+
+createWorkspaces()
diff --git a/dots/sketchybar/.config/sketchybar/items/widgets/battery.lua b/dots/sketchybar/.config/sketchybar/items/widgets/battery.lua
new file mode 100644
index 0000000..32546f0
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/widgets/battery.lua
@@ -0,0 +1,91 @@
+local constants = require("constants")
+local settings = require("config.settings")
+
+local isCharging = false
+
+local battery = sbar.add("item", constants.items.battery, {
+ position = "right",
+ update_freq = 60,
+})
+
+local batteryPopup = sbar.add("item", {
+ position = "popup." .. battery.name,
+ width = "dynamic",
+ label = {
+ padding_right = settings.dimens.padding.label,
+ padding_left = settings.dimens.padding.label,
+ },
+ icon = {
+ padding_left = 0,
+ padding_right = 0,
+ },
+})
+
+battery:subscribe({ "routine", "power_source_change", "system_woke" }, function()
+ sbar.exec("pmset -g batt", function(batteryInfo)
+ local icon = "!"
+ local label = "?"
+
+ local found, _, charge = batteryInfo:find("(%d+)%%")
+ if found then
+ charge = tonumber(charge)
+ label = charge .. "%"
+ end
+
+ local color = settings.colors.green
+ local charging, _, _ = batteryInfo:find("AC Power")
+
+ isCharging = charging
+
+ if charging then
+ icon = settings.icons.text.battery.charging
+ else
+ if found and charge > 80 then
+ icon = settings.icons.text.battery._100
+ elseif found and charge > 60 then
+ icon = settings.icons.text.battery._75
+ elseif found and charge > 40 then
+ icon = settings.icons.text.battery._50
+ elseif found and charge > 30 then
+ icon = settings.icons.text.battery._50
+ color = settings.colors.yellow
+ elseif found and charge > 20 then
+ icon = settings.icons.text.battery._25
+ color = settings.colors.orange
+ else
+ icon = settings.icons.text.battery._0
+ color = settings.colors.red
+ end
+ end
+
+ local lead = ""
+ if found and charge < 10 then
+ lead = "0"
+ end
+
+ battery:set({
+ icon = {
+ string = icon,
+ color = color
+ },
+ label = {
+ string = lead .. label,
+ padding_left = 0,
+ },
+ })
+ end)
+end)
+
+battery:subscribe("mouse.clicked", function(env)
+ local drawing = battery:query().popup.drawing
+
+ battery:set({ popup = { drawing = "toggle" } })
+
+ if drawing == "off" then
+ sbar.exec("pmset -g batt", function(batteryInfo)
+ local found, _, remaining = batteryInfo:find("(%d+:%d+) remaining")
+ local label = found and ("Time remaining: " .. remaining .. "h") or (isCharging and "Charging" or "No estimate")
+ batteryPopup:set({ label = label })
+ end)
+ end
+end)
diff --git a/dots/sketchybar/.config/sketchybar/items/widgets/calendar.lua b/dots/sketchybar/.config/sketchybar/items/widgets/calendar.lua
new file mode 100644
index 0000000..436591d
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/widgets/calendar.lua
@@ -0,0 +1,17 @@
+local constants = require("constants")
+
+local calendar = sbar.add("item", constants.items.CALENDAR, {
+ position = "right",
+ update_freq = 1,
+ icon = { padding_left = 0, padding_right = 0 }
+})
+
+calendar:subscribe({ "forced", "routine", "system_woke" }, function(env)
+ calendar:set({
+ label = os.date("%a %d %b, %H:%M"),
+ })
+end)
+
+calendar:subscribe("mouse.clicked", function(env)
+ sbar.exec("open -a 'Calendar'")
+end)
diff --git a/dots/sketchybar/.config/sketchybar/items/widgets/init.lua b/dots/sketchybar/.config/sketchybar/items/widgets/init.lua
new file mode 100644
index 0000000..8e9631c
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/widgets/init.lua
@@ -0,0 +1,4 @@
+require("items.widgets.calendar")
+require("items.widgets.battery")
+require("items.widgets.volume")
+require("items.widgets.wifi")
diff --git a/dots/sketchybar/.config/sketchybar/items/widgets/volume.lua b/dots/sketchybar/.config/sketchybar/items/widgets/volume.lua
new file mode 100644
index 0000000..7a24847
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/widgets/volume.lua
@@ -0,0 +1,128 @@
+local constants = require("constants")
+local settings = require("config.settings")
+
+local currentAudioDevice = "None"
+
+local volumeValue = sbar.add("item", constants.items.VOLUME .. ".value", {
+ position = "right",
+ label = {
+ string = "??%",
+ padding_left = 0,
+ },
+})
+
+local volumeBracket = sbar.add("bracket", constants.items.VOLUME .. ".bracket", { volumeValue.name }, {
+ popup = {
+ align = "center"
+ },
+})
+
+local volumeSlider = sbar.add("slider", constants.items.VOLUME .. ".slider", settings.dimens.graphics.popup.width, {
+ position = "popup." .. volumeBracket.name,
+ click_script = 'osascript -e "set volume output volume $PERCENTAGE"'
+})
+
+volumeValue:subscribe("volume_change", function(env)
+ local icon = settings.icons.text.volume._0
+ local volume = tonumber(env.INFO)
+
+ sbar.exec("SwitchAudioSource -t output -c", function(result)
+ -- local currentOutputDevice = result:sub(1, -2)
+ -- if currentOutputDevice == "AirPods Max" then
+ -- icon = "􀺹"
+ -- elseif currentOutputDevice == "AirPods von Longdong Silver" or currentOutputDevice == "AirPods von Anna" then
+ -- icon = "􀟥"
+ -- elseif currentOutputDevice == "Arctis Nova Pro Wireless" then
+ -- icon = "􀑈"
+ -- elseif currentOutputDevice == "Ear (2)" then
+ -- icon = "􀪷"
+ -- elseif currentOutputDevice == "iD4" then
+ -- icon = "􀝎"
+ -- else
+ if volume > 60 then
+ icon = settings.icons.text.volume._100
+ elseif volume > 30 then
+ icon = settings.icons.text.volume._66
+ elseif volume > 10 then
+ icon = settings.icons.text.volume._33
+ elseif volume > 0 then
+ icon = settings.icons.text.volume._10
+ end
+ -- end
+
+ local lead = ""
+ if volume < 10 then
+ lead = "0"
+ end
+
+ -- volumeIcon:set({ label = icon })
+ volumeSlider:set({ slider = { percentage = volume } })
+
+ local hasVolume = volume ~= 0
+ volumeValue:set({
+ icon = icon,
+ label = {
+ string = hasVolume and lead .. volume .. "%" or "",
+ padding_right = hasVolume and 8 or 0,
+ },
+ })
+ end)
+end)
+
+local function hideVolumeDetails()
+ local drawing = volumeBracket:query().popup.drawing == "on"
+ if not drawing then return end
+ volumeBracket:set({ popup = { drawing = false } })
+ sbar.remove("/" .. constants.items.VOLUME .. ".device\\.*/")
+end
+
+local function toggleVolumeDetails(env)
+ if env.BUTTON == "right" then
+ sbar.exec("open /System/Library/PreferencePanes/Sound.prefpane")
+ return
+ end
+
+ local shouldDraw = volumeBracket:query().popup.drawing == "off"
+ if shouldDraw then
+ volumeBracket:set({ popup = { drawing = true } })
+
+ sbar.exec("SwitchAudioSource -t output -c", function(result)
+ currentAudioDevice = result:sub(1, -2)
+
+ sbar.exec("SwitchAudioSource -a -t output", function(available)
+ local current = currentAudioDevice
+ local counter = 0
+
+ for device in string.gmatch(available, '[^\r\n]+') do
+ local color = settings.colors.grey
+ if current == device then
+ color = settings.colors.white
+ end
+
+ sbar.add("item", constants.items.VOLUME .. ".device." .. counter, {
+ position = "popup." .. volumeBracket.name,
+ align = "center",
+ label = { string = device, color = color },
+ click_script = 'SwitchAudioSource -s "' ..
+ device ..
+ '" && sketchybar --set /' .. constants.items.VOLUME .. '.device\\.*/ label.color=' ..
+ settings.colors.grey .. ' --set $NAME label.color=' .. settings.colors.white
+
+ })
+ counter = counter + 1
+ end
+ end)
+ end)
+ else
+ hideVolumeDetails()
+ end
+end
+
+local function changeVolume(env)
+ local delta = env.SCROLL_DELTA
+ sbar.exec('osascript -e "set volume output volume (output volume of (get volume settings) + ' .. delta .. ')"')
+end
+
+volumeValue:subscribe("mouse.clicked", toggleVolumeDetails)
+volumeValue:subscribe("mouse.scrolled", changeVolume)
+-- volumeValue:subscribe("mouse.exited.global", hideVolumeDetails)
diff --git a/dots/sketchybar/.config/sketchybar/items/widgets/wifi.lua b/dots/sketchybar/.config/sketchybar/items/widgets/wifi.lua
new file mode 100644
index 0000000..551a4da
--- /dev/null
+++ b/dots/sketchybar/.config/sketchybar/items/widgets/wifi.lua
@@ -0,0 +1,261 @@
+local constants = require("constants")
+local settings = require("config.settings")
+
+local popupWidth <const> = settings.dimens.graphics.popup.width + 20
+
+sbar.exec(
+ "killall network_load >/dev/null; $CONFIG_DIR/bridge/network_load/bin/network_load en0 network_update 2.0"
+)
+
+local wifiUp = sbar.add("item", constants.items.WIFI .. ".up", {
+ position = "right",
+ width = 0,
+ icon = {
+ padding_left = 0,
+ padding_right = 0,
+ font = {
+ style = settings.fonts.styles.bold,
+ size = 10.0,
+ },
+ string = settings.icons.text.wifi.upload,
+ },
+ label = {
+ font = {
+ family = settings.fonts.numbers,
+ style = settings.fonts.styles.bold,
+ size = 10.0,
+ },
+ color = settings.colors.orange,
+ string = "??? Bps",
+ },
+ y_offset = 4,
+})
+
+local wifiDown = sbar.add("item", constants.items.WIFI .. ".down", {
+ position = "right",
+ icon = {
+ padding_left = 0,
+ padding_right = 0,
+ font = {
+ style = settings.fonts.styles.bold,
+ size = 10.0,
+ },
+ string = settings.icons.text.wifi.download,
+ },
+ label = {
+ font = {
+ family = settings.fonts.numbers,
+ style = settings.fonts.styles.bold,
+ size = 10,
+ },
+ color = settings.colors.blue,
+ string = "??? Bps",
+ },
+ y_offset = -4,
+})
+
+local wifi = sbar.add("item", constants.items.WIFI .. ".padding", {
+ position = "right",
+ label = { drawing = false },
+ padding_right = 0,
+})
+
+local wifiBracket = sbar.add("bracket", constants.items.WIFI .. ".bracket", {
+ wifi.name,
+ wifiUp.name,
+ wifiDown.name
+}, {
+ popup = { align = "center" }
+})
+
+local ssid = sbar.add("item", {
+ align = "center",
+ position = "popup." .. wifiBracket.name,
+ width = popupWidth,
+ height = 16,
+ icon = {
+ string = settings.icons.text.wifi.router,
+ font = {
+ style = settings.fonts.styles.bold
+ },
+ },
+ label = {
+ font = {
+ style = settings.fonts.styles.bold,
+ size = settings.dimens.text.label,
+ },
+ max_chars = 18,
+ string = "????????????",
+ },
+})
+
+local hostname = sbar.add("item", {
+ position = "popup." .. wifiBracket.name,
+ background = {
+ height = 16,
+ },
+ icon = {
+ align = "left",
+ string = "Hostname:",
+ width = popupWidth / 2,
+ font = {
+ size = settings.dimens.text.label
+ },
+ },
+ label = {
+ max_chars = 20,
+ string = "????????????",
+ width = popupWidth / 2,
+ align = "right",
+ }
+})
+
+local ip = sbar.add("item", {
+ position = "popup." .. wifiBracket.name,
+ background = {
+ height = 16,
+ },
+ icon = {
+ align = "left",
+ string = "IP:",
+ width = popupWidth / 2,
+ font = {
+ size = settings.dimens.text.label
+ },
+ },
+ label = {
+ align = "right",
+ string = "???.???.???.???",
+ width = popupWidth / 2,
+ }
+})
+
+local router = sbar.add("item", {
+ position = "popup." .. wifiBracket.name,
+ background = {
+ height = 16,
+ },
+ icon = {
+ align = "left",
+ string = "Router:",
+ width = popupWidth / 2,
+ font = {
+ size = settings.dimens.text.label
+ },
+ },
+ label = {
+ align = "right",
+ string = "???.???.???.???",
+ width = popupWidth / 2,
+ },
+})
+
+sbar.add("item", { position = "right", width = settings.dimens.padding.item })
+
+wifiUp:subscribe("network_update", function(env)
+ local upColor = (env.upload == "000 Bps") and settings.colors.grey or settings.colors.orange
+ local downColor = (env.download == "000 Bps") and settings.colors.grey or settings.colors.blue
+
+ wifiUp:set({
+ icon = { color = upColor },
+ label = {
+ string = env.upload,
+ color = upColor
+ }
+ })
+ wifiDown:set({
+ icon = { color = downColor },
+ label = {
+ string = env.download,
+ color = downColor
+ }
+ })
+end)
+
+wifi:subscribe({ "wifi_change", "system_woke", "forced" }, function(env)
+ wifi:set({
+ icon = {
+ string = settings.icons.text.wifi.disconnected,
+ color = settings.colors.magenta,
+ }
+ })
+
+ sbar.exec([[ipconfig getifaddr en0]], function(ip)
+ local ipConnected = not (ip == "")
+
+ local wifiIcon
+ local wifiColor
+
+ if ipConnected then
+ wifiIcon = settings.icons.text.wifi.connected
+ wifiColor = settings.colors.white
+ end
+
+ wifi:set({
+ icon = {
+ string = wifiIcon,
+ color = wifiColor,
+ }
+ })
+
+ sbar.exec([[sleep 2; scutil --nwi | grep -m1 'utun' | awk '{ print $1 }']], function(vpn)
+ local isVPNConnected = not (vpn == "")
+
+ if isVPNConnected then
+ wifiIcon = settings.icons.text.wifi.vpn
+ wifiColor = settings.colors.green
+ end
+
+ wifi:set({
+ icon = {
+ string = wifiIcon,
+ color = wifiColor,
+ }
+ })
+ end)
+ end)
+end)
+
+local function hideDetails()
+ wifiBracket:set({ popup = { drawing = false } })
+end
+
+local function toggleDetails()
+ local shouldDrawDetails = wifiBracket:query().popup.drawing == "off"
+
+ if shouldDrawDetails then
+ wifiBracket:set({ popup = { drawing = true } })
+ sbar.exec("networksetup -getcomputername", function(result)
+ hostname:set({ label = result })
+ end)
+ sbar.exec("ipconfig getifaddr en0", function(result)
+ ip:set({ label = result })
+ end)
+ sbar.exec("ipconfig getsummary en0 | awk -F ' SSID : ' '/ SSID : / {print $2}'", function(result)
+ ssid:set({ label = result })
+ end)
+ sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Router: ' '/^Router: / {print $2}'", function(result)
+ router:set({ label = result })
+ end)
+ else
+ hideDetails()
+ end
+end
+
+local function copyLabelToClipboard(env)
+ local label = sbar.query(env.NAME).label.value
+ sbar.exec("echo \"" .. label .. "\" | pbcopy")
+ sbar.set(env.NAME, { label = { string = settings.icons.text.clipboard, align = "center" } })
+ sbar.delay(1, function()
+ sbar.set(env.NAME, { label = { string = label, align = "right" } })
+ end)
+end
+
+wifiUp:subscribe("mouse.clicked", toggleDetails)
+wifiDown:subscribe("mouse.clicked", toggleDetails)
+wifi:subscribe("mouse.clicked", toggleDetails)
+
+ssid:subscribe("mouse.clicked", copyLabelToClipboard)
+hostname:subscribe("mouse.clicked", copyLabelToClipboard)
+ip:subscribe("mouse.clicked", copyLabelToClipboard)
+router:subscribe("mouse.clicked", copyLabelToClipboard)