194 lines
4.8 KiB
JavaScript
194 lines
4.8 KiB
JavaScript
const { app, BrowserWindow, ipcMain, dialog, Menu } = require('electron');
|
|
const path = require('path');
|
|
|
|
let mainWindow;
|
|
|
|
function createWindow() {
|
|
mainWindow = new BrowserWindow({
|
|
width: 1200,
|
|
height: 800,
|
|
minWidth: 900,
|
|
minHeight: 600,
|
|
webPreferences: {
|
|
nodeIntegration: false,
|
|
contextIsolation: true,
|
|
preload: path.join(__dirname, 'preload.js')
|
|
},
|
|
titleBarStyle: 'hiddenInset',
|
|
show: false
|
|
});
|
|
|
|
mainWindow.loadFile('index.html');
|
|
|
|
mainWindow.once('ready-to-show', () => {
|
|
mainWindow.show();
|
|
});
|
|
|
|
mainWindow.on('closed', () => {
|
|
mainWindow = null;
|
|
});
|
|
|
|
// Menu contestuale (tasto destro)
|
|
mainWindow.webContents.on('context-menu', (event, params) => {
|
|
const contextMenu = Menu.buildFromTemplate([
|
|
{
|
|
label: 'Taglia',
|
|
accelerator: 'CmdOrCtrl+X',
|
|
role: 'cut',
|
|
enabled: params.editFlags.canCut
|
|
},
|
|
{
|
|
label: 'Copia',
|
|
accelerator: 'CmdOrCtrl+C',
|
|
role: 'copy',
|
|
enabled: params.editFlags.canCopy
|
|
},
|
|
{
|
|
label: 'Incolla',
|
|
accelerator: 'CmdOrCtrl+V',
|
|
role: 'paste',
|
|
enabled: params.editFlags.canPaste
|
|
},
|
|
{
|
|
label: 'Seleziona tutto',
|
|
accelerator: 'CmdOrCtrl+A',
|
|
role: 'selectAll',
|
|
enabled: params.editFlags.canSelectAll
|
|
},
|
|
{ type: 'separator' },
|
|
{
|
|
label: 'Elimina',
|
|
role: 'delete',
|
|
enabled: params.editFlags.canDelete
|
|
}
|
|
]);
|
|
contextMenu.popup(mainWindow);
|
|
});
|
|
|
|
createMenu();
|
|
}
|
|
|
|
function createMenu() {
|
|
const template = [
|
|
{
|
|
label: 'File',
|
|
submenu: [
|
|
{
|
|
label: 'Esci',
|
|
accelerator: 'CmdOrCtrl+Q',
|
|
click: () => {
|
|
app.quit();
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
label: 'Impostazioni',
|
|
submenu: [
|
|
{
|
|
label: 'Configura Modello e URL',
|
|
accelerator: 'CmdOrCtrl+,',
|
|
click: () => {
|
|
mainWindow.webContents.send('open-settings');
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
label: 'Aiuto',
|
|
submenu: [
|
|
{
|
|
label: 'Informazioni',
|
|
click: () => {
|
|
dialog.showMessageBox(mainWindow, {
|
|
type: 'info',
|
|
title: 'Informazioni',
|
|
message: 'Traduttore AI',
|
|
detail: 'Applicazione desktop per traduzioni con modelli AI locali tramite Ollama.'
|
|
});
|
|
}
|
|
}
|
|
]
|
|
}
|
|
];
|
|
|
|
const menu = Menu.buildFromTemplate(template);
|
|
Menu.setApplicationMenu(menu);
|
|
}
|
|
|
|
app.whenReady().then(createWindow);
|
|
|
|
app.on('window-all-closed', () => {
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|
|
|
|
app.on('activate', () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
createWindow();
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('translate-text', async (event, { text, direction, model, baseUrl }) => {
|
|
try {
|
|
const sourceLang = direction === 'en-it' ? 'inglese' : 'italiano';
|
|
const targetLang = direction === 'en-it' ? 'italiano' : 'inglese';
|
|
|
|
// Usa 127.0.0.1 invece di localhost per evitare problemi IPv6
|
|
const cleanBaseUrl = baseUrl.replace('localhost', '127.0.0.1');
|
|
|
|
const response = await fetch(`${cleanBaseUrl}/api/generate`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
model: model,
|
|
prompt: `Traduci il seguente testo da ${sourceLang} a ${targetLang}. Rispondi SOLO con la traduzione, senza spiegazioni o commenti aggiuntivi:\n\n${text}`,
|
|
stream: false
|
|
})
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Errore HTTP: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
return { success: true, translation: data.response };
|
|
} catch (error) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
ipcMain.handle('get-models', async (event, baseUrl) => {
|
|
try {
|
|
// Assicurati che l'URL sia pulito e sostituisci localhost con 127.0.0.1 per evitare problemi IPv6
|
|
let cleanUrl = baseUrl.trim().replace(/\/$/, '');
|
|
cleanUrl = cleanUrl.replace('localhost', '127.0.0.1');
|
|
const fullUrl = `${cleanUrl}/api/tags`;
|
|
|
|
console.log('Richiesta modelli da:', fullUrl);
|
|
|
|
const response = await fetch(fullUrl, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
}
|
|
});
|
|
|
|
console.log('Risposta status:', response.status);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Errore HTTP: ${response.status} - ${response.statusText}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log('Modelli trovati:', data.models?.length || 0);
|
|
return { success: true, models: data.models || [] };
|
|
} catch (error) {
|
|
console.error('Errore in get-models:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|