зеркало из https://github.com/mozilla/snowl.git
implement source refresh pause/resume with collections tree state indicators and contextmenus.
This commit is contained in:
Родитель
e28a8779ef
Коммит
7c9557d679
|
@ -97,7 +97,18 @@
|
|||
list-style-image: url("chrome://snowl/content/icons/exclamation.png");
|
||||
}
|
||||
|
||||
/* Source is paused */
|
||||
#sourcesViewTreeChildren::-moz-tree-image(isPaused) {
|
||||
list-style-image: url("chrome://snowl/content/icons/control_play.png");
|
||||
}
|
||||
|
||||
/* Source is paused/disabled */
|
||||
#sourcesViewTreeChildren::-moz-tree-cell-text(isPaused),
|
||||
#sourcesViewTreeChildren::-moz-tree-cell-text(isDisabled) {
|
||||
color: GrayText;
|
||||
}
|
||||
|
||||
#sourcesViewTreeChildren::-moz-tree-cell-text(selected, isPaused),
|
||||
#sourcesViewTreeChildren::-moz-tree-cell-text(selected, isDisabled) {
|
||||
color: -moz-cellhighlighttext;
|
||||
}
|
||||
|
|
|
@ -717,6 +717,38 @@ this._log.info("onClick: START itemIds - " +this.itemIds.toSource());
|
|||
}
|
||||
},
|
||||
|
||||
setRefreshStatus: function(aStatus, aAll) {
|
||||
// aStatus is 'paused' or 'active' or 'disabled'.
|
||||
let source, sourceID, selectedSource, selectedSourceIDs = [];
|
||||
if (aAll) {
|
||||
for each (source in SnowlService.sources) {
|
||||
source.attributes["refreshStatus"] = aStatus;
|
||||
source.persistAttributes();
|
||||
SnowlService.sourcesByID[source.id].attributes["refreshStatus"] = aStatus;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Single selection pause/resume refresh of source for now.
|
||||
selectedSource = this._tree.view.nodeForTreeIndex(this._tree.currentSelectedIndex);
|
||||
let query = new SnowlQuery(selectedSource.uri);
|
||||
|
||||
if (!query.queryTypeSource)
|
||||
return;
|
||||
|
||||
selectedSourceIDs.push(query.queryID);
|
||||
|
||||
// Delete loop here, if multiple selections..
|
||||
for (let i = 0; i < selectedSourceIDs.length; ++i) {
|
||||
source = SnowlService.sourcesByID[selectedSourceIDs[i]];
|
||||
source.attributes["refreshStatus"] = aStatus;
|
||||
source.persistAttributes();
|
||||
SnowlService.sourcesByID[source.id].attributes["refreshStatus"] = aStatus;
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh tree.
|
||||
this._tree.treeBoxObject.invalidate();
|
||||
},
|
||||
|
||||
removeSource: function() {
|
||||
// Single selection removal of source for now; all messages, authors, and the
|
||||
|
@ -1031,7 +1063,21 @@ this._log.info("onClick: START itemIds - " +this.itemIds.toSource());
|
|||
},
|
||||
|
||||
buildContextMenu: function(aPopup) {
|
||||
// extra contextmenu customization here
|
||||
// Additional collections tree contextmenu rules.
|
||||
let selection = this._tree.view.nodeForTreeIndex(this._tree.currentSelectedIndex);
|
||||
let query = new SnowlQuery(selection.uri);
|
||||
|
||||
if (query.queryTypeSource) {
|
||||
let source = SnowlService.sourcesByID[query.queryID];
|
||||
if (source.attributes["refreshStatus"] == "paused") {
|
||||
document.getElementById("snowlCollectionPauseMenuitem").hidden = true;
|
||||
document.getElementById("snowlCollectionResumeMenuitem").hidden = false;
|
||||
}
|
||||
else {
|
||||
document.getElementById("snowlCollectionPauseMenuitem").hidden = false;
|
||||
document.getElementById("snowlCollectionResumeMenuitem").hidden = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_collectionChildStats: {},
|
||||
|
@ -1261,6 +1307,9 @@ function SnowlTreeViewGetCellProperties(aRow, aColumn, aProperties) {
|
|||
if (source && source.attributes["refreshStatus"] &&
|
||||
source.attributes["refreshStatus"] == "disabled" && !node.containerOpen)
|
||||
aProperties.AppendElement(this._getAtomFor("isDisabled"));
|
||||
if (source && source.attributes["refreshStatus"] &&
|
||||
source.attributes["refreshStatus"] == "paused" && !node.containerOpen)
|
||||
aProperties.AppendElement(this._getAtomFor("isPaused"));
|
||||
|
||||
if ((query.queryFolder != SnowlPlaces.collectionsSourcesID &&
|
||||
query.queryFolder != SnowlPlaces.collectionsAuthorsID) &&
|
||||
|
@ -1338,7 +1387,9 @@ function SnowlTreeViewGetImageSrc(aRow, aColumn) {
|
|||
|
||||
if ((nodeStats && (nodeStats.n || nodeStats.busy)) ||
|
||||
(source && (source.busy || source.error ||
|
||||
(source.attributes["refreshStatus"] && source.attributes["refreshStatus"] == "disabled"))))
|
||||
(source.attributes["refreshStatus"] &&
|
||||
(source.attributes["refreshStatus"] == "disabled" ||
|
||||
source.attributes["refreshStatus"] == "paused")))))
|
||||
// Don't set icon, let css handle it for 'new' or 'busy' or 'error'.
|
||||
// "all" collection (only) has a busy property so we can set an indicator on
|
||||
// a closed container.
|
||||
|
|
|
@ -118,6 +118,36 @@
|
|||
selectiontype="multiple"
|
||||
selection="any"
|
||||
oncommand="SnowlService.refreshAllSources();"/>
|
||||
<menuitem id="snowlCollectionPauseMenuitem"
|
||||
insertbefore="placesContext_show:info"
|
||||
label="&pause.label;"
|
||||
accesskey="&pause.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="Snowl/Collections/Source"
|
||||
oncommand="CollectionsView.setRefreshStatus('paused');"/>
|
||||
<menuitem id="snowlCollectionResumeMenuitem"
|
||||
insertbefore="placesContext_show:info"
|
||||
label="&resume.label;"
|
||||
accesskey="&resume.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="Snowl/Collections/Source"
|
||||
oncommand="CollectionsView.setRefreshStatus('active');"/>
|
||||
<menuitem id="snowlCollectionPauseAllMenuitem"
|
||||
insertbefore="placesContext_show:info"
|
||||
label="&pause.label;"
|
||||
accesskey="&pause.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="Snowl/Collections"
|
||||
oncommand="CollectionsView.setRefreshStatus('paused', true);"/>
|
||||
<menuitem id="snowlCollectionResumeAllMenuitem"
|
||||
insertbefore="placesContext_show:info"
|
||||
label="&resume.label;"
|
||||
accesskey="&resume.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="Snowl/Collections"
|
||||
oncommand="CollectionsView.setRefreshStatus('active', true);"/>
|
||||
<menuseparator id="snowlPlacesContextRemoveSourceSep"
|
||||
insertbefore="placesContext_show:info"/>
|
||||
<menuitem id="snowlCollectionRemoveSourceMenuitem"
|
||||
insertbefore="placesContext_show:info"
|
||||
label="&removeSource.label;"
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 592 B |
|
@ -7,6 +7,10 @@
|
|||
<!ENTITY refresh.accesskey "R">
|
||||
<!ENTITY refreshAll.label "Refresh All Sources">
|
||||
<!ENTITY refreshAll.accesskey "c">
|
||||
<!ENTITY pause.label "Pause Refresh">
|
||||
<!ENTITY pause.accesskey "P">
|
||||
<!ENTITY resume.label "Resume Refresh">
|
||||
<!ENTITY resume.accesskey "m">
|
||||
<!ENTITY removeSource.label "Remove Source">
|
||||
<!ENTITY removeSource.accesskey "S">
|
||||
<!ENTITY removeAuthor.label "Remove Author">
|
||||
|
|
|
@ -283,7 +283,7 @@ SnowlFeed.prototype = {
|
|||
let request = new Request({
|
||||
// The feed processor is going to parse the response, so we override
|
||||
// the MIME type in order to turn off parsing by XMLHttpRequest itself.
|
||||
// XXX: overrideMimeType removed, text/plain hoses non ascii, ???
|
||||
// XXX: overrideMimeType removed, find mimetype that does not encode..
|
||||
// overrideMimeType: "text/plain",
|
||||
url: this.machineURI,
|
||||
// Listen for notification callbacks so we can handle authentication.
|
||||
|
|
|
@ -287,6 +287,7 @@ let SnowlService = {
|
|||
for each (let source in this.sources)
|
||||
if (now - source.lastRefreshed > source.refreshInterval &&
|
||||
!this.sourcesByID[source.id].busy &&
|
||||
source.attributes["refreshStatus"] != "paused" &&
|
||||
source.attributes["refreshStatus"] != "disabled")
|
||||
// Do not autorefresh (as opposed to user initiated refresh) if a source
|
||||
// is permanently disabled (404 error eg); do not refresh busy source.
|
||||
|
@ -303,21 +304,26 @@ let SnowlService = {
|
|||
},
|
||||
|
||||
refreshAllSources: function(sources) {
|
||||
let cachedsource;
|
||||
let cachedsource, refreshSources = [];
|
||||
let allSources = sources ? sources : this.sources;
|
||||
|
||||
// Set busy property.
|
||||
for each (let source in allSources) {
|
||||
cachedsource = this.sourcesByID[source.id];
|
||||
if (cachedsource) {
|
||||
if (cachedsource.attributes["refreshStatus"] == "paused")
|
||||
continue;
|
||||
cachedsource.busy = true;
|
||||
cachedsource.error = false;
|
||||
cachedsource.attributes["refreshStatus"] = "active";
|
||||
}
|
||||
|
||||
refreshSources.push(source);
|
||||
this.refreshingCount = ++this.refreshingCount;
|
||||
}
|
||||
this._log.info("refreshAllSources: count - "+this.refreshingCount);
|
||||
|
||||
if (allSources.length > 0)
|
||||
if (refreshSources.length > 0)
|
||||
// Invalidate collections tree to show new state.
|
||||
Observers.notify("snowl:messages:completed", "refresh");
|
||||
|
||||
|
@ -328,7 +334,7 @@ let SnowlService = {
|
|||
// when retrieved in the same refresh (f.e. when the user starts their
|
||||
// browser in the morning after leaving it off overnight).
|
||||
let refreshTime = new Date();
|
||||
for each (let source in allSources)
|
||||
for each (let source in refreshSources)
|
||||
this.refreshSourceTimer(source, refreshTime);
|
||||
},
|
||||
|
||||
|
|
|
@ -540,6 +540,24 @@ this._log.info("persist placeID:sources.id - " + this.placeID + " : " + this.id)
|
|||
return this.id;
|
||||
},
|
||||
|
||||
get _persistAttributesStmt() {
|
||||
let statement = SnowlDatastore.createStatement(
|
||||
"UPDATE sources SET attributes = :attributes WHERE id = :id");
|
||||
this.__defineGetter__("_persistAttributesStmt", function() statement);
|
||||
return this._persistAttributesStmt;
|
||||
},
|
||||
|
||||
persistAttributes: function() {
|
||||
try {
|
||||
this._persistAttributesStmt.params.id = this.id;
|
||||
this._persistAttributesStmt.params.attributes = JSON.stringify(this.attributes);
|
||||
this._persistAttributesStmt.step()
|
||||
}
|
||||
finally {
|
||||
this._persistAttributesStmt.reset();
|
||||
}
|
||||
},
|
||||
|
||||
unstore: function() {
|
||||
SnowlDatastore.dbConnection.beginTransaction();
|
||||
try {
|
||||
|
|
Загрузка…
Ссылка в новой задаче