summaryrefslogtreecommitdiff
path: root/services/Bluetooth.qml
blob: 0769095b6f8c6f8dc19dbc5d606b75af254f86e3 (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
pragma Singleton

import Quickshell
import Quickshell.Io
import QtQuick

Singleton {
    id: root

    property bool powered
    property bool discovering
    readonly property list<Device> devices: []

    Process {
        running: true
        command: ["bluetoothctl"]
        stdout: SplitParser {
            onRead: {
                getInfo.running = true;
                getDevices.running = true;
            }
        }
    }

    Process {
        id: getInfo

        running: true
        command: ["bluetoothctl", "show"]
        environment: ({
                LANG: "C",
                LC_ALL: "C"
            })
        stdout: StdioCollector {
            onStreamFinished: {
                root.powered = text.includes("Powered: yes");
                root.discovering = text.includes("Discovering: yes");
            }
        }
    }

    Process {
        id: getDevices

        running: true
        command: ["fish", "-c", `
            for a in (bluetoothctl devices)
                if string match -q 'Device *' $a
                    bluetoothctl info $addr (string split ' ' $a)[2]
                    echo
                end
            end`]
        environment: ({
                LANG: "C",
                LC_ALL: "C"
            })
        stdout: StdioCollector {
            onStreamFinished: {
                const devices = text.trim().split("\n\n").map(d => ({
                            name: d.match(/Name: (.*)/)[1],
                            alias: d.match(/Alias: (.*)/)[1],
                            address: d.match(/Device ([0-9A-Z:]{17})/)[1],
                            icon: d.match(/Icon: (.*)/)[1],
                            connected: d.includes("Connected: yes"),
                            paired: d.includes("Paired: yes"),
                            trusted: d.includes("Trusted: yes")
                        }));
                const rDevices = root.devices;

                const destroyed = rDevices.filter(rd => !devices.find(d => d.address === rd.address));
                for (const device of destroyed)
                    rDevices.splice(rDevices.indexOf(device), 1).forEach(d => d.destroy());

                for (const device of devices) {
                    const match = rDevices.find(d => d.address === device.address);
                    if (match) {
                        match.lastIpcObject = device;
                    } else {
                        rDevices.push(deviceComp.createObject(root, {
                            lastIpcObject: device
                        }));
                    }
                }
            }
        }
    }

    component Device: QtObject {
        required property var lastIpcObject
        readonly property string name: lastIpcObject.name
        readonly property string alias: lastIpcObject.alias
        readonly property string address: lastIpcObject.address
        readonly property string icon: lastIpcObject.icon
        readonly property bool connected: lastIpcObject.connected
        readonly property bool paired: lastIpcObject.paired
        readonly property bool trusted: lastIpcObject.trusted
    }

    Component {
        id: deviceComp

        Device {}
    }
}