keeweb/app/scripts/views/settings/settings-plugins-view.js

267 lines
9.7 KiB
JavaScript
Raw Normal View History

2019-09-16 20:42:33 +02:00
import { View } from 'framework/views/view';
2019-09-16 22:57:56 +02:00
import { Events } from 'framework/events';
2019-10-26 22:56:36 +02:00
import { RuntimeInfo } from 'const/runtime-info';
import { Launcher } from 'comp/launcher';
2019-09-15 14:16:32 +02:00
import { SettingsManager } from 'comp/settings/settings-manager';
import { Links } from 'const/links';
import { AppSettingsModel } from 'models/app-settings-model';
import { PluginGallery } from 'plugins/plugin-gallery';
import { PluginManager } from 'plugins/plugin-manager';
import { Comparators } from 'util/data/comparators';
import { SemVer } from 'util/data/semver';
import { Features } from 'util/features';
2020-11-27 18:38:11 +01:00
import { DateFormat } from 'comp/i18n/date-format';
2019-09-15 14:16:32 +02:00
import { Locale } from 'util/locale';
2019-09-16 20:40:20 +02:00
import template from 'templates/settings/settings-plugins.hbs';
2017-02-18 23:46:59 +01:00
2019-09-16 20:40:20 +02:00
class SettingsPluginsView extends View {
template = template;
2017-02-18 23:46:59 +01:00
2019-09-16 20:40:20 +02:00
events = {
2017-02-19 12:40:21 +01:00
'click .settings_plugins-install-btn': 'installClick',
'click .settings_plugins-uninstall-btn': 'uninstallClick',
2017-04-26 22:06:07 +02:00
'click .settings_plugins-disable-btn': 'disableClick',
'click .settings_plugins-enable-btn': 'enableClick',
2017-04-08 23:35:26 +02:00
'click .settings_plugins-update-btn': 'updateClick',
2017-02-21 22:05:18 +01:00
'click .settings_plugins-use-locale-btn': 'useLocaleClick',
2017-05-13 22:36:07 +02:00
'click .settings_plugins-use-theme-btn': 'useThemeClick',
2017-05-14 13:13:09 +02:00
'click .settings__plugins-gallery-plugin-install-btn': 'galleryInstallClick',
2017-05-19 22:05:35 +02:00
'input .settings__plugins-gallery-search': 'gallerySearchInput',
'change select.settings__plugins-plugin-input': 'pluginSettingChange',
'change input[type=checkbox].settings__plugins-plugin-input': 'pluginSettingChange',
2017-05-20 11:27:28 +02:00
'input input[type=text].settings__plugins-plugin-input': 'pluginSettingChange',
2017-05-28 17:03:10 +02:00
'change .settings__plugins-plugin-updates': 'autoUpdateChange',
'click .settings__plugins-gallery-load-btn': 'loadPluginGalleryClick'
2019-09-16 20:40:20 +02:00
};
2017-02-19 12:40:21 +01:00
2019-09-16 20:40:20 +02:00
searchStr = null;
installFromUrl = null;
installing = {};
installErrors = {};
2017-05-14 13:13:09 +02:00
2019-09-16 20:40:20 +02:00
constructor(model, options) {
super(model, options);
2019-09-16 22:01:59 +02:00
this.listenTo(PluginManager, 'change', this.render.bind(this));
2019-08-18 08:05:38 +02:00
this.listenTo(
2019-09-16 23:10:22 +02:00
Events,
2019-08-18 08:05:38 +02:00
'plugin-gallery-load-complete',
this.pluginGalleryLoadComplete.bind(this)
);
2019-09-16 20:40:20 +02:00
}
2017-02-18 23:46:59 +01:00
render() {
2019-09-16 20:40:20 +02:00
super.render({
2019-09-18 21:15:48 +02:00
plugins: PluginManager.plugins
2020-06-01 16:53:51 +02:00
.map((plugin) => ({
2019-08-16 23:05:39 +02:00
id: plugin.id,
2019-09-18 21:15:48 +02:00
manifest: plugin.manifest,
status: plugin.status,
installTime: Math.round(plugin.installTime),
updateError: plugin.updateError,
updateCheckDate: DateFormat.dtStr(plugin.updateCheckDate),
installError: plugin.installError,
official: plugin.official,
autoUpdate: plugin.autoUpdate,
2019-08-16 23:05:39 +02:00
settings: plugin.getSettings()
}))
.sort(Comparators.stringComparator('id', true)),
2017-05-16 22:28:29 +02:00
installingFromUrl: this.installFromUrl && !this.installFromUrl.error,
installUrl: this.installFromUrl ? this.installFromUrl.url : null,
installUrlError: this.installFromUrl ? this.installFromUrl.error : null,
2017-05-13 22:36:07 +02:00
galleryLoading: PluginGallery.loading,
galleryLoadError: PluginGallery.loadError,
2017-05-14 13:13:09 +02:00
galleryPlugins: this.getGalleryPlugins(),
2017-05-14 17:14:21 +02:00
searchStr: this.searchStr,
2019-09-15 08:11:11 +02:00
hasUnicodeFlags: Features.hasUnicodeFlags(),
2017-05-17 19:25:08 +02:00
pluginDevLink: Links.PluginDevelopStart,
translateLink: Links.Translation
2017-02-18 23:46:59 +01:00
});
2017-05-14 13:13:09 +02:00
if (this.searchStr) {
this.showFilterResults();
}
2019-09-16 20:40:20 +02:00
}
2017-02-18 23:46:59 +01:00
2018-01-01 21:40:49 +01:00
pluginGalleryLoadComplete() {
this.render();
2019-09-16 22:57:56 +02:00
Events.emit('page-geometry', { source: 'view' });
2019-09-16 20:40:20 +02:00
}
2018-01-01 21:40:49 +01:00
2017-05-13 22:53:45 +02:00
getGalleryPlugins() {
2017-05-13 22:36:07 +02:00
if (!PluginGallery.gallery) {
return null;
}
2019-09-18 21:15:48 +02:00
const plugins = PluginManager.plugins;
2017-05-13 22:53:45 +02:00
return PluginGallery.gallery.plugins
2020-06-01 16:53:51 +02:00
.map((pl) => ({
2017-05-16 22:28:29 +02:00
url: pl.url,
manifest: pl.manifest,
installing: this.installing[pl.url],
installError: this.installErrors[pl.url],
2017-11-28 18:54:06 +01:00
official: pl.official
2017-05-16 22:28:29 +02:00
}))
2020-06-01 16:53:51 +02:00
.filter((pl) => !plugins.get(pl.manifest.name) && this.canInstallPlugin(pl))
2017-05-13 22:53:45 +02:00
.sort((x, y) => x.manifest.name.localeCompare(y.manifest.name));
2019-09-16 20:40:20 +02:00
}
2017-05-13 22:36:07 +02:00
canInstallPlugin(plugin) {
if (plugin.manifest.locale && SettingsManager.allLocales[plugin.manifest.locale.name]) {
return false;
}
2019-10-26 22:56:36 +02:00
if (plugin.manifest.desktop && !Launcher) {
return false;
}
2019-08-18 08:05:38 +02:00
if (
plugin.manifest.versionMin &&
SemVer.compareVersions(plugin.manifest.versionMin, RuntimeInfo.version) > 0
) {
return false;
}
2019-08-18 08:05:38 +02:00
if (
plugin.manifest.versionMax &&
SemVer.compareVersions(plugin.manifest.versionMax, RuntimeInfo.version) > 0
) {
return false;
}
return true;
2019-09-16 20:40:20 +02:00
}
2017-05-28 17:03:10 +02:00
loadPluginGalleryClick() {
if (PluginGallery.loading) {
return;
}
PluginGallery.loadPlugins();
this.render();
2019-09-16 20:40:20 +02:00
}
2017-05-28 17:03:10 +02:00
2017-02-18 23:46:59 +01:00
installClick() {
const installBtn = this.$el.find('.settings_plugins-install-btn');
const urlTextBox = this.$el.find('#settings__plugins-install-url');
const errorBox = this.$el.find('.settings__plugins-install-error');
2020-05-09 20:15:46 +02:00
errorBox.empty();
2017-02-18 23:46:59 +01:00
const url = urlTextBox.val().trim();
if (!url) {
return;
}
urlTextBox.prop('disabled', true);
installBtn.text(Locale.setPlInstallBtnProgress + '...').prop('disabled', true);
2017-05-16 22:28:29 +02:00
this.installFromUrl = { url };
2019-09-16 22:01:59 +02:00
PluginManager.install(url, undefined, true)
2017-02-18 23:46:59 +01:00
.then(() => {
this.installFinished();
2017-05-16 22:28:29 +02:00
this.installFromUrl = null;
this.render();
this.$el.closest('.scroller').scrollTop(0);
2017-02-18 23:46:59 +01:00
})
2020-06-01 16:53:51 +02:00
.catch((e) => {
2017-02-18 23:46:59 +01:00
this.installFinished();
2017-05-16 22:28:29 +02:00
this.installFromUrl.error = e;
this.$el.find('.settings__plugins-install-error').text(e.toString());
this.$el.closest('.scroller').scrollTop(this.$el.height());
2017-02-18 23:46:59 +01:00
});
2019-09-16 20:40:20 +02:00
}
2017-02-18 23:46:59 +01:00
installFinished() {
const installBtn = this.$el.find('.settings_plugins-install-btn');
const urlTextBox = this.$el.find('#settings__plugins-install-url');
urlTextBox.prop('disabled', false);
installBtn.text(Locale.setPlInstallBtn).prop('disabled', false);
2019-09-16 20:40:20 +02:00
}
2017-02-19 12:40:21 +01:00
uninstallClick(e) {
const pluginId = $(e.target).data('plugin');
2019-09-16 22:01:59 +02:00
PluginManager.uninstall(pluginId);
2019-09-16 20:40:20 +02:00
}
2017-02-19 12:40:21 +01:00
2017-04-26 22:06:07 +02:00
disableClick(e) {
const pluginId = $(e.target).data('plugin');
2019-09-16 22:01:59 +02:00
PluginManager.disable(pluginId);
2019-09-16 20:40:20 +02:00
}
2017-04-26 22:06:07 +02:00
enableClick(e) {
const pluginId = $(e.target).data('plugin');
2019-09-16 22:01:59 +02:00
PluginManager.activate(pluginId);
2019-09-16 20:40:20 +02:00
}
2017-04-26 22:06:07 +02:00
2017-04-08 23:35:26 +02:00
updateClick(e) {
const pluginId = $(e.target).data('plugin');
2019-09-16 22:01:59 +02:00
PluginManager.update(pluginId);
2019-09-16 20:40:20 +02:00
}
2017-04-08 23:35:26 +02:00
2017-02-19 12:40:21 +01:00
useLocaleClick(e) {
const locale = $(e.target).data('locale');
2019-09-17 19:50:42 +02:00
AppSettingsModel.locale = locale;
2019-09-16 20:40:20 +02:00
}
2017-02-21 22:05:18 +01:00
useThemeClick(e) {
const theme = $(e.target).data('theme');
2019-09-17 19:50:42 +02:00
AppSettingsModel.theme = theme;
2019-09-16 20:40:20 +02:00
}
2017-05-13 22:36:07 +02:00
galleryInstallClick(e) {
2017-05-13 22:53:45 +02:00
const installBtn = $(e.target);
const pluginId = installBtn.data('plugin');
2020-06-01 16:53:51 +02:00
const plugin = PluginGallery.gallery.plugins.find((pl) => pl.manifest.name === pluginId);
2017-05-13 22:53:45 +02:00
installBtn.text(Locale.setPlInstallBtnProgress + '...').prop('disabled', true);
2017-05-16 22:28:29 +02:00
this.installing[plugin.url] = true;
delete this.installErrors[plugin.url];
2019-09-16 22:01:59 +02:00
PluginManager.install(plugin.url, plugin.manifest)
2020-06-01 16:53:51 +02:00
.catch((e) => {
2017-05-16 22:28:29 +02:00
this.installErrors[plugin.url] = e;
delete this.installing[plugin.url];
this.render();
})
2017-05-13 22:53:45 +02:00
.then(() => {
installBtn.prop('disabled', true);
2017-05-16 22:28:29 +02:00
delete this.installing[plugin.url];
2017-05-13 22:53:45 +02:00
});
2019-09-16 20:40:20 +02:00
}
2017-05-14 13:13:09 +02:00
gallerySearchInput(e) {
this.searchStr = e.target.value.toLowerCase();
this.showFilterResults();
2019-09-16 20:40:20 +02:00
}
2017-05-14 13:13:09 +02:00
showFilterResults() {
const pluginsById = {};
for (const plugin of PluginGallery.gallery.plugins) {
pluginsById[plugin.manifest.name] = plugin;
}
for (const pluginEl of $('.settings__plugins-gallery-plugin', this.$el)) {
const pluginId = pluginEl.dataset.plugin;
const visible = this.pluginMatchesFilter(pluginsById[pluginId]);
$(pluginEl).toggle(visible);
}
2019-09-16 20:40:20 +02:00
}
2017-05-14 13:13:09 +02:00
pluginMatchesFilter(plugin) {
const searchStr = this.searchStr;
const manifest = plugin.manifest;
2019-09-29 09:58:45 +02:00
return !!(
2019-08-16 23:05:39 +02:00
!searchStr ||
2017-05-14 13:13:09 +02:00
manifest.name.toLowerCase().indexOf(searchStr) >= 0 ||
2019-08-16 23:05:39 +02:00
(manifest.description && manifest.description.toLowerCase().indexOf(searchStr) >= 0) ||
(manifest.locale &&
2017-05-14 13:13:09 +02:00
(manifest.locale.name.toLowerCase().indexOf(searchStr) >= 0 ||
2019-08-16 23:05:39 +02:00
manifest.locale.title.toLowerCase().indexOf(searchStr) >= 0))
);
2019-09-16 20:40:20 +02:00
}
2017-05-19 22:05:35 +02:00
pluginSettingChange(e) {
const el = e.target;
const settingEl = $(el).closest('.settings__plugins-plugin-setting');
const setting = settingEl.data('setting');
const pluginId = settingEl.data('plugin');
const val = el.type === 'checkbox' ? el.checked : el.value;
2019-09-16 22:01:59 +02:00
const plugin = PluginManager.getPlugin(pluginId);
2017-05-19 22:05:35 +02:00
plugin.setSettings({ [setting]: val });
2019-09-16 20:40:20 +02:00
}
2017-05-20 11:27:28 +02:00
autoUpdateChange(e) {
const pluginId = $(e.target).data('plugin');
const enabled = e.target.checked;
2019-09-16 22:01:59 +02:00
PluginManager.setAutoUpdate(pluginId, enabled);
2017-02-18 23:46:59 +01:00
}
2019-09-16 20:40:20 +02:00
}
2017-02-18 23:46:59 +01:00
2019-09-15 14:16:32 +02:00
export { SettingsPluginsView };