[polari/wip/raresv/popoverRebasedOnTracker: 2/7] work so far



commit c2bff89e86da1c0d7bf20e0b1e4fccf2a029242f
Author: raresv <rares visalom gmail com>
Date:   Sat Jun 18 15:52:52 2016 +0300

    work so far

 data/org.gnome.Polari.data.gresource.xml           |    2 +-
 .../{user-list-details.ui => user-details.ui}      |   61 +++++++++--
 po/POTFILES.in                                     |    2 +-
 src/chatView.js                                    |   67 ++++++++++--
 src/userList.js                                    |  109 +++++++++++++++++---
 5 files changed, 203 insertions(+), 38 deletions(-)
---
diff --git a/data/org.gnome.Polari.data.gresource.xml b/data/org.gnome.Polari.data.gresource.xml
index 542288e..65ee61b 100644
--- a/data/org.gnome.Polari.data.gresource.xml
+++ b/data/org.gnome.Polari.data.gresource.xml
@@ -12,6 +12,6 @@
     <file alias="ui/main-window.ui" preprocess="xml-stripblanks">resources/main-window.ui</file>
     <file alias="ui/room-list-header.ui" preprocess="xml-stripblanks">resources/room-list-header.ui</file>
     <file alias="ui/room-list-row.ui" preprocess="xml-stripblanks">resources/room-list-row.ui</file>
-    <file alias="ui/user-list-details.ui" preprocess="xml-stripblanks">resources/user-list-details.ui</file>
+    <file alias="ui/user-details.ui" preprocess="xml-stripblanks">resources/user-details.ui</file>
   </gresource>
 </gresources>
diff --git a/data/resources/user-list-details.ui b/data/resources/user-details.ui
similarity index 62%
rename from data/resources/user-list-details.ui
rename to data/resources/user-details.ui
index 2ff4eb3..c10dd16 100644
--- a/data/resources/user-list-details.ui
+++ b/data/resources/user-details.ui
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <template class="Gjs_UserListDetails" parent="GtkFrame">
+  <template class="Gjs_UserDetails" parent="GtkFrame">
     <property name="visible">True</property>
     <property name="hexpand">True</property>
     <child>
@@ -36,13 +36,13 @@
             <property name="hexpand">True</property>
             <property name="visible">True</property>
             <child>
-              <object class="GtkLabel" id="fullnameLabel">
-                <property name="ellipsize">end</property>
-                <property name="halign">start</property>
+              <object class="GtkImage">
+                <property name="icon-name">document-open-recent-symbolic</property>
                 <property name="visible">True</property>
+                <property name="halign">start</property>
               </object>
               <packing>
-                <property name="width">2</property>
+                <property name="width">1</property>
                 <property name="top-attach">0</property>
                 <property name="left-attach">0</property>
               </packing>
@@ -51,11 +51,13 @@
               <object class="GtkLabel" id="lastHeader">
                 <property name="label" translatable="yes">Last Activity:</property>
                 <property name="valign">start</property>
+                <property name="halign">start</property>
                 <property name="use-markup">True</property>
                 <property name="visible">True</property>
+                <property name="margin-start">17</property>
               </object>
               <packing>
-                <property name="top-attach">1</property>
+                <property name="top-attach">0</property>
                 <property name="left-attach">0</property>
               </packing>
             </child>
@@ -68,17 +70,56 @@
                 <property name="visible">True</property>
               </object>
               <packing>
-                <property name="top-attach">1</property>
+                <property name="top-attach">0</property>
                 <property name="left-attach">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkImage">
+                <property name="icon-name">avatar-default-symbolic</property>
+                <property name="visible">True</property>
+                <property name="halign">start</property>
+              </object>
+              <packing>
+                <property name="width">1</property>
+                <property name="top-attach">1</property>
+                <property name="left-attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="fullnameLabel">
+                <property name="ellipsize">end</property>
+                <property name="halign">start</property>
+                <property name="visible">True</property>
+                <property name="margin-start">17</property>
+              </object>
+              <packing>
+                <property name="width">2</property>
+                <property name="top-attach">1</property>
+                <property name="left-attach">0</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkSeparator" id="separator">
+            <property name="visible">True</property>
+            <property name="margin-top">10</property>
           </object>
         </child>
         <child>
-          <object class="GtkButton" id="messageButton">
+          <object class="GtkModelButton" id="messageButton">
             <property name="label" translatable="yes">Message</property>
-            <property name="margin-top">12</property>
-            <property name="halign">end</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+            <property name="visible">True</property>
+            <property name="no-show-all">False</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkModelButton" id="pastActivityButton">
+            <property name="label" translatable="yes">View Past Activity</property>
+            <property name="halign">start</property>
             <property name="hexpand">True</property>
             <property name="visible">True</property>
           </object>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c011eeb..617311a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -9,7 +9,7 @@ data/resources/join-room-dialog.ui
 data/resources/main-window.ui
 data/resources/menus.ui
 data/resources/room-list-header.ui
-data/resources/user-list-details.ui
+data/resources/user-details.ui
 src/application.js
 src/appNotifications.js
 src/chatView.js
diff --git a/src/chatView.js b/src/chatView.js
index 265413e..27bfcff 100644
--- a/src/chatView.js
+++ b/src/chatView.js
@@ -15,6 +15,7 @@ const PasteManager = imports.pasteManager;
 const Signals = imports.signals;
 const Utils = imports.utils;
 const UserTracker = imports.userTracker;
+const userList = imports.userList;
 
 const MAX_NICK_CHARS = 8;
 const IGNORE_STATUS_TIME = 5;
@@ -1168,15 +1169,17 @@ const ChatView = new Lang.Class({
                 let tags = [this._lookupTag('nick')];
                 let nickTagName = this._getNickTagName(message.nick);
                 let nickTag = this._lookupTag(nickTagName);
+                let buffer = this._view.get_buffer();
 
                 if (!nickTag) {
-                    nickTag = this._createNickTag(message.nick);
-                    this._view.get_buffer().get_tag_table().add(nickTag);
+                    nickTag = this._createNickTag(nickTagName);
+                    buffer.get_tag_table().add(nickTag);
                 }
                 tags.push(nickTag);
                 if (needsGap)
                     tags.push(this._lookupTag('gap'));
-                this._insertWithTags(iter, message.nick + '\t', tags);
+                this._insertWithTags(iter, message.nick, tags);
+                buffer.insert(iter, '\t', -1);
             }
             state.lastNick = message.nick;
             tags.push(this._lookupTag('message'));
@@ -1208,15 +1211,6 @@ const ChatView = new Lang.Class({
         this._insertWithTags(iter, text.substr(pos), tags);
     },
 
-    _createNickTag: function(nickName) {
-        let nickTagName = this._getNickTagName(nickName);
-
-        let tag = new Gtk.TextTag({ name: nickTagName });
-        this._updateNickTag(tag, this._userTracker.getNickStatus(nickName));
-
-        return tag;
-    },
-
     _updateNickTag: function(tag, status) {
         if (status == Tp.ConnectionPresenceType.AVAILABLE)
             tag.foreground_rgba = this._activeNickColor;
@@ -1224,6 +1218,55 @@ const ChatView = new Lang.Class({
             tag.foreground_rgba = this._inactiveNickColor;
     },
 
+    _createNickTag: function(name) {
+        let tag = new ButtonTag({ name: name });
+        tag._popover = new userList.UserPopover({ relative_to: this._view });
+        tag.connect('clicked', Lang.bind(this,
+            function() {
+                let view = this._view;
+                let event = Gtk.get_current_event();
+                let [, eventX, eventY] = event.get_coords();
+                let [x, y] = view.window_to_buffer_coords(Gtk.TextWindowType.WIDGET,
+                                                          eventX, eventY);
+                let [inside, start] = view.get_iter_at_location(x, y);
+                let end = start.copy();
+
+                start.backward_to_tag_toggle(tag);
+                end.forward_to_tag_toggle(tag);
+
+                //log(view.get_buffer().get_slice(start, end, false));
+
+                let rect1 = view.get_iter_location(start);
+                let rect2 = view.get_iter_location(end);
+
+                [rect1.x, rect1.y] = view.buffer_to_window_coords(Gtk.TextWindowType.WIDGET, rect1.x, 
rect1.y);
+                [rect2.x, rect2.y] = view.buffer_to_window_coords(Gtk.TextWindowType.WIDGET, rect2.x, 
rect2.y);
+                rect1.width = rect2.x - rect1.x;
+                rect1.height = rect2.y - rect1.y;
+
+                //TODO: special chars?
+                let actualNickName = view.get_buffer().get_slice(start, end, false);
+
+                tag._popover.fallbackNick = actualNickName;
+
+                for (let i = 0; i < tag._contacts.length; i++) {
+                    //log(tag._contacts[i].alias);
+                    if (actualNickName == tag._contacts[i].alias) {
+                        if (!tag._popover.user) {
+                            tag._popover.user = tag._contacts[i];
+                        }
+                        else if (tag._popover.user != tag._contacts[i]) {
+                            tag._popover.user = tag._contacts[i];
+                        }
+                    }
+                }
+
+                tag._popover.pointing_to = rect1;
+                tag._popover.show_all();
+            }));
+        return tag;
+    },
+
     _createUrlTag: function(url) {
         if (url.indexOf(':') == -1)
             url = 'http://' + url;
diff --git a/src/userList.js b/src/userList.js
index 6009c1d..1848df5 100644
--- a/src/userList.js
+++ b/src/userList.js
@@ -99,17 +99,19 @@ const UserListPopover = new Lang.Class({
     }
 });
 
-const UserListDetails = new Lang.Class({
-    Name: 'UserListDetails',
+const UserDetails = new Lang.Class({
+    Name: 'UserDetails',
     Extends: Gtk.Frame,
-    Template: 'resource:///org/gnome/Polari/ui/user-list-details.ui',
+    Template: 'resource:///org/gnome/Polari/ui/user-details.ui',
     InternalChildren: ['spinnerBox',
                        'spinner',
                        'detailsGrid',
                        'fullnameLabel',
                        'lastHeader',
                        'lastLabel',
-                       'messageButton'],
+                       'separator',
+                       'messageButton',
+                       'pastActivityButton'],
     Properties: { 'expanded': GObject.ParamSpec.boolean('expanded',
                                                         'expanded',
                                                         'expanded',
@@ -117,19 +119,29 @@ const UserListDetails = new Lang.Class({
                                                         false)},
 
     _init: function(params) {
-        this._user = params.user;
-        delete params.user;
-
         this._expanded = false;
 
-        this.parent(params);
+        this.parent();
 
         this._messageButton.connect('clicked',
-                                    Lang.bind(this, this._onButtonClicked));
+                                    Lang.bind(this, this._onMessageButtonClicked));
+        //this._user.connection.connect('notify::self-contact',
+        //                              Lang.bind(this, this._updateButtonVisibility));
+        this._updateButtonVisibility();
+        this._detailsGrid.hide();
+    },
+
+    set user(user) {
+        this._user = user;
         this._user.connection.connect('notify::self-contact',
                                       Lang.bind(this, this._updateButtonVisibility));
         this._updateButtonVisibility();
-        this._detailsGrid.hide();
+    },
+
+    set fallbackNick(fallbackNick) {
+        this._fallbackNick = fallbackNick;
+
+        this._updateButtonVisibility();
     },
 
     get expanded() {
@@ -157,8 +169,11 @@ const UserListDetails = new Lang.Class({
         this._spinner.start();
 
         this._cancellable = new Gio.Cancellable();
-        this._user.request_contact_info_async(this._cancellable,
+
+        if (this._user)
+            this._user.request_contact_info_async(this._cancellable,
                                               Lang.bind(this, this._onContactInfoReady));
+        //TODO: else use this._falbackNick to quert tracker
     },
 
     _unexpand: function() {
@@ -230,7 +245,7 @@ const UserListDetails = new Lang.Class({
         this._detailsGrid.show();
     },
 
-    _onButtonClicked: function() {
+    _onMessageButtonClicked: function() {
         let account = this._user.connection.get_account();
 
         let app = Gio.Application.get_default();
@@ -244,11 +259,74 @@ const UserListDetails = new Lang.Class({
     },
 
     _updateButtonVisibility: function() {
+        if (!this._user) {
+            this._messageButton.visible = false;
+
+            return;
+        }
+
         let visible = this._user != this._user.connection.self_contact;
         this._messageButton.visible = visible;
     }
 });
 
+const UserPopover = new Lang.Class({
+    Name: 'UserPopover',
+    Extends: Gtk.Popover,
+
+    _init: function(params) {
+        this.parent(params);
+
+        this._nickLabel = new Gtk.Label({ halign: Gtk.Align.START, margin_left: 5 });
+        this._statusLabel = new Gtk.Label({ halign: Gtk.Align.START, margin_left: 5 });
+        //this._userDetails = new UserDetails();
+
+        this._vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL });
+        this._vbox.add(this._nickLabel);
+        this._vbox.add(this._statusLabel);
+        //this._vbox.add(this._userDetails);
+
+        this.add(this._vbox);
+    },
+
+    set user(user) {
+        this._user  = user;
+
+        this._populateUserPopover();
+    },
+
+    get user() {
+        return this._user;
+    },
+
+    set fallbackNick(fallbackNick) {
+        this._fallbackNick = fallbackNick;
+
+        this._populateUserPopover();
+    },
+
+    _populateUserPopover: function() {
+        this._nickLabel.set_label(this._user ? this._user.alias : this._fallbackNick);
+        this._statusLabel.set_label(this._user ? "ONLINE" : "OFFLINE");
+
+
+        if (this._userDetails)
+            this._userDetails.destroy();
+
+        this._userDetails = new UserDetails();
+
+        if (this._user) {
+            this._userDetails.user = this._user;
+        }
+
+        this._userDetails.fallbackNick = this._fallbackNick;
+
+        this.bind_property('visible', this._userDetails, 'expanded', 0);
+
+        this._vbox.add(this._userDetails);
+    }
+});
+
 const UserListRow = new Lang.Class({
     Name: 'UserListRow',
     Extends: Gtk.ListBoxRow,
@@ -291,7 +369,7 @@ const UserListRow = new Lang.Class({
         let hbox = new Gtk.Box({ margin: 4, spacing: 4 });
         this._arrow = new Gtk.Arrow({ arrow_type: Gtk.ArrowType.RIGHT,
                                       no_show_all: true });
-        hbox.add(new Gtk.Image({ icon_name: 'avatar-default-symbolic' }));
+        //hbox.add(new Gtk.Image({ icon_name: 'avatar-default-symbolic' }));
         this._label = new Gtk.Label({ label: this._user.alias,
                                       halign: Gtk.Align.START,
                                       hexpand: true,
@@ -312,7 +390,10 @@ const UserListRow = new Lang.Class({
         if (this._revealer.get_child())
             return;
 
-        let details = new UserListDetails({ user: this._user })
+        //let details = new UserDetails({ user: this._user });
+        let details = new UserDetails();
+        details.user = this._user;
+
         this._revealer.bind_property('reveal-child', details, 'expanded', 0);
 
         this._revealer.add(details);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]