Фокус редактора при предустановленном заголовке

У меня есть URL, похожий на этот:

https://forum.example.com/new-message?groupname=moderators&title=Help+me+with+some+task+please

Я ссылаюсь на него со своего сайта, чтобы перенаправить пользователей на форум для задания вопроса. Я использую различные значения для параметра title, чтобы предварительно заполнить заголовок темой, которая их интересует, и хотел бы, чтобы редактор сразу получал фокус.

Я искал, как это изменить, и нашел файл composer.js с определением focusTarget, что позволило бы довольно легко добавить поддержку такого поведения, если бы параметр title передавался.

Проблема в том, что я не вижу, где именно вызывается focusTarget. Я программирую уже много лет, но новичок в Ember и мало занимался JavaScript.

Буду очень признателен за любые советы по подходу к решению этой задачи (даже ссылка на разумную документацию или руководство будет полезна).

Спасибо!

Думаю, вот то, что вы ищете:

https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/components/composer-editor.js#L159-L164

Каждый раз, когда значение focusTarget меняется, вызывается эта функция setFocus.

Верно, этот код обеспечивает работу. А вот я не уверен, какой именно код нужно изменить, чтобы этот метод мог получать заголовок, и тогда я смогу корректно установить фокус на редактор…

https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/services/composer.js#L218-L243

Думаю, можно сделать что-то подобное. Это должно сработать.

import putCursorAtEnd from "discourse/lib/put-cursor-at-end";

api.onAppEvent("composer:open", ({ model }) => {
  if (model.title !== "") {
    scheduleOnce("afterRender", () => {
      putCursorAtEnd(document.querySelector("textarea.d-editor-input"));
    });
  }
});

Я почти добился успеха — при выполнении кода возникает ошибка: scheduleOnce не определён. Я попробовал вызвать api.scheduleOnce, но, похоже, scheduleOnce — это функция Ember. Я попытался добавить этот импорт в свой компонент, но получил ошибку: импорты разрешены только на верхнем уровне.
import { scheduleOnce } from "@ember/runloop";

Думаю, я упускаю что-то мелкое, и продолжу экспериментировать, но подумал, стоит ли спросить у вас — не очевидно ли это?

Спасибо ещё раз :slight_smile:

Да, импорт верный. Разместите оба импорта в верхней части файла, и всё будет в порядке.

В какой файл мне их поместить? Я пытался просто использовать это в как компонент. Вот что я сделал, что привело к появлению лога «scheduling afterRender», а затем к ошибке о том, что scheduleOnce не существует. Я пробовал несколько способов импорта, но ничего не получается. Подозреваю, что проблема в моём неопытности с модулями в JavaScript. Возможно, я не могу сделать это через компонент и мне нужно создать полноценный плагин. Посмотрю на этот вариант — ещё раз спасибо за помощь :slight_smile:

<script type="text/discourse-plugin" version="1.8.0">
    api.onAppEvent("composer:open", ({ model }) => {
      console.log("composer open happened, model is: ", model);
      if (model.title !== "") {
        console.log("scheduling afterRender");
        scheduleOnce("afterRender", () => {
          console.log("after render happening");
          api.putCursorAtEnd(document.querySelector("textarea.d-editor-input"));
        });
      }
    });
</script>

А, я понял. Я предположил, что вы используете JS в его файлах.

В таком случае из интерфейса администратора вы напишете:

<script type="text/discourse-plugin" version="1.8.0">
    const putCursorAtEnd = require("discourse/lib/put-cursor-at-end").default;
    const { scheduleOnce } = require("@ember/runloop");

    api.onAppEvent("composer:open", ({ model }) => {
      if (model.title !== "") {
        scheduleOnce("afterRender", () => {
          putCursorAtEnd(document.querySelector("textarea.d-editor-input"));
        });
      }
    });
</script>

Кстати, я настоятельно рекомендую вам использовать CLI для тем. Вы можете создать компонент темы из шаблона, синхронизировать его с Discourse с возможностью обновления в реальном времени и вносить любые изменения с помощью редактора. Это намного проще, чем использовать интерфейс!

Спасибо большое — я знал, что что-то упускал! Обязательно настрою использование CLI темы и буду редактировать их таким образом :slight_smile: :slight_smile:

Ещё раз спасибо, Arkshine! Я создал свой первый компонент с помощью discourse_theme :slight_smile:
Для тех, кто наткнулся на эту тему: мне просто нужно было выполнить несколько команд:

gem install discourse_theme
npm install -g yarn
discourse_theme new <component-name>

затем отредактировать файл: javascripts/discourse/api-initializers/.js
загрузить его на GitHub, и всё — можно устанавливать и делиться.
Мой компонент находится здесь.
Похоже, там есть функция автоматического обновления версии на вашем сервере по мере изменения файлов. Звучит отлично и полезно, особенно когда я займусь более сложными компонентами.

Ура!