feat: add sync progress, break loops once we get 0 users back

This commit is contained in:
Sticks
2025-04-22 18:56:27 -04:00
parent ba25e5d485
commit 5a7c3155ac
13 changed files with 292 additions and 40 deletions

View File

@ -1,4 +1,5 @@
<script lang="ts">
/* eslint-disable @typescript-eslint/no-unused-vars */
import { info, error } from '@tauri-apps/plugin-log';
import { awaiter } from '$lib/utils';
import { onDestroy, onMount } from 'svelte';
@ -21,6 +22,7 @@
appVersion: 'Loading...',
tauriVersion: 'Loading...'
};
let syncState = {
show: false,
syncing: false,
@ -30,6 +32,14 @@
message: ''
};
let syncProgress = {
currentStep: '',
percentage: 0,
current_count: 0,
total_count: 0,
complete: false
}
let isAutoSyncConfigModalOpen = false;
let canSave = false;
let config: Config | null = null;
@ -47,14 +57,14 @@
};
onMount(async () => {
info(`[FanslySync::page_init:home] onMount() called. Starting page initialization...`);
await info(`[FanslySync::page_init:home] onMount() called. Starting page initialization...`);
const [configData, configError] = await awaiter(invoke('get_config') as Promise<Config>);
if (configError || !configData) {
error(
await error(
`[FanslySync::page_init:home] Failed to get configuration. Error: ${configError ?? 'Config was null'}`
);
info(
await info(
`[FanslySync::page_init:home] Page Initialization failed due to configuration error. Exiting...`
);
await message(
@ -76,43 +86,48 @@
loadingSync = false;
const updateStatus = await check();
upToDate = !updateStatus?.available ?? false;
// We are up to date if the update status is null
upToDate = updateStatus === null;
updateData = updateStatus;
info(
await info(
`[FanslySync::page_init:home] Update check completed. Up to date: ${upToDate}, Update data: ${updateData}`
);
info(`[FanslySync::page_init:home] Getting app and Tauri versions...`);
await info(`[FanslySync::page_init:home] Getting app and Tauri versions...`);
versionData.appVersion = await getVersion();
versionData.tauriVersion = await getTauriVersion();
info(
await info(
`[FanslySync::page_init:home] App and Tauri versions fetched. We are running App version: ${versionData.appVersion}, atop Tauri version: ${versionData.tauriVersion}`
);
info(`[FanslySync::page_init:home] Setting up autosync interval...`);
await info(`[FanslySync::page_init:home] Setting up autosync interval...`);
syncInterval = setInterval(
async () => {
if (config?.auto_sync_enabled) {
info(`[FanslySync::autoSyncProcess] Auto Sync enabled - syncing data automatically.`);
await info(`[FanslySync::autoSyncProcess] Auto Sync enabled - syncing data automatically.`);
const nextIntervalTime = new Date(
Date.now() + (config?.sync_interval ?? 1) * 60 * 60 * 1000
);
const nextIntervalTimeString = nextIntervalTime.toLocaleTimeString();
const returnedData = await syncNow(true);
if (!returnedData || returnedData === null) {
error(`[FanslySync::autoSyncProcess] Failed to sync data automatically.`);
await error(`[FanslySync::autoSyncProcess] Failed to sync data automatically.`);
// Send error notification
await sendNotification({
sendNotification({
title: 'FanslySync: Auto Sync Failed!',
body: `An error occurred while syncing data automatically. We will automatically retry at ${nextIntervalTimeString}.`
});
} else {
info(
await info(
`[FanslySync::autoSyncProcess] Synced data automatically - preparing to send to server.`
);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, uploadErr] = await awaiter(
invoke('fansly_upload_auto_sync_data', {
token: config?.sync_token,
@ -121,12 +136,12 @@
);
if (uploadErr) {
error(
await error(
`[FanslySync::autoSyncProcess] Failed to upload data to server. Error: ${uploadErr}`
);
// Send error notification
await sendNotification({
sendNotification({
title: 'FanslySync: Auto Sync Failed!',
body: `An error occurred while uploading data to the server. We will automatically retry at ${nextIntervalTimeString}.`
});
@ -135,29 +150,53 @@
}
// Send success notification
await sendNotification({
sendNotification({
title: 'FanslySync: Auto Sync Successful!',
body: `Data synced and uploaded successfully. Next sync will occur at ${nextIntervalTimeString}.`
});
}
} else {
info(`[FanslySync::autoSyncProcess] Auto Sync disabled - skipping this sync.`);
await info(`[FanslySync::autoSyncProcess] Auto Sync disabled - skipping this sync.`);
}
},
(config?.sync_interval ?? 1) * 60 * 60 * 1000
);
info(`[FanslySync::page_init:home] Autosync interval set successfully.`);
info(`[FanslySync::page_init:home] Page initialization completed successfully.`);
await info(`[FanslySync::page_init:home] Autosync interval set successfully.`);
await info(`[FanslySync::page_init:home] Page initialization completed successfully.`);
});
async function syncNow(auto: boolean = false) {
info(`[FanslySync::syncNow] Starting manual sync...`);
await info(`[FanslySync::syncNow] Starting manual sync...`);
syncState.error = false;
syncState.success = false;
syncState.syncing = true;
syncState.show = !auto;
syncState.show = true;
const updateThread = setInterval(async () => {
const [progress, progressErr] = await awaiter<{
current_step: string;
percentage_done: number;
current_count: number;
total_count: number;
complete: boolean;
}>(invoke('fansly_get_sync_status'))
if (progressErr || !progress) {
await error(`[FanslySync::syncNow] Failed to get sync status. Error: ${progressErr} or progress was null.`);
return;
}
syncProgress.currentStep = progress.current_step;
syncProgress.percentage = progress.percentage_done;
syncProgress.current_count = progress.current_count;
syncProgress.total_count = progress.total_count;
await info(`[FanslySync::syncNow] Sync progress updated: ${JSON.stringify(syncProgress)}`);
console.log(`[FanslySync::syncNow] Sync progress updated: ${JSON.stringify(syncProgress)}`);
}, 1000);
const [syncData, syncError] = await awaiter(
invoke('fansly_sync', {
@ -165,8 +204,10 @@
}) as Promise<SyncData>
);
clearInterval(updateThread);
if (syncError || syncData === null) {
error(
await error(
`[FanslySync::syncNow] Failed to sync data. Error: ${syncError ?? 'Sync data was null'}`
);
syncState.syncing = false;
@ -174,7 +215,7 @@
syncState.message = syncError ?? 'Sync data was null';
// Send failure notification
await sendNotification({
sendNotification({
title: 'FanslySync: Sync Failed!',
body: 'An error occurred while syncing data. Please check the app for more details.'
});
@ -188,17 +229,17 @@
config!.last_sync = Date.now();
config!.last_sync_data = syncData!;
const [saveConfigData, saveConfigError] = await awaiter(
const [, saveConfigError] = await awaiter(
invoke('save_config', { config }) as Promise<boolean>
);
if (saveConfigError) {
error(`[FanslySync::syncNow] Failed to save config data. Error: ${saveConfigError}`);
await error(`[FanslySync::syncNow] Failed to save config data. Error: ${saveConfigError}`);
syncState.syncing = false;
syncState.error = true;
syncState.message = saveConfigError ?? 'Save config data was null';
// Send failure notification
await sendNotification({
sendNotification({
title: 'FanslySync: Sync Failed!',
body: 'An error occurred while syncing data. Please check the app for more details.'
});
@ -220,21 +261,29 @@
}
if (!auto)
await sendNotification({
sendNotification({
title: 'FanslySync: Sync Successful!',
body: 'Data synced successfully. Please look at the app for more details.',
sound: soundName
});
info(`[FanslySync::syncNow] Manual sync completed successfully.`);
await info(`[FanslySync::syncNow] Manual sync completed successfully.`);
if (auto) {
setTimeout(() => {
syncState.show = false;
}, 5000);
}
if (auto) return syncData;
else return null;
// If auto is true, auto-hide the sync state after 5 seconds
}
async function doUpdate() {
if (!updateData || !updateData.available) {
message('You are up to date! Current version: ' + versionData.appVersion, {
await message('You are up to date! Current version: ' + versionData.appVersion, {
title: 'FanslySync | Update',
kind: 'info'
});
@ -303,6 +352,8 @@
// Enable autosync
config!.auto_sync_enabled = !config?.auto_sync_enabled;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, saveConfigError] = await awaiter(invoke('save_config', { config }));
if (saveConfigError) {
@ -485,16 +536,16 @@
const [_, saveConfigError] = await awaiter(invoke('save_config', { config }));
if (saveConfigError) {
await toast.error('Failed to save Auto Sync configuration. Please try again.', {
toast.error('Failed to save Auto Sync configuration. Please try again.', {
id: savingToast
});
error(
await error(
`[FanslySync::onAutoSyncSave] Failed to save Auto Sync configuration. Error: ${saveConfigError}`
);
return;
} else {
info(`[FanslySync::onAutoSyncSave] Auto Sync configuration saved successfully.`);
await toast.success('Auto Sync configuration saved successfully.', { id: savingToast });
await info(`[FanslySync::onAutoSyncSave] Auto Sync configuration saved successfully.`);
toast.success('Auto Sync configuration saved successfully.', { id: savingToast });
}
}
@ -515,6 +566,7 @@
autoSyncConfig.didRunInitialValidation = true;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
function useDebounce(fn: Function, delay: number) {
let timeout: number;
return function (...args: any) {
@ -813,8 +865,8 @@
<div class="flex flex-col">
<h1 class="text-lg font-bold">Syncing...</h1>
<p class="text-sm">
Please wait while we sync your followers and subscriber data. This can take awhile on
some connections.
We are currently {syncProgress.currentStep}. We've processed {syncProgress.current_count} of {syncProgress.total_count} items so far. We
are about {syncProgress.percentage}% done with this step.
</p>
</div>
{:else if syncState.success}