mirror of
https://github.com/Kuingsmile/PicList.git
synced 2025-02-08 13:28:13 -05:00
✨ Feature(custom): support use presigned url for image preview
ISSUES CLOSED: #265
This commit is contained in:
parent
cd48b24a21
commit
4209838925
@ -392,6 +392,7 @@ MANAGE_SETTING_CLEAR_CACHE_TIPS: After clearing, the file list will be reloaded
|
|||||||
MANAGE_SETTING_CLEAR_CACHE_PROMPT: Are you sure you want to clear the file list cache database?
|
MANAGE_SETTING_CLEAR_CACHE_PROMPT: Are you sure you want to clear the file list cache database?
|
||||||
MANAGE_SETTING_CLEAR_CACHE_BUTTON: Clear
|
MANAGE_SETTING_CLEAR_CACHE_BUTTON: Clear
|
||||||
MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE: Display the original image instead of format icon (requires public access permissions)
|
MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE: Display the original image instead of format icon (requires public access permissions)
|
||||||
|
MANAGE_SETTING_ISUSEPRESIGNEDURL_TITLE: Use presigned URL for image display
|
||||||
MANAGE_SETTING_ISSHOWLIST_TITLE: Default display mode for the file list
|
MANAGE_SETTING_ISSHOWLIST_TITLE: Default display mode for the file list
|
||||||
MANAGE_SETTING_ISSHOWLIST_ON: List
|
MANAGE_SETTING_ISSHOWLIST_ON: List
|
||||||
MANAGE_SETTING_ISSHOWLIST_OFF: Card
|
MANAGE_SETTING_ISSHOWLIST_OFF: Card
|
||||||
|
@ -394,6 +394,7 @@ MANAGE_SETTING_CLEAR_CACHE_TIPS: 清空后下次进入新目录时将会重新
|
|||||||
MANAGE_SETTING_CLEAR_CACHE_PROMPT: 确定要清空文件列表缓存数据库吗?
|
MANAGE_SETTING_CLEAR_CACHE_PROMPT: 确定要清空文件列表缓存数据库吗?
|
||||||
MANAGE_SETTING_CLEAR_CACHE_BUTTON: 清空
|
MANAGE_SETTING_CLEAR_CACHE_BUTTON: 清空
|
||||||
MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE: 图片显示为原图而非默认文件格式图标(需要存储桶可公开访问)
|
MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE: 图片显示为原图而非默认文件格式图标(需要存储桶可公开访问)
|
||||||
|
MANAGE_SETTING_ISUSEPRESIGNEDURL_TITLE: 使用预签名URL预览图片
|
||||||
MANAGE_SETTING_ISSHOWLIST_TITLE: 文件列表默认显示方式
|
MANAGE_SETTING_ISSHOWLIST_TITLE: 文件列表默认显示方式
|
||||||
MANAGE_SETTING_ISSHOWLIST_ON: 列表
|
MANAGE_SETTING_ISSHOWLIST_ON: 列表
|
||||||
MANAGE_SETTING_ISSHOWLIST_OFF: 卡片
|
MANAGE_SETTING_ISSHOWLIST_OFF: 卡片
|
||||||
|
@ -392,6 +392,7 @@ MANAGE_SETTING_CLEAR_CACHE_TIPS: 清空後下次進入新目錄時將會重新
|
|||||||
MANAGE_SETTING_CLEAR_CACHE_PROMPT: 確定要清空檔案列表快取資料庫嗎?
|
MANAGE_SETTING_CLEAR_CACHE_PROMPT: 確定要清空檔案列表快取資料庫嗎?
|
||||||
MANAGE_SETTING_CLEAR_CACHE_BUTTON: 清空
|
MANAGE_SETTING_CLEAR_CACHE_BUTTON: 清空
|
||||||
MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE: 顯示圖片的原始圖像而非預設的檔案格式圖示(需要存儲桶公開訪問權限)
|
MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE: 顯示圖片的原始圖像而非預設的檔案格式圖示(需要存儲桶公開訪問權限)
|
||||||
|
MANAGE_SETTING_ISUSEPRESIGNEDURL_TITLE: 使用預簽名URL预览圖片
|
||||||
MANAGE_SETTING_ISSHOWLIST_TITLE: 檔案列表預設顯示方式
|
MANAGE_SETTING_ISSHOWLIST_TITLE: 檔案列表預設顯示方式
|
||||||
MANAGE_SETTING_ISSHOWLIST_ON: 列表
|
MANAGE_SETTING_ISSHOWLIST_ON: 列表
|
||||||
MANAGE_SETTING_ISSHOWLIST_OFF: 卡片
|
MANAGE_SETTING_ISSHOWLIST_OFF: 卡片
|
||||||
|
51
src/renderer/components/ImagePreSign.vue
Normal file
51
src/renderer/components/ImagePreSign.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<el-image :src="imageSource" fit="contain" style="height: 100px; width: 100%; margin: 0 auto">
|
||||||
|
<template #placeholder>
|
||||||
|
<el-icon>
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
<template #error>
|
||||||
|
<el-image :src="iconPath" fit="contain" style="height: 100px; width: 100%; margin: 0 auto" />
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted, watch, computed } from 'vue'
|
||||||
|
import { Loading } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
import { getFileIconPath } from '@/manage/utils/common'
|
||||||
|
import { IRPCActionType } from '#/types/enum'
|
||||||
|
import { triggerRPC } from '@/utils/common'
|
||||||
|
|
||||||
|
const preSignedUrl = ref('')
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
item: {
|
||||||
|
key: string
|
||||||
|
isImage: boolean
|
||||||
|
fileName: string | null | undefined
|
||||||
|
}
|
||||||
|
alias: string
|
||||||
|
url: string
|
||||||
|
config: any
|
||||||
|
isShowThumbnail: boolean
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const imageSource = computed(() => {
|
||||||
|
return props.isShowThumbnail && props.item.isImage
|
||||||
|
? preSignedUrl.value
|
||||||
|
: require(`../manage/pages/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
const iconPath = computed(() => require(`../manage/pages/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`))
|
||||||
|
|
||||||
|
async function getUrl() {
|
||||||
|
preSignedUrl.value = await triggerRPC<any>(IRPCActionType.MANAGE_GET_PRE_SIGNED_URL, props.alias, props.config)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => [props.url, props.item], getUrl, { deep: true })
|
||||||
|
|
||||||
|
onMounted(getUrl)
|
||||||
|
</script>
|
65
src/renderer/components/ImagePreSignTsx.tsx
Normal file
65
src/renderer/components/ImagePreSignTsx.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { ElImage, ElIcon } from 'element-plus'
|
||||||
|
import { defineComponent, ref, onMounted, watch, computed } from 'vue'
|
||||||
|
import { Loading } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
import { getFileIconPath } from '@/manage/utils/common'
|
||||||
|
import { IRPCActionType } from '#/types/enum'
|
||||||
|
import { triggerRPC } from '@/utils/common'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
isShowThumbnail: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
alias: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setup(props) {
|
||||||
|
const preSignedUrl = ref('')
|
||||||
|
|
||||||
|
const imageSource = computed(() => {
|
||||||
|
return props.isShowThumbnail && props.item.isImage
|
||||||
|
? preSignedUrl.value
|
||||||
|
: require(`../manage/pages/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
|
||||||
|
})
|
||||||
|
const iconPath = computed(() =>
|
||||||
|
require(`../manage/pages/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
|
||||||
|
)
|
||||||
|
|
||||||
|
async function getUrl() {
|
||||||
|
preSignedUrl.value = await triggerRPC<any>(IRPCActionType.MANAGE_GET_PRE_SIGNED_URL, props.alias, props.config)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => [props.url, props.item], getUrl, { deep: true })
|
||||||
|
onMounted(getUrl)
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<ElImage src={imageSource.value} fit='contain' style='height: 100px;width: 100%;margin: 0 auto;'>
|
||||||
|
{{
|
||||||
|
placeholder: () => (
|
||||||
|
<ElIcon>
|
||||||
|
<Loading />
|
||||||
|
</ElIcon>
|
||||||
|
),
|
||||||
|
error: () => <ElImage src={iconPath.value} fit='contain' style='height: 100px;width: 100%;margin: 0 auto;' />
|
||||||
|
}}
|
||||||
|
</ElImage>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
@ -5,7 +5,7 @@
|
|||||||
<span v-for="(segment, index) in segments" :key="index" :style="segment.style">
|
<span v-for="(segment, index) in segments" :key="index" :style="segment.style">
|
||||||
{{ segment.text }}
|
{{ segment.text }}
|
||||||
</span>
|
</span>
|
||||||
<el-tooltip :content="tooltip" effect="dark" placement="right" :persistent="false" teleported>
|
<el-tooltip v-if="tooltip" :content="tooltip" effect="dark" placement="right" :persistent="false" teleported>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<InfoFilled />
|
<InfoFilled />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
|
@ -391,12 +391,7 @@ https://www.baidu.com/img/bd_logo1.png"
|
|||||||
shadow="hover"
|
shadow="hover"
|
||||||
>
|
>
|
||||||
<el-image
|
<el-image
|
||||||
v-if="
|
v-if="!item.isDir && !['webdavplist', 'sftp', 'local', 's3plist'].includes(currentPicBedName)"
|
||||||
!item.isDir &&
|
|
||||||
currentPicBedName !== 'webdavplist' &&
|
|
||||||
currentPicBedName !== 'sftp' &&
|
|
||||||
currentPicBedName !== 'local'
|
|
||||||
"
|
|
||||||
:src="
|
:src="
|
||||||
isShowThumbnail && item.isImage
|
isShowThumbnail && item.isImage
|
||||||
? item.url
|
? item.url
|
||||||
@ -419,6 +414,39 @@ https://www.baidu.com/img/bd_logo1.png"
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
|
<el-image
|
||||||
|
v-else-if="!item.isDir && currentPicBedName === 's3plist' && !isUsePreSignedUrl"
|
||||||
|
:src="
|
||||||
|
isShowThumbnail && item.isImage
|
||||||
|
? item.url
|
||||||
|
: require(`./assets/icons/${getFileIconPath(item.fileName ?? '')}`)
|
||||||
|
"
|
||||||
|
fit="contain"
|
||||||
|
style="height: 100px; width: 100%; margin: 0 auto"
|
||||||
|
@click="handleClickFile(item)"
|
||||||
|
>
|
||||||
|
<template #placeholder>
|
||||||
|
<el-icon>
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
<template #error>
|
||||||
|
<el-image
|
||||||
|
:src="require(`./assets/icons/${getFileIconPath(item.fileName ?? '')}`)"
|
||||||
|
fit="contain"
|
||||||
|
style="height: 100px; width: 100%; margin: 0 auto"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
<ImagePreSign
|
||||||
|
v-else-if="!item.isDir && currentPicBedName === 's3plist' && isUsePreSignedUrl"
|
||||||
|
:is-show-thumbnail="isShowThumbnail"
|
||||||
|
:item="item"
|
||||||
|
:alias="configMap.alias"
|
||||||
|
:url="item.url"
|
||||||
|
:config="handleGetS3Config(item)"
|
||||||
|
@click="handleClickFile(item)"
|
||||||
|
/>
|
||||||
<ImageWebdav
|
<ImageWebdav
|
||||||
v-else-if="!item.isDir && currentPicBedName === 'webdavplist' && item.isImage"
|
v-else-if="!item.isDir && currentPicBedName === 'webdavplist' && item.isImage"
|
||||||
:is-show-thumbnail="isShowThumbnail"
|
:is-show-thumbnail="isShowThumbnail"
|
||||||
@ -1222,8 +1250,10 @@ import { textFileExt } from '@/manage/utils/textfile'
|
|||||||
import { videoExt } from '@/manage/utils/videofile'
|
import { videoExt } from '@/manage/utils/videofile'
|
||||||
|
|
||||||
import ImageWebdav from '@/components/ImageWebdav.vue'
|
import ImageWebdav from '@/components/ImageWebdav.vue'
|
||||||
|
import ImagePreSign from '@/components/ImagePreSign.vue'
|
||||||
import ImageLocal from '@/components/ImageLocal.vue'
|
import ImageLocal from '@/components/ImageLocal.vue'
|
||||||
import ImageWebdavTsx from '@/components/ImageWebdavTsx'
|
import ImageWebdavTsx from '@/components/ImageWebdavTsx'
|
||||||
|
import ImagePreSignTsx from '@/components/ImagePreSignTsx'
|
||||||
|
|
||||||
import { T as $T } from '@/i18n'
|
import { T as $T } from '@/i18n'
|
||||||
|
|
||||||
@ -1231,7 +1261,7 @@ import { getExtension, trimPath } from '#/utils/common'
|
|||||||
import { cancelDownloadLoadingFileList, refreshDownloadFileTransferList } from '#/utils/static'
|
import { cancelDownloadLoadingFileList, refreshDownloadFileTransferList } from '#/utils/static'
|
||||||
import { IUploadTask, IDownloadTask } from '#/types/manage'
|
import { IUploadTask, IDownloadTask } from '#/types/manage'
|
||||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||||
import { IRPCActionType } from 'root/src/universal/types/enum'
|
import { IRPCActionType } from '#/types/enum'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
configMap:{
|
configMap:{
|
||||||
@ -1378,6 +1408,7 @@ const calculateAllFileSize = computed(
|
|||||||
'0'
|
'0'
|
||||||
)
|
)
|
||||||
const isShowThumbnail = computed(() => manageStore.config.settings.isShowThumbnail ?? false)
|
const isShowThumbnail = computed(() => manageStore.config.settings.isShowThumbnail ?? 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)
|
||||||
|
|
||||||
@ -2901,6 +2932,18 @@ function singleRename() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleGetS3Config(item: any) {
|
||||||
|
return {
|
||||||
|
bucketName: configMap.bucketName,
|
||||||
|
region: configMap.bucketConfig.Location,
|
||||||
|
key: item.key,
|
||||||
|
customUrl: currentCustomDomain.value,
|
||||||
|
expires: manageStore.config.settings.PreSignedExpire,
|
||||||
|
githubPrivate: configMap.bucketConfig.private,
|
||||||
|
rawUrl: item.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function getPreSignedUrl(item: any) {
|
async function getPreSignedUrl(item: any) {
|
||||||
const param = {
|
const param = {
|
||||||
// tcyun
|
// tcyun
|
||||||
@ -3180,6 +3223,15 @@ const columns: Column<any>[] = [
|
|||||||
reference: () =>
|
reference: () =>
|
||||||
!item.isDir ? (
|
!item.isDir ? (
|
||||||
currentPicBedName.value !== 'webdavplist' ? (
|
currentPicBedName.value !== 'webdavplist' ? (
|
||||||
|
currentPicBedName.value === 's3plist' && item.isImage && isUsePreSignedUrl.value ? (
|
||||||
|
<ImagePreSignTsx
|
||||||
|
isShowThumbnail={isShowThumbnail.value}
|
||||||
|
item={item}
|
||||||
|
config={handleGetS3Config(item)}
|
||||||
|
url={item.url}
|
||||||
|
alias={configMap.alias}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<ElImage
|
<ElImage
|
||||||
src={
|
src={
|
||||||
isShowThumbnail.value
|
isShowThumbnail.value
|
||||||
@ -3206,6 +3258,7 @@ const columns: Column<any>[] = [
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</ElImage>
|
</ElImage>
|
||||||
|
)
|
||||||
) : item.isImage ? (
|
) : item.isImage ? (
|
||||||
<ImageWebdavTsx
|
<ImageWebdavTsx
|
||||||
isShowThumbnail={isShowThumbnail.value}
|
isShowThumbnail={isShowThumbnail.value}
|
||||||
@ -3235,6 +3288,14 @@ const columns: Column<any>[] = [
|
|||||||
config={handleGetWebdavConfig()}
|
config={handleGetWebdavConfig()}
|
||||||
url={item.url}
|
url={item.url}
|
||||||
/>
|
/>
|
||||||
|
) : currentPicBedName.value === 's3plist' && item.isImage && isUsePreSignedUrl.value ? (
|
||||||
|
<ImagePreSignTsx
|
||||||
|
isShowThumbnail={isShowThumbnail.value}
|
||||||
|
item={item}
|
||||||
|
config={handleGetS3Config(item)}
|
||||||
|
url={item.url}
|
||||||
|
alias={configMap.alias}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ElImage
|
<ElImage
|
||||||
src={item.isImage ? item.url : require(`./assets/icons/${getFileIconPath(item.fileName ?? '')}`)}
|
src={item.isImage ? item.url : require(`./assets/icons/${getFileIconPath(item.fileName ?? '')}`)}
|
||||||
|
@ -214,6 +214,7 @@ const form = ref<IStringKeyMap>({
|
|||||||
isAutoRefresh: false,
|
isAutoRefresh: false,
|
||||||
isShowThumbnail: false,
|
isShowThumbnail: false,
|
||||||
isShowList: false,
|
isShowList: false,
|
||||||
|
isUsePreSignedUrl: false,
|
||||||
isIgnoreCase: false,
|
isIgnoreCase: false,
|
||||||
isForceCustomUrlHttps: false,
|
isForceCustomUrlHttps: false,
|
||||||
isEncodeUrl: false,
|
isEncodeUrl: false,
|
||||||
@ -246,6 +247,7 @@ const switchFieldsList = [
|
|||||||
'isAutoRefresh',
|
'isAutoRefresh',
|
||||||
'isShowThumbnail',
|
'isShowThumbnail',
|
||||||
'isShowList',
|
'isShowList',
|
||||||
|
'isUsePreSignedUrl',
|
||||||
'isForceCustomUrlHttps',
|
'isForceCustomUrlHttps',
|
||||||
'isEncodeUrl',
|
'isEncodeUrl',
|
||||||
'isUploadKeepDirStructure',
|
'isUploadKeepDirStructure',
|
||||||
@ -254,7 +256,7 @@ const switchFieldsList = [
|
|||||||
'randomStringRename',
|
'randomStringRename',
|
||||||
'customRename'
|
'customRename'
|
||||||
]
|
]
|
||||||
const switchFieldsNoTipsList = ['isShowThumbnail', 'isShowList']
|
const switchFieldsNoTipsList = ['isShowThumbnail', 'isShowList', 'isUsePreSignedUrl']
|
||||||
const switchFieldsHasActiveTextList = ['isShowList']
|
const switchFieldsHasActiveTextList = ['isShowList']
|
||||||
|
|
||||||
const switchFieldsConfigList = switchFieldsList.map(item => ({
|
const switchFieldsConfigList = switchFieldsList.map(item => ({
|
||||||
|
1
src/universal/types/i18n.d.ts
vendored
1
src/universal/types/i18n.d.ts
vendored
@ -368,6 +368,7 @@ interface ILocales {
|
|||||||
MANAGE_SETTING_CLEAR_CACHE_PROMPT: string
|
MANAGE_SETTING_CLEAR_CACHE_PROMPT: string
|
||||||
MANAGE_SETTING_CLEAR_CACHE_BUTTON: string
|
MANAGE_SETTING_CLEAR_CACHE_BUTTON: string
|
||||||
MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE: string
|
MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE: string
|
||||||
|
MANAGE_SETTING_ISUSEPRESIGNEDURL_TITLE: string
|
||||||
MANAGE_SETTING_ISSHOWLIST_TITLE: string
|
MANAGE_SETTING_ISSHOWLIST_TITLE: string
|
||||||
MANAGE_SETTING_ISSHOWLIST_ON: string
|
MANAGE_SETTING_ISSHOWLIST_ON: string
|
||||||
MANAGE_SETTING_ISSHOWLIST_OFF: string
|
MANAGE_SETTING_ISSHOWLIST_OFF: string
|
||||||
|
Loading…
Reference in New Issue
Block a user