mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-25 18:19:22 +03:00
A plugin that adds a screen has no way to offer a way into it. The
folder list toolbar holds Compose and Contacts, and nothing else can be
added to it, so plugins reach into the UI themselves: polling for an
existing button, replacing its icon and hanging a menu off it. That is
fragile, it varies per plugin, and it puts screens somewhere users do
not look for them.
rl.addNavEntry({icon, title, hash}) appends an entry to that toolbar,
rendered with the same .btn classes so it follows the active theme.
click may be given instead of hash for a popup rather than a route.
Three lines of template, one observableArray, one function, and no
change to existing behaviour when no plugin registers anything.
85 lines
2.4 KiB
JavaScript
85 lines
2.4 KiB
JavaScript
import ko from 'ko';
|
|
import { settingsAddViewModel } from 'Screen/AbstractSettings';
|
|
import { SettingsGet } from 'Common/Globals';
|
|
import { AbstractViewPopup } from 'Knoin/AbstractViews';
|
|
|
|
const USER_VIEW_MODELS_HOOKS = [],
|
|
ADMIN_VIEW_MODELS_HOOKS = [];
|
|
|
|
/**
|
|
* @param {Function} callback
|
|
* @param {string} action
|
|
* @param {Object=} parameters
|
|
* @param {?number=} timeout
|
|
*/
|
|
rl.pluginRemoteRequest = (callback, action, parameters, timeout) => {
|
|
rl.app.Remote.request('Plugin' + action, callback, parameters, timeout);
|
|
};
|
|
|
|
/**
|
|
* Navigation entries contributed by plugins, rendered in the folder list
|
|
* toolbar beside Compose and Contacts.
|
|
* @type {Array}
|
|
*/
|
|
export const pluginNavEntries = ko.observableArray();
|
|
|
|
/**
|
|
* Register a navigation entry for a screen a plugin provides.
|
|
*
|
|
* Without this a plugin that adds a screen has to reach into the folder list
|
|
* template itself, which several already do, each in its own way.
|
|
*
|
|
* @param {Object} entry
|
|
* @param {string} entry.icon character or glyph shown on the button
|
|
* @param {string} entry.title tooltip
|
|
* @param {string=} entry.hash location hash to navigate to
|
|
* @param {Function=} entry.click called instead of setting the hash
|
|
*/
|
|
rl.addNavEntry = entry => {
|
|
if (entry && entry.icon) {
|
|
pluginNavEntries.push({
|
|
icon: entry.icon,
|
|
title: entry.title || '',
|
|
click: entry.click || (() => { hasher.setHash(entry.hash || ''); })
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {Function} SettingsViewModelClass
|
|
* @param {string} labelName
|
|
* @param {string} template
|
|
* @param {string} route
|
|
*/
|
|
rl.addSettingsViewModel = (SettingsViewModelClass, template, labelName, route) => {
|
|
USER_VIEW_MODELS_HOOKS.push([SettingsViewModelClass, template, labelName, route]);
|
|
};
|
|
|
|
/**
|
|
* @param {Function} SettingsViewModelClass
|
|
* @param {string} labelName
|
|
* @param {string} template
|
|
* @param {string} route
|
|
*/
|
|
rl.addSettingsViewModelForAdmin = (SettingsViewModelClass, template, labelName, route) => {
|
|
ADMIN_VIEW_MODELS_HOOKS.push([SettingsViewModelClass, template, labelName, route]);
|
|
};
|
|
|
|
/**
|
|
* @param {boolean} admin
|
|
*/
|
|
export function runSettingsViewModelHooks(admin) {
|
|
(admin ? ADMIN_VIEW_MODELS_HOOKS : USER_VIEW_MODELS_HOOKS).forEach(view =>
|
|
settingsAddViewModel(...view)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param {string} pluginSection
|
|
* @param {string} name
|
|
* @returns {?}
|
|
*/
|
|
rl.pluginSettingsGet = (pluginSection, name) =>
|
|
SettingsGet('Plugins')?.[pluginSection]?.[name];
|
|
|
|
rl.pluginPopupView = AbstractViewPopup;
|