[polari/wip/fmuellner/combined-gsoc: 61/136] first try at fixing the conflicts
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari/wip/fmuellner/combined-gsoc: 61/136] first try at fixing the conflicts
- Date: Tue, 26 Jul 2016 23:21:06 +0000 (UTC)
commit e62299c7bb29f95b0afc3facd7c4d61fcbe89de1
Author: raresv <rares visalom gmail com>
Date: Fri Jul 1 23:14:45 2016 +0300
first try at fixing the conflicts
src/application.js | 7 +-
src/chatView.js | 35 +++++--
src/userTracker.js | 279 +++++++++++++++++++++++++++++++++++++++++++---------
3 files changed, 261 insertions(+), 60 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index 82f1a49..2ac60a0 100644
--- a/src/application.js
+++ b/src/application.js
@@ -48,13 +48,8 @@ const Application = new Lang.Class({
this._chatroomManager = ChatroomManager.getDefault();
this._accountsMonitor = AccountsMonitor.getDefault();
this._networkMonitor = Gio.NetworkMonitor.get_default();
+ this._userStatusMonitor = UserTracker.getUserStatusMonitor();
this._networksManager = NetworksManager.getDefault();
- /*created here as i couldn't make it work if it was created in the chatroomManager
- (it didn't receive the room-added signal for the channels restored from the previous session)*/
- /*this._globalUserTracker = new UserTracker.UserTracker(null);
- this._globalUserTracker.connect('status-changed', Lang.bind(this, function(tracker, nick, status){
- log("[Application] nick " + nick + " global status changed to " + status );
- }));*/
this._accountsMonitor.connect('account-removed', Lang.bind(this,
function(am, account) {
diff --git a/src/chatView.js b/src/chatView.js
index 72296cc..e29581e 100644
--- a/src/chatView.js
+++ b/src/chatView.js
@@ -305,11 +305,9 @@ const ChatView = new Lang.Class({
this._pendingLogs = [];
this._initialPending = [];
this._statusCount = { left: 0, joined: 0, total: 0 };
- this._chatroomManager = ChatroomManager.getDefault();
this._logWalker = null;
- this._userTracker = new UserTracker.UserTracker(this._room);
- this._userTracker.connect('status-changed', Lang.bind(this, this._onNickStatusChanged));
+ this._userStatusMonitor = UserTracker.getUserStatusMonitor();
this._room.account.connect('notify::nickname', Lang.bind(this,
function() {
@@ -348,6 +346,9 @@ const ChatView = new Lang.Class({
this._roomSignals.push(room.connect(signal.name, signal.handler));
}));
this._onChannelChanged();
+
+ /*where should we unwatch? int onChannelChanged when we don't have a channel?*/
+ this._roomWatchHandler =
this._userStatusMonitor.getUserTrackerForAccount(this._room.account).watchUser(this._room, null,
Lang.bind(this, this._onStatusChangedCallback));
},
_createTags: function() {
@@ -1213,7 +1214,7 @@ const ChatView = new Lang.Class({
nickTag = this._createNickTag(nickTagName);
buffer.get_tag_table().add(nickTag);
- this._updateNickTag(nickTag, this._userTracker.getNickStatus(message.nick));
+ this._updateNickTag(nickTag,
this._userStatusMonitor.getUserTrackerForAccount(this._room.account).getNickStatus(message.nick));
}
tags.push(nickTag);
if (needsGap)
@@ -1255,6 +1256,28 @@ const ChatView = new Lang.Class({
this._view.buffer.create_mark(null, iter, true));
},
+ _createNickTag: function(nickName) {
+ let nickTagName = this._getNickTagName(nickName);
+
+ let tag = new Gtk.TextTag({ name: nickTagName });
+ //this._updateNickTag(tag,
this._userStatusMonitor.getUserTrackerForAccount(this._room.account).getNickRoomStatus(nickName, this._room));
+ this._updateNickTag(tag, Tp.ConnectionPresenceType.OFFLINE);
+
+ return tag;
+ },
+
+ _onStatusChangedCallback: function(nick, status) {
+ log("Nick " + nick + " has local status " + status);
+
+ let nickTagName = this._getNickTagName(nick);
+ let nickTag = this._lookupTag(nickTagName);
+
+ if (!nickTag)
+ return;
+
+ this._updateNickTag(nickTag, status);
+ },
+
_updateNickTag: function(tag, status) {
if (status == Tp.ConnectionPresenceType.AVAILABLE)
tag.foreground_rgba = this._activeNickColor;
@@ -1264,7 +1287,7 @@ const ChatView = new Lang.Class({
_createNickTag: function(name) {
let tag = new ButtonTag({ name: name });
- tag._popover = new UserList.UserPopover({ relative_to: this._view, margin: 0, room: this._room,
userTracker: this._userTracker });
+ tag._popover = new UserList.UserPopover({ relative_to: this._view, margin: 0, room: this._room,
userTracker: this._userStatusMonitor.getUserTrackerForAccount(this._room.account) });
tag.connect('clicked', Lang.bind(this, this._onNickTagClicked));
return tag;
},
@@ -1298,8 +1321,6 @@ const ChatView = new Lang.Class({
tag._popover.nickname = actualNickName;
- //tag._popover.user = this._userTracker.getBestMatchingContact(actualNickName);
-
tag._popover.pointing_to = rect1;
tag._popover.show();
},
diff --git a/src/userTracker.js b/src/userTracker.js
index d9cac5b..7e78bbd 100644
--- a/src/userTracker.js
+++ b/src/userTracker.js
@@ -4,8 +4,57 @@ const Tp = imports.gi.TelepathyGLib;
const Signals = imports.signals;
const GObject = imports.gi.GObject;
+const AccountsMonitor = imports.accountsMonitor;
const ChatroomManager = imports.chatroomManager;
+let _singleton = null;
+
+function getUserStatusMonitor() {
+ if (_singleton == null)
+ _singleton = new UserStatusMonitor();
+ return _singleton;
+}
+
+const UserStatusMonitor = new Lang.Class({
+ Name: 'UserStatusMonitor',
+
+ _init: function() {
+ this._userTrackersMaping = new Map();
+ this._accountsMonitor = AccountsMonitor.getDefault();
+
+ this._accountsMonitor.connect('account-added', Lang.bind(this, this._onAccountAdded));
+ this._accountsMonitor.connect('account-removed', Lang.bind(this, this._onAccountRemoved));
+ },
+
+ _onAccountAdded: function(accountsMonitor, account) {
+ this._addUserTrackerForAccount(account);
+ },
+
+ _onAccountRemoved: function(accountsMonitor, account) {
+ this._removeUserTrackerForAccount(account);
+ },
+
+ _addUserTrackerForAccount: function(account) {
+ if (this._userTrackersMaping.has(account))
+ return;
+
+ this._userTrackersMaping.set(account, new UserTracker(account));
+ },
+
+ _removeUserTrackerForAccount: function(account) {
+ if (!this._userTrackersMaping.has(account))
+ return;
+
+ this._userTrackersMaping.delete(account);
+ },
+
+ getUserTrackerForAccount: function(account) {
+ if (this._userTrackersMaping.has(account))
+ return this._userTrackersMaping.get(account);
+ return null;
+ }
+});
+
const UserTracker = new Lang.Class({
Name: 'UserTracker',
@@ -18,9 +67,8 @@ const UserTracker = new Lang.Class({
},
},
- _init: function(room) {
+ _init: function(account) {
this.parent();
-
this._referenceRoomSignals = [
{ name: 'notify::channel',
handler: Lang.bind(this, this._onChannelChanged) },
@@ -38,33 +86,50 @@ const UserTracker = new Lang.Class({
handler: Lang.bind(this, this._onMemberLeft) }
];
- this._contactMapping = new Map();
+ this._account = account;
- if (!room) {
- log("global user tracker created");
- this._chatroomManager = ChatroomManager.getDefault();
+ this._globalContactMapping = new Map();
+ this._roomMapping = new Map();
+ this._handlerCounter = 0;
- this._chatroomManager.connect('room-added', Lang.bind(this, this._onRoomAdded));
- this._chatroomManager.connect('room-removed', Lang.bind(this, this._onRoomRemoved));
- } else {
- this._room = room;
+ this._userStatusMonitor = getUserStatusMonitor();
- this._onRoomAdded(null, this._room);
- this._onChannelChanged(this._room);
- }
+ this._chatroomManager = ChatroomManager.getDefault();
+ this._chatroomManager.connect('room-added', Lang.bind(this, this._onRoomAdded));
+ this._chatroomManager.connect('room-removed', Lang.bind(this, this._onRoomRemoved));
+ },
+
+ _onRoomAdded: function(roomManager, room) {
+ if (room.account == this._account)
+ this._connectRoomSignalsForRoom(room);
+ },
+
+ _onRoomRemoved: function(roomManager, room) {
+ if (room.account == this._account)
+ this._disconnectRoomSignalsForRoom(room);
+
+ this._clearUsersFromRoom(this._globalContactMapping, room);
+ this._clearUsersFromRoom(this._roomMapping.get(room)._contactMapping, room);
},
- _onRoomAdded: function(roomManager , room) {
- this._roomSignals = [];
+ _connectRoomSignalsForRoom: function(room) {
+ this._ensureRoomMappingForRoom(room);
+
+ let roomData = this._roomMapping.get(room);
+
+ roomData._roomSignals = [];
this._referenceRoomSignals.forEach(Lang.bind(this, function(signal) {
- this._roomSignals.push(room.connect(signal.name, signal.handler));
+ roomData._roomSignals.push(room.connect(signal.name, signal.handler));
}));
},
- _onRoomRemoved: function(roomManager, room) {
- for (let i = 0; i < this._roomSignals.length; i++)
- room.disconnect(this._roomSignals[i]);
- this._roomSignals = [];
+ _disconnectRoomSignalsForRoom: function(room) {
+ let roomData = this._roomMapping.get(room);
+
+ for (let i = 0; i < roomData._roomSignals.length; i++) {
+ room.disconnect(roomData._roomSignals[i]);
+ }
+ roomData._roomSignals = [];
},
_onChannelChanged: function(emittingRoom) {
@@ -75,84 +140,166 @@ const UserTracker = new Lang.Class({
else
members = [emittingRoom.channel.connection.self_contact,
emittingRoom.channel.target_contact];
+ /*is this needed here?*/
+ this._ensureRoomMappingForRoom(emittingRoom);
+
+ /*if there is no map keeping track of the users in the emittingRoom
+ create it*/
+ if (!this._roomMapping.get(emittingRoom)._contactMapping)
+ this._roomMapping.get(emittingRoom)._contactMapping = new Map();
+
+ /*if there is no map keeping track of the local status change handlers*/
+ this._ensureHandlerMappingForRoom(emittingRoom);
+
+ /*keep track of initial members in the emittingRoom, both locally and
+ globally*/
members.forEach(m => {
m._room = emittingRoom;
- this._trackMember(m);
+ this._trackMember(this._roomMapping.get(emittingRoom)._contactMapping, m, emittingRoom);
+ this._trackMember(this._globalContactMapping, m, emittingRoom);
});
} else {
- for ([baseNick, basenickContacts] of this._contactMapping) {
- basenickContacts.forEach(Lang.bind(this, function(member) {
- if (member._room == emittingRoom)
- this._untrackMember(member);
- }));
-
- this._contactMapping.delete(baseNick);
+ /*handle the absence of a channel for the global case*/
+ this._clearUsersFromRoom(this._globalContactMapping, emittingRoom);
+ /*handle the absence of a channel for the local case*/
+ this._clearUsersFromRoom(this._roomMapping.get(emittingRoom)._contactMapping, emittingRoom);
+
+ /*since we have no channel, all users must be locally marked offline. so call the callbacks*/
+ for ([handlerID, handlerInfo] of this._roomMapping.get(emittingRoom)._handlerMapping) {
+ if (handlerInfo.nickName)
+ handlerInfo.handler(handlerInfo.nickName, Tp.ConnectionPresenceType.OFFLINE);
}
}
},
+ _clearUsersFromRoom: function(mapping, room) {
+ for ([baseNick, basenickContacts] of mapping) {
+ basenickContacts.forEach(Lang.bind(this, function(member) {
+ if (member._room == room)
+ /*safe to delete while iterating?*/
+ this._untrackMember(mapping, member, room);
+ }));
+
+ mapping.delete(baseNick);
+ }
+ },
+
+ _ensureRoomMappingForRoom: function(room) {
+ if (!this._roomMapping.has(room))
+ this._roomMapping.set(room, {});
+ },
+
+ _ensureHandlerMappingForRoom: function(room) {
+ /*if there is no map keeping track of the local status change handlers*/
+ if (!this._roomMapping.get(room)._handlerMapping) {
+ this._roomMapping.get(room)._handlerMapping = new Map();
+ this._handlerCounter = 0;
+ }
+ },
+
_onMemberRenamed: function(room, oldMember, newMember) {
oldMember._room = room;
newMember._room = room;
- this._untrackMember(oldMember);
- this._trackMember(newMember);
+
+ this._untrackMember(this._roomMapping.get(room)._contactMapping, oldMember, room);
+ this._untrackMember(this._globalContactMapping, oldMember, room);
+ this._trackMember(this._roomMapping.get(room)._contactMapping, newMember, room);
+ this._trackMember(this._globalContactMapping, newMember, room);
},
_onMemberDisconnected: function(room, member, message) {
member._room = room;
- this._untrackMember(member);
+
+ this._untrackMember(this._roomMapping.get(room)._contactMapping, member, room);
+ this._untrackMember(this._globalContactMapping, member, room);
},
_onMemberKicked: function(room, member, actor) {
member._room = room;
- this._untrackMember(member);
+
+ this._untrackMember(this._roomMapping.get(room)._contactMapping, member, room);
+ this._untrackMember(this._globalContactMapping, member, room);
},
_onMemberBanned: function(room, member, actor) {
member._room = room;
- this._untrackMember(member);
+
+ this._untrackMember(this._roomMapping.get(room)._contactMapping, member, room);
+ this._untrackMember(this._globalContactMapping, member, room);
},
_onMemberJoined: function(room, member) {
member._room = room;
- this._trackMember(member);
+
+ this._trackMember(this._roomMapping.get(room)._contactMapping, member, room);
+ this._trackMember(this._globalContactMapping, member, room);
},
_onMemberLeft: function(room, member, message) {
member._room = room;
- this._untrackMember(member);
+
+ this._untrackMember(this._roomMapping.get(room)._contactMapping, member, room);
+ this._untrackMember(this._globalContactMapping, member, room);
},
- _trackMember: function(member) {
+ _trackMember: function(map, member, room) {
let baseNick = Polari.util_get_basenick(member.alias);
- if (this._contactMapping.has(baseNick))
- this._contactMapping.get(baseNick).push(member);
+ if (map.has(baseNick))
+ map.get(baseNick).push(member);
else
- this._contactMapping.set(baseNick, [member]);
+ map.set(baseNick, [member]);
- if (this._contactMapping.get(baseNick).length == 1)
- this.emit("status-changed::"+baseNick, member.alias, Tp.ConnectionPresenceType.AVAILABLE);
+ //was on HEAD
+ /*if (this._contactMapping.get(baseNick).length == 1)
+ this.emit("status-changed::"+baseNick, member.alias, Tp.ConnectionPresenceType.AVAILABLE);*/
+ if (map == this._globalContactMapping)log("length: " +
this._globalContactMapping.get(baseNick).length)
+
+ if (map.get(baseNick).length == 1)
+ if (map == this._globalContactMapping) {
+ this.emit("global-status-changed::" + member.alias, Tp.ConnectionPresenceType.AVAILABLE);
+ log("[global status] user " + member.alias + " is globally online");
+ }
+ else
+ //log("[Local UserTracker] User " + member.alias + " is now available in room " +
member._room.channelName + " on " + this._account.get_display_name());
+ for ([handlerID, handlerInfo] of this._roomMapping.get(room)._handlerMapping)
+ if (handlerInfo.nickName == member.alias)
+ handlerInfo.handler(handlerInfo.nickName, Tp.ConnectionPresenceType.AVAILABLE);
+ else if (!handlerInfo.nickName)
+ handlerInfo.handler(member.alias, Tp.ConnectionPresenceType.AVAILABLE);
},
- _untrackMember: function(member) {
+ _untrackMember: function(map, member, room) {
let baseNick = Polari.util_get_basenick(member.alias);
- let contacts = this._contactMapping.get(baseNick) || [];
- let indexToDelete = contacts.map(c => c.alias).indexOf(member.alias);
+ let contacts = map.get(baseNick) || [];
+ /*i really don't like this search. maybe use a for loop?*/
+ let indexToDelete = contacts.map(c => c.alias + "|" + c._room.channelName).indexOf(member.alias +
"|" + member._room.channelName);
if (indexToDelete > -1) {
- contacts.splice(indexToDelete, 1);
+ let removedMember = contacts.splice(indexToDelete, 1)[0];
if (contacts.length == 0)
- this.emit("status-changed::"+baseNick, member.alias, Tp.ConnectionPresenceType.OFFLINE);
+ //was on HEAD
+ /*this.emit("status-changed::"+baseNick, member.alias, Tp.ConnectionPresenceType.OFFLINE);*/
+ if (map == this._globalContactMapping) {
+ this.emit("global-status-changed::" + member.alias, Tp.ConnectionPresenceType.OFFLINE);
+ log("[global status] user " + member.alias + " is globally offline");
+ }
+ else
+ //log("[Local UserTracker] User " + member.alias + " is now offline in room " +
member._room.channelName + " on " + this._account.get_display_name());
+ for ([handlerID, handlerInfo] of this._roomMapping.get(room)._handlerMapping)
+ if (handlerInfo.nickName == member.alias)
+ handlerInfo.handler(handlerInfo.nickName, Tp.ConnectionPresenceType.OFFLINE);
+ else if (!handlerInfo.nickName)
+ handlerInfo.handler(member.alias, Tp.ConnectionPresenceType.OFFLINE);
}
},
getNickStatus: function(nickName) {
let baseNick = Polari.util_get_basenick(nickName);
- let contacts = this._contactMapping.get(baseNick) || [];
+ let contacts = this._globalContactMapping.get(baseNick) || [];
return contacts.length == 0 ? Tp.ConnectionPresenceType.OFFLINE
: Tp.ConnectionPresenceType.AVAILABLE;
},
@@ -170,5 +317,43 @@ const UserTracker = new Lang.Class({
return contacts[i];
return contacts[0];
+ },
+
+ getNickRoomStatus: function(nickName, room) {
+ let baseNick = Polari.util_get_basenick(nickName);
+
+ let contacts = this._roomMapping.get(room)._contactMapping.get(baseNick) || [];
+ return contacts.length == 0 ? Tp.ConnectionPresenceType.OFFLINE
+ : Tp.ConnectionPresenceType.AVAILABLE;
+ },
+
+ watchUser: function(room, nick, callback) {
+ this._ensureRoomMappingForRoom(room);
+ this._ensureHandlerMappingForRoom(room);
+
+ this._roomMapping.get(room)._handlerMapping.set(this._handlerCounter, {
+ nickName: nick,
+ handler: callback
+ });
+
+ this._handlerCounter++;
+
+ return this._handlerCounter - 1;
+ },
+
+ unwatchUser: function(room, nick, handlerID) {
+ /*it wouldn't make sense to call _ensure() here, right?*/
+
+ /*rewrite into a single conditional?*/
+ if (!this._roomMapping)
+ return;
+
+ if (!this._roomMapping.has(room))
+ return;
+
+ if (!this._roomMapping.get(room)._handlerMapping)
+ return;
+
+ this._roomMapping.get(room)._handlerMapping.delete(handlerID);
}
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]