[3.2][3.3] Emoji

Здесь авторы могут постить бета-версии своих расширений для phpBB. Внимание! Не устанавливайте бета-версии расширений на работающие форумы!
Правила форума
Местная Конституция | Шаблон запроса | Документация (phpBB3) | Мини [FAQ] по phpBB3.1.x/3.2.x | FAQ | Внимание! Прежде чем создать тему - прочти! | Как задавать вопросы | Как устанавливать расширения

Ваш вопрос может быть удален без объяснения причин, если на него есть ответы по приведённым ссылкам (а вы рискуете получить предупреждение ;) ).

Внимание! Не устанавливайте бета-версии расширений на работающие форумы!
Аватара пользователя
Kuskow
phpBB 2.0.5
Сообщения: 498
Стаж: 10 лет 3 месяца
Откуда: 🇰🇿 Караганда
Благодарил (а): 29 раз
Поблагодарили: 47 раз

Re: [3.2][3.3] Emoji

Сообщение Kuskow »

Шли годы, смеркалось. В ночи не спалось, решилось сделать вторую версию, которая не режет глаз. Рядом с кнопкой выбора цвета появляется ещё одна со смайликом. При её нажатии отображается панель эмодзи. В общем, всё как и с выбором цвета.

1️⃣ В папке styles/prosilver/template создаём файл emoji_panel.js с таким текстом:

Код: Выделить всё

(function() {
    // 1. АВТОНОМНОЕ ПОДКЛЮЧЕНИЕ IMGBB (если решите использовать комбо-вариант, иначе этот блок просто страхует)
    if (!document.getElementById('imgbb-plugin-script') && document.querySelector('script[src*="://imgbb.com"]')) {
        // Оставляем пустую проверку, чтобы не дублировать, если скрипт ImgBB уже есть в шаблоне
    }

    // 2. ЛОГИКА ПАНЕЛИ ЭМОДЗИ
    const rawEmojis = '😀🤣😉🤫😳😘😋🧐😭🤬🤯🥵🥶🤮🥳❤️💃🍻💩👌👉👈👇☝️👍👎👏💪💯➕✔❌✅⭕';
    const segmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
    const emojis = Array.from(segmenter.segment(rawEmojis), segment => segment.segment);

    let container = null;
    let listContainer = null;
    let currentTextarea = null;

    function createContainer() {
        if (container) return;
        
        container = document.createElement('div');
        container.id = 'phpbb-emoji-container';
        // z-index выставлен с запасом, чтобы перекрывать другие элементы формы
        container.style.cssText = 'display: none; position: absolute; z-index: 10000; background: #fff; border: 1px solid #ccc; padding: 6px; box-shadow: 0 -4px 8px rgba(0,0,0,0.1); border-radius: 4px; max-width: 452px;';
        
        listContainer = document.createElement('div');
        listContainer.id = 'phpbb-emoji-list';
        listContainer.style.cssText = 'display: grid; grid-template-columns: repeat(20, 22px); font-size: 16px; text-align: center;';
        
        container.appendChild(listContainer);
        document.body.appendChild(container);

        const fragment = document.createDocumentFragment();
        emojis.forEach(function(emoji) {
            const span = document.createElement('span');
            span.textContent = emoji;
            span.style.cssText = 'cursor:pointer;user-select:none;padding:0;transition:transform 0.1s;display:flex;align-items:center;justify-content:center;width:22px;height:22px;overflow:hidden;line-height:22px;box-sizing:border-box;';
            
            span.onmouseenter = () => span.style.transform = 'scale(1.25)';
            span.onmouseleave = () => span.style.transform = 'scale(1)';

            span.addEventListener('click', function(e) {
                e.preventDefault();
                if (!currentTextarea) return;
                
                const start = currentTextarea.selectionStart, end = currentTextarea.selectionEnd, scrollTop = currentTextarea.scrollTop;
                currentTextarea.value = currentTextarea.value.substring(0, start) + emoji + currentTextarea.value.substring(end);
                currentTextarea.focus();
                currentTextarea.selectionStart = currentTextarea.selectionEnd = start + emoji.length;
                currentTextarea.scrollTop = scrollTop;
            });
            fragment.appendChild(span);
        });
        listContainer.appendChild(fragment);
    }

    function injectEmojiButton(colorButton, textarea) {
        if (!colorButton || !textarea || colorButton.nextElementSibling?.classList.contains('phpbb-emoji-trigger')) return;

        const newButton = document.createElement('button');
        newButton.type = 'button';
        newButton.className = 'button button-icon-only responsive-hide phpbb-emoji-trigger';
        newButton.title = 'Выбрать эмодзи';
        newButton.innerHTML = '<i class="icon fa-smile-o fa-fw" aria-hidden="true"></i>';
        newButton.style.marginLeft = '4px';

        colorButton.parentNode.insertBefore(newButton, colorButton.nextSibling);

        newButton.onclick = function(e) {
            e.preventDefault();
            e.stopPropagation();

            // Если панель уже открыта именно для ЭТОЙ кнопки — закрываем её без лишних условий
            if (container.style.display === 'block' && container.dataset.activeButton === newButton.title) {
                container.style.display = 'none';
                container.dataset.activeButton = "";
                return;
            }

            currentTextarea = textarea;
            container.dataset.activeButton = newButton.title; // Запоминаем текущий активный триггер

            const rect = newButton.getBoundingClientRect();
            
            // Фиксированная высота нашей панели (62px). Из top кнопки вычитаем 62px и 5px зазор.
            container.style.top = (window.scrollY + rect.top - 67) + 'px';
            container.style.left = (window.scrollX + rect.left) + 'px';
            container.style.display = 'block';
        };
    }

    function autoScanAndInject() {
        const colorButtons = document.querySelectorAll('[name="bbpalette"], #bbpalette, .bbcode-color');
        
        if (colorButtons.length > 0) {
            createContainer();
            
            colorButtons.forEach(colorBtn => {
                const parentForm = colorBtn.closest('form') || colorBtn.closest('.quickreply') || colorBtn.closest('#qr_postform') || document;
                const textarea = parentForm.querySelector('textarea');
                
                if (textarea) {
                    injectEmojiButton(colorBtn, textarea);
                }
            });
        }
    }

    setInterval(autoScanAndInject, 500);

    document.addEventListener('click', function(e) {
        if (container && container.style.display === 'block') {
            if (!container.contains(e.target) && !e.target.closest('.phpbb-emoji-trigger')) {
                container.style.display = 'none';
            }
        }
    });
})();

2️⃣ В конце файла overall_footer.html перед закрывающим тегом </body> дописываем строчку:

Код: Выделить всё

<!-- INCLUDEJS emoji_panel.js -->

3️⃣ Заходим в админку форума, очищаем кэш. И вот нам результат:

Screenshot (10).png
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось Kuskow 07.09.2026 5:11, всего редактировалось 1 раз.
Аватара пользователя
Perfecthus
phpBB 2.0.14
Сообщения: 958
Стаж: 15 лет 10 месяцев
Откуда: Оттуда
Благодарил (а): 53 раза
Поблагодарили: 103 раза

Re: [3.2][3.3] Emoji

Сообщение Perfecthus »

Kuskow, Чего у тебя кнопка к соседней слева впритык? Поправь косячок. ;)
Кстати, количество эмодзи можно добавить во вкладку?
Аватара пользователя
Kuskow
phpBB 2.0.5
Сообщения: 498
Стаж: 10 лет 3 месяца
Откуда: 🇰🇿 Караганда
Благодарил (а): 29 раз
Поблагодарили: 47 раз

Re: [3.2][3.3] Emoji

Сообщение Kuskow »

Perfecthus писал(а): Сегодня 4:26 Кстати, количество эмодзи можно добавить во вкладку?
Да, вот тут в рамках кавычек делайте что хотите. не обязательно эмодзи - можн и обычными символами устроить виртуальную клавиатуру с иероглифами.

Screenshot (11).png
Отправлено спустя 35 минут 8 секунд:
Perfecthus писал(а): Сегодня 4:26 Чего у тебя кнопка к соседней слева впритык? Поправь косячок.
Исправил в исходном сообщении - успел до закрытия возможности редактирования.
У вас нет необходимых прав для просмотра вложений в этом сообщении.

Вернуться в «Бета-версии расширений для phpBB»