[polari/wip/raresv/nick-popover: 138/149] chatView: Split out status tracking
- From: Rares Visalom <raresvisalom src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari/wip/raresv/nick-popover: 138/149] chatView: Split out status tracking
- Date: Tue, 6 Sep 2016 19:54:52 +0000 (UTC)
commit ee04efb54e1c3167a0302096a3d266198c1e05ad
Author: raresv <rares visalom gmail com>
Date: Sun Aug 21 17:14:04 2016 +0300
chatView: Split out status tracking
As we want a new stand-alone way of tracking user status across
rooms, we want this code to be placed separately from other
modules in the app. As consequence, all the code that is related
to user status tracking needs to be split out from the ChatView
and moved to the new UserTracker module.
src/chatView.js | 104 ++++++--------------------
src/org.gnome.Polari.src.gresource.xml | 1 +
src/userTracker.js | 129 ++++++++++++++++++++++++++++++++
3 files changed, 153 insertions(+), 81 deletions(-)
---
diff --git a/src/chatView.js b/src/chatView.js
index 33e9f42..8563072 100644
--- a/src/chatView.js
+++ b/src/chatView.js
@@ -14,6 +14,7 @@ const Mainloop = imports.mainloop;
const PasteManager = imports.pasteManager;
const Signals = imports.signals;
const Utils = imports.utils;
+const UserTracker = imports.userTracker;
const MAX_NICK_CHARS = 8;
const IGNORE_STATUS_TIME = 5;
@@ -293,6 +294,9 @@ const ChatView = new Lang.Class({
this._initialPending = [];
this._statusCount = { left: 0, joined: 0, total: 0 };
+ this._userTracker = new UserTracker.UserTracker(this._room);
+ this._userTracker.connect('status-changed', Lang.bind(this, this._onNickStatusChanged));
+
this._room.account.connect('notify::nickname', Lang.bind(this,
function() {
this._updateMaxNickChars(this._room.account.nickname.length);
@@ -384,19 +388,6 @@ const ChatView = new Lang.Class({
});
},
- _foreachNickTag: function(func) {
- let tagTable = this._view.get_buffer().get_tag_table();
- tagTable.foreach(function(tag) {
- if (tag._contacts)
- func(tag);
- });
- },
-
- _resetNickTag: function(nickTag) {
- nickTag._contacts = [];
- this._updateTagStatus(nickTag);
- },
-
_onStyleUpdated: function() {
let context = this.get_style_context();
context.save();
@@ -448,8 +439,6 @@ const ChatView = new Lang.Class({
tag[prop] = tagProps[prop];
}
});
-
- this._foreachNickTag(t => { this._updateTagStatus(t); });
},
vfunc_destroy: function() {
@@ -554,15 +543,6 @@ const ChatView = new Lang.Class({
if (!this._channel)
return;
-
- if (this._room.type == Tp.HandleType.ROOM) {
- let members = this._channel.group_dup_members_contacts();
- for (let j = 0; j < members.length; j++)
- this._trackContact(members[j]);
- } else {
- this._trackContact(this._channel.connection.self_contact);
- this._trackContact(this._channel.target_contact);
- }
},
get max_nick_chars() {
@@ -836,40 +816,6 @@ const ChatView = new Lang.Class({
return NICKTAG_PREFIX + Polari.util_get_basenick(nick);
},
- _trackContact: function(contact) {
- let nickTag = this._lookupTag(this._getNickTagName(contact.alias));
- if (!nickTag)
- return;
-
- let alreadyTracked = nickTag._contacts.some(c => c.alias == contact.alias);
-
- if (!alreadyTracked)
- nickTag._contacts.push(contact);
-
- this._updateTagStatus(nickTag);
- },
-
- _untrackContact: function(contact) {
- let nickTag = this._lookupTag(this._getNickTagName(contact.alias));
- if (!nickTag)
- return;
-
- let indexToDelete = nickTag._contacts.map(c => c.alias).indexOf(contact.alias);
-
- if (indexToDelete > -1) {
- nickTag._contacts.splice(indexToDelete, 1);
-
- this._updateTagStatus(nickTag);
- }
- },
-
- _updateTagStatus: function(tag) {
- if (tag._contacts.length == 0)
- tag.foreground_rgba = this._inactiveNickColor;
- else
- tag.foreground_rgba = this._activeNickColor;
- },
-
_onChannelChanged: function() {
if (this._channel == this._room.channel)
return;
@@ -891,19 +837,6 @@ const ChatView = new Lang.Class({
: this._room.account.nickname;
this._updateMaxNickChars(nick.length);
- if (this._channel) {
- if (this._room.type == Tp.HandleType.ROOM) {
- let members = this._channel.group_dup_members_contacts();
- for (let j = 0; j < members.length; j++)
- this._trackContact(members[j]);
- } else {
- this._trackContact(this._channel.connection.self_contact);
- this._trackContact(this._channel.target_contact);
- }
- } else {
- this._foreachNickTag(t => { this._resetNickTag(t); });
- }
-
if (!this._channel)
return;
@@ -928,8 +861,6 @@ const ChatView = new Lang.Class({
_onMemberRenamed: function(room, oldMember, newMember) {
let text = _("%s is now known as %s").format(oldMember.alias, newMember.alias);
this._insertStatus(text, oldMember.alias, 'renamed');
- this._untrackContact(oldMember);
- this._trackContact(newMember);
},
_onMemberDisconnected: function(room, member, message) {
@@ -937,7 +868,6 @@ const ChatView = new Lang.Class({
if (message)
text += ' (%s)'.format(message);
this._insertStatus(text, member.alias, 'left');
- this._untrackContact(member);
},
_onMemberKicked: function(room, member, actor) {
@@ -946,7 +876,6 @@ const ChatView = new Lang.Class({
actor.alias)
: _("%s has been kicked").format(member.alias);
this._insertStatus(message, member.alias, 'left');
- this._untrackContact(member);
},
_onMemberBanned: function(room, member, actor) {
@@ -955,13 +884,11 @@ const ChatView = new Lang.Class({
actor.alias)
: _("%s has been banned").format(member.alias)
this._insertStatus(message, member.alias, 'left');
- this._untrackContact(member);
},
_onMemberJoined: function(room, member) {
let text = _("%s joined").format(member.alias);
this._insertStatus(text, member.alias, 'joined');
- this._trackContact(member);
},
_onMemberLeft: function(room, member, message) {
@@ -971,7 +898,6 @@ const ChatView = new Lang.Class({
text += ' (%s)'.format(message);
this._insertStatus(text, member.alias, 'left');
- this._untrackContact(member);
},
_onMessageReceived: function(channel, tpMessage) {
@@ -1194,7 +1120,6 @@ const ChatView = new Lang.Class({
let iter = this._view.buffer.get_end_iter();
this._insertMessage(iter, message, this._state);
- this._trackContact(tpMessage.sender);
if (message.pendingId == undefined /* outgoing */ ||
(this._app.isRoomFocused(this._room) && this._pending.size == 0))
@@ -1237,9 +1162,10 @@ const ChatView = new Lang.Class({
if (!nickTag) {
nickTag = new Gtk.TextTag({ name: nickTagName });
- this._view.get_buffer().get_tag_table().add(nickTag);
- this._resetNickTag(nickTag);
+ this._updateNickTag(nickTag, this._userTracker.getNickStatus(message.nick));
+
+ this._view.get_buffer().get_tag_table().add(nickTag);
}
tags.push(nickTag);
if (needsGap)
@@ -1280,6 +1206,22 @@ const ChatView = new Lang.Class({
this._view.buffer.create_mark(null, iter, true));
},
+ _onNickStatusChanged: function(tracker, nickName, status) {
+ let nickTag = this._lookupTag(this._getNickTagName(nickName));
+
+ if (!nickTag)
+ return;
+
+ this._updateNickTag(nickTag, status);
+ },
+
+ _updateNickTag: function(tag, status) {
+ if (status == Tp.ConnectionPresenceType.AVAILABLE)
+ tag.foreground_rgba = this._activeNickColor;
+ else
+ tag.foreground_rgba = this._inactiveNickColor;
+ },
+
_createUrlTag: function(url) {
if (url.indexOf(':') == -1)
url = 'http://' + url;
diff --git a/src/org.gnome.Polari.src.gresource.xml b/src/org.gnome.Polari.src.gresource.xml
index 4e3a0ec..17dc187 100644
--- a/src/org.gnome.Polari.src.gresource.xml
+++ b/src/org.gnome.Polari.src.gresource.xml
@@ -20,5 +20,6 @@
<file>telepathyClient.js</file>
<file>userList.js</file>
<file>utils.js</file>
+ <file>userTracker.js</file>
</gresource>
</gresources>
diff --git a/src/userTracker.js b/src/userTracker.js
new file mode 100644
index 0000000..5f9ca55
--- /dev/null
+++ b/src/userTracker.js
@@ -0,0 +1,129 @@
+const Polari = imports.gi.Polari;
+const Lang = imports.lang;
+const Tp = imports.gi.TelepathyGLib;
+const Signals = imports.signals;
+const GObject = imports.gi.GObject;
+const Utils = imports.utils;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+
+const UserTracker = new Lang.Class({
+ Name: 'UserTracker',
+ Extends: GObject.Object,
+
+ Signals: {
+ 'status-changed': {
+ flags: GObject.SignalFlags.DETAILED,
+ param_types: [GObject.TYPE_STRING, GObject.TYPE_INT]
+ }
+ },
+
+ _init: function(room) {
+ this.parent();
+
+ this._baseNickContacts = new Map();
+
+ this._room = room;
+
+ this._onRoomAdded(this._room);
+ this._onChannelChanged(this._room);
+ },
+
+ _onRoomAdded: function(room) {
+ let roomSignals = [
+ { name: 'notify::channel',
+ handler: Lang.bind(this, this._onChannelChanged) },
+ { name: 'member-renamed',
+ handler: Lang.bind(this, this._onMemberRenamed) },
+ { name: 'member-disconnected',
+ handler: Lang.bind(this, this._onMemberLeft) },
+ { name: 'member-kicked',
+ handler: Lang.bind(this, this._onMemberLeft) },
+ { name: 'member-banned',
+ handler: Lang.bind(this, this._onMemberLeft) },
+ { name: 'member-joined',
+ handler: Lang.bind(this, this._onMemberJoined) },
+ { name: 'member-left',
+ handler: Lang.bind(this, this._onMemberLeft) }
+ ];
+
+ roomSignals.forEach(Lang.bind(this, function(signal) {
+ room.connect(signal.name, signal.handler);
+ }));
+ }
+
+ _onChannelChanged: function(room) {
+ if (!room.channel) {
+ this._clearUsers();
+ return;
+ }
+
+ let members;
+ if (room.type == Tp.HandleType.ROOM)
+ members = room.channel.group_dup_members_contacts();
+ else
+ members = [room.channel.connection.self_contact, room.channel.target_contact];
+
+ members.forEach(m => { this._trackMember(m); });
+ },
+
+ _clearUsers: function() {
+ for ([baseNick, contacts] of this._baseNickContacts)
+ contacts.slice().forEach((m) => { this._untrackMember(m); });
+ },
+
+ _onMemberRenamed: function(room, oldMember, newMember) {
+ this._untrackMember(oldMember);
+ this._trackMember(newMember);
+ },
+
+ _onMemberJoined: function(room, member) {
+ this._trackMember(member);
+ },
+
+ _onMemberLeft: function(room, member) {
+ this._untrackMember(member);
+ },
+
+ _pushMember: function(baseNick, member) {
+ if (!this._baseNickContacts.has(baseNick))
+ this._baseNickContacts.set(baseNick, []);
+ let contacts = this._baseNickContacts.get(baseNick);
+ return contacts.push(member);
+ },
+
+ _trackMember: function(member) {
+ let baseNick = Polari.util_get_basenick(member.alias);
+ let status = Tp.ConnectionPresenceType.AVAILABLE;
+
+ if (this._pushMember(baseNick, member) == 1)
+ this.emit("status-changed::" + baseNick, baseNick, status);
+ },
+
+ _popMember: function(baseNick, member) {
+ let contacts = this._baseNickContacts.get(baseNick) || [];
+ let index = contacts.map(c => c.alias).indexOf(member.alias);
+ if (index < 0)
+ return [false, contacts.length];
+ contacts.splice(index, 1);
+ return [true, contacts.length];
+ },
+
+ _untrackMember: function(member) {
+ let baseNick = Polari.util_get_basenick(member.alias);
+ let status = Tp.ConnectionPresenceType.OFFLINE;
+
+ let [found, nContacts] = this._popMember(baseNick, member);
+ if (found)
+ if (nContacts == 0)
+ this.emit("status-changed::" + baseNick, member.alias, status);
+ },
+
+ getNickStatus: function(nickName) {
+ let baseNick = Polari.util_get_basenick(nickName);
+
+ let contacts = this._baseNickContacts.get(baseNick) || [];
+ return contacts.length == 0 ? Tp.ConnectionPresenceType.OFFLINE
+ : Tp.ConnectionPresenceType.AVAILABLE;
+ }
+});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]