Emoji mention theme component

Я хотел бы иметь возможность использовать пользовательские SVG-изображения в качестве иконки рядом с упоминанием. Я видел подобное на Guilded для сотрудников, и мне тоже хотелось бы иметь такую возможность, но у меня не получалось. И это ещё одна причина, по которой мне так нравится Discourse: здесь я могу самостоятельно собрать что-то рабочее, вместо того чтобы надеяться и ждать, пока разработчики добавят эту функцию.

Поэтому я собрал следующее решение. Оно далеко не идеальное: вероятно, загружаемый вами SVG-файл должен иметь переменную SCSS, начинающуюся с svg. Тем не менее, на данный момент этого достаточно для моей задачи :slight_smile:

Если кто-то захочет взять этот код, доработать его и сделать ещё лучше, я буду очень признателен!

Возможные улучшения:

  1. Сделать так, чтобы это работало для всех SVG-иконки, включая все стандартные иконки Discourse и загруженные файлы, названия которых не начинаются с svg.
  2. Очистить код.
  3. Улучшить стилизацию, так как я довольно кустарно настроил CSS, и он может не работать во всех ситуациях.

В любом случае, вот пример упоминания с использованием моей пользовательской иконки для «Эмоциональной самозащиты» в качестве иконки упоминания сотрудника:

image

Вот код, который я добавил:

header.html

  // Добавить SVG-иконки как опцию, при условии, что они включены в assets и загружены
  // Создает объект всех ассетов и перебирает их, чтобы найти ссылки, у которых атрибут data-emoji
  // равен имени переменной ассета, а затем добавляет для них URL

  // преобразовать объект в массив ключей
  const keys = Object.keys(settings.theme_uploads);

  // вывести все ключи
  console.log(keys);

  // перебрать объект
  keys.forEach((key, index) => {
      console.log(`${key}: ${settings.theme_uploads[key]}`);
      api.decorateCooked($elem => {
        var url = settings.theme_uploads[key];
        console.log("key: " + key);
        console.log("index: " + index);
        console.log("url: " + url);
        console.log(JSON.stringify(settings.theme_uploads));
        $elem
          .find("a[data-emoji^='" + key + "']")
          .css("--svg-icon", "url('" + url + "')");
        }
      );    
  });

common.scss

@if $show-after-mention == "true" {
  [data-emoji^="svg"]:after {
    content: 'hey ';
    color: transparent;
    height:5px;
    width:15px;
    background: var(--svg-icon) no-repeat center;
    background-size: contain;
    display: inline;
  }
} @else {
  [data-emoji^="svg"]:before {
    content: 'hey ';
    color: transparent;
    height:5px;
    width:15px;
    background: var(--svg-icon) no-repeat center;
    background-size: contain;
    display: inline;
  }
}

Это также требует от вас:

  1. Создать папку /assets.
  2. Добавить файлы svg в папку /assets, например /assets/esd-heart.svg.
  3. Обновить файл about.json, чтобы добавить ссылки на эти ассеты, например:
"assets": {
  	"svg_esd_heart": "assets/esd-heart.svg"
}
1 лайк