Feature(custom): optimize the logic of second picbed upload, and fix a bug of local picbed

This commit is contained in:
Kuingsmile
2026-01-12 21:13:21 +08:00
parent a57afd4161
commit e69ebd95ac
19 changed files with 142 additions and 165 deletions

View File

@@ -1,7 +1,7 @@
import db, { GalleryDB } from '@core/datastore'
import picgo from '@core/picgo'
import uploader from 'apis/app/uploader'
import { handleSecondaryUpload, uploadClipboardFiles } from 'apis/app/uploader/apis'
import { uploadClipboardFiles } from 'apis/app/uploader/apis'
import windowManager from 'apis/app/window/windowManager'
import {
app,
@@ -312,16 +312,9 @@ export function createTray(tooltip: string) {
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
const rawInput = cloneDeep(files)
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
const { needRestore, ctx } = await handleSecondaryUpload(trayWindow.webContents, files, 'tray')
let imgs: ImgInfo[] | false = false
if (needRestore) {
const res = await uploader
.setWebContents(trayWindow.webContents)
.uploadReturnCtx(ctx ? ctx.processedInput : files, true)
imgs = res ? res.output : false
} else {
imgs = await uploader.setWebContents(trayWindow.webContents).upload(files)
}
const res = await uploader.setWebContents(trayWindow.webContents).uploadReturnCtx(files)
const imgs = res[0] ? res[0] : false
const backImgs = res[1] ? res[1] : false
const deleteLocalFile = db.get(configPaths.settings.deleteLocalFile) || false
if (imgs !== false) {
const pasteText: string[] = []
@@ -355,6 +348,12 @@ export function createTray(tooltip: string) {
handleCopyUrl(pasteText.join('\n'))
trayWindow.webContents.send('dragFiles', imgs)
}
if (backImgs !== false) {
for (const backImg of backImgs) {
await GalleryDB.getInstance().insert(backImg)
}
trayWindow.webContents.send('dragFiles', backImgs)
}
})
}
// toggleWindow()

View File

@@ -5,48 +5,31 @@ import windowManager from 'apis/app/window/windowManager'
import { Notification, WebContents } from 'electron'
import fs from 'fs-extra'
import { cloneDeep } from 'lodash-es'
import type { IPicGo } from 'piclist'
import { T as $t } from '~/i18n/index'
import { handleCopyUrl, handleUrlEncodeWithSetting } from '~/utils/common'
import { configPaths } from '~/utils/configPaths'
import { IPasteStyle, IWindowList } from '~/utils/enum'
import { changeCurrentUploader } from '~/utils/handleUploaderConfig'
import pasteTemplate from '~/utils/pasteTemplate'
const handleClipboardUploading = async (): Promise<false | ImgInfo[]> => {
const handleClipboardUploadingReturnCtx = async (img?: IUploadOption): Promise<(ImgInfo[] | false)[]> => {
const useBuiltinClipboard =
db.get(configPaths.settings.useBuiltinClipboard) === undefined
? true
: !!db.get(configPaths.settings.useBuiltinClipboard)
const win = windowManager.getAvailableWindow()
if (useBuiltinClipboard) {
return await uploader.setWebContents(win!.webContents).uploadWithBuildInClipboard()
return await uploader.setWebContents(win!.webContents).uploadWithBuildInClipboardReturnCtx(img)
}
return await uploader.setWebContents(win!.webContents).upload()
}
const handleClipboardUploadingReturnCtx = async (img?: IUploadOption, skipProcess = false): Promise<false | IPicGo> => {
const useBuiltinClipboard =
db.get(configPaths.settings.useBuiltinClipboard) === undefined
? true
: !!db.get(configPaths.settings.useBuiltinClipboard)
const win = windowManager.getAvailableWindow()
if (useBuiltinClipboard) {
return await uploader.setWebContents(win!.webContents).uploadWithBuildInClipboardReturnCtx(img, skipProcess)
}
return await uploader.setWebContents(win!.webContents).uploadReturnCtx(img, skipProcess)
return await uploader.setWebContents(win!.webContents).uploadReturnCtx(img)
}
export const uploadClipboardFiles = async (): Promise<IStringKeyMap> => {
const { needRestore, ctx } = await handleSecondaryUpload(undefined, undefined, 'clipboard')
let img: ImgInfo[] | false = false
if (needRestore) {
const res = await handleClipboardUploadingReturnCtx(ctx ? ctx.processedInput : undefined, true)
img = res ? res.output : false
} else {
img = await handleClipboardUploading()
}
let backImg: ImgInfo[] | false = false
const res = await handleClipboardUploadingReturnCtx()
img = res[0] ? res[0] : false
backImg = res[1] ? res[1] : false
if (img !== false) {
if (img.length > 0) {
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)
@@ -71,10 +54,17 @@ export const uploadClipboardFiles = async (): Promise<IStringKeyMap> => {
const inserted = await GalleryDB.getInstance().insert(img[0])
// trayWindow just be created in mac/windows, not in linux
trayWindow?.webContents?.send('clipboardFiles', [])
trayWindow?.webContents?.send('uploadFiles', img)
trayWindow?.webContents?.send('uploadFiles')
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents?.send('updateGallery')
}
if (backImg !== false) {
await GalleryDB.getInstance().insert(backImg[0])
trayWindow?.webContents?.send('uploadFiles')
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents?.send('updateGallery')
}
}
return {
url: handleUrlEncodeWithSetting(inserted.imgUrl as string),
fullResult: inserted,
@@ -104,14 +94,11 @@ export const uploadChoosedFiles = async (
): Promise<IStringKeyMap[]> => {
const input = files.map(item => item.path)
const rawInput = cloneDeep(input)
const { needRestore, ctx } = await handleSecondaryUpload(webContents, input)
let imgs: ImgInfo[] | false = false
if (needRestore) {
const res = await uploader.setWebContents(webContents).uploadReturnCtx(ctx ? ctx.processedInput : input, true)
imgs = res ? res.output : false
} else {
imgs = await uploader.setWebContents(webContents).upload(input)
}
let backImgs: ImgInfo[] | false = false
const res = await uploader.setWebContents(webContents).uploadReturnCtx(input)
imgs = res[0] ? res[0] : false
backImgs = res[1] ? res[1] : false
const result = []
if (imgs !== false) {
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
@@ -167,80 +154,21 @@ export const uploadChoosedFiles = async (
}
handleCopyUrl(pasteText.join('\n'))
// trayWindow just be created in mac/windows, not in linux
windowManager.get(IWindowList.TRAY_WINDOW)?.webContents?.send('uploadFiles', imgs)
windowManager.get(IWindowList.TRAY_WINDOW)?.webContents?.send('uploadFiles')
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents?.send('updateGallery')
}
if (backImgs !== false) {
for (const backImg of backImgs) {
await GalleryDB.getInstance().insert(backImg)
}
windowManager.get(IWindowList.TRAY_WINDOW)?.webContents?.send('uploadFiles')
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents?.send('updateGallery')
}
}
return result
} else {
return []
}
}
export const handleSecondaryUpload = async (
webContents?: WebContents,
input?: string[],
uploadType: 'clipboard' | 'file' | 'tray' = 'file',
): Promise<{ needRestore: boolean; ctx: IPicGo | false }> => {
const enableSecondUploader = db.get(configPaths.settings.enableSecondUploader) || false
let currentPicBedType = ''
let currentPicBedConfig = {} as IStringKeyMap
let currentPicBedConfigId = ''
let needRestore = false
let ctx: IPicGo | false = false
if (enableSecondUploader) {
const secondUploader = db.get(configPaths.picBed.secondUploader)
const secondUploaderConfig = db.get(configPaths.picBed.secondUploaderConfig)
const secondUploaderId = db.get(configPaths.picBed.secondUploaderId)
const currentPicBed = db.get('picBed') || ({} as IStringKeyMap)
currentPicBedType = currentPicBed.uploader || currentPicBed.current || 'smms'
currentPicBedConfig = currentPicBed[currentPicBedType] || ({} as IStringKeyMap)
currentPicBedConfigId = currentPicBedConfig._id
if (
secondUploader === currentPicBedType &&
secondUploaderConfig._configName === currentPicBedConfig._configName &&
secondUploaderId === currentPicBedConfigId
) {
picgo.log.info('second uploader is the same as current uploader')
} else {
needRestore = true
let secondImgs: ImgInfo[] | false = false
changeCurrentUploader(secondUploader, secondUploaderConfig, secondUploaderId)
if (uploadType === 'clipboard') {
ctx = await handleClipboardUploadingReturnCtx(undefined)
} else {
ctx = await uploader.setWebContents(webContents!).uploadReturnCtx(input)
}
secondImgs = ctx ? ctx.output : false
if (secondImgs !== false) {
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)
if (uploadType === 'clipboard') {
if (secondImgs.length > 0) {
await GalleryDB.getInstance().insert(secondImgs[0])
trayWindow?.webContents?.send('clipboardFiles', [])
trayWindow?.webContents?.send('uploadFiles', secondImgs)
}
} else {
for (const secondImgsItem of secondImgs) {
await GalleryDB.getInstance().insert(secondImgsItem)
}
if (uploadType === 'tray') {
trayWindow?.webContents?.send('dragFiles', secondImgs)
} else {
trayWindow?.webContents?.send('uploadFiles', secondImgs)
}
}
if (windowManager.has(IWindowList.SETTING_WINDOW) && uploadType !== 'tray') {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents?.send('updateGallery')
}
}
}
}
if (needRestore) {
changeCurrentUploader(currentPicBedType, currentPicBedConfig, currentPicBedConfigId)
}
return {
needRestore,
ctx,
}
}

View File

@@ -137,15 +137,15 @@ class Uploader {
}
}
async uploadWithBuildInClipboardReturnCtx(img?: IUploadOption, skipProcess = false): Promise<IPicGo | false> {
async uploadWithBuildInClipboardReturnCtx(img?: IUploadOption): Promise<(ImgInfo[] | false)[]> {
let imgPath: string | false = false
try {
imgPath = await this.getClipboardImagePath()
if (!imgPath) return false
return await this.uploadReturnCtx(img ?? [imgPath], skipProcess)
if (!imgPath) return [false, false]
return await this.uploadReturnCtx(img ?? [imgPath])
} catch (e: any) {
logger.error(e)
return false
return [false, false]
} finally {
if (imgPath && imgPath.startsWith(path.join(picgo.baseDir, CLIPBOARD_IMAGE_FOLDER))) {
fs.remove(imgPath)
@@ -153,16 +153,25 @@ class Uploader {
}
}
async uploadReturnCtx(img?: IUploadOption, skipProcess = false): Promise<IPicGo | false> {
async uploadReturnCtx(img?: IUploadOption): Promise<(ImgInfo[] | false)[]> {
try {
const ctx = await picgo.uploadReturnCtx(img, skipProcess)
if (!Array.isArray(ctx.output) || !ctx.output.some((item: ImgInfo) => item.imgUrl)) return false
const result = [false, false] as (ImgInfo[] | false)[]
const res = await picgo.uploadReturnCtx(img)
ctx.output.forEach((item: ImgInfo) => {
item.config = JSON.parse(JSON.stringify(db.get(`picBed.${item.type}`)))
})
if (Array.isArray(res.output) && res.output.some((item: ImgInfo) => item.imgUrl)) {
res.output.forEach((item: ImgInfo) => {
item.config = JSON.parse(JSON.stringify(db.get(`picBed.${item.type}`)))
})
result[0] = res.output
}
return ctx
if (Array.isArray(res.backupOutput) && res.backupOutput.some((item: ImgInfo) => item.imgUrl)) {
res.backupOutput.forEach((item: ImgInfo) => {
item.config = JSON.parse(JSON.stringify(db.get(`picBed.${item.type}`)))
})
result[1] = res.backupOutput
}
return result
} catch (e: any) {
logger.error(e)
setTimeout(() => {
@@ -172,7 +181,7 @@ class Uploader {
clickToCopy: true,
})
}, 500)
return false
return [false, false]
} finally {
ipcMain.removeAllListeners(GET_RENAME_FILE_NAME)
}

View File

@@ -3,7 +3,6 @@ import db, { GalleryDB } from '@core/datastore'
import { dbPathChecker, defaultConfigPath, getGalleryDBPath } from '@core/datastore/dbChecker'
import { DBStore } from '@piclist/store'
import uploader from 'apis/app/uploader'
import { handleSecondaryUpload } from 'apis/app/uploader/apis'
import { BrowserWindow, dialog, ipcMain, IpcMainEvent, MessageBoxOptions, Notification } from 'electron'
import fs from 'fs-extra'
import { cloneDeep } from 'lodash-es'
@@ -74,14 +73,10 @@ class GuiApi implements IGuiApi {
this.windowId = await getWindowId()
const webContents = this.getWebcontentsByWindowId(this.windowId)
const rawInput = cloneDeep(input)
const { needRestore, ctx } = await handleSecondaryUpload(webContents!, input)
let imgs: ImgInfo[] | false = false
if (needRestore) {
const res = await uploader.setWebContents(webContents!).uploadReturnCtx(ctx ? ctx.processedInput : input, true)
imgs = res ? res.output : false
} else {
imgs = await uploader.setWebContents(webContents!).upload(input)
}
const res = await uploader.setWebContents(webContents!).uploadReturnCtx(input)
const imgs = res[0] ? res[0] : false
const backImgs = res[1] ? res[1] : false
let result: ImgInfo[] = []
if (imgs !== false) {
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
const deleteLocalFile = db.get(configPaths.settings.deleteLocalFile) || false
@@ -114,11 +109,18 @@ class GuiApi implements IGuiApi {
await GalleryDB.getInstance().insert(imgs[i])
}
handleCopyUrl(pasteText.join('\n'))
webContents?.send('uploadFiles', imgs)
webContents?.send('uploadFiles')
webContents?.send('updateGallery')
return imgs
result = imgs
}
return []
if (backImgs !== false) {
for (const backImg of backImgs) {
await GalleryDB.getInstance().insert(backImg)
}
webContents?.send('uploadFiles')
webContents?.send('updateGallery')
}
return result
}
showNotification(

View File

@@ -139,12 +139,16 @@ const buildMainPageMenu = (win: BrowserWindow) => {
const buildSecondPicBedMenu = () => {
const picBeds = getPicBeds().picBeds
const secondUploader = picgo.getConfig(configPaths.picBed.secondUploader)
const defaultSecondUploaderId = picgo.getConfig(configPaths.picBed.secondUploaderId)
const defaultSecondUploaderConfig = picgo.getConfig(configPaths.picBed.secondUploaderConfig) as
| IUploaderConfig
| undefined
const defaultSecondUploaderId = defaultSecondUploaderConfig?._id || ''
const defaultSecondUploaderName = defaultSecondUploaderConfig?._configName || 'Default'
const currentPicBedName = picBeds.find(item => item.type === secondUploader)?.name
const picBedConfigList = picgo.getConfig<IUploaderConfig>('uploader')
const currentPicBedMenuItem = [
{
label: `${$t('CURRENT_SECOND_PICBED')} - ${currentPicBedName || 'None'}`,
label: `${$t('CURRENT_SECOND_PICBED')} - ${currentPicBedName || 'None'} - ${defaultSecondUploaderName}`,
enabled: false,
},
{
@@ -169,16 +173,17 @@ const buildSecondPicBedMenu = () => {
type: 'checkbox',
checked: config._id === defaultSecondUploaderId && item.type === secondUploader,
click() {
changeSecondUploader(item.type, config, config._id)
changeSecondUploader(item.type, config)
},
}
})
: undefined,
click: !hasSubmenu
? function () {
picgo.saveConfig({
[configPaths.picBed.secondUploader]: item.type,
})
const current = picgo.getConfig(`picBed.${item.type}`)
if (current) {
changeSecondUploader(item.type, current)
}
}
: undefined,
}

View File

@@ -27,7 +27,7 @@ const getPicBeds = () => {
}
return 0
}) as IPicBedType[]
return { picBeds, defaultPicBed, defaultId, defaultConfigName }
return { picBeds, defaultPicBed, defaultId, defaultConfigName, defaultConfig }
}
export default getPicBeds

View File

@@ -27,15 +27,10 @@ export const completeUploaderMetaConfig = (originData: IStringKeyMap, id?: strin
}
}
export const changeSecondUploader = (type: string, config?: IStringKeyMap, id?: string) => {
export const changeSecondUploader = (type: string, config?: IStringKeyMap) => {
if (!type) {
return
}
if (id) {
picgo.saveConfig({
[configPaths.picBed.secondUploaderId]: id,
})
}
if (config) {
picgo.saveConfig({
[configPaths.picBed.secondUploaderConfig]: config,

View File

@@ -261,7 +261,7 @@ class UploadTaskQueueManager {
const inserted = await GalleryDB.getInstance().insert(img)
windowManager.get(IWindowList.TRAY_WINDOW)?.webContents?.send('uploadFiles', [img])
windowManager.get(IWindowList.TRAY_WINDOW)?.webContents?.send('uploadFiles')
if (windowManager.has(IWindowList.SETTING_WINDOW)) {
windowManager.get(IWindowList.SETTING_WINDOW)!.webContents?.send('updateGallery')
}