mirror of
https://github.com/yang991178/fluent-reader.git
synced 2025-03-17 11:50:06 +01:00
add link context menu
This commit is contained in:
parent
aeb1b95975
commit
52e0c1b90c
@ -49,10 +49,10 @@ const utilsBridge = {
|
||||
callback(pos, text)
|
||||
})
|
||||
},
|
||||
addWebviewContextListener: (callback: (pos: [number, number], text: string) => any) => {
|
||||
addWebviewContextListener: (callback: (pos: [number, number], text: string, url: string) => any) => {
|
||||
ipcRenderer.removeAllListeners("webview-context-menu")
|
||||
ipcRenderer.on("webview-context-menu", (_, pos, text) => {
|
||||
callback(pos, text)
|
||||
ipcRenderer.on("webview-context-menu", (_, pos, text, url) => {
|
||||
callback(pos, text, url)
|
||||
})
|
||||
},
|
||||
imageCallback: (type: ImageCallbackTypes) => {
|
||||
|
@ -19,7 +19,7 @@ type ArticleProps = {
|
||||
toggleHasRead: (item: RSSItem) => void
|
||||
toggleStarred: (item: RSSItem) => void
|
||||
toggleHidden: (item: RSSItem) => void
|
||||
textMenu: (text: string, position: [number, number]) => void
|
||||
textMenu: (position: [number, number], text: string, url: string) => void
|
||||
imageMenu: (position: [number, number]) => void
|
||||
dismissContextMenu: () => void
|
||||
}
|
||||
@ -95,9 +95,9 @@ class Article extends React.Component<ArticleProps, ArticleState> {
|
||||
]
|
||||
})
|
||||
|
||||
contextMenuHandler = (pos: [number, number], text: string) => {
|
||||
contextMenuHandler = (pos: [number, number], text: string, url: string) => {
|
||||
if (pos) {
|
||||
if (text) this.props.textMenu(text, pos)
|
||||
if (text || url) this.props.textMenu(pos, text, url)
|
||||
else this.props.imageMenu(pos)
|
||||
} else {
|
||||
this.props.dismissContextMenu()
|
||||
|
@ -16,6 +16,7 @@ export type ContextMenuProps = ContextReduxProps & {
|
||||
item?: RSSItem
|
||||
feedId?: string
|
||||
text?: string
|
||||
url?: string
|
||||
viewType?: ViewType
|
||||
filter?: FilterType
|
||||
sids?: number[]
|
||||
@ -143,15 +144,41 @@ export class ContextMenu extends React.Component<ContextMenuProps> {
|
||||
onClick: () => { window.utils.writeClipboard(this.props.item.link) }
|
||||
}
|
||||
]
|
||||
case ContextMenuType.Text: return [
|
||||
{
|
||||
key: "copyText",
|
||||
text: intl.get("context.copy"),
|
||||
iconProps: { iconName: "Copy" },
|
||||
onClick: () => { window.utils.writeClipboard(this.props.text) }
|
||||
},
|
||||
getSearchItem(this.props.text)
|
||||
]
|
||||
case ContextMenuType.Text: {
|
||||
const items: IContextualMenuItem[] = this.props.text? [
|
||||
{
|
||||
key: "copyText",
|
||||
text: intl.get("context.copy"),
|
||||
iconProps: { iconName: "Copy" },
|
||||
onClick: () => { window.utils.writeClipboard(this.props.text) }
|
||||
},
|
||||
getSearchItem(this.props.text)
|
||||
] : []
|
||||
if (this.props.url) {
|
||||
items.push({
|
||||
key: "urlSection",
|
||||
itemType: ContextualMenuItemType.Section,
|
||||
sectionProps: {
|
||||
topDivider: items.length > 0,
|
||||
items: [
|
||||
{
|
||||
key: "openInBrowser",
|
||||
text: intl.get("openExternal"),
|
||||
iconProps: { iconName: "NavigateExternalInline" },
|
||||
onClick: (e) => { window.utils.openExternal(this.props.url, platformCtrl(e)) }
|
||||
},
|
||||
{
|
||||
key: "copyURL",
|
||||
text: intl.get("context.copyURL"),
|
||||
iconProps: { iconName: "Link" },
|
||||
onClick: () => { window.utils.writeClipboard(this.props.url) }
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
return items
|
||||
}
|
||||
case ContextMenuType.Image: return [
|
||||
{
|
||||
key: "openInBrowser",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as React from "react"
|
||||
import { connect } from 'react-redux'
|
||||
import { ContextMenuContainer } from "../containers/context-menu-container"
|
||||
import { closeContextMenu, openTextMenu } from "../scripts/models/app"
|
||||
import { closeContextMenu } from "../scripts/models/app"
|
||||
import PageContainer from "../containers/page-container"
|
||||
import MenuContainer from "../containers/menu-container"
|
||||
import NavContainer from "../containers/nav-container"
|
||||
|
@ -34,7 +34,7 @@ const mapDispatchToProps = (dispatch: AppDispatch) => {
|
||||
toggleHasRead: (item: RSSItem) => dispatch(item.hasRead ? markUnread(item) : markRead(item)),
|
||||
toggleStarred: (item: RSSItem) => dispatch(toggleStarred(item)),
|
||||
toggleHidden: (item: RSSItem) => dispatch(toggleHidden(item)),
|
||||
textMenu: (text: string, position: [number, number]) => dispatch(openTextMenu(text, position)),
|
||||
textMenu: (position: [number, number], text: string, url: string) => dispatch(openTextMenu(position, text, url)),
|
||||
imageMenu: (position: [number, number]) => dispatch(openImageMenu(position)),
|
||||
dismissContextMenu: () => dispatch(closeContextMenu())
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ const mapStateToProps = createSelector(
|
||||
case ContextMenuType.Text: return {
|
||||
type: context.type,
|
||||
position: context.position,
|
||||
text: context.target as string
|
||||
text: context.target[0],
|
||||
url: context.target[1]
|
||||
}
|
||||
case ContextMenuType.View: return {
|
||||
type: context.type,
|
||||
|
@ -23,7 +23,7 @@ const store = createStore(
|
||||
store.dispatch(initApp())
|
||||
|
||||
window.utils.addMainContextListener((pos, text) => {
|
||||
store.dispatch(openTextMenu(text, pos))
|
||||
store.dispatch(openTextMenu(pos, text))
|
||||
})
|
||||
|
||||
ReactDOM.render(
|
||||
|
@ -110,7 +110,7 @@ export function setUtilsListeners(manager: WindowManager) {
|
||||
}
|
||||
})
|
||||
contents.on("context-menu", (_, params) => {
|
||||
if ((params.hasImageContents || params.selectionText) && manager.hasWindow()) {
|
||||
if ((params.hasImageContents || params.selectionText || params.linkURL) && manager.hasWindow()) {
|
||||
if (params.hasImageContents) {
|
||||
ipcMain.removeHandler("image-callback")
|
||||
ipcMain.handleOnce("image-callback", (_, type: ImageCallbackTypes) => {
|
||||
@ -132,7 +132,7 @@ export function setUtilsListeners(manager: WindowManager) {
|
||||
})
|
||||
manager.mainWindow.webContents.send("webview-context-menu", [params.x, params.y])
|
||||
} else {
|
||||
manager.mainWindow.webContents.send("webview-context-menu", [params.x, params.y], params.selectionText)
|
||||
manager.mainWindow.webContents.send("webview-context-menu", [params.x, params.y], params.selectionText, params.linkURL)
|
||||
}
|
||||
contents.executeJavaScript(`new Promise(resolve => {
|
||||
const dismiss = () => {
|
||||
|
@ -61,7 +61,7 @@ export class AppState {
|
||||
type: ContextMenuType,
|
||||
event?: MouseEvent | string,
|
||||
position?: [number, number],
|
||||
target?: [RSSItem, string] | number[] | string
|
||||
target?: [RSSItem, string] | number[] | [string, string]
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@ -92,7 +92,7 @@ interface OpenItemMenuAction {
|
||||
interface OpenTextMenuAction {
|
||||
type: typeof OPEN_TEXT_MENU
|
||||
position: [number, number]
|
||||
item: string
|
||||
item: [string, string]
|
||||
}
|
||||
|
||||
interface OpenViewMenuAction {
|
||||
@ -153,11 +153,11 @@ export function openItemMenu(item: RSSItem, feedId: string, event: React.MouseEv
|
||||
}
|
||||
}
|
||||
|
||||
export function openTextMenu(text: string, position: [number, number]): ContextMenuActionTypes {
|
||||
export function openTextMenu(position: [number, number], text: string, url: string = null): ContextMenuActionTypes {
|
||||
return {
|
||||
type: OPEN_TEXT_MENU,
|
||||
position: position,
|
||||
item: text
|
||||
item: [text, url]
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user