diff --git a/CHANGELOG.md b/CHANGELOG.md index fb685df2..0bc45d86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +## :tada: 2.8.4 (2024-04-28) + + +### :sparkles: Features + +* **custom:** add feedback entry ([2087d9a](https://github.com/Kuingsmile/piclist/commit/2087d9a)) +* **custom:** auto refresh after change custom url ([939c907](https://github.com/Kuingsmile/piclist/commit/939c907)), closes [#191](https://github.com/Kuingsmile/piclist/issues/191) +* **custom:** change timestamp to milliseconds ([25648ea](https://github.com/Kuingsmile/piclist/commit/25648ea)), closes [#194](https://github.com/Kuingsmile/piclist/issues/194) + + +### :bug: Bug Fixes + +* **custom:** fix aws s3 urlprefix bug ([3681681](https://github.com/Kuingsmile/piclist/commit/3681681)) + + +### :pencil: Documentation + +* **custom:** prepare for 2.8.4 ([bcb4760](https://github.com/Kuingsmile/piclist/commit/bcb4760)) + + + ## :tada: 2.8.3 (2024-04-11) diff --git a/currentVersion.md b/currentVersion.md index 20f12774..4274de9a 100644 --- a/currentVersion.md +++ b/currentVersion.md @@ -1,9 +1,15 @@ -✨ Features -- 现在不再对gif图片进行格式转换 +### ✨ Features -🐛 Bug Fixes +- 管理功能 + - 现在修改自定义域名后会自动强制刷新当前页面 + - 现在第一次进入管理页面时默认获取云端最新文件列表 +- 现在内置s3图床默认允许自签证书 +- 现在高级重命名中的时间戳精确到毫秒 -- 修复了重新保存配置后图片水印功能失效的问题 -- 修复了同时打开主界面和mini窗口时,重命名窗口定位错误的问题 -- 修复了特殊情况下软件界面异常退出并导致后台CPU占用过高的问题 +### 🐛 Bug Fixes + +- 管理功能 + - 修复了强制https对本地图床没有生效的问题 +- 修复了不填写区域时,minio无法正常删除图片的问题 +- 修复了内置s3图床,配合minio使用时会额外添加桶名的问题 diff --git a/currentVersion_en.md b/currentVersion_en.md index 735ae34c..4f297a3e 100644 --- a/currentVersion_en.md +++ b/currentVersion_en.md @@ -1,9 +1,14 @@ -✨ Features +### ✨ Features -- Now no longer convert gif images +- Manage + - Now, after modifying the custom domain name, the current page will be automatically forced to refresh + - Now, the cloud-side latest file list is obtained by default when entering the management page for the first time +- Now the built-in s3 image bed defaults to allowing self-signed certificates +- Now the timestamp in advanced renaming is accurate to milliseconds -🐛 Bug Fixes +### 🐛 Bug Fixes -- Fix the problem that the image watermark function is invalid after re-saving the configuration -- Fix the problem that the rename window is positioned incorrectly when the main interface and mini window are opened at the same time -- Fix the problem that the software interface exits abnormally under special circumstances and causes high CPU usage in the background +- Manage + - Fixed the problem that forcing https does not take effect on the local image bed +- Fixed the problem that Minio cannot delete images normally when the region is not filled in +- Fixed the problem that the built-in s3 image bed will add an additional bucket name when used with Minio \ No newline at end of file diff --git a/package.json b/package.json index 60d71b28..a87ad66e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "piclist", - "version": "2.8.3", + "version": "2.8.4", "author": { "name": "Kuingsmile", "email": "pkukuing@gmail.com" @@ -68,7 +68,7 @@ "multer": "^1.4.5-lts.1", "node-ssh-no-cpu-features": "^1.0.1", "nodejs-file-downloader": "^4.12.1", - "piclist": "^1.8.5", + "piclist": "^1.8.7", "pinia": "^2.1.7", "pinia-plugin-persistedstate": "^3.2.0", "proxy-agent": "^5.0.0", diff --git a/public/i18n/en.yml b/public/i18n/en.yml index 543dccb7..cc21af5b 100644 --- a/public/i18n/en.yml +++ b/public/i18n/en.yml @@ -22,6 +22,7 @@ CONFIG_THING: Config ${c} FIND_NEW_VERSION: Find New Version NO_MORE_NOTICE: No More Notice SHOW_DEVTOOLS: Show Devtools +FEEDBACK: Feedback CURRENT_PICBED: Current Picbed START_WATCH_CLIPBOARD: Start Watch Clipboard STOP_WATCH_CLIPBOARD: Stop Watch Clipboard diff --git a/public/i18n/zh-CN.yml b/public/i18n/zh-CN.yml index 38a3cde2..740eb8f7 100644 --- a/public/i18n/zh-CN.yml +++ b/public/i18n/zh-CN.yml @@ -22,6 +22,7 @@ CONFIG_THING: 配置${c} FIND_NEW_VERSION: 发现新版本 NO_MORE_NOTICE: 以后不再提醒 SHOW_DEVTOOLS: 打开开发者工具 +FEEDBACK: 反馈问题 CURRENT_PICBED: 当前图床 START_WATCH_CLIPBOARD: 开始监听剪贴板 STOP_WATCH_CLIPBOARD: 停止监听剪贴板 diff --git a/public/i18n/zh-TW.yml b/public/i18n/zh-TW.yml index 48d5e0db..02b0d376 100644 --- a/public/i18n/zh-TW.yml +++ b/public/i18n/zh-TW.yml @@ -22,6 +22,7 @@ CONFIG_THING: 設定${c} FIND_NEW_VERSION: 發現新版本 NO_MORE_NOTICE: 以後不再提醒 SHOW_DEVTOOLS: 開啟開發者工具 +FEEDBACK: 問題反饋 CURRENT_PICBED: 當前圖床 START_WATCH_CLIPBOARD: 開始監聽剪貼簿 STOP_WATCH_CLIPBOARD: 停止監聽剪貼簿 diff --git a/src/main/apis/app/window/windowManager.ts b/src/main/apis/app/window/windowManager.ts index 195ba2ce..2d23b6c6 100644 --- a/src/main/apis/app/window/windowManager.ts +++ b/src/main/apis/app/window/windowManager.ts @@ -10,22 +10,22 @@ import { BrowserWindow } from 'electron' import { IWindowList } from '#/types/enum' class WindowManager implements IWindowManager { - private windowMap: Map = new Map() - private windowIdMap: Map = new Map() + #windowMap: Map = new Map() + #windowIdMap: Map = new Map() create (name: IWindowList) { const windowConfig: IWindowListItem = windowList.get(name)! if (windowConfig.isValid) { if (!windowConfig.multiple) { - if (this.has(name)) return this.windowMap.get(name)! + if (this.has(name)) return this.#windowMap.get(name)! } const window = new BrowserWindow(windowConfig.options()) const id = window.id if (windowConfig.multiple) { - this.windowMap.set(`${name}_${window.id}`, window) - this.windowIdMap.set(window.id, `${name}_${window.id}`) + this.#windowMap.set(`${name}_${window.id}`, window) + this.#windowIdMap.set(window.id, `${name}_${window.id}`) } else { - this.windowMap.set(name, window) - this.windowIdMap.set(window.id, name) + this.#windowMap.set(name, window) + this.#windowIdMap.set(window.id, name) } windowConfig.callback(window, this) window.on('close', () => { @@ -39,7 +39,7 @@ class WindowManager implements IWindowManager { get (name: IWindowList) { if (this.has(name)) { - return this.windowMap.get(name)! + return this.#windowMap.get(name)! } else { const window = this.create(name) return window @@ -47,24 +47,24 @@ class WindowManager implements IWindowManager { } has (name: IWindowList) { - return this.windowMap.has(name) + return this.#windowMap.has(name) } deleteById = (id: number) => { - const name = this.windowIdMap.get(id) + const name = this.#windowIdMap.get(id) if (name) { - this.windowMap.delete(name) - this.windowIdMap.delete(id) + this.#windowMap.delete(name) + this.#windowIdMap.delete(id) } } getAvailableWindow (isSkipMiniWindow = false) { - const miniWindow = this.windowMap.get(IWindowList.MINI_WINDOW) + const miniWindow = this.#windowMap.get(IWindowList.MINI_WINDOW) if (miniWindow && miniWindow.isVisible() && !isSkipMiniWindow) { return miniWindow } else { - const settingWindow = this.windowMap.get(IWindowList.SETTING_WINDOW) - const trayWindow = this.windowMap.get(IWindowList.TRAY_WINDOW) + const settingWindow = this.#windowMap.get(IWindowList.SETTING_WINDOW) + const trayWindow = this.#windowMap.get(IWindowList.TRAY_WINDOW) return settingWindow || trayWindow || this.create(IWindowList.SETTING_WINDOW)! } } diff --git a/src/main/apis/core/datastore/index.ts b/src/main/apis/core/datastore/index.ts index 868d3e84..95bf4eb7 100644 --- a/src/main/apis/core/datastore/index.ts +++ b/src/main/apis/core/datastore/index.ts @@ -24,12 +24,12 @@ const CONFIG_PATH: string = dbPathChecker() export const DB_PATH: string = getGalleryDBPath().dbPath class ConfigStore { - private db: JSONStore + #db: JSONStore constructor () { - this.db = new JSONStore(CONFIG_PATH) + this.#db = new JSONStore(CONFIG_PATH) - if (!this.db.has('picBed')) { - this.db.set('picBed', { + if (!this.#db.has('picBed')) { + this.#db.set('picBed', { current: 'smms', // deprecated uploader: 'smms', smms: { @@ -38,8 +38,8 @@ class ConfigStore { }) } - if (!this.db.has(configPaths.settings.shortKey._path)) { - this.db.set(configPaths.settings.shortKey['picgo:upload'], { + if (!this.#db.has(configPaths.settings.shortKey._path)) { + this.#db.set(configPaths.settings.shortKey['picgo:upload'], { enable: true, key: 'CommandOrControl+Shift+P', name: 'upload', @@ -50,31 +50,31 @@ class ConfigStore { } flush () { - this.db = new JSONStore(CONFIG_PATH) + this.#db = new JSONStore(CONFIG_PATH) } read () { - this.db.read() - return this.db + this.#db.read() + return this.#db } get (key = ''): any { if (key === '') { - return this.db.read() + return this.#db.read() } - return this.db.get(key) + return this.#db.get(key) } set (key: string, value: any): void { - return this.db.set(key, value) + return this.#db.set(key, value) } has (key: string) { - return this.db.has(key) + return this.#db.has(key) } unset (key: string, value: any): boolean { - return this.db.unset(key, value) + return this.#db.unset(key, value) } getConfigPath () { @@ -88,16 +88,16 @@ export default db // v2.3.0 add gallery db class GalleryDB { - private static instance: DBStore + static #instance: DBStore private constructor () { console.log('init gallery db') } - public static getInstance (): DBStore { - if (!GalleryDB.instance) { - GalleryDB.instance = new DBStore(DB_PATH, 'gallery') + static getInstance (): DBStore { + if (!GalleryDB.#instance) { + GalleryDB.#instance = new DBStore(DB_PATH, 'gallery') } - return GalleryDB.instance + return GalleryDB.#instance } } diff --git a/src/main/apis/gui/index.ts b/src/main/apis/gui/index.ts index 1a1eff4e..72e4ed27 100644 --- a/src/main/apis/gui/index.ts +++ b/src/main/apis/gui/index.ts @@ -37,7 +37,7 @@ class GuiApi implements IGuiApi { console.log('init guiapi') } - public static getInstance (): GuiApi { + static getInstance (): GuiApi { if (!GuiApi.instance) { GuiApi.instance = new GuiApi() } diff --git a/src/main/events/remotes/menu.ts b/src/main/events/remotes/menu.ts index 05cf1c01..3ad18f2c 100644 --- a/src/main/events/remotes/menu.ts +++ b/src/main/events/remotes/menu.ts @@ -2,7 +2,7 @@ import pkg from 'root/package.json' // Electron modules -import { Menu, BrowserWindow, app, dialog } from 'electron' +import { Menu, BrowserWindow, app, dialog, shell } from 'electron' // Custom utilities and modules import windowManager from 'apis/app/window/windowManager' @@ -140,6 +140,13 @@ const buildMainPageMenu = (win: BrowserWindow) => { click () { win?.webContents?.openDevTools({ mode: 'detach' }) } + }, + { + label: T('FEEDBACK'), + click () { + const url = 'https://github.com/Kuingsmile/PicList/issues' + shell.openExternal(url) + } } ] // @ts-ignore diff --git a/src/main/lifeCycle/index.ts b/src/main/lifeCycle/index.ts index 92a55ad7..f5789f69 100644 --- a/src/main/lifeCycle/index.ts +++ b/src/main/lifeCycle/index.ts @@ -135,7 +135,7 @@ autoUpdater.on('error', (err) => { }) class LifeCycle { - private async beforeReady () { + async #beforeReady () { protocol.registerSchemesAsPrivileged([{ scheme: 'picgo', privileges: { secure: true, standard: true } }]) // fix the $PATH in macOS & linux fixPath() @@ -148,7 +148,7 @@ class LifeCycle { busEventList.listen() } - private onReady () { + #onReady () { const readyFunction = async () => { createProtocol('picgo') windowManager.create(IWindowList.TRAY_WINDOW) @@ -228,7 +228,7 @@ class LifeCycle { app.whenReady().then(readyFunction) } - private onRunning () { + #onRunning () { app.on('second-instance', (event, commandLine, workingDirectory) => { logger.info('detect second instance') const result = handleStartUpFiles(commandLine, workingDirectory) @@ -263,7 +263,7 @@ class LifeCycle { } } - private onQuit () { + #onQuit () { app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() @@ -298,10 +298,10 @@ class LifeCycle { if (!gotTheLock) { app.quit() } else { - await this.beforeReady() - this.onReady() - this.onRunning() - this.onQuit() + await this.#beforeReady() + this.#onReady() + this.#onRunning() + this.#onQuit() } } } diff --git a/src/main/manage/datastore/db.ts b/src/main/manage/datastore/db.ts index a48b6146..5bd25197 100644 --- a/src/main/manage/datastore/db.ts +++ b/src/main/manage/datastore/db.ts @@ -4,22 +4,22 @@ import { IJSON } from '@picgo/store/dist/types' import { ManageApiType, ManageConfigType } from '~/universal/types/manage' class ManageDB { - private readonly ctx: ManageApiType - private readonly db: JSONStore + readonly #ctx: ManageApiType + readonly #db: JSONStore constructor (ctx: ManageApiType) { - this.ctx = ctx - this.db = new JSONStore(this.ctx.configPath) + this.#ctx = ctx + this.#db = new JSONStore(this.#ctx.configPath) let initParams: IStringKeyMap = { picBed: {}, settings: {}, currentPicBed: 'placeholder' } for (let key in initParams) { - if (!this.db.has(key)) { + if (!this.#db.has(key)) { try { - this.db.set(key, initParams[key]) + this.#db.set(key, initParams[key]) } catch (e: any) { - this.ctx.logger.error(e) + this.#ctx.logger.error(e) throw e } } @@ -27,27 +27,27 @@ class ManageDB { } read (flush?: boolean): IJSON { - return this.db.read(flush) + return this.#db.read(flush) } get (key: string = ''): any { this.read(true) - return this.db.get(key) + return this.#db.get(key) } set (key: string, value: any): void { this.read(true) - return this.db.set(key, value) + return this.#db.set(key, value) } has (key: string): boolean { this.read(true) - return this.db.has(key) + return this.#db.has(key) } unset (key: string, value: any): boolean { this.read(true) - return this.db.unset(key, value) + return this.#db.unset(key, value) } saveConfig (config: Partial): void { diff --git a/src/main/manage/datastore/upDownTaskQueue.ts b/src/main/manage/datastore/upDownTaskQueue.ts index 019d824e..fe2b8af1 100644 --- a/src/main/manage/datastore/upDownTaskQueue.ts +++ b/src/main/manage/datastore/upDownTaskQueue.ts @@ -69,7 +69,7 @@ class UpDownTaskQueue { this.restore() } - public static getInstance () { + static getInstance () { if (!UpDownTaskQueue.instance) { UpDownTaskQueue.instance = new UpDownTaskQueue() } diff --git a/src/main/manage/utils/logger.ts b/src/main/manage/utils/logger.ts index d05453ee..abab5d63 100644 --- a/src/main/manage/utils/logger.ts +++ b/src/main/manage/utils/logger.ts @@ -10,49 +10,49 @@ import { enforceNumber, isDev } from '#/utils/common' import { configPaths } from '~/universal/utils/configPaths' export class ManageLogger implements ILogger { - private readonly level = { + readonly #level = { [ILogType.success]: 'green', [ILogType.info]: 'blue', [ILogType.warn]: 'yellow', [ILogType.error]: 'red' } - private readonly ctx: ManageApiType - private logLevel!: string - private logPath!: string + readonly #ctx: ManageApiType + #logLevel!: string + #logPath!: string constructor (ctx: ManageApiType) { - this.ctx = ctx + this.#ctx = ctx } - private handleLog (type: ILogType, ...msg: ILogArgvTypeWithError[]): void { - const logHeader = chalk[this.level[type] as ILogColor]( + #handleLog (type: ILogType, ...msg: ILogArgvTypeWithError[]): void { + const logHeader = chalk[this.#level[type] as ILogColor]( `[PicList ${type.toUpperCase()}]` ) console.log(logHeader, ...msg) - this.logLevel = this.ctx.getConfig(configPaths.settings.logLevel) - this.logPath = - this.ctx.getConfig>(configPaths.settings.logPath) || - path.join(this.ctx.baseDir, './manage.log') + this.#logLevel = this.#ctx.getConfig(configPaths.settings.logLevel) + this.#logPath = + this.#ctx.getConfig>(configPaths.settings.logPath) || + path.join(this.#ctx.baseDir, './manage.log') setTimeout(() => { try { - const result = this.checkLogFileIsLarge(this.logPath) + const result = this.#checkLogFileIsLarge(this.#logPath) if (result.isLarge) { const warningMsg = `Log file is too large (> ${ result.logFileSizeLimit! / 1024 / 1024 || '10' } MB), recreate log file` console.log(chalk.yellow('[PicList WARN]:'), warningMsg) - this.recreateLogFile(this.logPath) + this.#recreateLogFile(this.#logPath) msg.unshift(warningMsg) } - this.handleWriteLog(this.logPath, type, ...msg) + this.#handleWriteLog(this.#logPath, type, ...msg) } catch (e) { console.error('[PicList Error] on checking log file size', e) } }, 0) } - private checkLogFileIsLarge (logPath: string): { + #checkLogFileIsLarge (logPath: string): { isLarge: boolean logFileSize?: number logFileSizeLimit?: number @@ -61,7 +61,7 @@ export class ManageLogger implements ILogger { const logFileSize = fs.statSync(logPath).size const logFileSizeLimit = enforceNumber( - this.ctx.getConfig>( + this.#ctx.getConfig>( configPaths.settings.logFileSizeLimit ) || 10 ) * @@ -79,23 +79,23 @@ export class ManageLogger implements ILogger { } } - private recreateLogFile (logPath: string): void { + #recreateLogFile (logPath: string): void { if (fs.existsSync(logPath)) { fs.unlinkSync(logPath) fs.createFileSync(logPath) } } - private handleWriteLog ( + #handleWriteLog ( logPath: string, type: string, ...msg: ILogArgvTypeWithError[] ): void { try { - if (this.checkLogLevel(type, this.logLevel)) { + if (this.#checkLogLevel(type, this.#logLevel)) { let log = `${dayjs().format('YYYY-MM-DD HH:mm:ss')} [PicList ${type.toUpperCase()}] ` msg.forEach((item: ILogArgvTypeWithError) => { - log += this.formatLogItem(item, type) + log += this.#formatLogItem(item, type) }) log += '\n' fs.appendFileSync(logPath, log) @@ -105,7 +105,7 @@ export class ManageLogger implements ILogger { } } - private formatLogItem (item: ILogArgvTypeWithError, type: string): string { + #formatLogItem (item: ILogArgvTypeWithError, type: string): string { let result = '' if (item instanceof Error && type === 'error') { result += `\n------Error Stack Begin------\n${util.format(item?.stack)}\n-------Error Stack End------- ` @@ -121,7 +121,7 @@ export class ManageLogger implements ILogger { return result } - private checkLogLevel ( + #checkLogLevel ( type: string, level: undefined | string | string[] ): boolean { @@ -135,24 +135,24 @@ export class ManageLogger implements ILogger { } success (...msq: ILogArgvType[]): void { - return this.handleLog(ILogType.success, ...msq) + return this.#handleLog(ILogType.success, ...msq) } info (...msq: ILogArgvType[]): void { - return this.handleLog(ILogType.info, ...msq) + return this.#handleLog(ILogType.info, ...msq) } error (...msq: ILogArgvTypeWithError[]): void { - return this.handleLog(ILogType.error, ...msq) + return this.#handleLog(ILogType.error, ...msq) } warn (...msq: ILogArgvType[]): void { - return this.handleLog(ILogType.warn, ...msq) + return this.#handleLog(ILogType.warn, ...msq) } debug (...msq: ILogArgvType[]): void { if (isDev) { - this.handleLog(ILogType.info, ...msq) + this.#handleLog(ILogType.info, ...msq) } } } diff --git a/src/main/manage/utils/threadPool.ts b/src/main/manage/utils/threadPool.ts deleted file mode 100644 index 70bef7e9..00000000 --- a/src/main/manage/utils/threadPool.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Worker, WorkerOptions } from 'worker_threads' - -interface Task { - data: any - workerOptions: WorkerOptions | undefined - resolve: (result: any) => void - reject: (error: any) => void -} - -class ThreadPool { - private size: number - private workerPath: string - private availablePool: Worker[] - private taskQueue: Task[] - private busyPool: Worker[] - private callBackList: any[] - - constructor (size: number, workerPath: string) { - this.size = size - this.workerPath = workerPath - this.availablePool = [] - this.busyPool = [] - for (let i = 0; i < this.size; i++) { - this.availablePool.push(new Worker(this.workerPath)) - } - this.taskQueue = [] - this.callBackList = [] - this.init() - } - - private init () { - for (const worker of this.availablePool) { - worker.on('message', (result) => { - const { data } = result - this.callBackList.shift()(data) - this.busyPool = this.busyPool.filter((w) => w.threadId !== worker.threadId) - this.availablePool.push(worker) - this.processQueue() - }) - } - } - - private processQueue () { - if (this.taskQueue.length === 0) return - if (this.availablePool.length === 0) return - const task = this.taskQueue.shift() - const worker = this.availablePool.pop() - if (worker && task) { - this.callBackList.push(task.resolve) - this.busyPool.push(worker) - worker.postMessage(task.data) - } - } - - public async addTask (data: any, workerOptions?: WorkerOptions): Promise { - return new Promise((resolve, reject) => { - this.taskQueue.push({ data, workerOptions, resolve, reject }) - this.processQueue() - }) - } - - public async destroy (): Promise { - const terminatePromises = this.availablePool.map((worker) => new Promise((resolve) => { - worker.terminate() - worker.on('exit', () => { - resolve(true) - }) - })) - await Promise.all(terminatePromises) - this.availablePool = [] - this.taskQueue = [] - } -} - -export default ThreadPool diff --git a/src/main/server/index.ts b/src/main/server/index.ts index 655b1294..5f565cc2 100644 --- a/src/main/server/index.ts +++ b/src/main/server/index.ts @@ -41,17 +41,17 @@ const uploadMulter = multer({ }) class Server { - private httpServer: http.Server - private config: IServerConfig + #httpServer: http.Server + #config: IServerConfig constructor () { - this.config = this.getConfigWithDefaults() - this.httpServer = http.createServer(this.handleRequest) + this.#config = this.getConfigWithDefaults() + this.#httpServer = http.createServer(this.#handleRequest) } getConfigWithDefaults () { let config = picgo.getConfig(configPaths.settings.server) - if (!this.isValidConfig(config)) { + if (!this.#isValidConfig(config)) { config = { port: DEFAULT_PORT, host: DEFAULT_HOST, enable: true } picgo.saveConfig({ [configPaths.settings.server]: config }) } @@ -59,20 +59,20 @@ class Server { return config } - private isValidConfig (config: IObj | undefined) { + #isValidConfig (config: IObj | undefined) { return config && config.port && config.host && (config.enable !== undefined) } - private handleRequest = (request: http.IncomingMessage, response: http.ServerResponse) => { + #handleRequest = (request: http.IncomingMessage, response: http.ServerResponse) => { switch (request.method) { case 'OPTIONS': handleResponse({ response }) break case 'POST': - this.handlePostRequest(request, response) + this.#handlePostRequest(request, response) break case 'GET': - this.handleGetRequest(request, response) + this.#handleGetRequest(request, response) break default: logger.warn(`[PicList Server] don't support [${request.method}] method`) @@ -81,7 +81,7 @@ class Server { } } - private handlePostRequest = (request: http.IncomingMessage, response: http.ServerResponse) => { + #handlePostRequest = (request: http.IncomingMessage, response: http.ServerResponse) => { const [url, query] = (request.url || '').split('?') if (!routers.getHandler(url, 'POST')) { logger.warn(`[PicList Server] don't support [${url}] endpoint`) @@ -160,7 +160,7 @@ class Server { } } - private handleGetRequest = (_request: http.IncomingMessage, response: http.ServerResponse) => { + #handleGetRequest = (_request: http.IncomingMessage, response: http.ServerResponse) => { const [url, query] = (_request.url || '').split('?') if (!routers.getHandler(url, 'GET')) { logger.info(`[PicList Server] don't support [${url}] endpoint`) @@ -178,23 +178,23 @@ class Server { } // port as string is a bug - private listen = (port: number | string) => { - logger.info(`[PicList Server] is listening at ${port} of ${this.config.host}`) + #listen = (port: number | string) => { + logger.info(`[PicList Server] is listening at ${port} of ${this.#config.host}`) if (typeof port === 'string') { port = parseInt(port, 10) } - this.httpServer.listen(port, this.config.host).on('error', async (err: ErrnoException) => { + this.#httpServer.listen(port, this.#config.host).on('error', async (err: ErrnoException) => { if (err.code === 'EADDRINUSE') { try { // make sure the system has a PicGo Server instance - await axios.post(ensureHTTPLink(`${this.config.host}:${port}/heartbeat`)) + await axios.post(ensureHTTPLink(`${this.#config.host}:${port}/heartbeat`)) logger.info(`[PicList Server] server is already running at ${port}`) this.shutdown(true) } catch (e) { logger.warn(`[PicList Server] ${port} is busy, trying with port ${(port as number) + 1}`) // fix a bug: not write an increase number to config file // to solve the auto number problem - this.listen((port as number) + 1) + this.#listen((port as number) + 1) } } else { logger.error('[PicList Server]', err) @@ -203,13 +203,13 @@ class Server { } startup () { - if (this.config.enable) { - this.listen(this.config.port) + if (this.#config.enable) { + this.#listen(this.#config.port) } } shutdown (hasStarted?: boolean) { - this.httpServer.close() + this.#httpServer.close() if (!hasStarted) { logger.info('[PicList Server] shutdown') } @@ -217,7 +217,7 @@ class Server { restart () { this.shutdown() - this.config = this.getConfigWithDefaults() + this.#config = this.getConfigWithDefaults() this.startup() } } diff --git a/src/main/server/router.ts b/src/main/server/router.ts index c1283869..2211be02 100644 --- a/src/main/server/router.ts +++ b/src/main/server/router.ts @@ -1,31 +1,31 @@ type HttpMethod = 'GET' | 'POST' class Router { - private router = new Map>() + #router = new Map>() - private addRoute (method: HttpMethod, url: string, callback: routeHandler, urlparams?: URLSearchParams): void { - if (!this.router.has(url)) { - this.router.set(url, new Map()) + #addRoute (method: HttpMethod, url: string, callback: routeHandler, urlparams?: URLSearchParams): void { + if (!this.#router.has(url)) { + this.#router.set(url, new Map()) } - this.router.get(url)!.set(method, { handler: callback, urlparams }) + this.#router.get(url)!.set(method, { handler: callback, urlparams }) } get (url: string, callback: routeHandler, urlparams?: URLSearchParams): void { - this.addRoute('GET', url, callback, urlparams) + this.#addRoute('GET', url, callback, urlparams) } post (url: string, callback: routeHandler, urlparams?: URLSearchParams): void { - this.addRoute('POST', url, callback, urlparams) + this.#addRoute('POST', url, callback, urlparams) } any (url: string, callback: routeHandler, urlparams?: URLSearchParams): void { - this.addRoute('GET', url, callback, urlparams) - this.addRoute('POST', url, callback, urlparams) + this.#addRoute('GET', url, callback, urlparams) + this.#addRoute('POST', url, callback, urlparams) } getHandler (url: string, method: HttpMethod) { - if (this.router.has(url)) { - const methods = this.router.get(url)! + if (this.#router.has(url)) { + const methods = this.#router.get(url)! if (methods.has(method)) { return methods.get(method) } diff --git a/src/main/server/webServer/index.ts b/src/main/server/webServer/index.ts index 22ab2bc4..7c5e27c7 100644 --- a/src/main/server/webServer/index.ts +++ b/src/main/server/webServer/index.ts @@ -40,8 +40,8 @@ function serveFile (res:http.ServerResponse, filePath: fs.PathLike) { } class WebServer { - private server!: http.Server - private config!: IStringKeyMap + #server!: http.Server + #config!: IStringKeyMap constructor () { this.loadConfig() @@ -49,7 +49,7 @@ class WebServer { } loadConfig (): void { - this.config = { + this.#config = { enableWebServer: picgo.getConfig(configPaths.settings.enableWebServer) || false, webServerHost: picgo.getConfig(configPaths.settings.webServerHost) || '0.0.0.0', webServerPort: picgo.getConfig(configPaths.settings.webServerPort) || 37777, @@ -58,9 +58,9 @@ class WebServer { } initServer (): void { - this.server = http.createServer((req, res) => { + this.#server = http.createServer((req, res) => { const requestPath = req.url?.split('?')[0] - const filePath = path.join(this.config.webServerPath, decodeURIComponent(requestPath || '')) + const filePath = path.join(this.#config.webServerPath, decodeURIComponent(requestPath || '')) try { const stats = fs.statSync(filePath) @@ -77,12 +77,12 @@ class WebServer { } start () { - if (this.config.enableWebServer) { - this.server + if (this.#config.enableWebServer) { + this.#server .listen( - this.config.webServerPort === 36699 ? 37777 : this.config.webServerPort, - this.config.webServerHost, () => { - logger.info(`Web server is running at http://${this.config.webServerHost}:${this.config.webServerPort}, root path is ${this.config.webServerPath}`) + this.#config.webServerPort === 36699 ? 37777 : this.#config.webServerPort, + this.#config.webServerHost, () => { + logger.info(`Web server is running at http://${this.#config.webServerHost}:${this.#config.webServerPort}, root path is ${this.#config.webServerPath}`) }) .on('error', (err) => { logger.error(err) @@ -93,7 +93,7 @@ class WebServer { } stop () { - this.server.close(() => { + this.#server.close(() => { logger.info('Web server is stopped') }) } diff --git a/src/main/utils/aesHelper.ts b/src/main/utils/aesHelper.ts index 6a1c4cdf..a974f80d 100644 --- a/src/main/utils/aesHelper.ts +++ b/src/main/utils/aesHelper.ts @@ -3,18 +3,15 @@ import picgo from '@core/picgo' import { DEFAULT_AES_PASSWORD } from '~/universal/utils/static' import { configPaths } from '~/universal/utils/configPaths' -function getDerivedKey (): Buffer { - const userPassword = picgo.getConfig(configPaths.settings.aesPassword) || DEFAULT_AES_PASSWORD - const fixedSalt = Buffer.from('a8b3c4d2e4f5098712345678feedc0de', 'hex') - const fixedIterations = 100000 - const keyLength = 32 - return crypto.pbkdf2Sync(userPassword, fixedSalt, fixedIterations, keyLength, 'sha512') -} - export class AESHelper { key: Buffer + constructor () { - this.key = getDerivedKey() + const userPassword = picgo.getConfig(configPaths.settings.aesPassword) || DEFAULT_AES_PASSWORD + const fixedSalt = Buffer.from('a8b3c4d2e4f5098712345678feedc0de', 'hex') + const fixedIterations = 100000 + const keyLength = 32 + this.key = crypto.pbkdf2Sync(userPassword, fixedSalt, fixedIterations, keyLength, 'sha512') } encrypt (plainText: string) { @@ -22,17 +19,15 @@ export class AESHelper { const cipher = crypto.createCipheriv('aes-256-cbc', this.key, iv) let encrypted = cipher.update(plainText, 'utf8', 'hex') encrypted += cipher.final('hex') - const encryptedData = `${iv.toString('hex')}:${encrypted}` - return encryptedData + return `${iv.toString('hex')}:${encrypted}` } decrypt (encryptedData: string) { - const parts = encryptedData.split(':') - if (parts.length !== 2) { + const [ivHex, encryptedText] = encryptedData.split(':') + if (!ivHex || !encryptedText) { return '{}' } - const iv = Buffer.from(parts[0], 'hex') - const encryptedText = parts[1] + const iv = Buffer.from(ivHex, 'hex') const decipher = crypto.createDecipheriv('aes-256-cbc', this.key, iv) let decrypted = decipher.update(encryptedText, 'hex', 'utf8') decrypted += decipher.final('utf8') diff --git a/src/main/utils/deleteFunc.ts b/src/main/utils/deleteFunc.ts index c808ab90..648a2050 100644 --- a/src/main/utils/deleteFunc.ts +++ b/src/main/utils/deleteFunc.ts @@ -134,12 +134,23 @@ export async function removeFileFromS3InMain (configMap: IStringKeyMap, dogeMode sessionToken: configMap.config.sessionToken } } - const client = new S3Client(s3Options) - const command = new DeleteObjectCommand({ - Bucket: bucketName, - Key: fileKey - }) - const result = await client.send(command) + let result: any + try { + const client = new S3Client(s3Options) + const command = new DeleteObjectCommand({ + Bucket: bucketName, + Key: fileKey + }) + result = await client.send(command) + } catch (err: any) { + s3Options.region = 'us-east-1' + const client = new S3Client(s3Options) + const command = new DeleteObjectCommand({ + Bucket: bucketName, + Key: fileKey + }) + result = await client.send(command) + } return result.$metadata.httpStatusCode === 204 } catch (err: any) { console.log(err) diff --git a/src/main/utils/sshClient.ts b/src/main/utils/sshClient.ts index b783a20a..13363bd5 100644 --- a/src/main/utils/sshClient.ts +++ b/src/main/utils/sshClient.ts @@ -11,11 +11,11 @@ class SSHClient { private static _client: NodeSSH private _isConnected = false - public static get instance (): SSHClient { + static get instance (): SSHClient { return this._instance || (this._instance = new this()) } - public static get client (): NodeSSH { + static get client (): NodeSSH { return this._client || (this._client = new NodeSSH()) } @@ -23,7 +23,7 @@ class SSHClient { return path.replace(/\\/g, '/') } - public async connect (config: ISftpPlistConfig): Promise { + async connect (config: ISftpPlistConfig): Promise { const { username, password, privateKey, passphrase } = config const loginInfo: Config = privateKey ? { username, privateKeyPath: privateKey, passphrase: passphrase || undefined } @@ -41,7 +41,7 @@ class SSHClient { } } - public async deleteFileSFTP (config: ISftpPlistConfig, remote: string): Promise { + async deleteFileSFTP (config: ISftpPlistConfig, remote: string): Promise { try { const client = new Client() const { username, password, privateKey, passphrase } = config @@ -162,7 +162,7 @@ class SSHClient { return SSHClient.client.isConnected() } - public close (): void { + close (): void { SSHClient.client.dispose() this._isConnected = false } diff --git a/src/renderer/apis/aliyun.ts b/src/renderer/apis/aliyun.ts index 2d255ad0..e5138504 100644 --- a/src/renderer/apis/aliyun.ts +++ b/src/renderer/apis/aliyun.ts @@ -6,17 +6,7 @@ interface IConfigMap { } export default class AliyunApi { - private static createClient (config: IConfigMap['config']): OSS { - const { accessKeyId, accessKeySecret, bucket, area } = config - return new OSS({ - accessKeyId, - accessKeySecret, - bucket, - region: area - }) - } - - private static getKey (fileName: string, path?: string): string { + static #getKey (fileName: string, path?: string): string { return path && path !== '/' ? `${path.replace(/^\/+|\/+$/, '')}/${fileName}` : fileName @@ -25,8 +15,8 @@ export default class AliyunApi { static async delete (configMap: IConfigMap): Promise { const { fileName, config } = configMap try { - const client = AliyunApi.createClient(config) - const key = AliyunApi.getKey(fileName, config.path) + const client = new OSS({ ...config, region: config.area }) + const key = AliyunApi.#getKey(fileName, config.path) const result = await client.delete(key) return result.res.status === 204 } catch (error) { diff --git a/src/renderer/apis/github.ts b/src/renderer/apis/github.ts index f0073e7e..f5e61653 100644 --- a/src/renderer/apis/github.ts +++ b/src/renderer/apis/github.ts @@ -7,13 +7,13 @@ interface IConfigMap { } export default class GithubApi { - private static createOctokit (token: string) { + static #createOctokit (token: string) { return new Octokit({ auth: token }) } - private static createKey (path: string | undefined, fileName: string): string { + static #createKey (path: string | undefined, fileName: string): string { const formatedFileName = fileName.replace(/%2F/g, '/') return path && path !== '/' ? `${path.replace(/^\/+|\/+$/, '')}/${formatedFileName}` @@ -23,8 +23,8 @@ export default class GithubApi { static async delete (configMap: IConfigMap): Promise { const { fileName, hash, config: { repo, token, branch, path } } = configMap const [owner, repoName] = repo.split('/') - const octokit = GithubApi.createOctokit(token) - const key = GithubApi.createKey(path, fileName) + const octokit = GithubApi.#createOctokit(token) + const key = GithubApi.#createKey(path, fileName) try { const { status } = await octokit.rest.repos.deleteFile({ owner, diff --git a/src/renderer/apis/imgur.ts b/src/renderer/apis/imgur.ts index dff5b3a9..11e7e411 100644 --- a/src/renderer/apis/imgur.ts +++ b/src/renderer/apis/imgur.ts @@ -5,28 +5,8 @@ interface IConfigMap { hash?: string } -interface IConfig { - headers: { - Authorization: string - } - timeout: number -} - export default class ImgurApi { - static baseUrl = 'https://api.imgur.com/3' - private static async makeRequest ( - method: 'delete', - url: string, - config: IConfig - ): Promise { - try { - const response: AxiosResponse = await axios[method](url, config) - return response.status === 200 - } catch (error) { - console.error(error) - return false - } - } + static #baseUrl = 'https://api.imgur.com/3' static async delete (configMap: IConfigMap): Promise { const { @@ -37,17 +17,22 @@ export default class ImgurApi { if (username && accessToken) { Authorization = `Bearer ${accessToken}` - apiUrl = `${ImgurApi.baseUrl}/account/${username}/image/${hash}` + apiUrl = `${ImgurApi.#baseUrl}/account/${username}/image/${hash}` } else if (clientId) { Authorization = `Client-ID ${clientId}` - apiUrl = `${ImgurApi.baseUrl}/image/${hash}` + apiUrl = `${ImgurApi.#baseUrl}/image/${hash}` } else { return false } - const requestConfig: IConfig = { - headers: { Authorization }, - timeout: 30000 + try { + const response: AxiosResponse = await axios.delete(apiUrl, { + headers: { Authorization }, + timeout: 30000 + }) + return response.status === 200 + } catch (error) { + console.error(error) + return false } - return ImgurApi.makeRequest('delete', apiUrl, requestConfig) } } diff --git a/src/renderer/apis/smms.ts b/src/renderer/apis/smms.ts index 11763431..ae2c3647 100644 --- a/src/renderer/apis/smms.ts +++ b/src/renderer/apis/smms.ts @@ -6,7 +6,7 @@ interface IConfigMap { } export default class SmmsApi { - private static readonly baseUrl = 'https://smms.app/api/v2' + static readonly #baseUrl = 'https://smms.app/api/v2' static async delete (configMap: IConfigMap): Promise { const { hash, config } = configMap @@ -19,7 +19,7 @@ export default class SmmsApi { try { const response: AxiosResponse = await axios.get( - `${SmmsApi.baseUrl}/delete/${hash}`, { + `${SmmsApi.#baseUrl}/delete/${hash}`, { headers: { Authorization: token }, diff --git a/src/renderer/apis/tcyun.ts b/src/renderer/apis/tcyun.ts index 19ce67cc..e4ff9d26 100644 --- a/src/renderer/apis/tcyun.ts +++ b/src/renderer/apis/tcyun.ts @@ -6,7 +6,7 @@ interface IConfigMap { } export default class TcyunApi { - private static createCOS (SecretId: string, SecretKey: string): COS { + static #createCOS (SecretId: string, SecretKey: string): COS { return new COS({ SecretId, SecretKey @@ -16,7 +16,7 @@ export default class TcyunApi { static async delete (configMap: IConfigMap): Promise { const { fileName, config: { secretId, secretKey, bucket, area, path } } = configMap try { - const cos = TcyunApi.createCOS(secretId, secretKey) + const cos = TcyunApi.#createCOS(secretId, secretKey) let key if (path === '/' || !path) { key = `/${fileName}` diff --git a/src/renderer/i18n/index.ts b/src/renderer/i18n/index.ts index d3c5a37f..08bf77ab 100644 --- a/src/renderer/i18n/index.ts +++ b/src/renderer/i18n/index.ts @@ -5,45 +5,45 @@ import bus from '@/utils/bus' import { builtinI18nList } from '#/i18n' export class I18nManager { - private i18n: I18n | null = null - private i18nFileList: II18nItem[] = builtinI18nList + #i18n: I18n | null = null + #i18nFileList: II18nItem[] = builtinI18nList - private getLanguageList () { + #getLanguageList () { ipcRenderer.send(GET_LANGUAGE_LIST) ipcRenderer.once(GET_LANGUAGE_LIST, (event, list: II18nItem[]) => { - this.i18nFileList = list + this.#i18nFileList = list }) } - private getCurrentLanguage () { + #getCurrentLanguage () { ipcRenderer.send(GET_CURRENT_LANGUAGE) ipcRenderer.once(GET_CURRENT_LANGUAGE, (event, lang: string, locales: ILocales) => { - this.setLocales(lang, locales) + this.#setLocales(lang, locales) bus.emit(FORCE_UPDATE) }) } - private setLocales (lang: string, locales: ILocales) { + #setLocales (lang: string, locales: ILocales) { const objectAdapter = new ObjectAdapter({ [lang]: locales }) - this.i18n = new I18n({ + this.#i18n = new I18n({ adapter: objectAdapter, defaultLanguage: lang }) } constructor () { - this.getCurrentLanguage() - this.getLanguageList() + this.#getCurrentLanguage() + this.#getLanguageList() ipcRenderer.on(SET_CURRENT_LANGUAGE, (event, lang: string, locales: ILocales) => { - this.setLocales(lang, locales) + this.#setLocales(lang, locales) bus.emit(FORCE_UPDATE) }) } T (key: ILocalesKey, args: IStringKeyMap = {}): string { - return this.i18n?.translate(key, args) || key + return this.#i18n?.translate(key, args) || key } setCurrentLanguage (lang: string) { @@ -51,7 +51,7 @@ export class I18nManager { } get languageList () { - return this.i18nFileList + return this.#i18nFileList } } diff --git a/src/renderer/manage/pages/bucketPage.vue b/src/renderer/manage/pages/bucketPage.vue index 8e78fdef..a08fbf99 100644 --- a/src/renderer/manage/pages/bucketPage.vue +++ b/src/renderer/manage/pages/bucketPage.vue @@ -21,7 +21,7 @@ style="width: 200px;" :persistent="false" teleported - @change="handleChangeCustomUrl" + @change="handleChangeCustomUrlInput" > ('picBed') const currentConfig = currentConfigs[configMap.alias] const currentTransformedConfig = JSON.parse(currentConfig.transformedConfig ?? '{}') @@ -2174,7 +2165,7 @@ async function initCustomDomainList () { currentCustomDomain.value = `https://${configMap.bucketName}.s3.amazonaws.com` } } - handleChangeCustomUrl() + await handleChangeCustomUrl() } else if (currentPicBedName.value === 'webdavplist') { const currentConfigs = await getConfig('picBed') const currentConfig = currentConfigs[configMap.alias] @@ -2188,17 +2179,20 @@ async function initCustomDomainList () { } currentCustomDomain.value = endpoint } - handleChangeCustomUrl() + await handleChangeCustomUrl() } else if (currentPicBedName.value === 'local' || currentPicBedName.value === 'sftp') { const currentConfigs = await getConfig('picBed') const currentConfig = currentConfigs[configMap.alias] const currentTransformedConfig = JSON.parse(currentConfig.transformedConfig ?? '{}') if (currentTransformedConfig[configMap.bucketName] && currentTransformedConfig[configMap.bucketName]?.customUrl) { currentCustomDomain.value = currentTransformedConfig[configMap.bucketName].customUrl ?? '' + if (manageStore.config.settings.isForceCustomUrlHttps && currentCustomDomain.value.startsWith('http://')) { + currentCustomDomain.value = currentCustomDomain.value.replace('http://', 'https://') + } } else { currentCustomDomain.value = '' } - handleChangeCustomUrl() + await handleChangeCustomUrl() } } @@ -2232,6 +2226,7 @@ async function resetParam (force: boolean = false) { fileSortSizeReverse.value = false fileSortTimeReverse.value = false if (!isAutoRefresh.value && !force && !paging.value) { + console.log('use cache') const cachedData = await searchExistFileList() if (cachedData.length > 0) { currentPageFilesInfo.push(...cachedData[0].value.fullList) @@ -2283,7 +2278,7 @@ watch(route, async (newRoute) => { const parsedConfigMap = JSON.parse(queryConfigMap) Object.assign(configMap, parsedConfigMap) await initCustomDomainList() - await resetParam(false) + await resetParam(true) isShowLoadingPage.value = false } }) @@ -2837,9 +2832,8 @@ async function getBucketFileListBackStage () { isLoadingData.value = true const fileTransferStore = useFileTransferStore() fileTransferStore.resetFileTransferList() - if (currentPicBedName.value === 'webdavplist' || - currentPicBedName.value === 'local' || - currentPicBedName.value === 'sftp') { + const picBedNamesArr = ['webdavplist', 'local', 'sftp'] + if (picBedNamesArr.includes(currentPicBedName.value)) { param.baseDir = configMap.baseDir param.webPath = configMap.webPath } @@ -3683,7 +3677,7 @@ onBeforeMount(async () => { await manageStore.refreshConfig() isShowLoadingPage.value = true await initCustomDomainList() - await resetParam(false) + await resetParam(true) isShowLoadingPage.value = false document.addEventListener('keydown', handleDetectShiftKey) document.addEventListener('keyup', handleDetectShiftKey) diff --git a/src/renderer/manage/pages/manageSetting.vue b/src/renderer/manage/pages/manageSetting.vue index 261ea880..30bca98e 100644 --- a/src/renderer/manage/pages/manageSetting.vue +++ b/src/renderer/manage/pages/manageSetting.vue @@ -618,7 +618,7 @@ async function initData () { form.isShowThumbnail = config.settings.isShowThumbnail ?? false form.isShowList = config.settings.isShowList ?? false form.isIgnoreCase = config.settings.isIgnoreCase ?? false - form.isForceCustomUrlHttps = config.settings.isForceCustomUrlHttps ?? true + form.isForceCustomUrlHttps = config.settings.isForceCustomUrlHttps ?? false form.isEncodeUrl = config.settings.isEncodeUrl ?? false form.isUploadKeepDirStructure = config.settings.isUploadKeepDirStructure ?? true form.isDownloadFileKeepDirStructure = config.settings.isDownloadKeepDirStructure ?? false diff --git a/src/renderer/utils/db.ts b/src/renderer/utils/db.ts index 5b3ad143..fd7181ea 100644 --- a/src/renderer/utils/db.ts +++ b/src/renderer/utils/db.ts @@ -25,36 +25,36 @@ import { getRawData } from './common' export class GalleryDB implements IGalleryDB { async get (filter?: IFilter): Promise> { - const res = await this.msgHandler>(PICGO_GET_DB, filter) + const res = await this.#msgHandler>(PICGO_GET_DB, filter) return res } async insert (value: T): Promise> { - const res = await this.msgHandler>(PICGO_INSERT_DB, value) + const res = await this.#msgHandler>(PICGO_INSERT_DB, value) return res } async insertMany (value: T[]): Promise[]> { - const res = await this.msgHandler[]>(PICGO_INSERT_MANY_DB, value) + const res = await this.#msgHandler[]>(PICGO_INSERT_MANY_DB, value) return res } async updateById (id: string, value: IObject): Promise { - const res = await this.msgHandler(PICGO_UPDATE_BY_ID_DB, id, value) + const res = await this.#msgHandler(PICGO_UPDATE_BY_ID_DB, id, value) return res } async getById (id: string): Promise | undefined> { - const res = await this.msgHandler | undefined>(PICGO_GET_BY_ID_DB, id) + const res = await this.#msgHandler | undefined>(PICGO_GET_BY_ID_DB, id) return res } async removeById (id: string): Promise { - const res = await this.msgHandler(PICGO_REMOVE_BY_ID_DB, id) + const res = await this.#msgHandler(PICGO_REMOVE_BY_ID_DB, id) return res } - private msgHandler (method: string, ...args: any[]): Promise { + #msgHandler (method: string, ...args: any[]): Promise { return new Promise((resolve) => { const callbackId = uuid() const callback = (event: IpcRendererEvent, data: T, returnCallbackId: string) => { diff --git a/src/universal/types/i18n.d.ts b/src/universal/types/i18n.d.ts index 08de9b1e..baa9b2a4 100644 --- a/src/universal/types/i18n.d.ts +++ b/src/universal/types/i18n.d.ts @@ -23,6 +23,7 @@ interface ILocales { FIND_NEW_VERSION: string NO_MORE_NOTICE: string SHOW_DEVTOOLS: string + FEEDBACK: string CURRENT_PICBED: string START_WATCH_CLIPBOARD: string STOP_WATCH_CLIPBOARD: string diff --git a/yarn.lock b/yarn.lock index 92dec1bd..b897d756 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12397,10 +12397,10 @@ performance-now@^2.1.0: resolved "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -piclist@^1.8.5: - version "1.8.5" - resolved "https://registry.yarnpkg.com/piclist/-/piclist-1.8.5.tgz#982f481420c83cb42d6c1ff07bd2ad467ed71539" - integrity sha512-RrSWViLbgTb3VeZ5Poajo6oyRbpFovF3g48/JiyMG6XChdt7BZ1dD/URmPzfrQNZM+bwunSwJr1yjhK87cSvwA== +piclist@^1.8.7: + version "1.8.7" + resolved "https://registry.yarnpkg.com/piclist/-/piclist-1.8.7.tgz#aa40af42762b857ac0c45a097421278a301320cf" + integrity sha512-asSc588Fh1aMpIq/guqqHGhZb0wsLn+wZllKbtznDasbh4zNZvQECNDxRGVtmvsSYJlR+V+yyA2Z85AW/aQqyA== dependencies: "@aws-sdk/client-s3" "3.421.0" "@aws-sdk/lib-storage" "3.421.0"