2 local setmetatable
= setmetatable
;
3 local st
= require
"util.stanza";
4 local util
= module
:require
"muc/util";
6 local function get_filtered_presence(stanza
)
7 return util
.filter_muc_x(st
.clone(stanza
));
10 local occupant_mt
= {};
11 occupant_mt
.__index
= occupant_mt
;
13 local function new_occupant(bare_real_jid
, nick
)
15 bare_jid
= bare_real_jid
;
16 nick
= nick
; -- in-room jid
17 sessions
= {}; -- hash from real_jid to presence stanzas. stanzas should not be modified
19 jid
= nil; -- Primary session
23 -- Deep copy an occupant
24 local function copy_occupant(occupant
)
26 for full_jid
, presence_stanza
in pairs(occupant
.sessions
) do
27 -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session
28 if presence_stanza
.attr
.type ~= "unavailable" or full_jid
== occupant
.jid
then
29 sessions
[full_jid
] = presence_stanza
;
33 bare_jid
= occupant
.bare_jid
;
41 -- finds another session to be the primary (there might not be one)
42 function occupant_mt
:choose_new_primary()
43 for jid
, pr
in self
:each_session() do
44 if pr
.attr
.type == nil then
51 function occupant_mt
:set_session(real_jid
, presence_stanza
, replace_primary
)
52 local pr
= get_filtered_presence(presence_stanza
);
53 pr
.attr
.from
= self
.nick
;
54 pr
.attr
.to
= real_jid
;
56 self
.sessions
[real_jid
] = pr
;
57 if replace_primary
then
59 elseif self
.jid
== nil or (pr
.attr
.type == "unavailable" and self
.jid
== real_jid
) then
60 -- Only leave an unavailable presence as primary when there are no other options
61 self
.jid
= self
:choose_new_primary() or real_jid
;
65 function occupant_mt
:remove_session(real_jid
)
66 -- Delete original session
67 self
.sessions
[real_jid
] = nil;
68 if self
.jid
== real_jid
then
69 self
.jid
= self
:choose_new_primary();
73 function occupant_mt
:each_session()
74 return pairs(self
.sessions
)
77 function occupant_mt
:get_presence(real_jid
)
78 return self
.sessions
[real_jid
or self
.jid
]