feat(portal): add category sorting controls (#940)

* feat(portal): add category sort modes

* fix(portal): address category sort review feedback
This commit is contained in:
4gray authored and GitHub committed 2026-05-15 00:28:32 +02:00
1 parent 2a5b1d1da7
commit 8232a86a1e
34 files changed
+579 -51

No files matched your search

@@ -1,5 +1,6 @@
import type { AppDatabase } from '../database.types';
import { saveCategories } from './category.operations';
import * as schema from 'database-schema';
import { getCategories, saveCategories } from './category.operations';
function createDbMock(existingCount = 0) {
const where = jest.fn().mockResolvedValue([{ count: existingCount }]);
@@ -24,6 +25,20 @@ function createDbMock(existingCount = 0) {
}
describe('category.operations', () => {
it('reads visible categories in insertion order to preserve server sorting', async () => {
const orderBy = jest.fn().mockResolvedValue([]);
const where = jest.fn().mockReturnValue({ orderBy });
const from = jest.fn().mockReturnValue({ where });
const select = jest.fn().mockReturnValue({ from });
const db = {
select,
} as unknown as AppDatabase;
await getCategories(db, 'playlist-1', 'live');
expect(orderBy).toHaveBeenCalledWith(schema.categories.id);
});
it('restores hidden categories when Xtream API category IDs are strings', async () => {
const { db, values, insert } = createDbMock();
@@ -7,7 +7,9 @@ type XtreamCategoryInput = {
category_id: string | number;
};
function normalizeXtreamCategoryId(rawCategoryId: string | number): number | null {
function normalizeXtreamCategoryId(
rawCategoryId: string | number
): number | null {
const xtreamId = Number.parseInt(String(rawCategoryId), 10);
return Number.isNaN(xtreamId) ? null : xtreamId;
@@ -36,6 +38,10 @@ export async function getCategories(
playlistId: string,
type: 'live' | 'movies' | 'series'
) {
// Xtream categories are inserted once in provider order and existing
// xtream IDs are preserved, so row id order represents server order.
// If partial category re-inserts are added later, persist a provider
// sort index instead of relying on the insertion id.
return db
.select()
.from(schema.categories)
@@ -46,7 +52,7 @@ export async function getCategories(
eq(schema.categories.hidden, false)
)
)
.orderBy(sql`name COLLATE NOCASE`);
.orderBy(schema.categories.id);
}
export async function saveCategories(