00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Dialog Nativi

Il modulo dialog di Electron fornisce accesso ai dialog nativi del sistema operativo: finestre per aprire file, salvare file, mostrare messaggi e selezionare cartelle.

Importare il Modulo

const { dialog } = require('electron');

Il modulo dialog è disponibile solo nel Main Process. Per usarlo dal renderer, devi passare attraverso IPC.

Dialog Apri File

async function openFileDialog(parentWindow) {
  const result = await dialog.showOpenDialog(parentWindow, {
    title: 'Seleziona un file',
    defaultPath: app.getPath('documents'),
    buttonLabel: 'Apri',

    // Filtri per tipo di file
    filters: [
      { name: 'Documenti di testo', extensions: ['txt', 'md'] },
      { name: 'JavaScript', extensions: ['js', 'ts', 'jsx', 'tsx'] },
      { name: 'Immagini', extensions: ['png', 'jpg', 'jpeg', 'gif', 'svg'] },
      { name: 'Tutti i file', extensions: ['*'] },
    ],

    // Proprietà
    properties: [
      'openFile',            // Permetti selezione file
    ],
  });

  if (result.canceled) return null;
  return result.filePaths[0];
}

Proprietà Disponibili

properties: [
  'openFile',          // Permetti selezione file
  'openDirectory',     // Permetti selezione cartelle
  'multiSelections',   // Permetti selezione multipla
  'showHiddenFiles',   // Mostra file nascosti
  'createDirectory',   // Permetti creazione cartelle (macOS)
  'promptToCreate',    // Chiedi di creare file inesistenti (Windows)
  'noResolveAliases',  // Non risolvere i link simbolici (macOS)
  'treatPackageAsDirectory', // Tratta i .app come cartelle (macOS)
  'dontAddToRecent',   // Non aggiungere ai file recenti (Windows)
],

Selezione Multipla

async function openMultipleFiles(parentWindow) {
  const result = await dialog.showOpenDialog(parentWindow, {
    title: 'Seleziona i file',
    properties: ['openFile', 'multiSelections'],
    filters: [
      { name: 'Immagini', extensions: ['png', 'jpg', 'gif'] },
    ],
  });

  if (result.canceled) return [];
  return result.filePaths; // Array di percorsi
}

Seleziona Cartella

async function selectFolder(parentWindow) {
  const result = await dialog.showOpenDialog(parentWindow, {
    title: 'Seleziona cartella del progetto',
    properties: ['openDirectory', 'createDirectory'],
  });

  if (result.canceled) return null;
  return result.filePaths[0];
}

Dialog Salva File

async function saveFileDialog(parentWindow, defaultName) {
  const result = await dialog.showSaveDialog(parentWindow, {
    title: 'Salva il file',
    defaultPath: path.join(app.getPath('documents'), defaultName || 'documento.txt'),
    buttonLabel: 'Salva',
    filters: [
      { name: 'File di testo', extensions: ['txt'] },
      { name: 'Markdown', extensions: ['md'] },
      { name: 'JSON', extensions: ['json'] },
    ],
    properties: [
      'showOverwriteConfirmation',  // Chiedi conferma sovrascrittura
    ],
  });

  if (result.canceled) return null;
  return result.filePath;
}

Dialog Messaggi

Messaggio Informativo

await dialog.showMessageBox(parentWindow, {
  type: 'info',
  title: 'Informazione',
  message: 'Operazione completata con successo!',
  detail: 'Il file è stato salvato in Documents/progetto.',
  buttons: ['OK'],
});

Messaggio di Errore

await dialog.showMessageBox(parentWindow, {
  type: 'error',
  title: 'Errore',
  message: 'Impossibile salvare il file',
  detail: 'Controlla i permessi della cartella e riprova.',
  buttons: ['OK'],
});

Conferma con Scelte

const result = await dialog.showMessageBox(parentWindow, {
  type: 'question',
  title: 'Conferma eliminazione',
  message: 'Sei sicuro di voler eliminare questo file?',
  detail: 'Questa azione non può essere annullata.',
  buttons: ['Elimina', 'Annulla'],
  defaultId: 1,       // "Annulla" selezionato di default
  cancelId: 1,        // ESC corrisponde a "Annulla"
  noLink: true,        // Non trasformare i bottoni in link (Windows)
});

if (result.response === 0) {
  // L'utente ha scelto "Elimina"
  deleteFile();
}

Dialog con Checkbox

const result = await dialog.showMessageBox(parentWindow, {
  type: 'warning',
  title: 'Attenzione',
  message: 'Vuoi procedere?',
  checkboxLabel: 'Non mostrare più questo messaggio',
  checkboxChecked: false,
  buttons: ['Procedi', 'Annulla'],
});

if (result.checkboxChecked) {
  // L'utente ha spuntato "Non mostrare più"
  savePreference('skipWarning', true);
}

Dialog Errore (Sincrono)

Per errori critici, usa il dialog sincrono che funziona anche prima che l’app sia pronta:

dialog.showErrorBox(
  'Errore critico',
  'L\'applicazione non può essere avviata. Verifica che tutti i file necessari siano presenti.'
);

Integrazione Completa con IPC

// main.js
ipcMain.handle('dialog:open', async (event, options) => {
  const win = BrowserWindow.fromWebContents(event.sender);
  const result = await dialog.showOpenDialog(win, options);
  if (result.canceled) return null;
  return result.filePaths;
});

ipcMain.handle('dialog:save', async (event, options) => {
  const win = BrowserWindow.fromWebContents(event.sender);
  const result = await dialog.showSaveDialog(win, options);
  if (result.canceled) return null;
  return result.filePath;
});

ipcMain.handle('dialog:message', async (event, options) => {
  const win = BrowserWindow.fromWebContents(event.sender);
  const result = await dialog.showMessageBox(win, options);
  return result.response;
});
// preload.js
contextBridge.exposeInMainWorld('dialog', {
  openFile: (filters) => ipcRenderer.invoke('dialog:open', {
    properties: ['openFile'],
    filters,
  }),
  openFolder: () => ipcRenderer.invoke('dialog:open', {
    properties: ['openDirectory'],
  }),
  saveFile: (defaultName, filters) => ipcRenderer.invoke('dialog:save', {
    defaultPath: defaultName,
    filters,
  }),
  showMessage: (options) => ipcRenderer.invoke('dialog:message', options),
});