Feature: support short url now

This commit is contained in:
萌萌哒赫萝 2023-04-17 17:26:49 +08:00
parent ef917ce26e
commit d55458197a
20 changed files with 151 additions and 75 deletions

View File

@ -1,58 +0,0 @@
# main.yml
# Workflow's name
name: Manually Build
# Workflow's trigger
on: workflow_dispatch
# Workflow's jobs
jobs:
# job's id
release:
# job's name
name: build and release electron app
# the type of machine to run the job on
runs-on: ${{ matrix.os }}
# create a build matrix for jobs
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-11]
# create steps
steps:
# step1: check out repository
- name: Check out git repository
uses: actions/checkout@v2
# step2: install node env
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: '16.x'
- name: Install system deps
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils
# step3: yarn
- name: Yarn install
run: |
yarn
yarn global add xvfb-maybe
- name: Build & release app
run: |
yarn release
yarn upload-dist
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
R2_SECRET_ID: ${{ secrets.R2_SECRET_ID }}
R2_SECRET_KEY: ${{ secrets.R2_SECRET_KEY }}
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}

View File

@ -109,7 +109,8 @@ UPLOAD_PAGE_IMAGE_PROCESS_POSITION_TOP_RIGHT: top right
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_BOTTOM_LEFT: bottom left
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_BOTTOM_RIGHT: bottom right
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_CENTER: center
UPLOAD_SHORT_URL: 短链接
UPLOAD_NORMAL_URL: 长链接
# settings
SETTINGS: Settings
@ -195,6 +196,7 @@ SETTINGS_ISHIDEDOCK: Hide Dock Icon
SETTINGS_ISHIDEDOCK_TIPS: Not support hide dock and tray at the same time
SETTINGS_ENCODE_OUTPUT_URL: Encode Output(or Copyed) URL
SETTINGS_WATCH_CLIPBOARD: Watch clipboard when software start
SETTINGS_SHORT_URL: Use short url
# shortcut-page
BUILTIN_CLIPBOARD_TIPS: Use builtin clipboard function to upload instead of using scripts

View File

@ -108,6 +108,9 @@ UPLOAD_PAGE_IMAGE_PROCESS_POSITION_TOP_RIGHT: 右上
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_BOTTOM_LEFT: 左下
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_BOTTOM_RIGHT: 右下
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_CENTER:
UPLOAD_SHORT_URL: 短链接
UPLOAD_NORMAL_URL: 长链接
# settings
@ -195,6 +198,7 @@ SETTINGS_ISHIDEDOCK: 是否隐藏dock图标
SETTINGS_ISHIDEDOCK_TIPS: 不支持同时隐藏dock和托盘
SETTINGS_ENCODE_OUTPUT_URL: 输出(复制) URL 时进行转义
SETTINGS_WATCH_CLIPBOARD: 软件启动时自动监听剪贴板上传
SETTINGS_SHORT_URL: 使用短链接
# shortcut-page
SHORTCUT_NAME: 快捷键名称

View File

@ -108,7 +108,8 @@ UPLOAD_PAGE_IMAGE_PROCESS_POSITION_TOP_RIGHT: 右上
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_BOTTOM_LEFT: 左下
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_BOTTOM_RIGHT: 右下
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_CENTER:
UPLOAD_SHORT_URL: 短链接
UPLOAD_NORMAL_URL: 长链接
# settings
SETTINGS: 設定
@ -195,6 +196,7 @@ SETTINGS_ISHIDEDOCK: 是否隱藏dock圖示
SETTINGS_ISHIDEDOCK_TIPS: 不支持同時隱藏dock和托盘
SETTINGS_ENCODE_OUTPUT_URL: 輸出(複製) URL 時進行轉義
SETTINGS_WATCH_CLIPBOARD: 軟體啟動時自動監聽剪貼簿上傳
SETTINGS_SHORT_URL: 使用短網址
# shortcut-page
SHORTCUT_NAME: 快捷鍵名稱

View File

@ -401,7 +401,7 @@ export function createTray () {
if (imgs !== false) {
const pasteText: string[] = []
for (let i = 0; i < imgs.length; i++) {
pasteText.push(pasteTemplate(pasteStyle, imgs[i], db.get('settings.customLink')))
pasteText.push(await (pasteTemplate(pasteStyle, imgs[i], db.get('settings.customLink'))))
const notification = new Notification({
title: T('UPLOAD_SUCCEED'),
body: imgs[i].imgUrl!

View File

@ -30,7 +30,7 @@ export const uploadClipboardFiles = async (): Promise<IStringKeyMap> => {
if (img.length > 0) {
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
handleCopyUrl(pasteTemplate(pasteStyle, img[0], db.get('settings.customLink')))
handleCopyUrl(await (pasteTemplate(pasteStyle, img[0], db.get('settings.customLink'))))
const notification = new Notification({
title: T('UPLOAD_SUCCEED'),
body: img[0].imgUrl!
@ -77,7 +77,7 @@ export const uploadChoosedFiles = async (webContents: WebContents, files: IFileW
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
const pasteText: string[] = []
for (let i = 0; i < imgs.length; i++) {
pasteText.push(pasteTemplate(pasteStyle, imgs[i], db.get('settings.customLink')))
pasteText.push(await (pasteTemplate(pasteStyle, imgs[i], db.get('settings.customLink'))))
const notification = new Notification({
title: T('UPLOAD_SUCCEED'),
body: imgs[i].imgUrl!

View File

@ -81,7 +81,7 @@ class GuiApi implements IGuiApi {
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
const pasteText: string[] = []
for (let i = 0; i < imgs.length; i++) {
pasteText.push(pasteTemplate(pasteStyle, imgs[i], db.get('settings.customLink')))
pasteText.push(await (pasteTemplate(pasteStyle, imgs[i], db.get('settings.customLink'))))
const notification = new Notification({
title: T('UPLOAD_SUCCEED'),
body: imgs[i].imgUrl as string

View File

@ -55,7 +55,7 @@ export default {
const img = await uploader.setWebContents(trayWindow.webContents).uploadWithBuildInClipboard()
if (img !== false) {
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
handleCopyUrl(pasteTemplate(pasteStyle, img[0], db.get('settings.customLink')))
handleCopyUrl(await (pasteTemplate(pasteStyle, img[0], db.get('settings.customLink'))))
const notification = new Notification({
title: T('UPLOAD_SUCCEED'),
body: img[0].imgUrl!

View File

@ -346,7 +346,7 @@ const handlePicGoGalleryDB = () => {
ipcMain.handle(PASTE_TEXT, async (_, item: ImgInfo, copy = true) => {
const pasteStyle = picgo.getConfig<IPasteStyle>('settings.pasteStyle') || IPasteStyle.MARKDOWN
const customLink = picgo.getConfig<string>('settings.customLink')
const txt = pasteTemplate(pasteStyle, item, customLink)
const txt = await pasteTemplate(pasteStyle, item, customLink)
if (copy) {
clipboard.writeText(txt)
}

View File

@ -1,5 +1,5 @@
import { IPasteStyle } from '#/types/enum'
import { handleUrlEncode } from '#/utils/common'
import { handleUrlEncode, generateShortUrl } from '#/utils/common'
import db from '~/main/apis/core/datastore'
export const formatCustomLink = (customLink: string, item: ImgInfo) => {
@ -21,11 +21,15 @@ export const formatCustomLink = (customLink: string, item: ImgInfo) => {
return customLink
}
export default (style: IPasteStyle, item: ImgInfo, customLink: string | undefined) => {
export default async (style: IPasteStyle, item: ImgInfo, customLink: string | undefined) => {
let url = item.url || item.imgUrl
if (db.get('settings.encodeOutputURL') !== false) {
url = handleUrlEncode(url)
}
const useShortUrl = db.get('settings.useShortUrl') || false
if (useShortUrl) {
url = await generateShortUrl(url)
}
const _customLink = customLink || '![$fileName]($url)'
const tpl = {
markdown: `![](${url})`,

View File

@ -11,7 +11,6 @@ class PrivacyManager {
return false
} else {
db.set('settings.privacyEnsure', true)
return true
}
}
return true

View File

@ -31,7 +31,7 @@
class="handle-bar"
:gutter="16"
>
<el-col :span="6">
<el-col :span="5">
<el-select
v-model="choosedPicBed"
multiple
@ -66,7 +66,7 @@
border-style="hidden"
/>
</el-col>
<el-col :span="5">
<el-col :span="3">
<el-select
v-model="pasteStyle"
size="small"
@ -82,6 +82,22 @@
/>
</el-select>
</el-col>
<el-col :span="3">
<el-select
v-model="useShortUrl"
size="small"
style="width: 100%"
placeholder="Choose"
@change="handleUseShortUrlChange"
>
<el-option
v-for="(value, key) in shortURLMap"
:key="key"
:label="key"
:value="value"
/>
</el-select>
</el-col>
<el-col :span="2">
<el-dropdown>
<el-button
@ -112,7 +128,7 @@
class="handle-bar"
:gutter="16"
>
<el-col :span="6">
<el-col :span="5">
<el-input
v-model="searchText"
:placeholder="$T('GALLERY_SEARCH_FILENAME')"
@ -146,6 +162,13 @@
</template>
</el-input>
</el-col>
<el-col :span="1">
<el-divider
direction="vertical"
style="height: 100%;"
border-style="hidden"
/>
</el-col>
<el-col :span="3">
<div
class="item-base copy round"
@ -439,6 +462,11 @@ const pasteStyleMap = {
UBB: 'UBB',
Custom: 'Custom'
}
const useShortUrl = ref<string>('')
const shortURLMap = {
[$T('UPLOAD_SHORT_URL')]: $T('UPLOAD_SHORT_URL'),
[$T('UPLOAD_NORMAL_URL')]: $T('UPLOAD_NORMAL_URL')
}
const fileSortNameReverse = ref(false)
const fileSortTimeReverse = ref(false)
const fileSortExtReverse = ref(false)
@ -835,6 +863,11 @@ async function handlePasteStyleChange (val: string) {
pasteStyle.value = val
}
function handleUseShortUrlChange (value: string) {
saveConfig('settings.useShortUrl', value === $T('UPLOAD_SHORT_URL'))
useShortUrl.value = value
}
function sortFile (type: 'name' | 'time' | 'ext' | 'check') {
switch (type) {
case 'name':
@ -954,6 +987,7 @@ onBeforeUnmount(() => {
onActivated(async () => {
pasteStyle.value = (await getConfig('settings.pasteStyle')) || 'markdown'
useShortUrl.value = (await getConfig('settings.useShortUrl') ? $T('UPLOAD_SHORT_URL') : $T('UPLOAD_NORMAL_URL'))
initDeleteCloud()
})

View File

@ -312,6 +312,16 @@
@change="handleAutoCopyUrl"
/>
</el-form-item>
<el-form-item
:label="$T('SETTINGS_SHORT_URL')"
>
<el-switch
v-model="form.useShortUrl"
:active-text="$T('SETTINGS_OPEN')"
:inactive-text="$T('SETTINGS_CLOSE')"
@change="handleUseShortUrl"
/>
</el-form-item>
<el-form-item>
<template #label>
<el-row align="middle">
@ -1062,7 +1072,8 @@ const form = reactive<ISettingForm>({
customMiniIcon: '',
isHideDock: false,
encodeOutputURL: true,
isAutoListenClipboard: false
isAutoListenClipboard: false,
useShortUrl: false
})
const languageList = i18nManager.languageList.map(item => ({
@ -1160,6 +1171,7 @@ async function initData () {
form.isCustomMiniIcon = settings.isCustomMiniIcon || false
form.customMiniIcon = settings.customMiniIcon || ''
form.isHideDock = settings.isHideDock || false
form.useShortUrl = settings.useShortUrl || false
currentLanguage.value = settings.language ?? 'zh-CN'
currentStartMode.value = settings.startMode || 'quiet'
customLink.value = settings.customLink || '![$fileName]($url)'
@ -1414,6 +1426,16 @@ function handleAutoCopyUrl (val: ICheckBoxValueType) {
}
}
function handleUseShortUrl (val: ICheckBoxValueType) {
saveConfig('settings.useShortUrl', val)
const successNotification = new Notification($T('SETTINGS_SHORT_URL'), {
body: $T('TIPS_SET_SUCCEED')
})
successNotification.onclick = () => {
return true
}
}
function confirmLogLevelSetting () {
if (form.logLevel.length === 0) {
return $message.error($T('TIPS_PLEASE_CHOOSE_LOG_LEVEL'))

View File

@ -70,7 +70,7 @@ import { IResult } from '@picgo/store/dist/types'
import { OPEN_WINDOW } from '#/events/constants'
import { IPasteStyle, IWindowList } from '#/types/enum'
import { getConfig, sendToMain } from '@/utils/dataSender'
import { handleUrlEncode } from '#/utils/common'
import { handleUrlEncode, generateShortUrl } from '#/utils/common'
const files = ref<IResult<ImgInfo>[]>([])
const notification = reactive({
@ -127,6 +127,10 @@ async function pasteTemplate (style: IPasteStyle, item: ImgInfo, customLink: str
if ((await getConfig('settings.encodeOutputURL')) !== false) {
url = handleUrlEncode(url)
}
const useShortUrl = await getConfig('settings.useShortUrl') || false
if (useShortUrl) {
url = await generateShortUrl(url)
}
const _customLink = customLink || '![$fileName]($url)'
const tpl = {
markdown: `![](${url})`,

View File

@ -102,6 +102,24 @@
:title="customLink"
/>
</el-radio-group>
<el-radio-group
v-model="useShortUrl"
size="small"
@change="handleUseShortUrlChange"
>
<el-radio-button
:label="true"
style="border-radius: 5px"
>
{{ $T('UPLOAD_SHORT_URL') }}
</el-radio-button>
<el-radio-button
:label="false"
style="border-radius: 5px"
>
{{ $T('UPLOAD_NORMAL_URL') }}
</el-radio-button>
</el-radio-group>
</div>
<div class="el-col-8">
<div class="paste-style__text">
@ -386,6 +404,7 @@ import { PICBEDS_PAGE } from '@/router/config'
const $router = useRouter()
const imageProcessDialogVisible = ref(false)
const useShortUrl = ref(false)
const waterMarkPositionMap = new Map([
['north', $T('UPLOAD_PAGE_IMAGE_PROCESS_POSITION_TOP')],
@ -488,6 +507,7 @@ onBeforeMount(() => {
showError.value = true
}
})
getUseShortUrl()
getPasteStyle()
getDefaultPicBed()
ipcRenderer.on('syncPicBed', () => {
@ -605,6 +625,17 @@ async function getPasteStyle () {
customLink.value = await getConfig('settings.customLink') || '![$fileName]($url)'
}
async function getUseShortUrl () {
useShortUrl.value = await getConfig('settings.useShortUrl') || false
}
async function handleUseShortUrlChange () {
console.log(useShortUrl.value)
saveConfig({
'settings.useShortUrl': useShortUrl.value
})
}
function handlePasteStyleChange (val: string | number | boolean) {
saveConfig({
'settings.pasteStyle': val

View File

@ -2,6 +2,7 @@ export const SHOW_INPUT_BOX = 'SHOW_INPUT_BOX'
export const SHOW_INPUT_BOX_RESPONSE = 'SHOW_INPUT_BOX_RESPONSE'
export const TOGGLE_SHORTKEY_MODIFIED_MODE = 'TOGGLE_SHORTKEY_MODIFIED_MODE'
export const TALKING_DATA_APPID = 'B743C16E2989419A9B02EDE9D1E6A530'
export const C1N = 'WjJoeFdWWklhVTlXYVRKTU5EUmFOVkEwUlVRPQ=='
export const TALKING_DATA_EVENT = 'TALKING_DATA_EVENT'
export const SHOW_PRIVACY_MESSAGE = 'SHOW_PRIVACY_MESSAGE'
export const PICGO_SAVE_CONFIG = 'PICGO_SAVE_CONFIG'

View File

@ -106,6 +106,8 @@ interface ILocales {
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_BOTTOM_LEFT: string
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_BOTTOM_RIGHT: string
UPLOAD_PAGE_IMAGE_PROCESS_POSITION_CENTER: string
UPLOAD_SHORT_URL: string
UPLOAD_NORMAL_URL: string
SETTINGS: string
SETTINGS_OPEN_CONFIG_FILE: string
SETTINGS_MIGRATE_FROM_PICGO: string
@ -190,6 +192,7 @@ interface ILocales {
SETTINGS_ISHIDEDOCK_TIPS: string
SETTINGS_ENCODE_OUTPUT_URL: string
SETTINGS_WATCH_CLIPBOARD: string
SETTINGS_SHORT_URL: string
SHORTCUT_NAME: string
SHORTCUT_BIND: string
SHORTCUT_STATUS: string

View File

@ -17,7 +17,8 @@ interface ISettingForm {
customMiniIcon: string,
isHideDock: boolean,
encodeOutputURL: boolean,
isAutoListenClipboard: boolean
isAutoListenClipboard: boolean,
useShortUrl: boolean
}
interface IShortKeyMap {

View File

@ -1,3 +1,7 @@
import axios from 'axios'
import FormData from 'form-data'
import { C1 } from './static'
export const isUrl = (url: string): boolean => {
try {
return Boolean(new URL(url))
@ -58,3 +62,24 @@ export const trimValues = (obj: IStringKeyMap) => {
})
return newObj
}
const c1nApi = 'https://c1n.cn/link/short'
export const generateShortUrl = async (url: string) => {
const form = new FormData()
form.append('url', url)
const C = Buffer.from(C1, 'base64').toString()
try {
const res = await axios.post(c1nApi, form, {
headers: {
token: C
}
})
if (res.status >= 200 && res.status < 300 && res.data?.code === 0) {
return res.data.data
}
} catch (e: any) {
console.log(e)
}
return url
}

View File

@ -1,4 +1,6 @@
import { C1N } from '../events/constants'
export const CLIPBOARD_IMAGE_FOLDER = 'piclist-clipboard-images'
export const RELEASE_URL = 'https://api.github.com/repos/Kuingsmile/PicList/releases'
export const RELEASE_URL_BACKUP = 'https://release.piclist.cn'
export const STABLE_RELEASE_URL = 'https://github.com/Kuingsmile/PicList/releases/latest'
export const C1 = Buffer.from(C1N, 'base64').toString()