perf: ♻️ FindInPage API

This commit is contained in:
viarotel 2024-05-13 22:49:39 +08:00
parent 6dd8244ed5
commit fcf8269e0e
13 changed files with 114 additions and 42 deletions

11
components.d.ts vendored
View File

@ -30,16 +30,6 @@ declare module 'vue' {
ElIcon: typeof import('element-plus/es')['ElIcon'] ElIcon: typeof import('element-plus/es')['ElIcon']
ElIconArrowDownBold: typeof import('@element-plus/icons-vue')['ArrowDownBold'] ElIconArrowDownBold: typeof import('@element-plus/icons-vue')['ArrowDownBold']
ElIconArrowUpBold: typeof import('@element-plus/icons-vue')['ArrowUpBold'] ElIconArrowUpBold: typeof import('@element-plus/icons-vue')['ArrowUpBold']
ElIconCaretLeft: typeof import('@element-plus/icons-vue')['CaretLeft']
ElIconCaretRight: typeof import('@element-plus/icons-vue')['CaretRight']
ElIconClose: typeof import('@element-plus/icons-vue')['Close']
ElIconCloseBold: typeof import('@element-plus/icons-vue')['CloseBold']
ElIconEditPen: typeof import('@element-plus/icons-vue')['EditPen']
ElIconLoading: typeof import('@element-plus/icons-vue')['Loading']
ElIconOperation: typeof import('@element-plus/icons-vue')['Operation']
ElIconQuestionFilled: typeof import('@element-plus/icons-vue')['QuestionFilled']
ElIconSelect: typeof import('@element-plus/icons-vue')['Select']
ElIconWarningFilled: typeof import('@element-plus/icons-vue')['WarningFilled']
ElInput: typeof import('element-plus/es')['ElInput'] ElInput: typeof import('element-plus/es')['ElInput']
ElLink: typeof import('element-plus/es')['ElLink'] ElLink: typeof import('element-plus/es')['ElLink']
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
@ -69,7 +59,6 @@ declare module 'vue' {
Remark: typeof import('./src/components/Device/components/Remark/index.vue')['default'] Remark: typeof import('./src/components/Device/components/Remark/index.vue')['default']
Rotation: typeof import('./src/components/Device/components/ControlBar/Rotation/index.vue')['default'] Rotation: typeof import('./src/components/Device/components/ControlBar/Rotation/index.vue')['default']
Screenshot: typeof import('./src/components/Device/components/ControlBar/Screenshot/index.vue')['default'] Screenshot: typeof import('./src/components/Device/components/ControlBar/Screenshot/index.vue')['default']
Search: typeof import('./src/components/Search/index.vue')['default']
TerminalAction: typeof import('./src/components/Device/components/TerminalAction/index.vue')['default'] TerminalAction: typeof import('./src/components/Device/components/TerminalAction/index.vue')['default']
TerminalDialog: typeof import('./src/components/Device/components/TerminalAction/components/TerminalDialog/index.vue')['default'] TerminalDialog: typeof import('./src/components/Device/components/TerminalAction/components/TerminalDialog/index.vue')['default']
VideoCodecSelect: typeof import('./src/components/Preference/components/VideoCodecSelect/index.vue')['default'] VideoCodecSelect: typeof import('./src/components/Preference/components/VideoCodecSelect/index.vue')['default']

View File

@ -1,11 +1,9 @@
import fs from 'fs-extra' import fs from 'fs-extra'
import { dialog, ipcMain, shell } from 'electron' import { dialog, ipcMain, shell } from 'electron'
import themeHandles from './theme/index.js' import themeHandles from './theme/index.js'
import searchHandles from './search/index.js'
export default (mainWindow) => { export default (mainWindow) => {
themeHandles(mainWindow) themeHandles(mainWindow)
searchHandles(mainWindow)
ipcMain.handle( ipcMain.handle(
'show-open-dialog', 'show-open-dialog',

View File

@ -1,12 +0,0 @@
import { ipcMain } from 'electron'
export default (mainWindow) => {
ipcMain.handle('find-in-page', async (_, { text, ...args } = {}) => {
return mainWindow.webContents.findInPage(text, {
...args,
})
})
ipcMain.handle('stop-find-in-page', async (_, action = 'clearSelection') => {
return mainWindow.webContents.stopFindInPage(action)
})
}

View File

@ -3,6 +3,7 @@ import { app, ipcMain } from 'electron'
import updater from './updater/index.js' import updater from './updater/index.js'
import handles from './handles/index.js' import handles from './handles/index.js'
import tray from './tray/index.js' import tray from './tray/index.js'
// import search from './search/index.js'
export default (mainWindow) => { export default (mainWindow) => {
ipcMain.on('restart-app', () => { ipcMain.on('restart-app', () => {
@ -10,7 +11,9 @@ export default (mainWindow) => {
app.relaunch() app.relaunch()
app.quit() app.quit()
}) })
handles(mainWindow) handles(mainWindow)
updater(mainWindow) updater(mainWindow)
tray(mainWindow) tray(mainWindow)
// search(mainWindow)
} }

View File

@ -0,0 +1,40 @@
export class FindInPageManager {
constructor(webContents) {
this.webContents = webContents
this.text = ''
}
update({ webContents } = {}) {
this.webContents = webContents
}
async start({ text, args = {} } = {}) {
this.text = text
this.webContents.on('found-in-page', (event, result) => {
console.log('found-in-page.result', result)
})
return this.webContents.findInPage(this.text, { findNext: false, ...args })
}
async next({ ...args } = {}) {
return this.webContents.findInPage(this.text, {
forward: true,
findNext: true,
...args,
})
}
async prev({ ...args } = {}) {
return this.webContents.findInPage(this.text, {
forward: false,
findNext: true,
...args,
})
}
async stop(action = 'clearSelection') {
return this.webContents.stopFindInPage(action)
}
}

View File

@ -0,0 +1,29 @@
import { globalShortcut, ipcMain } from 'electron'
import { FindInPageManager } from './helper.js'
export default (mainWindow) => {
mainWindow.on('focus', () => {
globalShortcut.register('CommandOrControl+F', (event) => {
mainWindow.webContents.send('focus-on-search')
})
})
mainWindow.on('blur', () => {
globalShortcut.unregister('CommandOrControl+F')
})
const findInPageManager = new FindInPageManager(mainWindow.webContents)
ipcMain.handle('findInPageStart', async (event, args = {}) => {
return findInPageManager.start(args)
})
ipcMain.handle('findInPageNext', async (event, args = {}) => {
return findInPageManager.next(args)
})
ipcMain.handle('findInPagePrev', async (event, args = {}) => {
return findInPageManager.prev(args)
})
ipcMain.handle('findInPageStop', async (event, args = {}) => {
return findInPageManager.stop(args)
})
}

View File

@ -45,6 +45,7 @@ export default antfu(
'no-restricted-syntax': 'off', 'no-restricted-syntax': 'off',
'no-new': 'off', 'no-new': 'off',
'prefer-promise-reject-errors': 'off', 'prefer-promise-reject-errors': 'off',
'no-unused-expressions': 'off',
'vue/html-self-closing': 'off', 'vue/html-self-closing': 'off',
'vue/block-order': 'off', 'vue/block-order': 'off',

View File

@ -21,6 +21,8 @@
"prepare": "husky install" "prepare": "husky install"
}, },
"dependencies": { "dependencies": {
"electron-find-in-page": "^1.0.8",
"electron-in-page-search": "^1.3.2",
"vue": "^3.4.26" "vue": "^3.4.26"
}, },
"devDependencies": { "devDependencies": {
@ -35,7 +37,7 @@
"@viarotel-org/unocss-preset-shades": "^0.8.2", "@viarotel-org/unocss-preset-shades": "^0.8.2",
"@vitejs/plugin-vue": "^5.0.4", "@vitejs/plugin-vue": "^5.0.4",
"dayjs": "^1.11.11", "dayjs": "^1.11.11",
"electron": "^30.0.2", "electron": "^30.0.3",
"electron-builder": "^24.13.3", "electron-builder": "^24.13.3",
"electron-context-menu": "^4.0.0", "electron-context-menu": "^4.0.0",
"electron-log": "^5.1.2", "electron-log": "^5.1.2",

View File

@ -3,9 +3,9 @@
<el-tabs <el-tabs
v-model="activeTab" v-model="activeTab"
class="el-tabs-flex" class="el-tabs-flex"
addable
@tab-change="onTabChange" @tab-change="onTabChange"
> >
<!-- addable -->
<template #add-icon> <template #add-icon>
<AppSearch /> <AppSearch />
</template> </template>

View File

@ -1,31 +1,35 @@
<template> <template>
<div class="absolute -bottom-1 right-0 z-10"> <div class="absolute -bottom-[5px] right-0 z-10">
<el-input <el-input
ref="elInputRef" ref="elInputRef"
v-model="keyword" v-model="keyword"
prefix-icon="Search" prefix-icon="Search"
placeholder="搜索" :placeholder="$t('common.search')"
clearable clearable
class="transition-all overflow-hidden" class="transition-all overflow-hidden"
:class="activated || keyword ? '!w-96' : '!w-24'" :class="activated || keyword ? '!w-96' : '!w-26'"
@focus="onFocus" @focus="onFocus"
@blur="onBlur" @blur="onBlur"
@input="onInput" @change="onChange"
@clear="onClear" @clear="onClear"
> >
<template v-if="keyword" #append> <template v-if="keyword" #append>
<div <div class="flex flex-col size-full absolute inset-0 justify-center">
class="flex flex-col size-full absolute inset-0 justify-center items-center" <div
> class="flex-1 h-0 flex items-end justify-center apply-search-button"
<div class="flex-1 h-0 flex items-end"> @click="handlePrev"
>
<el-icon size="12"> <el-icon size="12">
<ElIconArrowUpBold /> <ElIconArrowUpBold />
</el-icon> </el-icon>
</div> </div>
<div class="h-px w-full border-[0.5px] border-gray-200"></div> <div class="h-px w-full bg-gray-200 dark:bg-gray-600"></div>
<div class="flex-1 h-0 flex items-start"> <div
class="flex-1 h-0 flex items-start justify-center apply-search-button"
@click="handleNext"
>
<el-icon size="12"> <el-icon size="12">
<ElIconArrowDownBold /> <ElIconArrowDownBold />
</el-icon> </el-icon>
@ -55,20 +59,35 @@ function onBlur() {
} }
function onClear() { function onClear() {
window.electron.ipcRenderer.invoke('stop-find-in-page', 'clearSelection') window.electron.ipcRenderer.invoke('findInPageStop')
} }
function onInput(value) { async function onChange(value) {
if (!value) { if (!value) {
onClear() onClear()
return false return false
} }
window.electron.ipcRenderer.invoke('find-in-page', { window.electron.ipcRenderer.invoke('findInPageStart', {
text: value, text: value,
findNext: true,
}) })
} }
function handlePrev() {
window.electron.ipcRenderer.invoke('findInPagePrev')
}
function handleNext() {
window.electron.ipcRenderer.invoke('findInPageNext')
}
window.electron.ipcRenderer.on('focus-on-search', (event, ret) => {
handleFocus()
})
</script> </script>
<style></style> <style lang="postcss">
.apply-search-button {
@apply hover:bg-gray-200 dark:hover:bg-gray-700 !active:bg-gray-300 !dark:active:bg-gray-600 !active:text-primary-500;
}
</style>

View File

@ -9,6 +9,7 @@
"common.success": "Operation successful", "common.success": "Operation successful",
"common.progress": "Starting", "common.progress": "Starting",
"common.loading": "Loading", "common.loading": "Loading",
"common.search": "Search",
"common.language.name": "Language", "common.language.name": "Language",
"common.language.placeholder": "Select language", "common.language.placeholder": "Select language",

View File

@ -9,6 +9,7 @@
"common.success": "操作成功", "common.success": "操作成功",
"common.progress": "启动中", "common.progress": "启动中",
"common.loading": "加载中", "common.loading": "加载中",
"common.search": "搜索",
"common.language.name": "语言", "common.language.name": "语言",
"common.language.placeholder": "选择你需要的语言", "common.language.placeholder": "选择你需要的语言",

View File

@ -9,6 +9,7 @@
"common.success": "操作成功", "common.success": "操作成功",
"common.progress": "啟動中", "common.progress": "啟動中",
"common.loading": "載入中", "common.loading": "載入中",
"common.search": "搜尋",
"common.language.name": "語言", "common.language.name": "語言",
"common.language.placeholder": "選擇你要的語言", "common.language.placeholder": "選擇你要的語言",