Status: | Merged |
---|---|
Merged at revision: | 1250 |
Proposed branch: | lp:~bigwhale/gwibber/DMs |
Merge into: | lp:gwibber |
Diff against target: |
605 lines (+232/-79) 6 files modified
client/tab-bar-item.vala (+5/-3) libgwibber-gtk/action-box.vala (+69/-29) libgwibber-gtk/stream-view-tile.vala (+117/-37) libgwibber-gtk/stream-view.vala (+12/-6) libgwibber/stream-model-schema.vala (+4/-1) libgwibber/streams.vala (+25/-3) |
To merge this branch: | bzr merge lp:~bigwhale/gwibber/DMs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ken VanDine | Approve | ||
Review via email: mp+91151@code.launchpad.net |
Commit message
Description of the change
Added support for replying to private messages on twitter, and overlay avatars on private messages.
To post a comment you must log in.
Revision history for this message
Ken VanDine (ken-vandine) wrote : | # |
lp:~bigwhale/gwibber/DMs
updated
- 1178. By David Klasinc
-
Changes according to merge review.
Revision history for this message
David Klasinc (bigwhale) wrote : | # |
Added necessary changes.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'client/tab-bar-item.vala' |
2 | --- client/tab-bar-item.vala 2012-01-18 19:45:36 +0000 |
3 | +++ client/tab-bar-item.vala 2012-02-01 20:40:23 +0000 |
4 | @@ -38,9 +38,9 @@ |
5 | |
6 | view.model = streams_map[stream]; |
7 | view.stream = stream; |
8 | - view.reply.connect ((mid, account, sender) => { |
9 | + view.send.connect ((mid, account, sender, action) => { |
10 | entry.text_view.mid = mid; |
11 | - if (stream == "private") |
12 | + if (action == "private" || stream == "private") |
13 | { |
14 | entry.text_view.action = "private"; |
15 | entry.private.show (); |
16 | @@ -49,9 +49,11 @@ |
17 | entry.text_view.action = "reply"; |
18 | entry.target_bar.selected = account; |
19 | entry.showing = true; |
20 | - entry.text_view.buffer.text = sender + " "; |
21 | + if (entry.text_view.action != "private") |
22 | + entry.text_view.buffer.text = sender + " "; |
23 | entry.text_view.grab_focus (); |
24 | }); |
25 | + |
26 | notify["active"].connect(() => { |
27 | view.showing = active; |
28 | }); |
29 | |
30 | === modified file 'libgwibber-gtk/action-box.vala' |
31 | --- libgwibber-gtk/action-box.vala 2012-01-30 18:21:42 +0000 |
32 | +++ libgwibber-gtk/action-box.vala 2012-02-01 20:40:23 +0000 |
33 | @@ -60,6 +60,7 @@ |
34 | public string mid { get; construct set; } |
35 | public string sender { get; construct set; } |
36 | public string action { get; construct set; } |
37 | + public bool from_me { get; construct set; } |
38 | public string tooltip { get; construct set; } |
39 | |
40 | private Gtk.Image _image; |
41 | @@ -68,9 +69,9 @@ |
42 | private Gtk.Menu? _menu; |
43 | private Gtk.MenuItem? _amenu; |
44 | |
45 | - public ActionBoxItem (string service, string stream, string account, string mid, string sender, string tooltip = "") |
46 | + public ActionBoxItem (string service, string stream, string account, string mid, string sender, bool from_me, string tooltip = "") |
47 | { |
48 | - Object (service:service, stream:stream, account:account, mid:mid, sender:sender, tooltip:tooltip); |
49 | + Object (service:service, stream:stream, account:account, mid:mid, sender:sender, from_me:from_me, tooltip:tooltip); |
50 | } |
51 | |
52 | ~ActionBoxItem () |
53 | @@ -113,7 +114,7 @@ |
54 | } |
55 | |
56 | [Signal (action=true)] |
57 | - public virtual signal void reply (string mid, string account, string sender) |
58 | + public virtual signal void send (string mid, string account, string sender, string action = "send") |
59 | { |
60 | } |
61 | |
62 | @@ -140,7 +141,7 @@ |
63 | { |
64 | _menu = new Gtk.Menu (); |
65 | |
66 | - if (service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg") |
67 | + if ((service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg") && !from_me && stream != "private") |
68 | { |
69 | _amenu = new Gtk.MenuItem.with_mnemonic (_("_Reply")); |
70 | _amenu.activate.connect(() => { |
71 | @@ -156,30 +157,69 @@ |
72 | |
73 | var parser = new Json.Parser(); |
74 | parser.load_from_data(msg); |
75 | - |
76 | - obj = parser.get_root().get_object(); |
77 | - if (obj != null) |
78 | - { |
79 | - if (obj.has_member ("sender")) |
80 | - { |
81 | - sender_obj = obj.get_object_member ("sender"); |
82 | - if (sender_obj != null) |
83 | - { |
84 | - if (sender_obj.has_member ("nick")) |
85 | - nick = sender_obj.get_string_member ("nick"); |
86 | - } |
87 | - } |
88 | - } |
89 | - } catch (GLib.IOError e) { |
90 | - warning (e.message); |
91 | - } |
92 | - if (nick.length > 0) |
93 | - nick = "@" + nick; |
94 | - reply (mid, account, nick); |
95 | - }); |
96 | - _menu.append(_amenu); |
97 | - } |
98 | - |
99 | + |
100 | + obj = parser.get_root().get_object(); |
101 | + if (obj != null) |
102 | + { |
103 | + if (obj.has_member ("sender")) |
104 | + { |
105 | + sender_obj = obj.get_object_member ("sender"); |
106 | + if (sender_obj != null) |
107 | + { |
108 | + if (sender_obj.has_member ("nick")) |
109 | + nick = sender_obj.get_string_member ("nick"); |
110 | + } |
111 | + } |
112 | + } |
113 | + } catch (GLib.IOError e) { |
114 | + warning (e.message); |
115 | + } |
116 | + if (nick.length > 0) |
117 | + nick = "@" + nick; |
118 | + send (mid, account, nick); |
119 | + }); |
120 | + _menu.append(_amenu); |
121 | + } |
122 | + |
123 | + if ((service == "twitter" || service == "identica" || service == "statusnet") && !from_me) |
124 | + { |
125 | + _amenu = new Gtk.MenuItem.with_mnemonic (_("Pri_vate Reply")); |
126 | + _amenu.activate.connect(() => { |
127 | + hide(); |
128 | + string nick = ""; |
129 | + Json.Object obj = null; |
130 | + Json.Object sender_obj = null; |
131 | + |
132 | + try |
133 | + { |
134 | + var messages = new Gwibber.Messages (); |
135 | + var msg = messages.get_message (mid); |
136 | + |
137 | + var parser = new Json.Parser(); |
138 | + parser.load_from_data(msg); |
139 | + |
140 | + obj = parser.get_root().get_object(); |
141 | + if (obj != null) |
142 | + { |
143 | + if (obj.has_member ("sender")) |
144 | + { |
145 | + sender_obj = obj.get_object_member ("sender"); |
146 | + if (sender_obj != null) |
147 | + { |
148 | + if (sender_obj.has_member ("nick")) |
149 | + nick = sender_obj.get_string_member ("nick"); |
150 | + } |
151 | + } |
152 | + } |
153 | + } catch (GLib.IOError e) { |
154 | + warning (e.message); |
155 | + } |
156 | + if (nick.length > 0) |
157 | + nick = "@" + nick; |
158 | + send (mid, account, nick, "private"); |
159 | + }); |
160 | + _menu.append(_amenu); |
161 | + } |
162 | if (service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg" && service != "qaiku" && service != "buzz" && stream != "private") |
163 | { |
164 | _amenu = new Gtk.MenuItem.with_mnemonic (_("_Like")); |
165 | @@ -198,7 +238,7 @@ |
166 | |
167 | var parser = new Json.Parser(); |
168 | parser.load_from_data(msg); |
169 | - |
170 | + |
171 | obj = parser.get_root().get_object(); |
172 | if (obj != null) |
173 | { |
174 | |
175 | === modified file 'libgwibber-gtk/stream-view-tile.vala' |
176 | --- libgwibber-gtk/stream-view-tile.vala 2012-01-30 15:05:25 +0000 |
177 | +++ libgwibber-gtk/stream-view-tile.vala 2012-02-01 20:40:23 +0000 |
178 | @@ -82,6 +82,7 @@ |
179 | public bool show_fullname { get; construct set; } |
180 | private uint _update_time_area_id = 0; |
181 | private uint _cache_avatar_id = 0; |
182 | + private uint _cache_overlay_avatar_id = 0; |
183 | private ulong _expander_id = 0; |
184 | private ulong _thumb_expander_id = 0; |
185 | private List<ulong> _to_disconnect; |
186 | @@ -129,10 +130,10 @@ |
187 | |
188 | vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
189 | main_box.pack_start (vbox, true, true, 0); |
190 | - |
191 | + |
192 | var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); |
193 | vbox.pack_start (hbox, false, false, 2); |
194 | - |
195 | + |
196 | private = new Gtk.Image.from_icon_name ("status_lock", Gtk.IconSize.MENU); |
197 | private.set_no_show_all (true); |
198 | hbox.pack_start (private, false, false, 0); |
199 | @@ -327,7 +328,7 @@ |
200 | } |
201 | |
202 | [Signal (action=true)] |
203 | - public virtual signal void reply (string mid, string account, string sender) |
204 | + public virtual signal void send (string mid, string account, string sender, string action = "send") |
205 | { |
206 | } |
207 | |
208 | @@ -399,7 +400,10 @@ |
209 | string _video_src, |
210 | string _video_url, |
211 | string _video_name, |
212 | - string _comments) |
213 | + string _comments, |
214 | + string _recipient, |
215 | + string _recipient_nick, |
216 | + string _recipient_icon) |
217 | { |
218 | // hide and reset values to prevent reuse as the tiles change |
219 | action_box.hide (); |
220 | @@ -489,7 +493,7 @@ |
221 | chbox.pack_start (clalignment, false, false, 0); |
222 | var clbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); |
223 | clalignment.add (clbox); |
224 | - |
225 | + |
226 | comments_box.pack_start (chbox, false, false, 2); |
227 | chbox.pack_start (cvbox, false, false, 2); |
228 | if (obj.has_member ("text")) |
229 | @@ -521,7 +525,7 @@ |
230 | cname_label.set_markup ("<b><span font_size='small'>" + cname + "</span></b>"); |
231 | cname_box.pack_start (cname_label, false, false, 2); |
232 | cvbox.pack_end (cname_box, false, false, 2); |
233 | - } |
234 | + } |
235 | if (_sender_obj.has_member ("image")) |
236 | { |
237 | var cimage = _sender_obj.get_string_member ("image"); |
238 | @@ -545,7 +549,7 @@ |
239 | } |
240 | } |
241 | } |
242 | - } |
243 | + } |
244 | comments_box.set_no_show_all (false); |
245 | comments_box.show_all (); |
246 | } |
247 | @@ -564,12 +568,19 @@ |
248 | } |
249 | } |
250 | |
251 | - string display_name = _sender; |
252 | + string display_name = ""; |
253 | |
254 | - if (show_fullname && _sender.length > 0) |
255 | - display_name = _sender; |
256 | - else if (_sender_nick.length > 0) |
257 | - display_name = _sender_nick; |
258 | + if (_from_me && _stream == "private") { |
259 | + if (show_fullname && _recipient.length > 0) |
260 | + display_name = _recipient; |
261 | + else if (_recipient_nick.length > 0) |
262 | + display_name = _recipient_nick; |
263 | + } else { |
264 | + if (show_fullname && _sender.length > 0) |
265 | + display_name = _sender; |
266 | + else if (_sender_nick.length > 0) |
267 | + display_name = _sender_nick; |
268 | + } |
269 | |
270 | name.set_markup ("<b>" + display_name + "</b>"); |
271 | |
272 | @@ -579,7 +590,7 @@ |
273 | sender += ":"; |
274 | */ |
275 | |
276 | - /* iterate over the accounts, display the service icon and attach a menu |
277 | + /* iterate over the accounts, display the service icon and attach a menu |
278 | * for actions. |
279 | * this is a temporary hack until njpatel finishes the proper actions widget |
280 | */ |
281 | @@ -605,10 +616,10 @@ |
282 | if (_account in icon_displayed) |
283 | continue; |
284 | icon_displayed += _account; |
285 | - var action_item = new GwibberGtk.ActionBoxItem (_service, _stream, _account, _mid, sender); |
286 | + var action_item = new GwibberGtk.ActionBoxItem (_service, _stream, _account, _mid, sender, _from_me); |
287 | action_box.add(action_item); |
288 | - action_item.reply.connect((mid, account, sender) => { |
289 | - reply (mid, account, sender); |
290 | + action_item.send.connect((mid, account, sender, action) => { |
291 | + send (mid, account, sender, action); |
292 | }); |
293 | |
294 | } |
295 | @@ -618,22 +629,74 @@ |
296 | else |
297 | _avatar_box.reparent(lalignment); |
298 | |
299 | + var _avatar = new StreamViewAvatar (); |
300 | + var _overlay_avatar = new StreamViewAvatar (); |
301 | + |
302 | var _avatar_cache_image = utils.avatar_path (_icon_uri); |
303 | - if (_avatar_cache_image != null) |
304 | - { |
305 | - var _avatar = new StreamViewAvatar (); |
306 | - _avatar.set_from_file (_avatar_cache_image); |
307 | + var _overlay_avatar_cache_image = ""; |
308 | + |
309 | + if (_stream != "private") |
310 | + { |
311 | + if (_avatar_cache_image != null) |
312 | + { |
313 | + _avatar.set_from_file (_avatar_cache_image); |
314 | + _avatar_hbox.add (_avatar); |
315 | + _avatar_hbox.show (); |
316 | + _avatar.show (); |
317 | + } else |
318 | + { |
319 | + ulong _cache_avatar_id = Timeout.add (200, () => { |
320 | + load_avatar_async.begin (_icon_uri, _avatar_hbox); |
321 | + return false; |
322 | + }); |
323 | + _to_disconnect.append (_cache_avatar_id); |
324 | + } |
325 | + } else |
326 | + { |
327 | + _overlay_avatar_cache_image = utils.avatar_path (_recipient_icon); |
328 | + |
329 | + // Deal with the private streams and avatars, introduce new memory leaks ... |
330 | + Gdk.Pixbuf first_buf; |
331 | + Gdk.Pixbuf second_buf; |
332 | + |
333 | + _avatar.set_from_icon_name("stock-person", Gtk.IconSize.DIALOG); |
334 | + _overlay_avatar.set_from_icon_name("stock-person", Gtk.IconSize.DIALOG); |
335 | + |
336 | + first_buf = _avatar.get_pixbuf(); |
337 | + second_buf = _overlay_avatar.get_pixbuf(); |
338 | + |
339 | + if (_avatar_cache_image != null) |
340 | + { |
341 | + first_buf = new Gdk.Pixbuf.from_file(_avatar_cache_image); |
342 | + } else |
343 | + { |
344 | + ulong _cache_avatar_id = Timeout.add (200, () => { |
345 | + load_avatar_async.begin (_icon_uri, _avatar_hbox); |
346 | + return false; |
347 | + }); |
348 | + _to_disconnect.append (_cache_avatar_id); |
349 | + } |
350 | + |
351 | + if (_overlay_avatar_cache_image != null) |
352 | + { |
353 | + second_buf = new Gdk.Pixbuf.from_file(_overlay_avatar_cache_image); |
354 | + } else |
355 | + { |
356 | + ulong _cache_overlay_avatar_id = Timeout.add (200, () => { |
357 | + load_avatar_async.begin (_recipient_icon, _avatar_hbox, true); |
358 | + return false; |
359 | + }); |
360 | + _to_disconnect.append (_cache_overlay_avatar_id); |
361 | + } |
362 | + |
363 | + second_buf.composite(first_buf, 24, 24, 24, 24, 24, 24, 0.5, 0.5, Gdk.InterpType.BILINEAR, 255); |
364 | + _avatar.set_from_pixbuf(first_buf); |
365 | _avatar_hbox.add (_avatar); |
366 | _avatar_hbox.show (); |
367 | _avatar.show (); |
368 | - } else |
369 | - { |
370 | - ulong _cache_avatar_id = Timeout.add (200, () => { |
371 | - load_avatar_async.begin (_icon_uri, _avatar_hbox); |
372 | - return false; |
373 | - }); |
374 | - _to_disconnect.append (_cache_avatar_id); |
375 | - } |
376 | + } |
377 | + |
378 | + |
379 | |
380 | if (_stream == "user") |
381 | { |
382 | @@ -646,7 +709,7 @@ |
383 | } |
384 | |
385 | url = _url; |
386 | - |
387 | + |
388 | _avatar_box.button_press_event.disconnect(on_avatar_click); |
389 | _avatar_box.button_press_event.connect(on_avatar_click); |
390 | |
391 | @@ -658,7 +721,7 @@ |
392 | likes_hbox.set_no_show_all (false); |
393 | likes_hbox.show_all(); |
394 | } else { |
395 | - likes_count.set_markup("<span font_size='small'>" + |
396 | + likes_count.set_markup("<span font_size='small'>" + |
397 | ngettext("%i person liked this", "%i people liked this", (int) _likes).printf((int) _likes) + |
398 | "</span>"); |
399 | likes_hbox.set_no_show_all (false); |
400 | @@ -695,7 +758,7 @@ |
401 | } |
402 | |
403 | message.set_markup (msg_str); |
404 | - |
405 | + |
406 | if (img_uri.length > 0 ) |
407 | { |
408 | if (_thumb_expander_id != 0) |
409 | @@ -754,20 +817,23 @@ |
410 | retweeted_by.show (); |
411 | } |
412 | retweeted_by_string += "</span>"; |
413 | - |
414 | + |
415 | retweeted_by.set_markup (retweeted_by_string); |
416 | |
417 | queue_resize (); |
418 | show (); |
419 | - } |
420 | + } |
421 | |
422 | - private async void load_avatar_async (string url, Gtk.Box b) |
423 | + private async void load_avatar_async (string url, Gtk.Box b, bool overlay = false) |
424 | { |
425 | string t; |
426 | var file = File.new_for_uri (url); |
427 | try { |
428 | var stream = yield file.read_async (Priority.DEFAULT); |
429 | + |
430 | Gdk.Pixbuf pixbuf = null; |
431 | + Gdk.Pixbuf first_buf = null; |
432 | + |
433 | pixbuf = new Gdk.Pixbuf.from_stream_at_scale (stream, |
434 | 48, |
435 | 48, |
436 | @@ -776,11 +842,25 @@ |
437 | { |
438 | var avatar = new StreamViewAvatar (); |
439 | foreach (var _w in b.get_children ()) |
440 | + { |
441 | + if (overlay && _w is StreamViewAvatar) |
442 | + { |
443 | + Gtk.Image _r = (Gtk.Image) _w; |
444 | + first_buf = _r.get_pixbuf(); |
445 | + } |
446 | if (_w is Gtk.Widget) |
447 | _w.destroy (); |
448 | - avatar.set_from_pixbuf (pixbuf); |
449 | + } |
450 | + if (overlay) |
451 | + { |
452 | + pixbuf.composite(first_buf, 24, 24, 24, 24, 24, 24, 0.5, 0.5, Gdk.InterpType.BILINEAR, 255); |
453 | + avatar.set_from_pixbuf (first_buf); |
454 | + } else |
455 | + avatar.set_from_pixbuf (pixbuf); |
456 | + |
457 | b.add (avatar); |
458 | avatar.show (); |
459 | + |
460 | var cimage = Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_user_cache_dir(), "gwibber/avatars", url.replace("/","")); |
461 | t = "png"; |
462 | if (cimage.has_suffix ("JPG") || cimage.has_suffix ("jpeg") || cimage.has_suffix ("jpg")) |
463 | @@ -827,7 +907,7 @@ |
464 | { |
465 | /* let's point to the static content in imgur */ |
466 | var last = uri.rstr("/").substring(1); |
467 | - ret = "http://i.imgur.com/%s.png".printf(last); |
468 | + ret = "http://i.imgur.com/%s.png".printf(last); |
469 | } |
470 | else if (uri.contains("youtube.com")) |
471 | { |
472 | @@ -847,7 +927,7 @@ |
473 | |
474 | private bool on_avatar_click (Gdk.EventButton button) |
475 | { |
476 | - /* FIXME: Display a user view with user info and posts instead of |
477 | + /* FIXME: Display a user view with user info and posts instead of |
478 | launching external browser */ |
479 | try { |
480 | AppInfo.launch_default_for_uri (url, null); |
481 | |
482 | === modified file 'libgwibber-gtk/stream-view.vala' |
483 | --- libgwibber-gtk/stream-view.vala 2012-01-29 06:06:54 +0000 |
484 | +++ libgwibber-gtk/stream-view.vala 2012-02-01 20:40:23 +0000 |
485 | @@ -288,8 +288,8 @@ |
486 | tile.show_all (); |
487 | view_box.add (tile); |
488 | tiles.append (tile); |
489 | - tile.reply.connect((mid, account, sender) => { |
490 | - reply (mid, account, sender); |
491 | + tile.send.connect((mid, account, sender, action) => { |
492 | + send (mid, account, sender, action); |
493 | }); |
494 | } |
495 | |
496 | @@ -387,7 +387,11 @@ |
497 | stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_SRC), |
498 | stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_URL), |
499 | stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_NAME), |
500 | - stream_filter_model.get_string (iter, StreamModelColumn.COMMENTS)); |
501 | + stream_filter_model.get_string (iter, StreamModelColumn.COMMENTS), |
502 | + stream_filter_model.get_string (iter, StreamModelColumn.RECIPIENT), |
503 | + stream_filter_model.get_string (iter, StreamModelColumn.RECIPIENT_NICK), |
504 | + stream_filter_model.get_string (iter, StreamModelColumn.RECIPIENT_ICON)); |
505 | + |
506 | tiles_visible = i + 1; |
507 | } |
508 | else |
509 | @@ -444,9 +448,11 @@ |
510 | tile.show_all (); |
511 | view_box.add (tile); |
512 | tiles.append (tile); |
513 | - tile.reply.connect((mid, account, sender) => { |
514 | - reply (mid, account, sender); |
515 | + |
516 | + tile.send.connect((mid, account, sender, action) => { |
517 | + send (mid, account, sender, action); |
518 | }); |
519 | + |
520 | Idle.add (()=>{ |
521 | queue_draw (); |
522 | do_refresh (); |
523 | @@ -479,7 +485,7 @@ |
524 | } |
525 | |
526 | [Signal (action=true)] |
527 | - public virtual signal void reply (string mid, string account, string sender) |
528 | + public virtual signal void send (string mid, string account, string recipient, string action = "send") |
529 | { |
530 | } |
531 | |
532 | |
533 | === modified file 'libgwibber/stream-model-schema.vala' |
534 | --- libgwibber/stream-model-schema.vala 2011-08-25 06:53:05 +0000 |
535 | +++ libgwibber/stream-model-schema.vala 2012-02-01 20:40:23 +0000 |
536 | @@ -55,6 +55,9 @@ |
537 | VIDEO_SRC, |
538 | VIDEO_URL, |
539 | VIDEO_NAME, |
540 | - COMMENTS |
541 | + COMMENTS, |
542 | + RECIPIENT, |
543 | + RECIPIENT_NICK, |
544 | + RECIPIENT_ICON |
545 | } |
546 | } |
547 | |
548 | === modified file 'libgwibber/streams.vala' |
549 | --- libgwibber/streams.vala 2012-01-19 18:14:26 +0000 |
550 | +++ libgwibber/streams.vala 2012-02-01 20:40:23 +0000 |
551 | @@ -175,14 +175,14 @@ |
552 | private Dee.SequenceModel? create_model() |
553 | { |
554 | var m = new Dee.SequenceModel(); |
555 | - m.set_schema ("as", "s", "s", "s", "s", "b", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "d", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s"); |
556 | + m.set_schema ("as", "s", "s", "s", "s", "b", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "d", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s", "s"); |
557 | debug ("SCHEMA has %u rows", m.get_n_columns ()); |
558 | return m; |
559 | } |
560 | |
561 | public Dee.Model? streams_model(bool transients) |
562 | { |
563 | - uint schema_length = 35; |
564 | + uint schema_length = 38; |
565 | |
566 | resources = Dee.ResourceManager.get_default (); |
567 | |
568 | @@ -399,6 +399,25 @@ |
569 | Json.Object _sender_obj = null; |
570 | string _sender = ""; |
571 | string _sender_nick = ""; |
572 | + Json.Object _recipient_obj = null; |
573 | + string _recipient = ""; |
574 | + string _recipient_nick = ""; |
575 | + string _recipient_icon = ""; |
576 | + |
577 | + if (obj.has_member("recipient")) |
578 | + { |
579 | + _recipient_obj = obj.get_object_member("recipient"); |
580 | + |
581 | + if (_recipient_obj != null) |
582 | + { |
583 | + if (_recipient_obj.has_member("name")) |
584 | + _recipient = _recipient_obj.get_string_member("name"); |
585 | + if (_recipient_obj.has_member("nick")) |
586 | + _recipient_nick = _recipient_obj.get_string_member("nick"); |
587 | + if (_recipient_obj.has_member("image")) |
588 | + _recipient_icon = _recipient_obj.get_string_member("image"); |
589 | + } |
590 | + } |
591 | |
592 | if (obj.has_member("sender")) |
593 | { |
594 | @@ -696,7 +715,10 @@ |
595 | _video_src, |
596 | _video_url, |
597 | _video_name, |
598 | - _comments |
599 | + _comments, |
600 | + _recipient, |
601 | + _recipient_nick, |
602 | + _recipient_icon |
603 | ); |
604 | } catch { |
605 | iter = null; |
Looks great, a couple minor tweaks, in action-box.vala we shouldn't display the reply menu if the from_me is true or if the stream is private (since the private reply menu will cover that):
- if (service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg")
+ if ((service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg") && !from_me && stream != "private")
We should display the private reply menu for identica and statusnet too:
- if ((service == "twitter" || service != "identica") && !from_me)
+ if ((service == "twitter" || service == "identica" || service == "statusnet") && !from_me)
Of course once I convert the ActionBox to us the features API all that non-sense will go away, but I think this would be better for now.
It would also be nice to do some clipping on the overlay avatar, so the smaller one has rounder edges just like that bigger one. I won't block the merge for that, just a request for the future :)