feat(sync): implement background sync and visibility handling for mobile
This commit is contained in:
@@ -9,26 +9,28 @@ export const openExternalUrl = async (url: string): Promise<void> => {
|
||||
// Only run this in Tauri builds
|
||||
if (typeof window !== 'undefined' && (window as any).__TAURI__) {
|
||||
try {
|
||||
console.log('[openExternalUrl] invoking open_external_url command...');
|
||||
const { invoke } = await import('@tauri-apps/api/core');
|
||||
await invoke('open_external_url', { url });
|
||||
console.log('[openExternalUrl] command succeeded');
|
||||
// First, try the plugin directly (works on both desktop and mobile)
|
||||
console.log('[openExternalUrl] trying opener plugin...');
|
||||
const { openUrl } = await import('@tauri-apps/plugin-opener');
|
||||
await openUrl(url);
|
||||
console.log('[openExternalUrl] plugin succeeded');
|
||||
return;
|
||||
} catch (err) {
|
||||
console.error('[openExternalUrl] Tauri command failed:', err);
|
||||
// Try the plugin as fallback (for mobile)
|
||||
} catch (pluginErr) {
|
||||
console.warn('[openExternalUrl] opener plugin failed:', pluginErr);
|
||||
|
||||
// Fallback: try the custom command (useful if plugin fails due to ACL)
|
||||
try {
|
||||
console.log('[openExternalUrl] trying opener plugin fallback...');
|
||||
const { openUrl } = await import('@tauri-apps/plugin-opener');
|
||||
await openUrl(url);
|
||||
console.log('[openExternalUrl] plugin fallback succeeded');
|
||||
console.log('[openExternalUrl] trying invoke command fallback...');
|
||||
const { invoke } = await import('@tauri-apps/api/core');
|
||||
await invoke('open_external_url', { url });
|
||||
console.log('[openExternalUrl] command fallback succeeded');
|
||||
return;
|
||||
} catch (pluginErr) {
|
||||
console.error('[openExternalUrl] plugin fallback also failed:', pluginErr);
|
||||
} catch (invokeErr) {
|
||||
console.error('[openExternalUrl] command fallback also failed:', invokeErr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[openExternalUrl] falling back to window.open');
|
||||
window.open(url, '_blank');
|
||||
};
|
||||
@@ -269,3 +271,69 @@ export const readClipboardImage = async (): Promise<File | null> => {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Background Sync API for mobile platforms
|
||||
* Starts a native Rust-based Matrix sync that runs even when the app is backgrounded
|
||||
*/
|
||||
export interface BackgroundSyncCredentials {
|
||||
homeserverUrl: string;
|
||||
userId: string;
|
||||
accessToken: string;
|
||||
deviceId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start background Matrix sync on mobile
|
||||
* This runs the sync in native Rust code, allowing notifications even when the app is backgrounded
|
||||
*/
|
||||
export const startBackgroundSync = async (credentials: BackgroundSyncCredentials): Promise<void> => {
|
||||
if (!isTauriMobile()) {
|
||||
console.log('[BackgroundSync] Not on mobile, skipping');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { invoke } = await import('@tauri-apps/api/core');
|
||||
await invoke('start_background_sync', {
|
||||
homeserverUrl: credentials.homeserverUrl,
|
||||
userId: credentials.userId,
|
||||
accessToken: credentials.accessToken,
|
||||
deviceId: credentials.deviceId,
|
||||
});
|
||||
console.log('[BackgroundSync] Started successfully');
|
||||
} catch (err) {
|
||||
console.error('[BackgroundSync] Failed to start:', err);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop background Matrix sync on mobile
|
||||
*/
|
||||
export const stopBackgroundSync = async (): Promise<void> => {
|
||||
if (!isTauriMobile()) return;
|
||||
|
||||
try {
|
||||
const { invoke } = await import('@tauri-apps/api/core');
|
||||
await invoke('stop_background_sync');
|
||||
console.log('[BackgroundSync] Stopped');
|
||||
} catch (err) {
|
||||
console.error('[BackgroundSync] Failed to stop:', err);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current background sync state
|
||||
*/
|
||||
export const getBackgroundSyncState = async (): Promise<string> => {
|
||||
if (!isTauriMobile()) return 'NotApplicable';
|
||||
|
||||
try {
|
||||
const { invoke } = await import('@tauri-apps/api/core');
|
||||
return await invoke<string>('get_background_sync_state');
|
||||
} catch (err) {
|
||||
console.error('[BackgroundSync] Failed to get state:', err);
|
||||
return 'Error';
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user