From 4fb636e91c43b137b7866ca877b5ed40bcf41d6d Mon Sep 17 00:00:00 2001 From: AkiraFukushima Date: Sat, 14 Dec 2024 00:50:26 +0900 Subject: [PATCH 1/2] refs #5097 Add context menu to save images --- main/background.ts | 20 +++++++++++++++++++ .../components/timelines/FollowRequests.tsx | 20 +++++++++---------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/main/background.ts b/main/background.ts index e2a73e7b73..9b4893d660 100644 --- a/main/background.ts +++ b/main/background.ts @@ -39,6 +39,26 @@ let main: BrowserWindow = null await mainWindow.loadURL(`http://localhost:${port}/`) mainWindow.webContents.openDevTools() } + + mainWindow.webContents.on('context-menu', (_event, properties) => { + const contextMenu = Menu.buildFromTemplate([ + { + label: 'Select All', + click: () => { + mainWindow.webContents.selectAll() + } + }, + { + label: 'Save Image As', + visible: properties.mediaType === 'image', + click: () => { + console.log(properties.srcURL) + mainWindow.webContents.downloadURL(properties.srcURL) + } + } + ]) + contextMenu.popup({ window: mainWindow }) + }) })() app.on('window-all-closed', () => { diff --git a/renderer/components/timelines/FollowRequests.tsx b/renderer/components/timelines/FollowRequests.tsx index eceb86879d..d2bc534423 100644 --- a/renderer/components/timelines/FollowRequests.tsx +++ b/renderer/components/timelines/FollowRequests.tsx @@ -54,17 +54,15 @@ export default function FollowRequests(props: Props) {
{requests.map(r => ( - <> - { - const data = await refreshRequests() - updateUnreads(data.length) - }} - /> - + { + const data = await refreshRequests() + updateUnreads(data.length) + }} + /> ))}
From ec3007da6c5f941f663bc126979a22288009f20c Mon Sep 17 00:00:00 2001 From: AkiraFukushima Date: Sat, 14 Dec 2024 01:24:41 +0900 Subject: [PATCH 2/2] Implement context menu in background side --- main/background.ts | 52 ++++++++++++++++++- .../components/timelines/status/Status.tsx | 30 +---------- 2 files changed, 52 insertions(+), 30 deletions(-) diff --git a/main/background.ts b/main/background.ts index 9b4893d660..144154972f 100644 --- a/main/background.ts +++ b/main/background.ts @@ -1,5 +1,5 @@ import path from 'path' -import { app, ipcMain, shell, IpcMainInvokeEvent, BrowserWindow, Menu } from 'electron' +import { app, ipcMain, shell, IpcMainInvokeEvent, BrowserWindow, Menu, clipboard } from 'electron' import serve from 'electron-serve' import { createWindow } from './helpers' import { menu } from './menu' @@ -41,6 +41,9 @@ let main: BrowserWindow = null } mainWindow.webContents.on('context-menu', (_event, properties) => { + const { editFlags } = properties + const hasText = properties.selectionText.length > 0 + const can = (type: string) => editFlags[`can${type}`] && hasText const contextMenu = Menu.buildFromTemplate([ { label: 'Select All', @@ -48,6 +51,43 @@ let main: BrowserWindow = null mainWindow.webContents.selectAll() } }, + { + label: 'Copy', + enabled: can('Copy'), + visible: properties.isEditable || hasText, + click: () => { + const target = mainWindow.webContents + if (target) { + target.copy() + } else { + clipboard.writeText(properties.selectionText) + } + } + }, + { + label: 'Cut', + enabled: can('Cut'), + visible: properties.isEditable || hasText, + click: () => { + const target = mainWindow.webContents + if (target) { + target.cut() + } else { + clipboard.writeText(properties.selectionText) + } + } + }, + { + label: 'Paste', + enabled: editFlags.canPaste, + visible: properties.isEditable, + click: () => { + const target = mainWindow.webContents + if (target) { + target.paste() + } + } + }, { label: 'Save Image As', visible: properties.mediaType === 'image', @@ -55,6 +95,16 @@ let main: BrowserWindow = null console.log(properties.srcURL) mainWindow.webContents.downloadURL(properties.srcURL) } + }, + { + label: 'Copy Link', + visible: properties.linkURL.length > 0 && properties.mediaType === 'none', + click: () => { + clipboard.write({ + bookmark: properties.linkText, + text: properties.linkURL + }) + } } ]) contextMenu.popup({ window: mainWindow }) diff --git a/renderer/components/timelines/status/Status.tsx b/renderer/components/timelines/status/Status.tsx index dde79f82c6..65ef5348e5 100644 --- a/renderer/components/timelines/status/Status.tsx +++ b/renderer/components/timelines/status/Status.tsx @@ -88,29 +88,6 @@ export default function Status(props: Props) { ) } - const onContextMenu: MouseEventHandler = e => { - e.preventDefault() - hideOthers() - const context = document.getElementById(`context-${props.status.id}`) - if (context) { - context.style.left = `${e.clientX}px` - context.style.top = `${e.clientY}px` - context.style.display = 'block' - } - } - - const onClick: MouseEventHandler = e => { - e.preventDefault() - hideOthers() - } - - const hideOthers = () => { - const menu = document.getElementsByClassName('context-menu') - for (let i = 0; i < menu.length; i++) { - ;(menu[i] as HTMLElement).style.display = 'none' - } - } - const copyLink = () => { navigator.clipboard.writeText(status.url) } @@ -141,12 +118,7 @@ export default function Status(props: Props) { )} /> -
+
openUser(status.account.id)}>