🐛 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 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 yaml from 'js-yaml'
import mime from 'mime-types'
import { isReactive, isRef, toRaw, unref } from 'vue'
import type { IpcRendererListener } from '#/types/electron'
export const getRawData = (args: any): any => {
if (isRef(args)) return unref(args)
if (isReactive(args)) return toRaw(args)
@@ -52,11 +50,18 @@ try {
triggerRPC,
sendToMain,
sendRPC,
ipcRendererOn: (channel: string, listener: IpcRendererListener) => {
ipcRenderer.on(channel, listener)
ipcRendererOn: (channel: string, listener: (...args: any[]) => void) => {
const subscription = (_: IpcRendererEvent, ...args: any[]) => listener(...args)
ipcRenderer.on(channel, subscription)
return () => {
ipcRenderer.removeListener(channel, subscription)
}
},
ipcRendererRemoveListener: (channel: string, listener: IpcRendererListener) => {
ipcRenderer.removeListener(channel, listener)
ipcRendererCountListeners: (channel: string): number => {
return ipcRenderer.listenerCount(channel)
},
ipcRendererRemoveAllListeners: (channel: string) => {
ipcRenderer.removeAllListeners(channel)
},
showFilePath (file: File) {
return webUtils.getPathForFile(file)

View File

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

View File

@@ -2,7 +2,10 @@
<nav class="navigation">
<div class="title-bar">
<div class="app-title">
<div class="app-text">
<div
class="app-text"
@click="openGithubPage"
>
{{ t('app.title') }}
</div>
<div class="app-version">
@@ -79,18 +82,6 @@
class="qr-dialog"
@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">
<TransitionChild
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 QrcodeVue from 'qrcode.vue'
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 useMessage from '@/hooks/useMessage'
@@ -237,6 +228,8 @@ const qrcodeVisible = ref(false)
const choosedPicBedForQRCode: Ref<string[]> = ref([])
const picBedConfigString = ref('')
let removeIpcListener: () => void = () => {}
watch(
() => choosedPicBedForQRCode,
val => {
@@ -280,9 +273,17 @@ const navigationItems = computed(() => [
}
])
function openGithubPage () {
window.electron.sendRPC(IRPCActionType.OPEN_URL, 'https://github.com/Kuingsmile/PicList')
}
onBeforeMount(() => {
updatePicBedGlobal()
window.electron.ipcRendererOn(SHOW_MAIN_PAGE_QRCODE, qrCodeHandler)
removeIpcListener = window.electron.ipcRendererOn(SHOW_MAIN_PAGE_QRCODE, qrCodeHandler)
})
onBeforeUnmount(() => {
removeIpcListener()
})
</script>
@@ -333,6 +334,11 @@ onBeforeMount(() => {
letter-spacing: -0.025em;
}
.app-text:hover {
cursor: pointer;
color: var(--color-blue-common);
}
.app-version {
font-size: 10px;
font-weight: 500;
@@ -536,16 +542,11 @@ onBeforeMount(() => {
inset: 0;
z-index: 50;
display: flex;
overflow-y: auto;
align-items: center;
justify-content: center;
}
.dialog-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
}
.dialog-container {
position: fixed;
inset: 0;
@@ -561,7 +562,7 @@ onBeforeMount(() => {
.dialog-panel {
width: 100%;
max-width: 500px;
background: var(--color-surface);
background: var(--color-background-primary);
border-radius: 16px;
border: 1px solid var(--color-border);
box-shadow: var(--shadow-md);
@@ -634,11 +635,11 @@ onBeforeMount(() => {
right: 0;
z-index: 10;
margin-top: 4px;
background: var(--color-surface);
background: var(--color-background-primary);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
box-shadow: var(--shadow-md);
max-height: 200px;
max-height: 300px;
overflow-y: auto;
}

View File

@@ -74,7 +74,6 @@
</template>
<script setup lang="ts">
import type { IpcRendererEvent } from 'electron'
import { MinusIcon, PinIcon, ShrinkIcon, XIcon } from 'lucide-vue-next'
import { onBeforeMount, onBeforeUnmount, ref } from 'vue'
@@ -100,7 +99,8 @@ function openMiniWindow () {
function closeWindow () {
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
progress.value = data.progress
}
@@ -110,7 +110,7 @@ onBeforeMount(() => {
})
onBeforeUnmount(() => {
window.electron.ipcRendererRemoveListener('updateProgress', uploadProcessHandler)
window.electron.ipcRendererRemoveAllListeners('updateProgress')
})
</script>

View File

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

View File

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

View File

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

View File

@@ -289,7 +289,6 @@
</template>
<script lang="ts" setup>
import type { IpcRendererEvent } from 'electron'
import { debounce, DebouncedFunc } from 'lodash-es'
import {
AlertCircleIcon,
@@ -304,7 +303,7 @@ import {
XCircleIcon,
XIcon
} 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 ConfigForm from '@/components/UnifiedConfigForm.vue'
@@ -376,7 +375,7 @@ const hideLoadingHandler = () => {
loading.value = false
}
const picgoHandlePluginDoneHandler = (_: IpcRendererEvent, fullName: string) => {
const picgoHandlePluginDoneHandler = (fullName: string) => {
pluginList.value.forEach(item => {
if (item.fullName === fullName || item.name === fullName) {
item.ing = false
@@ -385,7 +384,7 @@ const picgoHandlePluginDoneHandler = (_: IpcRendererEvent, fullName: string) =>
loading.value = false
}
const pluginListHandler = (_: IpcRendererEvent, list: IPicGoPlugin[]) => {
const pluginListHandler = (list: IPicGoPlugin[]) => {
pluginList.value = list
pluginNameList.value = list.map(item => item.fullName)
for (const item of pluginList.value) {
@@ -395,7 +394,6 @@ const pluginListHandler = (_: IpcRendererEvent, list: IPicGoPlugin[]) => {
}
const installPluginHandler = (
_: IpcRendererEvent,
{
success,
body
@@ -413,7 +411,7 @@ const installPluginHandler = (
})
}
const updateSuccessHandler = (_: IpcRendererEvent, plugin: string) => {
const updateSuccessHandler = (plugin: string) => {
loading.value = false
pluginList.value.forEach(item => {
if (item.fullName === plugin) {
@@ -426,7 +424,7 @@ const updateSuccessHandler = (_: IpcRendererEvent, plugin: string) => {
getPluginList()
}
const uninstallSuccessHandler = (_: IpcRendererEvent, plugin: string) => {
const uninstallSuccessHandler = (plugin: string) => {
loading.value = false
pluginList.value = pluginList.value.filter(item => {
if (item.fullName === plugin) {
@@ -444,14 +442,14 @@ const uninstallSuccessHandler = (_: IpcRendererEvent, plugin: string) => {
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
configName.value = _configName
config.value = _config
dialogVisible.value = true
}
const picgoHandlePluginIngHandler = (_: IpcRendererEvent, fullName: string) => {
const picgoHandlePluginIngHandler = (fullName: string) => {
pluginList.value.forEach(item => {
if (item.fullName === fullName || item.name === fullName) {
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)
if (plugin) {
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) {
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 () {
window.electron.sendRPC(IRPCActionType.PLUGIN_GET_LIST)
}
@@ -650,17 +625,31 @@ function handleUpdateAllPlugin () {
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(() => {
window.removeEventListener('resize', handleResize)
window.electron.ipcRendererRemoveListener('pluginList', pluginListHandler)
window.electron.ipcRendererRemoveListener('installPlugin', installPluginHandler)
window.electron.ipcRendererRemoveListener('uninstallSuccess', uninstallSuccessHandler)
window.electron.ipcRendererRemoveListener('updateSuccess', updateSuccessHandler)
window.electron.ipcRendererRemoveListener('hideLoading', hideLoadingHandler)
window.electron.ipcRendererRemoveListener(PICGO_HANDLE_PLUGIN_DONE, picgoHandlePluginDoneHandler)
window.electron.ipcRendererRemoveListener(PICGO_CONFIG_PLUGIN, picgoConfigPluginHandler)
window.electron.ipcRendererRemoveListener(PICGO_HANDLE_PLUGIN_ING, picgoHandlePluginIngHandler)
window.electron.ipcRendererRemoveListener(PICGO_TOGGLE_PLUGIN, picgoTogglePluginHandler)
window.electron.ipcRendererRemoveAllListeners('pluginList')
window.electron.ipcRendererRemoveAllListeners('installPlugin')
window.electron.ipcRendererRemoveAllListeners('uninstallSuccess')
window.electron.ipcRendererRemoveAllListeners('updateSuccess')
window.electron.ipcRendererRemoveAllListeners('hideLoading')
window.electron.ipcRendererRemoveAllListeners(PICGO_HANDLE_PLUGIN_DONE)
window.electron.ipcRendererRemoveAllListeners(PICGO_CONFIG_PLUGIN)
window.electron.ipcRendererRemoveAllListeners(PICGO_HANDLE_PLUGIN_ING)
window.electron.ipcRendererRemoveAllListeners(PICGO_TOGGLE_PLUGIN)
// Reset body overflow
document.body.style.overflow = 'auto'

View File

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

View File

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

View File

@@ -13,7 +13,7 @@
<span class="provider-name">{{ picBedName }}</span>
<span class="provider-config">{{ picBedConfigName || 'Default' }}</span>
</div>
<ChevronDownIcon
<EditIcon
:size="16"
class="provider-arrow"
/>
@@ -31,7 +31,7 @@
class="action-button"
@click="handleChangePicBed"
>
<DatabaseIcon :size="16" />
<ArrowLeftRightIcon :size="16" />
<span>{{ t('pages.upload.changePicBed') }}</span>
</button>
</div>
@@ -173,7 +173,7 @@
<div
v-if="imageProcessDialogVisible"
class="modal-overlay"
@click="imageProcessDialogVisible = false"
@click.stop
>
<div
class="modal-container"
@@ -200,8 +200,7 @@
</template>
<script lang="ts" setup>
import type { IpcRendererEvent } from 'electron'
import { ChevronDownIcon, ClipboardIcon, DatabaseIcon, LinkIcon, Settings, UploadCloudIcon, XIcon } from 'lucide-vue-next'
import { ArrowLeftRightIcon, ClipboardIcon, EditIcon, LinkIcon, Settings, UploadCloudIcon, XIcon } from 'lucide-vue-next'
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
@@ -247,30 +246,23 @@ watch(picBedGlobal, () => {
getDefaultPicBed()
})
const uploadProgressHandler = (_event: IpcRendererEvent, _progress: number) => {
if (_progress !== -1) {
let removeUploadProgressListenerCallback: (() => void) = () => {}
let removeSyncPicBedListenerCallback: (() => void) = () => {}
function uploadProgressHandler (p: number): void {
if (p !== -1) {
showProgress.value = true
progress.value = _progress
progress.value = p
} else {
progress.value = 100
showError.value = true
}
}
const syncPicBedHandler = () => {
function syncPicBedHandler (): void {
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 = () => {
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) {
dragover.value = false
@@ -434,6 +420,23 @@ async function getDefaultPicBed () {
async function handleChangePicBed () {
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 lang="ts">

View File

@@ -156,21 +156,20 @@ function formatTime (time: number): string {
}
async function deleteConfig (id: string) {
confirm({
const result = await confirm({
title: t('pages.uploaderConfig.deleteTitle'),
message: t('pages.uploaderConfig.deleteConfirm'),
type: 'warning',
confirmButtonText: t('common.confirm'),
cancelButtonText: t('common.cancel'),
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 () {

View File

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

View File

View File

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