feat: Basic general context menu
All checks were successful
Queue Release Build / prepare (push) Successful in 14s
Deploy Web Apps / deploy (push) Successful in 14m39s
Queue Release Build / build-linux (push) Successful in 40m59s
Queue Release Build / build-windows (push) Successful in 28m59s
Queue Release Build / finalize (push) Successful in 1m58s
All checks were successful
Queue Release Build / prepare (push) Successful in 14s
Deploy Web Apps / deploy (push) Successful in 14m39s
Queue Release Build / build-linux (push) Successful in 40m59s
Queue Release Build / build-windows (push) Successful in 28m59s
Queue Release Build / finalize (push) Successful in 1m58s
This commit is contained in:
@@ -4,6 +4,8 @@ import {
|
||||
desktopCapturer,
|
||||
dialog,
|
||||
ipcMain,
|
||||
nativeImage,
|
||||
net,
|
||||
Notification,
|
||||
shell
|
||||
} from 'electron';
|
||||
@@ -503,4 +505,34 @@ export function setupSystemHandlers(): void {
|
||||
await fsp.mkdir(dirPath, { recursive: true });
|
||||
return true;
|
||||
});
|
||||
|
||||
ipcMain.handle('copy-image-to-clipboard', (_event, srcURL: string) => {
|
||||
if (typeof srcURL !== 'string' || !srcURL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return new Promise<boolean>((resolve) => {
|
||||
const request = net.request(srcURL);
|
||||
|
||||
request.on('response', (response) => {
|
||||
const chunks: Buffer[] = [];
|
||||
|
||||
response.on('data', (chunk) => chunks.push(chunk));
|
||||
response.on('end', () => {
|
||||
const image = nativeImage.createFromBuffer(Buffer.concat(chunks));
|
||||
|
||||
if (!image.isEmpty()) {
|
||||
clipboard.writeImage(image);
|
||||
resolve(true);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
response.on('error', () => resolve(false));
|
||||
});
|
||||
|
||||
request.on('error', () => resolve(false));
|
||||
request.end();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -124,6 +124,22 @@ function readLinuxDisplayServer(): string {
|
||||
}
|
||||
}
|
||||
|
||||
export interface ContextMenuParams {
|
||||
posX: number;
|
||||
posY: number;
|
||||
isEditable: boolean;
|
||||
selectionText: string;
|
||||
linkURL: string;
|
||||
mediaType: string;
|
||||
srcURL: string;
|
||||
editFlags: {
|
||||
canCut: boolean;
|
||||
canCopy: boolean;
|
||||
canPaste: boolean;
|
||||
canSelectAll: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ElectronAPI {
|
||||
linuxDisplayServer: string;
|
||||
minimizeWindow: () => void;
|
||||
@@ -194,6 +210,9 @@ export interface ElectronAPI {
|
||||
deleteFile: (filePath: string) => Promise<boolean>;
|
||||
ensureDir: (dirPath: string) => Promise<boolean>;
|
||||
|
||||
onContextMenu: (listener: (params: ContextMenuParams) => void) => () => void;
|
||||
copyImageToClipboard: (srcURL: string) => Promise<boolean>;
|
||||
|
||||
command: <T = unknown>(command: Command) => Promise<T>;
|
||||
query: <T = unknown>(query: Query) => Promise<T>;
|
||||
}
|
||||
@@ -299,6 +318,19 @@ const electronAPI: ElectronAPI = {
|
||||
deleteFile: (filePath) => ipcRenderer.invoke('delete-file', filePath),
|
||||
ensureDir: (dirPath) => ipcRenderer.invoke('ensure-dir', dirPath),
|
||||
|
||||
onContextMenu: (listener) => {
|
||||
const wrappedListener = (_event: Electron.IpcRendererEvent, params: ContextMenuParams) => {
|
||||
listener(params);
|
||||
};
|
||||
|
||||
ipcRenderer.on('show-context-menu', wrappedListener);
|
||||
|
||||
return () => {
|
||||
ipcRenderer.removeListener('show-context-menu', wrappedListener);
|
||||
};
|
||||
},
|
||||
copyImageToClipboard: (srcURL) => ipcRenderer.invoke('copy-image-to-clipboard', srcURL),
|
||||
|
||||
command: (command) => ipcRenderer.invoke('cqrs:command', command),
|
||||
query: (query) => ipcRenderer.invoke('cqrs:query', query)
|
||||
};
|
||||
|
||||
@@ -264,6 +264,24 @@ export async function createWindow(): Promise<void> {
|
||||
|
||||
emitWindowState();
|
||||
|
||||
mainWindow.webContents.on('context-menu', (_event, params) => {
|
||||
mainWindow?.webContents.send('show-context-menu', {
|
||||
posX: params.x,
|
||||
posY: params.y,
|
||||
isEditable: params.isEditable,
|
||||
selectionText: params.selectionText,
|
||||
linkURL: params.linkURL,
|
||||
mediaType: params.mediaType,
|
||||
srcURL: params.srcURL,
|
||||
editFlags: {
|
||||
canCut: params.editFlags.canCut,
|
||||
canCopy: params.editFlags.canCopy,
|
||||
canPaste: params.editFlags.canPaste,
|
||||
canSelectAll: params.editFlags.canSelectAll
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||
shell.openExternal(url);
|
||||
return { action: 'deny' };
|
||||
|
||||
Reference in New Issue
Block a user