This commit is contained in:
Fathi Ben Nasr 2026-08-16 12:57:24 +01:00 committed by GitHub
commit 121f4f5a64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 0 deletions

View file

@ -1,3 +1,4 @@
import ko from 'ko';
import { settingsAddViewModel } from 'Screen/AbstractSettings'; import { settingsAddViewModel } from 'Screen/AbstractSettings';
import { SettingsGet } from 'Common/Globals'; import { SettingsGet } from 'Common/Globals';
import { AbstractViewPopup } from 'Knoin/AbstractViews'; import { AbstractViewPopup } from 'Knoin/AbstractViews';
@ -15,6 +16,35 @@ rl.pluginRemoteRequest = (callback, action, parameters, timeout) => {
rl.app.Remote.request('Plugin' + action, callback, 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 {Function} SettingsViewModelClass
* @param {string} labelName * @param {string} labelName

View file

@ -7,6 +7,7 @@ import { mailBox, settings } from 'Common/Links';
import { addComputablesTo } from 'External/ko'; import { addComputablesTo } from 'External/ko';
import { AppUserStore } from 'Stores/User/App'; import { AppUserStore } from 'Stores/User/App';
import { pluginNavEntries } from 'Common/Plugins';
import { SettingsUserStore } from 'Stores/User/Settings'; import { SettingsUserStore } from 'Stores/User/Settings';
import { FolderUserStore } from 'Stores/User/Folder'; import { FolderUserStore } from 'Stores/User/Folder';
import { MessageUserStore } from 'Stores/User/Message'; import { MessageUserStore } from 'Stores/User/Message';
@ -36,6 +37,7 @@ export class MailFolderList extends AbstractViewLeft {
this.moveAction = moveAction; this.moveAction = moveAction;
this.allowContacts = AppUserStore.allowContacts(); this.allowContacts = AppUserStore.allowContacts();
this.pluginNavEntries = pluginNavEntries;
this.foldersFilter = foldersFilter; this.foldersFilter = foldersFilter;

View file

@ -5,6 +5,9 @@
<span class="buttonComposeText" data-i18n="FOLDER_LIST/BUTTON_NEW_MESSAGE"></span> <span class="buttonComposeText" data-i18n="FOLDER_LIST/BUTTON_NEW_MESSAGE"></span>
</a> </a>
<a class="btn buttonContacts fontastic" data-bind="visible: allowContacts, click: contactsClick" data-i18n="[title]GLOBAL/CONTACTS">📇</a> <a class="btn buttonContacts fontastic" data-bind="visible: allowContacts, click: contactsClick" data-i18n="[title]GLOBAL/CONTACTS">📇</a>
<!-- ko foreach: pluginNavEntries -->
<a class="btn buttonPluginNav fontastic" data-bind="text: icon, attr: { title: title }, click: click"></a>
<!-- /ko -->
</div> </div>
<div class="b-content"> <div class="b-content">
<ul class="b-folders-system" data-bind="foreach: systemFolders"> <ul class="b-folders-system" data-bind="foreach: systemFolders">