Bug 955653 - Show a notification bar in the awesometab while log sweeping, r=florian.
--- a/im/components/ibConvStatsService.js
+++ b/im/components/ibConvStatsService.js
@@ -38,22 +38,25 @@ var gStatsByConvId = {};
// or it was loaded from the JSON cache file).
var gStatsByContactId;
// Recursively sweeps log folders and parses log files for conversation statistics.
var gLogParser = {
_statsService: null,
_accounts: [],
_logFolders: [],
+ inProgress: false,
// The general path of a log is logs/prpl/account/conv/date.json.
// First, sweep the logs folder for prpl folders.
sweep: function(aStatsService) {
+ initLogModule("stats-service-log-sweeper", this);
+ this.inProgress = true;
this._statsService = aStatsService;
- initLogModule("stats-service-log-sweeper", this);
+ this._statsService._notifyObservers("log-sweeping", "ongoing");
let logsPath = OS.Path.join(OS.Constants.Path.profileDir, "logs");
let iterator = new OS.File.DirectoryIterator(logsPath);
iterator.nextBatch().then((function(aEntries) {
// Filter out any stray files (e.g. system files).
aEntries = aEntries.filter(function(e) e.isDir);
this._sweepPrpls(aEntries);
}).bind(this), function(aError) {
if (aError instanceof OS.File.Error && !aError.becauseNoSuchFile)
@@ -110,19 +113,21 @@ var gLogParser = {
_sweepLogFolder: function(aLogs) {
aLogs = aLogs.filter(function(l) l.name.endsWith(".json"));
let decoder = new TextDecoder();
let __sweepLogFolder = function() {
if (!aLogs.length) {
if (this._logFolders.length)
this._sweepLogFolders();
else { // We're done.
+ delete this.inProgress;
let statsService = this._statsService;
statsService._cacheAllStats(); // Flush stats to JSON cache.
statsService._convs.sort(statsService._sortComparator);
+ statsService._notifyObservers("log-sweeping", "done");
gStatsByContactId = {}; // Initialize stats cache for contacts.
}
return;
}
let log = aLogs.shift().path;
OS.File.read(log).then(function(aArray) {
// Try to parse the log file. If anything goes wrong here, the log file
// has likely been tampered with so we ignore it and move on.
@@ -369,16 +374,21 @@ ConvStatsService.prototype = {
});
});
});
}
return new nsSimpleEnumerator(filteredConvs);
},
_cacheAllStats: function() {
+ // Don't save anything to the JSON file until log sweeping is done. This is to
+ // ensure that a re-sweep is triggered on next startup if log sweeping could
+ // not complete.
+ if (gLogParser.inProgress)
+ return;
let encoder = new TextEncoder();
let objToWrite = {version: gStatsCacheVersion, stats: gStatsByConvId};
OS.File.writeAtomic(this._statsCacheFilePath,
encoder.encode(JSON.stringify(objToWrite)),
{tmpPath: this._statsCacheFilePath + ".tmp"});
if (this._statsCacheUpdateTimer) {
clearTimeout(this._statsCacheUpdateTimer);
delete this._statsCacheUpdateTimer;
@@ -414,30 +424,33 @@ ConvStatsService.prototype = {
}
},
addObserver: function(aObserver) {
if (this._observers.indexOf(aObserver) != -1)
return;
this._observers.push(aObserver);
+ if (gLogParser.inProgress)
+ aObserver.observe(this, "stats-service-log-sweeping", "ongoing");
+
this._repositionConvsWithUpdatedStats();
// We request chat lists from accounts when adding new observers.
this._requestRoomInfo();
},
removeObserver: function(aObserver) {
this._observers = this._observers.filter(function(o) o !== aObserver);
},
- _notifyObservers: function(aTopic) {
+ _notifyObservers: function(aTopic, aData) {
for each (let observer in this._observers) {
if ("observe" in observer) // Avoid failing on destructed XBL bindings.
- observer.observe(this, "stats-service-" + aTopic);
+ observer.observe(this, "stats-service-" + aTopic, aData);
}
},
// Maps prplConversation ids to their ConversationStats objects.
_statsByPrplConvId: new Map(),
// Maps prplConversation ids to the corresponding PossibleConversations.
_convsByPrplConvId: new Map(),
// These will be repositioned to reflect their new scores when a newtab is opened.
@@ -497,19 +510,17 @@ ConvStatsService.prototype = {
let chatList = this._chatsByAccountIdAndName.get(conv.account.id);
if (chatList && chatList.has(conv.normalizedName))
possibleConv = chatList.get(conv.name);
}
this._convsByPrplConvId.set(conv.id, possibleConv);
}
else if (aTopic == "conversation-closed")
this._statsByPrplConvId.delete(aSubject.id);
- if (kNotificationsToObserve.indexOf(aTopic) == -1)
- return;
- if (aTopic == "contact-no-longer-dummy") {
+ else if (aTopic == "contact-no-longer-dummy") {
// Contact ID changed. aData is the old ID.
let id = aSubject.id;
let oldId = parseInt(aData, 10);
this._contactsById.set(id, this._contactsById.get(oldId));
this._contactsById.delete(oldId);
this._contactsById.get(id)._contactId = id;
return;
}
--- a/im/content/blist.css
+++ b/im/content/blist.css
@@ -149,10 +149,10 @@ conv {
}
/* Make the notification bar work with narrow windows. */
.notification-inner > hbox {
display: inline-block;
}
.notification-inner > hbox > .messageImage {
- display: none;
+ max-width: 0;
}
--- a/im/content/newtab.xml
+++ b/im/content/newtab.xml
@@ -19,17 +19,19 @@
</resources>
<content>
<xul:vbox flex="1">
<xul:toolbar class="newtab-toolbar">
<xul:textbox class="filterbox" anonid="filterbox" type="search"
placeholder="&filterbox.placeholder;" flex="1"/>
</xul:toolbar>
- <xul:richlistbox anonid="newtab-listbox" class="newtab-listbox" flex="1"/>
+ <xul:notificationbox anonid="newtab-notifications" flex="1">
+ <xul:richlistbox anonid="newtab-listbox" class="newtab-listbox" flex="1"/>
+ </xul:notificationbox>
</xul:vbox>
</content>
<implementation implements="nsIObserver">
<property name="statsService" readonly="true">
<getter>
<![CDATA[
if (!this._statsService) {
@@ -317,16 +319,31 @@
<!-- nsIObserver implementation -->
<method name="observe">
<parameter name="aSubject"/>
<parameter name="aTopic"/>
<parameter name="aData"/>
<body>
<![CDATA[
+ if (aTopic == "stats-service-log-sweeping") {
+ let nb = document.getAnonymousElementByAttribute(this, "anonid",
+ "newtab-notifications");
+ let notification = nb.getNotificationWithValue("log-sweeping");
+ if (aData == "ongoing" && !notification) {
+ let notificationText =
+ Services.strings.createBundle("chrome://instantbird/locale/newtab.properties")
+ .GetStringFromName("newtab.logSweepingInProgress");
+ nb.appendNotification(notificationText, "log-sweeping", "",
+ nb.PRIORITY_WARNING_MEDIUM, []);
+ }
+ else if (aData == "done" && notification)
+ nb.removeNotification(notification);
+ return;
+ }
this._forceRefresh = true;
this.refresh();
]]>
</body>
</method>
</implementation>
<handlers>
--- a/im/locales/en-US/chrome/instantbird/newtab.properties
+++ b/im/locales/en-US/chrome/instantbird/newtab.properties
@@ -1,6 +1,7 @@
# 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/.
newtab.label=New Conversation
+newtab.logSweepingInProgress=Optimizing conversation suggestions…
existingConv.infoText=Switch to conversation