From 870c650de72488e33b5abb4d63091edf09eb7c80 Mon Sep 17 00:00:00 2001 From: Kuingsmile <96409857+Kuingsmile@users.noreply.github.com> Date: Wed, 20 Aug 2025 15:16:24 +0800 Subject: [PATCH] :sparkles: Feature(custom): add support for per-picbed image process setting --- .../components/ImageProcessSetting.vue | 404 +++++++++++- src/renderer/components/PerPicbedSetting.vue | 622 ++++++++++++++++++ src/renderer/i18n/locales/en.json | 4 + src/renderer/i18n/locales/zh-CN.json | 4 + src/renderer/i18n/locales/zh-TW.json | 4 + 5 files changed, 1034 insertions(+), 4 deletions(-) create mode 100644 src/renderer/components/PerPicbedSetting.vue diff --git a/src/renderer/components/ImageProcessSetting.vue b/src/renderer/components/ImageProcessSetting.vue index 0785e72e..1461b11b 100644 --- a/src/renderer/components/ImageProcessSetting.vue +++ b/src/renderer/components/ImageProcessSetting.vue @@ -64,12 +64,36 @@ {{ $t('pages.imageProcess.general.isRemoveExif') }} + +
{{ compressForm.quality }}%
+ +
@@ -85,6 +109,15 @@ {{ $t('pages.imageProcess.general.isConvert') }} + +
@@ -95,6 +128,18 @@ {{ format.toUpperCase() }} + +
@@ -105,6 +150,18 @@ rows="3" placeholder='{"jpg": "png", "png": "jpg"}' /> + +
@@ -124,6 +181,17 @@ {{ $t('pages.imageProcess.watermark.isAdd') }} + +
@@ -141,6 +209,21 @@ {{ $t('pages.imageProcess.watermark.image') }}
+ +
@@ -152,6 +235,18 @@ {{ $t('pages.imageProcess.watermark.isFullScreen') }}
+ +
@@ -164,6 +259,21 @@ class="form-range" />
{{ waterMarkForm.watermarkDegree }}°
+ +
@@ -177,10 +287,25 @@ class="form-range" />
{{ Math.round((waterMarkForm.watermarkScaleRatio || 0) * 100) }}%
+ +
-
@@ -190,6 +315,19 @@ class="form-input" :placeholder="$t('pages.imageProcess.watermark.inputTextPlaceholder')" /> + + +
@@ -200,6 +338,18 @@ class="form-input" :placeholder="$t('pages.imageProcess.watermark.textFontPathPlaceholder')" /> + +
@@ -213,6 +363,18 @@ placeholder="#CCCCCC73" />
+ +
@@ -225,6 +387,18 @@ class="form-input" :placeholder="$t('pages.imageProcess.watermark.imagePathPlaceholder')" /> + +
@@ -240,9 +414,22 @@
{{ waterMarkForm.watermarkImageOpacity || 0 }}
+ +
-
@@ -257,6 +444,25 @@ {{ label }}
+ + +
@@ -277,6 +483,15 @@ {{ $t('pages.imageProcess.transform.isFlip') }} + +
@@ -287,6 +502,15 @@ {{ $t('pages.imageProcess.transform.isFlop') }}
+ + @@ -303,12 +527,34 @@ {{ $t('pages.imageProcess.transform.isRotate') }} + +
{{ compressForm.rotateDegree }}°
+ +
@@ -324,6 +570,15 @@ {{ $t('pages.imageProcess.transform.isResize') }} + +
@@ -331,11 +586,37 @@
+ +
+ +
@@ -353,6 +634,17 @@ {{ $t('pages.imageProcess.transform.skipResizeOfSmallImgHeight') }} + + @@ -369,12 +661,36 @@ {{ $t('pages.imageProcess.transform.isResizeByPercentHint') }} + +
{{ compressForm.reSizePercent }}%
+ +
@@ -390,6 +706,9 @@ import { useI18n } from 'vue-i18n' import { configPaths } from '@/utils/configPaths' import { getConfig, saveConfig } from '@/utils/dataSender' +import { updatePicBedGlobal } from '@/utils/global' + +import PerPicbedSetting from './PerPicbedSetting.vue' const { t } = useI18n() const imageProcessDialogVisible = defineModel() @@ -452,33 +771,60 @@ const availableFormat = [ const waterMarkForm = reactive({ isAddWatermark: false, + isAddWatermarkMap: {}, watermarkType: 'text', + watermarkTypeMap: {}, isFullScreenWatermark: false, + isFullScreenWatermarkMap: {}, watermarkDegree: 0, + watermarkDegreeMap: {}, watermarkText: '', + watermarkTextMap: {}, watermarkFontPath: '', + watermarkFontPathMap: {}, watermarkScaleRatio: 0.15, + watermarkScaleRatioMap: {}, watermarkColor: '#CCCCCC73', + watermarkColorMap: {}, watermarkImagePath: '', + watermarkImagePathMap: {}, watermarkPosition: 'southeast', - watermarkImageOpacity: 255 + watermarkPositionMap: {}, + watermarkImageOpacity: 255, + watermarkImageOpacityMap: {} }) const compressForm = reactive({ quality: 100, + qualityMap: {}, isConvert: false, + isConvertMap: {}, convertFormat: 'jpg', + convertFormatMap: {}, isReSize: false, + isReSizeMap: {}, reSizeWidth: 500, + reSizeWidthMap: {}, reSizeHeight: 500, + reSizeHeightMap: {}, skipReSizeOfSmallImg: false, + skipReSizeOfSmallImgMap: {}, isReSizeByPercent: false, + isReSizeByPercentMap: {}, reSizePercent: 50, + reSizePercentMap: {}, isRotate: false, + isRotateMap: {}, rotateDegree: 0, + rotateDegreeMap: {}, isRemoveExif: false, + isRemoveExifMap: {}, isFlip: false, - isFlop: false + isFlipMap: {}, + isFlop: false, + isFlopMap: {}, + formatConvertObj: {}, + formatConvertObjMap: {} }) const formatConvertObj = ref('{}') @@ -486,6 +832,17 @@ const skipProcessForm = reactive({ skipProcessExtList: 'zip,rar,7z,tar,gz,tar.gz,tar.bz2,tar.xz' }) +// State for showing map settings for each field (now unused - kept for future reference) +// const showMapSettings = reactive>({}) + +// Available picbeds for map configuration (now unused - moved to component) +// const availablePicbeds = computed(() => { +// return picBedGlobal.value.map(picbed => ({ +// type: picbed.type, +// name: picbed.name +// })) +// }) + const waterMarkFormKeys = Object.keys(waterMarkForm) as (keyof typeof waterMarkForm)[] const compressFormKeys = Object.keys(compressForm) as (keyof typeof compressForm)[] const skipProcessFormKeys = Object.keys(skipProcessForm) as (keyof typeof skipProcessForm)[] @@ -502,6 +859,25 @@ function handleSaveConfig() { const formatConvertObjFilter = Object.fromEntries(formatConvertObjEntriesFilter) formatConvertObj.value = JSON.stringify(formatConvertObjFilter) compressForm.formatConvertObj = formatConvertObjFilter + + const processedFormatConvertObjMap: Record = {} + Object.entries(compressForm.formatConvertObjMap || {}).forEach(([picbedType, jsonString]) => { + try { + const parsedObj = JSON.parse(jsonString as string) + const objEntries = Object.entries(parsedObj) + const filteredEntries = objEntries.filter((item: any) => { + return imageExtList.includes(item[0]) && availableFormat.includes(item[1]) + }) + const filteredObj = Object.fromEntries(filteredEntries) + if (Object.keys(filteredObj).length > 0) { + processedFormatConvertObjMap[picbedType] = filteredObj + } + } catch (error) { + // Skip invalid JSON strings + } + }) + compressForm.formatConvertObjMap = processedFormatConvertObjMap + saveConfig(configPaths.buildIn.compress, toRaw(compressForm)) saveConfig(configPaths.buildIn.watermark, toRaw(waterMarkForm)) saveConfig(configPaths.buildIn.skipProcess, toRaw(skipProcessForm)) @@ -543,7 +919,27 @@ function closeDialog() { imageProcessDialogVisible.value = false } +// Helper function for getting map values (now unused - moved to component) +// function getMapValue(mapObj: Record | undefined, picbedType: string, defaultValue: any) { +// if (!mapObj) return defaultValue +// return mapObj[picbedType] !== undefined ? mapObj[picbedType] : defaultValue +// } + +// Safe wrapper for setMapValue that ensures map objects exist +function safeSetMapValue(form: any, fieldName: string, picbedType: string, value: any, defaultValue: any) { + const mapFieldName = `${fieldName}Map` + if (!form[mapFieldName]) { + form[mapFieldName] = {} + } + if (value === defaultValue) { + delete form[mapFieldName][picbedType] + } else { + form[mapFieldName][picbedType] = value + } +} + onBeforeMount(async () => { + await updatePicBedGlobal() await initData() }) diff --git a/src/renderer/components/PerPicbedSetting.vue b/src/renderer/components/PerPicbedSetting.vue new file mode 100644 index 00000000..14585646 --- /dev/null +++ b/src/renderer/components/PerPicbedSetting.vue @@ -0,0 +1,622 @@ + + + + + diff --git a/src/renderer/i18n/locales/en.json b/src/renderer/i18n/locales/en.json index 163a1e5a..e1741964 100644 --- a/src/renderer/i18n/locales/en.json +++ b/src/renderer/i18n/locales/en.json @@ -128,6 +128,10 @@ "isResizeByPercent": "Enable Resize by Percentage", "isResizeByPercentHint": "Higher priority", "resizePercent": "Resize Percentage (Enter 50 for 50%)" + }, + "perPicBed": { + "title": "Per-PicBed Settings", + "description": "Configure settings for each PicBed individually" } }, "settings": { diff --git a/src/renderer/i18n/locales/zh-CN.json b/src/renderer/i18n/locales/zh-CN.json index e4010768..fc5b5d57 100644 --- a/src/renderer/i18n/locales/zh-CN.json +++ b/src/renderer/i18n/locales/zh-CN.json @@ -128,6 +128,10 @@ "isResizeByPercent": "启用按比例调整", "isResizeByPercentHint": "优先级更高", "resizePercent": "调整比例 (输入 50 表示 50%)" + }, + "perPicBed": { + "title": "图床独立设置", + "description": "为每个图床单独配置设置" } }, "settings": { diff --git a/src/renderer/i18n/locales/zh-TW.json b/src/renderer/i18n/locales/zh-TW.json index 44dce708..a2f73464 100644 --- a/src/renderer/i18n/locales/zh-TW.json +++ b/src/renderer/i18n/locales/zh-TW.json @@ -128,6 +128,10 @@ "isResizeByPercent": "啟用按比例調整", "isResizeByPercentHint": "優先級更高", "resizePercent": "調整比例 (輸入 50 表示 50%)" + }, + "perPicBed": { + "title": "圖床獨立設置", + "description": "為每個圖床單獨配置設置" } }, "settings": {