Skip to content

Instantly share code, notes, and snippets.

@freaktechnik
Created March 20, 2019 20:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freaktechnik/a5cbf5e27b5bf2110e000ff670136201 to your computer and use it in GitHub Desktop.
Save freaktechnik/a5cbf5e27b5bf2110e000ff670136201 to your computer and use it in GitHub Desktop.
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
this.EXPORTED_SYMBOLS = [ 'ConversationStatusUtils' ];
const {Services} = ChromeUtils.import("resource:///modules/imServices.jsm");
const CHAT_TAB_HIDDEN_TOPIC = "chat-tab-hidden";
const CHAT_TAB_SHOWN_TOPIC = "chat-tab-shown";
const CONVERSATION_VISIBLE_TOPIC = "conversation-visible";
const CONVERSATION_HIDDEN_TOPIC = "conversation-hidden";
const ConversationStatusUtils = {
observersRegisterd: false,
listeners: new Map(),
windowsWithConvTab: new Set(),
conversations: new Map(),
attachListeners() {
Services.ww.registerNotification(this);
Services.obs.addObserver(this, CHAT_TAB_HIDDEN_TOPIC);
Services.obs.addObserver(this, CHAT_TAB_SHOWN_TOPIC);
Services.obs.addObserver(this, CONVERSATION_VISIBLE_TOPIC);
Services.obs.addObserver(this, CONVERSATION_HIDDEN_TOPIC);
this.observersRegisterd = true;
},
removeListeners() {
if(this.listeners.size) {
throw new Error("There are still conversation state listeners registered, can't remove observers");
}
Services.ww.unregisterNotification(this);
Services.obs.removeObserver(this, CHAT_TAB_HIDDEN_TOPIC);
Services.obs.removeObserver(this, CHAT_TAB_SHOWN_TOPIC);
Services.obs.removeObserver(this, CONVERSATION_VISIBLE_TOPIC);
Services.obs.removeObserver(this, CONVERSATION_HIDDEN_TOPIC);
this.observersRegisterd = false;
this.windowsWithConvTab.clear();
},
observe(aSubject, aTopic, aData) {
if(aTopic === 'donwindowclosed') {
const windowID = aSubject.windowUtils.outerWindowID;
for(const aConv of this.conversations.keys()) {
this.updateSet(aConv, windowID, false);
}
this.updateSet(null, windowID, false);
}
else if(aTopic === CHAT_TAB_HIDDEN_TOPIC) {
const windowID = aSubject.windowUtils.outerWindowID;
this.updateSet(null, windowID, false);
}
else if(aTopic === CHAT_TAB_SHOWN_TOPIC) {
const windowID = aSubject.windowUtils.outerWindowID;
this.updateSet(null, windowID, true);
}
else if(aTopic === CONVERSATION_HIDDEN_TOPIC) {
const windowID = aData;
this.updateSet(aSubject, windowID, false);
}
else if(aTopic === CONVERSATION_VISIBLE_TOPIC) {
const windowID = aData;
this.updateSet(aSubject, windowID, true);
}
//TODO track convs being opened in windows if that doesn't happen with conv visible
},
registerNotification(aConv, aObserver) {
if(!this.listeners.has(aConv)) {
this.listeners.add(aConv, new Set());
}
this.listeners.get(aConv).add(aObserver);
this.conversations.set(aConv, new Set());
if(!this.observersRegisterd) {
this.attachListeners();
}
//TODO get windows conversation is opened in
},
unregisterNotification(aConv, aObserver) {
const convListeners = this.listeners.get(aConv);
convListeners.delete(aObserver);
if(!convListeners.size) {
this.listeners.delete(aConv);
}
// this.conversations.get(aConv).clear(); shouldn't be needed since we just store strings?
this.conversations.delete(aConv);
if(noMoreListeners && this.observersRegisterd) {
this.removeListeners();
}
},
notifyListeners(aConv, aTopic) {
let eligibleListeners;
if(!aConv) {
eligibleListeners = Array.from(this.listeners.values(), (l) => Array.from(l)).falt(1);
}
else {
eligibleListeners = Array.from(this.listeners.get(aConv));
}
for(const listener of eligibleListeners) {
listener(aConv, aTopic);
}
},
updateSet(aConv, aWindowID, aShown) {
const windowSet = aConv ? this.conversations.get(aConv) : this.windowsWithConvTab;
const hadWindows = st.size > 0;
if(aShown) {
windowSet.add(aWindowID);
}
else {
windowSet.delete(aWindowID);
}
if(hadWindows != aShown) {
const newSize = windowSet.size;
const convPrefix = aConv ? 'conv' : 'tab';
if(!aShown && hadWindows && newSize === 0) {
this.notifyListeners(aConv, convPrefix + 'hidden');
}
else if(aShown && !hadWindows && newSize > 0) {
this.notifyListeners(aConv, convPrefix + 'shown');
}
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment