Add grouping categories feature

This commit is contained in:
2025-06-08 17:12:48 +09:00
parent fdaa7bb445
commit 3fee0294d9
3 changed files with 140 additions and 12 deletions

View File

@ -213,6 +213,7 @@ export interface Feed {
url: string;
title?: string;
description?: string;
category?: string;
lastUpdated?: string;
createdAt: string;
active: boolean;
@ -325,6 +326,7 @@ export async function getFeedByUrl(url: string): Promise<Feed | null> {
url: row.url,
title: row.title,
description: row.description,
category: row.category,
lastUpdated: row.last_updated,
createdAt: row.created_at,
active: Boolean(row.active),
@ -346,6 +348,7 @@ export async function getFeedById(id: string): Promise<Feed | null> {
url: row.url,
title: row.title,
description: row.description,
category: row.category,
lastUpdated: row.last_updated,
createdAt: row.created_at,
active: Boolean(row.active),
@ -368,6 +371,7 @@ export async function getAllFeeds(): Promise<Feed[]> {
url: row.url,
title: row.title,
description: row.description,
category: row.category,
lastUpdated: row.last_updated,
createdAt: row.created_at,
active: Boolean(row.active),
@ -549,6 +553,7 @@ export async function getAllFeedsIncludingInactive(): Promise<Feed[]> {
url: row.url,
title: row.title,
description: row.description,
category: row.category,
lastUpdated: row.last_updated,
createdAt: row.created_at,
active: Boolean(row.active),
@ -559,6 +564,68 @@ export async function getAllFeedsIncludingInactive(): Promise<Feed[]> {
}
}
export async function getFeedsByCategory(category?: string): Promise<Feed[]> {
try {
let stmt;
let rows;
if (category) {
stmt = db.prepare("SELECT * FROM feeds WHERE category = ? AND active = 1 ORDER BY created_at DESC");
rows = stmt.all(category) as any[];
} else {
// If no category specified, return all active feeds
stmt = db.prepare("SELECT * FROM feeds WHERE active = 1 ORDER BY created_at DESC");
rows = stmt.all() as any[];
}
return rows.map((row) => ({
id: row.id,
url: row.url,
title: row.title,
description: row.description,
category: row.category,
lastUpdated: row.last_updated,
createdAt: row.created_at,
active: Boolean(row.active),
}));
} catch (error) {
console.error("Error getting feeds by category:", error);
throw error;
}
}
export async function getAllCategories(): Promise<string[]> {
try {
const stmt = db.prepare("SELECT DISTINCT category FROM feeds WHERE category IS NOT NULL AND active = 1 ORDER BY category");
const rows = stmt.all() as any[];
return rows.map((row) => row.category).filter(Boolean);
} catch (error) {
console.error("Error getting all categories:", error);
throw error;
}
}
export async function getFeedsGroupedByCategory(): Promise<{ [category: string]: Feed[] }> {
try {
const feeds = await getAllFeeds();
const grouped: { [category: string]: Feed[] } = {};
for (const feed of feeds) {
const category = feed.category || 'Uncategorized';
if (!grouped[category]) {
grouped[category] = [];
}
grouped[category].push(feed);
}
return grouped;
} catch (error) {
console.error("Error getting feeds grouped by category:", error);
throw error;
}
}
export async function deleteFeed(feedId: string): Promise<boolean> {
try {
// Start transaction