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)}>