mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-05-31 13:59:45 +08:00
🚧 WIP(custom): v3.0.0 migrate to vite and esm
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
import { getConfig } from '@/utils/dataSender'
|
||||
|
||||
import { II18nLanguage } from '#/types/enum'
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
<template>
|
||||
<div id="gallery-view" :style="handleBarActive ? 'height: 85%;' : 'height: 95%;'">
|
||||
<div
|
||||
id="gallery-view"
|
||||
:style="handleBarActive ? 'height: 85%;' : 'height: 95%;'"
|
||||
>
|
||||
<div class="view-title">
|
||||
{{ $T('GALLERY') }} - {{ filterList.length }}
|
||||
<el-icon style="margin-left: 4px" class="cursor-pointer" @click="toggleHandleBar">
|
||||
<el-icon
|
||||
style="margin-left: 4px"
|
||||
class="cursor-pointer"
|
||||
@click="toggleHandleBar"
|
||||
>
|
||||
<CaretBottom v-show="!handleBarActive" />
|
||||
<CaretTop v-show="handleBarActive" />
|
||||
</el-icon>
|
||||
@@ -14,7 +21,11 @@
|
||||
:inactive-text="$T('SETTINGS_CLOSE')"
|
||||
@change="handleDeleteCloudFile"
|
||||
/>
|
||||
<el-button type="primary" :link="true" @click="refreshPage">
|
||||
<el-button
|
||||
type="primary"
|
||||
:link="true"
|
||||
@click="refreshPage"
|
||||
>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
@@ -23,7 +34,10 @@
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<el-icon size="25" style="cursor: pointer; margin-left: 10px">
|
||||
<el-icon
|
||||
size="25"
|
||||
style="cursor: pointer; margin-left: 10px"
|
||||
>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
@@ -32,8 +46,14 @@
|
||||
</div>
|
||||
<transition name="el-zoom-in-top">
|
||||
<el-row v-show="handleBarActive">
|
||||
<el-col :span="22" :offset="1">
|
||||
<el-row class="handle-bar" :gutter="16">
|
||||
<el-col
|
||||
:span="22"
|
||||
:offset="1"
|
||||
>
|
||||
<el-row
|
||||
class="handle-bar"
|
||||
:gutter="16"
|
||||
>
|
||||
<el-col :span="5">
|
||||
<el-select
|
||||
v-model="choosedPicBed"
|
||||
@@ -45,7 +65,12 @@
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<el-option v-for="item in picBedGlobal" :key="item.type" :label="item.name" :value="item.type" />
|
||||
<el-option
|
||||
v-for="item in picBedGlobal"
|
||||
:key="item.type"
|
||||
:label="item.name"
|
||||
:value="item.type"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
@@ -61,7 +86,11 @@
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-divider direction="vertical" style="height: 100%" border-style="hidden" />
|
||||
<el-divider
|
||||
direction="vertical"
|
||||
style="height: 100%"
|
||||
border-style="hidden"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-select
|
||||
@@ -73,7 +102,12 @@
|
||||
teleported
|
||||
@change="handlePasteStyleChange"
|
||||
>
|
||||
<el-option v-for="(value, key) in pasteStyleMap" :key="key" :label="key" :value="value" />
|
||||
<el-option
|
||||
v-for="(value, key) in pasteStyleMap"
|
||||
:key="key"
|
||||
:label="key"
|
||||
:value="value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -86,12 +120,21 @@
|
||||
teleported
|
||||
@change="handleUseShortUrlChange"
|
||||
>
|
||||
<el-option v-for="(value, key) in shortURLMap" :key="key" :label="key" :value="value" />
|
||||
<el-option
|
||||
v-for="(value, key) in shortURLMap"
|
||||
:key="key"
|
||||
:label="key"
|
||||
:value="value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-dropdown teleported>
|
||||
<el-button size="small" type="primary" :icon="Sort">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
:icon="Sort"
|
||||
>
|
||||
{{ $T('MANAGE_BUCKET_SORT_TITLE') }}
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
@@ -111,30 +154,57 @@
|
||||
</el-dropdown>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="handle-bar" :gutter="16">
|
||||
<el-row
|
||||
class="handle-bar"
|
||||
:gutter="16"
|
||||
>
|
||||
<el-col :span="5">
|
||||
<el-input v-model="searchText" :placeholder="$T('GALLERY_SEARCH_FILENAME')" size="small">
|
||||
<el-input
|
||||
v-model="searchText"
|
||||
:placeholder="$T('GALLERY_SEARCH_FILENAME')"
|
||||
size="small"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon class="el-input__icon" style="cursor: pointer" @click="cleanSearch">
|
||||
<el-icon
|
||||
class="el-input__icon"
|
||||
style="cursor: pointer"
|
||||
@click="cleanSearch"
|
||||
>
|
||||
<close />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-input v-model="searchTextURL" :placeholder="$T('GALLERY_SEARCH_URL')" size="small">
|
||||
<el-input
|
||||
v-model="searchTextURL"
|
||||
:placeholder="$T('GALLERY_SEARCH_URL')"
|
||||
size="small"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon class="el-input__icon" style="cursor: pointer" @click="cleanSearchUrl">
|
||||
<el-icon
|
||||
class="el-input__icon"
|
||||
style="cursor: pointer"
|
||||
@click="cleanSearchUrl"
|
||||
>
|
||||
<close />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-divider direction="vertical" style="height: 100%" border-style="hidden" />
|
||||
<el-divider
|
||||
direction="vertical"
|
||||
style="height: 100%"
|
||||
border-style="hidden"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<div class="item-base copy round" :class="{ active: isMultiple(choosedList) }" @click="multiCopy">
|
||||
<div
|
||||
class="item-base copy round"
|
||||
:class="{ active: isMultiple(choosedList) }"
|
||||
@click="multiCopy"
|
||||
>
|
||||
{{ $T('COPY') }}
|
||||
</div>
|
||||
</el-col>
|
||||
@@ -148,12 +218,20 @@
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<div class="item-base delete round" :class="{ active: isMultiple(choosedList) }" @click="multiRemove">
|
||||
<div
|
||||
class="item-base delete round"
|
||||
:class="{ active: isMultiple(choosedList) }"
|
||||
@click="multiRemove"
|
||||
>
|
||||
{{ $T('DELETE') }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<div class="item-base all-pick round" :class="{ active: filterList.length > 0 }" @click="toggleSelectAll">
|
||||
<div
|
||||
class="item-base all-pick round"
|
||||
:class="{ active: filterList.length > 0 }"
|
||||
@click="toggleSelectAll"
|
||||
>
|
||||
{{ isAllSelected ? $T('CANCEL') : $T('SELECT_ALL') }}
|
||||
</div>
|
||||
</el-col>
|
||||
@@ -161,8 +239,14 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</transition>
|
||||
<el-row class="gallery-list" :class="{ small: handleBarActive }">
|
||||
<el-col :span="22" :offset="1">
|
||||
<el-row
|
||||
class="gallery-list"
|
||||
:class="{ small: handleBarActive }"
|
||||
>
|
||||
<el-col
|
||||
:span="22"
|
||||
:offset="1"
|
||||
>
|
||||
<el-row :gutter="16">
|
||||
<photo-slider
|
||||
:items="filterListWithCacheBust"
|
||||
@@ -183,26 +267,45 @@
|
||||
:xl="2"
|
||||
class="gallery-list__img"
|
||||
>
|
||||
<div class="gallery-list__item" @click="zoomImage(index)">
|
||||
<div
|
||||
class="gallery-list__item"
|
||||
@click="zoomImage(index)"
|
||||
>
|
||||
<img
|
||||
v-lazy="{
|
||||
src: addCacheBustParam(item.galleryPath) || addCacheBustParam(item.imgUrl)
|
||||
}"
|
||||
class="gallery-list__item-img"
|
||||
/>
|
||||
>
|
||||
</div>
|
||||
<div class="gallery-list__file-name" :title="item.fileName">
|
||||
<div
|
||||
class="gallery-list__file-name"
|
||||
:title="item.fileName"
|
||||
>
|
||||
{{ formatFileName(item.fileName || '') }}
|
||||
</div>
|
||||
<el-row class="gallery-list__tool-panel" justify="space-between" align="middle">
|
||||
<el-row
|
||||
class="gallery-list__tool-panel"
|
||||
justify="space-between"
|
||||
align="middle"
|
||||
>
|
||||
<el-row>
|
||||
<el-icon class="cursor-pointer document" @click="copy(item)">
|
||||
<el-icon
|
||||
class="cursor-pointer document"
|
||||
@click="copy(item)"
|
||||
>
|
||||
<Document />
|
||||
</el-icon>
|
||||
<el-icon class="cursor-pointer edit" @click="openDialog(item)">
|
||||
<el-icon
|
||||
class="cursor-pointer edit"
|
||||
@click="openDialog(item)"
|
||||
>
|
||||
<Edit />
|
||||
</el-icon>
|
||||
<el-icon class="cursor-pointer delete" @click="remove(item)">
|
||||
<el-icon
|
||||
class="cursor-pointer delete"
|
||||
@click="remove(item)"
|
||||
>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-row>
|
||||
@@ -227,7 +330,10 @@
|
||||
<el-button @click="dialogVisible = false">
|
||||
{{ $T('CANCEL') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="confirmModify">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="confirmModify"
|
||||
>
|
||||
{{ $T('CONFIRM') }}
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -241,7 +347,10 @@
|
||||
destroy-on-close
|
||||
append-to-body
|
||||
>
|
||||
<el-link :underline="false" style="margin-bottom: 10px">
|
||||
<el-link
|
||||
:underline="false"
|
||||
style="margin-bottom: 10px"
|
||||
>
|
||||
<span>
|
||||
{{ $T('MANAGE_BUCKET_RENAME_FILE_INPUT_A') + $T('GALLERY_MATCHED') + mathcedCount + ' ' }}
|
||||
<el-tooltip
|
||||
@@ -262,16 +371,29 @@
|
||||
:placeholder="$T('MANAGE_BUCKET_RENAME_FILE_INPUT_A_PLACEHOLDER')"
|
||||
clearable
|
||||
/>
|
||||
<el-link :underline="false" style="margin-bottom: 10px; margin-top: 10px">
|
||||
<el-link
|
||||
:underline="false"
|
||||
style="margin-bottom: 10px; margin-top: 10px"
|
||||
>
|
||||
<span>
|
||||
{{ $T('MANAGE_BUCKET_RENAME_FILE_INPUT_B') }}
|
||||
<el-popover effect="light" placement="right" width="280" :persistent="false" teleported>
|
||||
<el-popover
|
||||
effect="light"
|
||||
placement="right"
|
||||
width="280"
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<template #reference>
|
||||
<el-icon color="#409EFF">
|
||||
<InfoFilled />
|
||||
</el-icon>
|
||||
</template>
|
||||
<el-descriptions :column="1" style="width: 250px" border>
|
||||
<el-descriptions
|
||||
:column="1"
|
||||
style="width: 250px"
|
||||
border
|
||||
>
|
||||
<el-descriptions-item
|
||||
v-for="(item, index) in customRenameFormatTable"
|
||||
:key="index"
|
||||
@@ -290,14 +412,22 @@
|
||||
>
|
||||
{{ item.descriptionB }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="{auto}" align="center" label-style="width: 100px;">
|
||||
<el-descriptions-item
|
||||
label="{auto}"
|
||||
align="center"
|
||||
label-style="width: 100px;"
|
||||
>
|
||||
{{ $T('MANAGE_BUCKET_RENAME_FILE_TABLE_IID') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-popover>
|
||||
</span>
|
||||
</el-link>
|
||||
<el-input v-model="batchRenameReplace" placeholder="Ex. {Y}-{m}-{uuid}" clearable />
|
||||
<el-input
|
||||
v-model="batchRenameReplace"
|
||||
placeholder="Ex. {Y}-{m}-{uuid}"
|
||||
clearable
|
||||
/>
|
||||
<div style="margin-top: 10px; align-items: center; display: flex; justify-content: flex-end">
|
||||
<el-button
|
||||
type="danger"
|
||||
@@ -312,7 +442,12 @@
|
||||
>
|
||||
{{ $T('MANAGE_BUCKET_RENAME_FILE_CANCEL') }}
|
||||
</el-button>
|
||||
<el-button type="primary" plain :icon="Edit" @click="handleBatchRename()">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
:icon="Edit"
|
||||
@click="handleBatchRename()"
|
||||
>
|
||||
{{ $T('MANAGE_BUCKET_RENAME_FILE_CONFIRM') }}
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -321,36 +456,37 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ipcRenderer, clipboard } from 'electron'
|
||||
import { CheckboxValueType, ElMessageBox, ElNotification, ElMessage } from 'element-plus'
|
||||
|
||||
import {
|
||||
InfoFilled,
|
||||
Close,
|
||||
CaretBottom,
|
||||
CaretTop,
|
||||
Close,
|
||||
Delete,
|
||||
Document,
|
||||
Edit,
|
||||
Delete,
|
||||
CaretTop,
|
||||
Sort,
|
||||
Refresh
|
||||
InfoFilled,
|
||||
Refresh,
|
||||
Sort
|
||||
} from '@element-plus/icons-vue'
|
||||
import path from 'path'
|
||||
import { computed, nextTick, onActivated, onBeforeUnmount, onBeforeMount, reactive, ref, watch } from 'vue'
|
||||
import { CheckboxValueType, ElMessage, ElMessageBox, ElNotification } from 'element-plus'
|
||||
import { computed, nextTick, onActivated, onBeforeMount, onBeforeUnmount, reactive, ref, watch } from 'vue'
|
||||
import { onBeforeRouteUpdate } from 'vue-router'
|
||||
import type { IResult } from '@picgo/store/dist/types'
|
||||
|
||||
import ALLApi from '@/apis/allApi'
|
||||
import { T as $T } from '@/i18n/index'
|
||||
import { customRenameFormatTable, customStrMatch, customStrReplace } from '@/manage/utils/common'
|
||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||
import { getConfig, saveConfig } from '@/utils/dataSender'
|
||||
import $$db from '@/utils/db'
|
||||
import { picBedGlobal } from '@/utils/global'
|
||||
|
||||
import { IPasteStyle, IRPCActionType } from '#/types/enum'
|
||||
import { ICheckBoxValueType, IGalleryItem, ImgInfo, IObj, IObjT } from '#/types/types'
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
import { picBedsCanbeDeleted } from '#/utils/static'
|
||||
import { IPasteStyle, IRPCActionType } from '#/types/enum'
|
||||
|
||||
type IResult<T> = T & {
|
||||
id: string
|
||||
createdAt: number
|
||||
updatedAt: number
|
||||
}
|
||||
const images = ref<ImgInfo[]>([])
|
||||
const dialogVisible = ref(false)
|
||||
const imgInfo = reactive({
|
||||
@@ -406,22 +542,22 @@ onBeforeRouteUpdate((to, from) => {
|
||||
}
|
||||
})
|
||||
|
||||
async function initDeleteCloud() {
|
||||
async function initDeleteCloud () {
|
||||
deleteCloud.value = (await getConfig<boolean>(configPaths.settings.deleteCloudFile)) || false
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
ipcRenderer.on('updateGallery', () => {
|
||||
nextTick(async () => {
|
||||
updateGallery()
|
||||
})
|
||||
const updateGalleryHandler = () => {
|
||||
nextTick(async () => {
|
||||
updateGallery()
|
||||
})
|
||||
}
|
||||
onBeforeMount(async () => {
|
||||
window.electron.ipcRendererOn('updateGallery', updateGalleryHandler)
|
||||
updateGallery()
|
||||
document.addEventListener('keydown', handleDetectShiftKey)
|
||||
document.addEventListener('keyup', handleDetectShiftKey)
|
||||
})
|
||||
|
||||
function handleDetectShiftKey(event: KeyboardEvent) {
|
||||
function handleDetectShiftKey (event: KeyboardEvent) {
|
||||
if (event.key === 'Shift') {
|
||||
isShiftKeyPress.value = event.type === 'keydown'
|
||||
}
|
||||
@@ -469,11 +605,11 @@ const isAllSelected = computed(() => {
|
||||
return Object.values(choosedList).length > 0 && filterList.value.every(item => choosedList[item.id!])
|
||||
})
|
||||
|
||||
function formatFileName(name: string) {
|
||||
return path.basename(name)
|
||||
function formatFileName (name: string) {
|
||||
return window.node.path.basename(name)
|
||||
}
|
||||
|
||||
function getGallery(): IGalleryItem[] {
|
||||
function getGallery (): IGalleryItem[] {
|
||||
if (searchText.value || choosedPicBed.value.length > 0 || searchTextURL.value || dateRange.value) {
|
||||
return images.value
|
||||
.filter(item => {
|
||||
@@ -517,7 +653,7 @@ function getGallery(): IGalleryItem[] {
|
||||
}
|
||||
}
|
||||
|
||||
async function updateGallery() {
|
||||
async function updateGallery () {
|
||||
images.value = (await $$db.get({ orderBy: 'desc' }))!.data
|
||||
}
|
||||
|
||||
@@ -528,7 +664,7 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
function handleChooseImage(val: CheckboxValueType, index: number) {
|
||||
function handleChooseImage (val: CheckboxValueType, index: number) {
|
||||
if (val === true) {
|
||||
handleBarActive.value = true
|
||||
if (lastChoosed.value !== -1 && isShiftKeyPress.value) {
|
||||
@@ -543,11 +679,11 @@ function handleChooseImage(val: CheckboxValueType, index: number) {
|
||||
}
|
||||
}
|
||||
|
||||
function refreshPage() {
|
||||
sendRPC(IRPCActionType.REFRESH_SETTING_WINDOW)
|
||||
function refreshPage () {
|
||||
window.electron.sendRPC(IRPCActionType.REFRESH_SETTING_WINDOW)
|
||||
}
|
||||
|
||||
function clearChoosedList() {
|
||||
function clearChoosedList () {
|
||||
isShiftKeyPress.value = false
|
||||
Object.keys(choosedList).forEach(key => {
|
||||
choosedList[key] = false
|
||||
@@ -555,13 +691,13 @@ function clearChoosedList() {
|
||||
lastChoosed.value = -1
|
||||
}
|
||||
|
||||
function zoomImage(index: number) {
|
||||
function zoomImage (index: number) {
|
||||
gallerySliderControl.index = index
|
||||
gallerySliderControl.visible = true
|
||||
changeZIndexForGallery(true)
|
||||
}
|
||||
|
||||
function changeZIndexForGallery(isOpen: boolean) {
|
||||
function changeZIndexForGallery (isOpen: boolean) {
|
||||
if (isOpen) {
|
||||
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
|
||||
document.querySelector('.main-content.el-row').style.zIndex = 101
|
||||
@@ -571,15 +707,15 @@ function changeZIndexForGallery(isOpen: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
function handleClose () {
|
||||
gallerySliderControl.index = 0
|
||||
gallerySliderControl.visible = false
|
||||
changeZIndexForGallery(false)
|
||||
}
|
||||
|
||||
async function copy(item: ImgInfo) {
|
||||
async function copy (item: ImgInfo) {
|
||||
item.config = JSON.parse(JSON.stringify(item.config) || '{}')
|
||||
const result = await triggerRPC<[string, string]>(IRPCActionType.GALLERY_PASTE_TEXT, item)
|
||||
const result = await window.electron.triggerRPC<[string, string]>(IRPCActionType.GALLERY_PASTE_TEXT, item)
|
||||
if (result && result[1] && item.id) {
|
||||
await $$db.updateById(item.id, {
|
||||
shortUrl: result[1]
|
||||
@@ -596,7 +732,7 @@ async function copy(item: ImgInfo) {
|
||||
updateGallery()
|
||||
}
|
||||
|
||||
function remove(item: ImgInfo) {
|
||||
function remove (item: ImgInfo) {
|
||||
if (!item.id) return
|
||||
$confirm($T('TIPS_REMOVE_LINK'), $T('TIPS_NOTICE'), {
|
||||
confirmButtonText: $T('CONFIRM'),
|
||||
@@ -626,7 +762,7 @@ function remove(item: ImgInfo) {
|
||||
}
|
||||
}
|
||||
await $$db.removeById(item.id!)
|
||||
sendRPC(IRPCActionType.GALLERY_REMOVE_FILES, [file])
|
||||
window.electron.sendRPC(IRPCActionType.GALLERY_REMOVE_FILES, [file])
|
||||
const obj = {
|
||||
title: $T('OPERATION_SUCCEED'),
|
||||
body: ''
|
||||
@@ -643,19 +779,19 @@ function remove(item: ImgInfo) {
|
||||
})
|
||||
}
|
||||
|
||||
function handleDeleteCloudFile(val: ICheckBoxValueType) {
|
||||
function handleDeleteCloudFile (val: ICheckBoxValueType) {
|
||||
saveConfig({
|
||||
[configPaths.settings.deleteCloudFile]: val
|
||||
})
|
||||
}
|
||||
|
||||
function openDialog(item: ImgInfo) {
|
||||
function openDialog (item: ImgInfo) {
|
||||
imgInfo.id = item.id!
|
||||
imgInfo.imgUrl = item.imgUrl as string
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
async function confirmModify() {
|
||||
async function confirmModify () {
|
||||
await $$db.updateById(imgInfo.id, {
|
||||
imgUrl: imgInfo.imgUrl
|
||||
})
|
||||
@@ -671,26 +807,26 @@ async function confirmModify() {
|
||||
updateGallery()
|
||||
}
|
||||
|
||||
function cleanSearch() {
|
||||
function cleanSearch () {
|
||||
searchText.value = ''
|
||||
}
|
||||
|
||||
function cleanSearchUrl() {
|
||||
function cleanSearchUrl () {
|
||||
searchTextURL.value = ''
|
||||
}
|
||||
|
||||
function isMultiple(obj: IObj) {
|
||||
function isMultiple (obj: IObj) {
|
||||
return Object.values(obj).some(item => item)
|
||||
}
|
||||
|
||||
function toggleSelectAll() {
|
||||
function toggleSelectAll () {
|
||||
const result = !isAllSelected.value
|
||||
filterList.value.forEach(item => {
|
||||
choosedList[item.id!] = result
|
||||
})
|
||||
}
|
||||
|
||||
function multiRemove() {
|
||||
function multiRemove () {
|
||||
const multiRemoveNumber = Object.values(choosedList).filter(item => item).length
|
||||
if (multiRemoveNumber) {
|
||||
$confirm(
|
||||
@@ -709,8 +845,8 @@ function multiRemove() {
|
||||
const imageIDList = Object.keys(choosedList)
|
||||
const isDeleteCloudFile = await getConfig(configPaths.settings.deleteCloudFile)
|
||||
if (isDeleteCloudFile) {
|
||||
for (let i = 0; i < imageIDList.length; i++) {
|
||||
const key = imageIDList[i]
|
||||
for (const imageIDListItem of imageIDList) {
|
||||
const key = imageIDListItem
|
||||
if (choosedList[key]) {
|
||||
const file = await $$db.getById<ImgInfo>(key)
|
||||
if (file) {
|
||||
@@ -741,8 +877,8 @@ function multiRemove() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < imageIDList.length; i++) {
|
||||
const key = imageIDList[i]
|
||||
for (const imageIDListItem of imageIDList) {
|
||||
const key = imageIDListItem
|
||||
if (choosedList[key]) {
|
||||
const file = await $$db.getById<ImgInfo>(key)
|
||||
if (file) {
|
||||
@@ -759,7 +895,7 @@ function multiRemove() {
|
||||
title: $T('OPERATION_SUCCEED'),
|
||||
body: ''
|
||||
}
|
||||
sendRPC(IRPCActionType.GALLERY_REMOVE_FILES, files)
|
||||
window.electron.sendRPC(IRPCActionType.GALLERY_REMOVE_FILES, files)
|
||||
const myNotification = new Notification(obj.title, obj)
|
||||
myNotification.onclick = () => {
|
||||
return true
|
||||
@@ -772,17 +908,17 @@ function multiRemove() {
|
||||
}
|
||||
}
|
||||
|
||||
async function multiCopy() {
|
||||
async function multiCopy () {
|
||||
if (Object.values(choosedList).some(item => item)) {
|
||||
const copyString: string[] = []
|
||||
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
|
||||
const imageIDList = Object.keys(choosedList)
|
||||
for (let i = 0; i < imageIDList.length; i++) {
|
||||
const key = imageIDList[i]
|
||||
for (const imageIDListItem of imageIDList) {
|
||||
const key = imageIDListItem
|
||||
if (choosedList[key]) {
|
||||
const item = await $$db.getById<ImgInfo>(key)
|
||||
if (item) {
|
||||
const result = await triggerRPC<string>(IRPCActionType.GALLERY_PASTE_TEXT, item)
|
||||
const result = await window.electron.triggerRPC<string>(IRPCActionType.GALLERY_PASTE_TEXT, item)
|
||||
copyString.push(result ? result[0] : '')
|
||||
if (result && result[1] && item.id) {
|
||||
await $$db.updateById(item.id, {
|
||||
@@ -798,7 +934,7 @@ async function multiCopy() {
|
||||
body: copyString.join('\n')
|
||||
}
|
||||
const myNotification = new Notification(obj.title, obj)
|
||||
clipboard.writeText(copyString.join('\n'))
|
||||
window.electron.clipboard.writeText(copyString.join('\n'))
|
||||
myNotification.onclick = () => {
|
||||
return true
|
||||
}
|
||||
@@ -806,21 +942,21 @@ async function multiCopy() {
|
||||
}
|
||||
}
|
||||
|
||||
function toggleHandleBar() {
|
||||
function toggleHandleBar () {
|
||||
handleBarActive.value = !handleBarActive.value
|
||||
}
|
||||
|
||||
async function handlePasteStyleChange(val: string) {
|
||||
async function handlePasteStyleChange (val: string) {
|
||||
saveConfig(configPaths.settings.pasteStyle, val)
|
||||
pasteStyle.value = val
|
||||
}
|
||||
|
||||
function handleUseShortUrlChange(value: string) {
|
||||
function handleUseShortUrlChange (value: string) {
|
||||
saveConfig(configPaths.settings.useShortUrl, value === $T('UPLOAD_SHORT_URL'))
|
||||
useShortUrl.value = value
|
||||
}
|
||||
|
||||
function sortFile(type: 'name' | 'time' | 'ext' | 'check') {
|
||||
function sortFile (type: 'name' | 'time' | 'ext' | 'check') {
|
||||
switch (type) {
|
||||
case 'name':
|
||||
fileSortNameReverse.value = !fileSortNameReverse.value
|
||||
@@ -866,7 +1002,7 @@ function sortFile(type: 'name' | 'time' | 'ext' | 'check') {
|
||||
}
|
||||
}
|
||||
|
||||
function handleBatchRename() {
|
||||
function handleBatchRename () {
|
||||
isShowBatchRenameDialog.value = false
|
||||
if (batchRenameMatch.value === '') {
|
||||
ElMessage.warning($T('MANAGE_BUCKET_BATCH_RENAME_ERROR_MSG'))
|
||||
@@ -882,8 +1018,8 @@ function handleBatchRename() {
|
||||
ElMessage.warning($T('MANAGE_BUCKET_BATCH_RENAME_ERROR_MSG2'))
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < matchedFiles.length; i++) {
|
||||
matchedFiles[i].newUrl = customStrReplace(matchedFiles[i].imgUrl, batchRenameMatch.value, batchRenameReplace.value)
|
||||
for (const matchedFile of matchedFiles) {
|
||||
matchedFile.newUrl = customStrReplace(matchedFile.imgUrl, batchRenameMatch.value, batchRenameReplace.value)
|
||||
}
|
||||
matchedFiles = matchedFiles.filter((item: any) => item.imgUrl !== item.newUrl)
|
||||
if (matchedFiles.length === 0) {
|
||||
@@ -902,8 +1038,8 @@ function handleBatchRename() {
|
||||
}
|
||||
const rename = () => {
|
||||
const promiseList = [] as any[]
|
||||
for (let i = 0; i < matchedFiles.length; i++) {
|
||||
promiseList.push(renamefunc(matchedFiles[i]))
|
||||
for (const matchedFile of matchedFiles) {
|
||||
promiseList.push(renamefunc(matchedFile))
|
||||
}
|
||||
Promise.all(promiseList)
|
||||
.then(() => {
|
||||
@@ -943,7 +1079,7 @@ function handleBatchRename() {
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
ipcRenderer.removeAllListeners('updateGallery')
|
||||
window.electron.ipcRendererRemoveListener('updateGallery', updateGalleryHandler)
|
||||
})
|
||||
|
||||
onActivated(async () => {
|
||||
|
||||
@@ -14,29 +14,36 @@
|
||||
>
|
||||
<img
|
||||
v-if="!dragover && !isShowingProgress"
|
||||
:src="logoPath ? logoPath : require('../assets/squareLogo.png')"
|
||||
:src="logoPath ? logoPath : '/squareLogo.png'"
|
||||
style="width: 100%; height: 100%; border-radius: 50%"
|
||||
/>
|
||||
<div id="upload-dragger" @dblclick="openUploadWindow">
|
||||
<input id="file-uploader" type="file" multiple @change="onChange" />
|
||||
>
|
||||
<div
|
||||
id="upload-dragger"
|
||||
@dblclick="openUploadWindow"
|
||||
>
|
||||
<input
|
||||
id="file-uploader"
|
||||
type="file"
|
||||
multiple
|
||||
@change="onChange"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { IpcRendererEvent } from 'electron'
|
||||
import { ElMessage as $message } from 'element-plus'
|
||||
import { ipcRenderer, IpcRendererEvent } from 'electron'
|
||||
import { IConfig } from 'piclist'
|
||||
import { onBeforeUnmount, onBeforeMount, ref, watch } from 'vue'
|
||||
import type { IConfig } from 'piclist'
|
||||
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
|
||||
|
||||
import { T as $T } from '@/i18n/index'
|
||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||
import { getConfig } from '@/utils/dataSender'
|
||||
import { osGlobal } from '@/utils/global'
|
||||
|
||||
import { isUrl } from '#/utils/common'
|
||||
import { IRPCActionType } from '#/types/enum'
|
||||
import { IFileWithPath } from '#/types/types'
|
||||
import { isUrl } from '#/utils/common'
|
||||
|
||||
const logoPath = ref('')
|
||||
const dragover = ref(false)
|
||||
@@ -48,30 +55,34 @@ const wY = ref(-1)
|
||||
const screenX = ref(-1)
|
||||
const screenY = ref(-1)
|
||||
|
||||
async function initLogoPath() {
|
||||
async function initLogoPath () {
|
||||
const config = await getConfig<IConfig>()
|
||||
if (config) {
|
||||
if (config.settings?.isCustomMiniIcon && config.settings?.customMiniIcon) {
|
||||
logoPath.value =
|
||||
'data:image/jpg;base64,' +
|
||||
(await triggerRPC(IRPCActionType.MANAGE_CONVERT_PATH_TO_BASE64, config.settings.customMiniIcon))
|
||||
(await window.electron.triggerRPC(IRPCActionType.MANAGE_CONVERT_PATH_TO_BASE64, config.settings.customMiniIcon))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uploadProgressHandler = (_: IpcRendererEvent, _progress: number) => {
|
||||
if (_progress !== -1) {
|
||||
isShowingProgress.value = true
|
||||
progress.value = _progress
|
||||
} else {
|
||||
progress.value = 100
|
||||
}
|
||||
}
|
||||
|
||||
const updateMiniIconHandler = async () => {
|
||||
await initLogoPath()
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
await initLogoPath()
|
||||
ipcRenderer.on('uploadProgress', (_: IpcRendererEvent, _progress: number) => {
|
||||
if (_progress !== -1) {
|
||||
isShowingProgress.value = true
|
||||
progress.value = _progress
|
||||
} else {
|
||||
progress.value = 100
|
||||
}
|
||||
})
|
||||
ipcRenderer.on('updateMiniIcon', async () => {
|
||||
await initLogoPath()
|
||||
})
|
||||
window.electron.ipcRendererOn('uploadProgress', uploadProgressHandler)
|
||||
window.electron.ipcRendererOn('updateMiniIcon', updateMiniIconHandler)
|
||||
window.addEventListener('mousedown', handleMouseDown, false)
|
||||
window.addEventListener('mousemove', handleMouseMove, false)
|
||||
window.addEventListener('mouseup', handleMouseUp, false)
|
||||
@@ -88,7 +99,7 @@ watch(progress, val => {
|
||||
}
|
||||
})
|
||||
|
||||
function onDrop(e: DragEvent) {
|
||||
function onDrop (e: DragEvent) {
|
||||
dragover.value = false
|
||||
|
||||
// send files first
|
||||
@@ -101,7 +112,7 @@ function onDrop(e: DragEvent) {
|
||||
} else if (items[0].type === 'text/plain') {
|
||||
const str = e.dataTransfer!.getData(items[0].type)
|
||||
if (isUrl(str)) {
|
||||
sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [{ path: str }])
|
||||
window.electron.sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [{ path: str }])
|
||||
} else {
|
||||
$message.error($T('TIPS_DRAG_VALID_PICTURE_OR_URL'))
|
||||
}
|
||||
@@ -109,13 +120,13 @@ function onDrop(e: DragEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleURLDrag(items: DataTransferItemList, dataTransfer: DataTransfer) {
|
||||
function handleURLDrag (items: DataTransferItemList, dataTransfer: DataTransfer) {
|
||||
// text/html
|
||||
// Use this data to get a more precise URL
|
||||
const urlString = dataTransfer.getData(items[1].type)
|
||||
const urlMatch = urlString.match(/<img.*src="(.*?)"/)
|
||||
if (urlMatch) {
|
||||
sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [
|
||||
window.electron.sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [
|
||||
{
|
||||
path: urlMatch[1]
|
||||
}
|
||||
@@ -125,30 +136,30 @@ function handleURLDrag(items: DataTransferItemList, dataTransfer: DataTransfer)
|
||||
}
|
||||
}
|
||||
|
||||
function openUploadWindow() {
|
||||
function openUploadWindow () {
|
||||
// @ts-expect-error file-uploader
|
||||
document.getElementById('file-uploader').click()
|
||||
}
|
||||
|
||||
function onChange(e: any) {
|
||||
function onChange (e: any) {
|
||||
ipcSendFiles(e.target.files)
|
||||
// @ts-expect-error file-uploader
|
||||
document.getElementById('file-uploader').value = ''
|
||||
}
|
||||
|
||||
function ipcSendFiles(files: FileList) {
|
||||
function ipcSendFiles (files: FileList) {
|
||||
const sendFiles: IFileWithPath[] = []
|
||||
Array.from(files).forEach(item => {
|
||||
const obj = {
|
||||
name: item.name,
|
||||
path: item.path
|
||||
path: item.webkitRelativePath
|
||||
}
|
||||
sendFiles.push(obj)
|
||||
})
|
||||
sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, sendFiles)
|
||||
window.electron.sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, sendFiles)
|
||||
}
|
||||
|
||||
function handleMouseDown(e: MouseEvent) {
|
||||
function handleMouseDown (e: MouseEvent) {
|
||||
draggingState.value = true
|
||||
wX.value = e.pageX
|
||||
wY.value = e.pageY
|
||||
@@ -156,13 +167,13 @@ function handleMouseDown(e: MouseEvent) {
|
||||
screenY.value = e.screenY
|
||||
}
|
||||
|
||||
function handleMouseMove(e: MouseEvent) {
|
||||
function handleMouseMove (e: MouseEvent) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
if (draggingState.value) {
|
||||
const xLoc = e.screenX - wX.value
|
||||
const yLoc = e.screenY - wY.value
|
||||
sendRPC(IRPCActionType.SET_MINI_WINDOW_POS, {
|
||||
window.electron.sendRPC(IRPCActionType.SET_MINI_WINDOW_POS, {
|
||||
x: xLoc,
|
||||
y: yLoc,
|
||||
width: 64,
|
||||
@@ -171,7 +182,7 @@ function handleMouseMove(e: MouseEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseUp(e: MouseEvent) {
|
||||
function handleMouseUp (e: MouseEvent) {
|
||||
draggingState.value = false
|
||||
if (screenX.value === e.screenX && screenY.value === e.screenY) {
|
||||
if (e.button === 0) {
|
||||
@@ -183,13 +194,13 @@ function handleMouseUp(e: MouseEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
function openContextMenu() {
|
||||
sendRPC(IRPCActionType.SHOW_MINI_PAGE_MENU)
|
||||
function openContextMenu () {
|
||||
window.electron.sendRPC(IRPCActionType.SHOW_MINI_PAGE_MENU)
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
ipcRenderer.removeAllListeners('uploadProgress')
|
||||
ipcRenderer.removeAllListeners('updateMiniIcon')
|
||||
window.electron.ipcRendererRemoveListener('uploadProgress', uploadProgressHandler)
|
||||
window.electron.ipcRendererRemoveListener('updateMiniIcon', updateMiniIconHandler)
|
||||
window.removeEventListener('mousedown', handleMouseDown, false)
|
||||
window.removeEventListener('mousemove', handleMouseMove, false)
|
||||
window.removeEventListener('mouseup', handleMouseUp, false)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,32 +2,72 @@
|
||||
<div id="plugin-view">
|
||||
<div class="view-title">
|
||||
{{ $T('PLUGIN_SETTINGS') }} -
|
||||
<el-tooltip :content="pluginListToolTip" placement="right" :persistent="false" teleported>
|
||||
<el-icon class="el-icon-goods" @click="goAwesomeList">
|
||||
<el-tooltip
|
||||
:content="pluginListToolTip"
|
||||
placement="right"
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<el-icon
|
||||
class="el-icon-goods"
|
||||
@click="goAwesomeList"
|
||||
>
|
||||
<Goods />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="updateAllToolTip" placement="left" :persistent="false" teleported>
|
||||
<el-icon class="el-icon-update" @click="handleUpdateAllPlugin">
|
||||
<el-tooltip
|
||||
:content="updateAllToolTip"
|
||||
placement="left"
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<el-icon
|
||||
class="el-icon-update"
|
||||
@click="handleUpdateAllPlugin"
|
||||
>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="importLocalPluginToolTip" placement="left">
|
||||
<el-icon class="el-icon-download" :persistent="false" teleported @click="handleImportLocalPlugin">
|
||||
<el-tooltip
|
||||
:content="importLocalPluginToolTip"
|
||||
placement="left"
|
||||
>
|
||||
<el-icon
|
||||
class="el-icon-download"
|
||||
:persistent="false"
|
||||
teleported
|
||||
@click="handleImportLocalPlugin"
|
||||
>
|
||||
<Download />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-row class="handle-bar" :class="{ 'cut-width': pluginList.length > 6 }">
|
||||
<el-input v-model="searchText" :placeholder="$T('PLUGIN_SEARCH_PLACEHOLDER')" size="small">
|
||||
<el-row
|
||||
class="handle-bar"
|
||||
:class="{ 'cut-width': pluginList.length > 6 }"
|
||||
>
|
||||
<el-input
|
||||
v-model="searchText"
|
||||
:placeholder="$T('PLUGIN_SEARCH_PLACEHOLDER')"
|
||||
size="small"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon class="el-input__icon" style="cursor: pointer" @click="cleanSearch">
|
||||
<el-icon
|
||||
class="el-input__icon"
|
||||
style="cursor: pointer"
|
||||
@click="cleanSearch"
|
||||
>
|
||||
<close />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-row>
|
||||
<el-row id="pluginList" v-loading="loading" :gutter="10" class="plugin-list">
|
||||
<el-row
|
||||
id="pluginList"
|
||||
v-loading="loading"
|
||||
:gutter="10"
|
||||
class="plugin-list"
|
||||
>
|
||||
<el-col
|
||||
v-for="item in pluginList"
|
||||
:key="item.fullName"
|
||||
@@ -38,11 +78,30 @@
|
||||
:lg="pluginList.length === 1 ? 24 : 12"
|
||||
:xl="pluginList.length === 1 ? 24 : 12"
|
||||
>
|
||||
<div class="plugin-item" :class="{ darwin: osGlobal === 'darwin' }">
|
||||
<div v-if="!item.gui" class="cli-only-badge" title="CLI only">CLI</div>
|
||||
<img class="plugin-item__logo" :src="item.logo" :onerror="defaultLogo" />
|
||||
<div class="plugin-item__content" :class="{ disabled: !item.enabled }">
|
||||
<div class="plugin-item__name" @click="openHomepage(item.homepage)">
|
||||
<div
|
||||
class="plugin-item"
|
||||
:class="{ darwin: osGlobal === 'darwin' }"
|
||||
>
|
||||
<div
|
||||
v-if="!item.gui"
|
||||
class="cli-only-badge"
|
||||
title="CLI only"
|
||||
>
|
||||
CLI
|
||||
</div>
|
||||
<img
|
||||
class="plugin-item__logo"
|
||||
:src="item.logo"
|
||||
:onerror="defaultLogo"
|
||||
>
|
||||
<div
|
||||
class="plugin-item__content"
|
||||
:class="{ disabled: !item.enabled }"
|
||||
>
|
||||
<div
|
||||
class="plugin-item__name"
|
||||
@click="openHomepage(item.homepage)"
|
||||
>
|
||||
{{ item.name }} <small>{{ ' ' + item.version }}</small>
|
||||
<!-- 升级提示 -->
|
||||
<el-tag
|
||||
@@ -55,7 +114,10 @@
|
||||
new
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="plugin-item__desc" :title="item.description">
|
||||
<div
|
||||
class="plugin-item__desc"
|
||||
:title="item.description"
|
||||
>
|
||||
{{ item.description }}
|
||||
</div>
|
||||
<div class="plugin-item__info-bar">
|
||||
@@ -65,26 +127,47 @@
|
||||
<span class="plugin-item__config">
|
||||
<template v-if="searchText">
|
||||
<template v-if="!item.hasInstall">
|
||||
<span v-if="!item.ing" class="config-button install" @click="installPlugin(item)">
|
||||
<span
|
||||
v-if="!item.ing"
|
||||
class="config-button install"
|
||||
@click="installPlugin(item)"
|
||||
>
|
||||
{{ $T('PLUGIN_INSTALL') }}
|
||||
</span>
|
||||
<span v-else-if="item.ing" class="config-button ing">
|
||||
<span
|
||||
v-else-if="item.ing"
|
||||
class="config-button ing"
|
||||
>
|
||||
{{ $T('PLUGIN_INSTALLING') }}
|
||||
</span>
|
||||
</template>
|
||||
<span v-else class="config-button ing">
|
||||
<span
|
||||
v-else
|
||||
class="config-button ing"
|
||||
>
|
||||
{{ $T('PLUGIN_INSTALLED') }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-if="item.ing" class="config-button ing">
|
||||
<span
|
||||
v-if="item.ing"
|
||||
class="config-button ing"
|
||||
>
|
||||
{{ $T('PLUGIN_DOING_SOMETHING') }}
|
||||
</span>
|
||||
<template v-else>
|
||||
<el-icon v-if="item.enabled" class="el-icon-setting" @click="buildContextMenu(item)">
|
||||
<el-icon
|
||||
v-if="item.enabled"
|
||||
class="el-icon-setting"
|
||||
@click="buildContextMenu(item)"
|
||||
>
|
||||
<Tools />
|
||||
</el-icon>
|
||||
<el-icon v-else class="el-icon-remove-outline" @click="buildContextMenu(item)">
|
||||
<el-icon
|
||||
v-else
|
||||
class="el-icon-remove-outline"
|
||||
@click="buildContextMenu(item)"
|
||||
>
|
||||
<Remove />
|
||||
</el-icon>
|
||||
</template>
|
||||
@@ -95,8 +178,18 @@
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-show="needReload" class="reload-mask" :class="{ 'cut-width': pluginList.length > 6 }" justify="center">
|
||||
<el-button type="primary" size="small" round @click="reloadApp">
|
||||
<el-row
|
||||
v-show="needReload"
|
||||
class="reload-mask"
|
||||
:class="{ 'cut-width': pluginList.length > 6 }"
|
||||
justify="center"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
round
|
||||
@click="reloadApp"
|
||||
>
|
||||
{{ $T('TIPS_NEED_RELOAD') }}
|
||||
</el-button>
|
||||
</el-row>
|
||||
@@ -111,12 +204,25 @@
|
||||
width="70%"
|
||||
append-to-body
|
||||
>
|
||||
<config-form :id="configName" ref="$configForm" :config="config" :type="currentType" color-mode="white" />
|
||||
<config-form
|
||||
:id="configName"
|
||||
ref="$configForm"
|
||||
:config="config"
|
||||
:type="currentType"
|
||||
color-mode="white"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button round @click="dialogVisible = false">
|
||||
<el-button
|
||||
round
|
||||
@click="dialogVisible = false"
|
||||
>
|
||||
{{ $T('CANCEL') }}
|
||||
</el-button>
|
||||
<el-button type="primary" round @click="handleConfirmConfig">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
@click="handleConfirmConfig"
|
||||
>
|
||||
{{ $T('CONFIRM') }}
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -125,26 +231,24 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import axios from 'axios'
|
||||
import { ipcRenderer, IpcRendererEvent } from 'electron'
|
||||
import { Close, Download, Goods, Refresh, Remove, Tools } from '@element-plus/icons-vue'
|
||||
import type { IpcRendererEvent } from 'electron'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { debounce, DebouncedFunc } from 'lodash'
|
||||
import { Close, Download, Refresh, Goods, Remove, Tools } from '@element-plus/icons-vue'
|
||||
import { computed, ref, onBeforeMount, onBeforeUnmount, watch, onMounted, reactive, toRaw } from 'vue'
|
||||
import { debounce, DebouncedFunc } from 'lodash-es'
|
||||
import { computed, onBeforeMount, onBeforeUnmount, onMounted, reactive, ref, toRaw, watch } from 'vue'
|
||||
|
||||
import ConfigForm from '@/components/ConfigFormForPlugin.vue'
|
||||
import { T as $T } from '@/i18n/index'
|
||||
import { sendRPC } from '@/utils/common'
|
||||
import { getConfig, saveConfig } from '@/utils/dataSender'
|
||||
import { osGlobal, updatePicBedGlobal } from '@/utils/global'
|
||||
|
||||
import {
|
||||
PICGO_CONFIG_PLUGIN,
|
||||
PICGO_HANDLE_PLUGIN_DONE,
|
||||
PICGO_HANDLE_PLUGIN_ING,
|
||||
PICGO_TOGGLE_PLUGIN,
|
||||
PICGO_HANDLE_PLUGIN_DONE
|
||||
PICGO_TOGGLE_PLUGIN
|
||||
} from '#/events/constants'
|
||||
import { IRPCActionType } from '#/types/enum'
|
||||
import { INPMSearchResult, INPMSearchResultObject, IPicGoPlugin } from '#/types/types'
|
||||
import { handleStreamlinePluginName } from '#/utils/common'
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
|
||||
@@ -162,7 +266,7 @@ const latestVersionMap = reactive<{ [key: string]: string }>({})
|
||||
const pluginListToolTip = $T('PLUGIN_LIST')
|
||||
const importLocalPluginToolTip = $T('PLUGIN_IMPORT_LOCAL')
|
||||
const updateAllToolTip = $T('PLUGIN_UPDATE_ALL')
|
||||
const defaultLogo = ref(`this.src="file://${__static.replace(/\\/g, '/')}/roundLogo.png"`)
|
||||
const defaultLogo = ref('this.src=\'/roundLogo.png\'')
|
||||
const $configForm = ref<InstanceType<typeof ConfigForm> | null>(null)
|
||||
const npmSearchText = computed(() => {
|
||||
return searchText.value.match('picgo-plugin-')
|
||||
@@ -193,120 +297,132 @@ watch(dialogVisible, (val: boolean) => {
|
||||
}
|
||||
})
|
||||
|
||||
async function getLatestVersionOfPlugIn(pluginName: string) {
|
||||
async function getLatestVersionOfPlugIn (pluginName: string) {
|
||||
try {
|
||||
const res = await axios.get(`https://registry.npmjs.com/${pluginName}`)
|
||||
const res = await window.node.axios.get(`https://registry.npmjs.com/${pluginName}`)
|
||||
latestVersionMap[pluginName] = res.data['dist-tags'].latest
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
const hideLoadingHandler = () => {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const picgoHandlePluginDoneHandler = (_: IpcRendererEvent, fullName: string) => {
|
||||
pluginList.value.forEach(item => {
|
||||
if (item.fullName === fullName || item.name === fullName) {
|
||||
item.ing = false
|
||||
}
|
||||
})
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const pluginListHandler = (_: IpcRendererEvent, list: IPicGoPlugin[]) => {
|
||||
pluginList.value = list
|
||||
pluginNameList.value = list.map(item => item.fullName)
|
||||
for (const item of pluginList.value) {
|
||||
getLatestVersionOfPlugIn(item.fullName)
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const installPluginHandler = (
|
||||
_: IpcRendererEvent,
|
||||
{
|
||||
success,
|
||||
body
|
||||
}: {
|
||||
success: boolean
|
||||
body: string
|
||||
}
|
||||
) => {
|
||||
loading.value = false
|
||||
pluginList.value.forEach(item => {
|
||||
if (item.fullName === body) {
|
||||
item.ing = false
|
||||
item.hasInstall = success
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const updateSuccessHandler = (_: IpcRendererEvent, plugin: string) => {
|
||||
loading.value = false
|
||||
pluginList.value.forEach(item => {
|
||||
if (item.fullName === plugin) {
|
||||
item.ing = false
|
||||
item.hasInstall = true
|
||||
}
|
||||
updatePicBedGlobal()
|
||||
})
|
||||
handleReload()
|
||||
getPluginList()
|
||||
}
|
||||
|
||||
const uninstallSuccessHandler = (_: IpcRendererEvent, plugin: string) => {
|
||||
loading.value = false
|
||||
pluginList.value = pluginList.value.filter(item => {
|
||||
if (item.fullName === plugin) {
|
||||
// restore Uploader & Transformer after uninstalling
|
||||
if (item.config.transformer.name) {
|
||||
handleRestoreState('transformer', item.config.transformer.name)
|
||||
}
|
||||
if (item.config.uploader.name) {
|
||||
handleRestoreState('uploader', item.config.uploader.name)
|
||||
}
|
||||
updatePicBedGlobal()
|
||||
}
|
||||
return item.fullName !== plugin
|
||||
})
|
||||
pluginNameList.value = pluginNameList.value.filter(item => item !== plugin)
|
||||
}
|
||||
|
||||
const picgoConfigPluginHandler = (_: IpcRendererEvent, _currentType: 'plugin' | 'transformer' | 'uploader', _configName: string, _config: any) => {
|
||||
currentType.value = _currentType
|
||||
configName.value = _configName
|
||||
config.value = _config
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const picgoHandlePluginIngHandler = (_: IpcRendererEvent, fullName: string) => {
|
||||
pluginList.value.forEach(item => {
|
||||
if (item.fullName === fullName || item.name === fullName) {
|
||||
item.ing = true
|
||||
}
|
||||
})
|
||||
loading.value = true
|
||||
}
|
||||
|
||||
const picgoTogglePluginHandler = (_: IpcRendererEvent, fullName: string, enabled: boolean) => {
|
||||
const plugin = pluginList.value.find(item => item.fullName === fullName)
|
||||
if (plugin) {
|
||||
plugin.enabled = enabled
|
||||
updatePicBedGlobal()
|
||||
needReload.value = true
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
ipcRenderer.on('hideLoading', () => {
|
||||
loading.value = false
|
||||
})
|
||||
ipcRenderer.on(PICGO_HANDLE_PLUGIN_DONE, (_: IpcRendererEvent, fullName: string) => {
|
||||
pluginList.value.forEach(item => {
|
||||
if (item.fullName === fullName || item.name === fullName) {
|
||||
item.ing = false
|
||||
}
|
||||
})
|
||||
loading.value = false
|
||||
})
|
||||
ipcRenderer.on('pluginList', (_: IpcRendererEvent, list: IPicGoPlugin[]) => {
|
||||
pluginList.value = list
|
||||
pluginNameList.value = list.map(item => item.fullName)
|
||||
for (const item of pluginList.value) {
|
||||
getLatestVersionOfPlugIn(item.fullName)
|
||||
}
|
||||
loading.value = false
|
||||
})
|
||||
ipcRenderer.on(
|
||||
'installPlugin',
|
||||
(
|
||||
_: IpcRendererEvent,
|
||||
{
|
||||
success,
|
||||
body
|
||||
}: {
|
||||
success: boolean
|
||||
body: string
|
||||
}
|
||||
) => {
|
||||
loading.value = false
|
||||
pluginList.value.forEach(item => {
|
||||
if (item.fullName === body) {
|
||||
item.ing = false
|
||||
item.hasInstall = success
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
ipcRenderer.on('updateSuccess', (_: IpcRendererEvent, plugin: string) => {
|
||||
loading.value = false
|
||||
pluginList.value.forEach(item => {
|
||||
if (item.fullName === plugin) {
|
||||
item.ing = false
|
||||
item.hasInstall = true
|
||||
}
|
||||
updatePicBedGlobal()
|
||||
})
|
||||
handleReload()
|
||||
getPluginList()
|
||||
})
|
||||
ipcRenderer.on('uninstallSuccess', (_: IpcRendererEvent, plugin: string) => {
|
||||
loading.value = false
|
||||
pluginList.value = pluginList.value.filter(item => {
|
||||
if (item.fullName === plugin) {
|
||||
// restore Uploader & Transformer after uninstalling
|
||||
if (item.config.transformer.name) {
|
||||
handleRestoreState('transformer', item.config.transformer.name)
|
||||
}
|
||||
if (item.config.uploader.name) {
|
||||
handleRestoreState('uploader', item.config.uploader.name)
|
||||
}
|
||||
updatePicBedGlobal()
|
||||
}
|
||||
return item.fullName !== plugin
|
||||
})
|
||||
pluginNameList.value = pluginNameList.value.filter(item => item !== plugin)
|
||||
})
|
||||
ipcRenderer.on(
|
||||
PICGO_CONFIG_PLUGIN,
|
||||
(_: IpcRendererEvent, _currentType: 'plugin' | 'transformer' | 'uploader', _configName: string, _config: any) => {
|
||||
currentType.value = _currentType
|
||||
configName.value = _configName
|
||||
config.value = _config
|
||||
dialogVisible.value = true
|
||||
}
|
||||
)
|
||||
ipcRenderer.on(PICGO_HANDLE_PLUGIN_ING, (_: IpcRendererEvent, fullName: string) => {
|
||||
pluginList.value.forEach(item => {
|
||||
if (item.fullName === fullName || item.name === fullName) {
|
||||
item.ing = true
|
||||
}
|
||||
})
|
||||
loading.value = true
|
||||
})
|
||||
ipcRenderer.on(PICGO_TOGGLE_PLUGIN, (_: IpcRendererEvent, fullName: string, enabled: boolean) => {
|
||||
const plugin = pluginList.value.find(item => item.fullName === fullName)
|
||||
if (plugin) {
|
||||
plugin.enabled = enabled
|
||||
updatePicBedGlobal()
|
||||
needReload.value = true
|
||||
}
|
||||
})
|
||||
window.electron.ipcRendererOn('hideLoading', hideLoadingHandler)
|
||||
window.electron.ipcRendererOn(PICGO_HANDLE_PLUGIN_DONE, picgoHandlePluginDoneHandler)
|
||||
window.electron.ipcRendererOn('pluginList', pluginListHandler)
|
||||
window.electron.ipcRendererOn('installPlugin', installPluginHandler)
|
||||
window.electron.ipcRendererOn('updateSuccess', updateSuccessHandler)
|
||||
window.electron.ipcRendererOn('uninstallSuccess', uninstallSuccessHandler)
|
||||
window.electron.ipcRendererOn(PICGO_CONFIG_PLUGIN, picgoConfigPluginHandler)
|
||||
window.electron.ipcRendererOn(PICGO_HANDLE_PLUGIN_ING, picgoHandlePluginIngHandler)
|
||||
window.electron.ipcRendererOn(PICGO_TOGGLE_PLUGIN, picgoTogglePluginHandler)
|
||||
getPluginList()
|
||||
getSearchResult = debounce(_getSearchResult, 50)
|
||||
needReload.value = (await getConfig<boolean>(configPaths.needReload)) || false
|
||||
})
|
||||
|
||||
async function buildContextMenu(plugin: IPicGoPlugin) {
|
||||
sendRPC(IRPCActionType.SHOW_PLUGIN_PAGE_MENU, plugin)
|
||||
async function buildContextMenu (plugin: IPicGoPlugin) {
|
||||
window.electron.sendRPC(IRPCActionType.SHOW_PLUGIN_PAGE_MENU, plugin)
|
||||
}
|
||||
|
||||
function handleResize() {
|
||||
function handleResize () {
|
||||
const myDiv = document.getElementById('pluginList') as HTMLElement
|
||||
const windowHeight = window.innerHeight
|
||||
const newHeight = windowHeight * 0.75
|
||||
@@ -317,11 +433,11 @@ onMounted(() => {
|
||||
window.addEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
function getPluginList() {
|
||||
sendRPC(IRPCActionType.PLUGIN_GET_LIST)
|
||||
function getPluginList () {
|
||||
window.electron.sendRPC(IRPCActionType.PLUGIN_GET_LIST)
|
||||
}
|
||||
|
||||
function installPlugin(item: IPicGoPlugin) {
|
||||
function installPlugin (item: IPicGoPlugin) {
|
||||
if (!item.gui) {
|
||||
$confirm($T('TIPS_PLUGIN_NOT_GUI_IMPLEMENT'), $T('TIPS_NOTICE'), {
|
||||
confirmButtonText: $T('CONFIRM'),
|
||||
@@ -330,22 +446,22 @@ function installPlugin(item: IPicGoPlugin) {
|
||||
})
|
||||
.then(() => {
|
||||
item.ing = true
|
||||
sendRPC(IRPCActionType.PLUGIN_INSTALL, item.fullName)
|
||||
window.electron.sendRPC(IRPCActionType.PLUGIN_INSTALL, item.fullName)
|
||||
})
|
||||
.catch(() => {
|
||||
console.log('Install canceled')
|
||||
})
|
||||
} else {
|
||||
item.ing = true
|
||||
sendRPC(IRPCActionType.PLUGIN_INSTALL, item.fullName)
|
||||
window.electron.sendRPC(IRPCActionType.PLUGIN_INSTALL, item.fullName)
|
||||
}
|
||||
}
|
||||
|
||||
function reloadApp() {
|
||||
sendRPC(IRPCActionType.RELOAD_APP)
|
||||
function reloadApp () {
|
||||
window.electron.sendRPC(IRPCActionType.RELOAD_APP)
|
||||
}
|
||||
|
||||
async function handleReload() {
|
||||
async function handleReload () {
|
||||
saveConfig({
|
||||
needReload: true
|
||||
})
|
||||
@@ -358,11 +474,11 @@ async function handleReload() {
|
||||
}
|
||||
}
|
||||
|
||||
function cleanSearch() {
|
||||
function cleanSearch () {
|
||||
searchText.value = ''
|
||||
}
|
||||
|
||||
async function handleConfirmConfig() {
|
||||
async function handleConfirmConfig () {
|
||||
const result = (await $configForm.value?.validate()) || false
|
||||
if (result !== false) {
|
||||
switch (currentType.value) {
|
||||
@@ -393,8 +509,8 @@ async function handleConfirmConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
function _getSearchResult(val: string) {
|
||||
axios
|
||||
function _getSearchResult (val: string) {
|
||||
window.node.axios
|
||||
.get(`https://registry.npmjs.com/-/v1/search?text=${val}`)
|
||||
.then((res: INPMSearchResult) => {
|
||||
pluginList.value = res.data.objects
|
||||
@@ -412,7 +528,7 @@ function _getSearchResult(val: string) {
|
||||
})
|
||||
}
|
||||
|
||||
function handleSearchResult(item: INPMSearchResultObject) {
|
||||
function handleSearchResult (item: INPMSearchResultObject) {
|
||||
const pkg = item.package
|
||||
const name = handleStreamlinePluginName(pkg.name)
|
||||
let gui = false
|
||||
@@ -437,7 +553,7 @@ function handleSearchResult(item: INPMSearchResultObject) {
|
||||
}
|
||||
|
||||
// restore Uploader & Transformer
|
||||
async function handleRestoreState(item: string, name: string) {
|
||||
async function handleRestoreState (item: string, name: string) {
|
||||
if (item === 'uploader') {
|
||||
const current = await getConfig(configPaths.picBed.current)
|
||||
if (current === name) {
|
||||
@@ -457,33 +573,36 @@ async function handleRestoreState(item: string, name: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function openHomepage(url: string) {
|
||||
function openHomepage (url: string) {
|
||||
if (url) {
|
||||
sendRPC(IRPCActionType.OPEN_URL, url)
|
||||
window.electron.sendRPC(IRPCActionType.OPEN_URL, url)
|
||||
}
|
||||
}
|
||||
|
||||
function goAwesomeList() {
|
||||
sendRPC(IRPCActionType.OPEN_URL, 'https://github.com/PicGo/Awesome-PicGo')
|
||||
function goAwesomeList () {
|
||||
window.electron.sendRPC(IRPCActionType.OPEN_URL, 'https://github.com/PicGo/Awesome-PicGo')
|
||||
}
|
||||
|
||||
function handleImportLocalPlugin() {
|
||||
sendRPC(IRPCActionType.PLUGIN_IMPORT_LOCAL)
|
||||
function handleImportLocalPlugin () {
|
||||
window.electron.sendRPC(IRPCActionType.PLUGIN_IMPORT_LOCAL)
|
||||
loading.value = true
|
||||
}
|
||||
|
||||
function handleUpdateAllPlugin() {
|
||||
sendRPC(IRPCActionType.PLUGIN_UPDATE_ALL, toRaw(pluginNameList.value))
|
||||
function handleUpdateAllPlugin () {
|
||||
window.electron.sendRPC(IRPCActionType.PLUGIN_UPDATE_ALL, toRaw(pluginNameList.value))
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
ipcRenderer.removeAllListeners('pluginList')
|
||||
ipcRenderer.removeAllListeners('installPlugin')
|
||||
ipcRenderer.removeAllListeners('uninstallSuccess')
|
||||
ipcRenderer.removeAllListeners('updateSuccess')
|
||||
ipcRenderer.removeAllListeners('hideLoading')
|
||||
ipcRenderer.removeAllListeners(PICGO_HANDLE_PLUGIN_DONE)
|
||||
window.electron.ipcRendererRemoveListener('pluginList', pluginListHandler)
|
||||
window.electron.ipcRendererRemoveListener('installPlugin', installPluginHandler)
|
||||
window.electron.ipcRendererRemoveListener('uninstallSuccess', uninstallSuccessHandler)
|
||||
window.electron.ipcRendererRemoveListener('updateSuccess', updateSuccessHandler)
|
||||
window.electron.ipcRendererRemoveListener('hideLoading', hideLoadingHandler)
|
||||
window.electron.ipcRendererRemoveListener(PICGO_HANDLE_PLUGIN_DONE, picgoHandlePluginDoneHandler)
|
||||
window.electron.ipcRendererRemoveListener(PICGO_CONFIG_PLUGIN, picgoConfigPluginHandler)
|
||||
window.electron.ipcRendererRemoveListener(PICGO_HANDLE_PLUGIN_ING, picgoHandlePluginIngHandler)
|
||||
window.electron.ipcRendererRemoveListener(PICGO_TOGGLE_PLUGIN, picgoTogglePluginHandler)
|
||||
})
|
||||
</script>
|
||||
<script lang="ts">
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
<template>
|
||||
<div id="rename-page">
|
||||
<el-form ref="formRef" :model="form" @submit.prevent>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-form-item
|
||||
:label="$T('FILE_RENAME')"
|
||||
prop="fileName"
|
||||
:rules="[{ required: true, message: 'file name is required', trigger: 'blur' }]"
|
||||
>
|
||||
<el-input v-model="form.fileName" size="small" autofocus @keyup.enter="confirmName">
|
||||
<el-input
|
||||
v-model="form.fileName"
|
||||
size="small"
|
||||
autofocus
|
||||
@keyup.enter="confirmName"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon class="el-input__icon" style="cursor: pointer" @click="form.fileName = ''">
|
||||
<el-icon
|
||||
class="el-input__icon"
|
||||
style="cursor: pointer"
|
||||
@click="form.fileName = ''"
|
||||
>
|
||||
<close />
|
||||
</el-icon>
|
||||
</template>
|
||||
@@ -17,10 +30,19 @@
|
||||
</el-form>
|
||||
<el-row>
|
||||
<div class="pull-right">
|
||||
<el-button round size="small" @click="cancel">
|
||||
<el-button
|
||||
round
|
||||
size="small"
|
||||
@click="cancel"
|
||||
>
|
||||
{{ $T('CANCEL') }}
|
||||
</el-button>
|
||||
<el-button type="primary" round size="small" @click="confirmName">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
size="small"
|
||||
@click="confirmName"
|
||||
>
|
||||
{{ $T('CONFIRM') }}
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -29,15 +51,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ipcRenderer, IpcRendererEvent } from 'electron'
|
||||
import { FormInstance } from 'element-plus'
|
||||
import { Close } from '@element-plus/icons-vue'
|
||||
import { onBeforeUnmount, onBeforeMount, ref, reactive } from 'vue'
|
||||
import type { IpcRendererEvent } from 'electron'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue'
|
||||
|
||||
import { useIPCOn } from '@/hooks/useIPC'
|
||||
import { T as $T } from '@/i18n/index'
|
||||
import { sendToMain } from '@/utils/common'
|
||||
|
||||
import { GET_RENAME_FILE_NAME, RENAME_FILE_NAME } from '#/events/constants'
|
||||
|
||||
const id = ref<string | null>(null)
|
||||
@@ -54,27 +73,27 @@ const handleFileName = (_: IpcRendererEvent, newName: string, _originName: strin
|
||||
id.value = _id
|
||||
}
|
||||
|
||||
useIPCOn(RENAME_FILE_NAME, handleFileName)
|
||||
window.electron.ipcRendererOn(RENAME_FILE_NAME, handleFileName)
|
||||
|
||||
onBeforeMount(() => {
|
||||
ipcRenderer.send(GET_RENAME_FILE_NAME)
|
||||
window.electron.sendToMain(GET_RENAME_FILE_NAME, '')
|
||||
})
|
||||
|
||||
function confirmName() {
|
||||
function confirmName () {
|
||||
formRef.value?.validate(valid => {
|
||||
if (valid) {
|
||||
sendToMain(`${RENAME_FILE_NAME}${id.value}`, form.fileName)
|
||||
window.electron.sendToMain(`${RENAME_FILE_NAME}${id.value}`, form.fileName)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
function cancel () {
|
||||
// if cancel, use origin file name
|
||||
sendToMain(`${RENAME_FILE_NAME}${id.value}`, form.originName)
|
||||
window.electron.sendToMain(`${RENAME_FILE_NAME}${id.value}`, form.originName)
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
ipcRenderer.removeAllListeners(RENAME_FILE_NAME)
|
||||
window.electron.ipcRendererRemoveListener(RENAME_FILE_NAME, handleFileName)
|
||||
})
|
||||
</script>
|
||||
<script lang="ts">
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
{{ $T('SETTINGS_SET_SHORTCUT') }}
|
||||
</div>
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="2">
|
||||
<el-col
|
||||
:span="20"
|
||||
:offset="2"
|
||||
>
|
||||
<el-table
|
||||
class="shortcut-page-table-border"
|
||||
:data="list"
|
||||
@@ -17,20 +20,33 @@
|
||||
{{ scope.row.label ? scope.row.label : scope.row.name }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="160px" :label="$T('SHORTCUT_BIND')" prop="key" />
|
||||
<el-table-column
|
||||
width="160px"
|
||||
:label="$T('SHORTCUT_BIND')"
|
||||
prop="key"
|
||||
/>
|
||||
<el-table-column :label="$T('SHORTCUT_STATUS')">
|
||||
<template #default="scope">
|
||||
<el-tag size="small" :type="scope.row.enable ? 'success' : 'danger'">
|
||||
<el-tag
|
||||
size="small"
|
||||
:type="scope.row.enable ? 'success' : 'danger'"
|
||||
>
|
||||
{{ scope.row.enable ? $T('SHORTCUT_ENABLED') : $T('SHORTCUT_DISABLED') }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$T('SHORTCUT_SOURCE')" width="100px">
|
||||
<el-table-column
|
||||
:label="$T('SHORTCUT_SOURCE')"
|
||||
width="100px"
|
||||
>
|
||||
<template #default="scope">
|
||||
{{ calcOriginShowName(scope.row.from) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$T('SHORTCUT_HANDLE')" width="100px">
|
||||
<el-table-column
|
||||
:label="$T('SHORTCUT_HANDLE')"
|
||||
width="100px"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-row>
|
||||
<el-button
|
||||
@@ -65,7 +81,10 @@
|
||||
:modal-append-to-body="false"
|
||||
append-to-body
|
||||
>
|
||||
<el-form label-position="top" label-width="80px">
|
||||
<el-form
|
||||
label-position="top"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item>
|
||||
<el-input
|
||||
v-model="shortKey"
|
||||
@@ -76,10 +95,17 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button round @click="cancelKeyBinding">
|
||||
<el-button
|
||||
round
|
||||
@click="cancelKeyBinding"
|
||||
>
|
||||
{{ $T('CANCEL') }}
|
||||
</el-button>
|
||||
<el-button type="primary" round @click="confirmKeyBinding">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
@click="confirmKeyBinding"
|
||||
>
|
||||
{{ $T('CONFIRM') }}
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -88,15 +114,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeUnmount, onBeforeMount, ref, watch } from 'vue'
|
||||
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
|
||||
|
||||
import { T as $T } from '@/i18n'
|
||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||
import { getConfig } from '@/utils/dataSender'
|
||||
import keyBinding from '@/utils/key-binding'
|
||||
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
import { IRPCActionType } from '#/types/enum'
|
||||
import { IShortKeyConfig, IShortKeyConfigs } from '#/types/types'
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
|
||||
const list = ref<IShortKeyConfig[]>([])
|
||||
const keyBindingVisible = ref(false)
|
||||
@@ -115,45 +140,45 @@ onBeforeMount(async () => {
|
||||
})
|
||||
|
||||
watch(keyBindingVisible, (val: boolean) => {
|
||||
sendRPC(IRPCActionType.SHORTKEY_TOGGLE_SHORTKEY_MODIFIED_MODE, val)
|
||||
window.electron.sendRPC(IRPCActionType.SHORTKEY_TOGGLE_SHORTKEY_MODIFIED_MODE, val)
|
||||
})
|
||||
|
||||
function calcOrigin(item: string) {
|
||||
function calcOrigin (item: string) {
|
||||
const [origin] = item.split(':')
|
||||
return origin
|
||||
}
|
||||
|
||||
function calcOriginShowName(item: string) {
|
||||
function calcOriginShowName (item: string) {
|
||||
return item.replace('picgo-plugin-', '')
|
||||
}
|
||||
|
||||
function toggleEnable(item: IShortKeyConfig) {
|
||||
function toggleEnable (item: IShortKeyConfig) {
|
||||
const status = !item.enable
|
||||
item.enable = status
|
||||
sendRPC(IRPCActionType.SHORTKEY_BIND_OR_UNBIND, item, item.from)
|
||||
window.electron.sendRPC(IRPCActionType.SHORTKEY_BIND_OR_UNBIND, item, item.from)
|
||||
}
|
||||
|
||||
function keyDetect(event: KeyboardEvent) {
|
||||
function keyDetect (event: KeyboardEvent) {
|
||||
shortKey.value = keyBinding(event).join('+')
|
||||
}
|
||||
|
||||
async function openKeyBindingDialog(config: IShortKeyConfig, index: number) {
|
||||
async function openKeyBindingDialog (config: IShortKeyConfig, index: number) {
|
||||
command.value = `${config.from}:${config.name}`
|
||||
shortKey.value = (await getConfig(`settings.shortKey.${command.value}.key`)) || ''
|
||||
currentIndex.value = index
|
||||
keyBindingVisible.value = true
|
||||
}
|
||||
|
||||
async function cancelKeyBinding() {
|
||||
async function cancelKeyBinding () {
|
||||
keyBindingVisible.value = false
|
||||
shortKey.value = (await getConfig<string>(`settings.shortKey.${command.value}.key`)) || ''
|
||||
}
|
||||
|
||||
async function confirmKeyBinding() {
|
||||
async function confirmKeyBinding () {
|
||||
const oldKey = await getConfig<string>(`settings.shortKey.${command.value}.key`)
|
||||
const config = Object.assign({}, list.value[currentIndex.value])
|
||||
const config = { ...list.value[currentIndex.value] }
|
||||
config.key = shortKey.value
|
||||
const result = await triggerRPC<boolean>(IRPCActionType.SHORTKEY_UPDATE, config, oldKey, config.from)
|
||||
const result = await window.electron.triggerRPC<boolean>(IRPCActionType.SHORTKEY_UPDATE, config, oldKey, config.from)
|
||||
if (result) {
|
||||
keyBindingVisible.value = false
|
||||
list.value[currentIndex.value].key = shortKey.value
|
||||
@@ -161,7 +186,7 @@ async function confirmKeyBinding() {
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
sendRPC(IRPCActionType.SHORTKEY_TOGGLE_SHORTKEY_MODIFIED_MODE, false)
|
||||
window.electron.sendRPC(IRPCActionType.SHORTKEY_TOGGLE_SHORTKEY_MODIFIED_MODE, false)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
<el-row>
|
||||
<el-row class="toolbox-header">
|
||||
<el-row>
|
||||
<img class="toolbox-header__logo" :src="defaultLogo" />
|
||||
<img
|
||||
class="toolbox-header__logo"
|
||||
:src="defaultLogo"
|
||||
>
|
||||
<el-row class="toolbox-header__text">
|
||||
<el-row class="toolbox-header__title">
|
||||
{{ $T('TOOLBOX_TITLE') }}
|
||||
@@ -15,7 +18,12 @@
|
||||
</el-row>
|
||||
<el-row>
|
||||
<template v-if="progress !== 100">
|
||||
<el-button type="primary" round :disabled="isLoading" @click="handleCheck">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
:disabled="isLoading"
|
||||
@click="handleCheck"
|
||||
>
|
||||
{{ $T('TOOLBOX_START_SCAN') }}
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -26,14 +34,23 @@
|
||||
</template>
|
||||
<template v-else-if="!isAllSuccess">
|
||||
<template v-if="canFixLength !== 0">
|
||||
<el-button type="primary" round @click="handleFix">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
@click="handleFix"
|
||||
>
|
||||
{{ $T('TOOLBOX_START_FIX') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="toolbox-cant-fix toolbox-tips">
|
||||
{{ $T('TOOLBOX_CANT_AUTO_FIX') }}
|
||||
<el-button type="primary" round class="toolbox-cant-fix__btn" @click="handleCheck">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
class="toolbox-cant-fix__btn"
|
||||
@click="handleCheck"
|
||||
>
|
||||
{{ $T('TOOLBOX_RE_SCAN') }}
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -43,11 +60,23 @@
|
||||
</el-row>
|
||||
</el-row>
|
||||
<el-row class="progress">
|
||||
<el-progress :percentage="progress" :format="format" />
|
||||
<el-progress
|
||||
:percentage="progress"
|
||||
:format="format"
|
||||
/>
|
||||
</el-row>
|
||||
<el-collapse v-model="activeTypes" accordion>
|
||||
<el-collapse-item v-for="(item, key) in fixList" :key="key" :name="key">
|
||||
<template #title> {{ item.title }} <toolbox-status-icon :status="item.status" /> </template>
|
||||
<el-collapse
|
||||
v-model="activeTypes"
|
||||
accordion
|
||||
>
|
||||
<el-collapse-item
|
||||
v-for="(item, key) in fixList"
|
||||
:key="key"
|
||||
:name="key"
|
||||
>
|
||||
<template #title>
|
||||
{{ item.title }} <toolbox-status-icon :status="item.status" />
|
||||
</template>
|
||||
<div class="toolbox-item-msg">
|
||||
{{ item.msg || '' }}
|
||||
<template v-if="item.handler && item.handlerText && item.value">
|
||||
@@ -66,26 +95,25 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { IToolboxCheckRes } from 'root/src/universal/types/rpc'
|
||||
import { IToolboxMap } from 'root/src/universal/types/view'
|
||||
import { computed, onUnmounted, reactive, ref } from 'vue'
|
||||
|
||||
import ToolboxStatusIcon from '@/components/ToolboxStatusIcon.vue'
|
||||
import ToolboxHandler from '@/components/ToolboxHandler.vue'
|
||||
import { useIPC } from '@/hooks/useIPC'
|
||||
import ToolboxStatusIcon from '@/components/ToolboxStatusIcon.vue'
|
||||
import { T as $T } from '@/i18n'
|
||||
|
||||
import { IToolboxItemType, IToolboxItemCheckStatus, IRPCActionType } from '#/types/enum'
|
||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||
import { IRPCActionType, IToolboxItemCheckStatus, IToolboxItemType } from '#/types/enum'
|
||||
|
||||
const $confirm = ElMessageBox.confirm
|
||||
const defaultLogo = ref(`file://${__static.replace(/\\/g, '/')}/roundLogo.png`)
|
||||
const defaultLogo = ref('/roundLogo.png')
|
||||
const activeTypes = ref<IToolboxItemType[]>([])
|
||||
const fixList = reactive<IToolboxMap>({
|
||||
[IToolboxItemType.IS_CONFIG_FILE_BROKEN]: {
|
||||
title: $T('TOOLBOX_CHECK_CONFIG_FILE_BROKEN'),
|
||||
status: IToolboxItemCheckStatus.INIT,
|
||||
handlerText: $T('SETTINGS_OPEN_CONFIG_FILE'),
|
||||
handler(value: string) {
|
||||
sendRPC(IRPCActionType.OPEN_FILE, value)
|
||||
handler (value: string) {
|
||||
window.electron.sendRPC(IRPCActionType.OPEN_FILE, value)
|
||||
}
|
||||
},
|
||||
[IToolboxItemType.IS_GALLERY_FILE_BROKEN]: {
|
||||
@@ -96,8 +124,8 @@ const fixList = reactive<IToolboxMap>({
|
||||
title: $T('TOOLBOX_CHECK_PROBLEM_WITH_CLIPBOARD_PIC_UPLOAD'), // picgo-image-clipboard folder
|
||||
status: IToolboxItemCheckStatus.INIT,
|
||||
handlerText: $T('OPEN_FILE_PATH'),
|
||||
handler(value: string) {
|
||||
sendRPC(IRPCActionType.OPEN_FILE, value)
|
||||
handler (value: string) {
|
||||
window.electron.sendRPC(IRPCActionType.OPEN_FILE, value)
|
||||
}
|
||||
},
|
||||
[IToolboxItemType.HAS_PROBLEM_WITH_PROXY]: {
|
||||
@@ -139,16 +167,16 @@ const canFixLength = computed(() => {
|
||||
|
||||
const format = (_percentage: number) => ''
|
||||
|
||||
const ipc = useIPC()
|
||||
|
||||
ipc.on(IRPCActionType.TOOLBOX_CHECK_RES, (_event: any, { type, msg = '', status, value = '' }: IToolboxCheckRes) => {
|
||||
const toolboxCheckResHandler = (_event: any, { type, msg = '', status, value = '' }: IToolboxCheckRes) => {
|
||||
fixList[type].status = status
|
||||
fixList[type].msg = msg
|
||||
fixList[type].value = value
|
||||
if (status === IToolboxItemCheckStatus.ERROR) {
|
||||
activeTypes.value.push(type)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
window.electron.ipcRendererOn(IRPCActionType.TOOLBOX_CHECK_RES, toolboxCheckResHandler)
|
||||
|
||||
const handleCheck = () => {
|
||||
activeTypes.value = []
|
||||
@@ -157,7 +185,7 @@ const handleCheck = () => {
|
||||
fixList[key as IToolboxItemType].msg = ''
|
||||
fixList[key as IToolboxItemType].value = ''
|
||||
})
|
||||
sendRPC(IRPCActionType.TOOLBOX_CHECK)
|
||||
window.electron.sendRPC(IRPCActionType.TOOLBOX_CHECK)
|
||||
}
|
||||
|
||||
const handleFix = async () => {
|
||||
@@ -168,7 +196,7 @@ const handleFix = async () => {
|
||||
return status === IToolboxItemCheckStatus.ERROR && !fixList[key as IToolboxItemType].hasNoFixMethod
|
||||
})
|
||||
.map(async key => {
|
||||
return triggerRPC<IToolboxCheckRes>(IRPCActionType.TOOLBOX_CHECK_FIX, key as IToolboxItemType)
|
||||
return window.electron.triggerRPC<IToolboxCheckRes>(IRPCActionType.TOOLBOX_CHECK_FIX, key as IToolboxItemType)
|
||||
})
|
||||
)
|
||||
|
||||
@@ -188,10 +216,14 @@ const handleFix = async () => {
|
||||
type: 'info'
|
||||
})
|
||||
.then(() => {
|
||||
sendRPC(IRPCActionType.RELOAD_APP)
|
||||
window.electron.sendRPC(IRPCActionType.RELOAD_APP)
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
window.electron.ipcRendererRemoveListener(IRPCActionType.TOOLBOX_CHECK_RES, toolboxCheckResHandler)
|
||||
})
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
<template>
|
||||
<div id="tray-page">
|
||||
<div class="open-main-window" @click="openSettingWindow">
|
||||
<div
|
||||
class="open-main-window"
|
||||
@click="openSettingWindow"
|
||||
>
|
||||
{{ $T('OPEN_MAIN_WINDOW') }}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div v-if="clipboardFiles.length > 0" class="wait-upload-img">
|
||||
<div
|
||||
v-if="clipboardFiles.length > 0"
|
||||
class="wait-upload-img"
|
||||
>
|
||||
<div class="list-title">
|
||||
{{ $T('WAIT_TO_UPLOAD') }}
|
||||
</div>
|
||||
<div v-for="(item, index) in clipboardFiles" :key="index" class="img-list">
|
||||
<div class="upload-img__container" :class="{ upload: uploadFlag }" @click="uploadClipboardFiles">
|
||||
<img :src="item.imgUrl" class="upload-img" />
|
||||
<div
|
||||
v-for="(item, index) in clipboardFiles"
|
||||
:key="index"
|
||||
class="img-list"
|
||||
>
|
||||
<div
|
||||
class="upload-img__container"
|
||||
:class="{ upload: uploadFlag }"
|
||||
@click="uploadClipboardFiles"
|
||||
>
|
||||
<img
|
||||
:src="item.imgUrl"
|
||||
class="upload-img"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -18,10 +35,23 @@
|
||||
<div class="list-title">
|
||||
{{ $T('ALREADY_UPLOAD') }}
|
||||
</div>
|
||||
<div v-for="item in files" :key="item.imgUrl" class="img-list">
|
||||
<div class="upload-img__container" @click="copyTheLink(item)">
|
||||
<img v-lazy="item.imgUrl" class="upload-img" />
|
||||
<div class="upload-img__title" :title="item.fileName">
|
||||
<div
|
||||
v-for="item in files"
|
||||
:key="item.imgUrl"
|
||||
class="img-list"
|
||||
>
|
||||
<div
|
||||
class="upload-img__container"
|
||||
@click="copyTheLink(item)"
|
||||
>
|
||||
<img
|
||||
v-lazy="item.imgUrl"
|
||||
class="upload-img"
|
||||
>
|
||||
<div
|
||||
class="upload-img__title"
|
||||
:title="item.fileName"
|
||||
>
|
||||
{{ item.fileName }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -32,20 +62,22 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { clipboard, ipcRenderer } from 'electron'
|
||||
import { reactive, ref, onBeforeUnmount, onBeforeMount } from 'vue'
|
||||
import { IResult } from '@picgo/store/dist/types'
|
||||
import type { IpcRendererEvent } from 'electron'
|
||||
import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue'
|
||||
|
||||
import { T as $T } from '@/i18n/index'
|
||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||
import { getConfig } from '@/utils/dataSender'
|
||||
|
||||
import $$db from '@/utils/db'
|
||||
|
||||
import { IPasteStyle, IRPCActionType, IWindowList } from '#/types/enum'
|
||||
import { ImgInfo } from '#/types/types'
|
||||
import { handleUrlEncode } from '#/utils/common'
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
|
||||
type IResult<T> = T & {
|
||||
id: string
|
||||
createdAt: number
|
||||
updatedAt: number
|
||||
}
|
||||
const files = ref<IResult<ImgInfo>[]>([])
|
||||
const notification = reactive({
|
||||
title: $T('COPY_LINK_SUCCEED'),
|
||||
@@ -55,11 +87,11 @@ const notification = reactive({
|
||||
const clipboardFiles = ref<ImgInfo[]>([])
|
||||
const uploadFlag = ref(false)
|
||||
|
||||
function openSettingWindow() {
|
||||
sendRPC(IRPCActionType.OPEN_WINDOW, IWindowList.SETTING_WINDOW)
|
||||
function openSettingWindow () {
|
||||
window.electron.sendRPC(IRPCActionType.OPEN_WINDOW, IWindowList.SETTING_WINDOW)
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
async function getData () {
|
||||
files.value = (await $$db.get<ImgInfo>({ orderBy: 'desc', limit: 5 }))!.data
|
||||
}
|
||||
|
||||
@@ -82,18 +114,18 @@ const formatCustomLink = (customLink: string, item: ImgInfo) => {
|
||||
return customLink
|
||||
}
|
||||
|
||||
async function copyTheLink(item: ImgInfo) {
|
||||
async function copyTheLink (item: ImgInfo) {
|
||||
const pasteStyle = (await getConfig<IPasteStyle>(configPaths.settings.pasteStyle)) || IPasteStyle.MARKDOWN
|
||||
const customLink = await getConfig<string>(configPaths.settings.customLink)
|
||||
const txt = await pasteTemplate(pasteStyle, item, customLink)
|
||||
clipboard.writeText(txt)
|
||||
window.electron.clipboard.writeText(txt)
|
||||
const myNotification = new Notification(notification.title, notification)
|
||||
myNotification.onclick = () => {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
async function pasteTemplate(style: IPasteStyle, item: ImgInfo, customLink: string | undefined) {
|
||||
async function pasteTemplate (style: IPasteStyle, item: ImgInfo, customLink: string | undefined) {
|
||||
let url = item.url || item.imgUrl
|
||||
if (item.type === 'aws-s3' || item.type === 'aws-s3-plist') {
|
||||
url = item.imgUrl || item.url || ''
|
||||
@@ -103,7 +135,7 @@ async function pasteTemplate(style: IPasteStyle, item: ImgInfo, customLink: stri
|
||||
}
|
||||
const useShortUrl = (await getConfig(configPaths.settings.useShortUrl)) || false
|
||||
if (useShortUrl) {
|
||||
url = (await triggerRPC<string>(IRPCActionType.TRAY_GET_SHORT_URL, url)) || url
|
||||
url = (await window.electron.triggerRPC<string>(IRPCActionType.TRAY_GET_SHORT_URL, url)) || url
|
||||
}
|
||||
notification.body = url
|
||||
const _customLink = customLink || ''
|
||||
@@ -120,7 +152,7 @@ async function pasteTemplate(style: IPasteStyle, item: ImgInfo, customLink: stri
|
||||
return tpl[style]
|
||||
}
|
||||
|
||||
function disableDragFile() {
|
||||
function disableDragFile () {
|
||||
window.addEventListener(
|
||||
'dragover',
|
||||
e => {
|
||||
@@ -139,47 +171,54 @@ function disableDragFile() {
|
||||
)
|
||||
}
|
||||
|
||||
function uploadClipboardFiles() {
|
||||
function uploadClipboardFiles () {
|
||||
if (uploadFlag.value) {
|
||||
return
|
||||
}
|
||||
uploadFlag.value = true
|
||||
sendRPC(IRPCActionType.TRAY_UPLOAD_CLIPBOARD_FILES)
|
||||
window.electron.sendRPC(IRPCActionType.TRAY_UPLOAD_CLIPBOARD_FILES)
|
||||
}
|
||||
|
||||
const dragFilesHandler = async (_: IpcRendererEvent, _files: string[]) => {
|
||||
for (const file of _files) {
|
||||
await $$db.insert(file)
|
||||
}
|
||||
files.value = (await $$db.get<ImgInfo>({
|
||||
orderBy: 'desc',
|
||||
limit: 5
|
||||
}))!.data
|
||||
}
|
||||
|
||||
const clipboardFilesHandler = (_: IpcRendererEvent, files: ImgInfo[]) => {
|
||||
clipboardFiles.value = files
|
||||
}
|
||||
|
||||
const uploadFilesHandler = async () => {
|
||||
files.value = (await $$db.get<ImgInfo>({
|
||||
orderBy: 'desc',
|
||||
limit: 5
|
||||
}))!.data
|
||||
uploadFlag.value = false
|
||||
}
|
||||
|
||||
const updateFilesHandler = () => {
|
||||
getData()
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
disableDragFile()
|
||||
getData()
|
||||
ipcRenderer.on('dragFiles', async (_: Event, _files: string[]) => {
|
||||
for (let i = 0; i < _files.length; i++) {
|
||||
const item = _files[i]
|
||||
await $$db.insert(item)
|
||||
}
|
||||
files.value = (await $$db.get<ImgInfo>({
|
||||
orderBy: 'desc',
|
||||
limit: 5
|
||||
}))!.data
|
||||
})
|
||||
ipcRenderer.on('clipboardFiles', (_: Event, files: ImgInfo[]) => {
|
||||
clipboardFiles.value = files
|
||||
})
|
||||
ipcRenderer.on('uploadFiles', async () => {
|
||||
files.value = (await $$db.get<ImgInfo>({
|
||||
orderBy: 'desc',
|
||||
limit: 5
|
||||
}))!.data
|
||||
uploadFlag.value = false
|
||||
})
|
||||
ipcRenderer.on('updateFiles', () => {
|
||||
getData()
|
||||
})
|
||||
window.electron.ipcRendererOn('dragFiles', dragFilesHandler)
|
||||
window.electron.ipcRendererOn('clipboardFiles', clipboardFilesHandler)
|
||||
window.electron.ipcRendererOn('uploadFiles', uploadFilesHandler)
|
||||
window.electron.ipcRendererOn('updateFiles', updateFilesHandler)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
ipcRenderer.removeAllListeners('dragFiles')
|
||||
ipcRenderer.removeAllListeners('clipboardFiles')
|
||||
ipcRenderer.removeAllListeners('uploadFiles')
|
||||
ipcRenderer.removeAllListeners('updateFiles')
|
||||
window.electron.ipcRendererRemoveListener('dragFiles', dragFilesHandler)
|
||||
window.electron.ipcRendererRemoveListener('clipboardFiles', clipboardFilesHandler)
|
||||
window.electron.ipcRendererRemoveListener('uploadFiles', uploadFilesHandler)
|
||||
window.electron.ipcRendererRemoveListener('updateFiles', updateFilesHandler)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
<template>
|
||||
<div id="upload-view">
|
||||
<el-row :gutter="16" align="middle">
|
||||
<el-row
|
||||
:gutter="16"
|
||||
align="middle"
|
||||
>
|
||||
<el-col :span="24">
|
||||
<div class="view-title">
|
||||
<el-tooltip placement="top" effect="light" :content="$T('UPLOAD_VIEW_HINT')" :persistent="false" teleported>
|
||||
<span id="upload-view-title" @click="handlePicBedNameClick(picBedName, picBedConfigName)">
|
||||
<el-tooltip
|
||||
placement="top"
|
||||
effect="light"
|
||||
:content="$T('UPLOAD_VIEW_HINT')"
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<span
|
||||
id="upload-view-title"
|
||||
@click="handlePicBedNameClick(picBedName, picBedConfigName)"
|
||||
>
|
||||
{{ picBedName }} - {{ picBedConfigName || 'Default' }}
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<el-icon style="cursor: pointer; margin-left: 4px" @click="handleChangePicBed">
|
||||
<el-icon
|
||||
style="cursor: pointer; margin-left: 4px"
|
||||
@click="handleChangePicBed"
|
||||
>
|
||||
<CaretBottom />
|
||||
</el-icon>
|
||||
<el-button
|
||||
@@ -29,7 +44,10 @@
|
||||
@dragover.prevent="dragover = true"
|
||||
@dragleave.prevent="dragover = false"
|
||||
>
|
||||
<div id="upload-dragger" @click="openUplodWindow">
|
||||
<div
|
||||
id="upload-dragger"
|
||||
@click="openUplodWindow"
|
||||
>
|
||||
<el-icon>
|
||||
<UploadFilled />
|
||||
</el-icon>
|
||||
@@ -37,7 +55,12 @@
|
||||
{{ $T('DRAG_FILE_TO_HERE') }}
|
||||
<span>{{ $T('CLICK_TO_UPLOAD') }}</span>
|
||||
</div>
|
||||
<input id="file-uploader" type="file" multiple @change="onChange" />
|
||||
<input
|
||||
id="file-uploader"
|
||||
type="file"
|
||||
multiple
|
||||
@change="onChange"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<el-progress
|
||||
@@ -52,16 +75,35 @@
|
||||
<div class="paste-style__text">
|
||||
{{ $T('LINK_FORMAT') }}
|
||||
</div>
|
||||
<el-radio-group v-model="pasteStyle" size="small" @change="handlePasteStyleChange">
|
||||
<el-radio-button v-for="(item, key) in pasteFormatList" :key="key" :value="key" :title="item">
|
||||
<el-radio-group
|
||||
v-model="pasteStyle"
|
||||
size="small"
|
||||
@change="handlePasteStyleChange"
|
||||
>
|
||||
<el-radio-button
|
||||
v-for="(item, key) in pasteFormatList"
|
||||
:key="key"
|
||||
:value="key"
|
||||
:title="item"
|
||||
>
|
||||
{{ key }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-radio-group v-model="useShortUrl" size="small" @change="handleUseShortUrlChange">
|
||||
<el-radio-button :value="true" style="border-radius: 5px">
|
||||
<el-radio-group
|
||||
v-model="useShortUrl"
|
||||
size="small"
|
||||
@change="handleUseShortUrlChange"
|
||||
>
|
||||
<el-radio-button
|
||||
:value="true"
|
||||
style="border-radius: 5px"
|
||||
>
|
||||
{{ $T('UPLOAD_SHORT_URL') }}
|
||||
</el-radio-button>
|
||||
<el-radio-button :value="false" style="border-radius: 5px">
|
||||
<el-radio-button
|
||||
:value="false"
|
||||
style="border-radius: 5px"
|
||||
>
|
||||
{{ $T('UPLOAD_NORMAL_URL') }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
@@ -109,25 +151,24 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ipcRenderer, IpcRendererEvent } from 'electron'
|
||||
import { CaretBottom, UploadFilled } from '@element-plus/icons-vue'
|
||||
import type { IpcRendererEvent } from 'electron'
|
||||
import { ElMessage as $message } from 'element-plus'
|
||||
import { UploadFilled, CaretBottom } from '@element-plus/icons-vue'
|
||||
import { ref, onBeforeMount, onBeforeUnmount, watch } from 'vue'
|
||||
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import ImageProcessSetting from '@/components/ImageProcessSetting.vue'
|
||||
import { T as $T } from '@/i18n'
|
||||
import { PICBEDS_PAGE } from '@/router/config'
|
||||
import $bus from '@/utils/bus'
|
||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||
import { getConfig, saveConfig } from '@/utils/dataSender'
|
||||
import { useDragEventListeners } from '@/utils/drag'
|
||||
import { picBedGlobal, updatePicBedGlobal } from '@/utils/global'
|
||||
|
||||
import { SHOW_INPUT_BOX, SHOW_INPUT_BOX_RESPONSE } from '#/events/constants'
|
||||
import { IPasteStyle, IRPCActionType } from '#/types/enum'
|
||||
import { IFileWithPath, IUploaderConfigItem } from '#/types/types'
|
||||
import { isUrl } from '#/utils/common'
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
import { useDragEventListeners } from '@/utils/drag'
|
||||
|
||||
useDragEventListeners()
|
||||
const $router = useRouter()
|
||||
@@ -154,23 +195,27 @@ watch(picBedGlobal, () => {
|
||||
getDefaultPicBed()
|
||||
})
|
||||
|
||||
const uploadProgressHandler = (_event: IpcRendererEvent, _progress: number) => {
|
||||
if (_progress !== -1) {
|
||||
showProgress.value = true
|
||||
progress.value = _progress
|
||||
} else {
|
||||
progress.value = 100
|
||||
showError.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const syncPicBedHandler = () => {
|
||||
getDefaultPicBed()
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
updatePicBedGlobal()
|
||||
ipcRenderer.on('uploadProgress', (_event: IpcRendererEvent, _progress: number) => {
|
||||
if (_progress !== -1) {
|
||||
showProgress.value = true
|
||||
progress.value = _progress
|
||||
} else {
|
||||
progress.value = 100
|
||||
showError.value = true
|
||||
}
|
||||
})
|
||||
window.electron.ipcRendererOn('uploadProgress', uploadProgressHandler)
|
||||
getUseShortUrl()
|
||||
getPasteStyle()
|
||||
getDefaultPicBed()
|
||||
ipcRenderer.on('syncPicBed', () => {
|
||||
getDefaultPicBed()
|
||||
})
|
||||
window.electron.ipcRendererOn('syncPicBed', syncPicBedHandler)
|
||||
$bus.on(SHOW_INPUT_BOX_RESPONSE, handleInputBoxValue)
|
||||
})
|
||||
|
||||
@@ -180,7 +225,7 @@ const handleImageProcess = () => {
|
||||
|
||||
watch(progress, onProgressChange)
|
||||
|
||||
function onProgressChange(val: number) {
|
||||
function onProgressChange (val: number) {
|
||||
if (val === 100) {
|
||||
setTimeout(() => {
|
||||
showProgress.value = false
|
||||
@@ -192,11 +237,11 @@ function onProgressChange(val: number) {
|
||||
}
|
||||
}
|
||||
|
||||
async function handlePicBedNameClick(_picBedName: string, picBedConfigName: string | undefined) {
|
||||
async function handlePicBedNameClick (_picBedName: string, picBedConfigName: string | undefined) {
|
||||
const formatedpicBedConfigName = picBedConfigName || 'Default'
|
||||
const currentPicBed = await getConfig<string>(configPaths.picBed.current)
|
||||
const currentPicBedConfig = ((await getConfig<any[]>(`uploader.${currentPicBed}`)) as any) || {}
|
||||
const configList = await triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_GET_CONFIG_LIST, currentPicBed)
|
||||
const configList = await window.electron.triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_GET_CONFIG_LIST, currentPicBed)
|
||||
const currentConfigList = configList?.configList ?? []
|
||||
const config = currentConfigList.find((item: any) => item._configName === formatedpicBedConfigName)
|
||||
$router.push({
|
||||
@@ -213,11 +258,11 @@ async function handlePicBedNameClick(_picBedName: string, picBedConfigName: stri
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
$bus.off(SHOW_INPUT_BOX_RESPONSE)
|
||||
ipcRenderer.removeAllListeners('uploadProgress')
|
||||
ipcRenderer.removeAllListeners('syncPicBed')
|
||||
window.electron.ipcRendererRemoveListener('uploadProgress', uploadProgressHandler)
|
||||
window.electron.ipcRendererRemoveListener('syncPicBed', syncPicBedHandler)
|
||||
})
|
||||
|
||||
function onDrop(e: DragEvent) {
|
||||
function onDrop (e: DragEvent) {
|
||||
dragover.value = false
|
||||
|
||||
// send files first
|
||||
@@ -230,7 +275,7 @@ function onDrop(e: DragEvent) {
|
||||
} else if (items[0].type === 'text/plain') {
|
||||
const str = e.dataTransfer.getData(items[0].type)
|
||||
if (isUrl(str)) {
|
||||
sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [{ path: str }])
|
||||
window.electron.sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [{ path: str }])
|
||||
} else {
|
||||
$message.error($T('TIPS_DRAG_VALID_PICTURE_OR_URL'))
|
||||
}
|
||||
@@ -238,13 +283,13 @@ function onDrop(e: DragEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleURLDrag(items: DataTransferItemList, dataTransfer: DataTransfer) {
|
||||
function handleURLDrag (items: DataTransferItemList, dataTransfer: DataTransfer) {
|
||||
// text/html
|
||||
// Use this data to get a more precise URL
|
||||
const urlString = dataTransfer.getData(items[1].type)
|
||||
const urlMatch = urlString.match(/<img.*src="(.*?)"/)
|
||||
if (urlMatch) {
|
||||
sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [
|
||||
window.electron.sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [
|
||||
{
|
||||
path: urlMatch[1]
|
||||
}
|
||||
@@ -254,53 +299,53 @@ function handleURLDrag(items: DataTransferItemList, dataTransfer: DataTransfer)
|
||||
}
|
||||
}
|
||||
|
||||
function openUplodWindow() {
|
||||
function openUplodWindow () {
|
||||
document.getElementById('file-uploader')!.click()
|
||||
}
|
||||
|
||||
function onChange(e: any) {
|
||||
function onChange (e: any) {
|
||||
ipcSendFiles(e.target.files)
|
||||
;(document.getElementById('file-uploader') as HTMLInputElement).value = ''
|
||||
}
|
||||
|
||||
function ipcSendFiles(files: FileList) {
|
||||
function ipcSendFiles (files: FileList) {
|
||||
const sendFiles: IFileWithPath[] = []
|
||||
Array.from(files).forEach(item => {
|
||||
const obj = {
|
||||
name: item.name,
|
||||
path: item.path
|
||||
path: item.webkitRelativePath
|
||||
}
|
||||
sendFiles.push(obj)
|
||||
})
|
||||
sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, sendFiles)
|
||||
window.electron.sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, sendFiles)
|
||||
}
|
||||
|
||||
async function getPasteStyle() {
|
||||
async function getPasteStyle () {
|
||||
pasteStyle.value = (await getConfig(configPaths.settings.pasteStyle)) || IPasteStyle.MARKDOWN
|
||||
pasteFormatList.value.Custom = (await getConfig(configPaths.settings.customLink)) || ''
|
||||
}
|
||||
|
||||
async function getUseShortUrl() {
|
||||
async function getUseShortUrl () {
|
||||
useShortUrl.value = (await getConfig(configPaths.settings.useShortUrl)) || false
|
||||
}
|
||||
|
||||
async function handleUseShortUrlChange() {
|
||||
async function handleUseShortUrlChange () {
|
||||
saveConfig({
|
||||
[configPaths.settings.useShortUrl]: useShortUrl.value
|
||||
})
|
||||
}
|
||||
|
||||
function handlePasteStyleChange(val: string | number | boolean | undefined) {
|
||||
function handlePasteStyleChange (val: string | number | boolean | undefined) {
|
||||
saveConfig({
|
||||
[configPaths.settings.pasteStyle]: val || IPasteStyle.MARKDOWN
|
||||
})
|
||||
}
|
||||
|
||||
function uploadClipboardFiles() {
|
||||
sendRPC(IRPCActionType.UPLOAD_CLIPBOARD_FILES_FROM_UPLOAD_PAGE)
|
||||
function uploadClipboardFiles () {
|
||||
window.electron.sendRPC(IRPCActionType.UPLOAD_CLIPBOARD_FILES_FROM_UPLOAD_PAGE)
|
||||
}
|
||||
|
||||
async function uploadURLFiles() {
|
||||
async function uploadURLFiles () {
|
||||
const str = await navigator.clipboard.readText()
|
||||
$bus.emit(SHOW_INPUT_BOX, {
|
||||
value: isUrl(str) ? str : '',
|
||||
@@ -309,10 +354,10 @@ async function uploadURLFiles() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleInputBoxValue(val: string) {
|
||||
function handleInputBoxValue (val: string) {
|
||||
if (val === '') return
|
||||
if (isUrl(val)) {
|
||||
sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [
|
||||
window.electron.sendRPC(IRPCActionType.UPLOAD_CHOOSED_FILES, [
|
||||
{
|
||||
path: val
|
||||
}
|
||||
@@ -322,7 +367,7 @@ function handleInputBoxValue(val: string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getDefaultPicBed() {
|
||||
async function getDefaultPicBed () {
|
||||
const currentPicBed = await getConfig<string>(configPaths.picBed.current)
|
||||
picBedGlobal.value.forEach(item => {
|
||||
if (item.type === currentPicBed) {
|
||||
@@ -332,8 +377,8 @@ async function getDefaultPicBed() {
|
||||
picBedConfigName.value = (await getConfig<string>(`picBed.${currentPicBed}._configName`)) || ''
|
||||
}
|
||||
|
||||
async function handleChangePicBed() {
|
||||
sendRPC(IRPCActionType.SHOW_UPLOAD_PAGE_MENU)
|
||||
async function handleChangePicBed () {
|
||||
window.electron.sendRPC(IRPCActionType.SHOW_UPLOAD_PAGE_MENU)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -3,7 +3,13 @@
|
||||
<div class="view-title">
|
||||
{{ $T('SETTINGS') }}
|
||||
</div>
|
||||
<el-row :gutter="15" justify="space-between" align="middle" type="flex" class="config-list">
|
||||
<el-row
|
||||
:gutter="15"
|
||||
justify="space-between"
|
||||
align="middle"
|
||||
type="flex"
|
||||
class="config-list"
|
||||
>
|
||||
<el-col
|
||||
v-for="item in curConfigList"
|
||||
:key="item._id"
|
||||
@@ -24,11 +30,17 @@
|
||||
<div class="config-update-time">
|
||||
{{ formatTime(item._updatedAt) }}
|
||||
</div>
|
||||
<div v-if="defaultConfigId === item._id" class="default-text">
|
||||
<div
|
||||
v-if="defaultConfigId === item._id"
|
||||
class="default-text"
|
||||
>
|
||||
{{ $T('SELECTED_SETTING_HINT') }}
|
||||
</div>
|
||||
<div class="operation-container">
|
||||
<el-icon class="el-icon-edit" @click="openEditPage(item._id)">
|
||||
<el-icon
|
||||
class="el-icon-edit"
|
||||
@click="openEditPage(item._id)"
|
||||
>
|
||||
<Edit />
|
||||
</el-icon>
|
||||
<el-icon
|
||||
@@ -49,14 +61,22 @@
|
||||
:lg="curConfigList.length === 1 ? 12 : 6"
|
||||
:xl="curConfigList.length === 1 ? 12 : 3"
|
||||
>
|
||||
<div class="config-item config-item-add" @click="addNewConfig">
|
||||
<div
|
||||
class="config-item config-item-add"
|
||||
@click="addNewConfig"
|
||||
>
|
||||
<el-icon class="el-icon-plus">
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row type="flex" justify="center" :span="24" class="set-default-container">
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
:span="24"
|
||||
class="set-default-container"
|
||||
>
|
||||
<el-button
|
||||
class="set-default-btn"
|
||||
type="success"
|
||||
@@ -71,18 +91,17 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Delete, Edit, Plus } from '@element-plus/icons-vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { Edit, Delete, Plus } from '@element-plus/icons-vue'
|
||||
import { onBeforeMount, ref } from 'vue'
|
||||
import { useRouter, useRoute, onBeforeRouteUpdate } from 'vue-router'
|
||||
import { saveConfig } from '@/utils/dataSender'
|
||||
import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import { T as $T } from '@/i18n/index'
|
||||
import { useStore } from '@/hooks/useStore'
|
||||
import { T as $T } from '@/i18n/index'
|
||||
import { PICBEDS_PAGE, UPLOADER_CONFIG_PAGE } from '@/router/config'
|
||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||
|
||||
import { saveConfig } from '@/utils/dataSender'
|
||||
import { IRPCActionType } from '#/types/enum'
|
||||
import { IStringKeyMap, IUploaderConfigItem } from '#/types/types'
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -93,10 +112,10 @@ const curConfigList = ref<IStringKeyMap[]>([])
|
||||
const defaultConfigId = ref('')
|
||||
const store = useStore()
|
||||
|
||||
async function selectItem(id: string) {
|
||||
await triggerRPC<void>(IRPCActionType.UPLOADER_SELECT, type.value, id)
|
||||
async function selectItem (id: string) {
|
||||
await window.electron.triggerRPC<void>(IRPCActionType.UPLOADER_SELECT, type.value, id)
|
||||
if (store?.state.defaultPicBed === type.value) {
|
||||
sendRPC(
|
||||
window.electron.sendRPC(
|
||||
IRPCActionType.TRAY_SET_TOOL_TIP,
|
||||
`${type.value} ${curConfigList.value.find(item => item._id === id)?._configName || ''}`
|
||||
)
|
||||
@@ -117,13 +136,13 @@ onBeforeMount(() => {
|
||||
getCurrentConfigList()
|
||||
})
|
||||
|
||||
async function getCurrentConfigList() {
|
||||
const configList = await triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_GET_CONFIG_LIST, type.value)
|
||||
async function getCurrentConfigList () {
|
||||
const configList = await window.electron.triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_GET_CONFIG_LIST, type.value)
|
||||
curConfigList.value = configList?.configList ?? []
|
||||
defaultConfigId.value = configList?.defaultId ?? ''
|
||||
}
|
||||
|
||||
function openEditPage(configId: string) {
|
||||
function openEditPage (configId: string) {
|
||||
router.push({
|
||||
name: PICBEDS_PAGE,
|
||||
params: {
|
||||
@@ -136,18 +155,18 @@ function openEditPage(configId: string) {
|
||||
})
|
||||
}
|
||||
|
||||
function formatTime(time: number): string {
|
||||
function formatTime (time: number): string {
|
||||
return dayjs(time).format('YY-MM-DD HH:mm')
|
||||
}
|
||||
|
||||
async function deleteConfig(id: string) {
|
||||
const res = await triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_DELETE_CONFIG, type.value, id)
|
||||
async function deleteConfig (id: string) {
|
||||
const res = await window.electron.triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_DELETE_CONFIG, type.value, id)
|
||||
if (!res) return
|
||||
curConfigList.value = res.configList
|
||||
defaultConfigId.value = res.defaultId
|
||||
}
|
||||
|
||||
function addNewConfig() {
|
||||
function addNewConfig () {
|
||||
router.push({
|
||||
name: PICBEDS_PAGE,
|
||||
params: {
|
||||
@@ -157,7 +176,7 @@ function addNewConfig() {
|
||||
})
|
||||
}
|
||||
|
||||
function setDefaultPicBed(type: string) {
|
||||
function setDefaultPicBed (type: string) {
|
||||
saveConfig({
|
||||
[configPaths.picBed.current]: type,
|
||||
[configPaths.picBed.uploader]: type
|
||||
@@ -165,7 +184,7 @@ function setDefaultPicBed(type: string) {
|
||||
|
||||
store?.setDefaultPicBed(type)
|
||||
const currentConfigName = curConfigList.value.find(item => item._id === defaultConfigId.value)?._configName
|
||||
sendRPC(IRPCActionType.TRAY_SET_TOOL_TIP, `${type} ${currentConfigName || ''}`)
|
||||
window.electron.sendRPC(IRPCActionType.TRAY_SET_TOOL_TIP, `${type} ${currentConfigName || ''}`)
|
||||
const successNotification = new Notification($T('SETTINGS_DEFAULT_PICBED'), {
|
||||
body: $T('TIPS_SET_SUCCEED')
|
||||
})
|
||||
|
||||
@@ -1,26 +1,60 @@
|
||||
<template>
|
||||
<div id="picbeds-page">
|
||||
<el-row :gutter="20" class="setting-list">
|
||||
<el-col :span="22" :offset="1">
|
||||
<el-row
|
||||
:gutter="20"
|
||||
class="setting-list"
|
||||
>
|
||||
<el-col
|
||||
:span="22"
|
||||
:offset="1"
|
||||
>
|
||||
<div class="view-title">
|
||||
<span class="view-title-text" @click="handleNameClick"> {{ picBedName }} {{ $T('SETTINGS') }}</span>
|
||||
<span
|
||||
class="view-title-text"
|
||||
@click="handleNameClick"
|
||||
> {{ picBedName }} {{ $T('SETTINGS') }}</span>
|
||||
<el-icon>
|
||||
<Link />
|
||||
</el-icon>
|
||||
<el-button type="primary" round size="small" style="margin-left: 6px" @click="handleCopyApi">
|
||||
<el-button
|
||||
type="primary"
|
||||
round
|
||||
size="small"
|
||||
style="margin-left: 6px"
|
||||
@click="handleCopyApi"
|
||||
>
|
||||
{{ $T('UPLOAD_PAGE_COPY_UPLOAD_API') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<config-form v-if="config.length > 0" :id="type" ref="$configForm" :config="config" type="uploader">
|
||||
<config-form
|
||||
v-if="config.length > 0"
|
||||
:id="type"
|
||||
ref="$configForm"
|
||||
:config="config"
|
||||
type="uploader"
|
||||
>
|
||||
<el-form-item>
|
||||
<el-button-group>
|
||||
<el-button type="info" round @click="handleReset">
|
||||
<el-button
|
||||
type="info"
|
||||
round
|
||||
@click="handleReset"
|
||||
>
|
||||
{{ $T('RESET_PICBED_CONFIG') }}
|
||||
</el-button>
|
||||
<el-button type="success" round @click="handleConfirm">
|
||||
<el-button
|
||||
type="success"
|
||||
round
|
||||
@click="handleConfirm"
|
||||
>
|
||||
{{ $T('CONFIRM') }}
|
||||
</el-button>
|
||||
<el-button round type="warning" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
||||
<el-button
|
||||
round
|
||||
type="warning"
|
||||
@mouseenter="handleMouseEnter"
|
||||
@mouseleave="handleMouseLeave"
|
||||
>
|
||||
<el-dropdown
|
||||
ref="$dropdown"
|
||||
placement="top"
|
||||
@@ -30,7 +64,11 @@
|
||||
>
|
||||
{{ $T('MANAGE_LOGIN_PAGE_PANE_IMPORT') }}
|
||||
<template #dropdown>
|
||||
<el-dropdown-item v-for="i in picBedConfigList" :key="i._id" @click="handleConfigImport(i)">
|
||||
<el-dropdown-item
|
||||
v-for="i in picBedConfigList"
|
||||
:key="i._id"
|
||||
@click="handleConfigImport(i)"
|
||||
>
|
||||
{{ i._configName }}
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
@@ -39,7 +77,10 @@
|
||||
</el-button-group>
|
||||
</el-form-item>
|
||||
</config-form>
|
||||
<div v-else class="single">
|
||||
<div
|
||||
v-else
|
||||
class="single"
|
||||
>
|
||||
<div class="notice">
|
||||
{{ $T('SETTINGS_NOT_CONFIG_OPTIONS') }}
|
||||
</div>
|
||||
@@ -50,19 +91,17 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import dayjs from 'dayjs'
|
||||
import { clipboard } from 'electron'
|
||||
import { ElDropdown, ElMessage } from 'element-plus'
|
||||
import { Link } from '@element-plus/icons-vue'
|
||||
import { ref, onBeforeMount } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { ElDropdown, ElMessage } from 'element-plus'
|
||||
import { onBeforeMount, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import ConfigForm from '@/components/ConfigForm.vue'
|
||||
import { T as $T } from '@/i18n/index'
|
||||
import { sendRPC, triggerRPC } from '@/utils/common'
|
||||
import { getConfig } from '@/utils/dataSender'
|
||||
|
||||
import { II18nLanguage, IRPCActionType } from '#/types/enum'
|
||||
import { IPicGoPluginConfig, IStringKeyMap, IUploaderConfigItem, IUploaderConfigListItem } from '#/types/types'
|
||||
import { configPaths } from '#/utils/configPaths'
|
||||
import { picBedManualUrlList } from '#/utils/static'
|
||||
|
||||
@@ -84,7 +123,7 @@ onBeforeMount(async () => {
|
||||
const handleConfirm = async () => {
|
||||
const result = (await $configForm.value?.validate()) || false
|
||||
if (result !== false) {
|
||||
await triggerRPC<void>(IRPCActionType.UPLOADER_UPDATE_CONFIG, type.value, result?._id, result)
|
||||
await window.electron.triggerRPC<void>(IRPCActionType.UPLOADER_UPDATE_CONFIG, type.value, result?._id, result)
|
||||
const successNotification = new Notification($T('SETTINGS_RESULT'), {
|
||||
body: $T('TIPS_SET_SUCCEED')
|
||||
})
|
||||
@@ -95,27 +134,27 @@ const handleConfirm = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseEnter() {
|
||||
function handleMouseEnter () {
|
||||
$dropdown.value?.handleOpen()
|
||||
}
|
||||
|
||||
function handleMouseLeave() {
|
||||
function handleMouseLeave () {
|
||||
$dropdown.value?.handleClose()
|
||||
}
|
||||
|
||||
async function getPicBeds() {
|
||||
const result = await triggerRPC<any>(IRPCActionType.PICBED_GET_PICBED_CONFIG, $route.params.type)
|
||||
async function getPicBeds () {
|
||||
const result = await window.electron.triggerRPC<any>(IRPCActionType.PICBED_GET_PICBED_CONFIG, $route.params.type)
|
||||
config.value = result.config
|
||||
picBedName.value = result.name
|
||||
}
|
||||
|
||||
async function getPicBedConfigList() {
|
||||
const res = (await triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_GET_CONFIG_LIST, type.value)) || undefined
|
||||
async function getPicBedConfigList () {
|
||||
const res = (await window.electron.triggerRPC<IUploaderConfigItem>(IRPCActionType.PICBED_GET_CONFIG_LIST, type.value)) || undefined
|
||||
const configList = res?.configList || []
|
||||
picBedConfigList.value = configList.filter(item => item._id !== $route.params.configId)
|
||||
}
|
||||
|
||||
async function handleConfigImport(configItem: IUploaderConfigListItem) {
|
||||
async function handleConfigImport (configItem: IUploaderConfigListItem) {
|
||||
const { _id, _configName, _updatedAt, _createdAt, ...rest } = configItem
|
||||
for (const key in rest) {
|
||||
if (Object.prototype.hasOwnProperty.call(rest, key)) {
|
||||
@@ -127,7 +166,7 @@ async function handleConfigImport(configItem: IUploaderConfigListItem) {
|
||||
}
|
||||
|
||||
const handleReset = async () => {
|
||||
await triggerRPC<void>(IRPCActionType.UPLOADER_RESET_CONFIG, type.value, $route.params.configId)
|
||||
await window.electron.triggerRPC<void>(IRPCActionType.UPLOADER_RESET_CONFIG, type.value, $route.params.configId)
|
||||
const successNotification = new Notification($T('SETTINGS_RESULT'), {
|
||||
body: $T('TIPS_RESET_SUCCEED')
|
||||
})
|
||||
@@ -137,15 +176,15 @@ const handleReset = async () => {
|
||||
$router.back()
|
||||
}
|
||||
|
||||
async function handleNameClick() {
|
||||
async function handleNameClick () {
|
||||
const lang = (await getConfig(configPaths.settings.language)) || II18nLanguage.ZH_CN
|
||||
const url = picBedManualUrlList[lang === II18nLanguage.EN ? 'en' : 'zh_cn'][$route.params.type as string]
|
||||
if (url) {
|
||||
sendRPC(IRPCActionType.OPEN_URL, url)
|
||||
window.electron.sendRPC(IRPCActionType.OPEN_URL, url)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleCopyApi() {
|
||||
async function handleCopyApi () {
|
||||
try {
|
||||
const { port = 36677, host = '127.0.0.1' } = (await getConfig<IStringKeyMap>(configPaths.settings.server)) || {}
|
||||
const serverKey = (await getConfig(configPaths.settings.serverKey)) || ''
|
||||
@@ -157,7 +196,7 @@ async function handleCopyApi() {
|
||||
return
|
||||
}
|
||||
const apiUrl = `http://${host === '0.0.0.0' ? '127.0.0.1' : host}:${port}/upload?picbed=${$route.params.type}&configName=${picBedConfig._configName}${serverKey ? `&key=${serverKey}` : ''}`
|
||||
clipboard.writeText(apiUrl)
|
||||
window.electron.clipboard.writeText(apiUrl)
|
||||
ElMessage.success(`${$T('MANAGE_BUCKET_COPY_SUCCESS')} ${apiUrl}`)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
|
||||
Reference in New Issue
Block a user