Два клика — это не так уж много работы, но это хорошая возможность дать общее объяснение, документирующее, как работать с кнопками композера, с акцентом на то, что вы пытаетесь сделать.
Добавление кнопок на панель инструментов осуществляется с помощью другого метода API плагинов.
Панель инструментов использует этот метод plugin-api.js.es6#L375-L391, в то время как всплывающее меню использует этот plugin-api.js.es6#L396-L411.
Плагин готовых ответов использует метод всплывающего меню следующим образом:
Вы не можете переместить кнопку, если не сделаете форк плагина — это крайне не рекомендуется.
Что вы можете сделать, так это добавить другую кнопку на панель инструментов, которая выполняет то же самое, и скрыть старую. Чтобы создать кнопку на панели инструментов, вам нужно посмотреть, как добавляются другие кнопки.
На панели инструментов есть два типа кнопок. Первый тип — это кнопки, обрабатывающие форматирование, например Жирный и Курсив. Поскольку они не похожи на то, чего вы хотите достичь, пока проигнорируем их.
Другой тип кнопок вставляет такие вещи, как даты и эмодзи. Давайте посмотрим на кнопку даты — календаря.
Теперь у нас есть пример, к которому можно обратиться. Давайте попробуем создать новую кнопку.
Начнем с этого:
api.onToolbarCreate(toolbar => {
toolbar.addButton({
});
});
и по одному добавим атрибуты из кнопки готовых ответов. Для справки они следующие:
id: "canned_replies_button",
icon: "far-clipboard",
action: "showCannedRepliesButton",
label: "canned_replies.composer_button_text"
id: это позволяет добавить CSS-классы к кнопке — мы используем custom-canned-button.
icon: иконка, которую будет использовать кнопка — мы оставим её прежней.
label: у всплывающих кнопок есть текст, а у кнопок композера его нет, поэтому нам нужно изменить это на title и использовать то же значение.
action: здесь вы определяете, что делает кнопка. Давайте соберем всё вместе:
api.onToolbarCreate(toolbar => {
toolbar.addButton({
id: "custom-canned-replies",
icon: "far-clipboard",
action: "showCannedRepliesButton",
title: "canned_replies.composer_button_text"
});
});
Если вы попробуете это, вы получите кнопку на панели инструментов, но при нажатии на неё ничего не произойдет. Это происходит потому, что действие showCannedRepliesButton не определено. Это связано с другим контекстом, так как вы делаете это в теме.
Если вы посмотрите на плагин готовых ответов, то заметите, что это действие определено в контроллере композера:
Следующий шаг — обратиться к контроллеру композера, чтобы иметь возможность отправлять это действие при нажатии на кнопку. Вы можете сделать это следующим образом:
const composerController = api.container.lookup("controller:composer");
api.onToolbarCreate(toolbar => {
toolbar.addButton({
title: "canned_replies.composer_button_text",
id: "custom-canned-replies",
group: "extras",
icon: "far-clipboard",
sendAction: () => composerController.send("showCannedRepliesButton")
});
});
Обратите внимание, что мы использовали тот же паттерн, что и в кнопке календаря, для sendAction. Единственные два отличия: вместо этого
toolbar.context.send мы используем composerController.send
и мы не передаем событие, так как, думаю, это не нужно.
Это должно дать вам полностью функциональную кнопку на панели инструментов:
но мы еще не закончили, так как эта кнопка теперь видна всем участникам. Условия использования всё ещё применяются, и если пользователь без прав попытается на неё нажать, он получит ошибку. Однако нерабочая кнопка — это плохо, поэтому давайте исправим это.
Права на использование готовых ответов здесь:
Нам нужно только воспроизвести их как условия для добавления кнопки. Что-то вроде этого:
const currentUser = api.getCurrentUser();
const canUseCannedReplies = currentUser
? currentUser.can_use_canned_replies
: false;
if (!canUseCannedReplies) return;
и это обеспечит отображение кнопки только при наличии необходимых прав.
Итак, давайте соберем всё вместе:
import { withPluginApi } from "discourse/lib/plugin-api";
export default {
name: "move-canned-button",
initialize() {
withPluginApi("0.8.7", api => {
const currentUser = api.getCurrentUser();
const canUseCannedReplies = currentUser
? currentUser.can_use_canned_replies
: false;
if (!canUseCannedReplies) return;
const composerController = api.container.lookup("controller:composer");
api.onToolbarCreate(toolbar => {
toolbar.addButton({
title: "canned_replies.composer_button_text",
id: "custom-canned-replies",
group: "extras",
icon: "far-clipboard",
sendAction: () => composerController.send("showCannedRepliesButton")
});
});
});
}
};
Это помещается в этот файл в компоненте темы:
javascripts/discourse/initializers/move-canned-button.js.es6
если вы используете новую функцию Split up theme Javascript into multiple files — крайне рекомендуется.
Или вы можете просто добавить этот скрипт во вкладку заголовка в вашей теме, если делаете это через админку.
Старый синтаксис
<script type="text/discourse-plugin"
version="0.8">
const currentUser = api.getCurrentUser();
const canUseCannedReplies = currentUser
? currentUser.can_use_canned_replies
: false;
if (!canUseCannedReplies) return;
const composerController = api.container.lookup("controller:composer");
api.onToolbarCreate(toolbar => {
toolbar.addButton({
title: "canned_replies.composer_button_text",
id: "custom-canned-replies",
group: "extras",
icon: "far-clipboard",
sendAction: () => composerController.send("showCannedRepliesButton")
});
});
</script>
Последнее, что вам нужно сделать, — скрыть старую кнопку, и это можно сделать так:
.toolbar-popup-menu-options {
[data-name="Canned replies"] {
display: none;
}
}