mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-03 16:59:08 +00:00
Merge branch 'main' into saimuelbr/main
This commit is contained in:
commit
e6faa7c59f
30 changed files with 21611 additions and 20166 deletions
|
|
@ -768,7 +768,17 @@ const AndroidVideoPlayer: React.FC = () => {
|
||||||
onProgress={handleProgress}
|
onProgress={handleProgress}
|
||||||
onSeek={(data) => {
|
onSeek={(data) => {
|
||||||
playerState.isSeeking.current = false;
|
playerState.isSeeking.current = false;
|
||||||
if (data.currentTime) traktAutosync.handleProgressUpdate(data.currentTime, playerState.duration, true);
|
if (data.currentTime) {
|
||||||
|
if (id && type && playerState.duration > 0) {
|
||||||
|
void storageService.setWatchProgress(id, type, {
|
||||||
|
currentTime: data.currentTime,
|
||||||
|
duration: playerState.duration,
|
||||||
|
lastUpdated: Date.now(),
|
||||||
|
addonId: currentStreamProvider
|
||||||
|
}, episodeId);
|
||||||
|
}
|
||||||
|
traktAutosync.handleProgressUpdate(data.currentTime, playerState.duration, true);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
onEnd={() => {
|
onEnd={() => {
|
||||||
if (modals.showEpisodeStreamsModal) return;
|
if (modals.showEpisodeStreamsModal) return;
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ import { useTraktAutosync } from '../../hooks/useTraktAutosync';
|
||||||
import { useMetadata } from '../../hooks/useMetadata';
|
import { useMetadata } from '../../hooks/useMetadata';
|
||||||
import { usePlayerGestureControls } from '../../hooks/usePlayerGestureControls';
|
import { usePlayerGestureControls } from '../../hooks/usePlayerGestureControls';
|
||||||
import stremioService from '../../services/stremioService';
|
import stremioService from '../../services/stremioService';
|
||||||
|
import { storageService } from '../../services/storageService';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
|
|
@ -227,7 +228,15 @@ const KSPlayerCore: React.FC = () => {
|
||||||
currentTime,
|
currentTime,
|
||||||
duration,
|
duration,
|
||||||
isSeeking,
|
isSeeking,
|
||||||
isMounted
|
isMounted,
|
||||||
|
onSeekComplete: (timeInSeconds) => {
|
||||||
|
if (!id || !type || duration <= 0) return;
|
||||||
|
void storageService.setWatchProgress(id, type, {
|
||||||
|
currentTime: timeInSeconds,
|
||||||
|
duration,
|
||||||
|
lastUpdated: Date.now()
|
||||||
|
}, episodeId);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const watchProgress = useWatchProgress(
|
const watchProgress = useWatchProgress(
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ interface PlayerControlsConfig {
|
||||||
duration: number;
|
duration: number;
|
||||||
isSeeking: MutableRefObject<boolean>;
|
isSeeking: MutableRefObject<boolean>;
|
||||||
isMounted: MutableRefObject<boolean>;
|
isMounted: MutableRefObject<boolean>;
|
||||||
|
onSeekComplete?: (timeInSeconds: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const usePlayerControls = (config: PlayerControlsConfig) => {
|
export const usePlayerControls = (config: PlayerControlsConfig) => {
|
||||||
|
|
@ -27,7 +28,8 @@ export const usePlayerControls = (config: PlayerControlsConfig) => {
|
||||||
currentTime,
|
currentTime,
|
||||||
duration,
|
duration,
|
||||||
isSeeking,
|
isSeeking,
|
||||||
isMounted
|
isMounted,
|
||||||
|
onSeekComplete
|
||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
// iOS seeking helpers
|
// iOS seeking helpers
|
||||||
|
|
@ -54,6 +56,7 @@ export const usePlayerControls = (config: PlayerControlsConfig) => {
|
||||||
|
|
||||||
// Actually perform the seek
|
// Actually perform the seek
|
||||||
playerRef.current.seek(timeInSeconds);
|
playerRef.current.seek(timeInSeconds);
|
||||||
|
onSeekComplete?.(timeInSeconds);
|
||||||
|
|
||||||
// Debounce the seeking state reset
|
// Debounce the seeking state reset
|
||||||
seekTimeoutRef.current = setTimeout(() => {
|
seekTimeoutRef.current = setTimeout(() => {
|
||||||
|
|
@ -62,7 +65,7 @@ export const usePlayerControls = (config: PlayerControlsConfig) => {
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}, [duration, paused, playerRef, isSeeking, isMounted]);
|
}, [duration, paused, playerRef, isSeeking, isMounted, onSeekComplete]);
|
||||||
|
|
||||||
const skip = useCallback((seconds: number) => {
|
const skip = useCallback((seconds: number) => {
|
||||||
seekToTime(currentTime + seconds);
|
seekToTime(currentTime + seconds);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useState, useEffect, useRef } from 'react';
|
import { useState, useEffect, useRef } from 'react';
|
||||||
import { AppState, AppStateStatus } from 'react-native';
|
import { AppState } from 'react-native';
|
||||||
import { storageService } from '../../../services/storageService';
|
import { storageService } from '../../../services/storageService';
|
||||||
import { logger } from '../../../utils/logger';
|
import { logger } from '../../../utils/logger';
|
||||||
import { useSettings } from '../../../hooks/useSettings';
|
import { useSettings } from '../../../hooks/useSettings';
|
||||||
|
|
@ -19,10 +19,9 @@ export const useWatchProgress = (
|
||||||
const [savedDuration, setSavedDuration] = useState<number | null>(null);
|
const [savedDuration, setSavedDuration] = useState<number | null>(null);
|
||||||
const [initialPosition, setInitialPosition] = useState<number | null>(null);
|
const [initialPosition, setInitialPosition] = useState<number | null>(null);
|
||||||
const [showResumeOverlay, setShowResumeOverlay] = useState(false);
|
const [showResumeOverlay, setShowResumeOverlay] = useState(false);
|
||||||
const [progressSaveInterval, setProgressSaveInterval] = useState<NodeJS.Timeout | null>(null);
|
|
||||||
|
|
||||||
const { settings: appSettings } = useSettings();
|
const { settings: appSettings } = useSettings();
|
||||||
const initialSeekTargetRef = useRef<number | null>(null);
|
const initialSeekTargetRef = useRef<number | null>(null);
|
||||||
|
const wasPausedRef = useRef<boolean>(paused);
|
||||||
|
|
||||||
// Values refs for unmount cleanup
|
// Values refs for unmount cleanup
|
||||||
const currentTimeRef = useRef(currentTime);
|
const currentTimeRef = useRef(currentTime);
|
||||||
|
|
@ -126,22 +125,16 @@ export const useWatchProgress = (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Save Interval
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (id && type && !paused && duration > 0) {
|
if (wasPausedRef.current !== paused) {
|
||||||
if (progressSaveInterval) clearInterval(progressSaveInterval);
|
const becamePaused = paused;
|
||||||
|
wasPausedRef.current = paused;
|
||||||
const interval = setInterval(() => {
|
if (becamePaused) {
|
||||||
saveWatchProgress();
|
void saveWatchProgress();
|
||||||
}, 10000);
|
}
|
||||||
|
|
||||||
setProgressSaveInterval(interval);
|
|
||||||
return () => {
|
|
||||||
clearInterval(interval);
|
|
||||||
setProgressSaveInterval(null);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}, [id, type, paused, currentTime, duration]);
|
}, [paused]);
|
||||||
|
|
||||||
// Unmount Save - deferred to allow navigation to complete first
|
// Unmount Save - deferred to allow navigation to complete first
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "سيؤدي هذا إلى إعادة تعيين كل الإعدادات ومسح كل البيانات المخزنة مؤقتاً. هل أنت متأكد؟",
|
"clear_data_desc": "سيؤدي هذا إلى إعادة تعيين كل الإعدادات ومسح كل البيانات المخزنة مؤقتاً. هل أنت متأكد؟",
|
||||||
"app_updates": "تحديثات التطبيق",
|
"app_updates": "تحديثات التطبيق",
|
||||||
"about_nuvio": "حول Nuvio"
|
"about_nuvio": "حول Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "الخصوصية والبيانات",
|
"title": "الخصوصية والبيانات",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Това ще нулира всички настройки и ще изчисти всички кеширани данни. Сигурни ли сте?",
|
"clear_data_desc": "Това ще нулира всички настройки и ще изчисти всички кеширани данни. Сигурни ли сте?",
|
||||||
"app_updates": "Обновявания на приложението",
|
"app_updates": "Обновявания на приложението",
|
||||||
"about_nuvio": "Относно Nuvio"
|
"about_nuvio": "Относно Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Поверителност и данни",
|
"title": "Поверителност и данни",
|
||||||
|
|
|
||||||
|
|
@ -765,7 +765,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Això restablirà tota la configuració i esborrarà totes les dades en memòria cau. Estàs segur?",
|
"clear_data_desc": "Això restablirà tota la configuració i esborrarà totes les dades en memòria cau. Estàs segur?",
|
||||||
"app_updates": "Actualitzacions de l'aplicació",
|
"app_updates": "Actualitzacions de l'aplicació",
|
||||||
"about_nuvio": "Quant a Nuvio"
|
"about_nuvio": "Quant a Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privadesa i dades",
|
"title": "Privadesa i dades",
|
||||||
|
|
|
||||||
|
|
@ -754,7 +754,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Tímto dojde k resetování všech nastavení a vymazání všech dat v mezipaměti. Jste si jisti?",
|
"clear_data_desc": "Tímto dojde k resetování všech nastavení a vymazání všech dat v mezipaměti. Jste si jisti?",
|
||||||
"app_updates": "Aktualizace aplikace",
|
"app_updates": "Aktualizace aplikace",
|
||||||
"about_nuvio": "O aplikaci Nuvio"
|
"about_nuvio": "O aplikaci Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Soukromí a data",
|
"title": "Soukromí a data",
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Dies setzt alle Einstellungen zurück und löscht alle zwischengespeicherten Daten. Sind Sie sicher?",
|
"clear_data_desc": "Dies setzt alle Einstellungen zurück und löscht alle zwischengespeicherten Daten. Sind Sie sicher?",
|
||||||
"app_updates": "App-Updates",
|
"app_updates": "App-Updates",
|
||||||
"about_nuvio": "Über Nuvio"
|
"about_nuvio": "Über Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Datenschutz & Daten",
|
"title": "Datenschutz & Daten",
|
||||||
|
|
|
||||||
|
|
@ -765,65 +765,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "This will reset all settings and clear all cached data. Are you sure?",
|
"clear_data_desc": "This will reset all settings and clear all cached data. Are you sure?",
|
||||||
"app_updates": "App Updates",
|
"app_updates": "App Updates",
|
||||||
"about_nuvio": "About Nuvio"
|
"about_nuvio": "About Nuvio",
|
||||||
},
|
"cloud_sync": {
|
||||||
"cloud_sync": {
|
"title": "Nuvio Sync",
|
||||||
"title": "Nuvio Sync",
|
"description": "Sync data across your Nuvio devices",
|
||||||
"description": "Sync data across your Nuvio devices",
|
"hero_title": "Cloud Sync",
|
||||||
"hero_title": "Cloud Sync",
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
"auth": {
|
||||||
"auth": {
|
"account": "Account",
|
||||||
"account": "Account",
|
"not_configured": "Supabase not configured",
|
||||||
"not_configured": "Supabase not configured",
|
"not_authenticated": "Not authenticated",
|
||||||
"not_authenticated": "Not authenticated",
|
"email_session": "Email session",
|
||||||
"email_session": "Email session",
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
"signed_in_as": "Signed in as {{email}}",
|
"not_signed_in": "Not signed in",
|
||||||
"not_signed_in": "Not signed in",
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
"effective_owner": "Effective owner: {{id}}"
|
},
|
||||||
},
|
"stats": {
|
||||||
"stats": {
|
"title": "Database Statistics",
|
||||||
"title": "Database Statistics",
|
"plugins": "Plugins",
|
||||||
"plugins": "Plugins",
|
"addons": "Addons",
|
||||||
"addons": "Addons",
|
"watch_progress": "Watch Progress",
|
||||||
"watch_progress": "Watch Progress",
|
"library_items": "Library Items",
|
||||||
"library_items": "Library Items",
|
"watched_items": "Watched Items",
|
||||||
"watched_items": "Watched Items",
|
"signin_required": "Sign in to load remote data counts."
|
||||||
"signin_required": "Sign in to load remote data counts."
|
},
|
||||||
},
|
"actions": {
|
||||||
"actions": {
|
"title": "Actions",
|
||||||
"title": "Actions",
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
"pull_btn": "Pull from Cloud",
|
||||||
"pull_btn": "Pull from Cloud",
|
"push_btn": "Push from Device",
|
||||||
"push_btn": "Push from Device",
|
"manage_account": "Manage Account",
|
||||||
"manage_account": "Manage Account",
|
"sign_out": "Sign Out",
|
||||||
"sign_out": "Sign Out",
|
"sign_in_up": "Sign In / Up"
|
||||||
"sign_in_up": "Sign In / Up"
|
},
|
||||||
},
|
"alerts": {
|
||||||
"alerts": {
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
"pull_success_title": "Cloud Data Pulled",
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
"pull_failed_title": "Pull Failed",
|
||||||
"pull_failed_title": "Pull Failed",
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
"pull_failed_msg": "Failed to download data from the cloud",
|
"push_success_title": "Push Completed",
|
||||||
"push_success_title": "Push Completed",
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
"push_success_msg": "Device data has been uploaded to the cloud.",
|
"push_failed_title": "Push Failed",
|
||||||
"push_failed_title": "Push Failed",
|
"push_failed_msg": "Failed to upload local data",
|
||||||
"push_failed_msg": "Failed to upload local data",
|
"sign_out_failed": "Sign Out Failed",
|
||||||
"sign_out_failed": "Sign Out Failed",
|
"sign_out_failed_title": "Logout Error"
|
||||||
"sign_out_failed_title": "Logout Error"
|
},
|
||||||
},
|
"external_sync": {
|
||||||
"external_sync": {
|
"title": "External Sync Priority",
|
||||||
"title": "External Sync Priority",
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
},
|
||||||
},
|
"pre_auth": {
|
||||||
"pre_auth": {
|
"title": "Before Syncing",
|
||||||
"title": "Before Syncing",
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
"point_1": "• Addons and plugins settings",
|
||||||
"point_1": "• Addons and plugins settings",
|
"point_2": "• Watch progress and library",
|
||||||
"point_2": "• Watch progress and library",
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
},
|
||||||
},
|
"connection": "Connection"
|
||||||
"connection": "Connection"
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privacy & Data",
|
"title": "Privacy & Data",
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Esto restablecerá todos los ajustes y borrará todos los datos almacenados en caché. ¿Estás seguro?",
|
"clear_data_desc": "Esto restablecerá todos los ajustes y borrará todos los datos almacenados en caché. ¿Estás seguro?",
|
||||||
"app_updates": "Actualizaciones de la app",
|
"app_updates": "Actualizaciones de la app",
|
||||||
"about_nuvio": "Acerca de Nuvio"
|
"about_nuvio": "Acerca de Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privacidad y Datos",
|
"title": "Privacidad y Datos",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "I-re-reset nito ang lahat ng settings at buburahin ang lahat ng cached data. Sigurado ka ba?",
|
"clear_data_desc": "I-re-reset nito ang lahat ng settings at buburahin ang lahat ng cached data. Sigurado ka ba?",
|
||||||
"app_updates": "Mga Update ng App",
|
"app_updates": "Mga Update ng App",
|
||||||
"about_nuvio": "Tungkol sa Nuvio"
|
"about_nuvio": "Tungkol sa Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privacy at Data",
|
"title": "Privacy at Data",
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Cela réinitialisera tous les paramètres et effacera toutes les données en cache. Êtes-vous sûr ?",
|
"clear_data_desc": "Cela réinitialisera tous les paramètres et effacera toutes les données en cache. Êtes-vous sûr ?",
|
||||||
"app_updates": "Mises à jour de l'application",
|
"app_updates": "Mises à jour de l'application",
|
||||||
"about_nuvio": "À propos de Nuvio"
|
"about_nuvio": "À propos de Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Confidentialité et Données",
|
"title": "Confidentialité et Données",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "פעולה זו תאפס את כל ההגדרות ותנקה את כל המידע השמור. האם אתם בטוחים?",
|
"clear_data_desc": "פעולה זו תאפס את כל ההגדרות ותנקה את כל המידע השמור. האם אתם בטוחים?",
|
||||||
"app_updates": "עדכוני אפליקציה",
|
"app_updates": "עדכוני אפליקציה",
|
||||||
"about_nuvio": "אודות Nuvio"
|
"about_nuvio": "אודות Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "פרטיות ומידע",
|
"title": "פרטיות ומידע",
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "यह सभी सेटिंग्स को रीसेट कर देगा और सभी कैश किए गए डेटा को साफ़ कर देगा। क्या आप सुनिश्चित हैं?",
|
"clear_data_desc": "यह सभी सेटिंग्स को रीसेट कर देगा और सभी कैश किए गए डेटा को साफ़ कर देगा। क्या आप सुनिश्चित हैं?",
|
||||||
"app_updates": "ऐप अपडेट",
|
"app_updates": "ऐप अपडेट",
|
||||||
"about_nuvio": "Nuvio के बारे में"
|
"about_nuvio": "Nuvio के बारे में",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "गोपनीयता और डेटा",
|
"title": "गोपनीयता और डेटा",
|
||||||
|
|
|
||||||
|
|
@ -747,7 +747,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Ovo će resetirati sve postavke i obrisati sve privremene podatke. Jeste li sigurni?",
|
"clear_data_desc": "Ovo će resetirati sve postavke i obrisati sve privremene podatke. Jeste li sigurni?",
|
||||||
"app_updates": "Ažuriranja aplikacije",
|
"app_updates": "Ažuriranja aplikacije",
|
||||||
"about_nuvio": "O Nuviju"
|
"about_nuvio": "O Nuviju",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privatnost i Podaci",
|
"title": "Privatnost i Podaci",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Dit zal alle instellingen resetten en alle gecachte gegevens wissen. Weet je het zeker?",
|
"clear_data_desc": "Dit zal alle instellingen resetten en alle gecachte gegevens wissen. Weet je het zeker?",
|
||||||
"app_updates": "App Updates",
|
"app_updates": "App Updates",
|
||||||
"about_nuvio": "Over Nuvio"
|
"about_nuvio": "Over Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privacy & Gegevens",
|
"title": "Privacy & Gegevens",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "To zresetuje wszystkie ustawienia i wyczyści pamięć podręczną. Czy na pewno?",
|
"clear_data_desc": "To zresetuje wszystkie ustawienia i wyczyści pamięć podręczną. Czy na pewno?",
|
||||||
"app_updates": "Aktualizacje aplikacji",
|
"app_updates": "Aktualizacje aplikacji",
|
||||||
"about_nuvio": "O Nuvio"
|
"about_nuvio": "O Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Prywatność i Dane",
|
"title": "Prywatność i Dane",
|
||||||
|
|
|
||||||
|
|
@ -773,65 +773,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Isso redefinirá todas as configurações e limpará todos os dados em cache. Você tem certeza?",
|
"clear_data_desc": "Isso redefinirá todas as configurações e limpará todos os dados em cache. Você tem certeza?",
|
||||||
"app_updates": "Atualizações do App",
|
"app_updates": "Atualizações do App",
|
||||||
"about_nuvio": "Sobre o Nuvio"
|
"about_nuvio": "Sobre o Nuvio",
|
||||||
},
|
"cloud_sync": {
|
||||||
"cloud_sync": {
|
"title": "Nuvio Sync",
|
||||||
"title": "Nuvio Sync",
|
"description": "Sincronize dados entre seus dispositivos Nuvio",
|
||||||
"description": "Sincronize dados entre seus dispositivos Nuvio",
|
"hero_title": "Sincronização na Nuvem",
|
||||||
"hero_title": "Sincronização na Nuvem",
|
"hero_subtitle": "Mantenha seus addons, progresso e biblioteca alinhados em todos os dispositivos.",
|
||||||
"hero_subtitle": "Mantenha seus addons, progresso e biblioteca alinhados em todos os dispositivos.",
|
"auth": {
|
||||||
"auth": {
|
"account": "Conta",
|
||||||
"account": "Conta",
|
"not_configured": "Supabase não configurado",
|
||||||
"not_configured": "Supabase não configurado",
|
"not_authenticated": "Não autenticado",
|
||||||
"not_authenticated": "Não autenticado",
|
"email_session": "Sessão de email",
|
||||||
"email_session": "Sessão de email",
|
"signed_in_as": "Logado como {{email}}",
|
||||||
"signed_in_as": "Logado como {{email}}",
|
"not_signed_in": "Não logado",
|
||||||
"not_signed_in": "Não logado",
|
"effective_owner": "Proprietário efetivo: {{id}}"
|
||||||
"effective_owner": "Proprietário efetivo: {{id}}"
|
},
|
||||||
},
|
"stats": {
|
||||||
"stats": {
|
"title": "Estatísticas do Banco de Dados",
|
||||||
"title": "Estatísticas do Banco de Dados",
|
"plugins": "Plugins",
|
||||||
"plugins": "Plugins",
|
"addons": "Addons",
|
||||||
"addons": "Addons",
|
"watch_progress": "Progresso",
|
||||||
"watch_progress": "Progresso",
|
"library_items": "Itens na Biblioteca",
|
||||||
"library_items": "Itens na Biblioteca",
|
"watched_items": "Itens Assistidos",
|
||||||
"watched_items": "Itens Assistidos",
|
"signin_required": "Faça login para carregar contagens de dados remotos."
|
||||||
"signin_required": "Faça login para carregar contagens de dados remotos."
|
},
|
||||||
},
|
"actions": {
|
||||||
"actions": {
|
"title": "Ações",
|
||||||
"title": "Ações",
|
"description": "Baixe para atualizar este dispositivo a partir da nuvem, ou envie deste dispositivo como a fonte mais recente.",
|
||||||
"description": "Baixe para atualizar este dispositivo a partir da nuvem, ou envie deste dispositivo como a fonte mais recente.",
|
"pull_btn": "Baixar da Nuvem",
|
||||||
"pull_btn": "Baixar da Nuvem",
|
"push_btn": "Enviar deste Dispositivo",
|
||||||
"push_btn": "Enviar deste Dispositivo",
|
"manage_account": "Gerenciar Conta",
|
||||||
"manage_account": "Gerenciar Conta",
|
"sign_out": "Sair",
|
||||||
"sign_out": "Sair",
|
"sign_in_up": "Entrar / Cadastrar"
|
||||||
"sign_in_up": "Entrar / Cadastrar"
|
},
|
||||||
},
|
"alerts": {
|
||||||
"alerts": {
|
"pull_success_title": "Dados da Nuvem Baixados",
|
||||||
"pull_success_title": "Dados da Nuvem Baixados",
|
"pull_success_msg": "Os dados mais recentes da nuvem foram baixados para este dispositivo.",
|
||||||
"pull_success_msg": "Os dados mais recentes da nuvem foram baixados para este dispositivo.",
|
"pull_failed_title": "Falha ao Baixar",
|
||||||
"pull_failed_title": "Falha ao Baixar",
|
"pull_failed_msg": "Falha ao baixar dados da nuvem",
|
||||||
"pull_failed_msg": "Falha ao baixar dados da nuvem",
|
"push_success_title": "Envio Concluído",
|
||||||
"push_success_title": "Envio Concluído",
|
"push_success_msg": "Os dados deste dispositivo foram enviados para a nuvem.",
|
||||||
"push_success_msg": "Os dados deste dispositivo foram enviados para a nuvem.",
|
"push_failed_title": "Falha ao Enviar",
|
||||||
"push_failed_title": "Falha ao Enviar",
|
"push_failed_msg": "Falha ao enviar dados locais",
|
||||||
"push_failed_msg": "Falha ao enviar dados locais",
|
"sign_out_failed": "Falha ao Sair",
|
||||||
"sign_out_failed": "Falha ao Sair",
|
"sign_out_failed_title": "Erro de Saida"
|
||||||
"sign_out_failed_title": "Erro de Saida"
|
},
|
||||||
},
|
"external_sync": {
|
||||||
"external_sync": {
|
"title": "Prioridade de Sincronização Externa",
|
||||||
"title": "Prioridade de Sincronização Externa",
|
"active_msg": "{{services}} está ativo. O progresso e atualizações da biblioteca são gerenciados por esses serviços em vez do banco de dados Nuvio.",
|
||||||
"active_msg": "{{services}} está ativo. O progresso e atualizações da biblioteca são gerenciados por esses serviços em vez do banco de dados Nuvio.",
|
"inactive_msg": "Se a sincronização do Trakt ou Simkl estiver ativada, o progresso e a biblioteca usarão esses serviços em vez do banco de dados Nuvio."
|
||||||
"inactive_msg": "Se a sincronização do Trakt ou Simkl estiver ativada, o progresso e a biblioteca usarão esses serviços em vez do banco de dados Nuvio."
|
},
|
||||||
},
|
"pre_auth": {
|
||||||
"pre_auth": {
|
"title": "Antes de Sincronizar",
|
||||||
"title": "Antes de Sincronizar",
|
"description": "Faça login para iniciar a sincronização na nuvem e manter seus dados consistentes entre dispositivos.",
|
||||||
"description": "Faça login para iniciar a sincronização na nuvem e manter seus dados consistentes entre dispositivos.",
|
"point_1": "• Configurações de addons e plugins",
|
||||||
"point_1": "• Configurações de addons e plugins",
|
"point_2": "• Progresso de exibição e biblioteca",
|
||||||
"point_2": "• Progresso de exibição e biblioteca",
|
"env_warning": "Defina EXPO_PUBLIC_SUPABASE_URL e EXPO_PUBLIC_SUPABASE_ANON_KEY para habilitar a sincronização."
|
||||||
"env_warning": "Defina EXPO_PUBLIC_SUPABASE_URL e EXPO_PUBLIC_SUPABASE_ANON_KEY para habilitar a sincronização."
|
},
|
||||||
},
|
"connection": "Conexão"
|
||||||
"connection": "Conexão"
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privacidade e Dados",
|
"title": "Privacidade e Dados",
|
||||||
|
|
|
||||||
|
|
@ -771,7 +771,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Isso redefinirá todas as configurações e limpará todos os dados em cache. Tens a certeza?",
|
"clear_data_desc": "Isso redefinirá todas as configurações e limpará todos os dados em cache. Tens a certeza?",
|
||||||
"app_updates": "Atualizações da App",
|
"app_updates": "Atualizações da App",
|
||||||
"about_nuvio": "Sobre o Nuvio"
|
"about_nuvio": "Sobre o Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privacidade e Dados",
|
"title": "Privacidade e Dados",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Această acțiune va reseta toate setările și va șterge toate datele cache. Ești sigur?",
|
"clear_data_desc": "Această acțiune va reseta toate setările și va șterge toate datele cache. Ești sigur?",
|
||||||
"app_updates": "Actualizări aplicație",
|
"app_updates": "Actualizări aplicație",
|
||||||
"about_nuvio": "Despre Nuvio"
|
"about_nuvio": "Despre Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Confidențialitate și Date",
|
"title": "Confidențialitate și Date",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Это сбросит все настройки и очистит кэш. Вы уверены?",
|
"clear_data_desc": "Это сбросит все настройки и очистит кэш. Вы уверены?",
|
||||||
"app_updates": "Обновления приложения",
|
"app_updates": "Обновления приложения",
|
||||||
"about_nuvio": "О Nuvio"
|
"about_nuvio": "О Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Конфиденциальность",
|
"title": "Конфиденциальность",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "To bo ponastavilo vse nastavitve in počistilo predpomnilnik. Ste prepričani?",
|
"clear_data_desc": "To bo ponastavilo vse nastavitve in počistilo predpomnilnik. Ste prepričani?",
|
||||||
"app_updates": "Posodobitve aplikacije",
|
"app_updates": "Posodobitve aplikacije",
|
||||||
"about_nuvio": "O Nuvio"
|
"about_nuvio": "O Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Zasebnost in podatki",
|
"title": "Zasebnost in podatki",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Kjo do të rikthejë të gjitha cilësimet dhe do të fshijë të gjithë cache-in. Jeni të sigurt?",
|
"clear_data_desc": "Kjo do të rikthejë të gjitha cilësimet dhe do të fshijë të gjithë cache-in. Jeni të sigurt?",
|
||||||
"app_updates": "Përditësimet e Aplikacionit",
|
"app_updates": "Përditësimet e Aplikacionit",
|
||||||
"about_nuvio": "Rreth Nuvio"
|
"about_nuvio": "Rreth Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Privatësia & Të dhënat",
|
"title": "Privatësia & Të dhënat",
|
||||||
|
|
|
||||||
|
|
@ -1,426 +1,426 @@
|
||||||
{
|
{
|
||||||
"common": {
|
"common": {
|
||||||
"loading": "Учитавање...",
|
"loading": "Учитавање...",
|
||||||
"cancel": "Одустани",
|
"cancel": "Одустани",
|
||||||
"save": "Сачувај",
|
"save": "Сачувај",
|
||||||
"delete": "Обриши",
|
"delete": "Обриши",
|
||||||
"edit": "Уреди",
|
"edit": "Уреди",
|
||||||
"search": "Претражи",
|
"search": "Претражи",
|
||||||
"error": "Грешка",
|
"error": "Грешка",
|
||||||
"success": "Успех",
|
"success": "Успех",
|
||||||
"ok": "У реду",
|
"ok": "У реду",
|
||||||
"unknown": "Непознато",
|
"unknown": "Непознато",
|
||||||
"retry": "Покушај поново",
|
"retry": "Покушај поново",
|
||||||
"try_again": "Покушај поново",
|
"try_again": "Покушај поново",
|
||||||
"go_back": "Иди назад",
|
"go_back": "Иди назад",
|
||||||
"settings": "Подешавања",
|
"settings": "Подешавања",
|
||||||
"close": "Затвори",
|
"close": "Затвори",
|
||||||
"enable": "Омогући",
|
"enable": "Омогући",
|
||||||
"disable": "Искључи",
|
"disable": "Искључи",
|
||||||
"show_more": "Прикажи више",
|
"show_more": "Прикажи више",
|
||||||
"show_less": "Прикажи мање",
|
"show_less": "Прикажи мање",
|
||||||
"load_more": "Учитај више",
|
"load_more": "Учитај више",
|
||||||
"unknown_date": "Непознат датум",
|
"unknown_date": "Непознат датум",
|
||||||
"anonymous_user": "Анонимни корисник",
|
"anonymous_user": "Анонимни корисник",
|
||||||
"time": {
|
"time": {
|
||||||
"now": "Управо сада",
|
"now": "Управо сада",
|
||||||
"minutes_ago": "пре {{count}} мин",
|
"minutes_ago": "пре {{count}} мин",
|
||||||
"hours_ago": "пре {{count}} ч",
|
"hours_ago": "пре {{count}} ч",
|
||||||
"days_ago": "пре {{count}} д"
|
"days_ago": "пре {{count}} д"
|
||||||
|
},
|
||||||
|
"days_short": {
|
||||||
|
"sun": "Нед",
|
||||||
|
"mon": "Пон",
|
||||||
|
"tue": "Уто",
|
||||||
|
"wed": "Сре",
|
||||||
|
"thu": "Чет",
|
||||||
|
"fri": "Пет",
|
||||||
|
"sat": "Суб"
|
||||||
|
},
|
||||||
|
"email": "Е-пошта",
|
||||||
|
"status": "Статус"
|
||||||
},
|
},
|
||||||
"days_short": {
|
"home": {
|
||||||
"sun": "Нед",
|
"categories": {
|
||||||
"mon": "Пон",
|
"movies": "Филмови",
|
||||||
"tue": "Уто",
|
"series": "Серије",
|
||||||
"wed": "Сре",
|
"channels": "Канали"
|
||||||
"thu": "Чет",
|
},
|
||||||
"fri": "Пет",
|
"movies": "Филмови",
|
||||||
"sat": "Суб"
|
"tv_shows": "Cерије",
|
||||||
|
"load_more_catalogs": "Учитај више каталога",
|
||||||
|
"no_content": "Садржај није доступан",
|
||||||
|
"add_catalogs": "Додај каталоге",
|
||||||
|
"sign_in_available": "Пријава доступна",
|
||||||
|
"sign_in_desc": "Можете се пријавити било када у Подешавања → Налог",
|
||||||
|
"view_all": "Види све",
|
||||||
|
"this_week": "Ове недеље",
|
||||||
|
"upcoming": "Надолазеће",
|
||||||
|
"recently_released": "Недавно објављено",
|
||||||
|
"no_scheduled_episodes": "Серије без заказаних епизода",
|
||||||
|
"check_back_later": "Проверите касније",
|
||||||
|
"continue_watching": "Настави са гледањем",
|
||||||
|
"up_next": "Следеће на реду",
|
||||||
|
"up_next_caps": "СЛЕДЕЋЕ",
|
||||||
|
"released": "Објављено",
|
||||||
|
"new": "Ново",
|
||||||
|
"tba": "Биће објављено",
|
||||||
|
"new_episodes": "{{count}} нове епизоде",
|
||||||
|
"season_short": "С{{season}}",
|
||||||
|
"episode_short": "Е{{episode}}",
|
||||||
|
"season": "Сезона {{season}}",
|
||||||
|
"episode": "Епизода {{episode}}",
|
||||||
|
"movie": "Филм",
|
||||||
|
"series": "Серија",
|
||||||
|
"tv_show": "Cерија",
|
||||||
|
"percent_watched": "{{percent}}% одгледано",
|
||||||
|
"view_details": "Види детаље",
|
||||||
|
"remove": "Уклони",
|
||||||
|
"play": "Пусти",
|
||||||
|
"play_now": "Пусти одмах",
|
||||||
|
"resume": "Настави",
|
||||||
|
"info": "Инфо",
|
||||||
|
"more_info": "Више информација",
|
||||||
|
"my_list": "Моја листа",
|
||||||
|
"save": "Сачувај",
|
||||||
|
"saved": "Сачувано",
|
||||||
|
"retry": "Покушај поново",
|
||||||
|
"install_addons": "Инсталирај додатке",
|
||||||
|
"settings": "Подешавања",
|
||||||
|
"no_featured_content": "Нема истакнутог садржаја",
|
||||||
|
"couldnt_load_featured": "Учитавање истакнутог садржаја није успело",
|
||||||
|
"no_featured_desc": "Инсталирајте додатке са каталозима или промените извор садржаја у подешавањима.",
|
||||||
|
"load_error_desc": "Дошло је до проблема при преузимању садржаја. Проверите везу и покушајте поново.",
|
||||||
|
"no_featured_available": "Нема доступног истакнутог садржаја",
|
||||||
|
"no_description": "Опис није доступан"
|
||||||
},
|
},
|
||||||
"email": "Е-пошта",
|
"navigation": {
|
||||||
"status": "Статус"
|
"home": "Почетна",
|
||||||
},
|
"library": "Библиотека",
|
||||||
"home": {
|
"search": "Претрага",
|
||||||
"categories": {
|
"downloads": "Преузимања",
|
||||||
"movies": "Филмови",
|
"settings": "Подешавања"
|
||||||
"series": "Серије",
|
|
||||||
"channels": "Канали"
|
|
||||||
},
|
},
|
||||||
"movies": "Филмови",
|
"search": {
|
||||||
"tv_shows": "Cерије",
|
"title": "Претрага",
|
||||||
"load_more_catalogs": "Учитај више каталога",
|
"recent_searches": "Недавне претраге",
|
||||||
"no_content": "Садржај није доступан",
|
"discover": "Откриј",
|
||||||
"add_catalogs": "Додај каталоге",
|
"movies": "Филмови",
|
||||||
"sign_in_available": "Пријава доступна",
|
"tv_shows": "Cерије",
|
||||||
"sign_in_desc": "Можете се пријавити било када у Подешавања → Налог",
|
"select_catalog": "Изабери каталог",
|
||||||
"view_all": "Види све",
|
"all_genres": "Сви жанрови",
|
||||||
"this_week": "Ове недеље",
|
"discovering": "Откривање садржаја...",
|
||||||
"upcoming": "Надолазеће",
|
"show_more": "Прикажи више ({{count}})",
|
||||||
"recently_released": "Недавно објављено",
|
"no_content_found": "Садржај није пронађен",
|
||||||
"no_scheduled_episodes": "Серије без заказаних епизода",
|
"try_different": "Покушајте други жанр или каталог",
|
||||||
"check_back_later": "Проверите касније",
|
"select_catalog_desc": "Изаберите каталог за истраживање",
|
||||||
"continue_watching": "Настави са гледањем",
|
"tap_catalog_desc": "Додирните дугме каталога изнад за почетак",
|
||||||
"up_next": "Следеће на реду",
|
"placeholder": "Претражи филмове, серије...",
|
||||||
"up_next_caps": "СЛЕДЕЋЕ",
|
"keep_typing": "Наставите са куцањем...",
|
||||||
"released": "Објављено",
|
"type_characters": "Упишите најмање 2 знака за претрагу",
|
||||||
"new": "Ново",
|
"no_results": "Нема резултата",
|
||||||
"tba": "Биће објављено",
|
"try_keywords": "Покушајте са другим кључним речима",
|
||||||
"new_episodes": "{{count}} нове епизоде",
|
"select_type": "Изабери тип",
|
||||||
"season_short": "С{{season}}",
|
"browse_movies": "Прегледај каталоге филмова",
|
||||||
"episode_short": "Е{{episode}}",
|
"browse_tv": "Прегледај каталоге cерија",
|
||||||
"season": "Сезона {{season}}",
|
"select_genre": "Изабери жанр",
|
||||||
"episode": "Епизода {{episode}}",
|
"show_all_content": "Прикажи сав садржај",
|
||||||
"movie": "Филм",
|
"genres_count": "{{count}} жанрова"
|
||||||
"series": "Серија",
|
},
|
||||||
"tv_show": "Cерија",
|
"library": {
|
||||||
"percent_watched": "{{percent}}% одгледано",
|
"title": "Библиотека",
|
||||||
"view_details": "Види детаље",
|
"watched": "Одгледано",
|
||||||
"remove": "Уклони",
|
"continue": "Настави",
|
||||||
"play": "Пусти",
|
"watchlist": "Листа за гледање",
|
||||||
"play_now": "Пусти одмах",
|
"collection": "Колекција",
|
||||||
"resume": "Настави",
|
"rated": "Оцењено",
|
||||||
"info": "Инфо",
|
"items": "ставки",
|
||||||
"more_info": "Више информација",
|
"trakt_collections": "Trakt колекције",
|
||||||
"my_list": "Моја листа",
|
"trakt_collection": "Trakt колекција",
|
||||||
"save": "Сачувај",
|
"no_trakt": "Нема Trakt колекција",
|
||||||
"saved": "Сачувано",
|
"no_trakt_desc": "Ваше Trakt колекције ће се појавити овде након коришћења Trakt-а",
|
||||||
"retry": "Покушај поново",
|
"load_collections": "Учитај колекције",
|
||||||
"install_addons": "Инсталирај додатке",
|
"empty_folder": "Нема садржаја у {{folder}}",
|
||||||
"settings": "Подешавања",
|
"empty_folder_desc": "Ова колекција је празна",
|
||||||
"no_featured_content": "Нема истакнутог садржаја",
|
"refresh": "Освежи",
|
||||||
"couldnt_load_featured": "Учитавање истакнутог садржаја није успело",
|
"no_movies": "Још нема филмова",
|
||||||
"no_featured_desc": "Инсталирајте додатке са каталозима или промените извор садржаја у подешавањима.",
|
"no_series": "Још нема cерија",
|
||||||
"load_error_desc": "Дошло је до проблема при преузимању садржаја. Проверите везу и покушајте поново.",
|
"no_content": "Још нема садржаја",
|
||||||
"no_featured_available": "Нема доступног истакнутог садржаја",
|
"add_content_desc": "Додајте садржај у своју библиотеку да бисте га видели овде",
|
||||||
"no_description": "Опис није доступан"
|
"find_something": "Пронађи нешто за гледање",
|
||||||
},
|
"removed_from_library": "Уклоњено из библиотеке",
|
||||||
"navigation": {
|
"item_removed": "Ставка је уклоњена из ваше библиотеке",
|
||||||
"home": "Почетна",
|
"failed_update_library": "Ажурирање библиотеке није успело",
|
||||||
"library": "Библиотека",
|
"unable_remove": "Неуспело уклањање ставке из библиотеке",
|
||||||
"search": "Претрага",
|
"marked_watched": "Означено као одгледано",
|
||||||
"downloads": "Преузимања",
|
"marked_unwatched": "Означено као неодгледано",
|
||||||
"settings": "Подешавања"
|
"item_marked_watched": "Ставка је означена као одгледана",
|
||||||
},
|
"item_marked_unwatched": "Ставка је означена као неодгледана",
|
||||||
"search": {
|
"failed_update_watched": "Ажурирање статуса гледања није успело",
|
||||||
"title": "Претрага",
|
"unable_update_watched": "Неуспело ажурирање статуса гледања",
|
||||||
"recent_searches": "Недавне претраге",
|
"added_to_library": "Додато у библиотеку",
|
||||||
"discover": "Откриј",
|
"item_added": "Додато у вашу локалну библиотеку",
|
||||||
"movies": "Филмови",
|
"add_to_library": "Додај у библиотеку",
|
||||||
"tv_shows": "Cерије",
|
"remove_from_library": "Уклони из библиотеке",
|
||||||
"select_catalog": "Изабери каталог",
|
"mark_watched": "Означи као одгледано",
|
||||||
"all_genres": "Сви жанрови",
|
"mark_unwatched": "Означи као неодгледано",
|
||||||
"discovering": "Откривање садржаја...",
|
"share": "Подели",
|
||||||
"show_more": "Прикажи више ({{count}})",
|
"add_to_watchlist": "Додај на Trakt листу гледања",
|
||||||
"no_content_found": "Садржај није пронађен",
|
"remove_from_watchlist": "Уклони са Trakt листе гледања",
|
||||||
"try_different": "Покушајте други жанр или каталог",
|
"added_to_watchlist": "Додато на листу гледања",
|
||||||
"select_catalog_desc": "Изаберите каталог за истраживање",
|
"added_to_watchlist_desc": "Додато на вашу Trakt листу гледања",
|
||||||
"tap_catalog_desc": "Додирните дугме каталога изнад за почетак",
|
"removed_from_watchlist": "Уклоњено са листе гледања",
|
||||||
"placeholder": "Претражи филмове, серије...",
|
"removed_from_watchlist_desc": "Уклоњено са ваше Trakt листе гледања",
|
||||||
"keep_typing": "Наставите са куцањем...",
|
"add_to_collection": "Додај у Trakt колекцију",
|
||||||
"type_characters": "Упишите најмање 2 знака за претрагу",
|
"remove_from_collection": "Уклони из Trakt колекције",
|
||||||
"no_results": "Нема резултата",
|
"added_to_collection": "Додато у колекцију",
|
||||||
"try_keywords": "Покушајте са другим кључним речима",
|
"added_to_collection_desc": "Додато у вашу Trakt колекцију",
|
||||||
"select_type": "Изабери тип",
|
"removed_from_collection": "Уклоњено из колекције",
|
||||||
"browse_movies": "Прегледај каталоге филмова",
|
"removed_from_collection_desc": "Уклоњено из ваше Trakt колекције"
|
||||||
"browse_tv": "Прегледај каталоге cерија",
|
},
|
||||||
"select_genre": "Изабери жанр",
|
"metadata": {
|
||||||
"show_all_content": "Прикажи сав садржај",
|
"unable_to_load": "Учитавање садржаја није успело",
|
||||||
"genres_count": "{{count}} жанрова"
|
"error_code": "Код грешке: {{code}}",
|
||||||
},
|
"content_not_found": "Садржај није пронађен",
|
||||||
"library": {
|
"content_not_found_desc": "Овај садржај не постоји или је можда уклоњен.",
|
||||||
"title": "Библиотека",
|
"server_error": "Грешка сервера",
|
||||||
"watched": "Одгледано",
|
"server_error_desc": "Сервер је привремено недоступан. Покушајте касније.",
|
||||||
"continue": "Настави",
|
"bad_gateway": "Лош gateway",
|
||||||
"watchlist": "Листа за гледање",
|
"bad_gateway_desc": "Сервер има потешкоћа. Покушајте касније.",
|
||||||
"collection": "Колекција",
|
"service_unavailable": "Услуга недоступна",
|
||||||
"rated": "Оцењено",
|
"service_unavailable_desc": "Услуга је тренутно недоступна због одржавања.",
|
||||||
"items": "ставки",
|
"too_many_requests": "Превише захтева",
|
||||||
"trakt_collections": "Trakt колекције",
|
"too_many_requests_desc": "Шаљете превише захтева. Молимо сачекајте тренутак.",
|
||||||
"trakt_collection": "Trakt колекција",
|
"request_timeout": "Истек захтева",
|
||||||
"no_trakt": "Нема Trakt колекција",
|
"request_timeout_desc": "Захтев је трајао предуго. Покушајте поново.",
|
||||||
"no_trakt_desc": "Ваше Trakt колекције ће се појавити овде након коришћења Trakt-а",
|
"network_error": "Мрежна грешка",
|
||||||
"load_collections": "Учитај колекције",
|
"network_error_desc": "Проверите интернет везу и покушајте поново.",
|
||||||
"empty_folder": "Нема садржаја у {{folder}}",
|
"auth_error": "Грешка у аутентификацији",
|
||||||
"empty_folder_desc": "Ова колекција је празна",
|
"auth_error_desc": "Проверите подешавања налога и покушајте поново.",
|
||||||
"refresh": "Освежи",
|
"access_denied": "Приступ одбијен",
|
||||||
"no_movies": "Још нема филмова",
|
"access_denied_desc": "Немате дозволу за приступ овом садржају.",
|
||||||
"no_series": "Још нема cерија",
|
"connection_error": "Грешка у вези",
|
||||||
"no_content": "Још нема садржаја",
|
"streams_unavailable": "Стримови недоступни",
|
||||||
"add_content_desc": "Додајте садржај у своју библиотеку да бисте га видели овде",
|
"streams_unavailable_desc": "Извори за стримовање су тренутно недоступни.",
|
||||||
"find_something": "Пронађи нешто за гледање",
|
"unknown_error": "Непозната грешка",
|
||||||
"removed_from_library": "Уклоњено из библиотеке",
|
"something_went_wrong": "Нешто је пошло по злу. Покушајте поново.",
|
||||||
"item_removed": "Ставка је уклоњена из ваше библиотеке",
|
"cast": "Глумачка постава",
|
||||||
"failed_update_library": "Ажурирање библиотеке није успело",
|
"more_like_this": "Слично овоме",
|
||||||
"unable_remove": "Неуспело уклањање ставке из библиотеке",
|
"collection": "Колекција",
|
||||||
"marked_watched": "Означено као одгледано",
|
"episodes": "Епизоде",
|
||||||
"marked_unwatched": "Означено као неодгледано",
|
"seasons": "Сезоне",
|
||||||
"item_marked_watched": "Ставка је означена као одгледана",
|
"posters": "Постери",
|
||||||
"item_marked_unwatched": "Ставка је означена као неодгледана",
|
"banners": "Банери",
|
||||||
"failed_update_watched": "Ажурирање статуса гледања није успело",
|
"specials": "Специјали",
|
||||||
"unable_update_watched": "Неуспело ажурирање статуса гледања",
|
"season_number": "Сезона {{number}}",
|
||||||
"added_to_library": "Додато у библиотеку",
|
"episode_count": "{{count}} епизода",
|
||||||
"item_added": "Додато у вашу локалну библиотеку",
|
"episode_count_plural": "{{count}} епизода",
|
||||||
"add_to_library": "Додај у библиотеку",
|
"no_episodes": "Нема доступних епизода",
|
||||||
"remove_from_library": "Уклони из библиотеке",
|
"no_episodes_for_season": "Нема доступних епизода за сезону {{season}}",
|
||||||
"mark_watched": "Означи као одгледано",
|
"episodes_not_released": "Епизоде можда још нису објављене",
|
||||||
"mark_unwatched": "Означи као неодгледано",
|
"no_description": "Опис није доступан",
|
||||||
"share": "Подели",
|
"episode_label": "ЕПИЗОДА {{number}}",
|
||||||
"add_to_watchlist": "Додај на Trakt листу гледања",
|
"watch_again": "Гледај поново",
|
||||||
"remove_from_watchlist": "Уклони са Trakt листе гледања",
|
"completed": "Завршено",
|
||||||
"added_to_watchlist": "Додато на листу гледања",
|
"play_episode": "Пусти С{{season}}Е{{episode}}",
|
||||||
"added_to_watchlist_desc": "Додато на вашу Trakt листу гледања",
|
"play": "Пусти",
|
||||||
"removed_from_watchlist": "Уклоњено са листе гледања",
|
"watched": "Одгледано",
|
||||||
"removed_from_watchlist_desc": "Уклоњено са ваше Trakt листе гледања",
|
"watched_on_trakt": "Одгледано на Trakt-у",
|
||||||
"add_to_collection": "Додај у Trakt колекцију",
|
"synced_with_trakt": "Синхронизовано са Trakt-ом",
|
||||||
"remove_from_collection": "Уклони из Trakt колекције",
|
"saved": "Сачувано",
|
||||||
"added_to_collection": "Додато у колекцију",
|
"director": "Режисер",
|
||||||
"added_to_collection_desc": "Додато у вашу Trakt колекцију",
|
"directors": "Режисери",
|
||||||
"removed_from_collection": "Уклоњено из колекције",
|
"creator": "Креатор",
|
||||||
"removed_from_collection_desc": "Уклоњено из ваше Trakt колекције"
|
"creators": "Креатори",
|
||||||
},
|
"production": "Продукција",
|
||||||
"metadata": {
|
"network": "Мрежа",
|
||||||
"unable_to_load": "Учитавање садржаја није успело",
|
"mark_watched": "Означи као одгледано",
|
||||||
"error_code": "Код грешке: {{code}}",
|
"mark_unwatched": "Означи као неодгледано",
|
||||||
"content_not_found": "Садржај није пронађен",
|
"marking": "Означавање...",
|
||||||
"content_not_found_desc": "Овај садржај не постоји или је можда уклоњен.",
|
"removing": "Уклањање...",
|
||||||
"server_error": "Грешка сервера",
|
"unmark_season": "Одозначи сезону {{season}}",
|
||||||
"server_error_desc": "Сервер је привремено недоступан. Покушајте касније.",
|
"mark_season": "Означи сезону {{season}}",
|
||||||
"bad_gateway": "Лош gateway",
|
"resume": "Настави",
|
||||||
"bad_gateway_desc": "Сервер има потешкоћа. Покушајте касније.",
|
"spoiler_warning": "Упозорење о спојлерима",
|
||||||
"service_unavailable": "Услуга недоступна",
|
"spoiler_warning_desc": "Овај коментар садржи спојлере. Да ли сте сигурни да желите да га откријете?",
|
||||||
"service_unavailable_desc": "Услуга је тренутно недоступна због одржавања.",
|
"cancel": "Одустани",
|
||||||
"too_many_requests": "Превише захтева",
|
"reveal_spoilers": "Откриј спојлере",
|
||||||
"too_many_requests_desc": "Шаљете превише захтева. Молимо сачекајте тренутак.",
|
"movie_details": "Детаљи о филму",
|
||||||
"request_timeout": "Истек захтева",
|
"show_details": "Детаљи о серији",
|
||||||
"request_timeout_desc": "Захтев је трајао предуго. Покушајте поново.",
|
"tagline": "Слоган",
|
||||||
"network_error": "Мрежна грешка",
|
"status": "Статус",
|
||||||
"network_error_desc": "Проверите интернет везу и покушајте поново.",
|
"release_date": "Датум објаве",
|
||||||
"auth_error": "Грешка у аутентификацији",
|
"runtime": "Трајање",
|
||||||
"auth_error_desc": "Проверите подешавања налога и покушајте поново.",
|
"budget": "Буџет",
|
||||||
"access_denied": "Приступ одбијен",
|
"revenue": "Приход",
|
||||||
"access_denied_desc": "Немате дозволу за приступ овом садржају.",
|
"origin_country": "Земља порекла",
|
||||||
"connection_error": "Грешка у вези",
|
"original_language": "Оригинални језик",
|
||||||
"streams_unavailable": "Стримови недоступни",
|
"first_air_date": "Прво емитовање",
|
||||||
"streams_unavailable_desc": "Извори за стримовање су тренутно недоступни.",
|
"last_air_date": "Последње емитовање",
|
||||||
"unknown_error": "Непозната грешка",
|
"total_episodes": "Укупно епизода",
|
||||||
"something_went_wrong": "Нешто је пошло по злу. Покушајте поново.",
|
"episode_runtime": "Трајање епизоде",
|
||||||
"cast": "Глумачка постава",
|
"created_by": "Креирао",
|
||||||
"more_like_this": "Слично овоме",
|
"backdrop_gallery": "Галерија позадина",
|
||||||
"collection": "Колекција",
|
"loading_episodes": "Учитавање епизода...",
|
||||||
"episodes": "Епизоде",
|
"no_episodes_available": "Нема доступних епизода",
|
||||||
"seasons": "Сезоне",
|
"play_next": "Пусти С{{season}}Е{{episode}}",
|
||||||
"posters": "Постери",
|
"play_next_episode": "Пусти следећу епизоду",
|
||||||
"banners": "Банери",
|
"save": "Сачувај",
|
||||||
"specials": "Специјали",
|
"percent_watched_trakt": "{{percent}}% одгледано ({{traktPercent}}% на Trakt-у)",
|
||||||
"season_number": "Сезона {{number}}",
|
"synced_with_trakt_progress": "Синхронизовано са Trakt-ом",
|
||||||
"episode_count": "{{count}} епизода",
|
"using_trakt_progress": "Користи се Trakt напредак",
|
||||||
"episode_count_plural": "{{count}} епизода",
|
"added_to_collection_hero": "Додато у колекцију",
|
||||||
"no_episodes": "Нема доступних епизода",
|
"added_to_collection_desc_hero": "Додато у вашу Trakt колекцију",
|
||||||
"no_episodes_for_season": "Нема доступних епизода за сезону {{season}}",
|
"removed_from_collection_hero": "Уклоњено из колекције",
|
||||||
"episodes_not_released": "Епизоде можда још нису објављене",
|
"removed_from_collection_desc_hero": "Уклоњено из ваше Trakt колекције",
|
||||||
"no_description": "Опис није доступан",
|
"mark_as_watched": "Означи као одгледано",
|
||||||
"episode_label": "ЕПИЗОДА {{number}}",
|
"mark_as_unwatched": "Означи као неодгледано"
|
||||||
"watch_again": "Гледај поново",
|
},
|
||||||
"completed": "Завршено",
|
"cast": {
|
||||||
"play_episode": "Пусти С{{season}}Е{{episode}}",
|
"biography": "Биографија",
|
||||||
"play": "Пусти",
|
"known_for": "Познат по",
|
||||||
"watched": "Одгледано",
|
"personal_info": "Лични подаци",
|
||||||
"watched_on_trakt": "Одгледано на Trakt-у",
|
"born_in": "Рођен у {{place}}",
|
||||||
"synced_with_trakt": "Синхронизовано са Trakt-ом",
|
"filmography": "Филмографија",
|
||||||
"saved": "Сачувано",
|
"also_known_as": "Познат и као",
|
||||||
"director": "Режисер",
|
"no_info_available": "Додатне информације нису доступне",
|
||||||
"directors": "Режисери",
|
"as_character": "као {{character}}",
|
||||||
"creator": "Креатор",
|
"loading_details": "Учитавање детаља...",
|
||||||
"creators": "Креатори",
|
"years_old": "{{age}} година",
|
||||||
"production": "Продукција",
|
"view_filmography": "Види филмографију",
|
||||||
"network": "Мрежа",
|
"filter": "Филтер",
|
||||||
"mark_watched": "Означи као одгледано",
|
"sort_by": "Сортирај по",
|
||||||
"mark_unwatched": "Означи као неодгледано",
|
"sort_popular": "Популарно",
|
||||||
"marking": "Означавање...",
|
"sort_latest": "Најновије",
|
||||||
"removing": "Уклањање...",
|
"sort_upcoming": "Надолазеће",
|
||||||
"unmark_season": "Одозначи сезону {{season}}",
|
"upcoming_badge": "НАДОЛАЗЕЋЕ",
|
||||||
"mark_season": "Означи сезону {{season}}",
|
"coming_soon": "Ускоро стиже",
|
||||||
"resume": "Настави",
|
"filmography_count": "Филмографија • {{count}} наслова",
|
||||||
"spoiler_warning": "Упозорење о спојлерима",
|
"loading_filmography": "Учитавање филмографије...",
|
||||||
"spoiler_warning_desc": "Овај коментар садржи спојлере. Да ли сте сигурни да желите да га откријете?",
|
"load_more_remaining": "Учитај још ({{count}} преостало)",
|
||||||
"cancel": "Одустани",
|
"alert_error_title": "Грешка",
|
||||||
"reveal_spoilers": "Откриј спојлере",
|
"alert_error_message": "Неуспело учитавање \"{{title}}\". Покушајте касније.",
|
||||||
"movie_details": "Детаљи о филму",
|
"alert_ok": "У реду",
|
||||||
"show_details": "Детаљи о серији",
|
"no_upcoming": "Нема надолазећих објава за овог глумца",
|
||||||
"tagline": "Слоган",
|
"no_content": "Нема доступног садржаја за овог глумца",
|
||||||
"status": "Статус",
|
"no_movies": "Нема доступних филмова за овог глумца",
|
||||||
"release_date": "Датум објаве",
|
"no_tv": "Нема доступних серија за овог глумца"
|
||||||
"runtime": "Трајање",
|
},
|
||||||
"budget": "Буџет",
|
"comments": {
|
||||||
"revenue": "Приход",
|
"title": "Trakt коментари",
|
||||||
"origin_country": "Земља порекла",
|
"spoiler_warning": "⚠️ Овај коментар садржи спојлере. Додирните да откријете.",
|
||||||
"original_language": "Оригинални језик",
|
"spoiler": "Спојлер",
|
||||||
"first_air_date": "Прво емитовање",
|
"contains_spoilers": "Садржи спојлере",
|
||||||
"last_air_date": "Последње емитовање",
|
"reveal": "Откриј",
|
||||||
"total_episodes": "Укупно епизода",
|
"vip": "VIP",
|
||||||
"episode_runtime": "Трајање епизоде",
|
"unavailable": "Коментари недоступни",
|
||||||
"created_by": "Креирао",
|
"no_comments": "Још нема коментара на Trakt-у",
|
||||||
"backdrop_gallery": "Галерија позадина",
|
"not_in_database": "Овај садржај можда још није у Trakt бази података",
|
||||||
"loading_episodes": "Учитавање епизода...",
|
"check_trakt": "Провери Trakt"
|
||||||
"no_episodes_available": "Нема доступних епизода",
|
},
|
||||||
"play_next": "Пусти С{{season}}Е{{episode}}",
|
"trailers": {
|
||||||
"play_next_episode": "Пусти следећу епизоду",
|
"title": "Трејлери",
|
||||||
"save": "Сачувај",
|
"official_trailers": "Званични трејлери",
|
||||||
"percent_watched_trakt": "{{percent}}% одгледано ({{traktPercent}}% на Trakt-у)",
|
"official_trailer": "Званични трејлер",
|
||||||
"synced_with_trakt_progress": "Синхронизовано са Trakt-ом",
|
"teasers": "Тизери",
|
||||||
"using_trakt_progress": "Користи се Trakt напредак",
|
"teaser": "Тизер",
|
||||||
"added_to_collection_hero": "Додато у колекцију",
|
"clips_scenes": "Клипови и сцене",
|
||||||
"added_to_collection_desc_hero": "Додато у вашу Trakt колекцију",
|
"clip": "Клип",
|
||||||
"removed_from_collection_hero": "Уклоњено из колекције",
|
"featurettes": "Кратки филмови о снимању",
|
||||||
"removed_from_collection_desc_hero": "Уклоњено из ваше Trakt колекције",
|
"featurette": "Кратки филм о снимању",
|
||||||
"mark_as_watched": "Означи као одгледано",
|
"behind_the_scenes": "Иза кулиса",
|
||||||
"mark_as_unwatched": "Означи као неодгледано"
|
"no_trailers": "Нема доступних трејлера",
|
||||||
},
|
"unavailable": "Трејлер недоступан",
|
||||||
"cast": {
|
"unavailable_desc": "Овај трејлер није могуће учитати тренутно.",
|
||||||
"biography": "Биографија",
|
"unable_to_play": "Није могуће пустити трејлер. Покушајте поново.",
|
||||||
"known_for": "Познат по",
|
"watch_on_youtube": "Гледај на YouTube-у"
|
||||||
"personal_info": "Лични подаци",
|
},
|
||||||
"born_in": "Рођен у {{place}}",
|
"catalog": {
|
||||||
"filmography": "Филмографија",
|
"no_content_found": "Садржај није пронађен",
|
||||||
"also_known_as": "Познат и као",
|
"no_content_filters": "Нема садржаја за изабране филтере",
|
||||||
"no_info_available": "Додатне информације нису доступне",
|
"loading_content": "Учитавање садржаја...",
|
||||||
"as_character": "као {{character}}",
|
"back": "Назад",
|
||||||
"loading_details": "Учитавање детаља...",
|
"in_theaters": "У биоскопима",
|
||||||
"years_old": "{{age}} година",
|
"all": "Све",
|
||||||
"view_filmography": "Види филмографију",
|
"failed_tmdb": "Неуспело учитавање садржаја са TMDB",
|
||||||
"filter": "Филтер",
|
"movies": "Филмови",
|
||||||
"sort_by": "Сортирај по",
|
"tv_shows": "Cерије",
|
||||||
"sort_popular": "Популарно",
|
"channels": "Канали"
|
||||||
"sort_latest": "Најновије",
|
},
|
||||||
"sort_upcoming": "Надолазеће",
|
"streams": {
|
||||||
"upcoming_badge": "НАДОЛАЗЕЋЕ",
|
"back_to_episodes": "Назад на епизоде",
|
||||||
"coming_soon": "Ускоро стиже",
|
"back_to_info": "Назад на инфо",
|
||||||
"filmography_count": "Филмографија • {{count}} наслова",
|
"fetching_from": "Преузимање са:",
|
||||||
"loading_filmography": "Учитавање филмографије...",
|
"no_sources_available": "Нема доступних извора за стримовање",
|
||||||
"load_more_remaining": "Учитај још ({{count}} преостало)",
|
"add_sources_desc": "Молимо додајте изворе у подешавањима",
|
||||||
"alert_error_title": "Грешка",
|
"add_sources": "Додај изворе",
|
||||||
"alert_error_message": "Неуспело учитавање \"{{title}}\". Покушајте касније.",
|
"finding_streams": "Проналажење доступних стримова...",
|
||||||
"alert_ok": "У реду",
|
"finding_best_stream": "Проналажење најбољег стрима за аутоматско пуштање...",
|
||||||
"no_upcoming": "Нема надолазећих објава за овог глумца",
|
"still_fetching": "Преузимање стримова је још у току...",
|
||||||
"no_content": "Нема доступног садржаја за овог глумца",
|
"no_streams_available": "Нема доступних стримова",
|
||||||
"no_movies": "Нема доступних филмова за овог глумца",
|
"starting_best_stream": "Покретање најбољег стрима...",
|
||||||
"no_tv": "Нема доступних серија за овог глумца"
|
"loading_more_sources": "Учитавање додатних извора..."
|
||||||
},
|
},
|
||||||
"comments": {
|
"player_ui": {
|
||||||
"title": "Trakt коментари",
|
"via": "преко {{name}}",
|
||||||
"spoiler_warning": "⚠️ Овај коментар садржи спојлере. Додирните да откријете.",
|
"audio_tracks": "Аудио траке",
|
||||||
"spoiler": "Спојлер",
|
"no_audio_tracks": "Нема доступних аудио трака",
|
||||||
"contains_spoilers": "Садржи спојлере",
|
"playback_speed": "Брзина репродукције",
|
||||||
"reveal": "Откриј",
|
"on_hold": "На чекању",
|
||||||
"vip": "VIP",
|
"playback_error": "Грешка при репродукцији",
|
||||||
"unavailable": "Коментари недоступни",
|
"unknown_error": "Дошло је до непознате грешке током репродукције.",
|
||||||
"no_comments": "Још нема коментара на Trakt-у",
|
"copy_error": "Копирај детаље о грешци",
|
||||||
"not_in_database": "Овај садржај можда још није у Trakt бази података",
|
"copied_to_clipboard": "Копирано у привремени меморију",
|
||||||
"check_trakt": "Провери Trakt"
|
"dismiss": "Одбаци",
|
||||||
},
|
"continue_watching": "Настави са гледањем",
|
||||||
"trailers": {
|
"start_over": "Крени испочетка",
|
||||||
"title": "Трејлери",
|
"resume": "Настави",
|
||||||
"official_trailers": "Званични трејлери",
|
"change_source": "Промени извор",
|
||||||
"official_trailer": "Званични трејлер",
|
"switching_source": "Промена извора...",
|
||||||
"teasers": "Тизери",
|
"no_sources_found": "Извори нису пронађени",
|
||||||
"teaser": "Тизер",
|
"sources": "Извори",
|
||||||
"clips_scenes": "Клипови и сцене",
|
"finding_sources": "Проналажење извора...",
|
||||||
"clip": "Клип",
|
"unknown_source": "Непознат извор",
|
||||||
"featurettes": "Кратки филмови о снимању",
|
"sources_limited": "Извори могу бити ограничени због грешака провајдера.",
|
||||||
"featurette": "Кратки филм о снимању",
|
"episodes": "Епизоде",
|
||||||
"behind_the_scenes": "Иза кулиса",
|
"specials": "Специјали",
|
||||||
"no_trailers": "Нема доступних трејлера",
|
"season": "Сезона {{season}}",
|
||||||
"unavailable": "Трејлер недоступан",
|
"stream": "Стрим {{number}}",
|
||||||
"unavailable_desc": "Овај трејлер није могуће учитати тренутно.",
|
"subtitles": "Титлови",
|
||||||
"unable_to_play": "Није могуће пустити трејлер. Покушајте поново.",
|
"built_in": "Уграђени",
|
||||||
"watch_on_youtube": "Гледај на YouTube-у"
|
"addons": "Додаци",
|
||||||
},
|
"style": "Стил",
|
||||||
"catalog": {
|
"none": "Ниједан",
|
||||||
"no_content_found": "Садржај није пронађен",
|
"search_online_subtitles": "Претражи титлове на мрежи",
|
||||||
"no_content_filters": "Нема садржаја за изабране филтере",
|
"preview": "Преглед",
|
||||||
"loading_content": "Учитавање садржаја...",
|
"quick_presets": "Брза подешавања",
|
||||||
"back": "Назад",
|
"default": "Подразумевано",
|
||||||
"in_theaters": "У биоскопима",
|
"yellow": "Жуто",
|
||||||
"all": "Све",
|
"high_contrast": "Висок контраст",
|
||||||
"failed_tmdb": "Неуспело учитавање садржаја са TMDB",
|
"large": "Велико",
|
||||||
"movies": "Филмови",
|
"core": "Језгро",
|
||||||
"tv_shows": "Cерије",
|
"font_size": "Величина фонта",
|
||||||
"channels": "Канали"
|
"show_background": "Прикажи позадину",
|
||||||
},
|
"advanced": "Напредно",
|
||||||
"streams": {
|
"position": "Позиција",
|
||||||
"back_to_episodes": "Назад на епизоде",
|
"text_color": "Боја текста",
|
||||||
"back_to_info": "Назад на инфо",
|
"align": "Поравнање",
|
||||||
"fetching_from": "Преузимање са:",
|
"bottom_offset": "Размак од дна",
|
||||||
"no_sources_available": "Нема доступних извора за стримовање",
|
"background_opacity": "Провидност позадине",
|
||||||
"add_sources_desc": "Молимо додајте изворе у подешавањима",
|
"text_shadow": "Сенка текста",
|
||||||
"add_sources": "Додај изворе",
|
"on": "Укључено",
|
||||||
"finding_streams": "Проналажење доступних стримова...",
|
"off": "Искључено",
|
||||||
"finding_best_stream": "Проналажење најбољег стрима за аутоматско пуштање...",
|
"outline_color": "Боја оквира",
|
||||||
"still_fetching": "Преузимање стримова је још у току...",
|
"outline": "Оквир",
|
||||||
"no_streams_available": "Нема доступних стримова",
|
"outline_width": "Ширина оквира",
|
||||||
"starting_best_stream": "Покретање најбољег стрима...",
|
"letter_spacing": "Размак између слова",
|
||||||
"loading_more_sources": "Учитавање додатних извора..."
|
"line_height": "Висина линије",
|
||||||
},
|
"timing_offset": "Временски помак (с)",
|
||||||
"player_ui": {
|
"visual_sync": "Визуелна синхронизација",
|
||||||
"via": "преко {{name}}",
|
"timing_hint": "Померите титлове раније (-) или касније (+) за синхронизацију.",
|
||||||
"audio_tracks": "Аудио траке",
|
"reset_defaults": "Врати на подразумевано"
|
||||||
"no_audio_tracks": "Нема доступних аудио трака",
|
},
|
||||||
"playback_speed": "Брзина репродукције",
|
"downloads": {
|
||||||
"on_hold": "На чекању",
|
|
||||||
"playback_error": "Грешка при репродукцији",
|
|
||||||
"unknown_error": "Дошло је до непознате грешке током репродукције.",
|
|
||||||
"copy_error": "Копирај детаље о грешци",
|
|
||||||
"copied_to_clipboard": "Копирано у привремени меморију",
|
|
||||||
"dismiss": "Одбаци",
|
|
||||||
"continue_watching": "Настави са гледањем",
|
|
||||||
"start_over": "Крени испочетка",
|
|
||||||
"resume": "Настави",
|
|
||||||
"change_source": "Промени извор",
|
|
||||||
"switching_source": "Промена извора...",
|
|
||||||
"no_sources_found": "Извори нису пронађени",
|
|
||||||
"sources": "Извори",
|
|
||||||
"finding_sources": "Проналажење извора...",
|
|
||||||
"unknown_source": "Непознат извор",
|
|
||||||
"sources_limited": "Извори могу бити ограничени због грешака провајдера.",
|
|
||||||
"episodes": "Епизоде",
|
|
||||||
"specials": "Специјали",
|
|
||||||
"season": "Сезона {{season}}",
|
|
||||||
"stream": "Стрим {{number}}",
|
|
||||||
"subtitles": "Титлови",
|
|
||||||
"built_in": "Уграђени",
|
|
||||||
"addons": "Додаци",
|
|
||||||
"style": "Стил",
|
|
||||||
"none": "Ниједан",
|
|
||||||
"search_online_subtitles": "Претражи титлове на мрежи",
|
|
||||||
"preview": "Преглед",
|
|
||||||
"quick_presets": "Брза подешавања",
|
|
||||||
"default": "Подразумевано",
|
|
||||||
"yellow": "Жуто",
|
|
||||||
"high_contrast": "Висок контраст",
|
|
||||||
"large": "Велико",
|
|
||||||
"core": "Језгро",
|
|
||||||
"font_size": "Величина фонта",
|
|
||||||
"show_background": "Прикажи позадину",
|
|
||||||
"advanced": "Напредно",
|
|
||||||
"position": "Позиција",
|
|
||||||
"text_color": "Боја текста",
|
|
||||||
"align": "Поравнање",
|
|
||||||
"bottom_offset": "Размак од дна",
|
|
||||||
"background_opacity": "Провидност позадине",
|
|
||||||
"text_shadow": "Сенка текста",
|
|
||||||
"on": "Укључено",
|
|
||||||
"off": "Искључено",
|
|
||||||
"outline_color": "Боја оквира",
|
|
||||||
"outline": "Оквир",
|
|
||||||
"outline_width": "Ширина оквира",
|
|
||||||
"letter_spacing": "Размак између слова",
|
|
||||||
"line_height": "Висина линије",
|
|
||||||
"timing_offset": "Временски помак (с)",
|
|
||||||
"visual_sync": "Визуелна синхронизација",
|
|
||||||
"timing_hint": "Померите титлове раније (-) или касније (+) за синхронизацију.",
|
|
||||||
"reset_defaults": "Врати на подразумевано"
|
|
||||||
},
|
|
||||||
"downloads": {
|
|
||||||
"title": "Преузимања",
|
"title": "Преузимања",
|
||||||
"no_downloads": "Још нема преузимања",
|
"no_downloads": "Још нема преузимања",
|
||||||
"no_downloads_desc": "Преузети садржај ће се појавити овде за гледање ван мреже",
|
"no_downloads_desc": "Преузети садржај ће се појавити овде за гледање ван мреже",
|
||||||
|
|
@ -758,7 +758,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Ово ће ресетовати сва подешавања и обрисати кеш. Да ли сте сигурни?",
|
"clear_data_desc": "Ово ће ресетовати сва подешавања и обрисати кеш. Да ли сте сигурни?",
|
||||||
"app_updates": "Ажурирања апликације",
|
"app_updates": "Ажурирања апликације",
|
||||||
"about_nuvio": "О Nuvio апликацији"
|
"about_nuvio": "О Nuvio апликацији",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Приватност и Подаци",
|
"title": "Приватност и Подаци",
|
||||||
|
|
|
||||||
|
|
@ -764,7 +764,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "Bu işlem tüm ayarları sıfırlayacak ve tüm önbelleği temizleyecektir. Emin misiniz?",
|
"clear_data_desc": "Bu işlem tüm ayarları sıfırlayacak ve tüm önbelleği temizleyecektir. Emin misiniz?",
|
||||||
"app_updates": "Uygulama Güncellemeleri",
|
"app_updates": "Uygulama Güncellemeleri",
|
||||||
"about_nuvio": "Nuvio Hakkında"
|
"about_nuvio": "Nuvio Hakkında",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "Gizlilik ve Veri",
|
"title": "Gizlilik ve Veri",
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,65 @@
|
||||||
},
|
},
|
||||||
"clear_data_desc": "这将重置所有设置并清除所有缓存数据。您确定吗?",
|
"clear_data_desc": "这将重置所有设置并清除所有缓存数据。您确定吗?",
|
||||||
"app_updates": "应用更新",
|
"app_updates": "应用更新",
|
||||||
"about_nuvio": "关于 Nuvio"
|
"about_nuvio": "关于 Nuvio",
|
||||||
|
"cloud_sync": {
|
||||||
|
"title": "Nuvio Sync",
|
||||||
|
"description": "Sync data across your Nuvio devices",
|
||||||
|
"hero_title": "Cloud Sync",
|
||||||
|
"hero_subtitle": "Keep your addons, progress, and library aligned across all devices.",
|
||||||
|
"auth": {
|
||||||
|
"account": "Account",
|
||||||
|
"not_configured": "Supabase not configured",
|
||||||
|
"not_authenticated": "Not authenticated",
|
||||||
|
"email_session": "Email session",
|
||||||
|
"signed_in_as": "Signed in as {{email}}",
|
||||||
|
"not_signed_in": "Not signed in",
|
||||||
|
"effective_owner": "Effective owner: {{id}}"
|
||||||
|
},
|
||||||
|
"stats": {
|
||||||
|
"title": "Database Statistics",
|
||||||
|
"plugins": "Plugins",
|
||||||
|
"addons": "Addons",
|
||||||
|
"watch_progress": "Watch Progress",
|
||||||
|
"library_items": "Library Items",
|
||||||
|
"watched_items": "Watched Items",
|
||||||
|
"signin_required": "Sign in to load remote data counts."
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"title": "Actions",
|
||||||
|
"description": "Pull to update this device from the cloud, or push from this device as the latest source.",
|
||||||
|
"pull_btn": "Pull from Cloud",
|
||||||
|
"push_btn": "Push from Device",
|
||||||
|
"manage_account": "Manage Account",
|
||||||
|
"sign_out": "Sign Out",
|
||||||
|
"sign_in_up": "Sign In / Up"
|
||||||
|
},
|
||||||
|
"alerts": {
|
||||||
|
"pull_success_title": "Cloud Data Pulled",
|
||||||
|
"pull_success_msg": "The latest cloud data has been downloaded to this device.",
|
||||||
|
"pull_failed_title": "Pull Failed",
|
||||||
|
"pull_failed_msg": "Failed to download data from the cloud",
|
||||||
|
"push_success_title": "Push Completed",
|
||||||
|
"push_success_msg": "Device data has been uploaded to the cloud.",
|
||||||
|
"push_failed_title": "Push Failed",
|
||||||
|
"push_failed_msg": "Failed to upload local data",
|
||||||
|
"sign_out_failed": "Sign Out Failed",
|
||||||
|
"sign_out_failed_title": "Logout Error"
|
||||||
|
},
|
||||||
|
"external_sync": {
|
||||||
|
"title": "External Sync Priority",
|
||||||
|
"active_msg": "{{services}} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.",
|
||||||
|
"inactive_msg": "If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database."
|
||||||
|
},
|
||||||
|
"pre_auth": {
|
||||||
|
"title": "Before Syncing",
|
||||||
|
"description": "Sign in to start cloud sync and keep your data consistent across devices.",
|
||||||
|
"point_1": "• Addons and plugins settings",
|
||||||
|
"point_2": "• Watch progress and library",
|
||||||
|
"env_warning": "Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync."
|
||||||
|
},
|
||||||
|
"connection": "Connection"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"privacy": {
|
"privacy": {
|
||||||
"title": "隐私和数据",
|
"title": "隐私和数据",
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { catalogService, StreamingContent } from './catalogService';
|
||||||
import { storageService } from './storageService';
|
import { storageService } from './storageService';
|
||||||
import { watchedService, LocalWatchedItem } from './watchedService';
|
import { watchedService, LocalWatchedItem } from './watchedService';
|
||||||
import { TraktService } from './traktService';
|
import { TraktService } from './traktService';
|
||||||
|
import { SimklService } from './simklService';
|
||||||
|
|
||||||
const SUPABASE_SESSION_KEY = '@supabase:session';
|
const SUPABASE_SESSION_KEY = '@supabase:session';
|
||||||
const DEFAULT_SYNC_DEBOUNCE_MS = 2000;
|
const DEFAULT_SYNC_DEBOUNCE_MS = 2000;
|
||||||
|
|
@ -123,6 +124,7 @@ class SupabaseSyncService {
|
||||||
private readonly foregroundPullCooldownMs = 30000;
|
private readonly foregroundPullCooldownMs = 30000;
|
||||||
private pendingWatchProgressDeleteKeys = new Set<string>();
|
private pendingWatchProgressDeleteKeys = new Set<string>();
|
||||||
private watchProgressDeleteTimer: ReturnType<typeof setTimeout> | null = null;
|
private watchProgressDeleteTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
private watchProgressPushedSignatures = new Map<string, string>();
|
||||||
|
|
||||||
private pendingPushTimers: Record<PushTarget, ReturnType<typeof setTimeout> | null> = {
|
private pendingPushTimers: Record<PushTarget, ReturnType<typeof setTimeout> | null> = {
|
||||||
plugins: null,
|
plugins: null,
|
||||||
|
|
@ -236,6 +238,7 @@ class SupabaseSyncService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.session = null;
|
this.session = null;
|
||||||
|
this.watchProgressPushedSignatures.clear();
|
||||||
await mmkvStorage.removeItem(SUPABASE_SESSION_KEY);
|
await mmkvStorage.removeItem(SUPABASE_SESSION_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,13 +280,15 @@ class SupabaseSyncService {
|
||||||
await this.pushPluginsFromLocal();
|
await this.pushPluginsFromLocal();
|
||||||
await this.pushAddonsFromLocal();
|
await this.pushAddonsFromLocal();
|
||||||
|
|
||||||
const traktConnected = await this.isTraktConnected();
|
await this.pushLibraryFromLocal();
|
||||||
if (traktConnected) {
|
const externalProgressSyncConnected = await this.isExternalProgressSyncConnected();
|
||||||
|
if (externalProgressSyncConnected) {
|
||||||
|
logger.log('[SupabaseSyncService] External sync (Trakt/Simkl) is connected; skipping watch progress/watched-items push, keeping library sync.');
|
||||||
|
logger.log('[SupabaseSyncService] pushAllLocalData: complete');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.pushWatchProgressFromLocal();
|
await this.pushWatchProgressFromLocal();
|
||||||
await this.pushLibraryFromLocal();
|
|
||||||
await this.pushWatchedItemsFromLocal();
|
await this.pushWatchedItemsFromLocal();
|
||||||
logger.log('[SupabaseSyncService] pushAllLocalData: complete');
|
logger.log('[SupabaseSyncService] pushAllLocalData: complete');
|
||||||
}
|
}
|
||||||
|
|
@ -296,13 +301,14 @@ class SupabaseSyncService {
|
||||||
await this.pullPluginsToLocal();
|
await this.pullPluginsToLocal();
|
||||||
await this.pullAddonsToLocal();
|
await this.pullAddonsToLocal();
|
||||||
|
|
||||||
const traktConnected = await this.isTraktConnected();
|
await this.pullLibraryToLocal();
|
||||||
if (traktConnected) {
|
const externalProgressSyncConnected = await this.isExternalProgressSyncConnected();
|
||||||
|
if (externalProgressSyncConnected) {
|
||||||
|
logger.log('[SupabaseSyncService] External sync (Trakt/Simkl) is connected; skipping watch progress/watched-items pull, keeping library sync.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.pullWatchProgressToLocal();
|
await this.pullWatchProgressToLocal();
|
||||||
await this.pullLibraryToLocal();
|
|
||||||
await this.pullWatchedItemsToLocal();
|
await this.pullWatchedItemsToLocal();
|
||||||
});
|
});
|
||||||
logger.log('[SupabaseSyncService] pullAllToLocal: complete');
|
logger.log('[SupabaseSyncService] pullAllToLocal: complete');
|
||||||
|
|
@ -493,9 +499,18 @@ class SupabaseSyncService {
|
||||||
logger.warn('[SupabaseSyncService] runStartupSync: one or more pull steps failed; skipped startup push-by-design');
|
logger.warn('[SupabaseSyncService] runStartupSync: one or more pull steps failed; skipped startup push-by-design');
|
||||||
}
|
}
|
||||||
|
|
||||||
const traktConnected = await this.isTraktConnected();
|
const libraryPullOk = await this.safeRun('pull_library', async () => {
|
||||||
if (traktConnected) {
|
await this.withSuppressedPushes(async () => {
|
||||||
logger.log('[SupabaseSyncService] Trakt is connected; skipping progress/library/watched Supabase sync.');
|
await this.pullLibraryToLocal();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const externalProgressSyncConnected = await this.isExternalProgressSyncConnected();
|
||||||
|
if (externalProgressSyncConnected) {
|
||||||
|
logger.log('[SupabaseSyncService] External sync (Trakt/Simkl) is connected; skipping watch progress/watched-items Supabase sync (library still synced).');
|
||||||
|
if (!libraryPullOk) {
|
||||||
|
logger.warn('[SupabaseSyncService] runStartupSync: library pull failed while external sync priority is active');
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -505,12 +520,6 @@ class SupabaseSyncService {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const libraryPullOk = await this.safeRun('pull_library', async () => {
|
|
||||||
await this.withSuppressedPushes(async () => {
|
|
||||||
await this.pullLibraryToLocal();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const watchedPullOk = await this.safeRun('pull_watched_items', async () => {
|
const watchedPullOk = await this.safeRun('pull_watched_items', async () => {
|
||||||
await this.withSuppressedPushes(async () => {
|
await this.withSuppressedPushes(async () => {
|
||||||
await this.pullWatchedItemsToLocal();
|
await this.pullWatchedItemsToLocal();
|
||||||
|
|
@ -629,8 +638,8 @@ class SupabaseSyncService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const traktConnected = await this.isTraktConnected();
|
const externalProgressSyncConnected = await this.isExternalProgressSyncConnected();
|
||||||
if (traktConnected) return;
|
if (externalProgressSyncConnected) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.log(`[SupabaseSyncService] flushWatchProgressDeletes: deleting ${keys.length} keys`);
|
logger.log(`[SupabaseSyncService] flushWatchProgressDeletes: deleting ${keys.length} keys`);
|
||||||
|
|
@ -700,12 +709,12 @@ class SupabaseSyncService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const traktConnected = await this.isTraktConnected();
|
|
||||||
if (traktConnected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target === 'watch_progress') {
|
if (target === 'watch_progress') {
|
||||||
|
const externalProgressSyncConnected = await this.isExternalProgressSyncConnected();
|
||||||
|
if (externalProgressSyncConnected) {
|
||||||
|
logger.log('[SupabaseSyncService] executeScheduledPush: skipping watch_progress due to external sync priority (Trakt/Simkl)');
|
||||||
|
return;
|
||||||
|
}
|
||||||
await this.pushWatchProgressFromLocal();
|
await this.pushWatchProgressFromLocal();
|
||||||
logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`);
|
logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`);
|
||||||
return;
|
return;
|
||||||
|
|
@ -716,6 +725,12 @@ class SupabaseSyncService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const externalProgressSyncConnected = await this.isExternalProgressSyncConnected();
|
||||||
|
if (externalProgressSyncConnected) {
|
||||||
|
logger.log('[SupabaseSyncService] executeScheduledPush: skipping watched_items due to external sync priority (Trakt/Simkl)');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await this.pushWatchedItemsFromLocal();
|
await this.pushWatchedItemsFromLocal();
|
||||||
logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`);
|
logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`);
|
||||||
}
|
}
|
||||||
|
|
@ -745,6 +760,8 @@ class SupabaseSyncService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setSession(session: SupabaseSession): Promise<void> {
|
private async setSession(session: SupabaseSession): Promise<void> {
|
||||||
|
// Reset per-entry push cache on session changes to avoid cross-account state bleed.
|
||||||
|
this.watchProgressPushedSignatures.clear();
|
||||||
this.session = session;
|
this.session = session;
|
||||||
await mmkvStorage.setItem(SUPABASE_SESSION_KEY, JSON.stringify(session));
|
await mmkvStorage.setItem(SUPABASE_SESSION_KEY, JSON.stringify(session));
|
||||||
}
|
}
|
||||||
|
|
@ -775,6 +792,7 @@ class SupabaseSyncService {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[SupabaseSyncService] Failed to refresh session:', error);
|
logger.error('[SupabaseSyncService] Failed to refresh session:', error);
|
||||||
this.session = null;
|
this.session = null;
|
||||||
|
this.watchProgressPushedSignatures.clear();
|
||||||
await mmkvStorage.removeItem(SUPABASE_SESSION_KEY);
|
await mmkvStorage.removeItem(SUPABASE_SESSION_KEY);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -791,6 +809,7 @@ class SupabaseSyncService {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[SupabaseSyncService] Token refresh failed:', error);
|
logger.error('[SupabaseSyncService] Token refresh failed:', error);
|
||||||
this.session = null;
|
this.session = null;
|
||||||
|
this.watchProgressPushedSignatures.clear();
|
||||||
await mmkvStorage.removeItem(SUPABASE_SESSION_KEY);
|
await mmkvStorage.removeItem(SUPABASE_SESSION_KEY);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -997,6 +1016,22 @@ class SupabaseSyncService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getWatchProgressEntrySignature(value: { currentTime?: number; duration?: number; lastUpdated?: number }): string {
|
||||||
|
return [
|
||||||
|
Number(value.currentTime || 0),
|
||||||
|
Number(value.duration || 0),
|
||||||
|
Number(value.lastUpdated || 0),
|
||||||
|
].join('|');
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildLocalWatchProgressKey(
|
||||||
|
contentType: 'movie' | 'series',
|
||||||
|
contentId: string,
|
||||||
|
episodeId?: string
|
||||||
|
): string {
|
||||||
|
return `${contentType}:${contentId}${episodeId ? `:${episodeId}` : ''}`;
|
||||||
|
}
|
||||||
|
|
||||||
private toStreamingContent(item: LibraryRow): StreamingContent {
|
private toStreamingContent(item: LibraryRow): StreamingContent {
|
||||||
const type = item.content_type === 'movie' ? 'movie' : 'series';
|
const type = item.content_type === 'movie' ? 'movie' : 'series';
|
||||||
const posterShape = (item.poster_shape || 'POSTER').toLowerCase() as 'poster' | 'square' | 'landscape';
|
const posterShape = (item.poster_shape || 'POSTER').toLowerCase() as 'poster' | 'square' | 'landscape';
|
||||||
|
|
@ -1037,6 +1072,19 @@ class SupabaseSyncService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async isSimklConnected(): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
return await SimklService.getInstance().isAuthenticated();
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async isExternalProgressSyncConnected(): Promise<boolean> {
|
||||||
|
if (await this.isTraktConnected()) return true;
|
||||||
|
return await this.isSimklConnected();
|
||||||
|
}
|
||||||
|
|
||||||
private async pullPluginsToLocal(): Promise<void> {
|
private async pullPluginsToLocal(): Promise<void> {
|
||||||
const token = await this.getValidAccessToken();
|
const token = await this.getValidAccessToken();
|
||||||
if (!token) return;
|
if (!token) return;
|
||||||
|
|
@ -1254,11 +1302,10 @@ class SupabaseSyncService {
|
||||||
const type = row.content_type === 'movie' ? 'movie' : 'series';
|
const type = row.content_type === 'movie' ? 'movie' : 'series';
|
||||||
const season = row.season == null ? null : Number(row.season);
|
const season = row.season == null ? null : Number(row.season);
|
||||||
const episode = row.episode == null ? null : Number(row.episode);
|
const episode = row.episode == null ? null : Number(row.episode);
|
||||||
remoteSet.add(`${type}:${row.content_id}:${season ?? ''}:${episode ?? ''}`);
|
|
||||||
|
|
||||||
const episodeId = type === 'series' && season != null && episode != null
|
const episodeId = type === 'series' && season != null && episode != null
|
||||||
? `${row.content_id}:${season}:${episode}`
|
? `${row.content_id}:${season}:${episode}`
|
||||||
: undefined;
|
: undefined;
|
||||||
|
remoteSet.add(this.buildLocalWatchProgressKey(type, row.content_id, episodeId));
|
||||||
|
|
||||||
const local = await storageService.getWatchProgress(row.content_id, type, episodeId);
|
const local = await storageService.getWatchProgress(row.content_id, type, episodeId);
|
||||||
const remoteLastWatched = this.normalizeEpochMs(row.last_watched);
|
const remoteLastWatched = this.normalizeEpochMs(row.last_watched);
|
||||||
|
|
@ -1284,15 +1331,46 @@ class SupabaseSyncService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log(`[SupabaseSyncService] pullWatchProgressToLocal: merged ${(rows || []).length} remote entries (no local prune)`);
|
// Remote-first continue watching: remove local entries that no longer exist remotely.
|
||||||
|
// This intentionally treats the successful remote pull as authoritative.
|
||||||
|
const allLocal = await storageService.getAllWatchProgress();
|
||||||
|
let pruned = 0;
|
||||||
|
for (const [localKey] of Object.entries(allLocal)) {
|
||||||
|
if (remoteSet.has(localKey)) continue;
|
||||||
|
|
||||||
|
const parsed = this.parseWatchProgressKey(localKey);
|
||||||
|
if (!parsed) continue;
|
||||||
|
|
||||||
|
const episodeId = parsed.videoId && parsed.videoId !== parsed.contentId ? parsed.videoId : undefined;
|
||||||
|
await storageService.removeWatchProgress(parsed.contentId, parsed.contentType, episodeId);
|
||||||
|
this.watchProgressPushedSignatures.delete(localKey);
|
||||||
|
pruned += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log(`[SupabaseSyncService] pullWatchProgressToLocal: merged=${(rows || []).length} prunedLocalMissing=${pruned}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async pushWatchProgressFromLocal(): Promise<void> {
|
private async pushWatchProgressFromLocal(): Promise<void> {
|
||||||
const all = await storageService.getAllWatchProgress();
|
const all = await storageService.getAllWatchProgress();
|
||||||
const entries: WatchProgressRow[] = Object.entries(all).reduce<WatchProgressRow[]>((acc, [key, value]) => {
|
const nextSeenKeys = new Set<string>();
|
||||||
|
const changedEntries: Array<{ key: string; row: WatchProgressRow; signature: string }> = [];
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(all)) {
|
||||||
|
nextSeenKeys.add(key);
|
||||||
|
const signature = this.getWatchProgressEntrySignature(value);
|
||||||
|
if (this.watchProgressPushedSignatures.get(key) === signature) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const parsed = this.parseWatchProgressKey(key);
|
const parsed = this.parseWatchProgressKey(key);
|
||||||
if (!parsed) return acc;
|
if (!parsed) {
|
||||||
acc.push({
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
changedEntries.push({
|
||||||
|
key,
|
||||||
|
signature,
|
||||||
|
row: {
|
||||||
content_id: parsed.contentId,
|
content_id: parsed.contentId,
|
||||||
content_type: parsed.contentType,
|
content_type: parsed.contentType,
|
||||||
video_id: parsed.videoId,
|
video_id: parsed.videoId,
|
||||||
|
|
@ -1302,11 +1380,30 @@ class SupabaseSyncService {
|
||||||
duration: this.secondsToMsLong(value.duration),
|
duration: this.secondsToMsLong(value.duration),
|
||||||
last_watched: this.normalizeEpochMs(value.lastUpdated || Date.now()),
|
last_watched: this.normalizeEpochMs(value.lastUpdated || Date.now()),
|
||||||
progress_key: parsed.progressKey,
|
progress_key: parsed.progressKey,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
return acc;
|
}
|
||||||
}, []);
|
|
||||||
|
|
||||||
await this.callRpc<void>('sync_push_watch_progress', { p_entries: entries });
|
// Prune signatures for entries no longer present locally (deletes are handled separately).
|
||||||
|
for (const existingKey of Array.from(this.watchProgressPushedSignatures.keys())) {
|
||||||
|
if (!nextSeenKeys.has(existingKey)) {
|
||||||
|
this.watchProgressPushedSignatures.delete(existingKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changedEntries.length === 0) {
|
||||||
|
logger.log('[SupabaseSyncService] pushWatchProgressFromLocal: no changed entries; skipping push');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.callRpc<void>('sync_push_watch_progress', {
|
||||||
|
p_entries: changedEntries.map((entry) => entry.row),
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const entry of changedEntries) {
|
||||||
|
this.watchProgressPushedSignatures.set(entry.key, entry.signature);
|
||||||
|
}
|
||||||
|
logger.log(`[SupabaseSyncService] pushWatchProgressFromLocal: pushedChanged=${changedEntries.length} totalLocal=${Object.keys(all).length}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async pullLibraryToLocal(): Promise<void> {
|
private async pullLibraryToLocal(): Promise<void> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue