mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 11:06:16 -08:00
fix(xtream): track and show import progress of playlist
This commit is contained in:
1 parent
c173553d78
commit
54f4abb48b
8 files changed
+82
-24
No files matched your search
@@ -28,6 +28,16 @@ contextBridge.exposeInMainWorld('electron', {
|
||||
) => {
|
||||
ipcRenderer.on('EPG_PROGRESS_UPDATE', (_event, data) => callback(data));
|
||||
},
|
||||
// DB save content progress listener
|
||||
onDbSaveContentProgress: (callback: (count: number) => void) => {
|
||||
ipcRenderer.on('DB_SAVE_CONTENT_PROGRESS', (_event, count) =>
|
||||
callback(count)
|
||||
);
|
||||
},
|
||||
// Remove DB save content progress listener
|
||||
removeDbSaveContentProgress: () => {
|
||||
ipcRenderer.removeAllListeners('DB_SAVE_CONTENT_PROGRESS');
|
||||
},
|
||||
getAppVersion: () => ipcRenderer.invoke('get-app-version'),
|
||||
platform: process.platform,
|
||||
fetchPlaylistByUrl: (url: string, title?: string) =>
|
||||
|
||||
@@ -184,8 +184,8 @@ ipcMain.handle(
|
||||
);
|
||||
totalInserted += chunk.length;
|
||||
|
||||
// Send progress update
|
||||
event.sender.send('DB_SAVE_CONTENT_PROGRESS', totalInserted);
|
||||
// Send incremental progress update (chunk size, not cumulative total)
|
||||
event.sender.send('DB_SAVE_CONTENT_PROGRESS', chunk.length);
|
||||
}
|
||||
|
||||
return { success: true, count: totalInserted };
|
||||
|
||||
@@ -184,7 +184,9 @@ export class ElectronXtreamDataSource implements IXtreamDataSource {
|
||||
async getContent(
|
||||
playlistId: string,
|
||||
credentials: XtreamCredentials,
|
||||
type: StreamType
|
||||
type: StreamType,
|
||||
onProgress?: (count: number) => void,
|
||||
onTotal?: (total: number) => void
|
||||
): Promise<XtreamContentItem[]> {
|
||||
// Check if we have cached data
|
||||
const exists = await this.dbService.hasXtreamContent(playlistId, type);
|
||||
@@ -198,11 +200,17 @@ export class ElectronXtreamDataSource implements IXtreamDataSource {
|
||||
const remoteData = await this.apiService.getStreams(credentials, type);
|
||||
|
||||
if (remoteData && Array.isArray(remoteData) && remoteData.length > 0) {
|
||||
// Save to cache
|
||||
// Report total items to import
|
||||
if (onTotal) {
|
||||
onTotal(remoteData.length);
|
||||
}
|
||||
|
||||
// Save to cache with progress tracking
|
||||
await this.dbService.saveXtreamContent(
|
||||
playlistId,
|
||||
remoteData as any[],
|
||||
type
|
||||
type,
|
||||
onProgress
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,9 @@ export class PwaXtreamDataSource implements IXtreamDataSource {
|
||||
async getContent(
|
||||
playlistId: string,
|
||||
credentials: XtreamCredentials,
|
||||
type: StreamType
|
||||
type: StreamType,
|
||||
onProgress?: (count: number) => void,
|
||||
onTotal?: (total: number) => void
|
||||
): Promise<XtreamLiveStream[] | XtreamVodStream[] | XtreamSerieItem[]> {
|
||||
const cacheKey = `${playlistId}-${type}-content`;
|
||||
|
||||
@@ -179,6 +181,14 @@ export class PwaXtreamDataSource implements IXtreamDataSource {
|
||||
// Fetch from API
|
||||
const content = await this.apiService.getStreams(credentials, type);
|
||||
|
||||
// Report total and progress (PWA doesn't have incremental save, so report all at once)
|
||||
if (onTotal) {
|
||||
onTotal(content.length);
|
||||
}
|
||||
if (onProgress) {
|
||||
onProgress(content.length);
|
||||
}
|
||||
|
||||
// Cache in memory
|
||||
this.contentCache.set(cacheKey, content);
|
||||
|
||||
|
||||
@@ -199,11 +199,15 @@ export interface IXtreamDataSource {
|
||||
|
||||
/**
|
||||
* Get content/streams for a playlist and type
|
||||
* @param onProgress - Optional callback for import progress (count)
|
||||
* @param onTotal - Optional callback for total items to import
|
||||
*/
|
||||
getContent(
|
||||
playlistId: string,
|
||||
credentials: XtreamCredentials,
|
||||
type: StreamType
|
||||
type: StreamType,
|
||||
onProgress?: ProgressCallback,
|
||||
onTotal?: (total: number) => void
|
||||
): Promise<XtreamLiveStream[] | XtreamVodStream[] | XtreamSerieItem[] | XtreamContentItem[]>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -181,7 +181,7 @@ export function withContent() {
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch all content/streams in parallel
|
||||
* Fetch all content/streams in parallel with progress tracking
|
||||
*/
|
||||
async fetchAllContent(): Promise<void> {
|
||||
const ctx = getCredentialsFromStore();
|
||||
@@ -189,22 +189,42 @@ export function withContent() {
|
||||
|
||||
patchState(store, { isLoadingContent: true });
|
||||
|
||||
// Track combined progress across all content types
|
||||
let totalItems = 0;
|
||||
let importedItems = 0;
|
||||
|
||||
const onTotal = (count: number) => {
|
||||
totalItems += count;
|
||||
patchState(store, { itemsToImport: totalItems });
|
||||
};
|
||||
|
||||
const onProgress = (count: number) => {
|
||||
importedItems += count;
|
||||
patchState(store, { importCount: importedItems });
|
||||
};
|
||||
|
||||
try {
|
||||
const [live, vod, series] = await Promise.all([
|
||||
dataSource.getContent(
|
||||
ctx.playlistId,
|
||||
ctx.credentials,
|
||||
'live'
|
||||
'live',
|
||||
onProgress,
|
||||
onTotal
|
||||
),
|
||||
dataSource.getContent(
|
||||
ctx.playlistId,
|
||||
ctx.credentials,
|
||||
'movie'
|
||||
'movie',
|
||||
onProgress,
|
||||
onTotal
|
||||
),
|
||||
dataSource.getContent(
|
||||
ctx.playlistId,
|
||||
ctx.credentials,
|
||||
'series'
|
||||
'series',
|
||||
onProgress,
|
||||
onTotal
|
||||
),
|
||||
]);
|
||||
|
||||
@@ -227,13 +247,13 @@ export function withContent() {
|
||||
const ctx = getCredentialsFromStore();
|
||||
if (!ctx) return;
|
||||
|
||||
patchState(store, { isImporting: true, importCount: 0 });
|
||||
patchState(store, { isImporting: true, importCount: 0, itemsToImport: 0 });
|
||||
|
||||
try {
|
||||
// Fetch categories first
|
||||
await this.fetchAllCategories();
|
||||
|
||||
// Then fetch content
|
||||
// Then fetch content (with progress tracking)
|
||||
await this.fetchAllContent();
|
||||
|
||||
// Restore user data if needed
|
||||
|
||||
Vendored
+3
@@ -210,6 +210,9 @@ declare global {
|
||||
error?: string;
|
||||
}) => void
|
||||
) => void;
|
||||
// DB save content progress listener
|
||||
onDbSaveContentProgress: (callback: (count: number) => void) => void;
|
||||
removeDbSaveContentProgress: () => void;
|
||||
dbDeleteAllPlaylists: () => Promise<{ success: boolean }>;
|
||||
};
|
||||
process: NodeJS.Process;
|
||||
|
||||
@@ -237,19 +237,22 @@ export class DatabaseService {
|
||||
): Promise<number> {
|
||||
// Setup progress listener if callback provided
|
||||
if (onProgress) {
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data.type === 'DB_SAVE_CONTENT_PROGRESS') {
|
||||
onProgress(event.data.count);
|
||||
}
|
||||
});
|
||||
window.electron.onDbSaveContentProgress(onProgress);
|
||||
}
|
||||
|
||||
const result = await window.electron.dbSaveContent(
|
||||
playlistId,
|
||||
streams,
|
||||
type
|
||||
);
|
||||
return result.count;
|
||||
try {
|
||||
const result = await window.electron.dbSaveContent(
|
||||
playlistId,
|
||||
streams,
|
||||
type
|
||||
);
|
||||
return result.count;
|
||||
} finally {
|
||||
// Clean up the listener
|
||||
if (onProgress) {
|
||||
window.electron.removeDbSaveContentProgress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user