mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-05-07 04:52:43 +08:00
✨ Feature(custom): add per picbed rename setting
This commit is contained in:
@@ -939,6 +939,114 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Rename Tab -->
|
||||||
|
<div v-else-if="activeTab === 'rename'" key="rename" class="tab-content">
|
||||||
|
<div class="settings-section">
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="switch-label">
|
||||||
|
<input v-model="autoRenameComputed" type="checkbox" class="switch-input" />
|
||||||
|
<span class="switch-slider" />
|
||||||
|
<div class="switch-content">
|
||||||
|
<span class="switch-title">{{ $t('pages.imageProcess.rename.renameTimestamp') }}</span>
|
||||||
|
<span class="switch-description">YYYYMMDDHHmmssSSS</span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="switch-label">
|
||||||
|
<input v-model="manualRenameComputed" type="checkbox" class="switch-input" />
|
||||||
|
<span class="switch-slider" />
|
||||||
|
<div class="switch-content">
|
||||||
|
<span class="switch-title">{{ $t('pages.imageProcess.rename.manualRename') }}</span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="switch-label">
|
||||||
|
<input v-model="renameSettingsComputed.rename.enable" type="checkbox" class="switch-input" />
|
||||||
|
<span class="switch-slider" />
|
||||||
|
<div class="switch-content">
|
||||||
|
<div class="switch-title">{{ $t('pages.settings.upload.enableAdvancedRname') }}</div>
|
||||||
|
<div class="switch-description">{{ $t('pages.settings.upload.enableAdvancedRnameDesc') }}</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group rename-format-field">
|
||||||
|
<label>
|
||||||
|
<Edit :size="14" />
|
||||||
|
{{ $t('pages.settings.upload.advancedRnameFormat') }}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="renameSettingsComputed.rename.format"
|
||||||
|
type="text"
|
||||||
|
class="form-input"
|
||||||
|
placeholder="Ex. {Y}-{m}-{uuid}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{ $t('pages.settings.upload.availablePlaceholders') }}</label>
|
||||||
|
<div class="placeholder-help">
|
||||||
|
<div class="placeholder-category">
|
||||||
|
<div class="category-title">
|
||||||
|
{{ $t('pages.settings.upload.placeholder.categoryTime') }}
|
||||||
|
</div>
|
||||||
|
<div class="placeholder-grid">
|
||||||
|
<div
|
||||||
|
v-for="item in advancedRenameList.categoryTime"
|
||||||
|
:key="item.value"
|
||||||
|
class="placeholder-item"
|
||||||
|
@click="copyPlaceholder(item.value)"
|
||||||
|
>
|
||||||
|
<code>{{ item.value }}</code>
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="placeholder-category">
|
||||||
|
<div class="category-title">
|
||||||
|
{{ $t('pages.settings.upload.placeholder.categoryHash') }}
|
||||||
|
</div>
|
||||||
|
<div class="placeholder-grid">
|
||||||
|
<div
|
||||||
|
v-for="item in advancedRenameList.categoryHash"
|
||||||
|
:key="item.value"
|
||||||
|
class="placeholder-item"
|
||||||
|
@click="copyPlaceholder(item.value)"
|
||||||
|
>
|
||||||
|
<code>{{ item.value }}</code>
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="placeholder-category">
|
||||||
|
<div class="category-title">
|
||||||
|
{{ $t('pages.settings.upload.placeholder.categoryFile') }}
|
||||||
|
</div>
|
||||||
|
<div class="placeholder-grid">
|
||||||
|
<div
|
||||||
|
v-for="item in advancedRenameList.categoryFile"
|
||||||
|
:key="item.value"
|
||||||
|
class="placeholder-item"
|
||||||
|
@click="copyPlaceholder(item.value)"
|
||||||
|
>
|
||||||
|
<code>{{ item.value }}</code>
|
||||||
|
<span>{{ item.label }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -947,6 +1055,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import {
|
||||||
Droplets,
|
Droplets,
|
||||||
|
Edit,
|
||||||
FileText,
|
FileText,
|
||||||
FlipHorizontal,
|
FlipHorizontal,
|
||||||
Image,
|
Image,
|
||||||
@@ -968,11 +1077,13 @@ import { computed, nextTick, onBeforeMount, onBeforeUnmount, onMounted, ref, toR
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import PerPicbedSetting from '@/components/PerPicbedSetting.vue'
|
import PerPicbedSetting from '@/components/PerPicbedSetting.vue'
|
||||||
|
import useMessage from '@/hooks/useMessage'
|
||||||
import { getRawData } from '@/utils/common'
|
import { getRawData } from '@/utils/common'
|
||||||
import { configPaths } from '@/utils/configPaths'
|
import { configPaths } from '@/utils/configPaths'
|
||||||
import { getConfig, saveConfig } from '@/utils/dataSender'
|
import { getConfig, saveConfig } from '@/utils/dataSender'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
const message = useMessage()
|
||||||
const activeTab = ref('general')
|
const activeTab = ref('general')
|
||||||
|
|
||||||
// Tab indicator animation
|
// Tab indicator animation
|
||||||
@@ -1028,6 +1139,37 @@ const tabs = computed(() => [
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const advancedRenameList = computed(() => ({
|
||||||
|
categoryTime: [
|
||||||
|
{ label: t('pages.settings.upload.placeholder.year4'), value: '{Y}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.year2'), value: '{y}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.month'), value: '{m}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.date'), value: '{d}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.hour'), value: '{h}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.minute'), value: '{i}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.second'), value: '{s}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.millisecond'), value: '{ms}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.timestamp'), value: '{timestamp}' },
|
||||||
|
],
|
||||||
|
categoryHash: [
|
||||||
|
{ label: t('pages.settings.upload.placeholder.md5'), value: '{md5}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.md5-16'), value: '{md5-16}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.uuid'), value: '{uuid}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.sha256'), value: '{sha256}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.sha256-n'), value: '{sha256-n}' },
|
||||||
|
],
|
||||||
|
categoryFile: [
|
||||||
|
{ label: t('pages.settings.upload.placeholder.filename'), value: '{filename}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.localFolder'), value: '{localFolder:n}' },
|
||||||
|
{ label: t('pages.settings.upload.placeholder.randomString'), value: '{str-n}' },
|
||||||
|
],
|
||||||
|
}))
|
||||||
|
|
||||||
|
function copyPlaceholder(placeholder: string) {
|
||||||
|
window.electron.clipboard.writeText(placeholder)
|
||||||
|
message.success(t('pages.settings.upload.copySuccess', { content: placeholder }))
|
||||||
|
}
|
||||||
|
|
||||||
const waterMarkPositionMap = new Map([
|
const waterMarkPositionMap = new Map([
|
||||||
['north', t('pages.imageProcess.watermark.positionOptions.top')],
|
['north', t('pages.imageProcess.watermark.positionOptions.top')],
|
||||||
['northeast', t('pages.imageProcess.watermark.positionOptions.topRight')],
|
['northeast', t('pages.imageProcess.watermark.positionOptions.topRight')],
|
||||||
@@ -1142,6 +1284,15 @@ const defaultSkipProcessSetting = {
|
|||||||
const skipProcessForm = ref<IBuildInSkipProcessOptions>({
|
const skipProcessForm = ref<IBuildInSkipProcessOptions>({
|
||||||
...defaultSkipProcessSetting,
|
...defaultSkipProcessSetting,
|
||||||
})
|
})
|
||||||
|
const globalRenameSettings = ref<{
|
||||||
|
enable?: boolean
|
||||||
|
format?: string
|
||||||
|
}>({
|
||||||
|
enable: false,
|
||||||
|
format: '{filename}',
|
||||||
|
})
|
||||||
|
const globalAutoRename = ref<Undefinable<boolean>>(false)
|
||||||
|
const globalManualRename = ref<Undefinable<boolean>>(false)
|
||||||
|
|
||||||
const isInitialized = ref(false)
|
const isInitialized = ref(false)
|
||||||
|
|
||||||
@@ -1182,11 +1333,21 @@ let singleConfigInFile = {
|
|||||||
id: configId || '',
|
id: configId || '',
|
||||||
} as IBuildInListItem
|
} as IBuildInListItem
|
||||||
let compressInFile = {} as IBuildInCompressOptions
|
let compressInFile = {} as IBuildInCompressOptions
|
||||||
|
|
||||||
async function initData() {
|
async function initData() {
|
||||||
// global settings
|
// global settings
|
||||||
compressInFile = (await getConfig<IBuildInCompressOptions>(configPaths.buildIn.compress)) || {}
|
compressInFile = (await getConfig<IBuildInCompressOptions>(configPaths.buildIn.compress)) || {}
|
||||||
const watermark = (await getConfig<IBuildInWaterMarkOptions>(configPaths.buildIn.watermark)) || {}
|
const watermark = (await getConfig<IBuildInWaterMarkOptions>(configPaths.buildIn.watermark)) || {}
|
||||||
const skipProcess = (await getConfig<IBuildInSkipProcessOptions>(configPaths.buildIn.skipProcess)) || {}
|
const skipProcess = (await getConfig<IBuildInSkipProcessOptions>(configPaths.buildIn.skipProcess)) || {}
|
||||||
|
globalRenameSettings.value = (await getConfig<{
|
||||||
|
enable?: boolean
|
||||||
|
format?: string
|
||||||
|
}>(configPaths.buildIn.rename)) || {
|
||||||
|
enable: false,
|
||||||
|
format: '{filename}',
|
||||||
|
}
|
||||||
|
globalAutoRename.value = (await getConfig<boolean>(configPaths.settings.autoRename)) ?? false
|
||||||
|
globalManualRename.value = (await getConfig<boolean>(configPaths.settings.rename)) ?? false
|
||||||
if (compressInFile) {
|
if (compressInFile) {
|
||||||
let cleanedObj = {}
|
let cleanedObj = {}
|
||||||
try {
|
try {
|
||||||
@@ -1251,8 +1412,6 @@ async function initData() {
|
|||||||
enable: false,
|
enable: false,
|
||||||
format: '{filename}',
|
format: '{filename}',
|
||||||
}
|
}
|
||||||
const globalAutoRename = (await getConfig<boolean>(configPaths.settings.rename)) || false
|
|
||||||
const globalManualRename = (await getConfig<boolean>(configPaths.settings.autoRename)) || false
|
|
||||||
if (!buildInList) {
|
if (!buildInList) {
|
||||||
saveConfig(configPaths.buildIn.list, [])
|
saveConfig(configPaths.buildIn.list, [])
|
||||||
buildInList = []
|
buildInList = []
|
||||||
@@ -1319,8 +1478,8 @@ async function initData() {
|
|||||||
...globalRenameSettings,
|
...globalRenameSettings,
|
||||||
...(singleConfigInFile.rename || {}),
|
...(singleConfigInFile.rename || {}),
|
||||||
},
|
},
|
||||||
autoRename: globalAutoRename || singleConfigInFile.autoRename || false,
|
autoRename: singleConfigInFile.autoRename ?? (globalAutoRename.value || false),
|
||||||
manualRename: globalManualRename || singleConfigInFile.manualRename || false,
|
manualRename: singleConfigInFile.manualRename ?? (globalManualRename.value || false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1397,6 +1556,99 @@ const activeForm = computed<any>(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const autoRenameComputed = computed({
|
||||||
|
get() {
|
||||||
|
return configId ? singleConfigSettings.value.autoRename : globalAutoRename.value
|
||||||
|
},
|
||||||
|
set(newValue) {
|
||||||
|
if (configId) {
|
||||||
|
singleConfigSettings.value.autoRename = newValue
|
||||||
|
const shouldUpdate = newValue !== (globalAutoRename.value ?? false)
|
||||||
|
singleConfigInFile.id = configId || ''
|
||||||
|
if (shouldUpdate) {
|
||||||
|
singleConfigInFile.autoRename = newValue
|
||||||
|
UpdateBuildInList(singleConfigInFile)
|
||||||
|
} else {
|
||||||
|
if (singleConfigInFile.autoRename !== undefined) delete singleConfigInFile.autoRename
|
||||||
|
checkIfItemOnlyId(singleConfigInFile).then(async isOnlyId => {
|
||||||
|
if (isOnlyId) {
|
||||||
|
await removeItemFromBuildInList(singleConfigInFile.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globalAutoRename.value = newValue
|
||||||
|
saveConfig(configPaths.settings.autoRename, newValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const manualRenameComputed = computed({
|
||||||
|
get() {
|
||||||
|
return configId ? singleConfigSettings.value.manualRename : globalManualRename.value
|
||||||
|
},
|
||||||
|
set(newValue) {
|
||||||
|
if (configId) {
|
||||||
|
singleConfigSettings.value.manualRename = newValue
|
||||||
|
const shouldUpdate = newValue !== (globalManualRename.value ?? false)
|
||||||
|
singleConfigInFile.id = configId || ''
|
||||||
|
if (shouldUpdate) {
|
||||||
|
singleConfigInFile.manualRename = newValue
|
||||||
|
UpdateBuildInList(singleConfigInFile)
|
||||||
|
} else {
|
||||||
|
if (singleConfigInFile.manualRename !== undefined) delete singleConfigInFile.manualRename
|
||||||
|
checkIfItemOnlyId(singleConfigInFile).then(async isOnlyId => {
|
||||||
|
if (isOnlyId) {
|
||||||
|
await removeItemFromBuildInList(singleConfigInFile.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
globalManualRename.value = newValue
|
||||||
|
saveConfig(configPaths.settings.rename, newValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const renameSettingsComputed = computed<any>(() => {
|
||||||
|
if (configId) {
|
||||||
|
return {
|
||||||
|
rename: singleConfigSettings.value.rename,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
rename: globalRenameSettings.value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
renameSettingsComputed,
|
||||||
|
newValue => {
|
||||||
|
if (configId) {
|
||||||
|
singleConfigSettings.value.rename = newValue.rename
|
||||||
|
const shouldUpdate =
|
||||||
|
newValue.rename.enable !== (globalRenameSettings.value.enable ?? false) ||
|
||||||
|
newValue.rename.format !== (globalRenameSettings.value.format ?? '{filename}')
|
||||||
|
singleConfigInFile.id = configId || ''
|
||||||
|
if (shouldUpdate) {
|
||||||
|
singleConfigInFile.rename = newValue.rename
|
||||||
|
UpdateBuildInList(singleConfigInFile)
|
||||||
|
} else {
|
||||||
|
if (singleConfigInFile.rename) delete singleConfigInFile.rename
|
||||||
|
checkIfItemOnlyId(singleConfigInFile).then(async isOnlyId => {
|
||||||
|
if (isOnlyId) {
|
||||||
|
await removeItemFromBuildInList(singleConfigInFile.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
saveConfig(configPaths.buildIn.rename, toRaw(newValue.rename))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
)
|
||||||
|
|
||||||
const convertStr = computed({
|
const convertStr = computed({
|
||||||
get() {
|
get() {
|
||||||
return configId ? singleFormatConvertObj.value : formatConvertObjStr.value
|
return configId ? singleFormatConvertObj.value : formatConvertObjStr.value
|
||||||
@@ -1454,11 +1706,9 @@ async function removeItemFromBuildInList(id: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compressWatchKeys.forEach(key => {
|
compressWatchKeys.forEach(key => {
|
||||||
console.log('setting up watch for compress key:', key)
|
|
||||||
watch(
|
watch(
|
||||||
() => singleConfigSettings.value.compress![key],
|
() => singleConfigSettings.value.compress![key],
|
||||||
async newValue => {
|
async newValue => {
|
||||||
console.log('detected change in compress key:', key, 'new value:', newValue)
|
|
||||||
const defaultValue = defaultCompressSetting[key]
|
const defaultValue = defaultCompressSetting[key]
|
||||||
const perPicBedValue = compressForm.value[`${key}Map`]?.[currentPicbedName]
|
const perPicBedValue = compressForm.value[`${key}Map`]?.[currentPicbedName]
|
||||||
const inheritedValue = perPicBedValue ?? compressForm.value[key] ?? defaultValue
|
const inheritedValue = perPicBedValue ?? compressForm.value[key] ?? defaultValue
|
||||||
|
|||||||
@@ -457,9 +457,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.switch-description {
|
.switch-description {
|
||||||
font-size: 0.8rem;
|
font-size: 0.75rem;
|
||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
line-height: 1.4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==================== Radio Group ==================== */
|
/* ==================== Radio Group ==================== */
|
||||||
@@ -857,3 +856,168 @@ small {
|
|||||||
:root.auto.dark small {
|
:root.auto.dark small {
|
||||||
background: var(--color-surface);
|
background: var(--color-surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Placeholder Help Styles */
|
||||||
|
.placeholder-help {
|
||||||
|
overflow-y: auto;
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 0;
|
||||||
|
max-height: 400px;
|
||||||
|
background: var(--color-background-tertiary);
|
||||||
|
box-shadow: 0 2px 8px rgb(0 0 0 / 6%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-category {
|
||||||
|
border-bottom: 1px solid var(--color-border-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-category:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-title {
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid var(--color-border-light);
|
||||||
|
padding: 0.875rem 1rem 0.5rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
background: linear-gradient(135deg, var(--color-background-secondary) 0%, var(--color-background-tertiary) 100%);
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||||
|
gap: 0;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-item:hover {
|
||||||
|
background: rgb(var(--color-accent-rgb), 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-item code {
|
||||||
|
margin-right: 0.875rem;
|
||||||
|
border: 1px solid rgb(255 255 255 / 20%);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0.3rem 0.6rem;
|
||||||
|
min-width: 80px;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: 'SF Mono', Monaco, Menlo, 'Ubuntu Mono', monospace;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
background: var(--color-blue-common);
|
||||||
|
box-shadow: 0 1px 3px rgb(0 0 0 / 12%), 0 1px 2px rgb(0 0 0 / 24%);
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-item span {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scrollbar styling for macOS feel */
|
||||||
|
.placeholder-help::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-help::-webkit-scrollbar-track {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-help::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--color-border);
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-help::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rename specific styles */
|
||||||
|
.rename-toggle-card {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 0.25rem;
|
||||||
|
background: var(--color-background-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rename-toggle-card .switch-label {
|
||||||
|
margin: 0;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rename-format-field label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rename-format-field label svg {
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-icon.rename-icon {
|
||||||
|
background: linear-gradient(135deg, #52c41a25 0%, #52c41a35 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark theme adjustments */
|
||||||
|
:root.dark .placeholder-help,
|
||||||
|
:root.auto.dark .placeholder-help {
|
||||||
|
border-color: var(--color-border);
|
||||||
|
background: var(--color-background-secondary);
|
||||||
|
box-shadow: 0 2px 8px rgb(0 0 0 / 20%);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .category-title,
|
||||||
|
:root.auto.dark .category-title {
|
||||||
|
border-bottom-color: var(--color-border);
|
||||||
|
background: linear-gradient(135deg, var(--color-background-tertiary) 0%, var(--color-background-secondary) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .placeholder-category,
|
||||||
|
:root.auto.dark .placeholder-category {
|
||||||
|
border-bottom-color: var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .placeholder-item:hover,
|
||||||
|
:root.auto.dark .placeholder-item:hover {
|
||||||
|
background: rgb(var(--color-accent-rgb), 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .placeholder-item code,
|
||||||
|
:root.auto.dark .placeholder-item code {
|
||||||
|
border-color: rgb(255 255 255 / 15%);
|
||||||
|
background: var(--color-blue-common);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .rename-toggle-card,
|
||||||
|
:root.auto.dark .rename-toggle-card {
|
||||||
|
background: var(--color-background-tertiary);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .section-icon.rename-icon,
|
||||||
|
:root.auto.dark .section-icon.rename-icon {
|
||||||
|
background: linear-gradient(135deg, #52c41a25 0%, #52c41a35 100%);
|
||||||
|
}
|
||||||
|
|||||||
@@ -108,6 +108,15 @@
|
|||||||
"description": "Configure settings for each PicBed individually",
|
"description": "Configure settings for each PicBed individually",
|
||||||
"title": "Per-PicBed Settings"
|
"title": "Per-PicBed Settings"
|
||||||
},
|
},
|
||||||
|
"rename": {
|
||||||
|
"description": "Configure renaming rules for uploaded files",
|
||||||
|
"manualRename": "Manual Rename",
|
||||||
|
"renameCustomFormat": "Custom Rename Format",
|
||||||
|
"renameCustomFormatPlaceholder": "Please enter custom rename format",
|
||||||
|
"renameDescription": "Set renaming rules for uploaded files",
|
||||||
|
"renameTimestamp": "Timestamp Rename",
|
||||||
|
"title": "Rename Settings"
|
||||||
|
},
|
||||||
"renameSettings": "Rename",
|
"renameSettings": "Rename",
|
||||||
"skipProcessSettings": "Skip Process",
|
"skipProcessSettings": "Skip Process",
|
||||||
"subtitle-Global": "Configure settings for all PicBeds",
|
"subtitle-Global": "Configure settings for all PicBeds",
|
||||||
|
|||||||
@@ -108,6 +108,15 @@
|
|||||||
"description": "为每个图床单独配置设置",
|
"description": "为每个图床单独配置设置",
|
||||||
"title": "图床独立设置"
|
"title": "图床独立设置"
|
||||||
},
|
},
|
||||||
|
"rename": {
|
||||||
|
"description": "配置上传文件的重命名规则",
|
||||||
|
"manualRename": "手动重命名",
|
||||||
|
"renameCustomFormat": "自定义重命名格式",
|
||||||
|
"renameCustomFormatPlaceholder": "请输入自定义重命名格式",
|
||||||
|
"renameDescription": "设置上传文件的重命名规则",
|
||||||
|
"renameTimestamp": "时间戳重命名",
|
||||||
|
"title": "重命名设置"
|
||||||
|
},
|
||||||
"renameSettings": "重命名",
|
"renameSettings": "重命名",
|
||||||
"skipProcessSettings": "文件跳过",
|
"skipProcessSettings": "文件跳过",
|
||||||
"subtitle-Global": "为所有图床配置通用设置",
|
"subtitle-Global": "为所有图床配置通用设置",
|
||||||
|
|||||||
@@ -108,6 +108,15 @@
|
|||||||
"description": "為每個圖床單獨配置設置",
|
"description": "為每個圖床單獨配置設置",
|
||||||
"title": "圖床獨立設置"
|
"title": "圖床獨立設置"
|
||||||
},
|
},
|
||||||
|
"rename": {
|
||||||
|
"description": "配置上傳文件的重命名規則",
|
||||||
|
"manualRename": "手動重命名",
|
||||||
|
"renameCustomFormat": "自定義重命名格式",
|
||||||
|
"renameCustomFormatPlaceholder": "請輸入自定義重命名格式",
|
||||||
|
"renameDescription": "設置上傳文件的重命名規則",
|
||||||
|
"renameTimestamp": "時間戳重命名",
|
||||||
|
"title": "重命名設置"
|
||||||
|
},
|
||||||
"renameSettings": "重命名",
|
"renameSettings": "重命名",
|
||||||
"skipProcessSettings": "文件跳過",
|
"skipProcessSettings": "文件跳過",
|
||||||
"subtitle-Global": "為所有圖床配置設置",
|
"subtitle-Global": "為所有圖床配置設置",
|
||||||
|
|||||||
Reference in New Issue
Block a user