wobin@18: local Model = Squawk.Model wobin@18: local Settings = Model.UserSettings wobin@18: local Controller = Squawk.Controller wobin@18: local View = Squawk.View wobin@18: wobin@18: wobin@18: -- Model -- wobin@18: --[[ wobin@18: --Each Squawk will have the following information: wobin@18: -- * Owner (Name) wobin@18: -- * Time (Epoch) wobin@18: -- * Message (140 characters) wobin@18: -- * ReplyTo (Name) wobin@18: -- * Related (Names) wobin@18: -- wobin@18: -- Each User will have the following lists: wobin@18: -- * Follower wobin@18: -- * Following wobin@18: -- * Blocked wobin@18: -- * Pending (Requests to follow that you haven't acted on) wobin@18: -- * Requested (Requests to follow that you have made) wobin@18: -- * Privacy State wobin@18: -- wobin@18: -- A user can only request to follow an online person. Requests can be approved wobin@18: -- on or offline, but the initial request must be made online. wobin@18: -- wobin@18: -- When a user makes a request to follow a private user, the subsequent paths occur: wobin@18: -- - Followee is added to Settings.Requested wobin@18: -- - Followee receives 'follow request' -> (their) Settings.Pending wobin@18: -- - Followee acts on request -> (their) Settings.Pending cleared wobin@18: -- 1) Follwer is online wobin@18: -- - Follower receives 'request accepted' -> Added to Settings.Following and wobin@18: -- cleared from Settings.Requested wobin@18: -- 2) Follower is offline wobin@18: -- - The next time Follower is online and recieves a Squawk we check if there wobin@18: -- is a Settings.Requested for that name, and if so assume they have approved wobin@18: -- and clear/add records appropriately. wobin@18: -- wobin@18: -- For updating, there can be a few methods. wobin@18: -- wobin@18: -- Guild open: you're not private, you broadcast to the guild your last X wobin@18: -- squawks on login wobin@18: -- wobin@18: -- followers: wobin@18: --]] wobin@18: Model.Squawks = {} wobin@18: local Squawks = Model.Squawks wobin@18: Squawks.Main = {} wobin@18: Squawks.Owners = {} wobin@18: wobin@18: local function wrap(str, limit) wobin@18: limit = limit or 72 wobin@18: local here = 1 wobin@18: return str:gsub("(%s+)()(%S+)()", wobin@18: function(sp, st, word, fi) wobin@18: if fi-here > limit then wobin@18: here = st wobin@18: return "\n"..word wobin@18: end wobin@18: end) wobin@18: end wobin@18: wobin@18: function Squawks:new(Message, Owner) wobin@18: local o = {} wobin@18: o.Owner = Owner or UnitName("player") wobin@18: o.Message = wrap(Message) wobin@18: o.Time = time() wobin@18: local reply, to = strsplit("@", ((strsplit(" ", Message)))) wobin@18: if reply == "" then wobin@18: o.ReplyTo = to wobin@18: end wobin@18: wobin@18: o.Related = {} wobin@18: wobin@18: for word in string.gmatch(Message, "@(%a+)") do wobin@18: if word ~= o.ReplyTo or "" then wobin@18: table.insert(o.Related, word) wobin@18: end wobin@18: end wobin@18: wobin@18: if #o.Related == 0 then wobin@18: o.Related = nil wobin@18: end wobin@18: wobin@18: table.insert(self.Main, o) wobin@18: wobin@18: if not self.Owners[Owner] then wobin@18: self.Owners[Owner] = {} wobin@18: end wobin@18: table.insert(self.Owners[Owner], o) wobin@18: return o wobin@18: end wobin@18: wobin@18: function Squawks:Reload() wobin@18: for _,squawk in ipairs(Model.Squawks.Main) do wobin@18: if not self.Owners[squawk.Owner] then wobin@18: self.Owners[squawk.Owner] = {} wobin@18: end wobin@18: table.insert(self.Owners[squawk.Owner], squawk) wobin@18: if squawk.Related and #squawk.Related == 0 then wobin@18: squawk.Related = nil wobin@18: end wobin@18: end wobin@18: end wobin@18: wobin@18: function Squawks:Sort(Squawks) wobin@18: table.sort(Squawks or self.Main, function(a,b) return a.Time > b.Time end) wobin@18: return Squawks or self.Main wobin@18: end wobin@18: wobin@18: function Squawks:GetOwn(Squawks) wobin@18: local mine = {} wobin@18: for _, squawk in ipairs(Squawks or self.Main) do wobin@18: if squawk.Owner == UnitName("player") then wobin@18: table.insert(mine, squawk) wobin@18: end wobin@18: end wobin@18: return self:Sort(mine) wobin@18: end wobin@18: wobin@18: function Squawks:GetLast10(Squawks) wobin@18: local mine = {} wobin@18: Squawks = Squawks or self.Main wobin@18: local limit = #Squawks < 10 and #Squawks or 10 wobin@18: wobin@18: Squawks = self:Sort(Squawks) wobin@18: wobin@18: for i=1,limit do wobin@18: table.insert(mine, Squawks[i]) wobin@18: end wobin@18: return mine wobin@18: end wobin@18: wobin@18: -- initially called with no arguments to get the latest timestamp of wobin@18: -- my squawks, or with a name to find the latest timestamp of all wobin@18: -- squawks from that user wobin@18: function Squawks:GetLatestTimestamp(Name, Squawks) wobin@18: if Name then wobin@18: if self.Owners[Name] then wobin@18: return self:GetLatestTimestamp(nil, self.Owners[Name]) wobin@18: else wobin@18: return -1 -- No squawks exist for that name in our records wobin@18: end wobin@18: end wobin@18: wobin@18: Squawks = Squawks or self.Main or {} wobin@18: local latest = self:Sort(Squawks) wobin@18: return latest and #latest > 0 and latest[1].Time or -1 wobin@18: end wobin@18: wobin@18: function Squawks:GetLatestSquawks(Timestamp) wobin@18: local latest = {} wobin@18: for i, squawk in ipairs(self:Sort()) do wobin@18: if squawk.Time > Timestamp and i < 10 then wobin@18: table.insert(latest, squawk) wobin@18: else wobin@18: return latest wobin@18: end wobin@18: end wobin@18: end wobin@18: wobin@18: function Settings:IsPrivate() wobin@18: return Settings.Private wobin@18: end wobin@18: wobin@18: function Settings:TogglePrivate() wobin@18: Settings.Private = not Settings.Private wobin@18: end wobin@18: wobin@18: function Settings:AddFollower(Name) wobin@18: Settings.Follower[Name] = 1 wobin@18: self:RemovePending(Name) wobin@18: end wobin@18: wobin@18: function Settings:AddFollowing(Name) wobin@18: Settings.Following[Name] = 1 wobin@18: self:RemoveRequested(Name) wobin@18: end wobin@18: wobin@18: function Settings:AddBlock(Name) wobin@18: Settings.Blocked[Name] = 1 wobin@18: self:RemoveFollower(Name) wobin@18: self:RemoveFollowing(Name) wobin@18: end wobin@18: wobin@18: function Settings:AddPending(Name) wobin@18: Settings.Pending[Name] = 1 wobin@18: end wobin@18: wobin@18: function Settings:AddRequested(Name) wobin@18: Settings.Requested[Name] = 1 wobin@18: end wobin@18: wobin@18: function Settings:RemoveFollower(Name) wobin@18: if Settings.Follower[Name] then wobin@18: Settings.Follower[Name] = nil wobin@18: end wobin@18: end wobin@18: wobin@18: function Settings:RemoveFollowing(Name) wobin@18: if Settings.Following[Name] then wobin@18: Settings.Following[Name] = nil wobin@18: end wobin@18: end wobin@18: wobin@18: function Settings:RemoveBlock(Name) wobin@18: if Settings.Blocked[Name] then wobin@18: Settings.Blocked[Name] = nil wobin@18: end wobin@18: end wobin@18: wobin@18: function Settings:RemovePending(Name) wobin@18: if Settings.Pending[Name] then wobin@18: Settings.Pending[Name] = nil wobin@18: end wobin@18: end wobin@18: wobin@18: function Settings:RemoveRequested(Name) wobin@18: if Settings.Requested[Name] then wobin@18: Settings.Requested[Name] = nil wobin@18: end wobin@18: end