Merge lp:~bigwhale/gwibber/DMs into lp:gwibber

Proposed by David Klasinc
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
Reviewer Review Type Date Requested Status
Ken VanDine Approve
Review via email: mp+91151@code.launchpad.net

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 :

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 :)

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.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Looks great

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'client/tab-bar-item.vala'
--- client/tab-bar-item.vala 2012-01-18 19:45:36 +0000
+++ client/tab-bar-item.vala 2012-02-01 20:40:23 +0000
@@ -38,9 +38,9 @@
3838
39 view.model = streams_map[stream];39 view.model = streams_map[stream];
40 view.stream = stream;40 view.stream = stream;
41 view.reply.connect ((mid, account, sender) => {41 view.send.connect ((mid, account, sender, action) => {
42 entry.text_view.mid = mid;42 entry.text_view.mid = mid;
43 if (stream == "private")43 if (action == "private" || stream == "private")
44 {44 {
45 entry.text_view.action = "private";45 entry.text_view.action = "private";
46 entry.private.show ();46 entry.private.show ();
@@ -49,9 +49,11 @@
49 entry.text_view.action = "reply";49 entry.text_view.action = "reply";
50 entry.target_bar.selected = account;50 entry.target_bar.selected = account;
51 entry.showing = true;51 entry.showing = true;
52 entry.text_view.buffer.text = sender + " ";52 if (entry.text_view.action != "private")
53 entry.text_view.buffer.text = sender + " ";
53 entry.text_view.grab_focus ();54 entry.text_view.grab_focus ();
54 });55 });
56
55 notify["active"].connect(() => {57 notify["active"].connect(() => {
56 view.showing = active;58 view.showing = active;
57 });59 });
5860
=== modified file 'libgwibber-gtk/action-box.vala'
--- libgwibber-gtk/action-box.vala 2012-01-30 18:21:42 +0000
+++ libgwibber-gtk/action-box.vala 2012-02-01 20:40:23 +0000
@@ -60,6 +60,7 @@
60 public string mid { get; construct set; }60 public string mid { get; construct set; }
61 public string sender { get; construct set; }61 public string sender { get; construct set; }
62 public string action { get; construct set; }62 public string action { get; construct set; }
63 public bool from_me { get; construct set; }
63 public string tooltip { get; construct set; }64 public string tooltip { get; construct set; }
6465
65 private Gtk.Image _image;66 private Gtk.Image _image;
@@ -68,9 +69,9 @@
68 private Gtk.Menu? _menu;69 private Gtk.Menu? _menu;
69 private Gtk.MenuItem? _amenu;70 private Gtk.MenuItem? _amenu;
7071
71 public ActionBoxItem (string service, string stream, string account, string mid, string sender, string tooltip = "")72 public ActionBoxItem (string service, string stream, string account, string mid, string sender, bool from_me, string tooltip = "")
72 {73 {
73 Object (service:service, stream:stream, account:account, mid:mid, sender:sender, tooltip:tooltip);74 Object (service:service, stream:stream, account:account, mid:mid, sender:sender, from_me:from_me, tooltip:tooltip);
74 }75 }
7576
76 ~ActionBoxItem ()77 ~ActionBoxItem ()
@@ -113,7 +114,7 @@
113 }114 }
114115
115 [Signal (action=true)]116 [Signal (action=true)]
116 public virtual signal void reply (string mid, string account, string sender)117 public virtual signal void send (string mid, string account, string sender, string action = "send")
117 {118 {
118 }119 }
119120
@@ -140,7 +141,7 @@
140 {141 {
141 _menu = new Gtk.Menu ();142 _menu = new Gtk.Menu ();
142143
143 if (service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg")144 if ((service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg") && !from_me && stream != "private")
144 {145 {
145 _amenu = new Gtk.MenuItem.with_mnemonic (_("_Reply"));146 _amenu = new Gtk.MenuItem.with_mnemonic (_("_Reply"));
146 _amenu.activate.connect(() => {147 _amenu.activate.connect(() => {
@@ -156,30 +157,69 @@
156157
157 var parser = new Json.Parser();158 var parser = new Json.Parser();
158 parser.load_from_data(msg);159 parser.load_from_data(msg);
159 160
160 obj = parser.get_root().get_object();161 obj = parser.get_root().get_object();
161 if (obj != null)162 if (obj != null)
162 {163 {
163 if (obj.has_member ("sender"))164 if (obj.has_member ("sender"))
164 {165 {
165 sender_obj = obj.get_object_member ("sender");166 sender_obj = obj.get_object_member ("sender");
166 if (sender_obj != null)167 if (sender_obj != null)
167 {168 {
168 if (sender_obj.has_member ("nick"))169 if (sender_obj.has_member ("nick"))
169 nick = sender_obj.get_string_member ("nick");170 nick = sender_obj.get_string_member ("nick");
170 }171 }
171 }172 }
172 }173 }
173 } catch (GLib.IOError e) {174 } catch (GLib.IOError e) {
174 warning (e.message);175 warning (e.message);
175 }176 }
176 if (nick.length > 0)177 if (nick.length > 0)
177 nick = "@" + nick;178 nick = "@" + nick;
178 reply (mid, account, nick);179 send (mid, account, nick);
179 });180 });
180 _menu.append(_amenu);181 _menu.append(_amenu);
181 }182 }
182183
184 if ((service == "twitter" || service == "identica" || service == "statusnet") && !from_me)
185 {
186 _amenu = new Gtk.MenuItem.with_mnemonic (_("Pri_vate Reply"));
187 _amenu.activate.connect(() => {
188 hide();
189 string nick = "";
190 Json.Object obj = null;
191 Json.Object sender_obj = null;
192
193 try
194 {
195 var messages = new Gwibber.Messages ();
196 var msg = messages.get_message (mid);
197
198 var parser = new Json.Parser();
199 parser.load_from_data(msg);
200
201 obj = parser.get_root().get_object();
202 if (obj != null)
203 {
204 if (obj.has_member ("sender"))
205 {
206 sender_obj = obj.get_object_member ("sender");
207 if (sender_obj != null)
208 {
209 if (sender_obj.has_member ("nick"))
210 nick = sender_obj.get_string_member ("nick");
211 }
212 }
213 }
214 } catch (GLib.IOError e) {
215 warning (e.message);
216 }
217 if (nick.length > 0)
218 nick = "@" + nick;
219 send (mid, account, nick, "private");
220 });
221 _menu.append(_amenu);
222 }
183 if (service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg" && service != "qaiku" && service != "buzz" && stream != "private")223 if (service != "flicker" && service != "pingfm" && service != "foursquare" && service != "digg" && service != "qaiku" && service != "buzz" && stream != "private")
184 {224 {
185 _amenu = new Gtk.MenuItem.with_mnemonic (_("_Like"));225 _amenu = new Gtk.MenuItem.with_mnemonic (_("_Like"));
@@ -198,7 +238,7 @@
198238
199 var parser = new Json.Parser();239 var parser = new Json.Parser();
200 parser.load_from_data(msg);240 parser.load_from_data(msg);
201 241
202 obj = parser.get_root().get_object();242 obj = parser.get_root().get_object();
203 if (obj != null)243 if (obj != null)
204 {244 {
205245
=== modified file 'libgwibber-gtk/stream-view-tile.vala'
--- libgwibber-gtk/stream-view-tile.vala 2012-01-30 15:05:25 +0000
+++ libgwibber-gtk/stream-view-tile.vala 2012-02-01 20:40:23 +0000
@@ -82,6 +82,7 @@
82 public bool show_fullname { get; construct set; }82 public bool show_fullname { get; construct set; }
83 private uint _update_time_area_id = 0;83 private uint _update_time_area_id = 0;
84 private uint _cache_avatar_id = 0;84 private uint _cache_avatar_id = 0;
85 private uint _cache_overlay_avatar_id = 0;
85 private ulong _expander_id = 0;86 private ulong _expander_id = 0;
86 private ulong _thumb_expander_id = 0;87 private ulong _thumb_expander_id = 0;
87 private List<ulong> _to_disconnect;88 private List<ulong> _to_disconnect;
@@ -129,10 +130,10 @@
129130
130 vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);131 vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
131 main_box.pack_start (vbox, true, true, 0);132 main_box.pack_start (vbox, true, true, 0);
132 133
133 var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);134 var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
134 vbox.pack_start (hbox, false, false, 2);135 vbox.pack_start (hbox, false, false, 2);
135 136
136 private = new Gtk.Image.from_icon_name ("status_lock", Gtk.IconSize.MENU);137 private = new Gtk.Image.from_icon_name ("status_lock", Gtk.IconSize.MENU);
137 private.set_no_show_all (true);138 private.set_no_show_all (true);
138 hbox.pack_start (private, false, false, 0);139 hbox.pack_start (private, false, false, 0);
@@ -327,7 +328,7 @@
327 }328 }
328329
329 [Signal (action=true)]330 [Signal (action=true)]
330 public virtual signal void reply (string mid, string account, string sender) 331 public virtual signal void send (string mid, string account, string sender, string action = "send")
331 {332 {
332 }333 }
333334
@@ -399,7 +400,10 @@
399 string _video_src,400 string _video_src,
400 string _video_url,401 string _video_url,
401 string _video_name,402 string _video_name,
402 string _comments)403 string _comments,
404 string _recipient,
405 string _recipient_nick,
406 string _recipient_icon)
403 {407 {
404 // hide and reset values to prevent reuse as the tiles change408 // hide and reset values to prevent reuse as the tiles change
405 action_box.hide ();409 action_box.hide ();
@@ -489,7 +493,7 @@
489 chbox.pack_start (clalignment, false, false, 0);493 chbox.pack_start (clalignment, false, false, 0);
490 var clbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);494 var clbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
491 clalignment.add (clbox);495 clalignment.add (clbox);
492 496
493 comments_box.pack_start (chbox, false, false, 2);497 comments_box.pack_start (chbox, false, false, 2);
494 chbox.pack_start (cvbox, false, false, 2);498 chbox.pack_start (cvbox, false, false, 2);
495 if (obj.has_member ("text"))499 if (obj.has_member ("text"))
@@ -521,7 +525,7 @@
521 cname_label.set_markup ("<b><span font_size='small'>" + cname + "</span></b>");525 cname_label.set_markup ("<b><span font_size='small'>" + cname + "</span></b>");
522 cname_box.pack_start (cname_label, false, false, 2);526 cname_box.pack_start (cname_label, false, false, 2);
523 cvbox.pack_end (cname_box, false, false, 2);527 cvbox.pack_end (cname_box, false, false, 2);
524 } 528 }
525 if (_sender_obj.has_member ("image"))529 if (_sender_obj.has_member ("image"))
526 {530 {
527 var cimage = _sender_obj.get_string_member ("image");531 var cimage = _sender_obj.get_string_member ("image");
@@ -545,7 +549,7 @@
545 }549 }
546 }550 }
547 }551 }
548 } 552 }
549 comments_box.set_no_show_all (false);553 comments_box.set_no_show_all (false);
550 comments_box.show_all ();554 comments_box.show_all ();
551 }555 }
@@ -564,12 +568,19 @@
564 }568 }
565 }569 }
566570
567 string display_name = _sender;571 string display_name = "";
568572
569 if (show_fullname && _sender.length > 0)573 if (_from_me && _stream == "private") {
570 display_name = _sender;574 if (show_fullname && _recipient.length > 0)
571 else if (_sender_nick.length > 0)575 display_name = _recipient;
572 display_name = _sender_nick;576 else if (_recipient_nick.length > 0)
577 display_name = _recipient_nick;
578 } else {
579 if (show_fullname && _sender.length > 0)
580 display_name = _sender;
581 else if (_sender_nick.length > 0)
582 display_name = _sender_nick;
583 }
573584
574 name.set_markup ("<b>" + display_name + "</b>");585 name.set_markup ("<b>" + display_name + "</b>");
575586
@@ -579,7 +590,7 @@
579 sender += ":";590 sender += ":";
580 */591 */
581592
582 /* iterate over the accounts, display the service icon and attach a menu 593 /* iterate over the accounts, display the service icon and attach a menu
583 * for actions.594 * for actions.
584 * this is a temporary hack until njpatel finishes the proper actions widget595 * this is a temporary hack until njpatel finishes the proper actions widget
585 */596 */
@@ -605,10 +616,10 @@
605 if (_account in icon_displayed)616 if (_account in icon_displayed)
606 continue;617 continue;
607 icon_displayed += _account;618 icon_displayed += _account;
608 var action_item = new GwibberGtk.ActionBoxItem (_service, _stream, _account, _mid, sender);619 var action_item = new GwibberGtk.ActionBoxItem (_service, _stream, _account, _mid, sender, _from_me);
609 action_box.add(action_item);620 action_box.add(action_item);
610 action_item.reply.connect((mid, account, sender) => {621 action_item.send.connect((mid, account, sender, action) => {
611 reply (mid, account, sender);622 send (mid, account, sender, action);
612 });623 });
613624
614 }625 }
@@ -618,22 +629,74 @@
618 else629 else
619 _avatar_box.reparent(lalignment);630 _avatar_box.reparent(lalignment);
620631
632 var _avatar = new StreamViewAvatar ();
633 var _overlay_avatar = new StreamViewAvatar ();
634
621 var _avatar_cache_image = utils.avatar_path (_icon_uri);635 var _avatar_cache_image = utils.avatar_path (_icon_uri);
622 if (_avatar_cache_image != null)636 var _overlay_avatar_cache_image = "";
623 {637
624 var _avatar = new StreamViewAvatar ();638 if (_stream != "private")
625 _avatar.set_from_file (_avatar_cache_image);639 {
640 if (_avatar_cache_image != null)
641 {
642 _avatar.set_from_file (_avatar_cache_image);
643 _avatar_hbox.add (_avatar);
644 _avatar_hbox.show ();
645 _avatar.show ();
646 } else
647 {
648 ulong _cache_avatar_id = Timeout.add (200, () => {
649 load_avatar_async.begin (_icon_uri, _avatar_hbox);
650 return false;
651 });
652 _to_disconnect.append (_cache_avatar_id);
653 }
654 } else
655 {
656 _overlay_avatar_cache_image = utils.avatar_path (_recipient_icon);
657
658 // Deal with the private streams and avatars, introduce new memory leaks ...
659 Gdk.Pixbuf first_buf;
660 Gdk.Pixbuf second_buf;
661
662 _avatar.set_from_icon_name("stock-person", Gtk.IconSize.DIALOG);
663 _overlay_avatar.set_from_icon_name("stock-person", Gtk.IconSize.DIALOG);
664
665 first_buf = _avatar.get_pixbuf();
666 second_buf = _overlay_avatar.get_pixbuf();
667
668 if (_avatar_cache_image != null)
669 {
670 first_buf = new Gdk.Pixbuf.from_file(_avatar_cache_image);
671 } else
672 {
673 ulong _cache_avatar_id = Timeout.add (200, () => {
674 load_avatar_async.begin (_icon_uri, _avatar_hbox);
675 return false;
676 });
677 _to_disconnect.append (_cache_avatar_id);
678 }
679
680 if (_overlay_avatar_cache_image != null)
681 {
682 second_buf = new Gdk.Pixbuf.from_file(_overlay_avatar_cache_image);
683 } else
684 {
685 ulong _cache_overlay_avatar_id = Timeout.add (200, () => {
686 load_avatar_async.begin (_recipient_icon, _avatar_hbox, true);
687 return false;
688 });
689 _to_disconnect.append (_cache_overlay_avatar_id);
690 }
691
692 second_buf.composite(first_buf, 24, 24, 24, 24, 24, 24, 0.5, 0.5, Gdk.InterpType.BILINEAR, 255);
693 _avatar.set_from_pixbuf(first_buf);
626 _avatar_hbox.add (_avatar);694 _avatar_hbox.add (_avatar);
627 _avatar_hbox.show ();695 _avatar_hbox.show ();
628 _avatar.show ();696 _avatar.show ();
629 } else697 }
630 {698
631 ulong _cache_avatar_id = Timeout.add (200, () => {699
632 load_avatar_async.begin (_icon_uri, _avatar_hbox);
633 return false;
634 });
635 _to_disconnect.append (_cache_avatar_id);
636 }
637700
638 if (_stream == "user")701 if (_stream == "user")
639 {702 {
@@ -646,7 +709,7 @@
646 }709 }
647710
648 url = _url;711 url = _url;
649 712
650 _avatar_box.button_press_event.disconnect(on_avatar_click);713 _avatar_box.button_press_event.disconnect(on_avatar_click);
651 _avatar_box.button_press_event.connect(on_avatar_click);714 _avatar_box.button_press_event.connect(on_avatar_click);
652715
@@ -658,7 +721,7 @@
658 likes_hbox.set_no_show_all (false);721 likes_hbox.set_no_show_all (false);
659 likes_hbox.show_all();722 likes_hbox.show_all();
660 } else {723 } else {
661 likes_count.set_markup("<span font_size='small'>" + 724 likes_count.set_markup("<span font_size='small'>" +
662 ngettext("%i person liked this", "%i people liked this", (int) _likes).printf((int) _likes) +725 ngettext("%i person liked this", "%i people liked this", (int) _likes).printf((int) _likes) +
663 "</span>");726 "</span>");
664 likes_hbox.set_no_show_all (false);727 likes_hbox.set_no_show_all (false);
@@ -695,7 +758,7 @@
695 }758 }
696759
697 message.set_markup (msg_str);760 message.set_markup (msg_str);
698 761
699 if (img_uri.length > 0 )762 if (img_uri.length > 0 )
700 {763 {
701 if (_thumb_expander_id != 0)764 if (_thumb_expander_id != 0)
@@ -754,20 +817,23 @@
754 retweeted_by.show ();817 retweeted_by.show ();
755 }818 }
756 retweeted_by_string += "</span>";819 retweeted_by_string += "</span>";
757 820
758 retweeted_by.set_markup (retweeted_by_string);821 retweeted_by.set_markup (retweeted_by_string);
759822
760 queue_resize ();823 queue_resize ();
761 show ();824 show ();
762 } 825 }
763826
764 private async void load_avatar_async (string url, Gtk.Box b)827 private async void load_avatar_async (string url, Gtk.Box b, bool overlay = false)
765 {828 {
766 string t;829 string t;
767 var file = File.new_for_uri (url);830 var file = File.new_for_uri (url);
768 try {831 try {
769 var stream = yield file.read_async (Priority.DEFAULT);832 var stream = yield file.read_async (Priority.DEFAULT);
833
770 Gdk.Pixbuf pixbuf = null;834 Gdk.Pixbuf pixbuf = null;
835 Gdk.Pixbuf first_buf = null;
836
771 pixbuf = new Gdk.Pixbuf.from_stream_at_scale (stream,837 pixbuf = new Gdk.Pixbuf.from_stream_at_scale (stream,
772 48,838 48,
773 48,839 48,
@@ -776,11 +842,25 @@
776 {842 {
777 var avatar = new StreamViewAvatar ();843 var avatar = new StreamViewAvatar ();
778 foreach (var _w in b.get_children ())844 foreach (var _w in b.get_children ())
845 {
846 if (overlay && _w is StreamViewAvatar)
847 {
848 Gtk.Image _r = (Gtk.Image) _w;
849 first_buf = _r.get_pixbuf();
850 }
779 if (_w is Gtk.Widget)851 if (_w is Gtk.Widget)
780 _w.destroy ();852 _w.destroy ();
781 avatar.set_from_pixbuf (pixbuf);853 }
854 if (overlay)
855 {
856 pixbuf.composite(first_buf, 24, 24, 24, 24, 24, 24, 0.5, 0.5, Gdk.InterpType.BILINEAR, 255);
857 avatar.set_from_pixbuf (first_buf);
858 } else
859 avatar.set_from_pixbuf (pixbuf);
860
782 b.add (avatar);861 b.add (avatar);
783 avatar.show ();862 avatar.show ();
863
784 var cimage = Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_user_cache_dir(), "gwibber/avatars", url.replace("/",""));864 var cimage = Path.build_path (Path.DIR_SEPARATOR_S, Environment.get_user_cache_dir(), "gwibber/avatars", url.replace("/",""));
785 t = "png";865 t = "png";
786 if (cimage.has_suffix ("JPG") || cimage.has_suffix ("jpeg") || cimage.has_suffix ("jpg"))866 if (cimage.has_suffix ("JPG") || cimage.has_suffix ("jpeg") || cimage.has_suffix ("jpg"))
@@ -827,7 +907,7 @@
827 {907 {
828 /* let's point to the static content in imgur */908 /* let's point to the static content in imgur */
829 var last = uri.rstr("/").substring(1);909 var last = uri.rstr("/").substring(1);
830 ret = "http://i.imgur.com/%s.png".printf(last); 910 ret = "http://i.imgur.com/%s.png".printf(last);
831 }911 }
832 else if (uri.contains("youtube.com"))912 else if (uri.contains("youtube.com"))
833 {913 {
@@ -847,7 +927,7 @@
847927
848 private bool on_avatar_click (Gdk.EventButton button)928 private bool on_avatar_click (Gdk.EventButton button)
849 {929 {
850 /* FIXME: Display a user view with user info and posts instead of 930 /* FIXME: Display a user view with user info and posts instead of
851 launching external browser */931 launching external browser */
852 try {932 try {
853 AppInfo.launch_default_for_uri (url, null);933 AppInfo.launch_default_for_uri (url, null);
854934
=== modified file 'libgwibber-gtk/stream-view.vala'
--- libgwibber-gtk/stream-view.vala 2012-01-29 06:06:54 +0000
+++ libgwibber-gtk/stream-view.vala 2012-02-01 20:40:23 +0000
@@ -288,8 +288,8 @@
288 tile.show_all ();288 tile.show_all ();
289 view_box.add (tile);289 view_box.add (tile);
290 tiles.append (tile);290 tiles.append (tile);
291 tile.reply.connect((mid, account, sender) => {291 tile.send.connect((mid, account, sender, action) => {
292 reply (mid, account, sender);292 send (mid, account, sender, action);
293 });293 });
294 }294 }
295295
@@ -387,7 +387,11 @@
387 stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_SRC),387 stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_SRC),
388 stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_URL),388 stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_URL),
389 stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_NAME),389 stream_filter_model.get_string (iter, StreamModelColumn.VIDEO_NAME),
390 stream_filter_model.get_string (iter, StreamModelColumn.COMMENTS));390 stream_filter_model.get_string (iter, StreamModelColumn.COMMENTS),
391 stream_filter_model.get_string (iter, StreamModelColumn.RECIPIENT),
392 stream_filter_model.get_string (iter, StreamModelColumn.RECIPIENT_NICK),
393 stream_filter_model.get_string (iter, StreamModelColumn.RECIPIENT_ICON));
394
391 tiles_visible = i + 1;395 tiles_visible = i + 1;
392 }396 }
393 else397 else
@@ -444,9 +448,11 @@
444 tile.show_all ();448 tile.show_all ();
445 view_box.add (tile);449 view_box.add (tile);
446 tiles.append (tile);450 tiles.append (tile);
447 tile.reply.connect((mid, account, sender) => {451
448 reply (mid, account, sender);452 tile.send.connect((mid, account, sender, action) => {
453 send (mid, account, sender, action);
449 });454 });
455
450 Idle.add (()=>{456 Idle.add (()=>{
451 queue_draw ();457 queue_draw ();
452 do_refresh ();458 do_refresh ();
@@ -479,7 +485,7 @@
479 }485 }
480486
481 [Signal (action=true)]487 [Signal (action=true)]
482 public virtual signal void reply (string mid, string account, string sender)488 public virtual signal void send (string mid, string account, string recipient, string action = "send")
483 {489 {
484 }490 }
485491
486492
=== modified file 'libgwibber/stream-model-schema.vala'
--- libgwibber/stream-model-schema.vala 2011-08-25 06:53:05 +0000
+++ libgwibber/stream-model-schema.vala 2012-02-01 20:40:23 +0000
@@ -55,6 +55,9 @@
55 VIDEO_SRC,55 VIDEO_SRC,
56 VIDEO_URL,56 VIDEO_URL,
57 VIDEO_NAME,57 VIDEO_NAME,
58 COMMENTS58 COMMENTS,
59 RECIPIENT,
60 RECIPIENT_NICK,
61 RECIPIENT_ICON
59 }62 }
60}63}
6164
=== modified file 'libgwibber/streams.vala'
--- libgwibber/streams.vala 2012-01-19 18:14:26 +0000
+++ libgwibber/streams.vala 2012-02-01 20:40:23 +0000
@@ -175,14 +175,14 @@
175 private Dee.SequenceModel? create_model()175 private Dee.SequenceModel? create_model()
176 {176 {
177 var m = new Dee.SequenceModel();177 var m = new Dee.SequenceModel();
178 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");178 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");
179 debug ("SCHEMA has %u rows", m.get_n_columns ());179 debug ("SCHEMA has %u rows", m.get_n_columns ());
180 return m;180 return m;
181 }181 }
182182
183 public Dee.Model? streams_model(bool transients)183 public Dee.Model? streams_model(bool transients)
184 {184 {
185 uint schema_length = 35;185 uint schema_length = 38;
186186
187 resources = Dee.ResourceManager.get_default ();187 resources = Dee.ResourceManager.get_default ();
188188
@@ -399,6 +399,25 @@
399 Json.Object _sender_obj = null;399 Json.Object _sender_obj = null;
400 string _sender = "";400 string _sender = "";
401 string _sender_nick = "";401 string _sender_nick = "";
402 Json.Object _recipient_obj = null;
403 string _recipient = "";
404 string _recipient_nick = "";
405 string _recipient_icon = "";
406
407 if (obj.has_member("recipient"))
408 {
409 _recipient_obj = obj.get_object_member("recipient");
410
411 if (_recipient_obj != null)
412 {
413 if (_recipient_obj.has_member("name"))
414 _recipient = _recipient_obj.get_string_member("name");
415 if (_recipient_obj.has_member("nick"))
416 _recipient_nick = _recipient_obj.get_string_member("nick");
417 if (_recipient_obj.has_member("image"))
418 _recipient_icon = _recipient_obj.get_string_member("image");
419 }
420 }
402421
403 if (obj.has_member("sender"))422 if (obj.has_member("sender"))
404 {423 {
@@ -696,7 +715,10 @@
696 _video_src,715 _video_src,
697 _video_url,716 _video_url,
698 _video_name,717 _video_name,
699 _comments718 _comments,
719 _recipient,
720 _recipient_nick,
721 _recipient_icon
700 );722 );
701 } catch {723 } catch {
702 iter = null;724 iter = null;