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

Added Extension Sorting capability according to downloads and last published date #13080

Merged
merged 6 commits into from
Feb 20, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions src/extensibility/ExtensionManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ define(function (require, exports, module) {
_idsToDisable = {};

PreferencesManager.stateManager.definePreference(FOLDER_AUTOINSTALL, "object", undefined);
PreferencesManager.definePreference("extensions.sort", "string", "publishedDate", {
description: Strings.SORT_EXTENSION_METHOD
});

/**
* @private
Expand Down
20 changes: 19 additions & 1 deletion src/extensibility/ExtensionManagerDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ define(function (require, exports, module) {
KeyEvent = require("utils/KeyEvent"),
ExtensionManager = require("extensibility/ExtensionManager"),
ExtensionManagerView = require("extensibility/ExtensionManagerView").ExtensionManagerView,
ExtensionManagerViewModel = require("extensibility/ExtensionManagerViewModel");
ExtensionManagerViewModel = require("extensibility/ExtensionManagerViewModel"),
PreferencesManager = require("preferences/PreferencesManager");

var dialogTemplate = require("text!htmlContent/extension-manager-dialog.html");

Expand Down Expand Up @@ -372,6 +373,11 @@ define(function (require, exports, module) {
if (models[_activeTabIndex]) {
$modalDlg.scrollTop(models[_activeTabIndex].scrollPos || 0);
clearSearch();
if (_activeTabIndex === 2) {
$(".ext-sort-group").hide();
} else {
$(".ext-sort-group").show();
}
}
}

Expand Down Expand Up @@ -460,6 +466,18 @@ define(function (require, exports, module) {
$modalDlg.scrollTop(0);
});
}).on("click", ".search-clear", clearSearch);

// Sort the extension list based on the current selected sorting criteria
$dlg.on("change", ".sort-extensions", function (e) {
var sortBy = $(this).val();
PreferencesManager.set("extensions.sort", sortBy);
models.forEach(function (model, index) {
if (index <= 1) {
model._setSortedExtensionList(ExtensionManager.extensions, index === 1);
views[index].filter($(".search").val());
}
});
});

// Disable the search field when there are no items in the model
models.forEach(function (model, index) {
Expand Down
5 changes: 4 additions & 1 deletion src/extensibility/ExtensionManagerView.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ define(function (require, exports, module) {
LanguageManager = require("language/LanguageManager"),
Mustache = require("thirdparty/mustache/mustache"),
PathUtils = require("thirdparty/path-utils/path-utils"),
itemTemplate = require("text!htmlContent/extension-manager-view-item.html");
itemTemplate = require("text!htmlContent/extension-manager-view-item.html"),
PreferencesManager = require("preferences/PreferencesManager");


/**
Expand Down Expand Up @@ -71,6 +72,7 @@ define(function (require, exports, module) {
this._$infoMessage = $("<div class='info-message'/>")
.appendTo(this.$el).html(this.model.infoMessage);
this._$table = $("<table class='table'/>").appendTo(this.$el);
$(".sort-extensions").val(PreferencesManager.get("extensions.sort"));

this.model.initialize().done(function () {
self._setupEventHandlers();
Expand Down Expand Up @@ -248,6 +250,7 @@ define(function (require, exports, module) {
var installWarningBase = context.requiresNewer ? Strings.EXTENSION_LATEST_INCOMPATIBLE_NEWER : Strings.EXTENSION_LATEST_INCOMPATIBLE_OLDER;
context.installWarning = StringUtils.format(installWarningBase, entry.registryInfo.versions[entry.registryInfo.versions.length - 1].version, latestVerCompatInfo.compatibleVersion);
}
context.downloadCount = entry.registryInfo.totalDownloads;
} else {
// We should only get here when viewing the Installed tab and some extensions don't exist in the registry
// (or registry is offline). These flags *should* always be ignored in that scenario, but just in case...
Expand Down
34 changes: 18 additions & 16 deletions src/extensibility/ExtensionManagerViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ define(function (require, exports, module) {

var ExtensionManager = require("extensibility/ExtensionManager"),
registry_utils = require("extensibility/registry_utils"),
EventDispatcher = require("utils/EventDispatcher"),
EventDispatcher = require("utils/EventDispatcher"),
Strings = require("strings");

/**
Expand Down Expand Up @@ -292,6 +292,20 @@ define(function (require, exports, module) {
});
};

ExtensionManagerViewModel.prototype._setSortedExtensionList = function (extensions, isTheme) {
this.filterSet = this.sortedFullSet = registry_utils.sortRegistry(extensions, "registryInfo")
.filter(function (entry) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

There seems to be some redundancy here, seems like same could be achieved with:

return entry.registryInfo && entry.registryInfo.metadata;

Do correct me if I am wrong 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah that can be changed :)

if (!isTheme) {
return entry.registryInfo !== undefined && !isTheme && entry.registryInfo.metadata.theme === undefined;
} else {
return entry.registryInfo !== undefined && entry.registryInfo.metadata.theme;
}
})
.map(function (entry) {
return entry.registryInfo.metadata.name;
});
};

/**
* The model for the ExtensionManagerView that is responsible for handling registry-based extensions.
* This extends ExtensionManagerViewModel.
Expand Down Expand Up @@ -329,13 +343,7 @@ define(function (require, exports, module) {
self.extensions = ExtensionManager.extensions;

// Sort the registry by last published date and store the sorted list of IDs.
self.sortedFullSet = registry_utils.sortRegistry(self.extensions, "registryInfo")
.filter(function (entry) {
return entry.registryInfo !== undefined && entry.registryInfo.metadata.theme === undefined;
})
.map(function (entry) {
return entry.registryInfo.metadata.name;
});
self._setSortedExtensionList(ExtensionManager.extensions, false);
self._setInitialFilter();
})
.fail(function () {
Expand Down Expand Up @@ -536,13 +544,7 @@ define(function (require, exports, module) {
self.extensions = ExtensionManager.extensions;

// Sort the registry by last published date and store the sorted list of IDs.
self.sortedFullSet = registry_utils.sortRegistry(self.extensions, "registryInfo")
.filter(function (entry) {
return entry.registryInfo !== undefined && entry.registryInfo.metadata.theme;
})
.map(function (entry) {
return entry.registryInfo.metadata.name;
});
self._setSortedExtensionList(ExtensionManager.extensions, true);
self._setInitialFilter();
})
.fail(function () {
Expand Down Expand Up @@ -570,4 +572,4 @@ define(function (require, exports, module) {
exports.RegistryViewModel = RegistryViewModel;
exports.ThemesViewModel = ThemesViewModel;
exports.InstalledViewModel = InstalledViewModel;
});
});
14 changes: 12 additions & 2 deletions src/extensibility/registry_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

define(function (require, exports, module) {
"use strict";

var PreferencesManager = require("preferences/PreferencesManager");

// From Brackets StringUtils
function htmlEscape(str) {
Expand Down Expand Up @@ -136,8 +138,16 @@ define(function (require, exports, module) {
sortedEntries.push(registry[key]);
});
sortedEntries.sort(function (entry1, entry2) {
return getPublishTime((subkey && entry2[subkey]) || entry2) -
getPublishTime((subkey && entry1[subkey]) || entry1);
if (PreferencesManager.get("extensions.sort") !== "publishedDate") {
if (entry1.registryInfo && entry2.registryInfo) {
return entry2.registryInfo.totalDownloads - entry1.registryInfo.totalDownloads;
} else {
return Number.NEGATIVE_INFINITY;
}
} else {
return getPublishTime((subkey && entry2[subkey]) || entry2) -
getPublishTime((subkey && entry1[subkey]) || entry1);
}
});

return sortedEntries;
Expand Down
5 changes: 5 additions & 0 deletions src/htmlContent/extension-manager-dialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
<li><a href="#installed" class="installed" data-toggle="tab"><span class="notification"></span><img src="styles/images/extension-manager-installed.svg"/><br/>{{Strings.EXTENSIONS_INSTALLED_TITLE}}</a></li>
</ul>
<div>
<span class="sort-extensions-title ext-sort-group">{{Strings.EXTENSIONS_SORT_BY}}</span>
<select class="sort-extensions ext-sort-group">
<option value="publishedDate">{{Strings.EXTENSIONS_LAST_UPDATED}}</option>
<option value="downloadCount">{{Strings.EXTENSIONS_DOWNLOADS}}</option>
</select>
<button class="search-clear">&times;</button>
<input class="search" type="text" placeholder="{{EXTENSION_SEARCH_PLACEHOLDER}}">
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/htmlContent/extension-manager-view-item.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
{{#hasVersionInfo}}
<span class="muted ext-date"> &mdash; {{lastVersionDate}}</span>
{{/hasVersionInfo}}
<p title="{{downloadCount}} {{Strings.EXTENSIONS_DOWNLOADS}}">&#x21F2; {{downloadCount}}</p>
</td>
<td class="ext-desc">
{{#showInstallButton}}
Expand Down Expand Up @@ -99,4 +100,4 @@
{{/isInstalled}}
</div>
</td>
</tr>
</tr>
4 changes: 4 additions & 0 deletions src/nls/root/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ define({
"INSTALL_CANCELED" : "Installation canceled.",
"VIEW_COMPLETE_DESCRIPTION" : "View complete description",
"VIEW_TRUNCATED_DESCRIPTION" : "View truncated description",
"SORT_EXTENSION_METHOD" : "Sort Extensions using downloadCount or publishedDate",
// These must match the error codes in ExtensionsDomain.Errors.* :
"INVALID_ZIP_FILE" : "The downloaded content is not a valid zip file.",
"MISSING_PACKAGE_JSON" : "The package has no package.json file.",
Expand Down Expand Up @@ -579,6 +580,9 @@ define({
"EXTENSIONS_AVAILABLE_TITLE" : "Available",
"EXTENSIONS_THEMES_TITLE" : "Themes",
"EXTENSIONS_UPDATES_TITLE" : "Updates",
"EXTENSIONS_SORT_BY" : "Sort By",
"EXTENSIONS_LAST_UPDATED" : "Last Updated",
"EXTENSIONS_DOWNLOADS" : "Downloads",

"INLINE_EDITOR_NO_MATCHES" : "No matches available.",
"INLINE_EDITOR_HIDDEN_MATCHES" : "All matches are collapsed. Expand the files listed at right to view matches.",
Expand Down
11 changes: 11 additions & 0 deletions src/styles/brackets_patterns_override.less
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,17 @@ a[href^="http"] {
opacity: 0.3;
}
}
.sort-extensions-title {
float: left;
margin-right: 5px;
margin-top: 5px;
}
.sort-extensions {
float: left;
margin-right: 10px;
width: auto;
padding-right: 18px;
}
}
.modal-body {
height: 400px;
Expand Down