Migrate from window.electron to tauri IPC functions across components

- Replaced `window.electron.invoke` calls with equivalent `tauri` function calls for all IPC interactions.
- Removed `electron.d.ts` TypeScript definitions as they are no longer needed.
- Updated related logic for offline/online state synchronization.
- Added `types.rs` and `shared/mod.rs` modules to support Tauri IPC integration with Rust enums and shared logic.
- Refactored IPC request queues to use updated handler names for consistency with Tauri.
This commit is contained in:
natreex
2026-03-21 09:34:13 -04:00
parent 1a15692e40
commit ee4438834c
144 changed files with 21258 additions and 876 deletions

View File

@@ -10,6 +10,7 @@ import {SessionProps} from "@/lib/models/Session";
import System from "@/lib/models/System";
import {SessionContext} from "@/context/SessionContext";
import {AlertContext} from "@/context/AlertContext";
import * as tauri from '@/lib/tauri';
const messagesMap = {
fr: frMessages,
@@ -36,10 +37,7 @@ export default function LoginWrapper({children}: { children: React.ReactNode })
useEffect((): void => {
if (session.isConnected) {
// Pas de router.push dans Electron, le main process gère
if (!window.electron) {
window.location.href = '/';
}
tauri.loginSuccess();
}
}, [session]);

View File

@@ -2,17 +2,16 @@ import {useContext, useState} from "react";
import System from "@/lib/models/System";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faEnvelope, faLock} from "@fortawesome/free-solid-svg-icons";
import {SessionContext, SessionContextProps} from "@/context/SessionContext";
import {AlertContext} from "@/context/AlertContext";
import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext";
import * as tauri from '@/lib/tauri';
export default function LoginForm() {
const {errorMessage} = useContext(AlertContext);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
const {setSession} = useContext<SessionContextProps>(SessionContext);
const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext)
@@ -48,21 +47,8 @@ export default function LoginForm() {
setIsLoading(false);
return;
}
// Stocker le token dans electron-store via IPC
if (window.electron) {
await window.electron.setToken(response);
window.electron.loginSuccess(response);
} else {
// Fallback pour le mode dev web
System.setCookie('token', response, 30);
const token: string | null = System.getCookie('token');
if (!token) {
errorMessage(t('loginForm.error.connection'));
setIsLoading(false);
return;
}
setSession({isConnected: true, user: null, accessToken: token})
}
await tauri.setToken(response);
await tauri.loginSuccess();
} catch (e: unknown) {
if (e instanceof Error) {
errorMessage(t('loginForm.error.server'));

View File

@@ -4,60 +4,44 @@ import React, {useContext, useEffect} from "react";
import System from "@/lib/models/System";
import {AlertContext} from "@/context/AlertContext";
import {configs} from "@/lib/configs";
import {SessionContext, SessionContextProps} from "@/context/SessionContext";
import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext";
import * as tauri from '@/lib/tauri';
export default function SocialForm() {
const {errorMessage} = useContext(AlertContext);
const {setSession} = useContext<SessionContextProps>(SessionContext)
const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext)
const isElectron = typeof window !== 'undefined' && !!window.electron;
useEffect((): void => {
// Skip URL parsing in Electron (OAuth is handled via BrowserWindow)
if (isElectron) return;
const params = new URLSearchParams(window.location.search);
const provider: string | null = params.get('provider');
if (!provider) {
return;
}
if (!provider) return;
const code: string | null = params.get('code');
if (!code) {
return;
}
if (!code) return;
if (provider === 'google') {
handleGoogleLogin(code).then();
return;
}
if (provider === 'facebook') {
const state: string | null = params.get('state');
if (!state) {
return;
}
if (!state) return;
handleFacebookLogin(code, state).then();
return;
}
if (provider === 'apple') {
const state: string | null = params.get('state');
if (!state) {
return;
}
if (!state) return;
handleAppleLogin(code, state).then();
return;
}
}, []);
async function handleLoginSuccess(token: string): Promise<void> {
if (window.electron) {
await window.electron.setToken(token);
window.electron.loginSuccess(token);
} else {
System.setCookie('token', token, 30);
setSession({isConnected: true, user: null, accessToken: token});
}
await tauri.setToken(token);
await tauri.loginSuccess();
}
async function handleFacebookLogin(code: string, state: string): Promise<void> {
@@ -102,28 +86,10 @@ export default function SocialForm() {
}
async function handleOAuthClick(provider: 'google' | 'facebook' | 'apple'): Promise<void> {
if (!window.electron) return;
try {
const result = await window.electron.oauthLogin(provider, configs.baseUrl);
if (!result.success) {
if (result.error !== 'Window closed by user') {
errorMessage(t('socialForm.error.connection'));
}
return;
}
if (result.code) {
if (provider === 'google') {
await handleGoogleLogin(result.code);
} else if (provider === 'facebook' && result.state) {
await handleFacebookLogin(result.code, result.state);
} else if (provider === 'apple' && result.state) {
await handleAppleLogin(result.code, result.state);
}
}
} catch (error) {
const oauthUrl = `${configs.baseUrl}auth/${provider}/desktop`;
await tauri.openExternal(oauthUrl);
} catch {
errorMessage(t('socialForm.error.connection'));
}
}

View File

@@ -7,6 +7,7 @@ import SocialForm from "@/app/login/login/SocialForm";
import {useTranslations} from "next-intl";
import {LangContext} from "@/context/LangContext";
import System from "@/lib/models/System";
import * as tauri from '@/lib/tauri';
export default function LoginPage() {
const t = useTranslations();
@@ -22,21 +23,12 @@ export default function LoginPage() {
useEffect(() => {
async function checkFirstConnectionAndNetwork() {
// Check if we're in Electron
if (!window.electron) {
return;
}
try {
// Check if token exists (first connection)
const token = await window.electron.getToken();
const token = await tauri.getToken();
const hasToken = !!token;
// Check network status
const online = navigator.onLine;
setIsOnline(online);
// Show warning if first connection AND offline
if (!hasToken && !online) {
setShowOfflineWarning(true);
}
@@ -47,19 +39,19 @@ export default function LoginPage() {
checkFirstConnectionAndNetwork();
// Listen for online/offline events
const handleOnline = () => {
setIsOnline(true);
setShowOfflineWarning(false);
};
const handleOffline = async () => {
setIsOnline(false);
// Check if token exists
if (window.electron) {
const token = await window.electron.getToken();
try {
const token = await tauri.getToken();
if (!token) {
setShowOfflineWarning(true);
}
} catch {
setShowOfflineWarning(true);
}
};

View File

@@ -5,44 +5,32 @@ import OfflinePinVerify from '@/components/offline/OfflinePinVerify';
import { useTranslations } from 'next-intl';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faWifi, faArrowLeft } from '@fortawesome/free-solid-svg-icons';
import * as tauri from '@/lib/tauri';
export default function OfflineLoginPage() {
const t = useTranslations();
async function handlePinSuccess(userId: string):Promise<void> {
// Initialize database with user's encryption key
if (window.electron) {
try {
// Get encryption key
const encryptionKey = await window.electron.getUserEncryptionKey(userId);
if (encryptionKey) {
// Initialize database
await window.electron.dbInitialize(userId, encryptionKey);
// Navigate to main page
window.location.href = '/';
}
} catch (error) {
console.error('[OfflineLogin] Error initializing database:', error);
async function handlePinSuccess(userId: string): Promise<void> {
try {
const encryptionKey = await tauri.getUserEncryptionKey(userId);
if (encryptionKey) {
await tauri.dbInitialize(userId, encryptionKey);
await tauri.loginSuccess();
}
} catch (error) {
console.error('[OfflineLogin] Error initializing database:', error);
}
}
function handleBackToOnline():void {
if (window.electron) {
window.electron.logout();
}
function handleBackToOnline(): void {
tauri.logout();
}
useEffect(():void => {
// Check if we have offline capability
useEffect((): void => {
async function checkOfflineCapability() {
if (window.electron) {
const offlineStatus = await window.electron.offlineModeGet();
if (!offlineStatus.hasPin) {
window.location.href = '/login/login';
}
const offlineStatus = await tauri.offlineModeGet();
if (!offlineStatus.hasPin) {
window.location.href = '/login/login';
}
}