aboutsummaryrefslogtreecommitdiff
path: root/lib/Matrix/Response.pm6
blob: 14e2b21416cb4eff358faf0ecba7b2198bf52f9f (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
use JSON::Tiny;

unit module Matrix::Response;

class Matrix::Response::Event {
    has %.content;
    has $.type is required;
}

class Matrix::Response::RoomEvent is Matrix::Response::Event {
    has Str $.sender;
    has Int $.origin_server_ts;
    has $.event_id;
    has Str $.room_id;

    method id { $.event_id }
    method timestamp { $!origin_server_ts }
    method room-id { $.room_id }
}

class Matrix::Response::StateEvent is Matrix::Response::RoomEvent {
    has $.prev_content;
    has $.state_key;
}

class Matrix::Response::Timeline {
    has Matrix::Response::Event @.events;
    has Bool $limited;
    has Str $prev-batch;
}

class Matrix::Response::RoomInfo {
    has $.room-id is required;
    has Matrix::Response::Event @.state;
    has Matrix::Response::Timeline $.timeline;

    method gist(--> Str) {
        "<Matrix::Response::RoomInfo: $.room-id>"
    }
}

class Matrix::Response::InviteInfo {
    has $.room-id is required;
    has Matrix::Response::Event @.events;

    method gist(--> Str) {
        "<Matrix::Response::InviteState: $.room-id>"
    }
}

sub gather-events($room-id, $from) {
    gather for $from<events>.List -> $ev {
        take Matrix::Response::StateEvent.new(:room_id($room-id), |$ev);
    }
}

class Matrix::Response::Sync {
    has Str $.next-batch;
    has Matrix::Response::Event @.presence;
    has Matrix::Response::RoomInfo @.joined-rooms;
    has Matrix::Response::InviteInfo @.invited-rooms;

    multi method new(Str $json) {
        return self.new(from-json($json));
    }

    multi method new(Hash $json) {
        my $next-batch = $json<next_batch>;
        my Matrix::Response::Event @presence;
        my Matrix::Response::RoomInfo @joined-rooms;
        my Matrix::Response::InviteInfo @invited-rooms;
        
        for $json<presence><events>.List -> $ev {
            @presence.push(Matrix::Response::Event.new(|$ev));
        }

        for $json<rooms><join>.kv -> $room-id, $data {
            my @state = gather-events($room-id, $data<state>);

            my $timeline = Matrix::Response::Timeline.new(
                limited => $data<timeline><limited>,
                prev-batch => $data<timeline><prev_batch>,
                events => gather-events($room-id, $data<timeline>)
            );

            @joined-rooms.push(Matrix::Response::RoomInfo.new(
                :$room-id, :$timeline, :@state
            ));
        }

        for $json<rooms><invite>.kv -> $room-id, $data {
            my @events = gather-events($room-id, $data<invite_state>);
            @invited-rooms.push(Matrix::Response::InviteInfo.new(
                :$room-id, :@events
            ));
        }

        return self.bless(:$next-batch, :@presence,
                          :@joined-rooms, :@invited-rooms);
    }
}

class Presence {
    has Str $.presence is required;
    has Int $.last-active-ago;
    has Str $.status-message;
    has Bool $.currently-active;

    submethod BUILD(
        Str :$!presence,
        :last_active_ago(:$!last-active-ago) = 0,
        :status_message(:$!status-message) = "",
        :currently_active(:$!currently-active) = False
    ) { }
}

class Tag {
    has @.tags;

    method new(%json) {
        my @tags = %json<tags>.keys;
        self.bless(:@tags)
    }
}


class Matrix::Response::Device {
    has Str $.device-id;
    has $.display-name;
    has $.last-seen-ip;
    has $.last-seen-ts;

    submethod BUILD(
        Str :device_id(:$!device-id),
        :display_name(:$!display-name)?,
        :last_seen_ip(:$!last-seen-ip)?,
        :last_seen_ts(:$!last-seen-ts)?
    ) { }
}