view Model.lua @ 18:a3328fffef5c

Split of main file into components
author wobin
date Thu, 07 May 2009 02:52:23 +1000
parents
children 431f2fce08f2
line wrap: on
line source
local Model = Squawk.Model
local Settings = Model.UserSettings
local Controller = Squawk.Controller
local View = Squawk.View


-- Model --
--[[
--Each Squawk will have the following information:
-- * Owner (Name)
-- * Time (Epoch)
-- * Message (140 characters)
-- * ReplyTo (Name)
-- * Related (Names)
--
-- Each User will have the following lists:
-- * Follower
-- * Following
-- * Blocked
-- * Pending (Requests to follow that you haven't acted on)
-- * Requested (Requests to follow that you have made)
-- * Privacy State
--
-- A user can only request to follow an online person. Requests can be approved
-- on or offline, but the initial request must be made online.
--
-- When a user makes a request to follow a private user, the subsequent paths occur:
-- - Followee is added to Settings.Requested 
-- - Followee receives 'follow request' -> (their) Settings.Pending
-- - Followee acts on request -> (their) Settings.Pending cleared
--  1) Follwer is online
--		- Follower receives 'request accepted' -> Added to Settings.Following and
--		cleared from Settings.Requested
--  2) Follower is offline
--		- The next time Follower is online and recieves a Squawk we check if there
--		is a Settings.Requested for that name, and if so assume they have approved
--		and clear/add records appropriately.
--
--		For updating, there can be a few methods.
--
--		Guild open: you're not private, you broadcast to the guild your last X
--		squawks on login
--
--		followers:
--]]
Model.Squawks = {}
local Squawks = Model.Squawks
Squawks.Main = {}
Squawks.Owners = {}

local function wrap(str, limit)
  limit = limit or 72
  local here = 1
  return str:gsub("(%s+)()(%S+)()",
                          function(sp, st, word, fi)
                            if fi-here > limit then
                              here = st 
                              return "\n"..word
                            end
                          end)
end

function Squawks:new(Message, Owner)
	local o = {}
	o.Owner = Owner or UnitName("player")
	o.Message = wrap(Message)
	o.Time = time()
	local reply, to = strsplit("@", ((strsplit(" ", Message))))
	if reply == "" then
		o.ReplyTo = to
	end

	o.Related = {}

	for word in string.gmatch(Message, "@(%a+)") do
		if word ~= o.ReplyTo or "" then
			table.insert(o.Related, word)
		end
	end
	
	if #o.Related == 0 then
		o.Related = nil
	end

	table.insert(self.Main, o)
	
	if not self.Owners[Owner] then
		self.Owners[Owner] = {}
	end
	table.insert(self.Owners[Owner], o)
	return o
end

function Squawks:Reload()
	for _,squawk in ipairs(Model.Squawks.Main) do
		if not self.Owners[squawk.Owner] then
			self.Owners[squawk.Owner] = {}
		end
		table.insert(self.Owners[squawk.Owner], squawk)
		if squawk.Related and #squawk.Related == 0 then
			squawk.Related = nil
		end
	end
end

function Squawks:Sort(Squawks)
	table.sort(Squawks or self.Main, function(a,b) return a.Time > b.Time end)
	return Squawks or self.Main
end

function Squawks:GetOwn(Squawks)
	local mine = {}
	for _, squawk in ipairs(Squawks or self.Main) do
		if squawk.Owner == UnitName("player") then
			table.insert(mine, squawk)
		end
	end
	return self:Sort(mine)
end

function Squawks:GetLast10(Squawks)
	local mine = {}
	Squawks = Squawks or self.Main
	local limit = #Squawks < 10 and #Squawks or 10
	
	Squawks = self:Sort(Squawks)

	for i=1,limit do
		table.insert(mine, Squawks[i])
	end
	return mine
end

-- initially called with no arguments to get the latest timestamp of 
-- my squawks, or with a name to find the latest timestamp of all 
-- squawks from that user
function Squawks:GetLatestTimestamp(Name, Squawks)
	if Name then
		if self.Owners[Name] then
			return self:GetLatestTimestamp(nil, self.Owners[Name])
		else
			return -1 -- No squawks exist for that name in our records
		end
	end

	Squawks = Squawks or self.Main or {}
	local latest = self:Sort(Squawks)
	return latest and #latest > 0 and latest[1].Time or -1
end

function Squawks:GetLatestSquawks(Timestamp)
	local latest = {}
	for i, squawk in ipairs(self:Sort()) do
		if squawk.Time > Timestamp and i < 10 then
			table.insert(latest, squawk)
		else
			return latest
		end
	end
end

function Settings:IsPrivate()
	return Settings.Private
end

function Settings:TogglePrivate()
	Settings.Private = not Settings.Private
end

function Settings:AddFollower(Name)
	Settings.Follower[Name] = 1
	self:RemovePending(Name)
end

function Settings:AddFollowing(Name)
	Settings.Following[Name] = 1
	self:RemoveRequested(Name)
end

function Settings:AddBlock(Name)
	Settings.Blocked[Name] = 1
	self:RemoveFollower(Name)
	self:RemoveFollowing(Name)
end

function Settings:AddPending(Name)
	Settings.Pending[Name] = 1
end

function Settings:AddRequested(Name)
	Settings.Requested[Name] = 1
end

function Settings:RemoveFollower(Name)
	if Settings.Follower[Name] then
		Settings.Follower[Name] = nil
	end
end

function Settings:RemoveFollowing(Name)
	if Settings.Following[Name] then
		Settings.Following[Name] = nil
	end
end

function Settings:RemoveBlock(Name)
	if Settings.Blocked[Name] then
		Settings.Blocked[Name] = nil
	end
end

function Settings:RemovePending(Name)
	if Settings.Pending[Name] then
		Settings.Pending[Name] = nil
	end
end

function Settings:RemoveRequested(Name)
	if Settings.Requested[Name] then
		Settings.Requested[Name] = nil
	end
end