Aggiungi un pulsante diretto alle risposte predefinite nell'editor

2 click non sono davvero molto lavoro, ma questa è una buona opportunità per una spiegazione generale che documenti come lavorare con i pulsanti del composer, concentrandosi su ciò che stai cercando di fare.

L’aggiunta di pulsanti alla barra degli strumenti viene effettuata con un metodo diverso dell’API dei plugin.

La barra degli strumenti utilizza questo metodo plugin-api.js.es6#L375-L391, mentre il menu a comparsa utilizza questo plugin-api.js.es6#L396-L411.

Il plugin delle risposte predefinite utilizza il metodo del menu a comparsa in questo modo:

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L18-L25

Non puoi spostare il pulsante a meno che non fork il plugin, cosa fortemente sconsigliata.

Ciò che puoi fare è aggiungere un altro pulsante nella barra degli strumenti che faccia la stessa cosa e nascondere quello vecchio. Per creare un pulsante nella barra degli strumenti, dovrai osservare come vengono aggiunti altri pulsanti.

Ci sono due tipi di pulsanti nella barra degli strumenti. Il primo tipo sono i pulsanti che gestiscono la formattazione, come Grassetto e Corsivo. Dato che non sono simili a ciò che vuoi ottenere, per ora ignoriamoli.

L’altro tipo di pulsante inserisce cose come date ed emoji. Esaminiamo il pulsante data - calendario.

Ora abbiamo un esempio a cui fare riferimento. Proviamo quindi a creare il nuovo pulsante.

Iniziamo con questo:

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
  
  });
});

e aggiungiamo gli attributi del pulsante delle risposte predefinite uno per uno. A titolo di riferimento, questi sono:

id: "canned_replies_button",
icon: "far-clipboard",
action: "showCannedRepliesButton",
label: "canned_replies.composer_button_text"

id: questo ti permette di aggiungere classi CSS al pulsante - useremo custom-canned-button.

icon: l’icona che il pulsante utilizzerà - la manterremo uguale.

label: i pulsanti a comparsa hanno del testo mentre quelli del composer no, quindi dobbiamo cambiarlo in title e usare lo stesso valore.

action: qui definisci cosa fa il pulsante. Mettiamo tutto insieme:

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
    id: "custom-canned-replies",
    icon: "far-clipboard",
    action: "showCannedRepliesButton",
    title: "canned_replies.composer_button_text"
  });
});

Se provi questo, otterrai un pulsante nella barra degli strumenti, ma cliccarlo non farà nulla. Questo accade perché l’azione showCannedRepliesButton non è definita. Questo succede a causa del contesto diverso - dato che lo stai facendo in un tema.

Se guardi il plugin delle risposte predefinite, noterai che quell’azione è definita nel controller del composer:

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L5-L16

Quindi il prossimo passo è riferirti al controller del composer per poter inviare quell’azione quando il pulsante viene cliccato. Puoi farlo in questo modo:

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")
  });
});

Notate che abbiamo usato lo stesso pattern del pulsante calendario per sendAction. Le uniche due eccezioni sono invece di questo:

toolbar.context.send usiamo composerController.send

e non stiamo passando l’evento perché non credo sia necessario.

Questo dovrebbe darti un pulsante pienamente funzionante nella barra degli strumenti:

ma non abbiamo ancora finito, poiché questo pulsante è ora visibile a tutti i membri. Le autorizzazioni di utilizzo rimangono valide e se un utente senza autorizzazioni prova a cliccarlo, riceverà solo un errore. Tuttavia, un pulsante rotto non va bene, quindi sistemiamolo.

Le autorizzazioni per l’uso delle risposte predefinite sono qui:

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L34-L38

Quindi dobbiamo solo replicarle come condizioni per l’aggiunta del pulsante. Quindi qualcosa del genere:

const currentUser = api.getCurrentUser();
const canUseCannedReplies = currentUser
  ? currentUser.can_use_canned_replies
  : false;

if (!canUseCannedReplies) return;

e questo assicurerà che il pulsante venga visualizzato solo se hai le autorizzazioni richieste.

Quindi, mettiamo tutto insieme:

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")
        });
      });
    });
  }
};

Questo va inserito in questo file in un componente del tema:

javascripts/discourse/initializers/move-canned-button.js.es6

se stai utilizzando la nuova funzionalità Split up theme Javascript into multiple files - fortemente raccomandata.

Oppure puoi semplicemente aggiungere questo script alla scheda Intestazione nel tuo tema se lo stai facendo nell’amministratore.

Vecchia sintassi
<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>

L’ultima cosa di cui hai bisogno è nascondere il vecchio pulsante e puoi farlo in questo modo:

.toolbar-popup-menu-options {
  [data-name="Canned replies"] {
    display: none;
  }
}