mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-28 17:46:16 +01:00
feat: show top 5 trending plugins in new tab in Extend > Plugins
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"trending": "Trending",
|
||||
"installed": "Installed",
|
||||
"active": "Active",
|
||||
"inactive": "Inactive",
|
||||
|
||||
@@ -8,15 +8,25 @@ const meta = require('../../meta');
|
||||
const pluginsController = module.exports;
|
||||
|
||||
pluginsController.get = async function (req, res) {
|
||||
const [compatible, all] = await Promise.all([
|
||||
const [compatible, all, trending] = await Promise.all([
|
||||
getCompatiblePlugins(),
|
||||
getAllPlugins(),
|
||||
plugins.listTrending(),
|
||||
]);
|
||||
|
||||
const compatiblePkgNames = compatible.map(pkgData => pkgData.name);
|
||||
const installedPlugins = compatible.filter(plugin => plugin && plugin.installed);
|
||||
const activePlugins = all.filter(plugin => plugin && plugin.installed && plugin.active);
|
||||
|
||||
const trendingScores = trending.reduce((memo, cur) => {
|
||||
memo[cur.label] = cur.value;
|
||||
return memo;
|
||||
}, {});
|
||||
const trendingPlugins = all.filter(plugin => plugin && Object.keys(trendingScores).includes(plugin.id)).sort((a, b) => trendingScores[b.id] - trendingScores[a.id]).map((plugin) => {
|
||||
plugin.downloads = trendingScores[plugin.id];
|
||||
return plugin;
|
||||
});
|
||||
|
||||
res.render('admin/extend/plugins', {
|
||||
installed: installedPlugins,
|
||||
installedCount: installedPlugins.length,
|
||||
@@ -34,6 +44,7 @@ pluginsController.get = async function (req, res) {
|
||||
incompatible: all.filter(function (plugin) {
|
||||
return !compatiblePkgNames.includes(plugin.name);
|
||||
}),
|
||||
trending: trendingPlugins,
|
||||
submitPluginUsage: meta.config.submitPluginUsage,
|
||||
version: nconf.get('version'),
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ const async = require('async');
|
||||
const winston = require('winston');
|
||||
const semver = require('semver');
|
||||
const nconf = require('nconf');
|
||||
const util = require('util');
|
||||
const request = require('request-promise-native');
|
||||
|
||||
const user = require('../user');
|
||||
const posts = require('../posts');
|
||||
@@ -141,24 +141,11 @@ Plugins.reloadRoutes = async function (params) {
|
||||
winston.verbose('[plugins] All plugins reloaded and rerouted');
|
||||
};
|
||||
|
||||
function request(url, callback) {
|
||||
require('request')(url, {
|
||||
json: true,
|
||||
}, function (err, res, body) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (res.statusCode === 404 || !body) {
|
||||
return callback(null, {});
|
||||
}
|
||||
callback(null, body);
|
||||
});
|
||||
}
|
||||
const requestAsync = util.promisify(request);
|
||||
|
||||
Plugins.get = async function (id) {
|
||||
const url = (nconf.get('registry') || 'https://packages.nodebb.org') + '/api/v1/plugins/' + id;
|
||||
const body = await requestAsync(url);
|
||||
const body = await request(url, {
|
||||
json: true,
|
||||
});
|
||||
|
||||
let normalised = await Plugins.normalise([body ? body.payload : {}]);
|
||||
normalised = normalised.filter(plugin => plugin.id === id);
|
||||
@@ -172,7 +159,9 @@ Plugins.list = async function (matching) {
|
||||
const version = require(path.join(nconf.get('base_dir'), 'package.json')).version;
|
||||
const url = (nconf.get('registry') || 'https://packages.nodebb.org') + '/api/v1/plugins' + (matching !== false ? '?version=' + version : '');
|
||||
try {
|
||||
const body = await requestAsync(url);
|
||||
const body = await request(url, {
|
||||
json: true,
|
||||
});
|
||||
return await Plugins.normalise(body);
|
||||
} catch (err) {
|
||||
winston.error('Error loading ' + url, err);
|
||||
@@ -180,6 +169,13 @@ Plugins.list = async function (matching) {
|
||||
}
|
||||
};
|
||||
|
||||
Plugins.listTrending = async () => {
|
||||
const url = `${nconf.get('registry') || 'https://packages.nodebb.org'}/api/v1/analytics/top/week`;
|
||||
return await request(url, {
|
||||
json: true,
|
||||
});
|
||||
};
|
||||
|
||||
Plugins.normalise = async function (apiReturn) {
|
||||
const themeNamePattern = /^(@.*?\/)?nodebb-theme-.*$/;
|
||||
const pluginMap = {};
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
<ul class="nav nav-pills">
|
||||
<li class="active"><a href="#installed" data-toggle="tab">
|
||||
[[admin/extend/plugins:installed]]
|
||||
<span class="badge">{installedCount}</span>
|
||||
</a></li>
|
||||
<li><a href="#active" data-toggle="tab">
|
||||
[[admin/extend/plugins:active]]
|
||||
<span class="badge">{activeCount}</span>
|
||||
</a></li>
|
||||
<li><a href="#deactive" data-toggle="tab">
|
||||
[[admin/extend/plugins:inactive]]
|
||||
<span class="badge">{inactiveCount}</span>
|
||||
</a></li>
|
||||
<li><a href="#upgrade" data-toggle="tab">
|
||||
[[admin/extend/plugins:out-of-date]]
|
||||
<span class="badge">{upgradeCount}</span>
|
||||
</a></li>
|
||||
<li><a href="#download" data-toggle="tab">[[admin/extend/plugins:find-plugins]]</a></li>
|
||||
<li>
|
||||
<a href="#trending" data-toggle="tab">
|
||||
[[admin/extend/plugins:trending]]
|
||||
<i class="fa fa-star"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="#installed" data-toggle="tab">
|
||||
[[admin/extend/plugins:installed]]
|
||||
<span class="badge">{installedCount}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#active" data-toggle="tab">
|
||||
[[admin/extend/plugins:active]]
|
||||
<span class="badge">{activeCount}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#deactive" data-toggle="tab">
|
||||
[[admin/extend/plugins:inactive]]
|
||||
<span class="badge">{inactiveCount}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#upgrade" data-toggle="tab">
|
||||
[[admin/extend/plugins:out-of-date]]
|
||||
<span class="badge">{upgradeCount}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#download" data-toggle="tab">[[admin/extend/plugins:find-plugins]]</a>
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
|
||||
@@ -58,6 +74,13 @@
|
||||
|
||||
<div class="col-lg-9 col-lg-pull-3">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade" id="trending">
|
||||
<ul class="trending">
|
||||
{{{ each trending }}}
|
||||
<!-- IMPORT admin/partials/installed_plugin_item.tpl -->
|
||||
{{{ end }}}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane fade active in" id="installed">
|
||||
<ul class="installed">
|
||||
<!-- BEGIN installed -->
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<li id="{download.id}" data-plugin-id="{download.id}" class="clearfix">
|
||||
<li id="{../id}" data-plugin-id="{../id}" class="clearfix">
|
||||
<div class="pull-right">
|
||||
<button data-action="toggleActive" class="btn btn-success hidden"><i class="fa fa-power-off"></i> [[admin/extend/plugins:plugin-item.activate]]</button>
|
||||
<button data-action="toggleInstall" data-installed="0" class="btn btn-success"><i class="fa fa-download"></i> [[admin/extend/plugins:plugin-item.install]]</button>
|
||||
</div>
|
||||
|
||||
<h2><strong>{download.name}</strong></h2>
|
||||
<h2><strong>{../name}</strong></h2>
|
||||
|
||||
<!-- IF download.description -->
|
||||
<p>{download.description}</p>
|
||||
<!-- ENDIF download.description -->
|
||||
<!-- IF ../description -->
|
||||
<p>{../description}</p>
|
||||
<!-- ENDIF ../description -->
|
||||
|
||||
<small>[[admin/extend/plugins:plugin-item.latest]] <strong class="latestVersion">{download.latest}</strong></small>
|
||||
<small>[[admin/extend/plugins:plugin-item.latest]] <strong class="latestVersion">{../latest}</strong></small>
|
||||
<p>
|
||||
<!-- IF download.isCompatible -->
|
||||
<!-- IF ../isCompatible -->
|
||||
<i class="fa fa-check text-success"></i> [[admin/extend/plugins:plugin-item.compatible, {version}]]
|
||||
<!-- ELSE -->
|
||||
<i class="fa fa-question text-warning"></i> [[admin/extend/plugins:plugin-item.not-compatible]]
|
||||
<!-- ENDIF -->
|
||||
</p>
|
||||
|
||||
<!-- IF download.url -->
|
||||
<p>[[admin/extend/plugins:plugin-item.more-info]] <a target="_blank" href="{download.url}">{download.url}</a></p>
|
||||
<!-- ENDIF download.url -->
|
||||
<!-- IF ../url -->
|
||||
<p>[[admin/extend/plugins:plugin-item.more-info]] <a target="_blank" href="{../url}">{../url}</a></p>
|
||||
<!-- ENDIF ../url -->
|
||||
</li>
|
||||
|
||||
@@ -1,56 +1,60 @@
|
||||
<!-- IF !installed.error -->
|
||||
<li id="{installed.id}" data-plugin-index="@index" data-plugin-id="{installed.id}" data-version="{installed.version}" class="clearfix <!-- IF installed.active -->active<!-- ENDIF installed.active -->">
|
||||
<!-- IF !../error -->
|
||||
<li id="{../id}" data-plugin-index="@index" data-plugin-id="{../id}" data-version="{../version}" class="clearfix <!-- IF ../active -->active<!-- ENDIF ../active -->">
|
||||
<div class="pull-right controls">
|
||||
<!-- IF installed.isTheme -->
|
||||
<a href="{config.relative_path}/admin/appearance/themes" class="btn btn-info">[[admin/extend/plugins:plugin-item.themes]]</a>
|
||||
<!-- ELSE -->
|
||||
<button data-action="toggleActive" class="btn <!-- IF installed.active --> btn-warning<!-- ELSE --> btn-success<!-- ENDIF installed.active -->">
|
||||
<i class="fa fa-power-off"></i> <!-- IF installed.active -->[[admin/extend/plugins:plugin-item.deactivate]]<!-- ELSE -->[[admin/extend/plugins:plugin-item.activate]]<!-- ENDIF installed.active --></button>
|
||||
<!-- ENDIF installed.isTheme -->
|
||||
{{{ if ../installed }}}
|
||||
<!-- IF ../isTheme -->
|
||||
<a href="{config.relative_path}/admin/appearance/themes" class="btn btn-info">[[admin/extend/plugins:plugin-item.themes]]</a>
|
||||
<!-- ELSE -->
|
||||
<button data-action="toggleActive" class="btn <!-- IF ../active --> btn-warning<!-- ELSE --> btn-success<!-- ENDIF ../active -->">
|
||||
<i class="fa fa-power-off"></i> <!-- IF ../active -->[[admin/extend/plugins:plugin-item.deactivate]]<!-- ELSE -->[[admin/extend/plugins:plugin-item.activate]]<!-- ENDIF ../active --></button>
|
||||
<!-- ENDIF ../isTheme -->
|
||||
|
||||
<button data-action="toggleInstall" data-installed="1" class="btn btn-danger"><i class="fa fa-trash-o"></i> [[admin/extend/plugins:plugin-item.uninstall]]</button>
|
||||
<button data-action="toggleInstall" data-installed="1" class="btn btn-danger"><i class="fa fa-trash-o"></i> [[admin/extend/plugins:plugin-item.uninstall]]</button>
|
||||
|
||||
<!-- IF installed.active -->
|
||||
<!-- IF installed.settingsRoute -->
|
||||
<a href="{config.relative_path}{installed.settingsRoute}" class="btn btn-primary"><i class="fa fa-wrench"></i> [[admin/extend/plugins:plugin-item.settings]]</a>
|
||||
<!-- ENDIF installed.settingsRoute -->
|
||||
<!-- ENDIF installed.active -->
|
||||
<!-- IF ../active -->
|
||||
<!-- IF ../settingsRoute -->
|
||||
<a href="{config.relative_path}{../settingsRoute}" class="btn btn-primary"><i class="fa fa-wrench"></i> [[admin/extend/plugins:plugin-item.settings]]</a>
|
||||
<!-- ENDIF ../settingsRoute -->
|
||||
<!-- ENDIF ../active -->
|
||||
{{{ else }}}
|
||||
<button data-action="toggleInstall" data-installed="0" class="btn btn-success"><i class="fa fa-download"></i> [[admin/extend/plugins:plugin-item.install]]</button>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
|
||||
<h2><strong>{installed.name}</strong></h2>
|
||||
<h2><strong>{../name}</strong></h2>
|
||||
|
||||
<!-- IF installed.description -->
|
||||
<p>{installed.description}</p>
|
||||
<!-- ENDIF installed.description -->
|
||||
<!-- IF installed.outdated --><i class="fa fa-exclamation-triangle text-danger"></i> <!-- ENDIF installed.outdated -->
|
||||
<small>[[admin/extend/plugins:plugin-item.installed]] <strong class="currentVersion">{installed.version}</strong> | [[admin/extend/plugins:plugin-item.latest]] <strong class="latestVersion">{installed.latest}</strong></small>
|
||||
<!-- IF ../description -->
|
||||
<p>{../description}</p>
|
||||
<!-- ENDIF ../description -->
|
||||
<!-- IF ../outdated --><i class="fa fa-exclamation-triangle text-danger"></i> <!-- ENDIF ../outdated -->
|
||||
<small>[[admin/extend/plugins:plugin-item.installed]] <strong class="currentVersion">{../version}</strong> | [[admin/extend/plugins:plugin-item.latest]] <strong class="latestVersion">{../latest}</strong></small>
|
||||
|
||||
<!-- IF installed.outdated -->
|
||||
<!-- IF ../outdated -->
|
||||
<button data-action="upgrade" class="btn btn-success btn-xs"><i class="fa fa-download"></i> [[admin/extend/plugins:plugin-item.upgrade]]</button>
|
||||
<p>
|
||||
<!-- IF installed.isCompatible -->
|
||||
<!-- IF ../isCompatible -->
|
||||
<i class="fa fa-check text-success"></i> [[admin/extend/plugins:plugin-item.compatible, {version}]]
|
||||
<!-- ELSE -->
|
||||
<i class="fa fa-question text-warning"></i> [[admin/extend/plugins:plugin-item.not-compatible]]
|
||||
<!-- ENDIF -->
|
||||
</p>
|
||||
<!-- ENDIF installed.outdated -->
|
||||
<!-- ENDIF ../outdated -->
|
||||
|
||||
<!-- IF installed.url -->
|
||||
<p>[[admin/extend/plugins:plugin-item.more-info]] <a target="_blank" href="{installed.url}">{installed.url}</a></p>
|
||||
<!-- ENDIF installed.url -->
|
||||
<!-- IF ../url -->
|
||||
<p>[[admin/extend/plugins:plugin-item.more-info]] <a target="_blank" href="{../url}">{../url}</a></p>
|
||||
<!-- ENDIF ../url -->
|
||||
</li>
|
||||
<!-- ENDIF !installed.error -->
|
||||
<!-- IF installed.error -->
|
||||
<li data-plugin-id="{installed.id}" class="clearfix">
|
||||
<!-- ENDIF !../error -->
|
||||
<!-- IF ../error -->
|
||||
<li data-plugin-id="{../id}" class="clearfix">
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-default disabled"><i class="fa fa-exclamation-triangle"></i> [[admin/extend/plugins:plugin-item.unknown]]</button>
|
||||
<button data-action="toggleInstall" data-installed="1" class="btn btn-danger"><i class="fa fa-trash-o"></i> [[admin/extend/plugins:plugin-item.uninstall]]</button>
|
||||
</div>
|
||||
|
||||
<h2><strong>{installed.id}</strong></h2>
|
||||
<h2><strong>{../id}</strong></h2>
|
||||
<p>
|
||||
[[admin/extend/plugins:plugin-item.unknown-explanation]]
|
||||
</p>
|
||||
</li>
|
||||
<!-- ENDIF installed.error -->
|
||||
<!-- ENDIF ../error -->
|
||||
|
||||
Reference in New Issue
Block a user