mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-06-09 17:49:53 +08:00
@@ -26,6 +26,7 @@ import { configPaths } from '~/utils/configPaths'
|
||||
import { IPasteStyle, IWindowList } from '~/utils/enum'
|
||||
import { isMacOSVersionGreaterThanOrEqualTo } from '~/utils/getMacOSVersion'
|
||||
import pasteTemplate from '~/utils/pasteTemplate'
|
||||
import { runScriptInStage } from '~/utils/runScript'
|
||||
import { hideMiniWindow, openMainWindow, openMiniWindow } from '~/utils/windowHelper'
|
||||
|
||||
import menubarPng from '../../../../../resources/menubar.png?asset&asarUnpack'
|
||||
@@ -308,8 +309,8 @@ export function createTray(tooltip: string) {
|
||||
const rawInput = cloneDeep(files)
|
||||
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)
|
||||
const res = await uploader.setWebContents(trayWindow?.webContents).uploadReturnCtx(files)
|
||||
const imgs = res[0] ? res[0] : false
|
||||
const backImgs = res[1] ? res[1] : false
|
||||
const imgs = res.ctx?.output ? res.ctx.output : false
|
||||
const backImgs = res.backupCtx?.output ? res.backupCtx.output : false
|
||||
const deleteLocalFile = allConfig.settings?.deleteLocalFile || false
|
||||
if (imgs !== false) {
|
||||
const pasteText: string[] = []
|
||||
@@ -334,7 +335,8 @@ export function createTray(tooltip: string) {
|
||||
notification.show()
|
||||
}, i * 100)
|
||||
}
|
||||
await GalleryDB.getInstance().insert(imgs[i])
|
||||
const inserted = await GalleryDB.getInstance().insert(imgs[i])
|
||||
runScriptInStage('onUploadSuccess', res.ctx || picgo, { galleryItem: inserted })
|
||||
}
|
||||
handleCopyUrl(pasteText.join('\n'))
|
||||
trayWindow?.webContents.send('dragFiles', imgs)
|
||||
|
||||
@@ -1,46 +1,56 @@
|
||||
import path from 'node:path'
|
||||
|
||||
import { themesDir } from '@core/datastore/dirs'
|
||||
import * as fsWalk from '@nodelib/fs.walk'
|
||||
import AdmZip from 'adm-zip'
|
||||
import axios from 'axios'
|
||||
import fs from 'fs-extra'
|
||||
|
||||
import { randomStringGenerator } from '@/manage/utils/common'
|
||||
import logger from '~/apis/core/picgo/logger'
|
||||
import { IWindowList } from '~/utils/enum'
|
||||
|
||||
import windowManager from '../window/windowManager'
|
||||
|
||||
export async function resolveThemes(): Promise<{ key: string; label: string }[]> {
|
||||
const files = fsWalk.walkSync(themesDir(), {
|
||||
followSymbolicLinks: true,
|
||||
fs,
|
||||
stats: true,
|
||||
throwErrorOnBrokenSymbolicLink: false,
|
||||
})
|
||||
const result: string[] = []
|
||||
files.forEach(item => {
|
||||
if (item.stats?.isFile()) {
|
||||
result.push(path.basename(item.path))
|
||||
}
|
||||
})
|
||||
const themes = await Promise.all(
|
||||
result
|
||||
.filter(file => file.endsWith('.css'))
|
||||
.map(async file => {
|
||||
const css = (await fs.readFile(path.join(themesDir(), file), 'utf-8')) || ''
|
||||
let name = file
|
||||
if (css.startsWith('/*')) {
|
||||
name = css.split('\n')[0].replace('/*', '').replace('*/', '').trim() || file
|
||||
const dir = themesDir()
|
||||
const entries = await fs.readdir(dir, { withFileTypes: true })
|
||||
const themePromises = entries
|
||||
.filter(entry => entry.isFile() && entry.name.endsWith('.css'))
|
||||
.map(async entry => {
|
||||
const filePath = path.join(dir, entry.name)
|
||||
|
||||
let label = entry.name
|
||||
let fd
|
||||
try {
|
||||
fd = await fs.open(filePath, 'r')
|
||||
const buffer = Buffer.alloc(256)
|
||||
const { bytesRead } = await fs.read(fd, buffer, 0, 256, 0)
|
||||
const content = buffer.toString('utf8', 0, bytesRead)
|
||||
const match = content.match(/^\/\*\s*(.*?)\s*\*\//)
|
||||
if (match && match[1]) {
|
||||
label = match[1].trim()
|
||||
}
|
||||
return { key: file, label: name }
|
||||
}),
|
||||
)
|
||||
if (themes.find(theme => theme.key === 'default.css')) {
|
||||
return themes
|
||||
} catch (e: any) {
|
||||
logger.error(e)
|
||||
} finally {
|
||||
if (fd !== undefined) await fs.close(fd)
|
||||
}
|
||||
|
||||
return { key: entry.name, label }
|
||||
})
|
||||
|
||||
const themes = await Promise.all(themePromises)
|
||||
|
||||
const hasDefault = themes.some(t => t.key === 'default.css')
|
||||
if (!hasDefault) {
|
||||
themes.unshift({ key: 'default.css', label: '默认' })
|
||||
} else {
|
||||
return [{ key: 'default.css', label: '默认' }, ...themes]
|
||||
const idx = themes.findIndex(t => t.key === 'default.css')
|
||||
const [defaultTheme] = themes.splice(idx, 1)
|
||||
themes.unshift(defaultTheme)
|
||||
}
|
||||
|
||||
return themes
|
||||
}
|
||||
|
||||
export async function fetchThemes(): Promise<boolean> {
|
||||
|
||||
@@ -11,8 +11,9 @@ import { handleCopyUrl, handleUrlEncodeWithSetting } from '~/utils/common'
|
||||
import { configPaths } from '~/utils/configPaths'
|
||||
import { IPasteStyle, IWindowList } from '~/utils/enum'
|
||||
import pasteTemplate from '~/utils/pasteTemplate'
|
||||
import { runScriptInStage } from '~/utils/runScript'
|
||||
|
||||
const handleClipboardUploadingReturnCtx = async (img?: IUploadOption): Promise<(ImgInfo[] | false)[]> => {
|
||||
const handleClipboardUploadingReturnCtx = async (img?: IUploadOption): Promise<IuploadReturnCtxResult> => {
|
||||
const useBuiltinClipboardConfig = picgo.getConfig<boolean | undefined>(configPaths.settings.useBuiltinClipboard)
|
||||
const useBuiltinClipboard = useBuiltinClipboardConfig === undefined ? true : !!useBuiltinClipboardConfig
|
||||
const win = windowManager.getAvailableWindow()
|
||||
@@ -26,8 +27,8 @@ export const uploadClipboardFiles = async (): Promise<IStringKeyMap> => {
|
||||
let img: ImgInfo[] | false = false
|
||||
let backImg: ImgInfo[] | false = false
|
||||
const res = await handleClipboardUploadingReturnCtx()
|
||||
img = res[0] ? res[0] : false
|
||||
backImg = res[1] ? res[1] : false
|
||||
img = res.ctx?.output ? res.ctx.output : false
|
||||
backImg = res.backupCtx?.output ? res.backupCtx.output : false
|
||||
const allConfig = picgo.getConfig<any>() || {}
|
||||
if (img !== false) {
|
||||
if (img.length > 0) {
|
||||
@@ -50,6 +51,7 @@ export const uploadClipboardFiles = async (): Promise<IStringKeyMap> => {
|
||||
}, 100)
|
||||
}
|
||||
const inserted = await GalleryDB.getInstance().insert(img[0])
|
||||
runScriptInStage('onUploadSuccess', res.ctx || picgo, { galleryItem: inserted })
|
||||
// trayWindow just be created in mac/windows, not in linux
|
||||
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)
|
||||
trayWindow?.webContents?.send('clipboardFiles', [])
|
||||
@@ -93,8 +95,8 @@ export const uploadChoosedFiles = async (
|
||||
let imgs: ImgInfo[] | false = false
|
||||
let backImgs: ImgInfo[] | false = false
|
||||
const res = await uploader.setWebContents(webContents).uploadReturnCtx(input)
|
||||
imgs = res[0] ? res[0] : false
|
||||
backImgs = res[1] ? res[1] : false
|
||||
imgs = res.ctx?.output ? res.ctx.output : false
|
||||
backImgs = res.backupCtx?.output ? res.backupCtx.output : false
|
||||
const result = []
|
||||
const allConfig = picgo.getConfig<any>() || {}
|
||||
if (imgs !== false) {
|
||||
@@ -140,6 +142,7 @@ export const uploadChoosedFiles = async (
|
||||
}
|
||||
}
|
||||
const inserted = await GalleryDB.getInstance().insert(imgs[i])
|
||||
runScriptInStage('onUploadSuccess', res.ctx || picgo, { galleryItem: inserted })
|
||||
result.push({
|
||||
url: handleUrlEncodeWithSetting(inserted.imgUrl!),
|
||||
fullResult: inserted,
|
||||
|
||||
@@ -118,15 +118,15 @@ class Uploader {
|
||||
return filePath
|
||||
}
|
||||
|
||||
async uploadWithBuildInClipboardReturnCtx(img?: IUploadOption): Promise<(ImgInfo[] | false)[]> {
|
||||
async uploadWithBuildInClipboardReturnCtx(img?: IUploadOption): Promise<IuploadReturnCtxResult> {
|
||||
let imgPath: string | false = false
|
||||
try {
|
||||
imgPath = await this.getClipboardImagePath()
|
||||
if (!imgPath) return [false, false]
|
||||
if (!imgPath) return { ctx: undefined, backupCtx: undefined }
|
||||
return await this.uploadReturnCtx(img ?? [imgPath])
|
||||
} catch (e: any) {
|
||||
logger.error(e)
|
||||
return [false, false]
|
||||
return { ctx: undefined, backupCtx: undefined }
|
||||
} finally {
|
||||
if (imgPath && imgPath.startsWith(path.join(picgo.baseDir, CLIPBOARD_IMAGE_FOLDER))) {
|
||||
fs.remove(imgPath)
|
||||
@@ -134,24 +134,24 @@ class Uploader {
|
||||
}
|
||||
}
|
||||
|
||||
async uploadReturnCtx(img?: IUploadOption): Promise<(ImgInfo[] | false)[]> {
|
||||
async uploadReturnCtx(img?: IUploadOption): Promise<IuploadReturnCtxResult> {
|
||||
try {
|
||||
const result = [false, false] as (ImgInfo[] | false)[]
|
||||
const result = { ctx: undefined, backupCtx: undefined } as IuploadReturnCtxResult
|
||||
const res = await picgo.uploadReturnCtx(img)
|
||||
const allConfig = picgo.getConfig<any>() || {}
|
||||
|
||||
if (Array.isArray(res.output) && res.output.some((item: ImgInfo) => item.imgUrl)) {
|
||||
res.output.forEach((item: ImgInfo) => {
|
||||
if (Array.isArray(res.ctx?.output) && res.ctx?.output.some((item: ImgInfo) => item.imgUrl)) {
|
||||
res.ctx.output.forEach((item: ImgInfo) => {
|
||||
item.config = JSON.parse(JSON.stringify(allConfig.picBed?.[item.type!]))
|
||||
})
|
||||
result[0] = res.output
|
||||
result.ctx = res.ctx
|
||||
}
|
||||
|
||||
if (Array.isArray(res.backupOutput) && res.backupOutput.some((item: ImgInfo) => item.imgUrl)) {
|
||||
res.backupOutput.forEach((item: ImgInfo) => {
|
||||
if (Array.isArray(res.backupCtx?.output) && res.backupCtx?.output.some((item: ImgInfo) => item.imgUrl)) {
|
||||
res.backupCtx.output.forEach((item: ImgInfo) => {
|
||||
item.config = JSON.parse(JSON.stringify(allConfig.picBed?.[item.type!]))
|
||||
})
|
||||
result[1] = res.backupOutput
|
||||
result.backupCtx = res.backupCtx
|
||||
}
|
||||
return result
|
||||
} catch (e: any) {
|
||||
@@ -163,7 +163,7 @@ class Uploader {
|
||||
clickToCopy: true,
|
||||
})
|
||||
}, 500)
|
||||
return [false, false]
|
||||
return { ctx: undefined, backupCtx: undefined } as IuploadReturnCtxResult
|
||||
} finally {
|
||||
ipcMain.removeAllListeners(GET_RENAME_FILE_NAME)
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ export function defaultDir() {
|
||||
return userDataDir()
|
||||
}
|
||||
|
||||
export function scriptsDir() {
|
||||
return path.join(dataDir(), 'scripts')
|
||||
}
|
||||
|
||||
export function defaultConfigPath() {
|
||||
if (isPortable()) {
|
||||
return path.join(exeDir(), 'data', 'data.json')
|
||||
|
||||
@@ -13,6 +13,7 @@ import { T as $t } from '~/i18n'
|
||||
import { handleCopyUrl } from '~/utils/common'
|
||||
import { IPasteStyle } from '~/utils/enum'
|
||||
import pasteTemplate from '~/utils/pasteTemplate'
|
||||
import { runScriptInStage } from '~/utils/runScript'
|
||||
|
||||
// Cross-process support may be required in the future
|
||||
class GuiApi implements IGuiApi {
|
||||
@@ -74,8 +75,8 @@ class GuiApi implements IGuiApi {
|
||||
const webContents = this.getWebcontentsByWindowId(this.windowId)
|
||||
const rawInput = cloneDeep(input)
|
||||
const res = await uploader.setWebContents(webContents!).uploadReturnCtx(input)
|
||||
const imgs = res[0] ? res[0] : false
|
||||
const backImgs = res[1] ? res[1] : false
|
||||
const imgs = res.ctx?.output ? res.ctx.output : false
|
||||
const backImgs = res.backupCtx?.output ? res.backupCtx.output : false
|
||||
let result: ImgInfo[] = []
|
||||
const allConfig = picgo.getConfig<any>() || {}
|
||||
if (imgs !== false) {
|
||||
@@ -103,7 +104,8 @@ class GuiApi implements IGuiApi {
|
||||
notification.show()
|
||||
}, i * 100)
|
||||
}
|
||||
await GalleryDB.getInstance().insert(imgs[i])
|
||||
const inserted = await GalleryDB.getInstance().insert(imgs[i])
|
||||
runScriptInStage('onUploadSuccess', res.ctx || picgo, { galleryItem: inserted })
|
||||
}
|
||||
handleCopyUrl(pasteText.join('\n'))
|
||||
webContents?.send('uploadFiles')
|
||||
|
||||
Reference in New Issue
Block a user