Feature(custom): refactor the logic of config data

This commit is contained in:
Kuingsmile
2026-01-14 14:33:56 +08:00
parent fc53c27f8f
commit d98f955a76
36 changed files with 373 additions and 467 deletions

View File

@@ -1,5 +1,6 @@
import path from 'node:path' import path from 'node:path'
import { defaultDir } from '@core/datastore/dirs'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
import axios from 'axios' import axios from 'axios'
import { app, clipboard, dialog, shell } from 'electron' import { app, clipboard, dialog, shell } from 'electron'
@@ -14,9 +15,7 @@ const REMOTE_NOTICE_URL = 'https://release.piclist.cn/remote-notice.json'
const REMOTE_NOTICE_LOCAL_STORAGE_FILE = 'piclist-remote-notice.json' const REMOTE_NOTICE_LOCAL_STORAGE_FILE = 'piclist-remote-notice.json'
const STORE_PATH = app.getPath('userData') const REMOTE_NOTICE_LOCAL_STORAGE_PATH = path.join(defaultDir(), REMOTE_NOTICE_LOCAL_STORAGE_FILE)
const REMOTE_NOTICE_LOCAL_STORAGE_PATH = path.join(STORE_PATH, REMOTE_NOTICE_LOCAL_STORAGE_FILE)
class RemoteNoticeHandler { class RemoteNoticeHandler {
private remoteNotice: IRemoteNotice | null = null private remoteNotice: IRemoteNotice | null = null

View File

@@ -1,5 +1,4 @@
import bus from '@core/bus' import bus from '@core/bus'
import db from '@core/datastore'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import shortKeyService from 'apis/app/shortKey/shortKeyService' import shortKeyService from 'apis/app/shortKey/shortKeyService'
@@ -23,7 +22,7 @@ class ShortKeyHandler {
} }
private initBuiltInShortKey() { private initBuiltInShortKey() {
const commands = db.get(configPaths.settings.shortKey._path) as IShortKeyConfigs const commands = picgo.getConfig<IShortKeyConfigs>(configPaths.settings.shortKey._path) || {}
Object.keys(commands) Object.keys(commands)
.filter(item => item.includes('picgo:')) .filter(item => item.includes('picgo:'))
.forEach(command => { .forEach(command => {
@@ -51,8 +50,8 @@ class ShortKeyHandler {
const commands = plugin.commands(picgo) as IPluginShortKeyConfig[] const commands = plugin.commands(picgo) as IPluginShortKeyConfig[]
for (const cmd of commands) { for (const cmd of commands) {
const command = `${item}:${cmd.name}` const command = `${item}:${cmd.name}`
if (db.has(`settings.shortKey[${command}]`)) { const commandConfig = picgo.getConfig<IShortKeyConfig | undefined>(`settings.shortKey[${command}]`)
const commandConfig = db.get(`settings.shortKey.${command}`) as IShortKeyConfig if (commandConfig) {
// if disabled, don't register #534 // if disabled, don't register #534
if (commandConfig.enable) { if (commandConfig.enable) {
this.registerShortKey(commandConfig, command, cmd.handle, false) this.registerShortKey(commandConfig, command, cmd.handle, false)
@@ -159,8 +158,8 @@ class ShortKeyHandler {
const commands = plugin.commands(picgo) as IPluginShortKeyConfig[] const commands = plugin.commands(picgo) as IPluginShortKeyConfig[]
for (const cmd of commands) { for (const cmd of commands) {
const command = `${pluginName}:${cmd.name}` const command = `${pluginName}:${cmd.name}`
if (db.has(`settings.shortKey[${command}]`)) { const commandConfig = picgo.getConfig<IShortKeyConfig | undefined>(`settings.shortKey[${command}]`)
const commandConfig = db.get(`settings.shortKey[${command}]`) as IShortKeyConfig if (commandConfig) {
this.registerShortKey(commandConfig, command, cmd.handle, false) this.registerShortKey(commandConfig, command, cmd.handle, false)
} else { } else {
this.registerShortKey(cmd, command, cmd.handle, true) this.registerShortKey(cmd, command, cmd.handle, true)
@@ -170,7 +169,7 @@ class ShortKeyHandler {
} }
unregisterPluginShortKey(pluginName: string) { unregisterPluginShortKey(pluginName: string) {
const commands = db.get(configPaths.settings.shortKey._path) as IShortKeyConfigs const commands = picgo.getConfig<IShortKeyConfigs>(configPaths.settings.shortKey._path) || {}
const keyList = Object.keys(commands) const keyList = Object.keys(commands)
.filter(command => command.includes(pluginName)) .filter(command => command.includes(pluginName))
.map(command => { .map(command => {
@@ -182,7 +181,7 @@ class ShortKeyHandler {
keyList.forEach(item => { keyList.forEach(item => {
globalShortcut.unregister(item.key) globalShortcut.unregister(item.key)
shortKeyService.unregisterCommand(item.command) shortKeyService.unregisterCommand(item.command)
db.unset(configPaths.settings.shortKey._path, item.command) picgo.removeConfig(configPaths.settings.shortKey._path, item.command)
}) })
} }
} }

View File

@@ -1,4 +1,4 @@
import db, { GalleryDB } from '@core/datastore' import { GalleryDB } from '@core/datastore'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import uploader from 'apis/app/uploader' import uploader from 'apis/app/uploader'
import { uploadClipboardFiles } from 'apis/app/uploader/apis' import { uploadClipboardFiles } from 'apis/app/uploader/apis'
@@ -36,7 +36,7 @@ import uploadDarkPng from '../../../../../resources/upload-dark.png?asset&asarUn
let contextMenu: Menu | null let contextMenu: Menu | null
export function setDockMenu() { export function setDockMenu() {
const isListeningClipboard = db.get(configPaths.settings.isListeningClipboard) || false const isListeningClipboard = picgo.getConfig<boolean | undefined>(configPaths.settings.isListeningClipboard) || false
const dockMenu = Menu.buildFromTemplate([ const dockMenu = Menu.buildFromTemplate([
{ {
label: $t('OPEN_MAIN_WINDOW'), label: $t('OPEN_MAIN_WINDOW'),
@@ -45,7 +45,7 @@ export function setDockMenu() {
{ {
label: $t('START_WATCH_CLIPBOARD'), label: $t('START_WATCH_CLIPBOARD'),
click() { click() {
db.set(configPaths.settings.isListeningClipboard, true) picgo.saveConfig({ [configPaths.settings.isListeningClipboard]: true })
clipboardPoll.startListening() clipboardPoll.startListening()
clipboardPoll.on('change', () => { clipboardPoll.on('change', () => {
picgo.log.info('clipboard changed') picgo.log.info('clipboard changed')
@@ -58,7 +58,7 @@ export function setDockMenu() {
{ {
label: $t('STOP_WATCH_CLIPBOARD'), label: $t('STOP_WATCH_CLIPBOARD'),
click() { click() {
db.set(configPaths.settings.isListeningClipboard, false) picgo.saveConfig({ [configPaths.settings.isListeningClipboard]: false })
clipboardPoll.stopListening() clipboardPoll.stopListening()
clipboardPoll.removeAllListeners() clipboardPoll.removeAllListeners()
setDockMenu() setDockMenu()
@@ -108,12 +108,12 @@ export function createMenu() {
export function createContextMenu() { export function createContextMenu() {
const ClipboardWatcher = clipboardPoll const ClipboardWatcher = clipboardPoll
const isListeningClipboard = db.get(configPaths.settings.isListeningClipboard) || false const isListeningClipboard = picgo.getConfig<boolean | undefined>(configPaths.settings.isListeningClipboard) || false
const isMiniWindowVisible = const isMiniWindowVisible =
windowManager.has(IWindowList.MINI_WINDOW) && windowManager.get(IWindowList.MINI_WINDOW)!.isVisible() windowManager.has(IWindowList.MINI_WINDOW) && windowManager.get(IWindowList.MINI_WINDOW)!.isVisible()
const startWatchClipboard = () => { const startWatchClipboard = () => {
db.set(configPaths.settings.isListeningClipboard, true) picgo.saveConfig({ [configPaths.settings.isListeningClipboard]: true })
ClipboardWatcher.startListening() ClipboardWatcher.startListening()
ClipboardWatcher.on('change', () => { ClipboardWatcher.on('change', () => {
picgo.log.info('clipboard changed') picgo.log.info('clipboard changed')
@@ -123,7 +123,7 @@ export function createContextMenu() {
} }
const stopWatchClipboard = () => { const stopWatchClipboard = () => {
db.set(configPaths.settings.isListeningClipboard, false) picgo.saveConfig({ [configPaths.settings.isListeningClipboard]: false })
ClipboardWatcher.stopListening() ClipboardWatcher.stopListening()
ClipboardWatcher.removeAllListeners() ClipboardWatcher.removeAllListeners()
createContextMenu() createContextMenu()
@@ -284,7 +284,8 @@ export function createTray(tooltip: string) {
windowManager.get(IWindowList.TRAY_WINDOW)!.hide() windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
} }
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW) const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
const autoCloseMiniWindow = db.get(configPaths.settings.autoCloseMiniWindow) || false const autoCloseMiniWindow =
picgo.getConfig<boolean | undefined>(configPaths.settings.autoCloseMiniWindow) || false
settingWindow!.show() settingWindow!.show()
settingWindow!.focus() settingWindow!.focus()
if (windowManager.has(IWindowList.MINI_WINDOW) && autoCloseMiniWindow) { if (windowManager.has(IWindowList.MINI_WINDOW) && autoCloseMiniWindow) {
@@ -309,13 +310,13 @@ export function createTray(tooltip: string) {
// so the tray window must be available // so the tray window must be available
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
;(tray as any).on('drop-files', async (_: Event, files: string[]) => { ;(tray as any).on('drop-files', async (_: Event, files: string[]) => {
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN const pasteStyle = picgo.getConfig<string>(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
const rawInput = cloneDeep(files) const rawInput = cloneDeep(files)
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)! const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
const res = await uploader.setWebContents(trayWindow.webContents).uploadReturnCtx(files) const res = await uploader.setWebContents(trayWindow.webContents).uploadReturnCtx(files)
const imgs = res[0] ? res[0] : false const imgs = res[0] ? res[0] : false
const backImgs = res[1] ? res[1] : false const backImgs = res[1] ? res[1] : false
const deleteLocalFile = db.get(configPaths.settings.deleteLocalFile) || false const deleteLocalFile = picgo.getConfig<boolean | undefined>(configPaths.settings.deleteLocalFile) || false
if (imgs !== false) { if (imgs !== false) {
const pasteText: string[] = [] const pasteText: string[] = []
for (let i = 0; i < imgs.length; i++) { for (let i = 0; i < imgs.length; i++) {
@@ -325,14 +326,14 @@ export function createTray(tooltip: string) {
const [pasteTextItem, shortUrl] = await pasteTemplate( const [pasteTextItem, shortUrl] = await pasteTemplate(
pasteStyle, pasteStyle,
imgs[i], imgs[i],
db.get(configPaths.settings.customLink), picgo.getConfig<string | undefined>(configPaths.settings.customLink),
) )
imgs[i].shortUrl = shortUrl imgs[i].shortUrl = shortUrl
pasteText.push(pasteTextItem) pasteText.push(pasteTextItem)
const isShowResultNotification = const isShowResultNotification =
db.get(configPaths.settings.uploadResultNotification) === undefined picgo.getConfig<boolean | undefined>(configPaths.settings.uploadResultNotification) === undefined
? true ? true
: !!db.get(configPaths.settings.uploadResultNotification) : !!picgo.getConfig<boolean | undefined>(configPaths.settings.uploadResultNotification)
if (isShowResultNotification) { if (isShowResultNotification) {
const notification = new Notification({ const notification = new Notification({
title: $t('UPLOAD_SUCCEED'), title: $t('UPLOAD_SUCCEED'),

View File

@@ -1,4 +1,4 @@
import db, { GalleryDB } from '@core/datastore' import { GalleryDB } from '@core/datastore'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import uploader from 'apis/app/uploader' import uploader from 'apis/app/uploader'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
@@ -14,9 +14,9 @@ import pasteTemplate from '~/utils/pasteTemplate'
const handleClipboardUploadingReturnCtx = async (img?: IUploadOption): Promise<(ImgInfo[] | false)[]> => { const handleClipboardUploadingReturnCtx = async (img?: IUploadOption): Promise<(ImgInfo[] | false)[]> => {
const useBuiltinClipboard = const useBuiltinClipboard =
db.get(configPaths.settings.useBuiltinClipboard) === undefined picgo.getConfig<boolean | undefined>(configPaths.settings.useBuiltinClipboard) === undefined
? true ? true
: !!db.get(configPaths.settings.useBuiltinClipboard) : !!picgo.getConfig<boolean | undefined>(configPaths.settings.useBuiltinClipboard)
const win = windowManager.getAvailableWindow() const win = windowManager.getAvailableWindow()
if (useBuiltinClipboard) { if (useBuiltinClipboard) {
return await uploader.setWebContents(win!.webContents).uploadWithBuildInClipboardReturnCtx(img) return await uploader.setWebContents(win!.webContents).uploadWithBuildInClipboardReturnCtx(img)
@@ -33,14 +33,18 @@ export const uploadClipboardFiles = async (): Promise<IStringKeyMap> => {
if (img !== false) { if (img !== false) {
if (img.length > 0) { if (img.length > 0) {
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW) const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN const pasteStyle = picgo.getConfig<string>(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
const [pastedText, shortUrl] = await pasteTemplate(pasteStyle, img[0], db.get(configPaths.settings.customLink)) const [pastedText, shortUrl] = await pasteTemplate(
pasteStyle,
img[0],
picgo.getConfig<string | undefined>(configPaths.settings.customLink),
)
img[0].shortUrl = shortUrl img[0].shortUrl = shortUrl
handleCopyUrl(pastedText) handleCopyUrl(pastedText)
const isShowResultNotification = const isShowResultNotification =
db.get(configPaths.settings.uploadResultNotification) === undefined picgo.getConfig<boolean | undefined>(configPaths.settings.uploadResultNotification) === undefined
? true ? true
: !!db.get(configPaths.settings.uploadResultNotification) : !!picgo.getConfig<boolean | undefined>(configPaths.settings.uploadResultNotification)
if (isShowResultNotification) { if (isShowResultNotification) {
const notification = new Notification({ const notification = new Notification({
title: $t('UPLOAD_SUCCEED'), title: $t('UPLOAD_SUCCEED'),
@@ -101,8 +105,8 @@ export const uploadChoosedFiles = async (
backImgs = res[1] ? res[1] : false backImgs = res[1] ? res[1] : false
const result = [] const result = []
if (imgs !== false) { if (imgs !== false) {
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN const pasteStyle = picgo.getConfig<string>(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
const deleteLocalFile = db.get(configPaths.settings.deleteLocalFile) || false const deleteLocalFile = picgo.getConfig<boolean>(configPaths.settings.deleteLocalFile) || false
const pasteText: string[] = [] const pasteText: string[] = []
const imgLength = imgs.length const imgLength = imgs.length
for (let i = 0; i < imgLength; i++) { for (let i = 0; i < imgLength; i++) {
@@ -118,14 +122,14 @@ export const uploadChoosedFiles = async (
const [pasteTextItem, shortUrl] = await pasteTemplate( const [pasteTextItem, shortUrl] = await pasteTemplate(
pasteStyle, pasteStyle,
imgs[i], imgs[i],
db.get(configPaths.settings.customLink), picgo.getConfig<string | undefined>(configPaths.settings.customLink),
) )
imgs[i].shortUrl = shortUrl imgs[i].shortUrl = shortUrl
pasteText.push(pasteTextItem) pasteText.push(pasteTextItem)
const isShowResultNotification = const isShowResultNotification =
db.get(configPaths.settings.uploadResultNotification) === undefined picgo.getConfig<boolean | undefined>(configPaths.settings.uploadResultNotification) === undefined
? true ? true
: !!db.get(configPaths.settings.uploadResultNotification) : !!picgo.getConfig<boolean | undefined>(configPaths.settings.uploadResultNotification)
if (isShowResultNotification) { if (isShowResultNotification) {
if (imgLength <= 3) { if (imgLength <= 3) {
const notification = new Notification({ const notification = new Notification({

View File

@@ -1,7 +1,6 @@
import path from 'node:path' import path from 'node:path'
import util from 'node:util' import util from 'node:util'
import db from '@core/datastore'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
@@ -49,7 +48,7 @@ class Uploader {
}) })
picgo.on(ICOREBuildInEvent.BEFORE_TRANSFORM, () => { picgo.on(ICOREBuildInEvent.BEFORE_TRANSFORM, () => {
if (db.get(configPaths.settings.uploadNotification)) { if (picgo.getConfig<boolean | undefined>(configPaths.settings.uploadNotification)) {
const notification = new Notification({ const notification = new Notification({
title: $t('UPLOAD_PROGRESS'), title: $t('UPLOAD_PROGRESS'),
body: $t('UPLOADING'), body: $t('UPLOADING'),
@@ -62,9 +61,9 @@ class Uploader {
handle: async (ctx: IPicGo) => { handle: async (ctx: IPicGo) => {
const uploaderType = getUploaderType(ctx) const uploaderType = getUploaderType(ctx)
const globalRename = db.get(configPaths.settings.rename) const globalRename = picgo.getConfig<boolean | undefined>(configPaths.settings.rename)
const globalAutoRename = db.get(configPaths.settings.autoRename) const globalAutoRename = picgo.getConfig<boolean | undefined>(configPaths.settings.autoRename)
const buildInList = db.get(configPaths.buildIn.list._name) || [] const buildInList = picgo.getConfig<any[]>(configPaths.buildIn.list._name) || []
const idSpecificRename = buildInList.find((item: any) => item.id === uploaderType.id)?.manualRename const idSpecificRename = buildInList.find((item: any) => item.id === uploaderType.id)?.manualRename
const idSpecificAutoRename = buildInList.find((item: any) => item.id === uploaderType.id)?.autoRename const idSpecificAutoRename = buildInList.find((item: any) => item.id === uploaderType.id)?.autoRename
const rename = idSpecificRename !== undefined ? !!idSpecificRename : !!globalRename const rename = idSpecificRename !== undefined ? !!idSpecificRename : !!globalRename
@@ -118,25 +117,6 @@ class Uploader {
return filePath return filePath
} }
/**
* use electron's clipboard image to upload
*/
async uploadWithBuildInClipboard(): Promise<ImgInfo[] | false> {
let imgPath: string | false = false
try {
imgPath = await this.getClipboardImagePath()
if (!imgPath) return false
return await this.upload([imgPath])
} catch (e: any) {
logger.error(e)
return false
} finally {
if (imgPath && imgPath.startsWith(path.join(picgo.baseDir, CLIPBOARD_IMAGE_FOLDER))) {
fs.remove(imgPath)
}
}
}
async uploadWithBuildInClipboardReturnCtx(img?: IUploadOption): Promise<(ImgInfo[] | false)[]> { async uploadWithBuildInClipboardReturnCtx(img?: IUploadOption): Promise<(ImgInfo[] | false)[]> {
let imgPath: string | false = false let imgPath: string | false = false
try { try {
@@ -160,14 +140,14 @@ class Uploader {
if (Array.isArray(res.output) && res.output.some((item: ImgInfo) => item.imgUrl)) { if (Array.isArray(res.output) && res.output.some((item: ImgInfo) => item.imgUrl)) {
res.output.forEach((item: ImgInfo) => { res.output.forEach((item: ImgInfo) => {
item.config = JSON.parse(JSON.stringify(db.get(`picBed.${item.type}`))) item.config = JSON.parse(JSON.stringify(picgo.getConfig<any>(`picBed.${item.type}`)))
}) })
result[0] = res.output result[0] = res.output
} }
if (Array.isArray(res.backupOutput) && res.backupOutput.some((item: ImgInfo) => item.imgUrl)) { if (Array.isArray(res.backupOutput) && res.backupOutput.some((item: ImgInfo) => item.imgUrl)) {
res.backupOutput.forEach((item: ImgInfo) => { res.backupOutput.forEach((item: ImgInfo) => {
item.config = JSON.parse(JSON.stringify(db.get(`picBed.${item.type}`))) item.config = JSON.parse(JSON.stringify(picgo.getConfig<any>(`picBed.${item.type}`)))
}) })
result[1] = res.backupOutput result[1] = res.backupOutput
} }
@@ -186,29 +166,6 @@ class Uploader {
ipcMain.removeAllListeners(GET_RENAME_FILE_NAME) ipcMain.removeAllListeners(GET_RENAME_FILE_NAME)
} }
} }
async upload(img?: IUploadOption): Promise<ImgInfo[] | false> {
try {
const output = await picgo.upload(img)
if (!Array.isArray(output) || !output.some((item: ImgInfo) => item.imgUrl)) return false
output.forEach((item: ImgInfo) => {
item.config = JSON.parse(JSON.stringify(db.get(`picBed.${item.type}`)))
})
return output.filter(item => item.imgUrl)
} catch (e: any) {
logger.error(e)
setTimeout(() => {
showNotification({
title: $t('UPLOAD_FAILED'),
body: util.format(e.stack),
clickToCopy: true,
})
}, 500)
return false
} finally {
ipcMain.removeAllListeners(GET_RENAME_FILE_NAME)
}
}
} }
export default new Uploader() export default new Uploader()

View File

@@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url'
import bus from '@core/bus' import bus from '@core/bus'
import { CREATE_APP_MENU } from '@core/bus/constants' import { CREATE_APP_MENU } from '@core/bus/constants'
import db from '@core/datastore' import picgo from '@core/picgo'
import { app, BrowserWindow, Rectangle } from 'electron' import { app, BrowserWindow, Rectangle } from 'electron'
import { TOGGLE_SHORTKEY_MODIFIED_MODE } from '~/events/constant' import { TOGGLE_SHORTKEY_MODIFIED_MODE } from '~/events/constant'
@@ -16,10 +16,8 @@ import logo from '../../../../../resources/logo.png?asset&asarUnpack'
const windowList = new Map<string, IWindowListItem>() const windowList = new Map<string, IWindowListItem>()
const getDefaultWindowSizes = (): { width: number; height: number } => { const getDefaultWindowSizes = (): { width: number; height: number } => {
const [mainWindowWidth, mainWindowHeight] = db.get([ const mainWindowWidth = picgo.getConfig<number>(configPaths.settings.mainWindowWidth)
configPaths.settings.mainWindowWidth, const mainWindowHeight = picgo.getConfig<number>(configPaths.settings.mainWindowHeight)
configPaths.settings.mainWindowHeight,
])
return { return {
width: mainWindowWidth || 1200, width: mainWindowWidth || 1200,
height: mainWindowHeight || 800, height: mainWindowHeight || 800,
@@ -115,7 +113,7 @@ const miniWindowOptions = {
}, },
} as IBrowserWindowOptions } as IBrowserWindowOptions
if (db.get(configPaths.settings.miniWindowOntop)) { if (picgo.getConfig<boolean>(configPaths.settings.miniWindowOntop)) {
miniWindowOptions.alwaysOnTop = true miniWindowOptions.alwaysOnTop = true
} }

View File

@@ -1,22 +1,12 @@
import path from 'node:path' import { appConfigBackupPath, appConfigPath, galleryDBBackupPath, galleryDBPath } from '@core/datastore/dirs'
import { getLogger } from '@core/utils/localLogger'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { app } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
import writeFile from 'write-file-atomic' import writeFile from 'write-file-atomic'
import { T as $t } from '~/i18n' import { T as $t } from '~/i18n'
import { notificationList } from '~/utils/notification' import { notificationList } from '~/utils/notification'
const STORE_PATH = app.getPath('userData') const configFileBackupPath = appConfigBackupPath()
const configFilePath = path.join(STORE_PATH, 'data.json')
const configFileBackupPath = path.join(STORE_PATH, 'data.bak.json')
export const defaultConfigPath = configFilePath
let _configFilePath = ''
let hasCheckPath = false
const errorMsg = { const errorMsg = {
broken: $t('TIPS_PICGO_CONFIG_FILE_BROKEN_WITH_DEFAULT'), broken: $t('TIPS_PICGO_CONFIG_FILE_BROKEN_WITH_DEFAULT'),
@@ -27,7 +17,8 @@ function dbChecker() {
if (process.type !== 'renderer') { if (process.type !== 'renderer') {
// db save bak // db save bak
try { try {
const { dbPath, dbBackupPath } = getGalleryDBPath() const dbPath = galleryDBPath()
const dbBackupPath = galleryDBBackupPath()
if (fs.existsSync(dbPath)) { if (fs.existsSync(dbPath)) {
fs.copyFileSync(dbPath, dbBackupPath) fs.copyFileSync(dbPath, dbBackupPath)
} }
@@ -35,7 +26,7 @@ function dbChecker() {
console.error(e) console.error(e)
} }
const configFilePath = dbPathChecker() const configFilePath = appConfigPath()
if (!fs.existsSync(configFilePath)) { if (!fs.existsSync(configFilePath)) {
return return
} }
@@ -77,64 +68,4 @@ function dbChecker() {
} }
} }
/** export { dbChecker }
* Get config path
*/
function dbPathChecker(): string {
if (_configFilePath) {
return _configFilePath
}
_configFilePath = defaultConfigPath
// if defaultConfig path is not exit
// do not parse the content of config
if (!fs.existsSync(defaultConfigPath)) {
return _configFilePath
}
try {
const configString = fs.readFileSync(defaultConfigPath, {
encoding: 'utf-8',
})
const config = JSON.parse(configString)
const userConfigPath: string = config.configPath || ''
if (userConfigPath) {
if (fs.existsSync(userConfigPath) && userConfigPath.endsWith('.json')) {
_configFilePath = userConfigPath
return _configFilePath
}
}
return _configFilePath
} catch (e) {
const piclistLogPath = path.join(STORE_PATH, 'piclist-gui-local.log')
const logger = getLogger(piclistLogPath, 'PicList')
if (!hasCheckPath) {
const optionsTpl = {
title: $t('TIPS_NOTICE'),
body: $t('TIPS_CUSTOM_CONFIG_FILE_PATH_ERROR'),
}
notificationList.push(optionsTpl)
hasCheckPath = true
}
logger('error', e)
_configFilePath = defaultConfigPath
return _configFilePath
}
}
function dbPathDir() {
return path.dirname(dbPathChecker())
}
function getGalleryDBPath(): {
dbPath: string
dbBackupPath: string
} {
const configPath = dbPathChecker()
const dbPath = path.join(path.dirname(configPath), 'piclist.db')
const dbBackupPath = path.join(path.dirname(dbPath), 'piclist.bak.db')
return {
dbPath,
dbBackupPath,
}
}
export { dbChecker, dbPathChecker, dbPathDir, getGalleryDBPath }

View File

@@ -0,0 +1,163 @@
import path from 'node:path'
import { getLogger } from '@core/utils/localLogger'
import { app } from 'electron'
import fs from 'fs-extra'
import { T as $t } from '~/i18n'
import { notificationList } from '~/utils/notification'
let _configFilePath = ''
let _manageConfigFilePath = ''
let hasCheckPath = false
let hasCheckManagePath = false
export function isPortable() {
return fs.existsSync(path.join(exeDir(), 'PORTABLE'))
}
export function exePath() {
return app.getPath('exe')
}
export function exeDir() {
return path.dirname(exePath())
}
export function userDataDir() {
return app.getPath('userData')
}
export function dataDir() {
const configDir = path.dirname(appConfigPath())
try {
if (!fs.existsSync(configDir)) {
fs.mkdirsSync(configDir)
}
} catch (_e) {}
return configDir
}
export function defaultDir() {
if (isPortable()) return path.join(exeDir(), 'data')
return userDataDir()
}
export function defaultConfigPath() {
if (isPortable()) {
return path.join(exeDir(), 'data', 'data.json')
}
return path.join(userDataDir(), 'data.json')
}
export function defaultManageConfigPath() {
if (isPortable()) {
return path.join(exeDir(), 'data', 'manage.json')
}
return path.join(userDataDir(), 'manage.json')
}
export function appConfigPath() {
if (_configFilePath) return _configFilePath
_configFilePath = defaultConfigPath()
if (!fs.existsSync(_configFilePath)) return _configFilePath
try {
const configString = fs.readFileSync(_configFilePath, {
encoding: 'utf-8',
})
const config = JSON.parse(configString)
// extract custom data dir
const userConfigPath: string = config.configPath || ''
if (userConfigPath) {
if (fs.existsSync(userConfigPath) && userConfigPath.endsWith('.json')) {
_configFilePath = userConfigPath
return _configFilePath
}
}
return _configFilePath
} catch (e) {
const piclistLogPath = appGUILogPath()
const logger = getLogger(piclistLogPath, 'PicList')
if (!hasCheckPath) {
const optionsTpl = {
title: $t('TIPS_NOTICE'),
body: $t('TIPS_CUSTOM_CONFIG_FILE_PATH_ERROR'),
}
notificationList.push(optionsTpl)
hasCheckPath = true
}
logger('error', e)
_configFilePath = defaultConfigPath()
return _configFilePath
}
}
export function themesDir() {
return path.join(defaultDir(), 'themes')
}
export function appConfigBackupPath() {
return path.join(dataDir(), 'data.bak.json')
}
export function galleryDBPath() {
return path.join(dataDir(), 'piclist.db')
}
export function galleryDBBackupPath() {
return path.join(dataDir(), 'piclist.bak.db')
}
export function manageConfigPath() {
if (_manageConfigFilePath) return _manageConfigFilePath
_manageConfigFilePath = defaultManageConfigPath()
if (!fs.existsSync(_manageConfigFilePath)) return _manageConfigFilePath
try {
const configString = fs.readFileSync(_manageConfigFilePath, {
encoding: 'utf-8',
})
const config = JSON.parse(configString)
const userConfigPath: string = config.configPath || ''
if (userConfigPath) {
if (fs.existsSync(userConfigPath) && userConfigPath.endsWith('.json')) {
_manageConfigFilePath = userConfigPath
return _manageConfigFilePath
}
}
return _manageConfigFilePath
} catch (e) {
const manageLogPath = manageGUILogPath()
const logger = getLogger(manageLogPath, 'Manage')
if (!hasCheckManagePath) {
const optionsTpl = {
title: $t('TIPS_NOTICE'),
body: $t('TIPS_CUSTOM_CONFIG_FILE_PATH_ERROR'),
}
notificationList.push(optionsTpl)
hasCheckManagePath = true
}
logger('error', e)
_manageConfigFilePath = defaultManageConfigPath()
return _manageConfigFilePath
}
}
export function manageConfigBackupPath() {
return path.join(dataDir(), 'manage.bak.json')
}
export function appLogPath() {
return path.join(defaultDir(), 'piclist.log')
}
export function appGUILogPath() {
return path.join(defaultDir(), 'piclist-gui-local.log')
}
export function manageGUILogPath() {
return path.join(defaultDir(), 'manage-gui-local.log')
}
export function manageLogPath() {
return path.join(defaultDir(), 'manage.log')
}

View File

@@ -1,104 +1,7 @@
import { dbPathChecker, dbPathDir, getGalleryDBPath } from '@core/datastore/dbChecker' import { galleryDBPath } from '@core/datastore/dirs'
import { DBStore, JSONStore } from '@piclist/store' import { DBStore } from '@piclist/store'
import fs from 'fs-extra'
import type { IConfig } from 'piclist'
import { T as $t } from '~/i18n' export const DB_PATH: string = galleryDBPath()
import { configPaths } from '~/utils/configPaths'
interface IJSON {
[propsName: string]: string | number | IJSON
}
const STORE_PATH = dbPathDir()
if (!fs.pathExistsSync(STORE_PATH)) {
fs.mkdirpSync(STORE_PATH)
}
const CONFIG_PATH: string = dbPathChecker()
export const DB_PATH: string = getGalleryDBPath().dbPath
class ConfigStore {
#db: JSONStore
constructor() {
this.#db = new JSONStore(CONFIG_PATH)
if (!this.#db.has('picBed')) {
this.#db.set('picBed', {
current: 'smms', // deprecated
uploader: 'smms',
smms: {
token: '',
},
})
}
if (!this.#db.has(configPaths.settings.shortKey._path)) {
this.#db.set(configPaths.settings.shortKey['picgo:upload'], {
enable: true,
key: 'CommandOrControl+Alt+P',
name: 'upload',
label: $t('QUICK_UPLOAD'),
})
}
this.read()
}
read(flush?: boolean): IJSON {
return this.#db.read(flush)
}
getSingle(key = ''): any {
if (key === '') {
return this.#db.read(true)
}
this.read(true)
return this.#db.get(key)
}
get(key: string): any
get(key: string[]): any[]
get(key: string | string[] = ''): any {
if (Array.isArray(key)) {
return key.map(k => this.getSingle(k))
}
return this.getSingle(key)
}
set(key: string, value: any): void {
this.read(true)
return this.#db.set(key, value)
}
has(key: string) {
this.read(true)
return this.#db.has(key)
}
unset(key: string, value: any): boolean {
this.read(true)
return this.#db.unset(key, value)
}
saveConfig(config: Partial<IConfig>): void {
Object.keys(config).forEach((name: string) => {
this.set(name, config[name])
})
}
removeConfig(config: IConfig): void {
Object.keys(config).forEach((name: string) => {
this.unset(name, config[name])
})
}
getConfigPath() {
return CONFIG_PATH
}
}
const db = new ConfigStore()
export default db
// v2.3.0 add gallery db // v2.3.0 add gallery db
class GalleryDB { class GalleryDB {

View File

@@ -1,10 +1,11 @@
import db from '@core/datastore' import { dbChecker } from '@core/datastore/dbChecker'
import { dbChecker, dbPathChecker } from '@core/datastore/dbChecker' import { appConfigPath } from '@core/datastore/dirs'
import { debounce } from 'lodash-es'
import { PicGo } from 'piclist' import { PicGo } from 'piclist'
import pkg from 'root/package.json' import pkg from 'root/package.json'
const CONFIG_PATH = dbPathChecker() import { T as $t } from '~/i18n'
import { configPaths } from '~/utils/configPaths'
const CONFIG_PATH = appConfigPath()
dbChecker() dbChecker()
@@ -15,20 +16,19 @@ picgo.saveConfig({
PICGO_ENV: 'GUI', PICGO_ENV: 'GUI',
}) })
const shortKeySetting = picgo.getConfig<any>(configPaths.settings.shortKey._path)
if (!shortKeySetting) {
picgo.saveConfig({
'settings.shortKey[picgo:upload]': {
enable: true,
key: 'CommandOrControl+Alt+P',
name: 'upload',
label: $t('QUICK_UPLOAD'),
},
})
}
picgo.GUI_VERSION = pkg.version picgo.GUI_VERSION = pkg.version
const originPicGoSaveConfig = picgo.saveConfig.bind(picgo)
function flushDB() {
db.read(true)
}
const debounced = debounce(flushDB, 1000)
picgo.saveConfig = (config: IStringKeyMap) => {
originPicGoSaveConfig(config)
// flush electron's db
debounced()
}
export default picgo export default picgo

View File

@@ -1,6 +1,7 @@
import { getSettingWindowId, getWindowId } from '@core/bus/apis' import { getSettingWindowId, getWindowId } from '@core/bus/apis'
import db, { GalleryDB } from '@core/datastore' import { GalleryDB } from '@core/datastore'
import { dbPathChecker, defaultConfigPath, getGalleryDBPath } from '@core/datastore/dbChecker' import { appConfigPath, defaultConfigPath as defaultConfigPathF, galleryDBPath } from '@core/datastore/dirs'
import picgo from '@core/picgo'
import { DBStore } from '@piclist/store' import { DBStore } from '@piclist/store'
import uploader from 'apis/app/uploader' import uploader from 'apis/app/uploader'
import { BrowserWindow, dialog, ipcMain, IpcMainEvent, MessageBoxOptions, Notification } from 'electron' import { BrowserWindow, dialog, ipcMain, IpcMainEvent, MessageBoxOptions, Notification } from 'electron'
@@ -78,8 +79,8 @@ class GuiApi implements IGuiApi {
const backImgs = res[1] ? res[1] : false const backImgs = res[1] ? res[1] : false
let result: ImgInfo[] = [] let result: ImgInfo[] = []
if (imgs !== false) { if (imgs !== false) {
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN const pasteStyle = picgo.getConfig<string>(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
const deleteLocalFile = db.get(configPaths.settings.deleteLocalFile) || false const deleteLocalFile = picgo.getConfig<boolean>(configPaths.settings.deleteLocalFile) || false
const pasteText: string[] = [] const pasteText: string[] = []
for (let i = 0; i < imgs.length; i++) { for (let i = 0; i < imgs.length; i++) {
if (deleteLocalFile) { if (deleteLocalFile) {
@@ -88,14 +89,14 @@ class GuiApi implements IGuiApi {
const [pasteTextItem, shortUrl] = await pasteTemplate( const [pasteTextItem, shortUrl] = await pasteTemplate(
pasteStyle, pasteStyle,
imgs[i], imgs[i],
db.get(configPaths.settings.customLink), picgo.getConfig<string>(configPaths.settings.customLink),
) )
imgs[i].shortUrl = shortUrl imgs[i].shortUrl = shortUrl
pasteText.push(pasteTextItem) pasteText.push(pasteTextItem)
const isShowResultNotification = const isShowResultNotification =
db.get(configPaths.settings.uploadResultNotification) === undefined picgo.getConfig<boolean>(configPaths.settings.uploadResultNotification) === undefined
? true ? true
: !!db.get(configPaths.settings.uploadResultNotification) : !!picgo.getConfig<boolean>(configPaths.settings.uploadResultNotification)
if (isShowResultNotification) { if (isShowResultNotification) {
const notification = new Notification({ const notification = new Notification({
title: $t('UPLOAD_SUCCEED'), title: $t('UPLOAD_SUCCEED'),
@@ -161,12 +162,12 @@ class GuiApi implements IGuiApi {
* get picgo config/data path * get picgo config/data path
*/ */
async getConfigPath() { async getConfigPath() {
const currentConfigPath = dbPathChecker() const currentConfigPath = appConfigPath()
const galleryDBPath = getGalleryDBPath().dbPath const galleryDBPathValue = galleryDBPath()
return { return {
defaultConfigPath, defaultConfigPath: defaultConfigPathF(),
currentConfigPath, currentConfigPath,
galleryDBPath, galleryDBPath: galleryDBPathValue,
} }
} }

View File

@@ -1,4 +1,3 @@
import db from '@core/datastore'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import { uploadClipboardFiles } from 'apis/app/uploader/apis' import { uploadClipboardFiles } from 'apis/app/uploader/apis'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
@@ -30,7 +29,7 @@ interface GuiMenuItem {
} }
const buildMiniPageMenu = () => { const buildMiniPageMenu = () => {
const isListeningClipboard = db.get(configPaths.settings.isListeningClipboard) || false const isListeningClipboard = picgo.getConfig<boolean>(configPaths.settings.isListeningClipboard) || false
const ClipboardWatcher = clipboardPoll const ClipboardWatcher = clipboardPoll
const submenu = buildPicBedListMenu() const submenu = buildPicBedListMenu()
const template: (MenuItemConstructorOptions | MenuItem)[] = [ const template: (MenuItemConstructorOptions | MenuItem)[] = [
@@ -58,7 +57,7 @@ const buildMiniPageMenu = () => {
{ {
label: $t('START_WATCH_CLIPBOARD'), label: $t('START_WATCH_CLIPBOARD'),
click() { click() {
db.set(configPaths.settings.isListeningClipboard, true) picgo.saveConfig({ [configPaths.settings.isListeningClipboard]: true })
ClipboardWatcher.startListening() ClipboardWatcher.startListening()
ClipboardWatcher.on('change', () => { ClipboardWatcher.on('change', () => {
picgo.log.info('clipboard changed') picgo.log.info('clipboard changed')
@@ -71,7 +70,7 @@ const buildMiniPageMenu = () => {
{ {
label: $t('STOP_WATCH_CLIPBOARD'), label: $t('STOP_WATCH_CLIPBOARD'),
click() { click() {
db.set(configPaths.settings.isListeningClipboard, false) picgo.saveConfig({ [configPaths.settings.isListeningClipboard]: false })
ClipboardWatcher.stopListening() ClipboardWatcher.stopListening()
ClipboardWatcher.removeAllListeners() ClipboardWatcher.removeAllListeners()
buildMiniPageMenu() buildMiniPageMenu()

View File

@@ -1,6 +1,6 @@
import path from 'node:path' import path from 'node:path'
import { dbPathDir } from '@core/datastore/dbChecker' import { dataDir } from '@core/datastore/dirs'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import shortKeyHandler from 'apis/app/shortKey/shortKeyHandler' import shortKeyHandler from 'apis/app/shortKey/shortKeyHandler'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
@@ -12,7 +12,7 @@ import { T as $t } from '~/i18n'
import { handleStreamlinePluginName, showNotification, simpleClone } from '~/utils/common' import { handleStreamlinePluginName, showNotification, simpleClone } from '~/utils/common'
import { ICOREBuildInEvent, IPicGoHelperType, IWindowList } from '~/utils/enum' import { ICOREBuildInEvent, IPicGoHelperType, IWindowList } from '~/utils/enum'
const STORE_PATH = dbPathDir() const STORE_PATH = dataDir()
// get uploader or transformer config // get uploader or transformer config
const getConfig = (name: string, type: keyof typeof IPicGoHelperType, ctx: PicGoCore) => { const getConfig = (name: string, type: keyof typeof IPicGoHelperType, ctx: PicGoCore) => {

View File

@@ -1,5 +1,6 @@
import path from 'node:path' import path from 'node:path'
import { dataDir } from '@core/datastore/dirs'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import { app } from 'electron' import { app } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
@@ -7,7 +8,7 @@ import fs from 'fs-extra'
import { IRPCActionType, IRPCType } from '~/utils/enum' import { IRPCActionType, IRPCType } from '~/utils/enum'
import { downloadFile, syncGallery, uploadFile } from '~/utils/syncSettings' import { downloadFile, syncGallery, uploadFile } from '~/utils/syncSettings'
const STORE_PATH = app.getPath('userData') const STORE_PATH = dataDir()
const commonConfigList = ['data.json', 'data.bak.json'] const commonConfigList = ['data.json', 'data.bak.json']
const manageConfigList = ['manage.json', 'manage.bak.json'] const manageConfigList = ['manage.json', 'manage.bak.json']
@@ -16,7 +17,7 @@ export default [
{ {
action: IRPCActionType.CONFIGURE_MIGRATE_FROM_PICGO, action: IRPCActionType.CONFIGURE_MIGRATE_FROM_PICGO,
handler: async () => { handler: async () => {
const picGoConfigPath = STORE_PATH.replace('piclist', 'picgo') const picGoConfigPath = app.getPath('userData').replace('piclist', 'picgo')
const files = ['data.json', 'data.bak.json', 'picgo.db', 'picgo.bak.db'] const files = ['data.json', 'data.bak.json', 'picgo.db', 'picgo.bak.db']
try { try {
await Promise.all( await Promise.all(

View File

@@ -1,6 +1,6 @@
import path from 'node:path' import path from 'node:path'
import { dbPathDir } from '@core/datastore/dbChecker' import { dataDir } from '@core/datastore/dirs'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import { IpcMainEvent, shell } from 'electron' import { IpcMainEvent, shell } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
@@ -8,7 +8,7 @@ import fs from 'fs-extra'
import { isAutoStartEnabled, setAutoStart } from '~/utils/autoStart' import { isAutoStartEnabled, setAutoStart } from '~/utils/autoStart'
import { IRPCActionType, IRPCType } from '~/utils/enum' import { IRPCActionType, IRPCType } from '~/utils/enum'
const STORE_PATH = dbPathDir() const STORE_PATH = dataDir()
export default [ export default [
{ {

View File

@@ -1,6 +1,6 @@
import path from 'node:path' import path from 'node:path'
import { dbPathChecker, defaultConfigPath } from '@core/datastore/dbChecker' import { appConfigPath, defaultDir } from '@core/datastore/dirs'
import fs from 'fs-extra' import fs from 'fs-extra'
import { sendToolboxResWithType } from '~/events/rpc/routes/toolbox/utils' import { sendToolboxResWithType } from '~/events/rpc/routes/toolbox/utils'
@@ -10,14 +10,14 @@ import { CLIPBOARD_IMAGE_FOLDER } from '~/utils/static'
const sendToolboxRes = sendToolboxResWithType(IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD) const sendToolboxRes = sendToolboxResWithType(IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD)
const defaultClipboardImagePath = path.join(defaultConfigPath, CLIPBOARD_IMAGE_FOLDER) const defaultClipboardImagePath = path.join(defaultDir(), CLIPBOARD_IMAGE_FOLDER)
export const checkClipboardUploadMap: IToolboxCheckerMap<string> = { export const checkClipboardUploadMap: IToolboxCheckerMap<string> = {
[IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD]: async event => { [IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD]: async event => {
sendToolboxRes(event, { sendToolboxRes(event, {
status: IToolboxItemCheckStatus.LOADING, status: IToolboxItemCheckStatus.LOADING,
}) })
const configFilePath = dbPathChecker() const configFilePath = appConfigPath()
if (fs.existsSync(configFilePath)) { if (fs.existsSync(configFilePath)) {
const dirPath = path.dirname(configFilePath) const dirPath = path.dirname(configFilePath)
const clipboardImagePath = path.join(dirPath, CLIPBOARD_IMAGE_FOLDER) const clipboardImagePath = path.join(dirPath, CLIPBOARD_IMAGE_FOLDER)
@@ -52,7 +52,7 @@ export const checkClipboardUploadMap: IToolboxCheckerMap<string> = {
export const fixClipboardUploadMap: IToolboxFixMap<string> = { export const fixClipboardUploadMap: IToolboxFixMap<string> = {
[IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD]: async () => { [IToolboxItemType.HAS_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD]: async () => {
const configFilePath = dbPathChecker() const configFilePath = appConfigPath()
const dirPath = path.dirname(configFilePath) const dirPath = path.dirname(configFilePath)
const clipboardImagePath = path.join(dirPath, CLIPBOARD_IMAGE_FOLDER) const clipboardImagePath = path.join(dirPath, CLIPBOARD_IMAGE_FOLDER)
try { try {

View File

@@ -1,7 +1,7 @@
import path from 'node:path' import path from 'node:path'
import { DB_PATH, GalleryDB } from '@core/datastore' import { DB_PATH, GalleryDB } from '@core/datastore'
import { dbPathChecker } from '@core/datastore/dbChecker' import { appConfigPath } from '@core/datastore/dirs'
import type { IpcMainEvent } from 'electron' import type { IpcMainEvent } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
@@ -15,7 +15,7 @@ export const checkFileMap: IToolboxCheckerMap<string> = {
sendToolboxRes(event, { sendToolboxRes(event, {
status: IToolboxItemCheckStatus.LOADING, status: IToolboxItemCheckStatus.LOADING,
}) })
const configFilePath = dbPathChecker() const configFilePath = appConfigPath()
try { try {
if (fs.existsSync(configFilePath)) { if (fs.existsSync(configFilePath)) {
await fs.readJSON(configFilePath) await fs.readJSON(configFilePath)
@@ -62,7 +62,7 @@ export const checkFileMap: IToolboxCheckerMap<string> = {
export const fixFileMap: IToolboxFixMap<string> = { export const fixFileMap: IToolboxFixMap<string> = {
[IToolboxItemType.IS_CONFIG_FILE_BROKEN]: async () => { [IToolboxItemType.IS_CONFIG_FILE_BROKEN]: async () => {
try { try {
fs.unlinkSync(dbPathChecker()) fs.unlinkSync(appConfigPath())
} catch (_e) { } catch (_e) {
// do nothing // do nothing
} }

View File

@@ -1,4 +1,4 @@
import { dbPathChecker } from '@core/datastore/dbChecker' import { appConfigPath } from '@core/datastore/dirs'
import axios, { AxiosRequestConfig } from 'axios' import axios, { AxiosRequestConfig } from 'axios'
import fs from 'fs-extra' import fs from 'fs-extra'
import { IConfig } from 'piclist' import { IConfig } from 'piclist'
@@ -29,7 +29,7 @@ export const checkProxyMap: IToolboxCheckerMap<string> = {
sendToolboxRes(event, { sendToolboxRes(event, {
status: IToolboxItemCheckStatus.LOADING, status: IToolboxItemCheckStatus.LOADING,
}) })
const configFilePath = dbPathChecker() const configFilePath = appConfigPath()
if (fs.existsSync(configFilePath)) { if (fs.existsSync(configFilePath)) {
let config: IConfig | undefined let config: IConfig | undefined
try { try {

View File

@@ -1,4 +1,5 @@
import db, { GalleryDB } from '@core/datastore' import { GalleryDB } from '@core/datastore'
import picgo from '@core/picgo'
import uploader from 'apis/app/uploader' import uploader from 'apis/app/uploader'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
import { Notification } from 'electron' import { Notification } from 'electron'
@@ -35,14 +36,18 @@ const trayRoutes = [
const img = res[0] ? res[0] : false const img = res[0] ? res[0] : false
const backupImgs = res[1] ? res[1] : false const backupImgs = res[1] ? res[1] : false
if (img !== false) { if (img !== false) {
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN const pasteStyle = picgo.getConfig<string>(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
const [pasteText, shortUrl] = await pasteTemplate(pasteStyle, img[0], db.get(configPaths.settings.customLink)) const [pasteText, shortUrl] = await pasteTemplate(
pasteStyle,
img[0],
picgo.getConfig<string>(configPaths.settings.customLink),
)
img[0].shortUrl = shortUrl img[0].shortUrl = shortUrl
handleCopyUrl(pasteText) handleCopyUrl(pasteText)
const isShowResultNotification = const isShowResultNotification =
db.get(configPaths.settings.uploadResultNotification) === undefined picgo.getConfig<boolean>(configPaths.settings.uploadResultNotification) === undefined
? true ? true
: !!db.get(configPaths.settings.uploadResultNotification) : !!picgo.getConfig<boolean>(configPaths.settings.uploadResultNotification)
if (isShowResultNotification) { if (isShowResultNotification) {
const notification = new Notification({ const notification = new Notification({
title: $t('UPLOAD_SUCCEED'), title: $t('UPLOAD_SUCCEED'),

View File

@@ -1,4 +1,4 @@
import db from '@core/datastore' import picgo from '@core/picgo'
import { BrowserWindow, shell } from 'electron' import { BrowserWindow, shell } from 'electron'
import updater from 'electron-updater' import updater from 'electron-updater'
@@ -30,7 +30,7 @@ const updaterRoutes = [
{ {
action: IRPCActionType.SET_SHOW_UPDATE_TIP, action: IRPCActionType.SET_SHOW_UPDATE_TIP,
handler: async (_: IIPCEvent, args: [value: boolean]) => { handler: async (_: IIPCEvent, args: [value: boolean]) => {
db.set(configPaths.settings.showUpdateTip, args[0]) picgo.saveConfig({ [configPaths.settings.showUpdateTip]: args[0] })
}, },
}, },
{ {

View File

@@ -1,10 +1,7 @@
import path from 'node:path' import { appGUILogPath } from '@core/datastore/dirs'
import { getLogger } from '@core/utils/localLogger' import { getLogger } from '@core/utils/localLogger'
import { app } from 'electron'
const STORE_PATH = app.getPath('userData') const LOG_PATH = appGUILogPath()
const LOG_PATH = path.join(STORE_PATH, 'piclist-gui-local.log')
const logger = getLogger(LOG_PATH, 'PicList') const logger = getLogger(LOG_PATH, 'PicList')

View File

@@ -3,7 +3,6 @@ import '~/lifeCycle/errorHandler'
import path from 'node:path' import path from 'node:path'
import bus from '@core/bus' import bus from '@core/bus'
import db from '@core/datastore'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import { remoteNoticeHandler } from 'apis/app/remoteNotice' import { remoteNoticeHandler } from 'apis/app/remoteNotice'
@@ -69,7 +68,7 @@ updater.autoUpdater.forceDevUpdateConfig = true
updater.autoUpdater.autoDownload = false updater.autoUpdater.autoDownload = false
updater.autoUpdater.on('update-available', async (info: updater.UpdateInfo) => { updater.autoUpdater.on('update-available', async (info: updater.UpdateInfo) => {
const lang = db.get(configPaths.settings.language) || II18nLanguage.ZH_CN const lang = picgo.getConfig<string>(configPaths.settings.language) || II18nLanguage.ZH_CN
let updateLog = '' let updateLog = ''
try { try {
const url = const url =
@@ -126,7 +125,7 @@ updater.autoUpdater.on('download-progress', progressObj => {
}) })
updater.autoUpdater.on('update-downloaded', () => { updater.autoUpdater.on('update-downloaded', () => {
const lang = db.get(configPaths.settings.language) || II18nLanguage.ZH_CN const lang = picgo.getConfig<string>(configPaths.settings.language) || II18nLanguage.ZH_CN
if (!windowManager.has(IWindowList.UPDATE_WINDOW)) { if (!windowManager.has(IWindowList.UPDATE_WINDOW)) {
windowManager.create(IWindowList.UPDATE_WINDOW) windowManager.create(IWindowList.UPDATE_WINDOW)
@@ -180,25 +179,28 @@ class LifeCycle {
const readyFunction = async () => { const readyFunction = async () => {
windowManager.create(IWindowList.TRAY_WINDOW) windowManager.create(IWindowList.TRAY_WINDOW)
windowManager.create(IWindowList.SETTING_WINDOW) windowManager.create(IWindowList.SETTING_WINDOW)
const isAutoListenClipboard = db.get(configPaths.settings.isAutoListenClipboard) || false const isAutoListenClipboard = picgo.getConfig<boolean>(configPaths.settings.isAutoListenClipboard) || false
const ClipboardWatcher = clipboardPoll const ClipboardWatcher = clipboardPoll
if (isAutoListenClipboard) { if (isAutoListenClipboard) {
db.set(configPaths.settings.isListeningClipboard, true) picgo.saveConfig({ [configPaths.settings.isListeningClipboard]: true })
ClipboardWatcher.startListening() ClipboardWatcher.startListening()
ClipboardWatcher.on('change', () => { ClipboardWatcher.on('change', () => {
picgo.log.info('clipboard changed') picgo.log.info('clipboard changed')
uploadClipboardFiles() uploadClipboardFiles()
}) })
} else { } else {
db.set(configPaths.settings.isListeningClipboard, false) picgo.saveConfig({ [configPaths.settings.isListeningClipboard]: false })
} }
const isHideDock = db.get(configPaths.settings.isHideDock) || false const isHideDock = picgo.getConfig<boolean>(configPaths.settings.isHideDock) || false
let startMode = db.get(configPaths.settings.startMode) || ISartMode.QUIET let startMode = picgo.getConfig<string>(configPaths.settings.startMode) || ISartMode.QUIET
if (process.platform === 'darwin' && startMode === ISartMode.MINI) { if (process.platform === 'darwin' && startMode === ISartMode.MINI) {
startMode = ISartMode.QUIET startMode = ISartMode.QUIET
} }
const currentPicBed = db.get(configPaths.picBed.uploader) || db.get(configPaths.picBed.current) || 'smms' const currentPicBed =
const currentPicBedConfig = db.get(`picBed.${currentPicBed}`)?._configName || 'Default' picgo.getConfig<string>(configPaths.picBed.uploader) ||
picgo.getConfig<string>(configPaths.picBed.current) ||
'smms'
const currentPicBedConfig = picgo.getConfig<any>(`picBed.${currentPicBed}`)?._configName || 'Default'
const tooltip = `${currentPicBed} ${currentPicBedConfig}` const tooltip = `${currentPicBed} ${currentPicBedConfig}`
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
isHideDock ? app.dock?.hide() : setDockMenu() isHideDock ? app.dock?.hide() : setDockMenu()
@@ -206,7 +208,7 @@ class LifeCycle {
} else { } else {
createTray(tooltip) createTray(tooltip)
} }
db.set(configPaths.needReload, false) picgo.saveConfig({ [configPaths.needReload]: false })
updateChecker() updateChecker()
// 不需要阻塞 // 不需要阻塞
process.nextTick(() => { process.nextTick(() => {
@@ -232,24 +234,26 @@ class LifeCycle {
windowManager.create(IWindowList.MINI_WINDOW) windowManager.create(IWindowList.MINI_WINDOW)
const miniWindow = windowManager.get(IWindowList.MINI_WINDOW)! const miniWindow = windowManager.get(IWindowList.MINI_WINDOW)!
miniWindow.removeAllListeners() miniWindow.removeAllListeners()
if (db.get(configPaths.settings.miniWindowOntop)) { if (picgo.getConfig<boolean>(configPaths.settings.miniWindowOntop)) {
miniWindow.setAlwaysOnTop(true) miniWindow.setAlwaysOnTop(true)
} }
const { width, height } = screen.getPrimaryDisplay().workAreaSize const { width, height } = screen.getPrimaryDisplay().workAreaSize
const lastPosition = db.get(configPaths.settings.miniWindowPosition) const lastPosition = picgo.getConfig<number[]>(configPaths.settings.miniWindowPosition)
if (lastPosition) { if (lastPosition) {
if (lastPosition[0] < 0 || lastPosition[0] > width || lastPosition[1] < 0 || lastPosition[1] > height) { if (lastPosition[0] < 0 || lastPosition[0] > width || lastPosition[1] < 0 || lastPosition[1] > height) {
miniWindow.setPosition(width - 100, height - 100) miniWindow.setPosition(width - 100, height - 100)
db.set(configPaths.settings.miniWindowPosition, [width - 100, height - 100]) picgo.saveConfig({ [configPaths.settings.miniWindowPosition]: [width - 100, height - 100] })
} else if ( } else if (
lastPosition[0] + miniWindow.getSize()[0] > width || lastPosition[0] + miniWindow.getSize()[0] > width ||
lastPosition[1] + miniWindow.getSize()[1] > height lastPosition[1] + miniWindow.getSize()[1] > height
) { ) {
miniWindow.setPosition(width - miniWindow.getSize()[0], height - miniWindow.getSize()[1]) miniWindow.setPosition(width - miniWindow.getSize()[0], height - miniWindow.getSize()[1])
db.set(configPaths.settings.miniWindowPosition, [ picgo.saveConfig({
width - miniWindow.getSize()[0], [configPaths.settings.miniWindowPosition]: [
height - miniWindow.getSize()[1], width - miniWindow.getSize()[0],
]) height - miniWindow.getSize()[1],
],
})
} else { } else {
miniWindow.setPosition(lastPosition[0], lastPosition[1]) miniWindow.setPosition(lastPosition[0], lastPosition[1])
} }
@@ -258,7 +262,7 @@ class LifeCycle {
} }
const setPositionFunc = () => { const setPositionFunc = () => {
const position = miniWindow.getPosition() const position = miniWindow.getPosition()
db.set(configPaths.settings.miniWindowPosition, position) picgo.saveConfig({ [configPaths.settings.miniWindowPosition]: position })
} }
miniWindow.on('close', setPositionFunc) miniWindow.on('close', setPositionFunc)
miniWindow.on('move', setPositionFunc) miniWindow.on('move', setPositionFunc)
@@ -297,7 +301,7 @@ class LifeCycle {
windowManager.create(IWindowList.SETTING_WINDOW) windowManager.create(IWindowList.SETTING_WINDOW)
} }
}) })
const storedAutoStartEnabled = db.get(configPaths.settings.autoStart) || false const storedAutoStartEnabled = picgo.getConfig<boolean>(configPaths.settings.autoStart) || false
isAutoStartEnabled() isAutoStartEnabled()
.then(actualAutoStartEnabled => { .then(actualAutoStartEnabled => {
if (actualAutoStartEnabled !== storedAutoStartEnabled) { if (actualAutoStartEnabled !== storedAutoStartEnabled) {
@@ -358,6 +362,7 @@ class LifeCycle {
} }
async launchApp() { async launchApp() {
console.log('launchApp called', app.getPath('exe'))
const gotTheLock = app.requestSingleInstanceLock() const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) { if (!gotTheLock) {
app.quit() app.quit()

View File

@@ -1,20 +1,13 @@
import path from 'node:path' import { manageConfigBackupPath, manageConfigPath } from '@core/datastore/dirs'
import { getLogger } from '@core/utils/localLogger'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { app } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
import writeFile from 'write-file-atomic' import writeFile from 'write-file-atomic'
import { T as $t } from '~/i18n' import { T as $t } from '~/i18n'
import { notificationList } from '~/utils/notification' import { notificationList } from '~/utils/notification'
const STORE_PATH = app.getPath('userData') const manageConfigFilePath = manageConfigPath()
const manageConfigFilePath = path.join(STORE_PATH, 'manage.json') const manageConfigFileBackupPath = manageConfigBackupPath()
export const defaultManageConfigPath = manageConfigFilePath
const manageConfigFileBackupPath = path.join(STORE_PATH, 'manage.bak.json')
let _configFilePath = ''
let hasCheckPath = false
const errorMsg = { const errorMsg = {
broken: $t('TIPS_PICGO_CONFIG_FILE_BROKEN_WITH_DEFAULT'), broken: $t('TIPS_PICGO_CONFIG_FILE_BROKEN_WITH_DEFAULT'),
@@ -23,7 +16,6 @@ const errorMsg = {
function manageDbChecker() { function manageDbChecker() {
if (process.type !== 'renderer') { if (process.type !== 'renderer') {
const manageConfigFilePath = managePathChecker()
if (!fs.existsSync(manageConfigFilePath)) { if (!fs.existsSync(manageConfigFilePath)) {
return return
} }
@@ -68,53 +60,4 @@ function manageDbChecker() {
}) })
} }
} }
export { manageDbChecker }
/**
* Get manage config path
*/
function managePathChecker(): string {
if (_configFilePath) {
return _configFilePath
}
// defaultConfigPath
_configFilePath = defaultManageConfigPath
// if defaultConfig path is not exit
// do not parse the content of config
if (!fs.existsSync(defaultManageConfigPath)) {
return _configFilePath
}
try {
const configString = fs.readFileSync(defaultManageConfigPath, {
encoding: 'utf-8',
})
const config = JSON.parse(configString)
const userConfigPath: string = config.configPath || ''
if (userConfigPath) {
if (fs.existsSync(userConfigPath) && userConfigPath.endsWith('.json')) {
_configFilePath = userConfigPath
return _configFilePath
}
}
return _configFilePath
} catch (e) {
const manageLogPath = path.join(STORE_PATH, 'manage-gui-local.log')
const logger = getLogger(manageLogPath, 'Manage')
if (!hasCheckPath) {
const optionsTpl = {
title: $t('TIPS_NOTICE'),
body: $t('TIPS_CUSTOM_CONFIG_FILE_PATH_ERROR'),
}
notificationList?.push(optionsTpl)
hasCheckPath = true
}
logger('error', e)
_configFilePath = defaultManageConfigPath
return _configFilePath
}
}
function managePathDir() {
return path.dirname(managePathChecker())
}
export { manageDbChecker, managePathChecker, managePathDir }

View File

@@ -3,7 +3,7 @@
import path from 'node:path' import path from 'node:path'
import { app } from 'electron' import { dataDir } from '@core/datastore/dirs'
import fs from 'fs-extra' import fs from 'fs-extra'
import { commonTaskStatus, downloadTaskSpecialStatus, uploadTaskSpecialStatus } from '~/utils/enum' import { commonTaskStatus, downloadTaskSpecialStatus, uploadTaskSpecialStatus } from '~/utils/enum'
@@ -15,7 +15,7 @@ class UpDownTaskQueue {
private downloadTaskQueue = [] as IDownloadTask[] private downloadTaskQueue = [] as IDownloadTask[]
private persistPath = path.join(app.getPath('userData'), 'UpDownTaskQueue.json') private persistPath = path.join(dataDir(), 'UpDownTaskQueue.json')
private constructor() { private constructor() {
this.restore() this.restore()

View File

@@ -2,6 +2,7 @@ import { EventEmitter } from 'node:events'
import { homedir } from 'node:os' import { homedir } from 'node:os'
import path from 'node:path' import path from 'node:path'
import { manageConfigPath } from '@core/datastore/dirs'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
import { ipcMain } from 'electron' import { ipcMain } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
@@ -9,7 +10,6 @@ import { get, set, unset } from 'lodash-es'
import API from '~/manage/apis/api' import API from '~/manage/apis/api'
import ManageDB from '~/manage/datastore/db' import ManageDB from '~/manage/datastore/db'
import { managePathChecker } from '~/manage/datastore/dbChecker'
import { formatError, isInputConfigValid } from '~/manage/utils/common' import { formatError, isInputConfigValid } from '~/manage/utils/common'
import { ManageLogger } from '~/manage/utils/logger' import { ManageLogger } from '~/manage/utils/logger'
import { IWindowList } from '~/utils/enum' import { IWindowList } from '~/utils/enum'
@@ -57,7 +57,7 @@ export class ManageApi extends EventEmitter implements IManageApiType {
constructor(currentPicBed: string = '') { constructor(currentPicBed: string = '') {
super() super()
this.currentPicBed = currentPicBed || 'placeholder' this.currentPicBed = currentPicBed || 'placeholder'
this.configPath = managePathChecker() this.configPath = manageConfigPath()
this.initConfigPath() this.initConfigPath()
this.logger = new ManageLogger(this) this.logger = new ManageLogger(this)
this.initconfig() this.initconfig()

View File

@@ -4,18 +4,18 @@ import path from 'node:path'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import axios from 'axios' import axios from 'axios'
import { app } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
import multer from 'multer' import multer from 'multer'
import { dataDir } from '~/apis/core/datastore/dirs'
import routers from '~/server/routerManager' import routers from '~/server/routerManager'
import { ensureHTTPLink, handleResponse } from '~/server/utils' import { ensureHTTPLink, handleResponse } from '~/server/utils'
import { configPaths } from '~/utils/configPaths' import { configPaths } from '~/utils/configPaths'
const DEFAULT_PORT = 36677 const DEFAULT_PORT = 36677
const DEFAULT_HOST = '0.0.0.0' const DEFAULT_HOST = '0.0.0.0'
const appPath = app.getPath('userData')
const serverTempDir = path.join(appPath, 'serverTemp') const serverTempDir = path.join(dataDir(), 'serverTemp')
fs.ensureDirSync(serverTempDir) fs.ensureDirSync(serverTempDir)

View File

@@ -1,12 +1,11 @@
import http from 'node:http' import http from 'node:http'
import path from 'node:path' import path from 'node:path'
import { dbPathDir } from '@core/datastore/dbChecker' import { appLogPath, dataDir } from '@core/datastore/dirs'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import { uploadChoosedFiles, uploadClipboardFiles } from 'apis/app/uploader/apis' import { uploadChoosedFiles, uploadClipboardFiles } from 'apis/app/uploader/apis'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
import { app } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
import { marked } from 'marked' import { marked } from 'marked'
@@ -17,11 +16,9 @@ import { AESHelper } from '~/utils/aesHelper'
import { configPaths } from '~/utils/configPaths' import { configPaths } from '~/utils/configPaths'
import { changeCurrentUploader } from '~/utils/handleUploaderConfig' import { changeCurrentUploader } from '~/utils/handleUploaderConfig'
const appPath = app.getPath('userData') const appPath = dataDir()
const serverTempDir = path.join(appPath, 'serverTemp') const serverTempDir = path.join(appPath, 'serverTemp')
const LOG_PATH = appLogPath()
const STORE_PATH = dbPathDir()
const LOG_PATH = path.join(STORE_PATH, 'piclist.log')
const errorMessage = `upload error. see ${LOG_PATH} for more detail.` const errorMessage = `upload error. see ${LOG_PATH} for more detail.`
const deleteErrorMessage = `delete error. see ${LOG_PATH} for more detail.` const deleteErrorMessage = `delete error. see ${LOG_PATH} for more detail.`

View File

@@ -1,4 +1,4 @@
import db, { GalleryDB } from '@core/datastore' import { GalleryDB } from '@core/datastore'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
@@ -49,7 +49,7 @@ export const deleteChoosedFiles = async (list: ImgInfo[]): Promise<boolean[]> =>
const dbStore = GalleryDB.getInstance() const dbStore = GalleryDB.getInstance()
const file = await dbStore.getById(item.id) const file = await dbStore.getById(item.id)
await dbStore.removeById(item.id) await dbStore.removeById(item.id)
if (await db.get(configPaths.settings.deleteCloudFile)) { if (picgo.getConfig<boolean>(configPaths.settings.deleteCloudFile)) {
if (item.type !== undefined && picBedsCanbeDeleted.includes(item.type)) { if (item.type !== undefined && picBedsCanbeDeleted.includes(item.type)) {
const noteFunc = (value: boolean) => { const noteFunc = (value: boolean) => {
const notification = new Notification({ const notification = new Notification({

View File

@@ -2,13 +2,13 @@ import os from 'node:os'
import path from 'node:path' import path from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { dbPathChecker } from '@core/datastore/dbChecker' import { appConfigPath } from '@core/datastore/dirs'
import fs from 'fs-extra' import fs from 'fs-extra'
import yaml from 'yaml' import yaml from 'yaml'
import { i18nManager } from '~/i18n' import { i18nManager } from '~/i18n'
const configPath = dbPathChecker() const configPath = appConfigPath()
const CONFIG_DIR = path.dirname(configPath) const CONFIG_DIR = path.dirname(configPath)
const dirname = path.dirname(fileURLToPath(import.meta.url)) const dirname = path.dirname(fileURLToPath(import.meta.url))

View File

@@ -1,6 +1,6 @@
import path from 'node:path' import path from 'node:path'
import db from '@core/datastore' import picgo from '@core/picgo'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import axios from 'axios' import axios from 'axios'
import { clipboard, Notification, Tray } from 'electron' import { clipboard, Notification, Tray } from 'electron'
@@ -50,7 +50,7 @@ export function setTrayToolTip(title: string): void {
} }
export const handleCopyUrl = (str: string): void => { export const handleCopyUrl = (str: string): void => {
if (db.get(configPaths.settings.autoCopy) !== false) { if (picgo.getConfig<boolean>(configPaths.settings.autoCopy) !== false) {
clipboard.writeText(str) clipboard.writeText(str)
} }
} }
@@ -132,7 +132,7 @@ export const getClipboardFilePath = (): string => {
const c1nApi = 'https://c1n.cn/link/short' const c1nApi = 'https://c1n.cn/link/short'
const createC1NShortUrl = async (url: string) => { const createC1NShortUrl = async (url: string) => {
const c1nToken = db.get(configPaths.settings.c1nToken) || '' const c1nToken = picgo.getConfig<string>(configPaths.settings.c1nToken) || ''
if (!c1nToken) { if (!c1nToken) {
logger.warn('c1n token is not set') logger.warn('c1n token is not set')
return url return url
@@ -155,8 +155,8 @@ const createC1NShortUrl = async (url: string) => {
} }
const createYOURLSShortLink = async (url: string) => { const createYOURLSShortLink = async (url: string) => {
let domain = db.get(configPaths.settings.yourlsDomain) || '' let domain = picgo.getConfig<string>(configPaths.settings.yourlsDomain) || ''
const signature = db.get(configPaths.settings.yourlsSignature) || '' const signature = picgo.getConfig<string>(configPaths.settings.yourlsSignature) || ''
if (!domain || !signature) { if (!domain || !signature) {
logger.warn('Yourls server or signature is not set') logger.warn('Yourls server or signature is not set')
@@ -187,7 +187,7 @@ const createYOURLSShortLink = async (url: string) => {
} }
const createShortUrlForCFWorker = async (url: string) => { const createShortUrlForCFWorker = async (url: string) => {
let cfWorkerHost = db.get(configPaths.settings.cfWorkerHost) || '' let cfWorkerHost = picgo.getConfig<string>(configPaths.settings.cfWorkerHost) || ''
cfWorkerHost = cfWorkerHost.replace(/\/$/, '') cfWorkerHost = cfWorkerHost.replace(/\/$/, '')
if (!cfWorkerHost) { if (!cfWorkerHost) {
logger.warn('CF Worker host is not set') logger.warn('CF Worker host is not set')
@@ -207,8 +207,8 @@ const createShortUrlForCFWorker = async (url: string) => {
} }
const createShortUrlFromSink = async (url: string) => { const createShortUrlFromSink = async (url: string) => {
let sinkDomain = db.get(configPaths.settings.sinkDomain) || '' let sinkDomain = picgo.getConfig<string>(configPaths.settings.sinkDomain) || ''
const sinkToken = db.get(configPaths.settings.sinkToken) || '' const sinkToken = picgo.getConfig<string>(configPaths.settings.sinkToken) || ''
if (!sinkDomain || !sinkToken) { if (!sinkDomain || !sinkToken) {
logger.warn('Sink domain or token is not set') logger.warn('Sink domain or token is not set')
return url return url
@@ -235,7 +235,7 @@ const createShortUrlFromSink = async (url: string) => {
} }
export const generateShortUrl = async (url: string) => { export const generateShortUrl = async (url: string) => {
const server = db.get(configPaths.settings.shortUrlServer) || IShortUrlServer.C1N const server = picgo.getConfig<string>(configPaths.settings.shortUrlServer) || IShortUrlServer.C1N
switch (server) { switch (server) {
case IShortUrlServer.C1N: case IShortUrlServer.C1N:
return createC1NShortUrl(url) return createC1NShortUrl(url)
@@ -270,7 +270,7 @@ export const isUrlEncode = (url: string): boolean => {
export const handleUrlEncode = (url: string): string => (isUrlEncode(url) ? url : encodeURI(url)) export const handleUrlEncode = (url: string): string => (isUrlEncode(url) ? url : encodeURI(url))
export const handleUrlEncodeWithSetting = (url: string) => export const handleUrlEncodeWithSetting = (url: string) =>
db.get(configPaths.settings.encodeOutputURL) ? handleUrlEncode(url) : url picgo.getConfig<boolean>(configPaths.settings.encodeOutputURL) ? handleUrlEncode(url) : url
export const handleStreamlinePluginName = (name: string) => name.replace(/(@[^/]+\/)?picgo-plugin-/, '') export const handleStreamlinePluginName = (name: string) => name.replace(/(@[^/]+\/)?picgo-plugin-/, '')
export const simpleClone = (obj: any) => JSON.parse(JSON.stringify(obj)) export const simpleClone = (obj: any) => JSON.parse(JSON.stringify(obj))

View File

@@ -1,10 +1,10 @@
import db from '@core/datastore' import picgo from '@core/picgo'
import { i18nManager } from '~/i18n' import { i18nManager } from '~/i18n'
import { configPaths } from '~/utils/configPaths' import { configPaths } from '~/utils/configPaths'
import { II18nLanguage } from '~/utils/enum' import { II18nLanguage } from '~/utils/enum'
export const initI18n = () => { export const initI18n = () => {
const currentLanguage = db.get(configPaths.settings.language) || II18nLanguage.ZH_CN const currentLanguage = picgo.getConfig<string>(configPaths.settings.language) || II18nLanguage.ZH_CN
i18nManager.setCurrentLanguage(currentLanguage) i18nManager.setCurrentLanguage(currentLanguage)
} }

View File

@@ -1,4 +1,4 @@
import db from '@core/datastore' import picgo from '@core/picgo'
import { generateShortUrl, handleUrlEncodeWithSetting } from '~/utils/common' import { generateShortUrl, handleUrlEncodeWithSetting } from '~/utils/common'
import { configPaths } from '~/utils/configPaths' import { configPaths } from '~/utils/configPaths'
@@ -28,7 +28,7 @@ export default async (style: string, item: ImgInfo, customLink: string | undefin
url = item.imgUrl || item.url || '' url = item.imgUrl || item.url || ''
} }
url = handleUrlEncodeWithSetting(url) url = handleUrlEncodeWithSetting(url)
const useShortUrl = db.get(configPaths.settings.useShortUrl) || false const useShortUrl = picgo.getConfig<boolean>(configPaths.settings.useShortUrl) || false
if (useShortUrl) { if (useShortUrl) {
url = item.shortUrl && item.shortUrl !== url ? item.shortUrl : await generateShortUrl(url) url = item.shortUrl && item.shortUrl !== url ? item.shortUrl : await generateShortUrl(url)
} }

View File

@@ -1,12 +1,12 @@
import os from 'node:os' import os from 'node:os'
import path from 'node:path' import path from 'node:path'
import db from '@core/datastore'
import { GalleryDB } from '@core/datastore' import { GalleryDB } from '@core/datastore'
import { dataDir } from '@core/datastore/dirs'
import picgo from '@core/picgo'
import logger from '@core/picgo/logger' import logger from '@core/picgo/logger'
import { Octokit } from '@octokit/rest' import { Octokit } from '@octokit/rest'
import axios from 'axios' import axios from 'axios'
import { app } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
import { HttpsProxyAgent } from 'hpagent' import { HttpsProxyAgent } from 'hpagent'
import { AuthType, createClient, WebDAVClientOptions } from 'webdav' import { AuthType, createClient, WebDAVClientOptions } from 'webdav'
@@ -15,7 +15,7 @@ import { extractData, zipData } from '~/utils/common'
import { formatEndpoint } from '~/utils/common' import { formatEndpoint } from '~/utils/common'
import { configPaths } from '~/utils/configPaths' import { configPaths } from '~/utils/configPaths'
const STORE_PATH = app.getPath('userData') const STORE_PATH = dataDir()
const tempDir = path.join(os.tmpdir(), `piclist-sync-tmp`) const tempDir = path.join(os.tmpdir(), `piclist-sync-tmp`)
const localDBPath = path.join(tempDir, 'db1') const localDBPath = path.join(tempDir, 'db1')
const remoteDBPath = path.join(tempDir, 'db2') const remoteDBPath = path.join(tempDir, 'db2')
@@ -36,7 +36,7 @@ const emptyDir = async (): Promise<void> => {
} }
const mergeGalleryDB = async (targetFile: string) => { const mergeGalleryDB = async (targetFile: string) => {
const lastSyncTime = db.get(configPaths.settings.lastSyncTime) || 0 const lastSyncTime = picgo.getConfig<number>(configPaths.settings.lastSyncTime) || 0
try { try {
const localDBData = (await extractData(path.join(localDBPath, targetFile))) as IGalleryDBFile const localDBData = (await extractData(path.join(localDBPath, targetFile))) as IGalleryDBFile
const remoteDBData = (await extractData(path.join(remoteDBPath, targetFile))) as IGalleryDBFile const remoteDBData = (await extractData(path.join(remoteDBPath, targetFile))) as IGalleryDBFile
@@ -77,7 +77,7 @@ const mergeGalleryDB = async (targetFile: string) => {
} }
const getSyncConfig = () => const getSyncConfig = () =>
db.get(configPaths.settings.sync) || { picgo.getConfig<ISyncConfig>(configPaths.settings.sync) || {
type: 'github', type: 'github',
username: '', username: '',
repo: '', repo: '',
@@ -594,7 +594,7 @@ async function syncGallery(): Promise<number> {
await uploadLocalToRemote(syncConfig, file) await uploadLocalToRemote(syncConfig, file)
logger.info(`gallery db ${file} not exist in cloud, upload local file instead`) logger.info(`gallery db ${file} not exist in cloud, upload local file instead`)
successCount++ successCount++
db.set(configPaths.settings.lastSyncTime, Date.now()) picgo.saveConfig({ [configPaths.settings.lastSyncTime]: Date.now() })
GalleryDB.getInstance(true) GalleryDB.getInstance(true)
continue continue
} }
@@ -606,7 +606,7 @@ async function syncGallery(): Promise<number> {
await fs.copyFile(path.join(STORE_PATH, file), path.join(localDBPath, file)) await fs.copyFile(path.join(STORE_PATH, file), path.join(localDBPath, file))
await mergeGalleryDB(file) await mergeGalleryDB(file)
await updateLocalToRemote(syncConfig, file) await updateLocalToRemote(syncConfig, file)
db.set(configPaths.settings.lastSyncTime, Date.now()) picgo.saveConfig({ [configPaths.settings.lastSyncTime]: Date.now() })
GalleryDB.getInstance(true) // refresh gallery db instance GalleryDB.getInstance(true) // refresh gallery db instance
logger.info(`sync gallery db ${file} success`) logger.info(`sync gallery db ${file} success`)
successCount++ successCount++

View File

@@ -1,12 +1,12 @@
import db from '@core/datastore' import picgo from '@core/picgo'
import updater from 'electron-updater' import updater from 'electron-updater'
import { configPaths } from '~/utils/configPaths' import { configPaths } from '~/utils/configPaths'
const updateChecker = async () => { const updateChecker = async () => {
let showTip = db.get(configPaths.settings.showUpdateTip) let showTip = picgo.getConfig<boolean | undefined>(configPaths.settings.showUpdateTip)
if (showTip === undefined) { if (showTip === undefined) {
db.set(configPaths.settings.showUpdateTip, true) picgo.saveConfig({ [configPaths.settings.showUpdateTip]: true })
showTip = true showTip = true
} }
if (showTip) { if (showTip) {

View File

@@ -1,11 +1,11 @@
import path from 'node:path' import path from 'node:path'
import { GalleryDB } from '@core/datastore' import { GalleryDB } from '@core/datastore'
import db from '@core/datastore' import { dataDir } from '@core/datastore/dirs'
import picgo from '@core/picgo' import picgo from '@core/picgo'
import uploader from 'apis/app/uploader' import uploader from 'apis/app/uploader'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
import { app, Notification, WebContents } from 'electron' import { Notification, WebContents } from 'electron'
import fs from 'fs-extra' import fs from 'fs-extra'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { v4 as uuid } from 'uuid' import { v4 as uuid } from 'uuid'
@@ -72,7 +72,7 @@ class UploadTaskQueueManager {
} }
private webContents: WebContents | null = null private webContents: WebContents | null = null
private persistPath = path.join(app.getPath('userData'), 'taskQueue.json') private persistPath = path.join(dataDir(), 'taskQueue.json')
private taskTimer: NodeJS.Timeout | null = null private taskTimer: NodeJS.Timeout | null = null
private constructor() { private constructor() {
@@ -242,8 +242,8 @@ class UploadTaskQueueManager {
const backupImgs = res[1] ? res[1] : false const backupImgs = res[1] ? res[1] : false
if (imgs !== false && imgs.length > 0) { if (imgs !== false && imgs.length > 0) {
const pasteStyle = db.get(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN const pasteStyle = picgo.getConfig<string>(configPaths.settings.pasteStyle) || IPasteStyle.MARKDOWN
const deleteLocalFile = db.get(configPaths.settings.deleteLocalFile) || false const deleteLocalFile = picgo.getConfig<boolean>(configPaths.settings.deleteLocalFile) || false
const img = imgs[0] const img = imgs[0]
@@ -257,7 +257,11 @@ class UploadTaskQueueManager {
}) })
} }
const [pasteText, shortUrl] = await pasteTemplate(pasteStyle, img, db.get(configPaths.settings.customLink)) const [pasteText, shortUrl] = await pasteTemplate(
pasteStyle,
img,
picgo.getConfig<string>(configPaths.settings.customLink),
)
img.shortUrl = shortUrl img.shortUrl = shortUrl
const inserted = await GalleryDB.getInstance().insert(img) const inserted = await GalleryDB.getInstance().insert(img)
@@ -567,9 +571,9 @@ class UploadTaskQueueManager {
if (stats.completed > 0 || stats.failed > 0) { if (stats.completed > 0 || stats.failed > 0) {
const isShowResultNotification = const isShowResultNotification =
db.get(configPaths.settings.uploadResultNotification) === undefined picgo.getConfig<boolean | undefined>(configPaths.settings.uploadResultNotification) === undefined
? true ? true
: !!db.get(configPaths.settings.uploadResultNotification) : !!picgo.getConfig<boolean>(configPaths.settings.uploadResultNotification)
if (isShowResultNotification) { if (isShowResultNotification) {
const notification = new Notification({ const notification = new Notification({

View File

@@ -1,4 +1,4 @@
import db from '@core/datastore' import picgo from '@core/picgo'
import windowManager from 'apis/app/window/windowManager' import windowManager from 'apis/app/window/windowManager'
import { screen } from 'electron' import { screen } from 'electron'
@@ -11,28 +11,27 @@ export function openMiniWindow(hideSettingWindow: boolean = true) {
miniWindow.removeAllListeners('close') miniWindow.removeAllListeners('close')
miniWindow.removeAllListeners('move') miniWindow.removeAllListeners('move')
if (db.get(configPaths.settings.miniWindowOntop)) { if (picgo.getConfig<boolean>(configPaths.settings.miniWindowOntop)) {
miniWindow.setAlwaysOnTop(true) miniWindow.setAlwaysOnTop(true)
} }
const { width, height } = screen.getPrimaryDisplay().workAreaSize const { width, height } = screen.getPrimaryDisplay().workAreaSize
const lastPosition = db.get(configPaths.settings.miniWindowPosition) const lastPosition = picgo.getConfig<number[]>(configPaths.settings.miniWindowPosition)
const setPositionFunc = () => { const setPositionFunc = () => {
const position = miniWindow.getPosition() const position = miniWindow.getPosition()
db.set(configPaths.settings.miniWindowPosition, position) picgo.saveConfig({ [configPaths.settings.miniWindowPosition]: position })
} }
if (lastPosition) { if (lastPosition) {
if (lastPosition[0] < 0 || lastPosition[0] > width || lastPosition[1] < 0 || lastPosition[1] > height) { if (lastPosition[0] < 0 || lastPosition[0] > width || lastPosition[1] < 0 || lastPosition[1] > height) {
miniWindow.setPosition(width - 100, height - 100) miniWindow.setPosition(width - 100, height - 100)
db.set(configPaths.settings.miniWindowPosition, [width - 100, height - 100]) picgo.saveConfig({ [configPaths.settings.miniWindowPosition]: [width - 100, height - 100] })
} else if ( } else if (
lastPosition[0] + miniWindow.getSize()[0] > width || lastPosition[0] + miniWindow.getSize()[0] > width ||
lastPosition[1] + miniWindow.getSize()[1] > height lastPosition[1] + miniWindow.getSize()[1] > height
) { ) {
miniWindow.setPosition(width - miniWindow.getSize()[0], height - miniWindow.getSize()[1]) miniWindow.setPosition(width - miniWindow.getSize()[0], height - miniWindow.getSize()[1])
db.set(configPaths.settings.miniWindowPosition, [ picgo.saveConfig({
width - miniWindow.getSize()[0], [configPaths.settings.miniWindowPosition]: [width - miniWindow.getSize()[0], height - miniWindow.getSize()[1]],
height - miniWindow.getSize()[1], })
])
} else { } else {
miniWindow.setPosition(lastPosition[0], lastPosition[1]) miniWindow.setPosition(lastPosition[0], lastPosition[1])
} }
@@ -48,7 +47,7 @@ export function openMiniWindow(hideSettingWindow: boolean = true) {
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)! const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)!
settingWindow.hide() settingWindow.hide()
} else { } else {
const autoCloseMainWindow = db.get(configPaths.settings.autoCloseMainWindow) || false const autoCloseMainWindow = picgo.getConfig<boolean>(configPaths.settings.autoCloseMainWindow) || false
if (windowManager.has(IWindowList.SETTING_WINDOW) && autoCloseMainWindow) { if (windowManager.has(IWindowList.SETTING_WINDOW) && autoCloseMainWindow) {
windowManager.get(IWindowList.SETTING_WINDOW)!.hide() windowManager.get(IWindowList.SETTING_WINDOW)!.hide()
} }
@@ -57,7 +56,7 @@ export function openMiniWindow(hideSettingWindow: boolean = true) {
export const openMainWindow = () => { export const openMainWindow = () => {
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW) const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
const autoCloseMiniWindow = db.get(configPaths.settings.autoCloseMiniWindow) || false const autoCloseMiniWindow = picgo.getConfig<boolean>(configPaths.settings.autoCloseMiniWindow) || false
settingWindow!.show() settingWindow!.show()
settingWindow!.focus() settingWindow!.focus()
if (windowManager.has(IWindowList.MINI_WINDOW) && autoCloseMiniWindow) { if (windowManager.has(IWindowList.MINI_WINDOW) && autoCloseMiniWindow) {