Регистрация Войти
Статья
Статья
Знакомьтесь: «Работаем!» — децентрализованная замена корпоративным блог-платформам

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

А выше код, к этому можно относиться, как к дизайну. Просто поменяли «пользовательскую» часть Lemmy.

Все обычно меняли дизайн Lemmy изменяя css, тут подошли капитально. Шаблоны все другие. Вот так, если упрощать.

Статья
1
Знакомьтесь: «Работаем!» — децентрализованная замена корпоративным блог-платформам

Не взлетит пока не будет доступна установка на обычном хостинге/php

Статья
1
Знакомьтесь: «Работаем!» — децентрализованная замена корпоративным блог-платформам

Я тоже ничего не понял… Ведь этот Lemmy — он же тоже есть на giithub… https://github.com/LemmyNet/lemmy

Может кто-то объяснить по простому как все это работает? И зачем мне проект по типу VC — если у меня нет контроля за базой данных… Так то вроде интересно все. Непонятно в чем фишка?

Статья
1
Архив фактов (sugata.ru)

Раньше у меня было вот так: search.домен.ru. А на самом домене, в html, стояла просто форма поиска с отправкой именно на search.

Статья
1
Архив фактов (sugata.ru)

Сами результаты поиска показывать на другом домене?

Статья
1
Архив фактов (sugata.ru)

api.sugata нужно делать и расположить там ещё поиск, чтобы форма была доступна на сайте, где только html. Тут идея заключается в том, чтобы в сам sugata, не заносить по возможности скрипты.

Статья
1
Архив фактов (sugata.ru)

Я правильно понял что Sugata запускает перегинерацию всех объектов при изменении?

Мы можем выбирать, какие части проекта нам надо пересобрать. Но надо добавить вариант, генерацию только того, что изменено. А вот где всё по сегментам, сдалать шаг с задержкой.

Там много чего нет. У меня времени нет прежде всего. (

P.S. я не думаю, что стоит туда «сувать» JS.

Статья
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
Знакомьтесь: «Работаем!» — децентрализованная замена корпоративным блог-платформам

Я хочу понять, что скрывается под словом «федерация». И я хочу понять что такое децентрализация и чем она отличается от той же libarea.

Статья
1
Знакомьтесь: «Работаем!» — децентрализованная замена корпоративным блог-платформам

Ну если не понятно, так зачем париться и создавать федерацию. На гит есть ссылка на чат поддержки, можете обратиться, разработчик пояснит, как и что работает. Насчёт шлака я пояснил, можно отключать федерации, можно создать чисто свой сайт. Есть же libarea, создайте на ней сообщество и все, я создал себе, все что не нужно было отключил, сделал свой стиль и довольствуюсь, над стилем ещё конечно поработаю, времени не хватает.

Статья
2
Знакомьтесь: «Работаем!» — децентрализованная замена корпоративным блог-платформам

Я всё равно нихера не понял.

Окей, то что лежит на гитхабе это интрфейс.

Я его запускаю у себя на vps и на моём сайте появляется всякий шлак, который строчат на какой-то Lemmy? или что?

Я хочу что бы пользователи регистрировались только у меня и писали/постили на моём сайте. Я не хочу получать какой-то мусор хер знает от кого на свой сайт.

Короче нихера не понял как это работает.

Статья
2
Знакомьтесь: «Работаем!» — децентрализованная замена корпоративным блог-платформам

Так не я же его создавал, я нашел его и поделился.

Суть проекта: Rabotaem — это фронтенд (визуальная оболочка/клиент) для Lemmy. Lemmy — это аналог Reddit, работающий на протоколе ActivityPub (Fediverse).

Вот ответы на вопросы из комментария по пунктам:

1. «Я не понимаю, как это работает? БД отсутствует?»

База данных есть, но она находится на стороне бэкенда.

  • Этот репозиторий (rabotaem) — это только клиент (интерфейс), написанный на Svelte/SvelteKit.
  • Он подключается к серверу Lemmy (бэкенду). Именно бэкенд хранит все данные в базе данных (обычно PostgreSQL).
  • Если устанавливать проект «с нуля», нужно поднимать и этот клиент, и бэкенд Lemmy (где и будет лежать БД).

2. «Если установить локально, то посты будут все равно распределятся по сети?»

Зависит от настройки бэкенда (Lemmy), к которому подключен клиент.

  • Да, если включена федерация: Lemmy работает через протокол ActivityPub. Это значит, что ваш сервер может «общаться» с другими серверами (как e-mail: вы можете отправить письмо с gmail на mail.ru). Посты могут улетать на другие сервера, если пользователи оттуда подписаны на ваши сообщества.
  • Нет, если закрыть сервер: В настройках Lemmy можно отключить федерацию (сделать «белый список» или полностью изолированный режим). Тогда посты останутся только у вас.

3. «Если кто-то установит и будет слать спам, такое можно отключить у себя?»

Да, можно.

  • Владелец своего сервера (инстанса) имеет полные права модератора.
  • Можно заблокировать конкретного пользователя.
  • Можно заблокировать целый сервер (домен), с которого идет спам (это называется «дефедерация»). Спам с заблокированного сервера перестанет приходить к вам.

4. «Если владелец проекта удалит проект, то все данные исчезнут?»

Нет, данные не исчезнут.

  • Код: Если автор удалит репозиторий на GitHub, исчезнет только источник обновлений кода. У вас останется ваша локальная копия, которая продолжит работать.
  • Данные: Ваши посты и пользователи хранятся в вашей базе данных на вашем сервере. Автор кода не имеет к ним доступа. Это главное преимущество Open Source и децентрализации — вы владеете своими данными.

5. Про адаптивность (UI на мобилках)

Это форк клиента Photon, который изначально делался с упором на минимализм. Вероятно, текущая верстка еще дорабатывается, так как проект позиционируется для SEO-контента и блогов.

Статья
1
Знакомьтесь: «Работаем!» — децентрализованная замена корпоративным блог-платформам

Поясните кто-нибудь что такое децентрализация в данном случае. Где файлы то хранятся?