Merge welcome-readme-refresh → dev (0.58.0 landing refresh)

This commit is contained in:
2026-07-29 18:29:18 +02:00
13 changed files with 92 additions and 41 deletions
+5 -3
View File
@@ -5,7 +5,7 @@ channels you follow into one clean, filterable feed — no algorithm deciding wh
Shorts or livestream noise unless you want it. Self-hosted, multi-user, and private: your data
stays on your own server.
![Siftlode feed](frontend/public/welcome/feed.png)
![Siftlode feed](frontend/public/welcome/feed.webp)
Everything expensive (channels, videos, metadata) is fetched from YouTube once and stored locally,
so filtering, searching and sorting are instant and don't burn API quota. Click a video to watch it
@@ -16,8 +16,8 @@ blocker and SponsorBlock keep working.
- **A readable subscription feed** — sort and filter by channel, tag, language, topic, length,
upload date or watch state; hide channels without unsubscribing; save filter setups as named views.
- **Search all of YouTube** from the feed — results play, save and add to playlists like any other
video, and are materialised into your catalog.
- **Search all of YouTube** from the feed — live results you can play, save or add to playlists like
any other video; they stay temporary and out of your catalog unless you keep one.
- **Channel pages & a channel manager** — per-channel stats and uploads, priorities, and your own
tags to slice the feed by.
- **Playlists with two-way YouTube sync** — build them locally, keep them in sync in both directions.
@@ -25,6 +25,8 @@ blocker and SponsorBlock keep working.
- **Download Center** — save videos to the server with yt-dlp in a Plex-friendly layout (format
presets, per-user storage quota), trim / crop / split & join them in a built-in editor, then save
to your device, share with another user, or hand out a public watch link.
- **Plex library** *(optional)* — point Siftlode at your own Plex server to browse and play its
movies and shows alongside your feed, with watch state kept in sync.
- **Multi-user** with per-user private state, a shared catalog, and a fair daily API-quota guard.
- **Self-hosted & private**, with a first-run web setup wizard and the interface in **English
and Hungarian**.
+1 -1
View File
@@ -1 +1 @@
0.57.2
0.58.0
Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

+28 -14
View File
@@ -2,7 +2,9 @@ import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import {
ArrowRight,
Clapperboard,
Code2,
Download,
Expand,
Filter,
Inbox,
@@ -115,20 +117,19 @@ export default function Welcome() {
</div>
</section>
{/* Secondary showcase — smaller thumbnails; click to view full size. */}
<section className="mt-12 flex flex-wrap justify-center gap-4">
<Preview
src="/welcome/channels.webp"
label={t("welcome.preview.channels")}
className="w-full sm:w-72 aspect-[4/3]"
onOpen={open}
/>
<Preview
src="/welcome/playlists.webp"
label={t("welcome.preview.playlists")}
className="w-full sm:w-72 aspect-[4/3]"
onOpen={open}
/>
{/* Gallery — one shot per module; click any to view it full size. */}
<section className="mt-12">
<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
{GALLERY.map((g) => (
<Preview
key={g.key}
src={g.src}
label={t(`welcome.preview.${g.key}`)}
className="aspect-video"
onOpen={open}
/>
))}
</div>
</section>
</main>
@@ -159,12 +160,25 @@ export default function Welcome() {
);
}
// The screenshot gallery below the hero — one shot per module, each opening full-size in the
// lightbox. Order roughly follows the nav rail; the feed leads as the hero above the fold.
const GALLERY: { key: string; src: string }[] = [
{ key: "channels", src: "/welcome/channels.webp" },
{ key: "playlists", src: "/welcome/playlists.webp" },
{ key: "search", src: "/welcome/search.webp" },
{ key: "player", src: "/welcome/player.webp" },
{ key: "downloads", src: "/welcome/downloads.webp" },
{ key: "plex", src: "/welcome/plex.webp" },
];
const FEATURES: { key: string; icon: LucideIcon }[] = [
{ key: "readable", icon: Filter },
{ key: "neverMiss", icon: Inbox },
{ key: "search", icon: Search },
{ key: "playlists", icon: ListVideo },
{ key: "player", icon: PlayCircle },
{ key: "downloads", icon: Download },
{ key: "plex", icon: Clapperboard },
{ key: "private", icon: Lock },
];
+23 -11
View File
@@ -1,24 +1,28 @@
{
"hero": {
"title": "Your YouTube subscriptions, the way a feed should work.",
"subtitle": "Every upload from the channels you follow in one clean, filterable feed — no algorithm deciding what you see, and no Shorts or livestream noise unless you want it.",
"trust": "Self-hosted and private. Sign in with email, or continue with Google."
"title": "Your subscriptions, in one quiet feed.",
"subtitle": "Every upload from the channels you follow, in one place you can actually filter, search and sort. No algorithm deciding what you see and no Shorts or livestreams unless you want them.",
"trust": "Self-hosted and private: your data stays on your own server. Sign in with email, or continue with Google."
},
"openSource": {
"title": "Free and open source",
"body": "Siftlode's code is public — see how it works, run your own private instance, or open an issue.",
"body": "The whole thing is open — read the code, run your own private copy, or open an issue.",
"link": "View the source"
},
"preview": {
"feed": "The feed — filter by channel, language, topic, length and date.",
"channels": "Channel manager",
"playlists": "Playlists"
"playlists": "Playlists",
"player": "In-app player",
"downloads": "Download Center",
"search": "Search results",
"plex": "Your Plex library"
},
"features": {
"heading": "Why Siftlode",
"heading": "What it does",
"readable": {
"title": "Your subscriptions, actually readable",
"body": "Sort and filter by channel, tag, language, topic, length or date, and save your setups as views. You decide what surfaces, not an algorithm."
"body": "Sort and filter by channel, tag, language, topic, length or date, and save your setups as views."
},
"neverMiss": {
"title": "Never miss an upload",
@@ -26,19 +30,27 @@
},
"search": {
"title": "Search all of YouTube",
"body": "Search YouTube right from your feed — results play, save and add to playlists like any other video."
"body": "Search right from your feed — results play, save and add to playlists like any other video."
},
"playlists": {
"title": "Playlists that sync both ways",
"body": "Build playlists locally and keep them in two-way sync with YouTube."
"body": "Build them locally and keep them in two-way sync with YouTube."
},
"player": {
"title": "Watch in-app, resume anywhere",
"body": "An in-app player picks up each video exactly where you left off — no recommendation rabbit-hole."
"body": "A built-in player picks each video up where you left off, with keyboard and scroll controls."
},
"downloads": {
"title": "Download Center",
"body": "Save videos to your server in a Plex-friendly layout, trim or join them, then share a link."
},
"plex": {
"title": "Your Plex library too",
"body": "Browse and play what your Plex server already holds, right alongside your feed."
},
"private": {
"title": "Self-hosted and private",
"body": "Run it yourself, multi-user, in English and Hungarian. Your data stays yours."
"body": "Run it yourself, multi-user, in English and Hungarian — your data stays yours."
}
},
"auth": {
+24 -12
View File
@@ -1,24 +1,28 @@
{
"hero": {
"title": "A YouTube-feliratkozásaid úgy, ahogy egy hírfolyamnak működnie kéne.",
"subtitle": "Minden feltöltés a követett csatornáidról egyetlen tiszta, szűrhető hírfolyamban — nincs algoritmus, ami eldönti, mit látsz, és nincs Shorts- vagy élő-zaj, hacsak nem kéred.",
"trust": "Self-hosted és privát. Lépj be e-maillel, vagy folytasd Google-fiókkal."
"title": "A feliratkozásaid egyetlen nyugodt hírfolyamban.",
"subtitle": "Minden feltöltés a követett csatornáidról egy helyen, amit tényleg szűrhetsz, kereshetsz és rendezhetsz. Nincs algoritmus, ami eldönti, mit látsz és nincs Shorts vagy élő adás, hacsak nem kéred.",
"trust": "Self-hosted és privát: az adataid a saját szervereden maradnak. Lépj be e-maillel, vagy folytasd Google-fiókkal."
},
"openSource": {
"title": "Ingyenes és nyílt forráskódú",
"body": "A Siftlode kódja nyilvános — nézd meg, hogyan működik, futtass saját privát példányt, vagy nyiss egy hibajegyet.",
"body": "Az egész nyílt — nézd meg a kódot, futtass saját privát példányt, vagy nyiss egy hibajegyet.",
"link": "Forráskód megtekintése"
},
"preview": {
"feed": "A hírfolyam — szűrés csatorna, nyelv, téma, hossz és dátum szerint.",
"channels": "Csatorna-kezelő",
"playlists": "Lejátszási listák"
"playlists": "Lejátszási listák",
"player": "Beépített lejátszó",
"downloads": "Letöltésközpont",
"search": "Keresési találatok",
"plex": "A Plex-könyvtárad"
},
"features": {
"heading": "Miért a Siftlode",
"heading": "Mit tud",
"readable": {
"title": "A feliratkozásaid végre olvashatóan",
"body": "Rendezz és szűrj csatorna, címke, nyelv, téma, hossz vagy dátum szerint, és mentsd el a beállításaidat nézetként. Te döntöd el, mi kerül elő, nem egy algoritmus."
"body": "Rendezz és szűrj csatorna, címke, nyelv, téma, hossz vagy dátum szerint, és mentsd el a beállításaidat nézetként."
},
"neverMiss": {
"title": "Egy feltöltés se vesszen el",
@@ -26,19 +30,27 @@
},
"search": {
"title": "Keress az egész YouTube-on",
"body": "Keress a YouTube-on közvetlenül a hírfolyamból — a találatok ugyanúgy lejátszhatók, menthetők és listához adhatók, mint bármely más videó."
"body": "Keress közvetlenül a hírfolyamból — a találatok ugyanúgy lejátszhatók, menthetők és listához adhatók, mint bármely más videó."
},
"playlists": {
"title": "Kétirányban szinkronizált lejátszási listák",
"body": "Építs helyi lejátszási listákat, és tartsd őket kétirányú szinkronban a YouTube-bal."
"title": "Kétirányban szinkronizált listák",
"body": "Építsd helyben, és tartsd kétirányú szinkronban a YouTube-bal."
},
"player": {
"title": "Nézd appon belül, folytasd bárhonnan",
"body": "Az appon belüli lejátszó pontosan onnan folytatja a videót, ahol abbahagytad — nincs ajánló-örvény."
"body": "A beépített lejátszó onnan folytatja a videót, ahol abbahagytad — billentyű- és görgetés-vezérléssel."
},
"downloads": {
"title": "Letöltésközpont",
"body": "Ments videókat a szerveredre Plex-barát elrendezésben, vágd vagy fűzd össze őket, majd oszd meg egy linkkel."
},
"plex": {
"title": "A Plex-könyvtárad is",
"body": "Böngészd és játszd le, amit a Plex-szervered már tárol, a hírfolyamod mellett."
},
"private": {
"title": "Self-hosted és privát",
"body": "Futtasd magad, többfelhasználós, angolul és magyarul. Az adataid a tieid maradnak."
"body": "Futtasd magad, többfelhasználós, angolul és magyarul — az adataid a tieid maradnak."
}
},
"auth": {
+11
View File
@@ -14,6 +14,17 @@ export interface ReleaseEntry {
}
export const RELEASE_NOTES: ReleaseEntry[] = [
{
version: "0.58.0",
date: "2026-07-29",
summary:
"Housekeeping: a refreshed public landing page and internal frontend cleanup — nothing changes for signed-in users.",
chores: [
"Landing: the signed-out welcome page has a new screenshot gallery (feed, channels, playlists, player, search, downloads and Plex) and refreshed, plainer copy describing what the app does.",
"Frontend: finished splitting the data-fetching layer into per-domain modules behind a thin façade (no behaviour change).",
"Docs: the README is brought up to date (feature list, Plex, search behaviour) and its landing screenshot fixed.",
],
},
{
version: "0.57.2",
date: "2026-07-28",