wobin@0
|
1 -- A Twitter client of sorts for World of Warcraft
|
wobin@0
|
2 -- Author: Wobin
|
wobin@0
|
3 -- Email: wobster@gmail.com
|
wobin@0
|
4 --
|
wobin@1
|
5 Squawk = LibStub("AceAddon-3.0"):NewAddon("Squawk")
|
wobin@0
|
6
|
wobin@0
|
7 Squawk.Model = {}
|
wobin@0
|
8 Squawk.View = {}
|
wobin@0
|
9 Squawk.Controller = {}
|
wobin@0
|
10
|
wobin@0
|
11 local Model = Squawk.Model
|
wobin@0
|
12 local View = Squawk.View
|
wobin@0
|
13 local Controller = Squawk.Controller
|
wobin@0
|
14
|
wobin@0
|
15 Model.UserSettings = {}
|
wobin@0
|
16 local Settings = Model.UserSettings
|
wobin@0
|
17
|
wobin@0
|
18 local defaults = {
|
wobin@0
|
19 profile = {
|
wobin@0
|
20 Squawks = {},
|
wobin@0
|
21 Follower = {},
|
wobin@0
|
22 Following = {},
|
wobin@7
|
23 Pending = {},
|
wobin@7
|
24 Requested = {},
|
wobin@0
|
25 Blocked = {},
|
wobin@0
|
26 }
|
wobin@0
|
27 }
|
wobin@0
|
28
|
wobin@0
|
29 function Squawk:OnInitialize()
|
wobin@0
|
30 Model.db = LibStub("AceDB-3.0"):New("SquawkDB", defaults)
|
wobin@4
|
31 Model.Squawks = Model.db.profile.Squawks
|
wobin@0
|
32 Settings.Follower = Model.db.profile.Follower
|
wobin@0
|
33 Settings.Following = Model.db.profile.Following
|
wobin@7
|
34 Settings.Pending = Model.db.profile.Pending
|
wobin@7
|
35 Settings.Requested = Model.db.profile.Requested
|
wobin@0
|
36 Settings.Blocked = Model.db.profile.Blocked
|
wobin@0
|
37 Settings.Private = Model.db.profile.Private
|
wobin@0
|
38
|
wobin@0
|
39 LibStub("AceComm-3.0"):Embed(Controller)
|
wobin@14
|
40 LibStub("AceTimer-3.0"):Embed(Controller)
|
wobin@3
|
41 Controller:RegisterComm("Squawk", Controller.ReceiveMessage)
|
wobin@14
|
42 LibStub("AceConsole-3.0"):Embed(View)
|
wobin@3
|
43
|
wobin@0
|
44 end
|
wobin@0
|
45
|
wobin@0
|
46 -- Model --
|
wobin@0
|
47 --[[
|
wobin@0
|
48 --Each Squawk will have the following information:
|
wobin@0
|
49 -- * Owner (Name)
|
wobin@0
|
50 -- * Time (Epoch)
|
wobin@0
|
51 -- * Message (140 characters)
|
wobin@0
|
52 -- * ReplyTo (Name)
|
wobin@0
|
53 -- * Related (Names)
|
wobin@0
|
54 --
|
wobin@0
|
55 -- Each User will have the following lists:
|
wobin@0
|
56 -- * Follower
|
wobin@0
|
57 -- * Following
|
wobin@0
|
58 -- * Blocked
|
wobin@7
|
59 -- * Pending (Requests to follow that you haven't acted on)
|
wobin@7
|
60 -- * Requested (Requests to follow that you have made)
|
wobin@0
|
61 -- * Privacy State
|
wobin@7
|
62 --
|
wobin@7
|
63 -- A user can only request to follow an online person. Requests can be approved
|
wobin@7
|
64 -- on or offline, but the initial request must be made online.
|
wobin@7
|
65 --
|
wobin@7
|
66 -- When a user makes a request to follow a private user, the subsequent paths occur:
|
wobin@7
|
67 -- - Followee is added to Settings.Requested
|
wobin@7
|
68 -- - Followee receives 'follow request' -> (their) Settings.Pending
|
wobin@7
|
69 -- - Followee acts on request -> (their) Settings.Pending cleared
|
wobin@7
|
70 -- 1) Follwer is online
|
wobin@7
|
71 -- - Follower receives 'request accepted' -> Added to Settings.Following and
|
wobin@7
|
72 -- cleared from Settings.Requested
|
wobin@7
|
73 -- 2) Follower is offline
|
wobin@7
|
74 -- - The next time Follower is online and recieves a Squawk we check if there
|
wobin@7
|
75 -- is a Settings.Requested for that name, and if so assume they have approved
|
wobin@7
|
76 -- and clear/add records appropriately.
|
wobin@13
|
77 --
|
wobin@13
|
78 -- For updating, there can be a few methods.
|
wobin@13
|
79 --
|
wobin@13
|
80 -- Guild open: you're not private, you broadcast to the guild your last X
|
wobin@13
|
81 -- squawks on login
|
wobin@13
|
82 --
|
wobin@13
|
83 -- followers:
|
wobin@0
|
84 --]]
|
wobin@15
|
85 Model.Squawks = {}
|
wobin@15
|
86 local Squawks = Model.Squawks
|
wobin@15
|
87 Squawks.Main = {}
|
wobin@15
|
88 Squawks.Owners = {}
|
wobin@15
|
89
|
wobin@13
|
90 local function wrap(str, limit)
|
wobin@13
|
91 limit = limit or 72
|
wobin@13
|
92 local here = 1
|
wobin@13
|
93 return str:gsub("(%s+)()(%S+)()",
|
wobin@13
|
94 function(sp, st, word, fi)
|
wobin@13
|
95 if fi-here > limit then
|
wobin@13
|
96 here = st
|
wobin@13
|
97 return "\n"..word
|
wobin@13
|
98 end
|
wobin@13
|
99 end)
|
wobin@13
|
100 end
|
wobin@15
|
101
|
wobin@15
|
102 function Squawks:new(Message, Owner)
|
wobin@0
|
103 local o = {}
|
wobin@0
|
104 o.Owner = Owner or UnitName("player")
|
wobin@13
|
105 o.Message = wrap(Message)
|
wobin@10
|
106 o.Time = time()
|
wobin@0
|
107 local reply, to = strsplit("@", ((strsplit(" ", Message))))
|
wobin@0
|
108 if reply == "" then
|
wobin@0
|
109 o.ReplyTo = to
|
wobin@0
|
110 end
|
wobin@0
|
111
|
wobin@0
|
112 o.Related = {}
|
wobin@0
|
113
|
wobin@0
|
114 for word in string.gmatch(Message, "@(%a+)") do
|
wobin@0
|
115 if word ~= o.ReplyTo or "" then
|
wobin@0
|
116 table.insert(o.Related, word)
|
wobin@0
|
117 end
|
wobin@0
|
118 end
|
wobin@15
|
119
|
wobin@15
|
120 table.insert(self.Main, o)
|
wobin@15
|
121
|
wobin@15
|
122 if not self.Owners[Owner] then
|
wobin@15
|
123 self.Owners[Owner] = {}
|
wobin@15
|
124 end
|
wobin@15
|
125 table.insert(self.Owners[Owner], o)
|
wobin@0
|
126
|
wobin@0
|
127 return o
|
wobin@0
|
128 end
|
wobin@0
|
129
|
wobin@15
|
130 function Squawks:Sort(Squawks)
|
wobin@15
|
131 table.sort(Squawks or self.Main, function(a,b) return a.Time > b.Time end)
|
wobin@15
|
132 return Squawks or self.Main
|
wobin@0
|
133 end
|
wobin@0
|
134
|
wobin@15
|
135 function Squawks:GetOwn(Squawks)
|
wobin@2
|
136 local mine = {}
|
wobin@15
|
137 for _, squawk in ipairs(Squawks or self.Main) do
|
wobin@2
|
138 if squawk.Owner == UnitName("player") then
|
wobin@2
|
139 table.insert(mine, squawk)
|
wobin@2
|
140 end
|
wobin@2
|
141 end
|
wobin@2
|
142 return self:Sort(mine)
|
wobin@2
|
143 end
|
wobin@2
|
144
|
wobin@15
|
145 function Squawks:GetLast10(Squawks)
|
wobin@14
|
146 local mine = {}
|
wobin@15
|
147 Squawks = Squawks or self.Main
|
wobin@14
|
148 local limit = #Squawks < 10 and #Squawks or 10
|
wobin@14
|
149
|
wobin@14
|
150 Squawks = Squawk:Sort(Squawks)
|
wobin@14
|
151
|
wobin@14
|
152 for i=1,limit do
|
wobin@14
|
153 table.insert(mine, Squawks[i])
|
wobin@14
|
154 end
|
wobin@14
|
155 return mine
|
wobin@14
|
156 end
|
wobin@14
|
157
|
wobin@15
|
158 -- initially called with no arguments to get the latest timestamp of
|
wobin@15
|
159 -- my squawks, or with a name to find the latest timestamp of all
|
wobin@15
|
160 -- squawks from that user
|
wobin@15
|
161 function Squawks:GetLatestTimestamp(Name, Squawks)
|
wobin@15
|
162 if Name then
|
wobin@15
|
163 if self.Owners[Name] then
|
wobin@15
|
164 return self:GetLatestTimestamp(nil, self.Owners[Name])
|
wobin@15
|
165 else
|
wobin@15
|
166 return -1 -- No squawks exist for that name in our records
|
wobin@15
|
167 end
|
wobin@15
|
168 end
|
wobin@15
|
169
|
wobin@15
|
170 Squawks = Squawks or self.Main or {}
|
wobin@15
|
171 local latest = self:Sort(Squawks)
|
wobin@15
|
172 return latest and #latest > 0 and latest[1].Time or -1
|
wobin@15
|
173 end
|
wobin@15
|
174
|
wobin@15
|
175 function Squawks:GetLatestSquawks(Timestamp)
|
wobin@15
|
176 local latest = {}
|
wobin@15
|
177 for i, squawk in ipairs(self:Sort()) do
|
wobin@15
|
178 if squawk.Time > Timestamp and i < 10 then
|
wobin@15
|
179 table.insert(latest, squawk)
|
wobin@15
|
180 else
|
wobin@15
|
181 return latest
|
wobin@15
|
182 end
|
wobin@15
|
183 end
|
wobin@15
|
184 end
|
wobin@15
|
185
|
wobin@0
|
186 function Settings:IsPrivate()
|
wobin@0
|
187 return Settings.Private
|
wobin@0
|
188 end
|
wobin@0
|
189
|
wobin@10
|
190 function Settings:TogglePrivate()
|
wobin@10
|
191 Settings.Private = not Settings.Private
|
wobin@10
|
192 end
|
wobin@10
|
193
|
wobin@0
|
194 function Settings:AddFollower(Name)
|
wobin@2
|
195 Settings.Follower[Name] = 1
|
wobin@7
|
196 self:RemovePending(Name)
|
wobin@0
|
197 end
|
wobin@0
|
198
|
wobin@0
|
199 function Settings:AddFollowing(Name)
|
wobin@2
|
200 Settings.Following[Name] = 1
|
wobin@7
|
201 self:RemoveRequested(Name)
|
wobin@0
|
202 end
|
wobin@0
|
203
|
wobin@0
|
204 function Settings:AddBlock(Name)
|
wobin@2
|
205 Settings.Blocked[Name] = 1
|
wobin@7
|
206 self:RemoveFollower(Name)
|
wobin@7
|
207 self:RemoveFollowing(Name)
|
wobin@7
|
208 end
|
wobin@7
|
209
|
wobin@7
|
210 function Settings:AddPending(Name)
|
wobin@7
|
211 Settings.Pending[Name] = 1
|
wobin@7
|
212 end
|
wobin@7
|
213
|
wobin@7
|
214 function Settings:AddRequested(Name)
|
wobin@7
|
215 Settings.Requested[Name] = 1
|
wobin@0
|
216 end
|
wobin@0
|
217
|
wobin@0
|
218 function Settings:RemoveFollower(Name)
|
wobin@2
|
219 if Settings.Follower[Name] then
|
wobin@2
|
220 Settings.Follower[Name] = nil
|
wobin@0
|
221 end
|
wobin@0
|
222 end
|
wobin@0
|
223
|
wobin@0
|
224 function Settings:RemoveFollowing(Name)
|
wobin@2
|
225 if Settings.Following[Name] then
|
wobin@2
|
226 Settings.Following[Name] = nil
|
wobin@0
|
227 end
|
wobin@0
|
228 end
|
wobin@0
|
229
|
wobin@0
|
230 function Settings:RemoveBlock(Name)
|
wobin@2
|
231 if Settings.Blocked[Name] then
|
wobin@2
|
232 Settings.Blocked[Name] = nil
|
wobin@0
|
233 end
|
wobin@0
|
234 end
|
wobin@0
|
235
|
wobin@7
|
236 function Settings:RemovePending(Name)
|
wobin@7
|
237 if Settings.Pending[Name] then
|
wobin@7
|
238 Settings.Pending[Name] = nil
|
wobin@7
|
239 end
|
wobin@7
|
240 end
|
wobin@7
|
241
|
wobin@7
|
242 function Settings:RemoveRequested(Name)
|
wobin@7
|
243 if Settings.Requested[Name] then
|
wobin@7
|
244 Settings.Requested[Name] = nil
|
wobin@7
|
245 end
|
wobin@7
|
246 end
|
wobin@7
|
247
|
wobin@0
|
248 --Controller--
|
wobin@0
|
249
|
wobin@0
|
250 function Controller:TheyWantToFollowMe(Name)
|
wobin@0
|
251 if Settings:IsPrivate() then
|
wobin@7
|
252 Settings:AddPending(Name)
|
wobin@0
|
253 self:PutForwardFollowRequest(Name)
|
wobin@0
|
254 self:SendMessageToTarget(Name, "#Pending|"..UnitName("player"))
|
wobin@0
|
255 else
|
wobin@0
|
256 Settings:AddFollower(Name)
|
wobin@0
|
257 View:NotifyOfNewFollower(Name)
|
wobin@0
|
258 self:SendMessageToTarget(Name, "#Follow|"..UnitName("player"))
|
wobin@0
|
259 end
|
wobin@0
|
260 end
|
wobin@0
|
261
|
wobin@7
|
262 function Controller:TheyWantToUnfollowMe(Name)
|
wobin@7
|
263 Settings:RemoveFollower(Name)
|
wobin@7
|
264 end
|
wobin@7
|
265
|
wobin@0
|
266 function Controller:IWantToFollowThem(Name)
|
wobin@2
|
267 self:SendMessageToTarget(Name, "#Request|"..UnitName("player"))
|
wobin@7
|
268 Settings:AddRequested(Name)
|
wobin@7
|
269 end
|
wobin@7
|
270
|
wobin@7
|
271 function Controller:IWantToUnfollowThem(Name)
|
wobin@7
|
272 Settings:RemoveFollowing(Name)
|
wobin@7
|
273 self:SendMessageToTarget(Name, "#Unfollow|"..UnitName("player"))
|
wobin@7
|
274 View:NotifyOfUnfollowing(Name)
|
wobin@0
|
275 end
|
wobin@0
|
276
|
wobin@0
|
277 function Controller:IAmNowFollowingThem(Name)
|
wobin@0
|
278 Settings:AddFollowing(Name)
|
wobin@0
|
279 View:NotifyOfNewFollowing(Name)
|
wobin@0
|
280 end
|
wobin@0
|
281
|
wobin@7
|
282 function Controller:AddANewSquawk(Name, Message, Source)
|
wobin@10
|
283 if not Settings.Blocked[Name] then
|
wobin@7
|
284
|
wobin@7
|
285 if Source == "WHISPER" then
|
wobin@10
|
286 if Settings.Requested[Name] then -- We've been approved offline!
|
wobin@10
|
287 Settings:AddFollowing(Name)
|
wobin@7
|
288 end
|
wobin@7
|
289
|
wobin@10
|
290 if not Settings.Following[Name] then -- If we're no longer following this person
|
wobin@7
|
291 self:SendMessageToTarget(Name, "#Unfollow|"..UnitName("player"))
|
wobin@9
|
292 return
|
wobin@9
|
293 end
|
wobin@10
|
294 end
|
wobin@10
|
295
|
wobin@10
|
296 if Source == "GUILD" and Name == UnitName("player") then
|
wobin@10
|
297 return
|
wobin@7
|
298 end
|
wobin@10
|
299
|
wobin@10
|
300 table.insert(Model.Squawks, Squawk:new(Message, Name))
|
wobin@10
|
301 View:UpdateSquawkList()
|
wobin@7
|
302 end
|
wobin@0
|
303 end
|
wobin@0
|
304
|
wobin@14
|
305 local trigger
|
wobin@14
|
306 local function RepressFailure(frame, event, ...)
|
wobin@14
|
307 if arg1:match(string.gsub(ERR_CHAT_PLAYER_NOT_FOUND_S, "%%s", "(.*)")) then
|
wobin@14
|
308 if trigger then Controller:CancelTimer(trigger, true) end
|
wobin@14
|
309 trigger = Controller:ScheduleTimer(
|
wobin@14
|
310 function()
|
wobin@14
|
311 ChatFrame_RemoveMessageEventFilter("CHAT_MSG_SYSTEM", RepressFailure)
|
wobin@14
|
312 end, 3) -- Give it three seconds and then remove the filter.
|
wobin@14
|
313 return true
|
wobin@14
|
314 else
|
wobin@14
|
315 return false, unpack(...)
|
wobin@14
|
316 end
|
wobin@14
|
317 end
|
wobin@14
|
318
|
wobin@2
|
319 function Controller:SendNewSquawk(Message)
|
wobin@10
|
320 if not Settings:IsPrivate() then
|
wobin@2
|
321 self:SendMessageToGuild("#Squawk|"..UnitName("player").."|"..Message)
|
wobin@2
|
322 end
|
wobin@2
|
323
|
wobin@2
|
324 self:AddANewSquawk(UnitName("player"), Message)
|
wobin@10
|
325 for name, _ in pairs(Settings.Following) do
|
wobin@2
|
326 self:SendMessageToTarget(name, "#Squawk|"..UnitName("player").."|"..Message)
|
wobin@2
|
327 end
|
wobin@2
|
328 end
|
wobin@2
|
329
|
wobin@1
|
330 function Controller:ImPending(Name)
|
wobin@1
|
331 View:NotifyOfPending(Name)
|
wobin@1
|
332 end
|
wobin@1
|
333
|
wobin@7
|
334 function Controller:PutForwardFollowRequest(Name)
|
wobin@7
|
335 View:NotifyOfPendingRequest(Name)
|
wobin@7
|
336 end
|
wobin@7
|
337
|
wobin@10
|
338 function Controller:ApprovePendingRequest(Name)
|
wobin@10
|
339 Settings:AddFollower(Name)
|
wobin@10
|
340 View:NotifyOfNewFollower(Name)
|
wobin@10
|
341 self:SendMessageToTarget(Name, "#Follow|"..UnitName("player"))
|
wobin@10
|
342 end
|
wobin@10
|
343
|
wobin@14
|
344
|
wobin@14
|
345
|
wobin@0
|
346 function Controller:SendMessageToTarget(Name, Message)
|
wobin@14
|
347 ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", RepressFailure)
|
wobin@10
|
348 self:SendCommMessage("Squawk", Message, "WHISPER", Name)
|
wobin@0
|
349 end
|
wobin@0
|
350
|
wobin@0
|
351 function Controller:SendMessageToGuild(Message)
|
wobin@0
|
352 self:SendCommMessage("Squawk", Message, "GUILD")
|
wobin@0
|
353 end
|
wobin@0
|
354
|
wobin@0
|
355 local Parse = {
|
wobin@1
|
356 ["#Pending"] = Controller.ImPending,
|
wobin@1
|
357 ["#Follow"] = Controller.IAmNowFollowingThem,
|
wobin@7
|
358 ["#Unfollow"] = Controller.TheyWantToUnfollowMe,
|
wobin@2
|
359 ["#Squawk"] = Controller.AddANewSquawk,
|
wobin@2
|
360 ["#Request"] = Controller.TheyWantToFollowMe,
|
wobin@0
|
361 }
|
wobin@0
|
362
|
wobin@10
|
363 function Controller:ReceiveMessage(Message, Distribution, Sender)
|
wobin@0
|
364 local command, name, info = strsplit("|",Message)
|
wobin@10
|
365 View:Print(Distribution..":"..Message)
|
wobin@10
|
366 Parse[command](Controller, name, info, Distribution)
|
wobin@0
|
367 end
|
wobin@14
|
368
|
wobin@0
|
369 -- View --
|
wobin@0
|
370
|
wobin@0
|
371 function View:UpdateSquawkList()
|
wobin@3
|
372 self:Print("Updated Squawk List")
|
wobin@4
|
373 self:ShowMeMySquawks()
|
wobin@0
|
374 end
|
wobin@0
|
375
|
wobin@3
|
376 function View:NotifyOfPending(Name)
|
wobin@3
|
377 self:Print(Name.." will have to approve your request")
|
wobin@0
|
378 end
|
wobin@0
|
379
|
wobin@7
|
380 function View:NotifyOfPendingRequest(Name)
|
wobin@7
|
381 self:Print(Name.." wants to follow you.")
|
wobin@7
|
382 end
|
wobin@7
|
383
|
wobin@0
|
384 function View:NotifyOfNewFollowing(Name)
|
wobin@3
|
385 self:Print("You are now following "..Name)
|
wobin@0
|
386 end
|
wobin@0
|
387
|
wobin@7
|
388 function View:NotifyOfUnfollowing(Name)
|
wobin@7
|
389 self:Print("You are no longer following "..Name)
|
wobin@7
|
390 end
|
wobin@7
|
391
|
wobin@0
|
392 function View:NotifyOfNewFollower(Name)
|
wobin@3
|
393 self:Print(Name.." is now following you")
|
wobin@0
|
394 end
|
wobin@4
|
395
|
wobin@4
|
396 function View:ShowMeMySquawks()
|
wobin@15
|
397 for _,squawk in ipairs(Model.Squawks.Main) do
|
wobin@4
|
398 self:Print(squawk.Message)
|
wobin@4
|
399 end
|
wobin@4
|
400 end
|
wobin@4
|
401
|
wobin@4
|
402 function View:ShowMeMyFollowers()
|
wobin@4
|
403 self:Print("My followers are:")
|
wobin@4
|
404 for name,_ in pairs(Settings.Follower) do
|
wobin@4
|
405 self:Print(name)
|
wobin@4
|
406 end
|
wobin@4
|
407 end
|
wobin@4
|
408
|
wobin@4
|
409 function View:ShowMeWhoImFollowing()
|
wobin@4
|
410 self:Print("I am following:")
|
wobin@4
|
411 for name,_ in pairs(Settings.Following) do
|
wobin@4
|
412 self:Print(name)
|
wobin@4
|
413 end
|
wobin@4
|
414 end
|
wobin@4
|
415
|
wobin@4
|
416 function View:ShowMeWhoIveBlocked()
|
wobin@4
|
417 self:Print("I've blocked:")
|
wobin@6
|
418 for name,_ in pairs(Settings.Blocked) do
|
wobin@4
|
419 self:Print(name)
|
wobin@4
|
420 end
|
wobin@4
|
421 end
|
wobin@10
|
422
|
wobin@13
|
423 local TimeSpan = { [1] = {"second", 60, 1},
|
wobin@13
|
424 [2] = {"minute", 3600, 60},
|
wobin@13
|
425 [3] = {"hour", 86400, 3600} }
|
wobin@13
|
426
|
wobin@13
|
427 function View:GetTime(stime)
|
wobin@13
|
428 local lapsed = difftime(time(), stime)
|
wobin@13
|
429 if lapsed < 86400 then -- if we're still in the same day...
|
wobin@13
|
430 for _,span in ipairs(TimeSpan) do
|
wobin@13
|
431 if lapsed < span[2] then
|
wobin@13
|
432 local timespan = math.floor(lapsed/span[3])
|
wobin@13
|
433 if timespan == 1 then
|
wobin@13
|
434 timespan = timespan .." ".. span[1]
|
wobin@13
|
435 else
|
wobin@13
|
436 timespan = timespan .. " ".. span[1].."s"
|
wobin@13
|
437 end
|
wobin@13
|
438 return timespan.. " ago"
|
wobin@13
|
439 end
|
wobin@13
|
440 end
|
wobin@13
|
441 end
|
wobin@13
|
442 return date("%I:%M %p %b %d", stime)
|
wobin@13
|
443 end
|
wobin@13
|
444
|
wobin@10
|
445 local LDBFeed = LibStub("LibDataBroker-1.1"):NewDataObject("Squawk", {type = "data source", text = "Awk!"})
|
wobin@10
|
446 local QTip = LibStub("LibQTip-1.0")
|
wobin@16
|
447 local QTipClick = LibStub("LibQTipClick-1.0")
|
wobin@16
|
448 local tooltip = {}
|
wobin@16
|
449
|
wobin@16
|
450 local function HideTooltip()
|
wobin@16
|
451 if MouseIsOver(tooltip) then return end
|
wobin@16
|
452 tooltip:SetScript("OnLeave", nil)
|
wobin@16
|
453 tooltip:Hide()
|
wobin@16
|
454 QTip:Release(tooltip)
|
wobin@16
|
455 tooltip = nil
|
wobin@16
|
456 end
|
wobin@16
|
457
|
wobin@16
|
458 local function ReplyToMe(cell, Owner, event)
|
wobin@16
|
459 View:Print("Replying to @"..Owner)
|
wobin@16
|
460 end
|
wobin@10
|
461
|
wobin@13
|
462 local function AddLine(tooltip, Line, Number, Owner, TimeStamp)
|
wobin@16
|
463 local x,y
|
wobin@13
|
464 if #Line < 79 then
|
wobin@16
|
465 y,x = tooltip:AddNormalLine(Number, Owner, Line, TimeStamp)
|
wobin@13
|
466 else
|
wobin@16
|
467 y,x = tooltip:AddNormalLine(Number, Owner, Line:sub(1, 80).."-", TimeStamp)
|
wobin@13
|
468 AddLine(tooltip, Line:sub(81))
|
wobin@13
|
469 end
|
wobin@16
|
470 if not TimeStamp then return end
|
wobin@16
|
471
|
wobin@16
|
472 -- Now add the reply clickback
|
wobin@16
|
473 tooltip:SetCell(y, 5, " ", Owner)
|
wobin@16
|
474 tooltip.lines[y].cells[5]:SetBackdrop({bgFile= "Interface\\Addons\\Squawk\\reply"})
|
wobin@16
|
475 if not tooltip.lines[y].cells[5]:GetScript("OnHide") then
|
wobin@16
|
476 tooltip.lines[y].cells[5]:SetScript("OnHide", function(self) self:SetBackdrop(nil) self:SetScript("OnHide", nil) end)
|
wobin@16
|
477 end
|
wobin@16
|
478 -- Reply clickback finished
|
wobin@13
|
479 end
|
wobin@13
|
480
|
wobin@10
|
481 function LDBFeed:OnEnter()
|
wobin@16
|
482 tooltip = QTipClick:Acquire("Squawk",5, "LEFT", "CENTER", "LEFT", "RIGHT", "RIGHT")
|
wobin@16
|
483 tooltip:Clear()
|
wobin@16
|
484 tooltip:SetCallback("OnMouseDown", ReplyToMe)
|
wobin@10
|
485 self.tooltip = tooltip
|
wobin@16
|
486 for i,squawk in ipairs(Squawk:GetLast10(Model.Squawks)) do
|
wobin@13
|
487 local head = true
|
wobin@13
|
488 local message = {strsplit("\n",squawk.Message)}
|
wobin@13
|
489 for _,line in ipairs(message) do
|
wobin@13
|
490 if head then
|
wobin@13
|
491 AddLine(tooltip, line, i..".", squawk.Owner, View:GetTime(squawk.Time))
|
wobin@13
|
492 head = false
|
wobin@13
|
493 else
|
wobin@13
|
494 AddLine(tooltip, line)
|
wobin@13
|
495 end
|
wobin@13
|
496 end
|
wobin@13
|
497 end
|
wobin@10
|
498 tooltip:SmartAnchorTo(self)
|
wobin@16
|
499 tooltip:SetScript("OnLeave", HideTooltip)
|
wobin@10
|
500 tooltip:Show()
|
wobin@10
|
501 end
|
wobin@10
|
502
|
wobin@16
|
503 function LDBFeed:OnLeave()
|
wobin@16
|
504 HideTooltip()
|
wobin@16
|
505 end
|
wobin@16
|
506 --[[
|
wobin@16
|
507
|
wobin@16
|
508 function LDBFeed:OnClick(button)
|
wobin@16
|
509 editbox:ClearAllPoints()
|
wobin@16
|
510 editbox:SetPoint(GetTipAnchor(self))
|
wobin@16
|
511 editbox:Show()
|
wobin@10
|
512 end
|
wobin@10
|
513
|
wobin@16
|
514 local function GetTipAnchor(frame)
|
wobin@16
|
515 if not x or not y then return "TOPLEFT", frame, "BOTTOMLEFT" end
|
wobin@16
|
516 local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
|
wobin@16
|
517 local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
|
wobin@16
|
518 return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
|
wobin@10
|
519 end
|
wobin@16
|
520
|
wobin@16
|
521 local editbox = CreateFrame('EditBox', nil, UIParent)
|
wobin@16
|
522 editbox:Hide()
|
wobin@16
|
523 editbox:SetAutoFocus(true)
|
wobin@16
|
524 editbox:SetHeight(32)
|
wobin@16
|
525 editbox:SetWidth(350)
|
wobin@16
|
526 editbox:SetFrameStrata("HIGH")
|
wobin@16
|
527 editbox:SetFontObject('GameFontHighlightSmall')
|
wobin@16
|
528 lib.editbox = editbox
|
wobin@16
|
529
|
wobin@16
|
530 editbox:SetScript("OnEscapePressed", editbox.ClearFocus)
|
wobin@16
|
531 editbox:SetScript("OnEnterPressed", editbox.ClearFocus)
|
wobin@16
|
532 editbox:SetScript("OnEditFocusLost", editbox.Hide)
|
wobin@16
|
533 editbox:SetScript("OnEditFocusGained", editbox.HighlightText)
|
wobin@16
|
534 editbox:SetScript("OnTextChanged", function(self)
|
wobin@16
|
535 self:SetText(self:GetParent().val)
|
wobin@16
|
536 self:HighlightText()
|
wobin@16
|
537 end)
|
wobin@16
|
538
|
wobin@16
|
539 local left = editbox:CreateTexture(nil, "BACKGROUND")
|
wobin@16
|
540 left:SetWidth(8) left:SetHeight(20)
|
wobin@16
|
541 left:SetPoint("LEFT", -5, 0)
|
wobin@16
|
542 left:SetTexture("Interface\\Common\\Common-Input-Border")
|
wobin@16
|
543 left:SetTexCoord(0, 0.0625, 0, 0.625)
|
wobin@16
|
544
|
wobin@16
|
545 local right = editbox:CreateTexture(nil, "BACKGROUND")
|
wobin@16
|
546 right:SetWidth(8) right:SetHeight(20)
|
wobin@16
|
547 right:SetPoint("RIGHT", 0, 0)
|
wobin@16
|
548 right:SetTexture("Interface\\Common\\Common-Input-Border")
|
wobin@16
|
549 right:SetTexCoord(0.9375, 1, 0, 0.625)
|
wobin@16
|
550
|
wobin@16
|
551 local center = editbox:CreateTexture(nil, "BACKGROUND")
|
wobin@16
|
552 center:SetHeight(20)
|
wobin@16
|
553 center:SetPoint("RIGHT", right, "LEFT", 0, 0)
|
wobin@16
|
554 center:SetPoint("LEFT", left, "RIGHT", 0, 0)
|
wobin@16
|
555 center:SetTexture("Interface\\Common\\Common-Input-Border")
|
wobin@16
|
556 center:SetTexCoord(0.0625, 0.9375, 0, 0.625)
|
wobin@16
|
557
|
wobin@16
|
558 function lib.OpenEditbox(self)
|
wobin@16
|
559 editbox:SetText(self.val)
|
wobin@16
|
560 editbox:SetParent(self)
|
wobin@16
|
561 editbox:SetPoint("LEFT", self)
|
wobin@16
|
562 editbox:SetPoint("RIGHT", self)
|
wobin@16
|
563 editbox:Show()
|
wobin@16
|
564 end
|
wobin@16
|
565 --]]
|
wobin@16
|
566
|