🐛 Fix(custom): fix static assets bugs
@@ -10,7 +10,7 @@
|
|||||||
"extraResources": [
|
"extraResources": [
|
||||||
{
|
{
|
||||||
"from": "resources",
|
"from": "resources",
|
||||||
"to": "resources",
|
"to": ".",
|
||||||
"filter": ["**/*"]
|
"filter": ["**/*"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import vue from '@vitejs/plugin-vue'
|
|||||||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
main: {
|
main: {
|
||||||
// Main process configuration
|
|
||||||
plugins: [
|
plugins: [
|
||||||
externalizeDepsPlugin()
|
externalizeDepsPlugin()
|
||||||
],
|
],
|
||||||
@@ -23,7 +22,6 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
preload: {
|
preload: {
|
||||||
// Preload scripts configuration
|
|
||||||
plugins: [externalizeDepsPlugin(),
|
plugins: [externalizeDepsPlugin(),
|
||||||
VueI18nPlugin({
|
VueI18nPlugin({
|
||||||
/* options */
|
/* options */
|
||||||
@@ -41,12 +39,8 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
renderer: {
|
renderer: {
|
||||||
// Renderer process configuration
|
|
||||||
root: resolve('src/renderer'),
|
root: resolve('src/renderer'),
|
||||||
publicDir: resolve('./public'),
|
base: './',
|
||||||
build: {
|
|
||||||
outDir: resolve('dist/renderer')
|
|
||||||
},
|
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': resolve('src/renderer'),
|
'@': resolve('src/renderer'),
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ windowList.set(IWindowList.TRAY_WINDOW, {
|
|||||||
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
||||||
window.loadURL(process.env.ELECTRON_RENDERER_URL)
|
window.loadURL(process.env.ELECTRON_RENDERER_URL)
|
||||||
} else {
|
} else {
|
||||||
window.loadFile(path.join(__dirname, '../render/index.html'))
|
window.loadFile(path.join(__dirname, '../renderer/index.html'))
|
||||||
}
|
}
|
||||||
window.on('blur', () => {
|
window.on('blur', () => {
|
||||||
window.hide()
|
window.hide()
|
||||||
@@ -197,7 +197,7 @@ windowList.set(IWindowList.SETTING_WINDOW, {
|
|||||||
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
||||||
window.loadURL(`${process.env.ELECTRON_RENDERER_URL}#main-page/upload`)
|
window.loadURL(`${process.env.ELECTRON_RENDERER_URL}#main-page/upload`)
|
||||||
} else {
|
} else {
|
||||||
window.loadFile(path.join(__dirname, '../render/index.html'), {
|
window.loadFile(path.join(__dirname, '../renderer/index.html'), {
|
||||||
hash: 'main-page/upload'
|
hash: 'main-page/upload'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ windowList.set(IWindowList.MINI_WINDOW, {
|
|||||||
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
||||||
window.loadURL(`${process.env.ELECTRON_RENDERER_URL}#mini-page`)
|
window.loadURL(`${process.env.ELECTRON_RENDERER_URL}#mini-page`)
|
||||||
} else {
|
} else {
|
||||||
window.loadFile(path.join(__dirname, '../render/index.html'), {
|
window.loadFile(path.join(__dirname, '../renderer/index.html'), {
|
||||||
hash: 'mini-page'
|
hash: 'mini-page'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ windowList.set(IWindowList.RENAME_WINDOW, {
|
|||||||
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
||||||
window.loadURL(`${process.env.ELECTRON_RENDERER_URL}#rename-page`)
|
window.loadURL(`${process.env.ELECTRON_RENDERER_URL}#rename-page`)
|
||||||
} else {
|
} else {
|
||||||
window.loadFile(path.join(__dirname, '../render/index.html'), {
|
window.loadFile(path.join(__dirname, '../renderer/index.html'), {
|
||||||
hash: 'rename-page'
|
hash: 'rename-page'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ windowList.set(IWindowList.TOOLBOX_WINDOW, {
|
|||||||
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
if (!app.isPackaged && process.env.ELECTRON_RENDERER_URL) {
|
||||||
window.loadURL(`${process.env.ELECTRON_RENDERER_URL}#toolbox-page`)
|
window.loadURL(`${process.env.ELECTRON_RENDERER_URL}#toolbox-page`)
|
||||||
} else {
|
} else {
|
||||||
window.loadFile(path.join(__dirname, '../render/index.html'), {
|
window.loadFile(path.join(__dirname, '../renderer/index.html'), {
|
||||||
hash: 'toolbox-page'
|
hash: 'toolbox-page'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,115 +1,115 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="image-container">
|
<div class="image-container">
|
||||||
<div
|
<div
|
||||||
v-if="isLoading"
|
v-if="isLoading"
|
||||||
class="loading-placeholder"
|
class="loading-placeholder"
|
||||||
>
|
>
|
||||||
<div class="loading-spinner" />
|
<div class="loading-spinner" />
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
v-else-if="!hasError"
|
v-else-if="!hasError"
|
||||||
:src="
|
:src="
|
||||||
isShowThumbnail && item.isImage
|
isShowThumbnail && item.isImage
|
||||||
? base64Image
|
? base64Image
|
||||||
: `/assets/icons/${getFileIconPath(item.fileName ?? '')}`
|
: `./assets/icons/${getFileIconPath(item.fileName ?? '')}`
|
||||||
"
|
"
|
||||||
alt=""
|
alt=""
|
||||||
class="image"
|
class="image"
|
||||||
@load="handleImageLoad"
|
@load="handleImageLoad"
|
||||||
@error="handleImageError"
|
@error="handleImageError"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-else
|
v-else
|
||||||
:src="`/assets/icons/${getFileIconPath(item.fileName ?? '')}`"
|
:src="`./assets/icons/${getFileIconPath(item.fileName ?? '')}`"
|
||||||
alt=""
|
alt=""
|
||||||
class="image"
|
class="image"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onBeforeMount, ref } from 'vue'
|
import { onBeforeMount, ref } from 'vue'
|
||||||
|
|
||||||
import { getFileIconPath } from '@/manage/utils/common'
|
import { getFileIconPath } from '@/manage/utils/common'
|
||||||
|
|
||||||
const base64Image = ref('')
|
const base64Image = ref('')
|
||||||
const isLoading = ref(true)
|
const isLoading = ref(true)
|
||||||
const hasError = ref(false)
|
const hasError = ref(false)
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
isShowThumbnail: boolean
|
isShowThumbnail: boolean
|
||||||
item: {
|
item: {
|
||||||
isImage: boolean
|
isImage: boolean
|
||||||
fileName: string
|
fileName: string
|
||||||
}
|
}
|
||||||
localPath: string
|
localPath: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const createBase64Image = async () => {
|
const createBase64Image = async () => {
|
||||||
try {
|
try {
|
||||||
const filePath = window.node.path.normalize(props.localPath)
|
const filePath = window.node.path.normalize(props.localPath)
|
||||||
const base64 = await window.node.fs.readFile(filePath, 'base64')
|
const base64 = await window.node.fs.readFile(filePath, 'base64')
|
||||||
base64Image.value = `data:${window.node.mime.lookup(filePath) || 'image/png'};base64,${base64}`
|
base64Image.value = `data:${window.node.mime.lookup(filePath) || 'image/png'};base64,${base64}`
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
hasError.value = true
|
hasError.value = true
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleImageLoad = () => {
|
const handleImageLoad = () => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
hasError.value = false
|
hasError.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleImageError = () => {
|
const handleImageError = () => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
hasError.value = true
|
hasError.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
await createBase64Image()
|
await createBase64Image()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.image-container {
|
.image-container {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-placeholder {
|
.loading-placeholder {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-spinner {
|
.loading-spinner {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border: 2px solid #e4e7ed;
|
border: 2px solid #e4e7ed;
|
||||||
border-top: 2px solid #409eff;
|
border-top: 2px solid #409eff;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
animation: spin 1s linear infinite;
|
animation: spin 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
0% { transform: rotate(0deg); }
|
0% { transform: rotate(0deg); }
|
||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,123 +1,123 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="image-container">
|
<div class="image-container">
|
||||||
<div
|
<div
|
||||||
v-if="isLoading"
|
v-if="isLoading"
|
||||||
class="loading-placeholder"
|
class="loading-placeholder"
|
||||||
>
|
>
|
||||||
<div class="loading-spinner" />
|
<div class="loading-spinner" />
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
v-else-if="!hasError"
|
v-else-if="!hasError"
|
||||||
:src="imageSource"
|
:src="imageSource"
|
||||||
alt=""
|
alt=""
|
||||||
class="image"
|
class="image"
|
||||||
@load="handleImageLoad"
|
@load="handleImageLoad"
|
||||||
@error="handleImageError"
|
@error="handleImageError"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-else
|
v-else
|
||||||
:src="iconPath"
|
:src="iconPath"
|
||||||
alt=""
|
alt=""
|
||||||
class="image"
|
class="image"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, ref, watch } from 'vue'
|
import { computed, onMounted, ref, watch } from 'vue'
|
||||||
|
|
||||||
import { getFileIconPath } from '@/manage/utils/common'
|
import { getFileIconPath } from '@/manage/utils/common'
|
||||||
import { IRPCActionType } from '@/utils/enum'
|
import { IRPCActionType } from '@/utils/enum'
|
||||||
|
|
||||||
const preSignedUrl = ref('')
|
const preSignedUrl = ref('')
|
||||||
const isLoading = ref(true)
|
const isLoading = ref(true)
|
||||||
const hasError = ref(false)
|
const hasError = ref(false)
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
item: {
|
item: {
|
||||||
key: string
|
key: string
|
||||||
isImage: boolean
|
isImage: boolean
|
||||||
fileName: string | null | undefined
|
fileName: string | null | undefined
|
||||||
}
|
}
|
||||||
alias: string
|
alias: string
|
||||||
url: string
|
url: string
|
||||||
config: any
|
config: any
|
||||||
isShowThumbnail: boolean
|
isShowThumbnail: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const imageSource = computed(() => {
|
const imageSource = computed(() => {
|
||||||
return props.isShowThumbnail && props.item.isImage
|
return props.isShowThumbnail && props.item.isImage
|
||||||
? preSignedUrl.value
|
? preSignedUrl.value
|
||||||
: `/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`
|
: `./assets/icons/${getFileIconPath(props.item.fileName ?? '')}`
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconPath = computed(() => `/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
|
const iconPath = computed(() => `./assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
|
||||||
|
|
||||||
async function getUrl () {
|
async function getUrl () {
|
||||||
try {
|
try {
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
hasError.value = false
|
hasError.value = false
|
||||||
preSignedUrl.value = await window.electron.triggerRPC<any>(IRPCActionType.MANAGE_GET_PRE_SIGNED_URL, props.alias, props.config)
|
preSignedUrl.value = await window.electron.triggerRPC<any>(IRPCActionType.MANAGE_GET_PRE_SIGNED_URL, props.alias, props.config)
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to get pre-signed URL:', error)
|
console.error('Failed to get pre-signed URL:', error)
|
||||||
hasError.value = true
|
hasError.value = true
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleImageLoad = () => {
|
const handleImageLoad = () => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
hasError.value = false
|
hasError.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleImageError = () => {
|
const handleImageError = () => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
hasError.value = true
|
hasError.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => [props.url, props.item], getUrl, { deep: true })
|
watch(() => [props.url, props.item], getUrl, { deep: true })
|
||||||
|
|
||||||
onMounted(getUrl)
|
onMounted(getUrl)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.image-container {
|
.image-container {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-placeholder {
|
.loading-placeholder {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-spinner {
|
.loading-spinner {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border: 2px solid #e4e7ed;
|
border: 2px solid #e4e7ed;
|
||||||
border-top: 2px solid #409eff;
|
border-top: 2px solid #409eff;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
animation: spin 1s linear infinite;
|
animation: spin 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
0% { transform: rotate(0deg); }
|
0% { transform: rotate(0deg); }
|
||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,154 +1,154 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="image-container">
|
<div class="image-container">
|
||||||
<div
|
<div
|
||||||
v-if="isLoading"
|
v-if="isLoading"
|
||||||
class="loading-placeholder"
|
class="loading-placeholder"
|
||||||
>
|
>
|
||||||
<div class="loading-spinner" />
|
<div class="loading-spinner" />
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
v-else-if="!hasError"
|
v-else-if="!hasError"
|
||||||
:src="imageSource"
|
:src="imageSource"
|
||||||
alt=""
|
alt=""
|
||||||
class="image"
|
class="image"
|
||||||
@load="handleImageLoad"
|
@load="handleImageLoad"
|
||||||
@error="handleImageError"
|
@error="handleImageError"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-else
|
v-else
|
||||||
:src="iconPath"
|
:src="iconPath"
|
||||||
alt=""
|
alt=""
|
||||||
class="image"
|
class="image"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, ref, watch } from 'vue'
|
import { computed, onMounted, ref, watch } from 'vue'
|
||||||
|
|
||||||
import { getFileIconPath } from '@/manage/utils/common'
|
import { getFileIconPath } from '@/manage/utils/common'
|
||||||
import { getAuthHeader } from '@/manage/utils/digestAuth'
|
import { getAuthHeader } from '@/manage/utils/digestAuth'
|
||||||
import { formatEndpoint } from '@/utils/common'
|
import { formatEndpoint } from '@/utils/common'
|
||||||
|
|
||||||
const base64Url = ref('')
|
const base64Url = ref('')
|
||||||
const success = ref(false)
|
const success = ref(false)
|
||||||
const isLoading = ref(true)
|
const isLoading = ref(true)
|
||||||
const hasError = ref(false)
|
const hasError = ref(false)
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
item: {
|
item: {
|
||||||
key: string
|
key: string
|
||||||
isImage: boolean
|
isImage: boolean
|
||||||
fileName: string | null | undefined
|
fileName: string | null | undefined
|
||||||
}
|
}
|
||||||
url: string
|
url: string
|
||||||
config: any
|
config: any
|
||||||
isShowThumbnail: boolean
|
isShowThumbnail: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const imageSource = computed(() => {
|
const imageSource = computed(() => {
|
||||||
return props.isShowThumbnail && props.item.isImage && success.value
|
return props.isShowThumbnail && props.item.isImage && success.value
|
||||||
? base64Url.value
|
? base64Url.value
|
||||||
: `/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`
|
: `./assets/icons/${getFileIconPath(props.item.fileName ?? '')}`
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconPath = computed(() => `/assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
|
const iconPath = computed(() => `./assets/icons/${getFileIconPath(props.item.fileName ?? '')}`)
|
||||||
|
|
||||||
async function getWebdavHeader (key: string) {
|
async function getWebdavHeader (key: string) {
|
||||||
let headers = {} as any
|
let headers = {} as any
|
||||||
if (props.config.authType === 'digest') {
|
if (props.config.authType === 'digest') {
|
||||||
const authHeader = await getAuthHeader(
|
const authHeader = await getAuthHeader(
|
||||||
'GET',
|
'GET',
|
||||||
formatEndpoint(props.config.endpoint, props.config.sslEnabled || false),
|
formatEndpoint(props.config.endpoint, props.config.sslEnabled || false),
|
||||||
`/${key.replace(/^\//, '')}`,
|
`/${key.replace(/^\//, '')}`,
|
||||||
props.config.username,
|
props.config.username,
|
||||||
props.config.password
|
props.config.password
|
||||||
)
|
)
|
||||||
headers = {
|
headers = {
|
||||||
Authorization: authHeader
|
Authorization: authHeader
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
headers = {
|
headers = {
|
||||||
Authorization: 'Basic ' + Buffer.from(`${props.config.username}:${props.config.password}`).toString('base64')
|
Authorization: 'Basic ' + Buffer.from(`${props.config.username}:${props.config.password}`).toString('base64')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return headers
|
return headers
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchImage = async () => {
|
const fetchImage = async () => {
|
||||||
try {
|
try {
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
hasError.value = false
|
hasError.value = false
|
||||||
const headers = await getWebdavHeader(props.item.key)
|
const headers = await getWebdavHeader(props.item.key)
|
||||||
const res = await fetch(props.url, { method: 'GET', headers })
|
const res = await fetch(props.url, { method: 'GET', headers })
|
||||||
if (res.status >= 200 && res.status < 300) {
|
if (res.status >= 200 && res.status < 300) {
|
||||||
const blob = await res.blob()
|
const blob = await res.blob()
|
||||||
success.value = true
|
success.value = true
|
||||||
base64Url.value = URL.createObjectURL(blob)
|
base64Url.value = URL.createObjectURL(blob)
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Network response was not ok.')
|
throw new Error('Network response was not ok.')
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
success.value = false
|
success.value = false
|
||||||
hasError.value = true
|
hasError.value = true
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleImageLoad = () => {
|
const handleImageLoad = () => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
hasError.value = false
|
hasError.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleImageError = () => {
|
const handleImageError = () => {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
hasError.value = true
|
hasError.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => [props.url, props.item], fetchImage, { deep: true })
|
watch(() => [props.url, props.item], fetchImage, { deep: true })
|
||||||
|
|
||||||
onMounted(fetchImage)
|
onMounted(fetchImage)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.image-container {
|
.image-container {
|
||||||
height: 100px;
|
height: 100px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-placeholder {
|
.loading-placeholder {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-spinner {
|
.loading-spinner {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border: 2px solid #e4e7ed;
|
border: 2px solid #e4e7ed;
|
||||||
border-top: 2px solid #409eff;
|
border-top: 2px solid #409eff;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
animation: spin 1s linear infinite;
|
animation: spin 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
0% { transform: rotate(0deg); }
|
0% { transform: rotate(0deg); }
|
||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="title-left">
|
<div class="title-left">
|
||||||
<div class="app-icon">
|
<div class="app-icon">
|
||||||
<img
|
<img
|
||||||
src="/roundLogo.png"
|
:src="defaultLogo"
|
||||||
alt="App Icon"
|
alt="App Icon"
|
||||||
width="20"
|
width="20"
|
||||||
height="20"
|
height="20"
|
||||||
@@ -75,13 +75,14 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { MinusIcon, PinIcon, ShrinkIcon, XIcon } from 'lucide-vue-next'
|
import { MinusIcon, PinIcon, ShrinkIcon, XIcon } from 'lucide-vue-next'
|
||||||
import { onBeforeMount, onBeforeUnmount, ref } from 'vue'
|
import { computed, onBeforeMount, onBeforeUnmount, ref } from 'vue'
|
||||||
|
|
||||||
import { IRPCActionType } from '@/utils/enum'
|
import { IRPCActionType } from '@/utils/enum'
|
||||||
|
|
||||||
const isShowprogress = ref(false)
|
const isShowprogress = ref(false)
|
||||||
const progress = ref(0)
|
const progress = ref(0)
|
||||||
const isAlwaysOnTop = ref(false)
|
const isAlwaysOnTop = ref(false)
|
||||||
|
const defaultLogo = computed(() => `${import.meta.env.BASE_URL}roundLogo.png`)
|
||||||
|
|
||||||
function setAlwaysOnTop () {
|
function setAlwaysOnTop () {
|
||||||
isAlwaysOnTop.value = !isAlwaysOnTop.value
|
isAlwaysOnTop.value = !isAlwaysOnTop.value
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ const i18n = createI18n<[MessageSchema], 'en' | 'zh-CN' | 'zh-TW'>({
|
|||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
pinia.use(piniaPluginPersistedstate)
|
pinia.use(piniaPluginPersistedstate)
|
||||||
app.use(VueLazyLoad, {
|
app.use(VueLazyLoad, {
|
||||||
loading: '/loading.jpg',
|
loading: './loading.jpg',
|
||||||
error: '/unknown-file-type.svg',
|
error: './unknown-file-type.svg',
|
||||||
delay: 500
|
delay: 500
|
||||||
})
|
})
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
|
|||||||
@@ -460,7 +460,7 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-else
|
v-else
|
||||||
:src="`/assets/icons/${getFileIconPath(item.fileName ?? '')}`"
|
:src="`./assets/icons/${getFileIconPath(item.fileName ?? '')}`"
|
||||||
class="file-image"
|
class="file-image"
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
@@ -495,7 +495,7 @@
|
|||||||
<!-- Default File Icon -->
|
<!-- Default File Icon -->
|
||||||
<template v-else-if="!item.isDir">
|
<template v-else-if="!item.isDir">
|
||||||
<img
|
<img
|
||||||
:src="`/assets/icons/${getFileIconPath(item.fileName ?? '')}`"
|
:src="`./assets/icons/${getFileIconPath(item.fileName ?? '')}`"
|
||||||
class="file-image"
|
class="file-image"
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
@@ -622,7 +622,7 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-else
|
v-else
|
||||||
:src="`/assets/icons/${getFileIconPath(item.fileName ?? '')}`"
|
:src="`./assets/icons/${getFileIconPath(item.fileName ?? '')}`"
|
||||||
style="width: 32px; height: 32px; object-fit: contain;"
|
style="width: 32px; height: 32px; object-fit: contain;"
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -318,7 +318,7 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="imageErrorStates[item.key || '']
|
:src="imageErrorStates[item.key || '']
|
||||||
? '/errorLoading.png'
|
? './errorLoading.png'
|
||||||
: isAlwaysForceReload ? addCacheBustParam(item.src) : item.src"
|
: isAlwaysForceReload ? addCacheBustParam(item.src) : item.src"
|
||||||
class="gallery-image"
|
class="gallery-image"
|
||||||
:class="{ loading: !imageLoadStates[item.key || ''] }"
|
:class="{ loading: !imageLoadStates[item.key || ''] }"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-if="!dragover && !isShowingProgress"
|
v-if="!dragover && !isShowingProgress"
|
||||||
:src="logoPath ? logoPath : '/squareLogo.png'"
|
:src="logoPath ? logoPath : './squareLogo.png'"
|
||||||
style="width: 100%; height: 100%; border-radius: 50%"
|
style="width: 100%; height: 100%; border-radius: 50%"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
@dragstart.prevent
|
@dragstart.prevent
|
||||||
|
|||||||
@@ -126,7 +126,7 @@
|
|||||||
<img
|
<img
|
||||||
class="plugin-logo"
|
class="plugin-logo"
|
||||||
:src="item.logo"
|
:src="item.logo"
|
||||||
:onerror="defaultLogo"
|
:onerror="setSrc"
|
||||||
alt=""
|
alt=""
|
||||||
>
|
>
|
||||||
<div class="plugin-info">
|
<div class="plugin-info">
|
||||||
@@ -331,9 +331,13 @@ const pluginNameList = ref<string[]>([])
|
|||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const needReload = ref(false)
|
const needReload = ref(false)
|
||||||
const latestVersionMap = reactive<{ [key: string]: string }>({})
|
const latestVersionMap = reactive<{ [key: string]: string }>({})
|
||||||
const defaultLogo = ref('this.src=\'/roundLogo.png\'')
|
|
||||||
const $configForm = ref<InstanceType<typeof ConfigForm> | null>(null)
|
const $configForm = ref<InstanceType<typeof ConfigForm> | null>(null)
|
||||||
|
|
||||||
|
function setSrc (e: Event) {
|
||||||
|
const target = e.target as HTMLImageElement
|
||||||
|
target.src = import.meta.env.BASE_URL + 'roundLogo.png'
|
||||||
|
}
|
||||||
|
|
||||||
const npmSearchText = computed(() => {
|
const npmSearchText = computed(() => {
|
||||||
return searchText.value.match('picgo-plugin-')
|
return searchText.value.match('picgo-plugin-')
|
||||||
? searchText.value
|
? searchText.value
|
||||||
|
|||||||
@@ -146,8 +146,8 @@ import type { IToolboxMap } from '#/types/view'
|
|||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { confirm } = useConfirm()
|
const { confirm } = useConfirm()
|
||||||
const defaultLogo = ref('/roundLogo.png')
|
|
||||||
const activeTypes = ref<string[]>([])
|
const activeTypes = ref<string[]>([])
|
||||||
|
const defaultLogo = computed(() => `${import.meta.env.BASE_URL}roundLogo.png`)
|
||||||
const fixList = reactive<IToolboxMap>({
|
const fixList = reactive<IToolboxMap>({
|
||||||
[IToolboxItemType.IS_CONFIG_FILE_BROKEN]: {
|
[IToolboxItemType.IS_CONFIG_FILE_BROKEN]: {
|
||||||
title: t('pages.toolbox.checkConfigFileBroken'),
|
title: t('pages.toolbox.checkConfigFileBroken'),
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 690 B After Width: | Height: | Size: 690 B |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |