summaryrefslogtreecommitdiff
path: root/lib/notifd/notification.vala
blob: 0b4af06daf56fc508f21583023c05756294fd85f (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
public enum AstalNotifd.Urgency {
    LOW = 0,
    NORMAL = 1,
    CRITICAL = 2,
}

public struct AstalNotifd.Action {
    public string id;
    public string label;
}

public class AstalNotifd.Notification : Object {
    private List<Action?> _actions;
    private HashTable<string, Variant> hints;

    public int64 time { construct set; get; }
    public string app_name { construct set; get; }
    public string app_icon { construct set; get; }
    public string summary { construct set; get; }
    public string body { construct set; get; }
    public uint id { construct set; get; }
    public int expire_timeout { construct set; get; }
    public List<Action?> actions { get { return _actions; } }

    public string image { get { return get_str_hint("image-path"); } }
    public bool action_icons { get { return get_bool_hint("action-icons"); } }
    public string category { get { return get_str_hint("category"); } }
    public string desktop_entry { get { return get_str_hint("desktop-entry"); } }
    public bool resident { get { return get_bool_hint("resident"); } }
    public string sound_file { get { return get_str_hint("sound-file"); } }
    public string sound_name { get { return get_str_hint("sound-name"); } }
    public bool suppress_sound { get { return get_bool_hint("suppress-sound"); } }
    public bool transient { get { return get_bool_hint("transient"); } }
    public int x { get { return get_int_hint("x"); } }
    public int y { get { return get_int_hint("y"); } }
    public Urgency urgency { get { return get_int_hint("urgency"); } }

    internal Notification(
        string app_name,
        uint id,
        string app_icon,
        string summary,
        string body,
        string[] actions,
        HashTable<string, Variant> hints,
        int expire_timeout
    ) {
        Object(
            app_name: app_name,
            id: id,
            app_icon: app_icon,
            summary: summary,
            body: body,
            expire_timeout: expire_timeout,
            time: new DateTime.now_local().to_unix()
        );

        this.hints = hints;
        _actions = new List<Action?>();
        for (var i = 0; i < actions.length; i += 2) {
            _actions.append(Action() {
                id = actions[i],
                label = actions[i + 1]
            });
        }
    }

    public Variant? get_hint(string hint) {
        return hints.contains(hint) ? hints.get(hint) : null;
    }

    public unowned string get_str_hint(string hint) {
        return hints.contains(hint) ? hints.get(hint).get_string() : null;
    }

    public bool get_bool_hint(string hint) {
        return hints.contains(hint) ? hints.get(hint).get_boolean() : false;
    }

    public int get_int_hint(string hint) {
        return hints.contains(hint) ? hints.get(hint).get_int32() : 0;
    }

    public signal void resolved(ClosedReason reason);
    public signal void dismissed();
    public signal void invoked(string action);

    public void dismiss() { dismissed(); }
    public void invoke(string action) { invoked(action); }

    internal Notification.from_json(Json.Object root) throws GLib.Error {
        foreach (var key in root.get_members()) {
            var node = root.get_member(key);
            switch (key) {
                case "id": id = (uint)node.get_int(); break;
                case "time": time = node.get_int(); break;
                case "expire_timeout": expire_timeout = (int)node.get_int(); break;
                case "app_name": app_name = node.get_string(); break;
                case "app_icon": app_icon = node.get_string(); break;
                case "summary": summary = node.get_string(); break;
                case "body": body = node.get_string(); break;
                case "hints":
                    hints = new HashTable<string, Variant>(str_hash, str_equal);
                    var obj = node.get_object();
                    foreach (var hint in obj.get_members()) {
                        hints.set(hint, Json.gvariant_deserialize(obj.get_member(hint), null));
                    }
                    break;
                case "actions":
                    _actions = new List<Action?>();
                    for (var i = 0; i < node.get_array().get_length(); ++i) {
                        var o = node.get_array().get_object_element(i);
                        _actions.append(Action() {
                            id = o.get_member("id").get_string(),
                            label = o.get_member("label").get_string()
                        });
                    }
                    break;
                default: break;
            }
        }
    }

    internal static Notification from_json_string(string json) throws GLib.Error {
        var parser = new Json.Parser();
        parser.load_from_data(json);
        return new Notification.from_json(parser.get_root().get_object());
    }

    public string to_json_string() {
    	var generator = new Json.Generator();
        generator.set_root(to_json());
        return generator.to_data(null);
    }

    internal Json.Node to_json() {
        var acts = new Json.Builder().begin_array();
        foreach (var action in actions) {
            acts.begin_object()
            .set_member_name("id").add_string_value(action.id)
            .set_member_name("label").add_string_value(action.label)
            .end_object();
        }
        acts.end_array();

        return new Json.Builder()
            .begin_object()
            .set_member_name("id").add_int_value(id)
            .set_member_name("time").add_int_value(time)
            .set_member_name("expire_timeout").add_int_value(expire_timeout)
            .set_member_name("app_name").add_string_value(app_name)
            .set_member_name("app_icon").add_string_value(app_icon)
            .set_member_name("summary").add_string_value(summary)
            .set_member_name("body").add_string_value(body)
            .set_member_name("actions").add_value(acts.get_root())
            .set_member_name("hints").add_value(Json.gvariant_serialize(hints))
            .end_object()
            .get_root();
    }
}