feat: nový způsob zobrazování novinek
All checks were successful
ci/woodpecker/push/workflow Pipeline was successful

fix: oprava kopírování changelogů do Docker image

fix: oprava kopírování changelogů do Docker image
This commit is contained in:
2026-03-08 09:59:07 +01:00
parent a1b1eed86d
commit f090d58bbb
28 changed files with 194 additions and 18 deletions

View File

@@ -0,0 +1,4 @@
[
"Zimní atmosféra",
"Skrytí podniku U Motlíků"
]

View File

@@ -0,0 +1,3 @@
[
"Přidání restaurace Zastávka u Michala"
]

View File

@@ -0,0 +1,3 @@
[
"Přidání restaurace Pivovarský šenk Šeříková"
]

View File

@@ -0,0 +1,3 @@
[
"Možnost výběru podniku/jídla kliknutím"
]

View File

@@ -0,0 +1,3 @@
[
"Stránka se statistikami nejoblíbenějších voleb"
]

View File

@@ -0,0 +1,3 @@
[
"Zobrazení počtu osob u každé volby"
]

View File

@@ -0,0 +1,3 @@
[
"Migrace na generované OpenApi"
]

View File

@@ -0,0 +1,3 @@
[
"Odebrání zimní atmosféry"
]

View File

@@ -0,0 +1,3 @@
[
"Možnost ručního přenačtení menu"
]

View File

@@ -0,0 +1,3 @@
[
"Parsování a zobrazení alergenů"
]

View File

@@ -0,0 +1,4 @@
[
"Oddělení přenačtení menu do vlastního dialogu",
"Podzimní atmosféra"
]

View File

@@ -0,0 +1,3 @@
[
"Možnost převzetí poznámky ostatních uživatelů"
]

View File

@@ -0,0 +1,3 @@
[
"Zimní atmosféra"
]

View File

@@ -0,0 +1,3 @@
[
"Možnost označit se jako objednávající u volby \"Budu objednávat\""
]

View File

@@ -0,0 +1,3 @@
[
"Podpora dark mode"
]

View File

@@ -0,0 +1,7 @@
[
"Redesign aplikace pomocí Claude Code",
"Zobrazení uplynulého týdne i o víkendu",
"Podpora Discord, ntfy a Teams notifikací (v Nastavení)",
"Trvalé zobrazení QR kódů do ručního zavření",
"Zobrazení nejvíce požadovaných funkcí (na stránce Statistiky)"
]

View File

@@ -0,0 +1,3 @@
[
"Zobrazení sekce Pizza day pouze při volbě \"Pizza day\""
]

View File

@@ -0,0 +1,3 @@
[
"Možnost generování obecných QR kódů pro platby i mimo Pizza day (v uživatelském menu)"
]

View File

@@ -0,0 +1,3 @@
[
"Podpora push notifikací pro připomenutí výběru oběda (v nastavení)"
]

View File

@@ -0,0 +1,3 @@
[
"Oprava detekce zastaralého menu"
]

View File

@@ -0,0 +1,3 @@
[
"Automatické zobrazení dialogu s dosud nezobrazenými novinkami"
]

View File

@@ -18,6 +18,7 @@ import statsRoutes from "./routes/statsRoutes";
import notificationRoutes from "./routes/notificationRoutes";
import qrRoutes from "./routes/qrRoutes";
import devRoutes from "./routes/devRoutes";
import changelogRoutes from "./routes/changelogRoutes";
const ENVIRONMENT = process.env.NODE_ENV ?? 'production';
dotenv.config({ path: path.resolve(__dirname, `../.env.${ENVIRONMENT}`) });
@@ -165,6 +166,7 @@ app.use("/api/stats", statsRoutes);
app.use("/api/notifications", notificationRoutes);
app.use("/api/qr", qrRoutes);
app.use("/api/dev", devRoutes);
app.use("/api/changelogs", changelogRoutes);
app.use('/stats', express.static('public'));
app.use(express.static('public'));

View File

@@ -0,0 +1,50 @@
import express, { Request, Response } from "express";
import fs from "fs";
import path from "path";
const router = express.Router();
const CHANGELOGS_DIR = path.resolve(__dirname, "../../changelogs");
// In-memory cache: datum → seznam změn
const cache: Record<string, string[]> = {};
function loadAllChangelogs(): Record<string, string[]> {
let files: string[];
try {
files = fs.readdirSync(CHANGELOGS_DIR).filter(f => f.endsWith(".json"));
} catch {
return {};
}
for (const file of files) {
const date = file.replace(".json", "");
if (!cache[date]) {
const content = fs.readFileSync(path.join(CHANGELOGS_DIR, file), "utf-8");
cache[date] = JSON.parse(content);
}
}
return cache;
}
router.get("/", (req: Request, res: Response) => {
const all = loadAllChangelogs();
const since = typeof req.query.since === "string" ? req.query.since : undefined;
// Seřazení od nejnovějšího po nejstarší
const sortedDates = Object.keys(all).sort((a, b) => b.localeCompare(a));
const filteredDates = since
? sortedDates.filter(date => date > since)
: sortedDates;
const result: Record<string, string[]> = {};
for (const date of filteredDates) {
result[date] = all[date];
}
res.status(200).json(result);
});
export default router;