mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 19:46:16 -08:00
feat: add backdrop_url to content schema and related database operations
This commit is contained in:
1 parent
423f693fe5
commit
ad528238b2
4 files changed
+82
-11
No files matched your search
Vendored
+15
-3
@@ -222,14 +222,21 @@ declare global {
|
||||
) => Promise<any[]>;
|
||||
dbGetGlobalRecentlyAdded: (
|
||||
kind: 'all' | 'vod' | 'series',
|
||||
limit?: number
|
||||
limit?: number,
|
||||
playlistType?:
|
||||
| 'xtream'
|
||||
| 'stalker'
|
||||
| 'm3u-file'
|
||||
| 'm3u-text'
|
||||
| 'm3u-url'
|
||||
) => Promise<any[]>;
|
||||
dbGetRecentlyViewed: () => Promise<any[]>;
|
||||
dbClearRecentlyViewed: () => Promise<{ success: boolean }>;
|
||||
// Favorites
|
||||
dbAddFavorite: (
|
||||
contentId: number,
|
||||
playlistId: string
|
||||
playlistId: string,
|
||||
backdropUrl?: string
|
||||
) => Promise<{ success: boolean }>;
|
||||
dbRemoveFavorite: (
|
||||
contentId: number,
|
||||
@@ -249,7 +256,8 @@ declare global {
|
||||
dbGetRecentItems: (playlistId: string) => Promise<any[]>;
|
||||
dbAddRecentItem: (
|
||||
contentId: number,
|
||||
playlistId: string
|
||||
playlistId: string,
|
||||
backdropUrl?: string
|
||||
) => Promise<{ success: boolean }>;
|
||||
dbClearPlaylistRecentItems: (
|
||||
playlistId: string
|
||||
@@ -263,6 +271,10 @@ declare global {
|
||||
playlistId: string,
|
||||
contentType?: 'live' | 'movie' | 'series'
|
||||
) => Promise<any | null>;
|
||||
dbSetContentBackdropIfMissing: (
|
||||
contentId: number,
|
||||
backdropUrl?: string
|
||||
) => Promise<{ success: boolean }>;
|
||||
dbGetAppState: (key: string) => Promise<string | null>;
|
||||
dbSetAppState: (
|
||||
key: string,
|
||||
|
||||
@@ -28,6 +28,7 @@ export interface XtreamContent {
|
||||
rating: string;
|
||||
added: string;
|
||||
poster_url: string;
|
||||
backdrop_url?: string | null;
|
||||
epg_channel_id?: string | null;
|
||||
tv_archive?: number | null;
|
||||
tv_archive_duration?: number | null;
|
||||
@@ -124,6 +125,13 @@ export function isDbAbortError(error: unknown): boolean {
|
||||
|
||||
export type GlobalRecentlyAddedKind = 'all' | 'vod' | 'series';
|
||||
|
||||
export type GlobalRecentlyAddedPlaylistType =
|
||||
| 'xtream'
|
||||
| 'stalker'
|
||||
| 'm3u-file'
|
||||
| 'm3u-text'
|
||||
| 'm3u-url';
|
||||
|
||||
export interface GlobalRecentlyAddedItem extends XtreamContent {
|
||||
playlist_id: string;
|
||||
playlist_name: string;
|
||||
@@ -581,15 +589,20 @@ export class DatabaseService {
|
||||
|
||||
/**
|
||||
* Get recently added VOD and series items across all Xtream playlists.
|
||||
* When `playlistType` is supplied, the LIMIT window is applied only to
|
||||
* rows from playlists of that type, so Xtream items cannot be squeezed
|
||||
* out by newer M3U/Stalker content.
|
||||
*/
|
||||
async getGlobalRecentlyAdded(
|
||||
kind: GlobalRecentlyAddedKind,
|
||||
limit = 200
|
||||
limit = 200,
|
||||
playlistType?: GlobalRecentlyAddedPlaylistType
|
||||
): Promise<GlobalRecentlyAddedItem[]> {
|
||||
try {
|
||||
const items = await window.electron.dbGetGlobalRecentlyAdded(
|
||||
kind,
|
||||
limit
|
||||
limit,
|
||||
playlistType
|
||||
);
|
||||
return items || [];
|
||||
} catch (error) {
|
||||
@@ -671,14 +684,22 @@ export class DatabaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content to favorites
|
||||
* Add content to favorites.
|
||||
* @param backdropUrl optionally persisted to `content.backdrop_url` when
|
||||
* the row doesn't already have one. Lets the dashboard hero surface a
|
||||
* cinematic backdrop without a separate round-trip.
|
||||
*/
|
||||
async addToFavorites(
|
||||
contentId: number,
|
||||
playlistId: string
|
||||
playlistId: string,
|
||||
backdropUrl?: string
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
await window.electron.dbAddFavorite(contentId, playlistId);
|
||||
await window.electron.dbAddFavorite(
|
||||
contentId,
|
||||
playlistId,
|
||||
backdropUrl
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error adding to favorites:', error);
|
||||
@@ -739,14 +760,19 @@ export class DatabaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add item to recently viewed
|
||||
* Add item to recently viewed. See `addToFavorites` for `backdropUrl`.
|
||||
*/
|
||||
async addRecentItem(
|
||||
contentId: number,
|
||||
playlistId: string
|
||||
playlistId: string,
|
||||
backdropUrl?: string
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
await window.electron.dbAddRecentItem(contentId, playlistId);
|
||||
await window.electron.dbAddRecentItem(
|
||||
contentId,
|
||||
playlistId,
|
||||
backdropUrl
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error adding recent item:', error);
|
||||
@@ -754,6 +780,35 @@ export class DatabaseService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist a backdrop URL onto an Xtream content row without touching
|
||||
* recently viewed ordering or timestamps.
|
||||
*/
|
||||
async setContentBackdropIfMissing(
|
||||
contentId: number,
|
||||
backdropUrl?: string
|
||||
): Promise<boolean> {
|
||||
const normalizedBackdropUrl = backdropUrl?.trim();
|
||||
if (!normalizedBackdropUrl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!window.electron?.dbSetContentBackdropIfMissing) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
await window.electron.dbSetContentBackdropIfMissing(
|
||||
contentId,
|
||||
normalizedBackdropUrl
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error backfilling content backdrop:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear recently viewed for a specific playlist
|
||||
*/
|
||||
|
||||
@@ -112,6 +112,7 @@ const CREATE_TABLE_STATEMENTS = [
|
||||
rating TEXT,
|
||||
added TEXT,
|
||||
poster_url TEXT,
|
||||
backdrop_url TEXT,
|
||||
epg_channel_id TEXT,
|
||||
tv_archive INTEGER,
|
||||
tv_archive_duration INTEGER,
|
||||
@@ -269,6 +270,8 @@ const COLUMN_MIGRATION_STATEMENTS = [
|
||||
`ALTER TABLE content ADD COLUMN tv_archive INTEGER`,
|
||||
`ALTER TABLE content ADD COLUMN tv_archive_duration INTEGER`,
|
||||
`ALTER TABLE content ADD COLUMN direct_source TEXT`,
|
||||
// v1.5.0 -> v1.6.0: Cinematic backdrop persisted on first detail fetch
|
||||
`ALTER TABLE content ADD COLUMN backdrop_url TEXT`,
|
||||
];
|
||||
|
||||
const INDEX_MIGRATION_STATEMENTS = [
|
||||
|
||||
@@ -87,6 +87,7 @@ export const content = sqliteTable(
|
||||
rating: text('rating'),
|
||||
added: text('added'),
|
||||
posterUrl: text('poster_url'),
|
||||
backdropUrl: text('backdrop_url'),
|
||||
epgChannelId: text('epg_channel_id'),
|
||||
tvArchive: integer('tv_archive'),
|
||||
tvArchiveDuration: integer('tv_archive_duration'),
|
||||
|
||||
Reference in new issue
Block a user