mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-08-29 12:06:39 +08:00
✨ Feature(custom): add thumbnail suffix functionality and related settings
ISSUES CLOSED: #539
This commit is contained in:
@@ -654,6 +654,9 @@
|
|||||||
},
|
},
|
||||||
"selectDownloadFolderTips": "Select download directory",
|
"selectDownloadFolderTips": "Select download directory",
|
||||||
"selectDownloadFolderTitle": "Choose download folder",
|
"selectDownloadFolderTitle": "Choose download folder",
|
||||||
|
"thumbnailSuffixPlaceholder": "Example: ?imageMogr2/thumbnail/200x200",
|
||||||
|
"thumbnailSuffixTips": "Only affects image previews in the cloud management list. Copy, download, and delete still use the original URL",
|
||||||
|
"thumbnailSuffixTitle": "Image preview thumbnail suffix",
|
||||||
"timestampRenameTips": "When enabled, uploaded files will be renamed to a timestamp",
|
"timestampRenameTips": "When enabled, uploaded files will be renamed to a timestamp",
|
||||||
"timestampRenameTitle": "Timestamp rename on upload (highest priority)",
|
"timestampRenameTitle": "Timestamp rename on upload (highest priority)",
|
||||||
"title": "Manage General Settings"
|
"title": "Manage General Settings"
|
||||||
|
|||||||
@@ -654,6 +654,9 @@
|
|||||||
},
|
},
|
||||||
"selectDownloadFolderTips": "选择下载目录",
|
"selectDownloadFolderTips": "选择下载目录",
|
||||||
"selectDownloadFolderTitle": "选择下载文件夹",
|
"selectDownloadFolderTitle": "选择下载文件夹",
|
||||||
|
"thumbnailSuffixPlaceholder": "例如:?imageMogr2/thumbnail/200x200",
|
||||||
|
"thumbnailSuffixTips": "仅影响云管理列表中的图片预览,不会改变复制链接、下载或删除使用的原始地址",
|
||||||
|
"thumbnailSuffixTitle": "图片预览缩略图后缀",
|
||||||
"timestampRenameTips": "开启后,上传的文件将自动重命名为时间戳",
|
"timestampRenameTips": "开启后,上传的文件将自动重命名为时间戳",
|
||||||
"timestampRenameTitle": "上传文件时间戳重命名(最高优先级)",
|
"timestampRenameTitle": "上传文件时间戳重命名(最高优先级)",
|
||||||
"title": "管理通用设置"
|
"title": "管理通用设置"
|
||||||
|
|||||||
@@ -654,6 +654,9 @@
|
|||||||
},
|
},
|
||||||
"selectDownloadFolderTips": "選擇下載目錄",
|
"selectDownloadFolderTips": "選擇下載目錄",
|
||||||
"selectDownloadFolderTitle": "選擇下載資料夾",
|
"selectDownloadFolderTitle": "選擇下載資料夾",
|
||||||
|
"thumbnailSuffixPlaceholder": "例如:?imageMogr2/thumbnail/200x200",
|
||||||
|
"thumbnailSuffixTips": "僅影響雲端管理列表中的圖片預覽,不會變更複製連結、下載或刪除使用的原始地址",
|
||||||
|
"thumbnailSuffixTitle": "圖片預覽縮圖後綴",
|
||||||
"timestampRenameTips": "啟用後,上傳的檔案將自動更名為時間戳",
|
"timestampRenameTips": "啟用後,上傳的檔案將自動更名為時間戳",
|
||||||
"timestampRenameTitle": "上傳檔案時間戳重新命名(最高優先級)",
|
"timestampRenameTitle": "上傳檔案時間戳重新命名(最高優先級)",
|
||||||
"title": "管理通用設置"
|
"title": "管理通用設置"
|
||||||
|
|||||||
@@ -327,7 +327,7 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-if="isShowThumbnail && item.isImage"
|
v-if="isShowThumbnail && item.isImage"
|
||||||
:src="item.url"
|
:src="getThumbnailUrl(item.url)"
|
||||||
class="h-full w-full object-contain transition-all duration-fast ease-apple"
|
class="h-full w-full object-contain transition-all duration-fast ease-apple"
|
||||||
@error="() => {}"
|
@error="() => {}"
|
||||||
/>
|
/>
|
||||||
@@ -1189,6 +1189,7 @@ import {
|
|||||||
} from '@/manage/utils/common'
|
} from '@/manage/utils/common'
|
||||||
import { getConfig, saveConfig } from '@/manage/utils/dataSender'
|
import { getConfig, saveConfig } from '@/manage/utils/dataSender'
|
||||||
import { textFileExt } from '@/manage/utils/textfile'
|
import { textFileExt } from '@/manage/utils/textfile'
|
||||||
|
import { appendThumbnailSuffix } from '@/manage/utils/thumbnailUrl'
|
||||||
import { videoExt } from '@/manage/utils/videofile'
|
import { videoExt } from '@/manage/utils/videofile'
|
||||||
import { trimPath } from '@/utils/common'
|
import { trimPath } from '@/utils/common'
|
||||||
import { useDragEventListeners } from '@/utils/drag'
|
import { useDragEventListeners } from '@/utils/drag'
|
||||||
@@ -1403,6 +1404,7 @@ const calculateAllFileSize = computed(
|
|||||||
'0',
|
'0',
|
||||||
)
|
)
|
||||||
const isShowThumbnail = computed(() => manageStore.config.settings.isShowThumbnail ?? false)
|
const isShowThumbnail = computed(() => manageStore.config.settings.isShowThumbnail ?? false)
|
||||||
|
const thumbnailSuffix = computed(() => manageStore.config.settings.thumbnailSuffix ?? '')
|
||||||
const isUsePreSignedUrl = computed(() => manageStore.config.settings.isUsePreSignedUrl ?? false)
|
const isUsePreSignedUrl = computed(() => manageStore.config.settings.isUsePreSignedUrl ?? false)
|
||||||
const isAutoRefresh = computed(() => manageStore.config.settings.isAutoRefresh ?? false)
|
const isAutoRefresh = computed(() => manageStore.config.settings.isAutoRefresh ?? false)
|
||||||
const isIgnoreCase = computed(() => manageStore.config.settings.isIgnoreCase ?? false)
|
const isIgnoreCase = computed(() => manageStore.config.settings.isIgnoreCase ?? false)
|
||||||
@@ -1468,6 +1470,10 @@ watch(
|
|||||||
|
|
||||||
const getExtension = (fileName: string) => window.node.path.extname(fileName).slice(1)
|
const getExtension = (fileName: string) => window.node.path.extname(fileName).slice(1)
|
||||||
|
|
||||||
|
function getThumbnailUrl(url: string) {
|
||||||
|
return appendThumbnailSuffix(url, thumbnailSuffix.value)
|
||||||
|
}
|
||||||
|
|
||||||
function getList() {
|
function getList() {
|
||||||
if (!searchText.value) {
|
if (!searchText.value) {
|
||||||
return currentPageFilesInfo
|
return currentPageFilesInfo
|
||||||
|
|||||||
@@ -56,20 +56,30 @@
|
|||||||
:placeholder="t('pages.manage.setting.copyFormat.customTips')"
|
:placeholder="t('pages.manage.setting.copyFormat.customTips')"
|
||||||
/>
|
/>
|
||||||
</SettingCard>
|
</SettingCard>
|
||||||
<SettingCard v-for="item in switchFieldsConfigList" :key="item.configName" class="mb-4" p1>
|
<template v-for="item in switchFieldsConfigList" :key="item.configName">
|
||||||
<CustomSwitch v-model="form[item.configName]" small no-border :tips="item.tooltip">
|
<SettingCard class="mb-4 flex flex-col justify-center" p1>
|
||||||
<template #custom-title>
|
<CustomSwitch v-model="form[item.configName]" small no-border :tips="item.tooltip">
|
||||||
<span v-for="(segment, index) in item.segments" :key="index" :class="segment.class">
|
<template #custom-title>
|
||||||
{{ segment.text }}
|
<span v-for="(segment, index) in item.segments" :key="index" :class="segment.class">
|
||||||
</span>
|
{{ segment.text }}
|
||||||
</template>
|
</span>
|
||||||
<template #switch-text>
|
</template>
|
||||||
<span class="text-sm text-secondary">{{
|
<template #switch-text>
|
||||||
form[item.configName] ? item.activeText : item.inactiveText
|
<span class="text-sm text-secondary">{{
|
||||||
}}</span>
|
form[item.configName] ? item.activeText : item.inactiveText
|
||||||
</template>
|
}}</span>
|
||||||
</CustomSwitch>
|
</template>
|
||||||
</SettingCard>
|
</CustomSwitch>
|
||||||
|
</SettingCard>
|
||||||
|
<SettingCard v-if="item.configName === 'isShowThumbnail' && form.isShowThumbnail" class="mb-4">
|
||||||
|
<CustomInput
|
||||||
|
v-model.trim="form.thumbnailSuffix"
|
||||||
|
:title="t('pages.manage.setting.thumbnailSuffixTitle')"
|
||||||
|
:placeholder="t('pages.manage.setting.thumbnailSuffixPlaceholder')"
|
||||||
|
:tips="t('pages.manage.setting.thumbnailSuffixTips')"
|
||||||
|
/>
|
||||||
|
</SettingCard>
|
||||||
|
</template>
|
||||||
</SettingSection>
|
</SettingSection>
|
||||||
|
|
||||||
<SettingSection
|
<SettingSection
|
||||||
@@ -171,6 +181,7 @@ const form = ref<IStringKeyMap>({
|
|||||||
customRename: false,
|
customRename: false,
|
||||||
isAutoRefresh: false,
|
isAutoRefresh: false,
|
||||||
isShowThumbnail: false,
|
isShowThumbnail: false,
|
||||||
|
thumbnailSuffix: '',
|
||||||
isUsePreSignedUrl: false,
|
isUsePreSignedUrl: false,
|
||||||
isIgnoreCase: false,
|
isIgnoreCase: false,
|
||||||
isForceCustomUrlHttps: false,
|
isForceCustomUrlHttps: false,
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
export function appendThumbnailSuffix(url: string, suffix?: string): string {
|
||||||
|
const normalizedSuffix = suffix?.trim() ?? ''
|
||||||
|
if (!url || !normalizedSuffix) return url
|
||||||
|
|
||||||
|
if (normalizedSuffix.startsWith('?')) {
|
||||||
|
return `${url}${url.includes('?') ? '&' : '?'}${normalizedSuffix.slice(1)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedSuffix.startsWith('&')) {
|
||||||
|
return `${url}${url.includes('?') ? '&' : '?'}${normalizedSuffix.slice(1)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${url}${normalizedSuffix}`
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
|
||||||
|
import { appendThumbnailSuffix } from '../src/renderer/manage/utils/thumbnailUrl'
|
||||||
|
|
||||||
|
describe('appendThumbnailSuffix', () => {
|
||||||
|
it('keeps the original URL when the suffix is empty', () => {
|
||||||
|
const url = 'https://example.com/image.png'
|
||||||
|
|
||||||
|
expect(appendThumbnailSuffix(url, '')).toBe(url)
|
||||||
|
expect(appendThumbnailSuffix(url)).toBe(url)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appends query-style suffixes to URLs without query strings', () => {
|
||||||
|
expect(appendThumbnailSuffix('https://example.com/image.png', '?imageMogr2/thumbnail/200x200')).toBe(
|
||||||
|
'https://example.com/image.png?imageMogr2/thumbnail/200x200',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('converts query-style suffixes to additional parameters when the URL already has a query string', () => {
|
||||||
|
expect(appendThumbnailSuffix('https://example.com/image.png?version=1', '?imageMogr2/thumbnail/200x200')).toBe(
|
||||||
|
'https://example.com/image.png?version=1&imageMogr2/thumbnail/200x200',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('normalizes ampersand-prefixed suffixes when the URL has no query string', () => {
|
||||||
|
expect(appendThumbnailSuffix('https://example.com/image.png', '&x-oss-process=image/resize,w_200')).toBe(
|
||||||
|
'https://example.com/image.png?x-oss-process=image/resize,w_200',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appends path-style suffixes unchanged', () => {
|
||||||
|
expect(appendThumbnailSuffix('https://example.com/image.png', '/thumbnail/200x200')).toBe(
|
||||||
|
'https://example.com/image.png/thumbnail/200x200',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user