make status notification prettier, part 1 of n

This commit is contained in:
ben%bengoodger.com 2005-06-17 22:55:58 +00:00
Родитель 80de303a96
Коммит dab16d5889
5 изменённых файлов: 251 добавлений и 10 удалений

Просмотреть файл

@ -20,3 +20,17 @@ app.update.url=https://aus.mozilla.org/update2/0/%PRODUCT%/%VERSION%/%BUILD_ID%/
app.update.url.manual=http://www.mozilla.org/update
# This value should be empty unless you wish to override app.update.url
app.update.url.override=
statusFormatKBKB=#1 of #2 KB
statusFormatKBMB=#1 KB of #2 MB
statusFormatMBMB=#1 of #2 MB
statusFormatUnknownKB=#1 KB
statusFormatUnknownMB=#1 MB
remain=remain
unknownFilesize=unknown file size
statusFormat=#1 at #2 KB/sec; #3
longTimeFormat=#1:#2:#3
shortTimeFormat=#2:#3
downloadingPrefix=Downloading %S...
pausedStatus=Download Paused
pausedName=Paused %S

Просмотреть файл

@ -366,6 +366,7 @@ var gDownloadingPage = {
active.startDownload();
active.state = STATE_DOWNLOADING;
active.progress = gUpdates.update.selectedPatch.progress;
active.status = gUpdates.update.selectedPatch.status;
},
onStatus: function(request, context, status, statusText) {

Просмотреть файл

@ -56,7 +56,7 @@
</resources>
<content>
<xul:hbox pack="start">
<xul:label class="update-item-name" xbl:inherits="value=name" crop="right" flex="1"/>
<xul:label anonid="name" class="update-item-name" xbl:inherits="value=name" crop="right" flex="1"/>
<xul:link class="update-item-details" xbl:inherits="href=detailsURL">&details.link;</xul:link>
</xul:hbox>
<xul:deck anonid="modeDeck">
@ -79,6 +79,9 @@
<field name="_strings">
document.getAnonymousElementByAttribute(this, "anonid", "strings");
</field>
<field name="_name">
document.getAnonymousElementByAttribute(this, "anonid", "name");
</field>
<field name="_progressBar">
document.getAnonymousElementByAttribute(this, "anonid", "progress");
</field>
@ -93,21 +96,24 @@
<body><![CDATA[
this._update = update;
this.setAttribute("name", update.name);
this.name = update.name;
this.setAttribute("detailsURL", update.detailsURL);
this.state = update.selectedPatch.state;
]]></body>
</method>
<property name="progress">
<getter><![CDATA[
return parseInt(this._progressBar.getAttribute("value"));
]]></getter>
<setter><![CDATA[
this._progressBar.setAttribute("value", val);
]]></setter>
</property>
<property name="name"
onget="return this._name.getAttribute('value');"
onset="this._name.setAttribute('value', val); return val;"/>
<property name="progress"
onget="return parseInt(this._progressBar.getAttribute('value'));"
onset="this._progressBar.setAttribute('value', val); return val;"/>
<property name="status"
onget="return this.getAttribute('status');"
onset="this.setAttribute('status', val); return val;"/>
<field name="_started">false</field>
<method name="startDownload">
<body><![CDATA[
@ -137,6 +143,19 @@
<setter><![CDATA[
this._paused = val;
var key = val ? "pauseButtonResume" : "pauseButtonPause";
if (val) {
this.setAttribute("old-status", this.status);
this.status = this._strings.getString("pausedStatus");
this.setAttribute("old-name", this.name);
this.name = this._strings.getFormattedString("pausedName", [this.name]);
LOG("GOAT = " + this._strings.getFormattedString("pausedName", [this.name]));
}
else {
this.status = this.getAttribute("old-status");
this.removeAttribute("old-status");
this.setAttribute("name", this.getAttribute("old-name"));
this.removeAttribute("old-name");
}
this._pauseButton.label = this._strings.getString(key);
return val;
]]></setter>
@ -149,6 +168,13 @@
<setter><![CDATA[
this.setAttribute("state", val);
this._modeDeck.setAttribute("selectedIndex", val == "downloading" ? 1 : 0);
var name = this._update.name;
if (val == "downloading") {
var name = this._strings.getFormattedString("downloadingPrefix",
[this._update.name]);
}
this.setAttribute("name", name);
if (val == "failed") {
var failed = this._strings.getString("statusFailed");
this.setAttribute("status", failed);

Просмотреть файл

@ -74,6 +74,11 @@ interface nsIUpdatePatch : nsISupports
*/
attribute double progress;
/**
*
*/
attribute AString status;
/**
* The state of this update
*/

Просмотреть файл

@ -862,6 +862,7 @@ function UpdatePatch(patch) {
this.size = parseInt(patch.getAttribute("size"));
this.percentage = parseFloat(patch.getAttribute("percentage"));
this.state = patch.getAttribute("state");
this.status = patch.getAttribute("status");
this.selected = patch.getAttribute("selected") == "true";
}
UpdatePatch.prototype = {
@ -877,6 +878,7 @@ UpdatePatch.prototype = {
patch.setAttribute("size", this.size);
patch.setAttribute("percentage", this.percentage);
patch.setAttribute("state", this.state);
patch.setAttribute("status", this.status);
patch.setAttribute("selected", this.selected);
return patch;
},
@ -1155,6 +1157,181 @@ Checker.prototype = {
}
};
/**
* Formats status messages for a download operation based on the progress
* of the download.
* @constructor
*/
function DownloadStatusFormatter() {
this._downloadStartTime = (new Date()).getTime();
this._elapsed = 0;
var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService);
var bundle = sbs.createBundle(URI_UPDATES_PROPERTIES);
this._statusFormat = bundle.GetStringFromName("statusFormat");
this._statusFormatKBMB = bundle.GetStringFromName("statusFormatKBMB");
this._statusFormatKBKB = bundle.GetStringFromName("statusFormatKBKB");
this._statusFormatMBMB = bundle.GetStringFromName("statusFormatMBMB");
this._statusFormatUnknownMB = bundle.GetStringFromName("statusFormatUnknownMB");
this._statusFormatUnknownKB = bundle.GetStringFromName("statusFormatUnknownKB");
this._remain = bundle.GetStringFromName("remain");
this._unknownFilesize = bundle.GetStringFromName("unknownFilesize");
this._longTimeFormat = bundle.GetStringFromName("longTimeFormat");
this._shortTimeFormat = bundle.GetStringFromName("shortTimeFormat");
}
DownloadStatusFormatter.prototype = {
/**
* Time when the download started (in seconds since epoch)
*/
_downloadStartTime: 0,
/**
* Time elapsed since the start of the download operation (in seconds)
*/
_elapsed: 0,
/**
* Format a human-readable status message based on the current download
* progress.
* @param currSize
* The current number of bytes transferred
* @param finalSize
* The total number of bytes to be transferred
* @returns A human readable status message, e.g.
* "3.4 of 4.7MB; 1.15 remain"
*/
formatStatus: function(currSize, finalSize) {
var now = (new Date()).getTime();
// 1) Determine the Download Progress in Kilobytes
var KBTotal = parseInt(finalSize/1024 + 0.5);
var KBProgress = this._formatKBytes(parseInt(currSize/1024 + 0.5), KBTotal);
LOG("KBP = " + KBProgress);
// 2) Determine the Transfer Rate
this._elapsed = now - (this._startTime / 1000);
var rate = this._elapsed ? (currSize * 1024) / this.elapsed : 0
var KBRate = "??.?";
if (rate) {
var KBRate = parseInt((rate / 1024) * 10 + 0.5);
var fraction = KBRate % 10;
KBRate = parseInt((KBRate - remainder) / 10);
if (KBRate < 100)
KBRate += "." + fraction;
}
// 3) Determine the Time Remaining
var remainingTime = this._unknownFileSize;
if (rate && (finalSize > 0)) {
remainingTime = (finalSize - currSize) / rate;
remainingTime = parseInt(remainingTime + 0.5);
remainingTime = this._formatSeconds(remainingTime);
}
var status = this._statusFormat;
status = this._replaceInsert(status, 1, KBProgress);
status = this._replaceInsert(status, 2, KBRate);
status = this._replaceInsert(status, 3, remainingTime);
return status;
},
/**
* Inserts a string into another string at the specified index, e.g. for
* the format string var foo ="#1 #2 #3", |_replaceInsert(foo, 2, "test")|
* returns "#1 test #3";
* @param format
* The format string
* @param index
* The Index to insert into
* @param value
* The value to insert
* @returns The string with the value inserted.
*/
_replaceInsert: function(format, index, value) {
return format.replace(new RegExp("#" + index), value);
},
/**
* Formats progress in the form of kilobytes transfered vs. total to
* transfer.
* @param currentKB
* The current amount of data transfered, in kilobytes.
* @param totalKB
* The total amount of data that must be transfered, in kilobytes.
* @returns A string representation of the progress, formatted according to:
*
* KB totalKB returns
* x, < 1MB y < 1MB x of y KB
* x, < 1MB y >= 1MB x KB of y MB
* x, >= 1MB y >= 1MB x of y MB
*/
_formatKBytes: function(currentKB, totalKB) {
var progressHasMB = parseInt(currentKB / 1024) > 0;
var totalHasMB = parseInt(totalKB / 1024) > 0;
var format = "";
if (!progressHasMB && !totalHasMB) {
if (!totalKB) {
format = this._statusFormatUnknownKB;
format = this._replaceInsert(format, 1, currentKB);
} else {
format = this._statusFormatKBKB;
format = this._replaceInsert(format, 1, currentKB);
format = this._replaceInsert(format, 2, totalKB);
}
}
else if (progressHasMB && totalHasMB) {
format = this._statusFormatMBMB;
format = this._replaceInsert(format, 1, (currentKB / 1024).toFixed(1));
format = this._replaceInsert(format, 2, (totalKB / 1024).toFixed(1));
}
else if (totalHasMB && !progressHasMB) {
format = this._statusFormatKBMB;
format = this._replaceInsert(format, 1, currentKB);
format = this._replaceInsert(format, 2, (totalKB / 1024).toFixed(1));
}
else if (progressHasMB && !totalHasMB) {
format = this._statusFormatUnknownMB;
format = this._replaceInsert(format, 1, (currentKB / 1024).toFixed(1));
}
return format;
},
/**
* Formats a time in seconds into something human readable.
* @param seconds
* The time to format
* @returns A human readable string representing the date.
*/
_formatSeconds: function(seconds) {
// Round the number of seconds to remove fractions.
seconds = parseInt(seconds + .5);
var hours = parseInt(seconds/3600);
seconds -= hours * 3600;
var minutes = parseInt(seconds/60);
seconds -= minutes * 60;
var result = hours ? this._longTimeFormat : this._shortTimeFormat;
if (hours < 10)
hours = "0" + hours;
if (minutes < 10)
minutes = "0" + minutes;
if (seconds < 10)
seconds = "0" + seconds;
// Insert hours, minutes, and seconds into result string.
result = this._replaceInsert(result, 1, hours);
result = this._replaceInsert(result, 2, minutes);
result = this._replaceInsert(result, 3, seconds);
return result;
}
};
/**
* Manages the download of updates
* @param background
@ -1454,19 +1631,31 @@ Downloader.prototype = {
LOG("LISTENERS1 = " + this._listeners.length);
},
_statusFormatter: null,
/**
*
*/
onStartRequest: function(request, context) {
request.QueryInterface(nsIIncrementalDownload);
LOG("Downloader.onStartRequest: " + request.URI.spec);
this._statusFormatter = new DownloadStatusFormatter();
var listenerCount = this._listeners.length;
for (var i = 0; i < listenerCount; ++i)
this._listeners[i].onStartRequest(request, context);
},
/**
*
*/
onProgress: function(request, context, progress, maxProgress) {
request.QueryInterface(nsIIncrementalDownload);
// LOG("Downloader.onProgress: " + request.URI.spec + ", " + progress + "/" + maxProgress);
this._patch.progress = Math.round(100 * (progress/maxProgress));
this._patch.status = this._statusFormatter.formatStatus(progress, maxProgress);
var listenerCount = this._listeners.length;
for (var i = 0; i < listenerCount; ++i) {
@ -1476,6 +1665,9 @@ Downloader.prototype = {
}
},
/**
*
*/
onStatus: function(request, context, status, statusText) {
request.QueryInterface(nsIIncrementalDownload);
LOG("Downloader.onStatus: " + request.URI.spec + " status = " + status + ", text = " + statusText);
@ -1487,6 +1679,9 @@ Downloader.prototype = {
}
},
/**
*
*/
onStopRequest: function(request, context, status) {
request.QueryInterface(nsIIncrementalDownload);
LOG("Downloader.onStopRequest: " + request.URI.spec + ", status = " + status);