Регистрация Войти
natvak7viu

ну такое

3 Января 2025
Комментарии natvak7viu
Статья
1
Архив фактов (sugata.ru)

было бы круто реализовать API для хранения реакций на записи, база уже есть на проекте

// emoji 
const REACTION_EMOJI = {
  like: "👍",
  dislike: "🥱",
  party: "🥳"
};

// иконки реакций
const REACTION_ICONS = {
  like: "/assets/reactions/like.svg",
  dislike: "/assets/reactions/dislike.svg",
  party: "/assets/reactions/party.svg"
};

// API
const API_URL =
  "https://api.sugata.ru/dev/posts/{slug}/likes";


// получаем slug поста из URL: /posts/my-post-slug
function getPostSlug() {
  return document.location.pathname.match(/^\/posts\/([a-z0-9-_]+)/)?.[1];
}


// рендер списка реакций
function renderReactions(data, container) {
  const html = Object.entries(data).map(([type, count]) => `
    <li class="reactions__item reaction" data-type="${type}">
      <button aria-label="Поставить реакцию ${type}">
        <img
          class="reaction__image"
          src="${REACTION_ICONS[type]}"
          alt="${REACTION_EMOJI[type]}"
          width="64"
          height="64"
        />
        <div class="reaction__counter">
          ${count}
        </div>
      </button>
    </li>
  `);

  container.innerHTML = html.join("");
}


// переключение активной реакции
function toggleReaction(container, selector, active) {
  const item = container.querySelector(selector);
  if (!item) return;

  const img = item.querySelector(".reaction__image");
  const counter = item.querySelector(".reaction__counter");
  const button = item.querySelector("button");

  if (active) {
    item.classList.add("reaction_active");
    button.setAttribute("aria-current", "true");
    img.src = img.src.replace(".svg", ".gif");
    counter.textContent = +counter.textContent + 1;
  } else {
    item.classList.remove("reaction_active");
    button.removeAttribute("aria-current");
    img.src = img.src.replace(".gif", ".svg");
    counter.textContent = +counter.textContent - 1;
  }
}


// === Инициализация ===

function initReactions() {
  const container = document.querySelector(".reactions");
  if (!container) return;

  // стартовые значения
  renderReactions({
    shocked: 0,
    love: 0,
    like: 0,
    dislike: 0,
    rage: 0,
    party: 0,
    partyPopper: 0
  }, container);

  // загрузка данных с сервера
  fetch(API_URL.replace("{slug}", getPostSlug()))
    .then(r => r.json())
    .then(data => {
      renderReactions(data, container);

      // обработчик кликов
      container.addEventListener("click", (e) => {
        const reaction = e.target.closest(".reaction");
        if (!reaction) return;

        const type = reaction.dataset.type;

        // снимаем предыдущую активную
        toggleReaction(container, ".reaction_active", false);

        // активируем текущую
        toggleReaction(container, `.reaction[data-type="${type}"]`, true);

        // отправляем на сервер
        fetch(API_URL.replace("{slug}", getPostSlug()), {
          method: "POST",
          headers: { "Content-Type": "application/x-www-form-urlencoded" },
          body: JSON.stringify({ reactionId: type })
        });
      });
    })
    .catch(console.error);
}

document.addEventListener("DOMContentLoaded", initReactions);
Статья
1
Архив фактов (sugata.ru)

По описанию интересный движок для ssg, попробую развернуть на выходных. Я для проектовы использую 11ty. Я правильно понял что Sugata запускает перегинерацию всех объектов при изменении? Нехватает только 404.html что бы не показывать серверное сообщение и можно прикрутить

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.open(CACHE_NAME)
      .then(cache => cache.match(event.request, { ignoreSearch: true }))
      .then(response => response || fetch(event.request))
      .catch(function() {
        return caches.match('/offline.html');
      })
  );
});

что бы красота была)

+ Забыл еще спросить, не смотрели в сторону SQLite, на первый взгляд он идеально подошел бы сюда.

+ Еще обратил внимание что отсутствует sitemap.xml, очень жаль что он не генерируется(

Статья
1
Замена редактора

Markitup заброшенный проект еще в 2018 году, он устарел во всех смыслах. Что бы его актуализировать это очень большой труд, проще новый написать. А imperavi предлагают купить персональную лицензию за $2 799 на один проект (сайт). Если он вам так нравится вам его конечно без проблем смогут поставить на ваш проект. Но предлагать подобные решения libarea весьма странно.

Пост
2
Статья
1
DEV: Вот надумал удалить из ядра прям каталог...

Заменить редактор не так сложно, если хорошо знаешь ядро системы. Модульная структура уже реализована: каталог, поиск и админка – это отдельные модули. Поэтому, при должном изучении ядра движка, вы сможете самостоятельно внести изменения и поделиться своими наработками с другими участниками сообщества.

Статья
Статья
5
🔔 Больше никаких пропущенных уведомлений 🔔

Можно оставить только эту строку notif_title('\uD83D\uDCAC (+'+ data.length +') ' + site_name + '', '\uD83D\uDD14 (+'+ data.length +') ' + site_name + ''); но заголовок будет обновляться в зависимости от настройки update_time.

Статья
1
Преображение комментариев: делаем вывод изящнее

ЗЫ Шаг 2: Делаем чистый код

<hr class="linta-100">
      <a class="flex flex-row items-center justify-between gray-600 gap-sm" href="<?= $post_url; ?>#comment">
         <div>
          <svg class="icon">
            <use xlink:href="/assets/svg/icons.svg#comments"></use>
          </svg>
          <?php if ($post['post_comments_count'] != 0) : ?>
                  <span class="lowercase text-sm"><?= Html::numWord($post['post_comments_count'], __('app.num_comment'), true); ?></span>
          <?php else : ?>
            <span class="lowercase text-sm"><?= __('app.add_comments'); ?></span>
            <?php endif; ?>
            </div>
          <svg class="icon">
          <use xlink:href="/assets/svg/icons.svg#chevron-right"></use>
        </svg>
        </a>
Статья
4
CSS: Отступы (+ размеры шрифта и др)...

добавил дополнительную полосу в шаблон, где вывел инфу по комментариям.

Отличное решение! Стало удобнее. Есть пара идей, как можно улучшить, если это не создаст дополнительной нагрузки: Группировка аватарок пользователей и отображение количества комментариев. Это добавляет ощущения близости, а знакомые лица на аватарках побуждают открыть и поучаствовать в дискуссии. Снимок экрана 2025-01-29 в 12.04.49.png

Отображение последнего или самого популярного комментария (или нескольких), как и предлагали ранее. Сейчас наблюдается тенденция отказа от перехода на отдельную страницу записи. Многие проекты позволяют читать запись целиком и видеть все комментарии прямо в ленте, а также оставлять ответы. Это, на мой взгляд, делает общение более динамичным. Снимок экрана 2025-01-29 в 11.50.56.png

Снимок экрана 2025-01-29 в 11.52.02.png

Если интегрировать WebSockets, то общение станет по-настоящему живым. Можно было бы наблюдать в реальном времени добавление постов, изменение количества комментариев, появление новых комментариев в процессе обсуждения, и все это без необходимости перезагрузки страницы.

Статья
1
Как отобразить чужой сайт в фрейме?

Откройте консоль разработчика в браузере во время загрузки вашего HTML-файла, содержащего iframe. Если сторонний сайт, который вы пытаетесь встроить, в своих HTTP-заголовках отдает заголовок X-Frame-Options со значением, запрещающим отображение в iframe (например, DENY или SAMEORIGIN), либо заголовок Content-Security-Policy с директивой frame-ancestors, которая не разрешает загрузку в iframe с вашего домена, браузер заблокирует отображение содержимого этого сайта внутри iframe, и вы увидите сообщение об ошибке в консоли.

Статья
1
Введите таймаут для хранения временных файлов, по истечении заданного времени файл будет автоматически удален

Выбирая VPS/VDS, вы получаете простой и логичный способ управлением диска. Наращивать его можно постепенно, без лишних затрат. Нет необходимости сразу арендовать 100 ГБ. Начните с 5 ГБ и плавно увеличивайте объем каждый месяц по мере роста. Это не только проще, но и намного выгоднее, чем сразу брать огромный объем.

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

Статья
2
Замена редактора

Разумеется Markdown вся молодость прошла с ним 😄!

+ Снимок экрана 2025-01-18 в 10.54.39.png

Markdown это стандарт!

Статья
2
Замена редактора

Можно сохранить Markdown?)

+ В Telegram, GitHub, Redmine, Trello, Discord, WhatsApp все используют Markdown Список может быть бесконечным. Markdown прекрасен и знаком каждому. Зачем его менять?

Но юным пользователям затмевает успех VC, DTF, TJ, и они хотят повторить его. И всё, что их отделяет от успеха, по их мнению, это редактор Комитета EditorJS 😄