Comparison

plugins/muc/occupant.lib.lua @ 6210:e9d62fff82a8

plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
author daurnimator <quae@daurnimator.com>
date Wed, 02 Apr 2014 18:37:52 -0400
parent 6179:e488a90195bc
child 6251:41a5e5205fd9
comparison
equal deleted inserted replaced
6209:cc00e78e6a31 6210:e9d62fff82a8
34 34
35 -- Deep copy an occupant 35 -- Deep copy an occupant
36 local function copy_occupant(occupant) 36 local function copy_occupant(occupant)
37 local sessions = {}; 37 local sessions = {};
38 for full_jid, presence_stanza in pairs(occupant.sessions) do 38 for full_jid, presence_stanza in pairs(occupant.sessions) do
39 if presence_stanza.attr.type ~= "unavailable" then 39 -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session
40 if presence_stanza.attr.type ~= "unavailable" or full_jid == occupant.jid then
40 sessions[full_jid] = presence_stanza; 41 sessions[full_jid] = presence_stanza;
41 end 42 end
42 end 43 end
43 return setmetatable({ 44 return setmetatable({
44 bare_jid = occupant.bare_jid; 45 bare_jid = occupant.bare_jid;
47 role = occupant.role; 48 role = occupant.role;
48 jid = occupant.jid; 49 jid = occupant.jid;
49 }, occupant_mt); 50 }, occupant_mt);
50 end 51 end
51 52
53 -- finds another session to be the primary (there might not be one)
54 function occupant_mt:choose_new_primary()
55 for jid, pr in self:each_session() do
56 if pr.attr.type ~= "unavailable" then
57 return jid;
58 end
59 end
60 return nil;
61 end
62
52 function occupant_mt:set_session(real_jid, presence_stanza, replace_primary) 63 function occupant_mt:set_session(real_jid, presence_stanza, replace_primary)
53 local pr = get_filtered_presence(presence_stanza); 64 local pr = get_filtered_presence(presence_stanza);
54 pr.attr.from = self.nick; 65 pr.attr.from = self.nick;
55 pr.attr.to = real_jid; 66 pr.attr.to = real_jid;
56 67
57 self.sessions[real_jid] = pr; 68 self.sessions[real_jid] = pr;
58 if replace_primary or self.jid == nil then 69 if replace_primary then
59 self.jid = real_jid; 70 self.jid = real_jid;
71 elseif self.jid == nil or (pr.attr.type == "unavailable" and self.jid == real_jid) then
72 -- Only leave an unavailable presence as primary when there are no other options
73 self.jid = self:choose_new_primary() or real_jid;
60 end 74 end
61 end 75 end
62 76
63 function occupant_mt:remove_session(real_jid) 77 function occupant_mt:remove_session(real_jid)
64 -- Delete original session 78 -- Delete original session
65 local presence_stanza = self.sessions[real_jid];
66 self.sessions[real_jid] = nil; 79 self.sessions[real_jid] = nil;
67 if self.jid == real_jid then 80 if self.jid == real_jid then
68 -- find another session to be the primary (might be nil) 81 self.jid = self:choose_new_primary();
69 self.jid = next(self.sessions);
70 end 82 end
71 end 83 end
72 84
73 function occupant_mt:each_session() 85 function occupant_mt:each_session()
74 return pairs(self.sessions) 86 return pairs(self.sessions)