Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Show update notification icon on Extension Manager "Installed" tab #5838

Merged
merged 2 commits into from
Nov 6, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/extensibility/ExtensionManagerDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,36 @@ define(function (require, exports, module) {
$(this).tab("show");
});

// Update & hide/show the notification overlay on a tab's icon, based on its model's notifyCount
function updateNotificationIcon(index) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should have a doc comment.

var model = models[index],
$notificationIcon = $dlg.find(".nav-tabs li").eq(index).find(".notification");
if (model.notifyCount) {
$notificationIcon.text(model.notifyCount);
$notificationIcon.show();
} else {
$notificationIcon.hide();
}
}

// Initialize models and create a view for each model
var modelInitPromise = Async.doInParallel(models, function (model, index) {
var view = new ExtensionManagerView(),
promise = view.initialize(model);
promise = view.initialize(model),
lastNotifyCount;

promise.always(function () {
views[index] = view;

lastNotifyCount = model.notifyCount;
updateNotificationIcon(index);
});

$(model).on("change", function () {
if (lastNotifyCount !== model.notifyCount) {
lastNotifyCount = model.notifyCount;
updateNotificationIcon(index);
}
});

return promise;
Expand Down
29 changes: 29 additions & 0 deletions src/extensibility/ExtensionManagerViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ define(function (require, exports, module) {
*/
ExtensionManagerViewModel.prototype.message = null;

/**
* @type {number}
* Number to show in tab's notification icon. No icon shown if 0.
*/
ExtensionManagerViewModel.prototype.notifyCount = 0;

/**
* @private {$.Promise}
* Internal use only to track when initialization fails, see usage in _updateMessage.
Expand Down Expand Up @@ -374,6 +380,8 @@ define(function (require, exports, module) {
});
this._sortFullSet();
this._setInitialFilter();
this._countUpdates();

return new $.Deferred().resolve().promise();
};

Expand All @@ -399,6 +407,20 @@ define(function (require, exports, module) {
});
};

/**
* @private
* Updates notifyCount based on number of extensions with an update available
*/
InstalledViewModel.prototype._countUpdates = function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should have a doc comment

var self = this;
this.notifyCount = 0;
this.sortedFullSet.forEach(function (key) {
if (self.extensions[key].installInfo.updateAvailable) {
self.notifyCount++;
}
});
};

/**
* @private
* Updates the initial set and filter as necessary when the status of an extension changes,
Expand All @@ -412,6 +434,7 @@ define(function (require, exports, module) {
if (index !== -1 && !this.extensions[id].installInfo) {
// This was in our set, but was uninstalled. Remove it.
this.sortedFullSet.splice(index, 1);
this._countUpdates(); // may also affect update count
refilter = true;
} else if (index === -1 && this.extensions[id].installInfo) {
// This was not in our set, but is now installed. Add it and resort.
Expand All @@ -422,6 +445,12 @@ define(function (require, exports, module) {
if (refilter) {
this.filter(this._lastQuery || "", true);
}

if (this.extensions[id].installInfo) {
// If our count of available updates may have been affected, re-count
this._countUpdates();
}

ExtensionManagerViewModel.prototype._handleStatusChange.call(this, e, id);
};

Expand Down
2 changes: 1 addition & 1 deletion src/htmlContent/extension-manager-dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<li><a href="#registry" class="registry" data-toggle="tab"><img src="styles/images/extension-manager-registry.svg"/><br/>{{Strings.EXTENSIONS_AVAILABLE_TITLE}}</a></li>
<!--<li><a href="#updates" class="updates" data-toggle="tab"><img src="styles/images/extension-manager-updates.svg"/><br/>{{Strings.EXTENSIONS_UPDATES_TITLE}}</a></li>-->
{{/showRegistry}}
<li><a href="#installed" class="installed" data-toggle="tab"><img src="styles/images/extension-manager-installed.svg"/><br/>{{Strings.EXTENSIONS_INSTALLED_TITLE}}</a></li>
<li><a href="#installed" class="installed" data-toggle="tab"><img src="styles/images/extension-manager-installed.svg"/><br/>{{Strings.EXTENSIONS_INSTALLED_TITLE}}</a><span class="notification"></span></li>
</ul>
<div>
<button class="search-clear"></button>
Expand Down
14 changes: 14 additions & 0 deletions src/styles/brackets_patterns_override.less
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,20 @@ a[href^="http"] {
background-color: #dfe2e2;
border-color: #b4b7b7 #b4b7b7 transparent #b4b7b7;
}

> li {
position: relative; // for positioning .notification icon
> .notification {
display: none; // hidden by default
background-color: #91CC41;
color: white;
border-radius: 16px;
padding: 0 5px;
position: absolute;
right: 19px;
top: 8px;
}
}
}

/* Search box */
Expand Down
10 changes: 10 additions & 0 deletions test/spec/ExtensionManager-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1040,11 +1040,18 @@ define(function (require, exports, module) {
item.metadata.name === "mock-legacy-extension") {
expect(view).toHaveText(item.metadata.name);
expect($button.length).toBe(1);

// But no update button
var $updateButton = $("button.update[data-extension-id=" + item.metadata.name + "]", view.$el);
expect($updateButton.length).toBe(0);
} else {
expect(view).not.toHaveText(item.metadata.name);
expect($button.length).toBe(0);
}
});

// And no overall update icon overlay
expect(model.notifyCount).toBe(0);
});
});

Expand Down Expand Up @@ -1172,6 +1179,7 @@ define(function (require, exports, module) {
var $button = $("button.update[data-extension-id=mock-extension]", view.$el);
expect($button.length).toBe(1);
expect($button.prop("disabled")).toBeFalsy();
expect(model.notifyCount).toBe(1);

expect($("button.install[data-extension-id=mock-extension]", view.$el).length).toBe(0);
});
Expand All @@ -1189,6 +1197,7 @@ define(function (require, exports, module) {
var $button = $("button.update[data-extension-id=mock-extension]", view.$el);
expect($button.length).toBe(1);
expect($button.prop("disabled")).toBeTruthy();
expect(model.notifyCount).toBe(1);

expect($("button.install[data-extension-id=mock-extension]", view.$el).length).toBe(0);
expect($(".alert.warning", view.$el).length).toBe(0);
Expand All @@ -1206,6 +1215,7 @@ define(function (require, exports, module) {
var $button = $("button.update[data-extension-id=mock-extension]", view.$el);
expect($button.length).toBe(1);
expect($button.prop("disabled")).toBeTruthy();
expect(model.notifyCount).toBe(1);

expect($("button.install[data-extension-id=mock-extension]", view.$el).length).toBe(0);
expect($(".alert.warning", view.$el).length).toBe(0);
Expand Down