Skip to content

Latest commit

 

History

History
124 lines (106 loc) · 5.67 KB

File metadata and controls

124 lines (106 loc) · 5.67 KB

Electron Backend Integration Fix

Issue Identified

The backend functions weren't working in the native Electron app because the unifiedAPI.js was evaluating the Electron environment check at module load time instead of runtime.

Root Cause

In frontend/src/utils/unifiedAPI.js, line 40 had:

export const api = {
  isElectron: isElectron(),  // ❌ Called once when module loads
  // ...
}

When the frontend bundle is built by Vite, this code is evaluated during the build process or when the module first loads in the browser context. At that point, window.electronAPI doesn't exist yet, so isElectron() returns false. This cached value then persists throughout the app's lifetime, causing all API calls to route to the HTTP backend (localhost:3003) instead of using Electron IPC.

The Fix

Changed isElectron from a static property to a getter function:

export const api = {
  // Environment detection - use getter to make it dynamic
  get isElectron() {
    return isElectron();  // ✅ Called every time it's accessed
  },
  // ...
}

This ensures the Electron environment is checked dynamically at runtime, after the preload script has exposed window.electronAPI.

Additional Improvements

  1. Added debug logging to createGifFromImages() to help trace execution flow:

    console.log('🎬 Creating GIF from', files.length, 'images');
    console.log('📱 Running in Electron:', inElectron);
    console.log('🔧 window.electronAPI available:', typeof window !== 'undefined' && !!window.electronAPI);
  2. Already properly handled: The getApiUrl() function correctly returns empty string in Electron mode to prevent HTTP API calls.

  3. Already properly handled: The ImageEditor component has proper Electron detection for AI features that require backend.

How It Works Now

In Electron Desktop App:

  1. App loads from file:// protocol
  2. Preload script (electron/preload.js) exposes window.electronAPI
  3. When user creates a GIF:
    • api.isElectron getter is called → returns true
    • Routes to Electron IPC: window.electronAPI.createGifFromImages()
    • Main process handles conversion using Sharp + GIF Encoder
    • Returns file path to rendered image
    • No HTTP requests made ✅

In Browser Mode:

  1. App loads from http://localhost:3001 (or deployed URL)
  2. No window.electronAPI available
  3. When user creates a GIF:
    • api.isElectron getter is called → returns false
    • Routes to HTTP API: fetch('http://localhost:3003/api/...')
    • Backend server handles conversion
    • Returns blob response ✅

Files Modified

  • frontend/src/utils/unifiedAPI.js - Changed isElectron to getter, added debug logs

Testing Steps

  1. Rebuild frontend: npm run build:frontend
  2. Launch Electron app: npm run electron
  3. Try creating a GIF from images
  4. Check DevTools console for log messages showing Electron mode detection
  5. Verify GIF is created successfully without HTTP errors

Result

✅ Backend functions now work properly in the Electron desktop app ✅ All processing happens locally via IPC, not HTTP ✅ No need for backend server when running as desktop app ✅ Browser mode continues to work with HTTP backend

Architecture Summary

┌─────────────────────────────────────────┐
│         Frontend (React/Vite)           │
│  ┌─────────────────────────────────┐   │
│  │   unifiedAPI.js                 │   │
│  │                                 │   │
│  │  get isElectron() {            │   │
│  │    return isElectron();  ◄──────────── Dynamic check!
│  │  }                             │   │
│  │                                 │   │
│  │  createGifFromImages() {       │   │
│  │    if (isElectron()) {         │   │
│  │      → IPC                     │   │
│  │    } else {                     │   │
│  │      → HTTP                    │   │
│  │    }                            │   │
│  │  }                              │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘
           ↓                ↓
    [Electron IPC]   [HTTP Fetch]
           ↓                ↓
┌─────────────────┐  ┌──────────────┐
│  Electron Main  │  │   Backend    │
│  (main.js)      │  │   Server     │
│                 │  │  (Express)   │
│  • Sharp        │  │  • Sharp     │
│  • FFmpeg       │  │  • FFmpeg    │
│  • Canvas       │  │  • Canvas    │
└─────────────────┘  └──────────────┘

Related Files

  • electron/main.js - Electron IPC handlers for all operations
  • electron/preload.js - Exposes safe API to renderer
  • frontend/src/utils/unifiedAPI.js - Unified API client (FIXED)
  • frontend/src/components/*.jsx - Components using the API

Previous Architecture Issue

Before the fix, the app was trying to make HTTP requests to localhost:3003 even when running in Electron, which would either:

  1. Fail with network errors (if backend not running)
  2. Use the backend server unnecessarily (if it happened to be running)

Now it correctly uses IPC for true offline/local processing in desktop mode! 🎉