aboutsummaryrefslogtreecommitdiff
path: root/lib/Matrix/Response.pm6
blob: edd4d519d9c490aa4141c89a7428d40292c44487 (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
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)
    }
}