🐛 Fix(custom): fix memory leak issues

This commit is contained in:
Kuingsmile
2025-08-11 17:38:39 +08:00
parent 0bf435a0da
commit 1a35831301
16 changed files with 7505 additions and 7507 deletions

View File

@@ -1,14 +1,12 @@
import crypto from 'node:crypto' import crypto from 'node:crypto'
import path from 'node:path' import path from 'node:path'
import { clipboard, contextBridge, ipcRenderer, webFrame, webUtils } from 'electron' import { clipboard, contextBridge, ipcRenderer, IpcRendererEvent, webFrame, webUtils } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
import yaml from 'js-yaml' import yaml from 'js-yaml'
import mime from 'mime-types' import mime from 'mime-types'
import { isReactive, isRef, toRaw, unref } from 'vue' import { isReactive, isRef, toRaw, unref } from 'vue'
import type { IpcRendererListener } from '#/types/electron'
export const getRawData = (args: any): any => { export const getRawData = (args: any): any => {
if (isRef(args)) return unref(args) if (isRef(args)) return unref(args)
if (isReactive(args)) return toRaw(args) if (isReactive(args)) return toRaw(args)
@@ -52,11 +50,18 @@ try {
triggerRPC, triggerRPC,
sendToMain, sendToMain,
sendRPC, sendRPC,
ipcRendererOn: (channel: string, listener: IpcRendererListener) => { ipcRendererOn: (channel: string, listener: (...args: any[]) => void) => {
ipcRenderer.on(channel, listener) const subscription = (_: IpcRendererEvent, ...args: any[]) => listener(...args)
ipcRenderer.on(channel, subscription)
return () => {
ipcRenderer.removeListener(channel, subscription)
}
}, },
ipcRendererRemoveListener: (channel: string, listener: IpcRendererListener) => { ipcRendererCountListeners: (channel: string): number => {
ipcRenderer.removeListener(channel, listener) return ipcRenderer.listenerCount(channel)
},
ipcRendererRemoveAllListeners: (channel: string) => {
ipcRenderer.removeAllListeners(channel)
}, },
showFilePath (file: File) { showFilePath (file: File) {
return webUtils.getPathForFile(file) return webUtils.getPathForFile(file)

View File

@@ -50,7 +50,6 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { IpcRendererEvent } from 'electron'
import { X } from 'lucide-vue-next' import { X } from 'lucide-vue-next'
import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue' import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@@ -67,12 +66,9 @@ const inputBoxOptions = reactive({
placeholder: '' placeholder: ''
}) })
onBeforeMount(() => { let removeInputBoxListenerCallback: (() => void) = () => {}
window.electron.ipcRendererOn(SHOW_INPUT_BOX, ipcEventHandler)
$bus.on(SHOW_INPUT_BOX, initInputBoxValue)
})
function ipcEventHandler (_: IpcRendererEvent, options: IShowInputBoxOption) { function handleIpcInputBoxEvent (options: IShowInputBoxOption) {
initInputBoxValue(options) initInputBoxValue(options)
} }
@@ -96,16 +92,23 @@ function handleInputBoxConfirm () {
$bus.emit(SHOW_INPUT_BOX_RESPONSE, inputBoxValue.value) $bus.emit(SHOW_INPUT_BOX_RESPONSE, inputBoxValue.value)
} }
onBeforeMount(() => {
removeInputBoxListenerCallback = window.electron.ipcRendererOn(SHOW_INPUT_BOX, handleIpcInputBoxEvent)
$bus.on(SHOW_INPUT_BOX, initInputBoxValue)
})
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.electron.ipcRendererRemoveListener(SHOW_INPUT_BOX, ipcEventHandler) removeInputBoxListenerCallback()
$bus.off(SHOW_INPUT_BOX) $bus.off(SHOW_INPUT_BOX)
}) })
</script> </script>
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'InputBoxDialog' name: 'InputBoxDialog'
} }
</script> </script>
<style scoped> <style scoped>
.inputbox-overlay { .inputbox-overlay {
position: fixed; position: fixed;

View File

@@ -2,7 +2,10 @@
<nav class="navigation"> <nav class="navigation">
<div class="title-bar"> <div class="title-bar">
<div class="app-title"> <div class="app-title">
<div class="app-text"> <div
class="app-text"
@click="openGithubPage"
>
{{ t('app.title') }} {{ t('app.title') }}
</div> </div>
<div class="app-version"> <div class="app-version">
@@ -79,18 +82,6 @@
class="qr-dialog" class="qr-dialog"
@close="qrcodeVisible = false" @close="qrcodeVisible = false"
> >
<TransitionChild
as="template"
enter="duration-300 ease-out"
enter-from="opacity-0"
enter-to="opacity-100"
leave="duration-200 ease-in"
leave-from="opacity-100"
leave-to="opacity-0"
>
<div class="dialog-overlay" />
</TransitionChild>
<div class="dialog-container"> <div class="dialog-container">
<TransitionChild <TransitionChild
as="template" as="template"
@@ -217,7 +208,7 @@ import { pick } from 'lodash-es'
import { CheckIcon, ChevronDownIcon, CopyIcon, DatabaseIcon, FolderIcon, Info, PieChartIcon, PlugIcon, Settings, UploadIcon } from 'lucide-vue-next' import { CheckIcon, ChevronDownIcon, CopyIcon, DatabaseIcon, FolderIcon, Info, PieChartIcon, PlugIcon, Settings, UploadIcon } from 'lucide-vue-next'
import QrcodeVue from 'qrcode.vue' import QrcodeVue from 'qrcode.vue'
import pkg from 'root/package.json' import pkg from 'root/package.json'
import { computed, nextTick, onBeforeMount, reactive, Ref, ref, watch } from 'vue' import { computed, nextTick, onBeforeMount, onBeforeUnmount, reactive, Ref, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import useMessage from '@/hooks/useMessage' import useMessage from '@/hooks/useMessage'
@@ -237,6 +228,8 @@ const qrcodeVisible = ref(false)
const choosedPicBedForQRCode: Ref<string[]> = ref([]) const choosedPicBedForQRCode: Ref<string[]> = ref([])
const picBedConfigString = ref('') const picBedConfigString = ref('')
let removeIpcListener: () => void = () => {}
watch( watch(
() => choosedPicBedForQRCode, () => choosedPicBedForQRCode,
val => { val => {
@@ -280,9 +273,17 @@ const navigationItems = computed(() => [
} }
]) ])
function openGithubPage () {
window.electron.sendRPC(IRPCActionType.OPEN_URL, 'https://github.com/Kuingsmile/PicList')
}
onBeforeMount(() => { onBeforeMount(() => {
updatePicBedGlobal() updatePicBedGlobal()
window.electron.ipcRendererOn(SHOW_MAIN_PAGE_QRCODE, qrCodeHandler) removeIpcListener = window.electron.ipcRendererOn(SHOW_MAIN_PAGE_QRCODE, qrCodeHandler)
})
onBeforeUnmount(() => {
removeIpcListener()
}) })
</script> </script>
@@ -333,6 +334,11 @@ onBeforeMount(() => {
letter-spacing: -0.025em; letter-spacing: -0.025em;
} }
.app-text:hover {
cursor: pointer;
color: var(--color-blue-common);
}
.app-version { .app-version {
font-size: 10px; font-size: 10px;
font-weight: 500; font-weight: 500;
@@ -536,16 +542,11 @@ onBeforeMount(() => {
inset: 0; inset: 0;
z-index: 50; z-index: 50;
display: flex; display: flex;
overflow-y: auto;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.dialog-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
}
.dialog-container { .dialog-container {
position: fixed; position: fixed;
inset: 0; inset: 0;
@@ -561,7 +562,7 @@ onBeforeMount(() => {
.dialog-panel { .dialog-panel {
width: 100%; width: 100%;
max-width: 500px; max-width: 500px;
background: var(--color-surface); background: var(--color-background-primary);
border-radius: 16px; border-radius: 16px;
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
box-shadow: var(--shadow-md); box-shadow: var(--shadow-md);
@@ -634,11 +635,11 @@ onBeforeMount(() => {
right: 0; right: 0;
z-index: 10; z-index: 10;
margin-top: 4px; margin-top: 4px;
background: var(--color-surface); background: var(--color-background-primary);
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
border-radius: var(--border-radius); border-radius: var(--border-radius);
box-shadow: var(--shadow-md); box-shadow: var(--shadow-md);
max-height: 200px; max-height: 300px;
overflow-y: auto; overflow-y: auto;
} }

View File

@@ -74,7 +74,6 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import type { IpcRendererEvent } from 'electron'
import { MinusIcon, PinIcon, ShrinkIcon, XIcon } from 'lucide-vue-next' import { MinusIcon, PinIcon, ShrinkIcon, XIcon } from 'lucide-vue-next'
import { onBeforeMount, onBeforeUnmount, ref } from 'vue' import { onBeforeMount, onBeforeUnmount, ref } from 'vue'
@@ -100,7 +99,8 @@ function openMiniWindow () {
function closeWindow () { function closeWindow () {
window.electron.sendRPC(IRPCActionType.CLOSE_WINDOW) window.electron.sendRPC(IRPCActionType.CLOSE_WINDOW)
} }
const uploadProcessHandler = (_event: IpcRendererEvent, data: { progress: number }) => {
const uploadProcessHandler = (data: { progress: number }) => {
isShowprogress.value = data.progress !== 100 && data.progress !== 0 isShowprogress.value = data.progress !== 100 && data.progress !== 0
progress.value = data.progress progress.value = data.progress
} }
@@ -110,7 +110,7 @@ onBeforeMount(() => {
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.electron.ipcRendererRemoveListener('updateProgress', uploadProcessHandler) window.electron.ipcRendererRemoveAllListeners('updateProgress')
}) })
</script> </script>

View File

@@ -1550,7 +1550,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { IpcRendererEvent } from 'electron'
import { import {
ArrowUpDownIcon, ArrowUpDownIcon,
ChevronDownIcon, ChevronDownIcon,
@@ -2563,7 +2562,7 @@ async function handleFolderBatchDownload (item: any) {
const downloadFileTransferStore = useDownloadFileTransferStore() const downloadFileTransferStore = useDownloadFileTransferStore()
downloadFileTransferStore.resetDownloadFileTransferList() downloadFileTransferStore.resetDownloadFileTransferList()
window.electron.sendRPC(IRPCActionType.MANAGE_GET_BUCKET_LIST_RECURSIVELY, configMap.alias, paramGet) window.electron.sendRPC(IRPCActionType.MANAGE_GET_BUCKET_LIST_RECURSIVELY, configMap.alias, paramGet)
window.electron.ipcRendererOn(refreshDownloadFileTransferList, (_: IpcRendererEvent, data) => { window.electron.ipcRendererOn(refreshDownloadFileTransferList, (data) => {
downloadFileTransferStore.refreshDownloadFileTransferList(data) downloadFileTransferStore.refreshDownloadFileTransferList(data)
}) })
downloadInterval = setInterval(() => { downloadInterval = setInterval(() => {
@@ -2989,7 +2988,7 @@ async function getBucketFileListBackStage () {
param.webPath = configMap.webPath param.webPath = configMap.webPath
} }
window.electron.sendRPC(IRPCActionType.MANAGE_GET_BUCKET_LIST_BACKSTAGE, configMap.alias, param) window.electron.sendRPC(IRPCActionType.MANAGE_GET_BUCKET_LIST_BACKSTAGE, configMap.alias, param)
window.electron.ipcRendererOn('refreshFileTransferList', (_: IpcRendererEvent, data) => { window.electron.ipcRendererOn('refreshFileTransferList', (data) => {
fileTransferStore.refreshFileTransferList(data) fileTransferStore.refreshFileTransferList(data)
}) })
fileTransferInterval = setInterval(() => { fileTransferInterval = setInterval(() => {
@@ -3334,8 +3333,8 @@ onBeforeUnmount(() => {
if (isLoadingDownloadData.value) { if (isLoadingDownloadData.value) {
window.electron.sendToMain(cancelDownloadLoadingFileList, downloadCancelToken.value) window.electron.sendToMain(cancelDownloadLoadingFileList, downloadCancelToken.value)
} }
window.electron.ipcRendererRemoveListener('refreshFileTransferList', () => {}) window.electron.ipcRendererRemoveAllListeners('refreshFileTransferList')
window.electron.ipcRendererRemoveListener(refreshDownloadFileTransferList, () => {}) window.electron.ipcRendererRemoveAllListeners(refreshDownloadFileTransferList)
}) })
</script> </script>

View File

@@ -1589,7 +1589,7 @@ onBeforeMount(async () => {
}) })
onBeforeUnmount(async () => { onBeforeUnmount(async () => {
window.electron.ipcRendererRemoveListener('updateGallery', updateGalleryHandler) window.electron.ipcRendererRemoveAllListeners('updateGallery')
document.removeEventListener('click', handleOutsideClick) document.removeEventListener('click', handleOutsideClick)
document.removeEventListener('keydown', handleDetectShiftKey) document.removeEventListener('keydown', handleDetectShiftKey)
document.removeEventListener('keyup', handleDetectShiftKey) document.removeEventListener('keyup', handleDetectShiftKey)

View File

@@ -35,7 +35,6 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { IpcRendererEvent } from 'electron'
import type { IConfig } from 'piclist' import type { IConfig } from 'piclist'
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue' import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
@@ -55,6 +54,8 @@ const wY = ref(-1)
const screenX = ref(-1) const screenX = ref(-1)
const screenY = ref(-1) const screenY = ref(-1)
let removeListeners: () => void = () => {}
async function initLogoPath () { async function initLogoPath () {
const config = await getConfig<IConfig>() const config = await getConfig<IConfig>()
if (config) { if (config) {
@@ -66,10 +67,10 @@ async function initLogoPath () {
} }
} }
const uploadProgressHandler = (_: IpcRendererEvent, _progress: number) => { const uploadProgressHandler = (p: number) => {
if (_progress !== -1) { if (p !== -1) {
isShowingProgress.value = true isShowingProgress.value = true
progress.value = _progress progress.value = p
} else { } else {
progress.value = 100 progress.value = 100
} }
@@ -79,15 +80,6 @@ const updateMiniIconHandler = async () => {
await initLogoPath() await initLogoPath()
} }
onBeforeMount(async () => {
await initLogoPath()
window.electron.ipcRendererOn('uploadProgress', uploadProgressHandler)
window.electron.ipcRendererOn('updateMiniIcon', updateMiniIconHandler)
window.addEventListener('mousedown', handleMouseDown, false)
window.addEventListener('mousemove', handleMouseMove, false)
window.addEventListener('mouseup', handleMouseUp, false)
})
watch(progress, val => { watch(progress, val => {
if (val === 100) { if (val === 100) {
setTimeout(() => { setTimeout(() => {
@@ -194,9 +186,18 @@ function openContextMenu () {
window.electron.sendRPC(IRPCActionType.SHOW_MINI_PAGE_MENU) window.electron.sendRPC(IRPCActionType.SHOW_MINI_PAGE_MENU)
} }
onBeforeMount(async () => {
await initLogoPath()
removeListeners = window.electron.ipcRendererOn('uploadProgress', uploadProgressHandler)
window.electron.ipcRendererOn('updateMiniIcon', updateMiniIconHandler)
window.addEventListener('mousedown', handleMouseDown, false)
window.addEventListener('mousemove', handleMouseMove, false)
window.addEventListener('mouseup', handleMouseUp, false)
})
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.electron.ipcRendererRemoveListener('uploadProgress', uploadProgressHandler) removeListeners()
window.electron.ipcRendererRemoveListener('updateMiniIcon', updateMiniIconHandler) window.electron.ipcRendererRemoveAllListeners('updateMiniIcon')
window.removeEventListener('mousedown', handleMouseDown, false) window.removeEventListener('mousedown', handleMouseDown, false)
window.removeEventListener('mousemove', handleMouseMove, false) window.removeEventListener('mousemove', handleMouseMove, false)
window.removeEventListener('mouseup', handleMouseUp, false) window.removeEventListener('mouseup', handleMouseUp, false)

View File

@@ -289,7 +289,6 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { IpcRendererEvent } from 'electron'
import { debounce, DebouncedFunc } from 'lodash-es' import { debounce, DebouncedFunc } from 'lodash-es'
import { import {
AlertCircleIcon, AlertCircleIcon,
@@ -304,7 +303,7 @@ import {
XCircleIcon, XCircleIcon,
XIcon XIcon
} from 'lucide-vue-next' } from 'lucide-vue-next'
import { computed, onBeforeMount, onBeforeUnmount, onMounted, reactive, ref, toRaw, watch } from 'vue' import { computed, onBeforeMount, onBeforeUnmount, reactive, ref, toRaw, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import ConfigForm from '@/components/UnifiedConfigForm.vue' import ConfigForm from '@/components/UnifiedConfigForm.vue'
@@ -376,7 +375,7 @@ const hideLoadingHandler = () => {
loading.value = false loading.value = false
} }
const picgoHandlePluginDoneHandler = (_: IpcRendererEvent, fullName: string) => { const picgoHandlePluginDoneHandler = (fullName: string) => {
pluginList.value.forEach(item => { pluginList.value.forEach(item => {
if (item.fullName === fullName || item.name === fullName) { if (item.fullName === fullName || item.name === fullName) {
item.ing = false item.ing = false
@@ -385,7 +384,7 @@ const picgoHandlePluginDoneHandler = (_: IpcRendererEvent, fullName: string) =>
loading.value = false loading.value = false
} }
const pluginListHandler = (_: IpcRendererEvent, list: IPicGoPlugin[]) => { const pluginListHandler = (list: IPicGoPlugin[]) => {
pluginList.value = list pluginList.value = list
pluginNameList.value = list.map(item => item.fullName) pluginNameList.value = list.map(item => item.fullName)
for (const item of pluginList.value) { for (const item of pluginList.value) {
@@ -395,7 +394,6 @@ const pluginListHandler = (_: IpcRendererEvent, list: IPicGoPlugin[]) => {
} }
const installPluginHandler = ( const installPluginHandler = (
_: IpcRendererEvent,
{ {
success, success,
body body
@@ -413,7 +411,7 @@ const installPluginHandler = (
}) })
} }
const updateSuccessHandler = (_: IpcRendererEvent, plugin: string) => { const updateSuccessHandler = (plugin: string) => {
loading.value = false loading.value = false
pluginList.value.forEach(item => { pluginList.value.forEach(item => {
if (item.fullName === plugin) { if (item.fullName === plugin) {
@@ -426,7 +424,7 @@ const updateSuccessHandler = (_: IpcRendererEvent, plugin: string) => {
getPluginList() getPluginList()
} }
const uninstallSuccessHandler = (_: IpcRendererEvent, plugin: string) => { const uninstallSuccessHandler = (plugin: string) => {
loading.value = false loading.value = false
pluginList.value = pluginList.value.filter(item => { pluginList.value = pluginList.value.filter(item => {
if (item.fullName === plugin) { if (item.fullName === plugin) {
@@ -444,14 +442,14 @@ const uninstallSuccessHandler = (_: IpcRendererEvent, plugin: string) => {
pluginNameList.value = pluginNameList.value.filter(item => item !== plugin) pluginNameList.value = pluginNameList.value.filter(item => item !== plugin)
} }
const picgoConfigPluginHandler = (_: IpcRendererEvent, _currentType: 'plugin' | 'transformer' | 'uploader', _configName: string, _config: any) => { const picgoConfigPluginHandler = (_currentType: 'plugin' | 'transformer' | 'uploader', _configName: string, _config: any) => {
currentType.value = _currentType currentType.value = _currentType
configName.value = _configName configName.value = _configName
config.value = _config config.value = _config
dialogVisible.value = true dialogVisible.value = true
} }
const picgoHandlePluginIngHandler = (_: IpcRendererEvent, fullName: string) => { const picgoHandlePluginIngHandler = (fullName: string) => {
pluginList.value.forEach(item => { pluginList.value.forEach(item => {
if (item.fullName === fullName || item.name === fullName) { if (item.fullName === fullName || item.name === fullName) {
item.ing = true item.ing = true
@@ -459,7 +457,7 @@ const picgoHandlePluginIngHandler = (_: IpcRendererEvent, fullName: string) => {
}) })
} }
const picgoTogglePluginHandler = (_: IpcRendererEvent, fullName: string, enabled: boolean) => { const picgoTogglePluginHandler = (fullName: string, enabled: boolean) => {
const plugin = pluginList.value.find(item => item.fullName === fullName) const plugin = pluginList.value.find(item => item.fullName === fullName)
if (plugin) { if (plugin) {
plugin.enabled = enabled plugin.enabled = enabled
@@ -468,33 +466,10 @@ const picgoTogglePluginHandler = (_: IpcRendererEvent, fullName: string, enabled
} }
} }
onBeforeMount(async () => {
window.electron.ipcRendererOn('hideLoading', hideLoadingHandler)
window.electron.ipcRendererOn(PICGO_HANDLE_PLUGIN_DONE, picgoHandlePluginDoneHandler)
window.electron.ipcRendererOn('pluginList', pluginListHandler)
window.electron.ipcRendererOn('installPlugin', installPluginHandler)
window.electron.ipcRendererOn('updateSuccess', updateSuccessHandler)
window.electron.ipcRendererOn('uninstallSuccess', uninstallSuccessHandler)
window.electron.ipcRendererOn(PICGO_CONFIG_PLUGIN, picgoConfigPluginHandler)
window.electron.ipcRendererOn(PICGO_HANDLE_PLUGIN_ING, picgoHandlePluginIngHandler)
window.electron.ipcRendererOn(PICGO_TOGGLE_PLUGIN, picgoTogglePluginHandler)
getPluginList()
getSearchResult = debounce(_getSearchResult, 50)
needReload.value = (await getConfig<boolean>(configPaths.needReload)) || false
})
async function buildContextMenu (plugin: IPicGoPlugin) { async function buildContextMenu (plugin: IPicGoPlugin) {
window.electron.sendRPC(IRPCActionType.SHOW_PLUGIN_PAGE_MENU, getRawData(plugin)) window.electron.sendRPC(IRPCActionType.SHOW_PLUGIN_PAGE_MENU, getRawData(plugin))
} }
function handleResize () {
// No longer needed with new layout
}
onMounted(() => {
window.addEventListener('resize', handleResize)
})
function getPluginList () { function getPluginList () {
window.electron.sendRPC(IRPCActionType.PLUGIN_GET_LIST) window.electron.sendRPC(IRPCActionType.PLUGIN_GET_LIST)
} }
@@ -650,17 +625,31 @@ function handleUpdateAllPlugin () {
window.electron.sendRPC(IRPCActionType.PLUGIN_UPDATE_ALL, toRaw(pluginNameList.value)) window.electron.sendRPC(IRPCActionType.PLUGIN_UPDATE_ALL, toRaw(pluginNameList.value))
} }
onBeforeMount(async () => {
window.electron.ipcRendererOn('hideLoading', hideLoadingHandler)
window.electron.ipcRendererOn(PICGO_HANDLE_PLUGIN_DONE, picgoHandlePluginDoneHandler)
window.electron.ipcRendererOn('pluginList', pluginListHandler)
window.electron.ipcRendererOn('installPlugin', installPluginHandler)
window.electron.ipcRendererOn('updateSuccess', updateSuccessHandler)
window.electron.ipcRendererOn('uninstallSuccess', uninstallSuccessHandler)
window.electron.ipcRendererOn(PICGO_CONFIG_PLUGIN, picgoConfigPluginHandler)
window.electron.ipcRendererOn(PICGO_HANDLE_PLUGIN_ING, picgoHandlePluginIngHandler)
window.electron.ipcRendererOn(PICGO_TOGGLE_PLUGIN, picgoTogglePluginHandler)
getPluginList()
getSearchResult = debounce(_getSearchResult, 50)
needReload.value = (await getConfig<boolean>(configPaths.needReload)) || false
})
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize) window.electron.ipcRendererRemoveAllListeners('pluginList')
window.electron.ipcRendererRemoveListener('pluginList', pluginListHandler) window.electron.ipcRendererRemoveAllListeners('installPlugin')
window.electron.ipcRendererRemoveListener('installPlugin', installPluginHandler) window.electron.ipcRendererRemoveAllListeners('uninstallSuccess')
window.electron.ipcRendererRemoveListener('uninstallSuccess', uninstallSuccessHandler) window.electron.ipcRendererRemoveAllListeners('updateSuccess')
window.electron.ipcRendererRemoveListener('updateSuccess', updateSuccessHandler) window.electron.ipcRendererRemoveAllListeners('hideLoading')
window.electron.ipcRendererRemoveListener('hideLoading', hideLoadingHandler) window.electron.ipcRendererRemoveAllListeners(PICGO_HANDLE_PLUGIN_DONE)
window.electron.ipcRendererRemoveListener(PICGO_HANDLE_PLUGIN_DONE, picgoHandlePluginDoneHandler) window.electron.ipcRendererRemoveAllListeners(PICGO_CONFIG_PLUGIN)
window.electron.ipcRendererRemoveListener(PICGO_CONFIG_PLUGIN, picgoConfigPluginHandler) window.electron.ipcRendererRemoveAllListeners(PICGO_HANDLE_PLUGIN_ING)
window.electron.ipcRendererRemoveListener(PICGO_HANDLE_PLUGIN_ING, picgoHandlePluginIngHandler) window.electron.ipcRendererRemoveAllListeners(PICGO_TOGGLE_PLUGIN)
window.electron.ipcRendererRemoveListener(PICGO_TOGGLE_PLUGIN, picgoTogglePluginHandler)
// Reset body overflow // Reset body overflow
document.body.style.overflow = 'auto' document.body.style.overflow = 'auto'

View File

@@ -57,7 +57,6 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { IpcRendererEvent } from 'electron'
import { XIcon } from 'lucide-vue-next' import { XIcon } from 'lucide-vue-next'
import { nextTick, onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue' import { nextTick, onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@@ -74,7 +73,7 @@ const form = reactive({
originName: '' originName: ''
}) })
const handleFileName = (_: IpcRendererEvent, newName: string, _originName: string, _id: string) => { const handleFileName = (newName: string, _originName: string, _id: string) => {
form.fileName = newName form.fileName = newName
form.originName = _originName form.originName = _originName
id.value = _id id.value = _id
@@ -86,10 +85,6 @@ const handleFileName = (_: IpcRendererEvent, newName: string, _originName: strin
window.electron.ipcRendererOn(RENAME_FILE_NAME, handleFileName) window.electron.ipcRendererOn(RENAME_FILE_NAME, handleFileName)
onBeforeMount(() => {
window.electron.sendToMain(GET_RENAME_FILE_NAME, '')
})
function validateFileName (fileName: string): string { function validateFileName (fileName: string): string {
if (!fileName.trim()) { if (!fileName.trim()) {
return 'File name is required' return 'File name is required'
@@ -133,9 +128,14 @@ function clearValidationError () {
} }
} }
onBeforeUnmount(() => { onBeforeMount(() => {
window.electron.ipcRendererRemoveListener(RENAME_FILE_NAME, handleFileName) window.electron.sendToMain(GET_RENAME_FILE_NAME, '')
}) })
onBeforeUnmount(() => {
window.electron.ipcRendererRemoveAllListeners(RENAME_FILE_NAME)
})
</script> </script>
<script lang="ts"> <script lang="ts">
export default { export default {

View File

@@ -215,7 +215,7 @@ const toggleItem = (key: string) => {
} }
} }
const toolboxCheckResHandler = (_event: any, { type, msg = '', status, value = '' }: IToolboxCheckRes) => { const toolboxCheckResHandler = ({ type, msg = '', status, value = '' }: IToolboxCheckRes) => {
fixList[type].status = status fixList[type].status = status
fixList[type].msg = msg fixList[type].msg = msg
fixList[type].value = value fixList[type].value = value
@@ -272,7 +272,7 @@ const handleFix = async () => {
} }
onUnmounted(() => { onUnmounted(() => {
window.electron.ipcRendererRemoveListener(IRPCActionType.TOOLBOX_CHECK_RES, toolboxCheckResHandler) window.electron.ipcRendererRemoveAllListeners(IRPCActionType.TOOLBOX_CHECK_RES)
}) })
</script> </script>
<script lang="ts"> <script lang="ts">

View File

@@ -121,7 +121,6 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { IpcRendererEvent } from 'electron'
import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue' import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@@ -245,7 +244,7 @@ function onImageError (event: Event) {
img.style.display = 'none' img.style.display = 'none'
} }
const dragFilesHandler = async (_: IpcRendererEvent, _files: string[]) => { const dragFilesHandler = async (_files: string[]) => {
for (const file of _files) { for (const file of _files) {
await $$db.insert(file) await $$db.insert(file)
} }
@@ -255,7 +254,7 @@ const dragFilesHandler = async (_: IpcRendererEvent, _files: string[]) => {
}))!.data }))!.data
} }
const clipboardFilesHandler = (_: IpcRendererEvent, files: ImgInfo[]) => { const clipboardFilesHandler = (files: ImgInfo[]) => {
clipboardFiles.value = files clipboardFiles.value = files
} }
@@ -281,10 +280,10 @@ onBeforeMount(async () => {
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.electron.ipcRendererRemoveListener('dragFiles', dragFilesHandler) window.electron.ipcRendererRemoveAllListeners('dragFiles')
window.electron.ipcRendererRemoveListener('clipboardFiles', clipboardFilesHandler) window.electron.ipcRendererRemoveAllListeners('clipboardFiles')
window.electron.ipcRendererRemoveListener('uploadFiles', uploadFilesHandler) window.electron.ipcRendererRemoveAllListeners('uploadFiles')
window.electron.ipcRendererRemoveListener('updateFiles', updateFilesHandler) window.electron.ipcRendererRemoveAllListeners('updateFiles')
}) })
</script> </script>

View File

@@ -13,7 +13,7 @@
<span class="provider-name">{{ picBedName }}</span> <span class="provider-name">{{ picBedName }}</span>
<span class="provider-config">{{ picBedConfigName || 'Default' }}</span> <span class="provider-config">{{ picBedConfigName || 'Default' }}</span>
</div> </div>
<ChevronDownIcon <EditIcon
:size="16" :size="16"
class="provider-arrow" class="provider-arrow"
/> />
@@ -31,7 +31,7 @@
class="action-button" class="action-button"
@click="handleChangePicBed" @click="handleChangePicBed"
> >
<DatabaseIcon :size="16" /> <ArrowLeftRightIcon :size="16" />
<span>{{ t('pages.upload.changePicBed') }}</span> <span>{{ t('pages.upload.changePicBed') }}</span>
</button> </button>
</div> </div>
@@ -173,7 +173,7 @@
<div <div
v-if="imageProcessDialogVisible" v-if="imageProcessDialogVisible"
class="modal-overlay" class="modal-overlay"
@click="imageProcessDialogVisible = false" @click.stop
> >
<div <div
class="modal-container" class="modal-container"
@@ -200,8 +200,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { IpcRendererEvent } from 'electron' import { ArrowLeftRightIcon, ClipboardIcon, EditIcon, LinkIcon, Settings, UploadCloudIcon, XIcon } from 'lucide-vue-next'
import { ChevronDownIcon, ClipboardIcon, DatabaseIcon, LinkIcon, Settings, UploadCloudIcon, XIcon } from 'lucide-vue-next'
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue' import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
@@ -247,30 +246,23 @@ watch(picBedGlobal, () => {
getDefaultPicBed() getDefaultPicBed()
}) })
const uploadProgressHandler = (_event: IpcRendererEvent, _progress: number) => { let removeUploadProgressListenerCallback: (() => void) = () => {}
if (_progress !== -1) { let removeSyncPicBedListenerCallback: (() => void) = () => {}
function uploadProgressHandler (p: number): void {
if (p !== -1) {
showProgress.value = true showProgress.value = true
progress.value = _progress progress.value = p
} else { } else {
progress.value = 100 progress.value = 100
showError.value = true showError.value = true
} }
} }
const syncPicBedHandler = () => { function syncPicBedHandler (): void {
getDefaultPicBed() getDefaultPicBed()
} }
onBeforeMount(() => {
updatePicBedGlobal()
window.electron.ipcRendererOn('uploadProgress', uploadProgressHandler)
getUseShortUrl()
getPasteStyle()
getDefaultPicBed()
window.electron.ipcRendererOn('syncPicBed', syncPicBedHandler)
$bus.on(SHOW_INPUT_BOX_RESPONSE, handleInputBoxValue)
})
const handleImageProcess = () => { const handleImageProcess = () => {
imageProcessDialogVisible.value = true imageProcessDialogVisible.value = true
} }
@@ -308,12 +300,6 @@ async function handlePicBedNameClick (_picBedName: string, picBedConfigName: str
}) })
} }
onBeforeUnmount(() => {
$bus.off(SHOW_INPUT_BOX_RESPONSE)
window.electron.ipcRendererRemoveListener('uploadProgress', uploadProgressHandler)
window.electron.ipcRendererRemoveListener('syncPicBed', syncPicBedHandler)
})
function onDrop (e: DragEvent) { function onDrop (e: DragEvent) {
dragover.value = false dragover.value = false
@@ -434,6 +420,23 @@ async function getDefaultPicBed () {
async function handleChangePicBed () { async function handleChangePicBed () {
window.electron.sendRPC(IRPCActionType.SHOW_UPLOAD_PAGE_MENU) window.electron.sendRPC(IRPCActionType.SHOW_UPLOAD_PAGE_MENU)
} }
onBeforeUnmount(() => {
$bus.off(SHOW_INPUT_BOX_RESPONSE)
removeUploadProgressListenerCallback()
removeSyncPicBedListenerCallback()
})
onBeforeMount(() => {
updatePicBedGlobal()
getUseShortUrl()
getPasteStyle()
getDefaultPicBed()
removeUploadProgressListenerCallback = window.electron.ipcRendererOn('uploadProgress', uploadProgressHandler)
removeSyncPicBedListenerCallback = window.electron.ipcRendererOn('syncPicBed', syncPicBedHandler)
$bus.on(SHOW_INPUT_BOX_RESPONSE, handleInputBoxValue)
})
</script> </script>
<script lang="ts"> <script lang="ts">

View File

@@ -156,21 +156,20 @@ function formatTime (time: number): string {
} }
async function deleteConfig (id: string) { async function deleteConfig (id: string) {
confirm({ const result = await confirm({
title: t('pages.uploaderConfig.deleteTitle'), title: t('pages.uploaderConfig.deleteTitle'),
message: t('pages.uploaderConfig.deleteConfirm'), message: t('pages.uploaderConfig.deleteConfirm'),
type: 'warning', type: 'warning',
confirmButtonText: t('common.confirm'), confirmButtonText: t('common.confirm'),
cancelButtonText: t('common.cancel'), cancelButtonText: t('common.cancel'),
center: true center: true
}).then(async result => {
if (!result) return
const res = await window.electron.triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_DELETE_CONFIG, type.value, id)
if (!res) return
curConfigList.value = res.configList
defaultConfigId.value = res.defaultId
message.success(t('pages.uploaderConfig.deleteSuccess'))
}) })
if (!result) return
const res = await window.electron.triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_DELETE_CONFIG, type.value, id)
if (!res) return
curConfigList.value = res.configList
defaultConfigId.value = res.defaultId
message.success(t('pages.uploaderConfig.deleteSuccess'))
} }
function addNewConfig () { function addNewConfig () {

View File

@@ -107,7 +107,6 @@ html, body {
.provider-button:hover .provider-arrow { .provider-button:hover .provider-arrow {
color: var(--color-accent); color: var(--color-accent);
transform: rotate(180deg);
} }
.header-actions { .header-actions {

View File

View File

@@ -9,7 +9,6 @@ import yaml from 'js-yaml'
import mime from 'mime-types' import mime from 'mime-types'
import { VNode } from 'vue' import { VNode } from 'vue'
import { IpcRendererListener } from '#/types/electron'
import { ILocales, ILocalesKey } from '#/types/i18n' import { ILocales, ILocalesKey } from '#/types/i18n'
import { IStringKeyMap } from '#/types/types' import { IStringKeyMap } from '#/types/types'
@@ -29,8 +28,9 @@ declare global {
triggerRPC: <T>(action: string, ...args: any[]) => Promise<T | undefined> triggerRPC: <T>(action: string, ...args: any[]) => Promise<T | undefined>
sendToMain: (channel: string, ...args: any[]) => void sendToMain: (channel: string, ...args: any[]) => void
sendRPC: (action: string, ...args: any[]) => void sendRPC: (action: string, ...args: any[]) => void
ipcRendererOn: (channel: string, listener: IpcRendererListener) => void ipcRendererOn: (channel: string, listener: (...args: any[]) => void) => () => void
ipcRendererRemoveListener: (channel: string, listener: IpcRendererListener) => void ipcRendererCountListeners: (channel: string) => number
ipcRendererRemoveAllListeners: (channel: string) => void
clipboard: { clipboard: {
writeText: typeof clipboard.writeText writeText: typeof clipboard.writeText
}, },