sync fix addon

This commit is contained in:
tapframe 2025-09-20 12:38:32 +05:30
parent 0011079199
commit 32591b2710

View file

@ -854,20 +854,35 @@ class SyncService {
logger.log(`[Sync] push installed_addons count=${addons.length}`);
let order = (stremioService as any).addonOrder as string[];
// Safety: if this is a first-time push and local addons are fewer than remote, pull before pushing
// Safety: Check if this device has ever synced addons for this user
// Only pull if this is truly a first-time sync AND remote has significantly more addons
try {
const initialized = (await AsyncStorage.getItem(`@user:${userId}:addons_initialized`)) === 'true';
const deviceInitialized = (await AsyncStorage.getItem(`@user:${userId}:addons_initialized`)) === 'true';
const { data: remoteBefore } = await supabase
.from('installed_addons')
.select('addon_id')
.eq('user_id', userId);
const remoteCount = (remoteBefore || []).length;
if (!initialized && remoteCount > addons.length) {
logger.log('[Sync] addons not initialized and local smaller than remote → pulling before push');
// Only pull if:
// 1. This device hasn't initialized addons for this user
// 2. Remote has significantly more addons (not just pre-installed ones)
// 3. Local has only pre-installed addons (2 or fewer)
const hasOnlyPreInstalled = addons.length <= 2 &&
addons.every(a => ['com.linvo.cinemeta', 'org.stremio.opensubtitlesv3'].includes(a.id));
if (!deviceInitialized && remoteCount > 2 && hasOnlyPreInstalled) {
logger.log('[Sync] Device first-time sync with only pre-installed addons → pulling before push');
await this.pullAddonsSnapshot(userId);
// refresh local state after pull
addons = await stremioService.getInstalledAddonsAsync();
order = (stremioService as any).addonOrder as string[];
} else if (!deviceInitialized && remoteCount > addons.length) {
logger.log('[Sync] Device first-time sync but local has custom addons → merging instead of pulling');
// Don't pull - merge the addons instead
await this.mergeAddonsFromServer(userId);
addons = await stremioService.getInstalledAddonsAsync();
order = (stremioService as any).addonOrder as string[];
}
} catch {}
@ -883,16 +898,23 @@ class SyncService {
manifest_data: a,
}));
// Delete remote addons that no longer exist locally (excluding pre-installed to be safe)
// Guard: do not perform deletions on first-time merge when remote has more addons
// Enhanced safety: only delete if device has been initialized and user explicitly removed addons
try {
const { data: remote, error: rErr } = await supabase
.from('installed_addons')
.select('addon_id')
.eq('user_id', userId);
if (!rErr && remote) {
const initialized = (await AsyncStorage.getItem(`@user:${userId}:addons_initialized`)) === 'true';
if (!initialized && (remote as any[]).length > addons.length) {
logger.log('[Sync] skipping deletions during first-time addon merge');
const deviceInitialized = (await AsyncStorage.getItem(`@user:${userId}:addons_initialized`)) === 'true';
// Only perform deletions if:
// 1. Device has been initialized (not first-time sync)
// 2. Local addons are not just pre-installed ones
const hasOnlyPreInstalled = addons.length <= 2 &&
addons.every(a => ['com.linvo.cinemeta', 'org.stremio.opensubtitlesv3'].includes(a.id));
if (!deviceInitialized || hasOnlyPreInstalled) {
logger.log('[Sync] skipping deletions during first-time sync or when only pre-installed addons present');
} else {
const localIds = new Set(addons.map((a: any) => a.id));
const toDeletePromises = (remote as any[])
@ -929,6 +951,55 @@ class SyncService {
}
// Excluded: pushLocalScrapers (local scrapers are device-local only)
private async mergeAddonsFromServer(userId: string): Promise<void> {
logger.log('[Sync] mergeAddonsFromServer: merging server addons with local addons');
try {
const { data: remoteAddons } = await supabase
.from('installed_addons')
.select('*')
.eq('user_id', userId)
.order('position', { ascending: true });
if (!remoteAddons || remoteAddons.length === 0) return;
// Get current local addons
const localAddons = await stremioService.getInstalledAddonsAsync();
const localAddonIds = new Set(localAddons.map(a => a.id));
// Merge remote addons that aren't already local
const addonsToInstall: any[] = [];
for (const remoteAddon of remoteAddons as any[]) {
if (!localAddonIds.has(remoteAddon.addon_id)) {
try {
let manifest = remoteAddon.manifest_data;
if (!manifest && remoteAddon.original_url) {
manifest = await stremioService.getManifest(remoteAddon.original_url);
}
if (manifest) {
addonsToInstall.push(manifest);
}
} catch (e) {
logger.warn('[Sync] Failed to fetch manifest for remote addon:', remoteAddon.addon_id);
}
}
}
// Install missing addons locally
for (const manifest of addonsToInstall) {
try {
await stremioService.installAddon(manifest.originalUrl || manifest.url);
logger.log('[Sync] Merged addon from server:', manifest.id);
} catch (e) {
logger.warn('[Sync] Failed to install merged addon:', manifest.id);
}
}
logger.log(`[Sync] mergeAddonsFromServer completed: ${addonsToInstall.length} addons merged`);
} catch (e) {
logger.error('[Sync] mergeAddonsFromServer failed:', e);
}
}
}
export const syncService = SyncService.getInstance();