aboutsummaryrefslogtreecommitdiff
path: root/.config/awesome/services/common.lua
blob: ad1f9982bd6d1643d45a2ca80244ec50d1ee1c92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
local gfs = require "gears.filesystem"
local gtimer = require "gears.timer"
local phosphor = require "assets.phosphor"
local qjson = require "quarrel.json"
local qmath = require "quarrel.math"
local qnative = require "quarrel.native"
local qstore = require "quarrel.store"
local qvars = require "quarrel.vars"
local UPower = require("lgi").UPowerGlib

--- Register a service
---@param name string
---@param service Service
local function register(name, service)
    gtimer {
        timeout = 1,
        call_now = true,
        autostart = true,
        callback = function()
            local service_result = table.pack(service[1]())
            awesome.emit_signal("services::" .. name, table.unpack(service_result))
            awesome.emit_signal("services::" .. name .. "::icon", service[2](table.unpack(service_result)))
        end,
    }
end

--- Read a file and automatically close it
---@param file FileHandle
---@param format ReadMode?
---@return string | number
local function read(file, format)
    local content = file:read(format or "a")
    file:rewind()
    return content
end

-- create file in case it's not there yet
if not gfs.file_readable "/tmp/wp_audio_status" then
    assert(io.open("/tmp/wp_audio_status", "w")):write("{}"):close()
end

qstore.audio_file = qnative.util.open_file "/tmp/wp_audio_status"
qstore.brightness_file = qnative.util.open_file "/sys/class/backlight/amdgpu_bl1/actual_brightness"
qstore.wifi_file = qnative.util.open_file "/proc/net/wireless"

-- follows the format `service = { provider, icon_provider }`
---@class Service
---@field [1] fun(): ...
---@field [2] fun(...): path: string, color: string

---@type table<string, Service>
local services = {
    audio = {
        -- volume, muted
        function()
            local audio_status = qjson.decode(read(qstore.audio_file))
            local default_sink = audio_status["G435 Wireless Gaming Headset Analog Stereo"]

            if not default_sink then
                return nil, false
            end

            return default_sink.volume, default_sink.muted
        end,
        function(volume, muted)
            if muted or not volume then
                return phosphor.speaker_simple_x_fill, qvars.colors.red
            end

            local icon_data = qmath.step_value(volume, {
                { 0, "slash" },
                { 25, "none" },
                { 50, "low" },
                { 75, "high" },
                { 100 },
            })

            return phosphor["speaker_simple_" .. icon_data .. "_fill"], qvars.colors.fg
        end,
    },
    brightness = {
        -- brightness
        function()
            return read(qstore.brightness_file, "n")
        end,
        function(brightness)
            local icon_data = qmath.step_value(brightness, {
                { 0, "cloud_moon" },
                { 51, "moon" },
                { 102, "sun_horizon" },
                { 153, "sun_dim" },
                { 204, "sun" },
                { 255 },
            })

            return phosphor[icon_data .. "_fill"], qvars.colors.fg
        end,
    },
    wifi = {
        -- essid, strength, connected
        function()
            local lines = qstore.wifi_file:lines()
            qstore.wifi_file:rewind()

            if not lines[3] then
                return nil, 0, false
            end

            local strength = lines[3]:match("^%s*(.*)"):match "^.-%s+.-%s+.-(%S+)%."

            return qnative.net.get_essid(), math.floor(tonumber(strength) * 10 / 7), true
        end,
        function(_, strength, connected)
            if not connected then
                return phosphor.wifi_x_fill, qvars.colors.red
            end

            local icon_data = qmath.step_value(strength, {
                { 0, { "none", "red" } },
                { 25, { "low", "yellow" } },
                { 50, { "medium", "yellow" } },
                { 75, { "high", "green" } },
                { 100 },
            })

            return phosphor["wifi_" .. icon_data[1] .. "_fill"], qvars.colors[icon_data[2]]
        end,
    },
}

for name, service in pairs(services) do
    register(name, service)
end