Стиль DiscoTOC сломан, если нет ответа на мобильном

Привет :wave:

Стиль DiscoTOC связан с классом .with-topic-progress, который добавляется к .topic-navigation, если в теме более одного сообщения. Таким образом, без ответа стиль DiscoTOC будет нарушен.

Я считаю, что оглавление (TOC) должно работать и в том случае, если в теме нет ответов, поскольку это не связано с количеством ответов. На настольных устройствах оно корректно отображается и для тем без ответов.

Вот тема для тестирования: Customizing the topic list

Думаю, стоит рассмотреть возможность изменения этого поведения.

Возможно, это не новая проблема, но я ранее не замечал её. Сейчас мы начали использовать это более активно.

Спасибо :slight_smile:

7 лайков

Я тоже только что столкнулся с этим здесь. :cry: (iPhone/Safari) Было бы здорово, если бы это исправили. Прокрутка к концу длинного документа, чтобы добраться до оглавления, немного утомительна.

3 лайка

С моими базовыми навыками программирования и некоторыми подсказками от ChatGPT, я, думаю, добился успеха.

Создал пользовательский компонент и добавил следующее в вкладку CSS:

@media (max-width: 767px) {
    #topic-progress-wrapper.sticky-bottom {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 1000;
    }
}

а это — во вкладку JS:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  api.onPageChange(() => {
    const observer = new MutationObserver(() => {
      const wrapper = document.getElementById("topic-progress-wrapper");
      const tocButton = wrapper?.querySelector(".d-toc-mini button");

      if (wrapper) {
        if (tocButton) {
          wrapper.classList.add("sticky-bottom");
        } else {
          wrapper.classList.remove("sticky-bottom");
        }
      }
    });

    observer.observe(document.body, {
      childList: true,
      subtree: true,
    });
  });
});

Это, кажется, работает отлично даже без ответа.
Опять же, я не эксперт, я просто умею хорошо задавать вопросы, и после небольшого диалога с ChatGPT, задавая правильные вопросы и ставя задачи, всё, похоже, работает.

Если кто-то из экспертов по JavaScript и CSS захочет улучшить это решение, пожалуйста, поделитесь.


Итак, если вы хотите:

  1. Текст «Оглавление» рядом с иконкой
  2. Раскрытые заголовки
  3. Закреплённую кнопку, не зависящую от наличия ответов, то полный код CSS выглядит так:
/* раскрывает все заголовки в боковой панели оглавления */
#d-toc li.d-toc-item > ul {
  max-height: 500em !important;
  overflow: visible !important;
  opacity: 1 !important;
}

@media screen and (max-width: 767px) {
    /* делает обёртку, включая кнопку оглавления, закреплённой внизу */
    #topic-progress-wrapper.sticky-bottom {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 1000;
    }

    /* добавляет «оглавление» к кнопке после иконки */
    .d-toc-mini button::after {
        content: "Оглавление";
        margin-left: 5px;
        font-size: 14px;
        vertical-align: middle;
    }
}

JavaScript-код остаётся без изменений.

1 лайк

Привет :wave:

Отлично, спасибо, но, думаю, мы можем сделать это только с помощью CSS тоже. :thinking: Нам просто нужно применить те же стили CSS к .topic-navigation, что и к .with-topic-progress. Отсутствующий класс .with-topic-progress блокирует стилизацию, если в теме нет ответов.

Что-то вроде этого должно сработать.

CSS для мобильных устройств

// Фиксированная навигация по теме
.container.posts .topic-navigation:not(.with-topic-progress) {
  position: sticky;
  bottom: calc(env(safe-area-inset-bottom) + var(--composer-height, 0px));
  z-index: z("timeline");
  pointer-events: none; // обертка может блокировать элементы управления на мобильных устройствах
  
  > * {
    pointer-events: auto; // это отменяет правило выше, чтобы дочерние элементы оставались интерактивными
  }
  
  // Добавление стиля оглавления
  .d-toc-wrapper {
    position: fixed;
    margin-top: 0.25em;
    height: calc(100vh - 50px - var(--header-offset));
    opacity: 0.5;
    right: -100vw;
    top: var(--header-offset);
    width: 75vw;
    max-width: 350px;
    background-color: var(--secondary);
    box-shadow: var(--shadow-dropdown);
    z-index: z("modal", "overlay");
    transition: all 0.2s ease-in-out;

    .d-toc-main {
      width: 100%;
      padding: 0.5em;
      height: 100%;

      #d-toc {
        max-height: calc(100% - 3em);
      }
    }

    &.overlay {
      right: 0;
      width: 75vw;
      opacity: 1;

      .d-toc-main #d-toc li.d-toc-item ul {
        transition: none;
      }
    }

    a.scroll-to-bottom,
    a.d-toc-close {
      display: inline-block;
      padding: 0.5em;
    }

    .d-toc-icons {
      text-align: right;
    }
  }
}

// Поддержка RTL
.rtl {
  .topic-navigation .d-toc-wrapper {
    right: unset;
    left: -100vw;

    &.overlay {
      right: unset;
      left: 0;
    }
  }
}
1 лайк

Должно быть исправлено в

2 лайка

Эта тема была автоматически закрыта через 7 дней после последнего ответа. Новые ответы больше не принимаются.