Compare commits

...
9 Commits
Author SHA1 Message Date
PiEgg f695e7ccaf 🎉 Release: v2.4.1-beta.0 2025-12-09 15:47:26 +08:00
PiEgg 366ac11ee2 📦 Chore: disabled build universal installer 2025-12-09 15:46:32 +08:00
PiEgg 9d4ea8277d 📦 Chore: change release url 2025-12-08 21:27:03 +08:00
PiEggandGitHub 56f61d458e 🐛 Fix: tray window clipboard image not show bug (#1362) 2025-12-08 21:16:25 +08:00
PiEgg 8e94b2a4d4 📦 Chore: fix upload dist arch bug 2025-12-08 18:47:05 +08:00
PiEgg db627a450f 📦 Chore: fix some workflow bug 2025-12-08 18:12:55 +08:00
PiEggandGitHub 070ce2b666 📦 Chore: upgrade electron version && migrate to electron-vite (#1361) 2025-12-08 17:42:35 +08:00
PiEgg b421c4b42a 🐛 Fix: pic-migrater post handler error 2025-11-28 21:18:52 +08:00
PiEgg d6c0a85a0f 🐛 Fix: fix docs link 2025-11-27 11:16:23 +08:00
59 changed files with 3685 additions and 5758 deletions
+116 -41
View File
@@ -1,61 +1,136 @@
# main.yml
name: Build & Release
# Workflow's name
name: Build
# Workflow's trigger
on:
push:
branches:
- master
tags:
- v*
workflow_dispatch:
inputs:
test_upload_dist:
description: "Test upload-dist.js script"
required: true
default: false
type: boolean
env:
NODE_VERSION: 22.x
# 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
# parallel build jobs
build:
name: Build on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
# create a build matrix for jobs
strategy:
# if one job fails, do not stop other jobs
fail-fast: false
matrix:
os: [ubuntu-latest, macos-14]
# create steps
os: [macos-latest, windows-latest, ubuntu-latest]
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
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '16.x'
- name: Install system deps
if: matrix.os == 'ubuntu-latest'
node-version: ${{ env.NODE_VERSION }}
- name: Clean workspace on Windows
if: runner.os == 'Windows'
run: |
sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils
if (Test-Path dist) { Remove-Item -Recurse -Force dist }
if (Test-Path dist_electron) { Remove-Item -Recurse -Force dist_electron }
if (Test-Path node_modules) { Remove-Item -Recurse -Force node_modules }
# step3: yarn
- name: Yarn install
if (Test-Path "$env:LOCALAPPDATA\electron-builder") {
Remove-Item "$env:LOCALAPPDATA\electron-builder" -Recurse -Force -ErrorAction SilentlyContinue
}
if (Test-Path "$env:LOCALAPPDATA\electron") {
Remove-Item "$env:LOCALAPPDATA\electron" -Recurse -Force -ErrorAction SilentlyContinue
}
- name: Clean workspace on macOS & Linux
if: runner.os == 'macOS' || runner.os == 'Linux'
run: |
yarn
yarn global add xvfb-maybe
- name: Build & release app
run: |
yarn release
yarn upload-dist
rm -rf dist dist_electron node_modules ~/.cache/electron-builder ~/.cache/electron
- name: Install dependencies
run: yarn install
- name: Ubuntu Update with sudo
if: runner.os == 'Linux'
run: sudo apt-get update
- name: Build Windows x64 & ARM64 App
if: runner.os == 'Windows'
run: yarn build:win || true
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
PICGO_ENV_COS_SECRET_ID: ${{ secrets.PICGO_ENV_COS_SECRET_ID }}
PICGO_ENV_COS_SECRET_KEY: ${{ secrets.PICGO_ENV_COS_SECRET_KEY }}
- name: Build macOS x64 & ARM64 App
if: runner.os == 'macOS'
run: yarn build:mac || true
shell: bash
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Build Linux x64 & ARM64 App
if: runner.os == 'Linux'
run: yarn build:linux || true
shell: bash
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: PicGo-${{ runner.os }}
path: dist/*.*
- name: Upload to release.picgo.app
if: startsWith(github.ref, 'refs/tags/v') || github.event.inputs.test_upload_dist
run: |
yarn upload-dist
env:
PICGO_ENV_S3_SECRET_ID: ${{ secrets.PICGO_ENV_S3_SECRET_ID }}
PICGO_ENV_S3_SECRET_KEY: ${{ secrets.PICGO_ENV_S3_SECRET_KEY }}
PICGO_ENV_S3_ACCOUNT_ID: ${{ secrets.PICGO_ENV_S3_ACCOUNT_ID }}
release:
name: Publish GitHub Release
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Publish GitHub Dev Release
if: github.event_name == 'workflow_dispatch'
uses: softprops/action-gh-release@v2
continue-on-error: true
with:
token: ${{ secrets.GH_TOKEN }}
tag_name: dev
draft: true
prerelease: false
files: |
!artifacts/**/*-unpacked/**
artifacts/**/*.exe
artifacts/**/*.dmg
artifacts/**/*.zip
artifacts/**/*.AppImage
artifacts/**/*.deb
artifacts/**/*.snap
artifacts/**/*.tar.gz
artifacts/**/*.yml
artifacts/**/*.blockmap
- name: Publish GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v2
continue-on-error: true
with:
token: ${{ secrets.GH_TOKEN }}
generate_release_notes: true
draft: true
prerelease: false
files: |
!artifacts/**/*-unpacked/**
artifacts/**/*.exe
artifacts/**/*.dmg
artifacts/**/*.zip
artifacts/**/*.AppImage
artifacts/**/*.deb
artifacts/**/*.snap
artifacts/**/*.tar.gz
artifacts/**/*.yml
artifacts/**/*.blockmap
-58
View File
@@ -1,58 +0,0 @@
# main.yml
# Workflow's name
name: 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-14]
# 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 }}
PICGO_ENV_COS_SECRET_ID: ${{ secrets.PICGO_ENV_COS_SECRET_ID }}
PICGO_ENV_COS_SECRET_KEY: ${{ secrets.PICGO_ENV_COS_SECRET_KEY }}
PICGO_ENV_S3_SECRET_ID: ${{ secrets.PICGO_ENV_S3_SECRET_ID }}
PICGO_ENV_S3_SECRET_KEY: ${{ secrets.PICGO_ENV_S3_SECRET_KEY }}
PICGO_ENV_S3_ACCOUNT_ID: ${{ secrets.PICGO_ENV_S3_ACCOUNT_ID }}
+3 -1
View File
@@ -21,4 +21,6 @@ test.js
scripts/*.yml
#Electron-builder output
/dist_electron
/dist_electron
.serena/
dist/*
+1 -1
View File
@@ -1 +1 @@
18
22
+11 -3
View File
@@ -11,8 +11,13 @@
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
},
"preLaunchTask": "electron-debug",
"args": ["--remote-debugging-port=9223", "./dist_electron"],
"outFiles": ["${workspaceFolder}/dist_electron/**/*.js"]
"args": [
"--remote-debugging-port=9223",
"./dist"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
]
},
{
"name": "Electron: Renderer",
@@ -30,7 +35,10 @@
"compounds": [
{
"name": "Electron: All",
"configurations": ["Electron: Main", "Electron: Renderer"]
"configurations": [
"Electron: Main",
"Electron: Renderer"
]
}
]
}
+7 -3
View File
@@ -5,14 +5,18 @@ PicGo is an Electron + Vue 3 desktop client. Source lives in `src/`: `src/main`
## Build, Test, and Development Commands
- `yarn install` — install dependencies; `npm install` is unsupported because native modules are patched for Yarn.
- `yarn dev` / `yarn electron:serve` — start the hot-reload dev environment for both processes.
- `yarn build` / `yarn electron:build` — package the app into `dist_electron/`; set `ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/` when downloads are slow.
- Always add/remove dependencies with `yarn` (never edit package.json versions by hand then install).
- `yarn dev` — electron-vite dev server for main/preload/renderer.
- `yarn build` — electron-vite build outputs to `dist/main`, `dist/preload`, `dist/renderer`; `yarn preview` for preview mode.
- Packaging config lives in `electron-builder.yml` (read by electron-builder via package.json `build` field/extraResources); set `ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/` if downloads are slow.
- `yarn lint` / `yarn lint:fix` — run or auto-fix ESLint (Standard, TypeScript, Vue rules).
- `yarn lint:dpdm` — fail fast on circular dependencies in `src/`.
- `yarn gen-i18n` — regenerate typed locales after touching `public/i18n/*.yml`.
## Coding Style & Naming Conventions
Follow ESLint Standard defaults: two-space indentation, single quotes, trailing commas where allowed, and no stray semicolons. Author new modules in TypeScript. Keep renderer files browser-safe; route Node APIs through IPC helpers such as `src/main/events/picgoCoreIPC.ts`. Name Vue components in PascalCase (`UploadPanel.vue`) and use camelCase for utilities. Centralize IPC event names inside `src/universal/events/constants.ts`, and store enums/types under `src/universal/types/` so they stay reusable.
Follow ESLint Standard defaults: two-space indentation, single quotes, trailing commas where allowed, and no stray semicolons. Author new modules in TypeScript. Keep renderer files browser-safe; route Node APIs through IPC helpers such as `src/main/events/picgoCoreIPC.ts`. Name Vue components in PascalCase (`UploadPanel.vue`) and use camelCase for utilities. Centralize IPC event names inside `src/universal/events/constants.ts`, and store enums/types under `src/universal/types/` so they stay reusable. Static assets are served from `public/` and resolved via `getStaticPath`/`getStaticFileUrl` (`src/universal/utils/staticPath.ts`); avoid using `__static` directly.
Static assets are served from `public/`. In the main process use `getStaticPath`/`getStaticFileUrl` (`src/universal/utils/staticPath.ts`). In the renderer, place assets under `public/` and resolve them via `import.meta.env.BASE_URL + filename` (helper: `src/renderer/utils/static.ts`); do not rely on `__static` in renderer code.
- Do not use `as any` under any circumstances; keep typings explicit and safe.
## Testing Guidelines
Place renderer unit specs in `test/unit/specs` with the `.spec.js` suffix; Karma picks them up via `require.context`. Run them with `npx karma start test/unit/karma.conf.js --single-run` and ensure new renderer folders are covered. Spectron e2e cases live in `test/e2e/specs`; build first (`yarn build`), then run `npx mocha test/e2e/index.js` so Spectron can launch `dist/electron/main.js`. Document any test data, IPC stubs, or fixtures you add to keep suites reproducible.
+20
View File
@@ -1,3 +1,23 @@
## :tada: 2.4.1-beta.0 (2025-12-09)
### :bug: Bug Fixes
* fix docs link ([d6c0a85](https://github.com/Molunerfinn/PicGo/commit/d6c0a85))
* pic-migrater post handler error ([b421c4b](https://github.com/Molunerfinn/PicGo/commit/b421c4b))
* tray window clipboard image not show bug ([#1362](https://github.com/Molunerfinn/PicGo/issues/1362)) ([56f61d4](https://github.com/Molunerfinn/PicGo/commit/56f61d4))
### :package: Chore
* change release url ([9d4ea82](https://github.com/Molunerfinn/PicGo/commit/9d4ea82))
* disabled build universal installer ([366ac11](https://github.com/Molunerfinn/PicGo/commit/366ac11))
* fix some workflow bug ([db627a4](https://github.com/Molunerfinn/PicGo/commit/db627a4))
* fix upload dist arch bug ([8e94b2a](https://github.com/Molunerfinn/PicGo/commit/8e94b2a))
* upgrade electron version && migrate to electron-vite ([#1361](https://github.com/Molunerfinn/PicGo/issues/1361)) ([070ce2b](https://github.com/Molunerfinn/PicGo/commit/070ce2b))
# :tada: 2.4.0 (2025-11-23)
+1 -1
View File
@@ -1,6 +1,6 @@
## 常见问题
> 在使用 PicGo 期间你会遇到很多问题,不过很多问题其实之前就有人提问过,也被解决,所以你可以先看看 [使用文档](https://picgo.github.io/PicGo-Doc/zh/guide/getting-started.html#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B),这份 FAQ,以及那些被关闭的 [issues](https://github.com/Molunerfinn/PicGo/issues?q=is%3Aissue+is%3Aclosed),应该能找到答案。
> 在使用 PicGo 期间你会遇到很多问题,不过很多问题其实之前就有人提问过,也被解决,所以你可以先看看 [使用文档](https://picgo.github.io/PicGo-Doc/guide/getting-started.html#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B),这份 FAQ,以及那些被关闭的 [issues](https://github.com/Molunerfinn/PicGo/issues?q=is%3Aissue+is%3Aclosed),应该能找到答案。
## 1. 七牛图床上传图片成功后,相册里无法显示或图片无`http://`前缀
+5 -5
View File
@@ -64,7 +64,7 @@ PicGo 本体支持如下图床:
- 开发进度可以查看 [Projects](https://github.com/Molunerfinn/PicGo/projects),会同步更新开发进度
<!-- - 欢迎加入 [官方讨论区](https://github.com/Molunerfinn/PicGo/discussions) 与我交流 -->
**如果第一次使用,请参考应用 [使用文档](https://picgo.github.io/PicGo-Doc/zh/guide/getting-started.html)。遇到问题了还可以看看 [FAQ](https://github.com/Molunerfinn/PicGo/blob/dev/FAQ.md) 以及被关闭的 [issues](https://github.com/Molunerfinn/PicGo/issues?q=is%3Aissue+is%3Aclosed)。**
**如果第一次使用,请参考应用 [使用文档](https://picgo.github.io/PicGo-Doc/guide/getting-started.html)。遇到问题了还可以看看 [FAQ](https://github.com/Molunerfinn/PicGo/blob/dev/FAQ.md) 以及被关闭的 [issues](https://github.com/Molunerfinn/PicGo/issues?q=is%3Aissue+is%3Aclosed)。**
## 下载安装
@@ -103,21 +103,21 @@ PicGo 本体支持如下图床:
```bash
ctrl+c # 退出开发模式
npm run electron:serve # 重新进入开发模式
npm run dev # 重新进入开发模式
```
**注:Windows 开发模式运行之后会在底部任务栏的右下角应用区出现 PicGo 的应用图标。**
### 生产模式
如果你需要自行构建,可以 `npm run electron:build` 开始进行构建。构建成功后,会在 `dist_electron` 目录里出现构建成功的相应安装文件。
如果你需要自行构建,可以 `npm run build` 开始进行构建。构建成功后,会在 `dist` 目录里出现构建成功的相应安装文件。
**注意**:如果你的网络环境不太好,可能会出现 `electron-builder` 下载 `electron` 二进制文件失败的情况。这个时候需要在 `npm run electron:build` 之前指定一下 `electron` 的源为国内源:
**注意**:如果你的网络环境不太好,可能会出现 `electron-builder` 下载 `electron` 二进制文件失败的情况。这个时候需要在 build 之前指定一下 `electron` 的源为国内源:
```bash
export ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
# 在 Windows 上,则可以使用 set ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ (无需引号)
npm run electron:build
npm run build
```
只需第一次构建的时候指定一下国内源即可。后续构建不需要特地指定。二进制文件下载在 `~/.electron/` 目录下。如果想要更新 `electron` 构建版本,可以删除 `~/.electron/` 目录,然后重新运行上一步,让 `electron-builder `去下载最新的 `electron` 二进制文件。
-32
View File
@@ -1,32 +0,0 @@
# Commented sections below can be used to run tests on the CI server
# https://simulatedgreg.gitbooks.io/electron-vue/content/en/testing.html#on-the-subject-of-ci-testing
version: 0.1.{build}
branches:
only:
- master
image: Visual Studio 2017
platform:
- x64
cache:
- '%APPDATA%\npm-cache'
- '%USERPROFILE%\.electron'
- '%USERPROFILE%\AppData\Local\Yarn\cache'
init:
- git config --global core.autocrlf input
install:
- ps: Install-Product node 16 x64
- git reset --hard HEAD
- yarn
- node --version
build_script:
#- yarn test
- yarn release
- yarn upload-dist
test: false
Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

+2 -2
View File
@@ -7,13 +7,13 @@
small(v-if="version") {{ version }}
h2.desc 图片上传+管理新体验
button.download(@click="goLink('https://github.com/Molunerfinn/picgo/releases')") 免费下载
button.download(@click="goLink('https://picgo.github.io/PicGo-Doc/zh/guide/')") 查看文档
button.download(@click="goLink('https://picgo.github.io/PicGo-Doc/guide/')") 查看文档
h3.desc
| 基于#[a(href="https://github.com/SimulatedGREG/electron-vue" target="_blank") electron-vue]开发
h3.desc
| 支持macOS,Windows,Linux
h3.desc
| 支持#[a(href="https://picgo.github.io/PicGo-Doc/zh/guide/config.html#%E6%8F%92%E4%BB%B6%E8%AE%BE%E7%BD%AE%EF%BC%88v2-0%EF%BC%89" target="_blank") 插件系统]让PicGo更强大
| 支持#[a(href="https://picgo.github.io/PicGo-Doc/guide/config.html#%E6%8F%92%E4%BB%B6%E8%AE%BE%E7%BD%AE%EF%BC%88v2-0%EF%BC%89" target="_blank") 插件系统]让PicGo更强大
#container.container-fluid
.row.ex-width
img.gallery.col-xs-10.col-xs-offset-1.col-md-offset-2.col-md-8(src="https://cdn.jsdelivr.net/gh/Molunerfinn/test/picgo-site/first.png")
+105
View File
@@ -0,0 +1,105 @@
/* eslint-disable no-template-curly-in-string */
import type { Configuration } from 'electron-builder'
const config: Configuration = {
appId: 'com.molunerfinn.picgo',
productName: 'PicGo',
publish: [
{
provider: 'github',
owner: 'Molunerfinn',
repo: 'PicGo',
releaseType: 'draft'
}
],
files: [
'dist_electron/**/*',
'node_modules/**/*',
'public/**/*',
'package.json',
'LICENSE',
'README.md'
],
extraResources: [
{
from: 'public',
to: 'public'
}
],
dmg: {
contents: [
{
x: 410,
y: 150,
type: 'link',
path: '/Applications'
},
{
x: 130,
y: 150,
type: 'file'
}
]
},
mac: {
icon: 'build/icons/512x512.png',
extendInfo: {
LSUIElement: 0
},
target: [
{
target: 'dmg',
arch: ['x64', 'arm64']
}
],
artifactName: 'PicGo-${version}-${arch}.${ext}'
},
win: {
icon: 'build/icons/icon.ico',
artifactName: 'PicGo-${version}-${arch}.exe',
target: [
{
target: 'nsis',
arch: ['x64']
},
{
target: 'nsis',
arch: ['ia32']
},
{
target: 'nsis',
arch: ['arm64']
}
]
},
nsis: {
shortcutName: 'PicGo',
oneClick: false,
allowToChangeInstallationDirectory: true,
buildUniversalInstaller: false,
include: 'build/installer.nsh'
},
linux: {
executableName: 'PicGo',
icon: 'build/icons/512x512.png',
artifactName: 'PicGo-${version}-${arch}.${ext}',
target: [
{
target: 'AppImage',
arch: ['x64', 'arm64']
},
{
target: 'deb',
arch: ['x64', 'arm64']
},
{
target: 'snap',
arch: ['x64']
}
],
maintainer: 'Molunerfinn',
category: 'Utility'
}
}
export default config
+58
View File
@@ -0,0 +1,58 @@
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
import vue from '@vitejs/plugin-vue'
// temp for webUtils
import electronRenderer from '@molunerfinn/vite-plugin-electron-renderer'
import { resolve } from 'path'
const alias = {
'@': resolve(__dirname, 'src/renderer'),
'~': resolve(__dirname, 'src'),
'#': resolve(__dirname, 'src/universal'),
root: resolve(__dirname, '.'),
apis: resolve(__dirname, 'src/main/apis'),
'@core': resolve(__dirname, 'src/main/apis/core')
}
export default defineConfig({
main: {
plugins: [externalizeDepsPlugin()],
resolve: { alias },
build: {
outDir: 'dist_electron/main',
rollupOptions: {
input: {
index: resolve(__dirname, 'src/background.ts')
}
}
}
},
preload: {
plugins: [externalizeDepsPlugin()],
resolve: { alias },
build: {
outDir: 'dist_electron/preload',
rollupOptions: {
input: {
index: resolve(__dirname, 'src/preload/index.ts')
}
}
}
},
renderer: {
root: 'src/renderer',
publicDir: resolve(__dirname, 'src/renderer/public'),
resolve: { alias },
plugins: [vue(), electronRenderer()],
build: {
outDir: 'dist_electron/renderer',
rollupOptions: {
input: {
index: resolve(__dirname, 'src/renderer/index.html')
}
}
},
server: {
port: 5173
}
}
})
+25 -24
View File
@@ -1,28 +1,36 @@
{
"name": "picgo",
"version": "2.4.0",
"version": "2.4.1-beta.0",
"private": true,
"main": "dist_electron/main/index.js",
"description": "A powerful & simple image uploader for creators.",
"author": {
"name": "Molunerfinn",
"email": "marksz@teamsz.xyz"
},
"scripts": {
"build": "vue-cli-service electron:build",
"lint": "vue-cli-service lint",
"build": "electron-vite build && electron-builder --config electron-builder.config.ts",
"build:win": "npm run build && electron-builder --config electron-builder.config.ts --win",
"build:mac": "npm run build && electron-builder --config electron-builder.config.ts --mac",
"build:linux": "npm run build && electron-builder --config electron-builder.config.ts --linux",
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.vue src/",
"bump": "bump-version",
"cz": "git-cz",
"dev": "vue-cli-service electron:serve",
"electron:build": "vue-cli-service electron:build",
"electron:serve": "vue-cli-service electron:serve",
"dev": "electron-vite dev",
"preview": "electron-vite preview",
"gen-i18n": "node ./scripts/gen-i18n-types.js",
"lint:fix": "eslint --fix --ext .js,.jsx,.ts,.tsx,.vue src/",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps",
"release": "vue-cli-service electron:build --publish always",
"upload-dist": "node ./scripts/upload-dist.js",
"lint:dpdm": "dpdm -T --tsconfig ./tsconfig.json --no-tree --no-warning --exit-code circular:1 src/background.ts"
},
"dependencies": {
"@element-plus/icons-vue": "^2.0.10",
"@element-plus/icons-vue": "^2.3.2",
"@picgo/i18n": "^1.0.0",
"@picgo/store": "^2.1.0",
"axios": "^0.19.0",
"clip-filepaths": "^0.3.0",
"compare-versions": "^4.1.3",
"core-js": "^3.27.1",
"element-plus": "^2.3.7",
@@ -48,7 +56,7 @@
"devDependencies": {
"@aws-sdk/client-s3": "^3.276.0",
"@aws-sdk/lib-storage": "^3.276.0",
"@babel/plugin-proposal-optional-chaining": "^7.16.7",
"@molunerfinn/vite-plugin-electron-renderer": "^0.14.7",
"@picgo/bump-version": "^1.1.2",
"@types/electron-devtools-installer": "^2.2.0",
"@types/fs-extra": "^9.0.13",
@@ -56,7 +64,7 @@
"@types/js-yaml": "^4.0.5",
"@types/lowdb": "^1.0.9",
"@types/multer": "^1.4.12",
"@types/node": "^16.10.2",
"@types/node": "^20",
"@types/request-promise-native": "^1.0.17",
"@types/semver": "^7.3.8",
"@types/tunnel": "^0.0.3",
@@ -64,21 +72,18 @@
"@types/write-file-atomic": "^4.0.0",
"@typescript-eslint/eslint-plugin": "^5.48.0",
"@typescript-eslint/parser": "^5.48.0",
"@vue/cli-plugin-babel": "^5.0.8",
"@vue/cli-plugin-eslint": "^5.0.8",
"@vue/cli-plugin-router": "^5.0.8",
"@vue/cli-plugin-typescript": "^5.0.8",
"@vue/cli-service": "^5.0.8",
"@vue/eslint-config-standard": "^8.0.1",
"@vue/eslint-config-typescript": "^11.0.2",
"@vue/runtime-dom": "^3.2.45",
"@vitejs/plugin-vue": "^6.0.2",
"@vue/eslint-config-standard": "8.0.1",
"@vue/eslint-config-typescript": "11.0.2",
"autoprefixer": "^10.4.14",
"conventional-changelog": "^3.1.18",
"cz-customizable": "^6.2.0",
"dotenv": "^16.0.1",
"dpdm": "^3.13.1",
"electron": "^16.0.6",
"electron": "^38",
"electron-builder": "26.0.12",
"electron-devtools-installer": "^3.2.0",
"electron-vite": "^4.0.1",
"eslint": "^8.31.0",
"eslint-config-standard": ">=16.0.0",
"eslint-plugin-import": "^2.24.2",
@@ -91,7 +96,7 @@
"stylus-loader": "^3.0.2",
"tailwindcss": "^3.3.2",
"typescript": "^4.4.3",
"vue-cli-plugin-electron-builder": "^3.0.0-alpha.4"
"vite": "^7.2.6"
},
"commitlint": {
"extends": [
@@ -110,9 +115,5 @@
"hooks": {
"commit-msg": "npm run lint:dpdm && commitlint -E HUSKY_GIT_PARAMS"
}
},
"resolutions": {
"@types/node": "^16.10.2",
"vue-cli-plugin-electron-builder/**/electron-builder": "23.3.3"
}
}
+25 -9
View File
@@ -1,6 +1,6 @@
// different platform has different format
// macos
// macos (dmg, x64 + arm64)
const darwin = [{
appNameWithPrefix: 'PicGo-',
ext: '.dmg',
@@ -13,33 +13,49 @@ const darwin = [{
'version-file': 'latest-mac.yml'
}]
// linux (AppImage, deb, snap)
const linux = [{
appNameWithPrefix: 'PicGo-',
ext: '.AppImage',
arch: '',
arch: '-arm64',
'version-file': 'latest-linux-arm64.yml'
}, {
appNameWithPrefix: 'PicGo-',
ext: '.AppImage',
arch: 'x86_64',
'version-file': 'latest-linux.yml'
}, {
appNameWithPrefix: 'picgo_',
appNameWithPrefix: 'PicGo-',
ext: '.deb',
arch: '-arm64',
'version-file': 'latest-linux-arm64.yml'
}, {
appNameWithPrefix: 'PicGo-',
ext: '.deb',
arch: 'amd64',
'version-file': 'latest-linux.yml'
}, {
appNameWithPrefix: 'PicGo-',
ext: '.snap',
arch: '_amd64',
arch: 'amd64',
'version-file': 'latest-linux.yml'
}]
// windows
// windows (nsis, x64 + ia32 + arm64)
const win32 = [{
appNameWithPrefix: 'PicGo-Setup-',
appNameWithPrefix: 'PicGo-',
ext: '.exe',
arch: '-ia32',
'version-file': 'latest.yml'
}, {
appNameWithPrefix: 'PicGo-Setup-',
appNameWithPrefix: 'PicGo-',
ext: '.exe',
arch: '-x64',
'version-file': 'latest.yml'
}, {
appNameWithPrefix: 'PicGo-Setup-',
appNameWithPrefix: 'PicGo-',
ext: '.exe',
arch: '', // 32 & 64
arch: '-arm64',
'version-file': 'latest.yml'
}]
+33 -17
View File
@@ -1,23 +1,39 @@
const pkg = require('../package.json')
const version = pkg.version
// TODO: use the same name format
const generateURL = (platform, ext, prefix = 'PicGo-') => {
return `https://picgo-release.molunerfinn.com/${version}/${prefix}${version}${platform}${ext}`
}
const platformExtList = [
['-arm64', '.dmg', 'PicGo-'],
['-x64', '.dmg', 'PicGo-'],
['', '.AppImage', 'PicGo-'],
['-ia32', '.exe', 'PicGo-Setup-'],
['-x64', '.exe', 'PicGo-Setup-'],
['', '.exe', 'PicGo-Setup-'],
['_amd64', '.snap', 'picgo_']
const generateURL = (arch, ext, prefix = 'PicGo-') => `https://release.picgo.app/${version}/${prefix}${version}${arch}${ext}`
const windows = [
{ label: '32 bit', arch: '-ia32', ext: '.exe' },
{ label: '64 bit', arch: '-x64', ext: '.exe' },
{ label: 'ARM64', arch: '-arm64', ext: '.exe' }
]
const links = platformExtList.map(([arch, ext, prefix]) => {
const markdownLink = `[${prefix}${version}${arch}${ext}](${generateURL(arch, ext, prefix)})`
return markdownLink
})
const macos = [
{ label: 'Intel', arch: '-x64', ext: '.dmg' },
{ label: 'Apple Silicon', arch: '-arm64', ext: '.dmg' }
]
console.log(links.join('\n'))
const linux = {
AppImage: [
{ label: '64 bit', arch: '-x64', ext: '.AppImage' },
{ label: 'ARM64', arch: '-arm64', ext: '.AppImage' }
],
Deb: [
{ label: '64 bit', arch: '-x64', ext: '.deb' },
{ label: 'ARM64', arch: '-arm64', ext: '.deb' }
],
Snap: [
{ label: '64 bit', arch: '-x64', ext: '.snap' }
]
}
const renderLine = (items) => items.map(({ label, arch, ext }) => `[${label}](${generateURL(arch, ext)})`).join(' | ')
const sections = [
`### Windows\n- ${renderLine(windows)}`,
`### macOS\n- ${renderLine(macos)}`,
`### Linux\n- AppImage: ${renderLine(linux.AppImage)}\n- Deb: ${renderLine(linux.Deb)}\n- Snap: ${renderLine(linux.Snap)}`
]
console.log(sections.join('\n\n'))
+23 -21
View File
@@ -9,14 +9,14 @@ const pkg = require('../package.json')
const configList = require('./config')
const mime = require('mime-types')
const path = require('path')
const distPath = path.join(__dirname, '../dist_electron')
const distPath = path.join(__dirname, '../dist')
const S3Client = require('@aws-sdk/client-s3').S3Client
const Upload = require('@aws-sdk/lib-storage').Upload
// const BUCKET = 'picgo-1251750343'
// const COS_SECRET_ID = process.env.PICGO_ENV_COS_SECRET_ID
// const COS_SECRET_KEY = process.env.PICGO_ENV_COS_SECRET_KEY
const S3_BUCKET = 'picgo'
const S3_BUCKET = 'release'
// const AREA = 'ap-chengdu'
const VERSION = pkg.version
const FILE_PATH = `${VERSION}/`
@@ -117,7 +117,7 @@ const uploadDist = async () => {
try {
const platform = process.platform
if (configList[platform]) {
let versionFileHasUploaded = false
const uploadedVersionFiles = new Set()
for (const [index, config] of configList[platform].entries()) {
const fileName = `${config.appNameWithPrefix}${VERSION}${config.arch}${config.ext}`
const filePath = path.join(distPath, fileName)
@@ -126,26 +126,27 @@ const uploadDist = async () => {
if (VERSION.toLocaleLowerCase().includes('beta')) {
versionFileName = versionFileName.replace('.yml', '.beta.yml')
}
const client = new S3Client(S3Options)
const uploadDistToS3 = new Upload({
client,
params: {
Bucket: S3_BUCKET,
Key: `${FILE_PATH}${fileName}`,
Body: fs.createReadStream(filePath),
ContentType: 'application/octet-stream'
}
})
// upload dist file
console.log('[PicGo Dist] Uploading...', fileName, `${index + 1}/${configList[platform].length}`)
uploadDistToS3.on('httpUploadProgress', progress => {
console.log(`[PicGo Dist] Uploading... ${progress.loaded}/${progress.total}`)
})
await uploadDistToS3.done()
if (fs.existsSync(filePath)) {
const uploadDistToS3 = new Upload({
client,
params: {
Bucket: S3_BUCKET,
Key: `${FILE_PATH}${fileName}`,
Body: fs.createReadStream(filePath),
ContentType: 'application/octet-stream'
}
})
// upload dist file
console.log('[PicGo Dist] Uploading...', fileName, `${index + 1}/${configList[platform].length}`)
uploadDistToS3.on('httpUploadProgress', progress => {
console.log(`[PicGo Dist] Uploading... ${progress.loaded}/${progress.total}`)
})
await uploadDistToS3.done()
}
// upload version file
if (!versionFileHasUploaded) {
if (!uploadedVersionFiles.has(versionFileName) && fs.existsSync(versionFilePath)) {
const uploadVersionFileToS3 = new Upload({
client,
params: {
@@ -157,7 +158,8 @@ const uploadDist = async () => {
})
console.log('[PicGo Version File] Uploading...', versionFileName)
await uploadVersionFileToS3.done()
versionFileHasUploaded = true
uploadedVersionFiles.add(versionFileName)
console.log('[PicGo Version File] Upload successfully')
}
}
} else {
+2
View File
@@ -1,5 +1,7 @@
import { initStaticPath } from '~/main/utils/env'
import { bootstrap } from '~/main/lifeCycle'
initStaticPath()
bootstrap.launchApp()
/**
+21 -35
View File
@@ -1,4 +1,3 @@
import fs from 'fs-extra'
import {
app,
Menu,
@@ -14,12 +13,13 @@ import windowManager from 'apis/app/window/windowManager'
import { IWindowList } from '#/types/enum'
import pasteTemplate from '~/main/utils/pasteTemplate'
import pkg from 'root/package.json'
import { ensureFilePath, handleCopyUrl } from '~/main/utils/common'
import { ensureFilePath, getClipboardFilePathList, handleCopyUrl } from '~/main/utils/common'
import { privacyManager } from '~/main/utils/privacyManager'
import { T } from '~/main/i18n'
import { isMacOSVersionGreaterThanOrEqualTo } from '~/main/utils/getMacOSVersion'
import { buildPicBedListMenu } from '~/main/events/remotes/menu'
import { isLinux, isMacOS } from '~/universal/utils/common'
import { getStaticPath } from '#/utils/staticPath'
let contextMenu: Menu | null
let menu: Menu | null
let tray: Tray | null
@@ -139,10 +139,10 @@ const getTrayIcon = () => {
if (process.platform === 'darwin') {
const isMacOSGreaterThan11 = isMacOSVersionGreaterThanOrEqualTo('11')
return isMacOSGreaterThan11
? `${__static}/menubar-newdarwinTemplate.png`
: `${__static}/menubar.png`
? getStaticPath('menubar-newdarwinTemplate.png')
: getStaticPath('menubar.png')
} else {
return `${__static}/menubar-nodarwin.png`
return getStaticPath('menubar-nodarwin.png')
}
}
@@ -164,33 +164,19 @@ export function createTray () {
if (process.platform === 'darwin') {
toggleWindow(bounds)
setTimeout(async () => {
const img = clipboard.readImage()
const obj: ImgInfo[] = []
if (!img.isEmpty()) {
// 从剪贴板来的图片默认转为png
// https://github.com/electron/electron/issues/9035
const imgPath = clipboard.read('public.file-url')
if (imgPath) {
const imgPathList = getClipboardFilePathList()
if (imgPathList.length > 0) {
for (const imgPath of imgPathList) {
const decodePath = ensureFilePath(imgPath)
if (decodePath === imgPath) {
obj.push({
imgUrl: imgPath
})
} else {
if (decodePath !== '') {
// 带有中文的路径,无法直接被img.src所使用,会被转义
const base64 = await fs.readFile(
decodePath.replace('file://', ''),
{ encoding: 'base64' }
)
obj.push({
imgUrl: `data:image/png;base64,${base64}`
})
}
}
} else {
obj.push({
imgUrl: decodePath
})
}
} else {
const img = clipboard.readImage()
if (!img.isEmpty()) {
const imgUrl = img.toDataURL()
// console.log(imgUrl)
obj.push({
width: img.getSize().width,
height: img.getSize().height,
@@ -217,9 +203,9 @@ export function createTray () {
tray.on('drag-enter', () => {
if (nativeTheme.shouldUseDarkColors) {
tray!.setImage(`${__static}/upload-dark.png`)
tray!.setImage(getStaticPath('upload-dark.png'))
} else {
tray!.setImage(`${__static}/upload.png`)
tray!.setImage(getStaticPath('upload.png'))
}
})
@@ -230,7 +216,7 @@ export function createTray () {
// drop-files only be supported in macOS
// so the tray window must be available
tray.on('drop-files', async (event: Event, files: string[]) => {
tray.on('drop-files', async (event, files: string[]) => {
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
const imgs = await uploader
@@ -268,10 +254,10 @@ export function createTray () {
export function handleDockIcon () {
if (isMacOS) {
if (db.get('settings.showDockIcon') !== false) {
app.dock.show()
app.dock.setMenu(createContextMenu())
app.dock?.show()
app.dock?.setMenu(createContextMenu())
} else {
app.dock.hide()
app.dock?.hide()
}
}
}
+6 -5
View File
@@ -12,7 +12,7 @@ import windowManager from 'apis/app/window/windowManager'
import { IWindowList } from '#/types/enum'
import util from 'util'
import { IPicGo } from 'picgo'
import { showNotification, calcDurationRange, getClipboardFilePath } from '~/main/utils/common'
import { showNotification, calcDurationRange, getClipboardFilePathList } from '~/main/utils/common'
import { GET_RENAME_FILE_NAME, RENAME_FILE_NAME, TALKING_DATA_EVENT } from '~/universal/events/constants'
import logger from '@core/picgo/logger'
import { T } from '~/main/i18n'
@@ -22,11 +22,12 @@ import { privacyManager } from '~/main/utils/privacyManager'
import writeFile from 'write-file-atomic'
import { CLIPBOARD_IMAGE_FOLDER } from '~/universal/utils/static'
import { cleanupFormUploaderFiles } from '~/main/utils/cleanupFormUploaderFiles'
import { IpcMainEvent } from 'electron/main'
const waitForRename = (window: BrowserWindow, id: number): Promise<string|null> => {
return new Promise((resolve) => {
const windowId = window.id
ipcMain.once(`${RENAME_FILE_NAME}${id}`, (evt: Event, newName: string) => {
ipcMain.once(`${RENAME_FILE_NAME}${id}`, (evt: IpcMainEvent, newName: string) => {
resolve(newName)
window.close()
})
@@ -119,8 +120,8 @@ class Uploader {
async uploadWithBuildInClipboard (): Promise<ImgInfo[]|false> {
let filePath = ''
try {
const imgPath = getClipboardFilePath()
if (!imgPath) {
const imgPath = getClipboardFilePathList()
if (!imgPath.length) {
const nativeImage = clipboard.readImage()
if (nativeImage.isEmpty()) {
return false
@@ -132,7 +133,7 @@ class Uploader {
await writeFile(filePath, buffer)
return await this.upload([filePath])
} else {
return await this.upload([imgPath])
return await this.upload(imgPath)
}
} catch (e: any) {
logger.error(e)
+6 -15
View File
@@ -1,21 +1,12 @@
const isDevelopment = process.env.NODE_ENV !== 'production'
import { buildRendererUrl } from '~/main/utils/env'
export const TRAY_WINDOW_URL = isDevelopment
? (process.env.WEBPACK_DEV_SERVER_URL as string)
: 'picgo://./index.html'
export const TRAY_WINDOW_URL = buildRendererUrl()
export const SETTING_WINDOW_URL = isDevelopment
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#main-page/upload`
: 'picgo://./index.html#main-page/upload'
export const SETTING_WINDOW_URL = buildRendererUrl('main-page/upload')
export const MINI_WINDOW_URL = isDevelopment
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#mini-page`
: 'picgo://./index.html#mini-page'
export const MINI_WINDOW_URL = buildRendererUrl('mini-page')
export const RENAME_WINDOW_URL = process.env.NODE_ENV === 'development'
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#rename-page`
: 'picgo://./index.html#rename-page'
export const RENAME_WINDOW_URL = buildRendererUrl('rename-page')
export const TOOLBOX_WINDOW_URL = process.env.NODE_ENV === 'development'
? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#toolbox-page`
: 'picgo://./index.html#toolbox-page'
export const TOOLBOX_WINDOW_URL = buildRendererUrl('toolbox-page')
+21 -33
View File
@@ -1,3 +1,4 @@
// import path from 'path'
import {
SETTING_WINDOW_URL,
TRAY_WINDOW_URL,
@@ -13,10 +14,19 @@ import { TOGGLE_SHORTKEY_MODIFIED_MODE } from '#/events/constants'
import { app } from 'electron'
import { T } from '~/main/i18n'
import { isLinux } from '~/universal/utils/common'
import { getStaticPath } from '#/utils/staticPath'
// import { URLSearchParams } from 'url'
const windowList = new Map<IWindowList, IWindowListItem>()
const defaultWebPreferences = {
// preload: path.join(__dirname, '../preload/index.js'),
nodeIntegration: true,
contextIsolation: false,
nodeIntegrationInWorker: true,
backgroundThrottling: false
}
const handleWindowParams = (windowURL: string) => {
// const [baseURL, hash = ''] = windowURL.split('#')
// const search = new URLSearchParams()
@@ -55,10 +65,7 @@ windowList.set(IWindowList.TRAY_WINDOW, {
transparent: true,
vibrancy: 'ultra-dark',
webPreferences: {
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
nodeIntegrationInWorker: true,
backgroundThrottling: false,
...defaultWebPreferences,
webSecurity: false
}
}
@@ -85,24 +92,18 @@ windowList.set(IWindowList.SETTING_WINDOW, {
fullscreenable: false,
resizable: false,
title: 'PicGo',
vibrancy: 'ultra-dark',
transparent: true,
skipTaskbar: !showDockIcon,
titleBarStyle: 'hidden',
webPreferences: {
backgroundThrottling: false,
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
nodeIntegrationInWorker: true,
...defaultWebPreferences,
webSecurity: false
}
}
if (process.platform !== 'darwin') {
options.show = false
options.frame = false
options.backgroundColor = '#3f3c37'
options.transparent = false
options.icon = `${__static}/logo.png`
options.icon = getStaticPath('logo.png')
options.skipTaskbar = false
}
return options
@@ -135,12 +136,9 @@ windowList.set(IWindowList.MINI_WINDOW, {
skipTaskbar: true,
resizable: false,
transparent: process.platform !== 'linux',
icon: `${__static}/logo.png`,
icon: getStaticPath('logo.png'),
webPreferences: {
backgroundThrottling: false,
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
nodeIntegrationInWorker: true
...defaultWebPreferences
}
}
@@ -164,19 +162,14 @@ windowList.set(IWindowList.RENAME_WINDOW, {
show: true,
fullscreenable: false,
resizable: false,
vibrancy: 'ultra-dark',
backgroundColor: 'rgba(26,40,42,0.9)',
webPreferences: {
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
nodeIntegrationInWorker: true,
backgroundThrottling: false
...defaultWebPreferences
}
}
if (process.platform !== 'darwin') {
options.show = true
options.backgroundColor = '#3f3c37'
options.autoHideMenuBar = true
options.transparent = false
}
return options
},
@@ -211,21 +204,16 @@ windowList.set(IWindowList.TOOLBOX_WINDOW, {
center: true,
fullscreenable: false,
resizable: false,
title: `PicGo ${T('TOOLBOX')}`,
vibrancy: 'ultra-dark',
icon: `${__static}/logo.png`,
backgroundColor: 'rgba(26,40,42,0.9)',
title: `PicGo-${T('TOOLBOX')}`,
icon: getStaticPath('logo.png'),
webPreferences: {
backgroundThrottling: false,
nodeIntegration: !!process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
nodeIntegrationInWorker: true,
...defaultWebPreferences,
webSecurity: false
}
}
if (process.platform !== 'darwin') {
options.backgroundColor = '#3f3c37'
options.autoHideMenuBar = true
options.transparent = false
}
return options
},
@@ -23,6 +23,10 @@ class WindowManager implements IWindowManager {
this.windowIdMap.set(window.id, name)
}
windowConfig.callback(window, this)
// https://github.com/electron/electron/issues/1594
window.on('page-title-updated', (evt) => {
evt.preventDefault()
})
window.on('close', () => {
this.deleteById(id)
})
+3 -1
View File
@@ -167,7 +167,9 @@ export default {
server.restart()
})
ipcMain.on(OPEN_DEVTOOLS, (event: IpcMainEvent) => {
event.sender.openDevTools()
event.sender.openDevTools({
mode: 'detach'
})
})
// menu & window methods
ipcMain.on(SHOW_MINI_PAGE_MENU, () => {
+2 -5
View File
@@ -7,6 +7,7 @@ import {
ipcMain,
clipboard
} from 'electron'
import fs from 'fs-extra'
import { IPasteStyle, IPicGoHelperType, IWindowList } from '#/types/enum'
import shortKeyHandler from 'apis/app/shortKey/shortKeyHandler'
import picgo from '@core/picgo'
@@ -39,11 +40,7 @@ import pasteTemplate from '../utils/pasteTemplate'
import { i18nManager, T } from '~/main/i18n'
import { rpcServer } from './rpc'
// eslint-disable-next-line
const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
// const PluginHandler = requireFunc('picgo/lib/PluginHandler').default
const STORE_PATH = path.dirname(dbPathChecker())
// const CONFIG_PATH = path.join(STORE_PATH, '/data.json')
interface GuiMenuItem {
label: string
@@ -84,7 +81,7 @@ const getPluginList = (): IPicGoPlugin[] => {
for (const i in pluginList) {
const plugin = picgo.pluginLoader.getPlugin(pluginList[i])!
const pluginPath = path.join(STORE_PATH, `/node_modules/${pluginList[i]}`)
const pluginPKG = requireFunc(path.join(pluginPath, 'package.json'))
const pluginPKG = fs.readJSONSync(path.join(pluginPath, 'package.json'), 'utf-8')
const uploaderName = plugin.uploader || ''
const transformerName = plugin.transformer || ''
let menu: Omit<IGuiMenuItem, 'handle'>[] = []
+3 -1
View File
@@ -105,7 +105,9 @@ const buildMainPageMenu = (win: BrowserWindow) => {
{
label: T('SHOW_DEVTOOLS'),
click () {
win?.webContents?.openDevTools()
win?.webContents?.openDevTools({
mode: 'detach'
})
}
},
{
+1 -1
View File
@@ -20,7 +20,7 @@ systemRouter
})
.add(IRPCActionType.SHOW_DOCK_ICON, async (args) => {
const [visible] = args as IShowDockIconArgs
app.dock[visible ? 'show' : 'hide']()
app.dock?.[visible ? 'show' : 'hide']()
const win = windowManager.get(IWindowList.SETTING_WINDOW)
if (!visible) {
win?.show()
+2 -1
View File
@@ -2,11 +2,12 @@ import yaml from 'js-yaml'
import { ObjectAdapter, I18n } from '@picgo/i18n'
import path from 'path'
import fs from 'fs-extra'
import { getStaticPath } from '#/utils/staticPath'
import { builtinI18nList } from '#/i18n'
class I18nManager {
private i18n: I18n | null = null
private builtinI18nFolder = path.join(__static, 'i18n')
private builtinI18nFolder = getStaticPath('i18n')
private outerI18nFolder = ''
private localesMap: Map<string, ILocales> = new Map()
private currentLanguage: string = 'zh-CN'
+3 -6
View File
@@ -5,9 +5,6 @@ import {
protocol,
Notification
} from 'electron'
import {
createProtocol
} from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
import beforeOpen from '~/main/utils/beforeOpen'
import ipcList from '~/main/events/ipcList'
@@ -38,8 +35,9 @@ import { initI18n } from '~/main/utils/handleI18n'
import { remoteNoticeHandler } from 'apis/app/remoteNotice'
import { isMacOS } from '../utils/getMacOSVersion'
import { isWindowShouldShowOnStartup } from '../apis/app/window/windowList'
import { initStaticPath, isDev } from '../utils/env'
const isDevelopment = process.env.NODE_ENV !== 'production'
const isDevelopment = isDev
const handleStartUpFiles = (argv: string[], cwd: string) => {
const files = getUploadFiles(argv, cwd, logger)
@@ -74,7 +72,6 @@ class LifeCycle {
private onReady () {
const readyFunction = async () => {
console.log('on ready')
createProtocol('picgo')
if (isDevelopment && !process.env.IS_TEST) {
// Install Vue Devtools
try {
@@ -140,7 +137,6 @@ class LifeCycle {
}
})
app.on('activate', () => {
createProtocol('picgo')
if (!windowManager.has(IWindowList.TRAY_WINDOW)) {
windowManager.create(IWindowList.TRAY_WINDOW)
}
@@ -200,6 +196,7 @@ class LifeCycle {
if (!gotTheLock) {
app.quit()
} else {
initStaticPath()
await this.beforeReady()
this.onReady()
this.onRunning()
+8 -7
View File
@@ -5,6 +5,7 @@ import { dbPathChecker } from 'apis/core/datastore/dbChecker'
import yaml from 'js-yaml'
import { i18nManager } from '~/main/i18n'
// import { ILocales } from '~/universal/types/i18n'
import { getStaticPath } from '#/utils/staticPath'
const configPath = dbPathChecker()
const CONFIG_DIR = path.dirname(configPath)
@@ -49,7 +50,7 @@ function resolveMacWorkFlow () {
return true
} else {
try {
copyFileOutsideOfElectronAsar(path.join(__static, 'Upload pictures with PicGo.workflow'), dest)
copyFileOutsideOfElectronAsar(getStaticPath('Upload pictures with PicGo.workflow'), dest)
} catch (e) {
console.log(e)
}
@@ -87,16 +88,16 @@ function resolveClipboardImageGenerator () {
function getClipboardFiles () {
const files = [
'/linux.sh',
'/mac.applescript',
'/windows.ps1',
'/windows10.ps1',
'/wsl.sh'
'linux.sh',
'mac.applescript',
'windows.ps1',
'windows10.ps1',
'wsl.sh'
]
return files.map(item => {
return {
origin: path.join(__static, item),
origin: getStaticPath(item),
dest: path.join(CONFIG_DIR, item)
}
})
+8 -4
View File
@@ -3,10 +3,14 @@ import fs from 'fs-extra'
import { getFormImageFolderPath } from '@core/datastore/dbChecker'
import logger from '@core/picgo/logger'
export const cleanupFormUploaderFiles = (filePathList?: string[]): void => {
export const cleanupFormUploaderFiles = (fileInfoList?: string[] | ImgInfo[]): void => {
const formImageFolderPath = getFormImageFolderPath()
if (Array.isArray(filePathList)) {
filePathList.forEach(async filePath => {
if (Array.isArray(fileInfoList)) {
fileInfoList.forEach(async fileInfo => {
const filePath = typeof fileInfo === 'string' ? fileInfo : fileInfo?.imgPath
if (!filePath) {
return
}
try {
// 检查文件路径是否在 formImageFolderPath 目录下
const relativePath = path.relative(formImageFolderPath, filePath)
@@ -17,7 +21,7 @@ export const cleanupFormUploaderFiles = (filePathList?: string[]): void => {
logger.info(`[PicGo] Deleted temp file: ${filePath}`)
}
} catch (error: any) {
logger.error(`[PicGo] Failed to delete temp file ${filePath}:`, error)
logger.error('[PicGo] Failed to delete temp file', filePath, error)
}
})
}
+4 -20
View File
@@ -2,6 +2,7 @@ import fs from 'fs-extra'
import db from '~/main/apis/core/datastore'
import { clipboard, Notification, dialog } from 'electron'
import { handleUrlEncode } from '~/universal/utils/common'
import { readClipboardFilePaths } from 'clip-filepaths'
export const handleCopyUrl = (str: string): void => {
if (db.get('settings.autoCopyUrl') !== false) {
@@ -97,26 +98,9 @@ export const ensureFilePath = (filePath: string, prefix = 'file://'): string =>
* for builtin clipboard to get image path from clipboard
* @returns
*/
export const getClipboardFilePath = (): string => {
// TODO: linux support
const img = clipboard.readImage()
if (img.isEmpty()) {
if (process.platform === 'win32') {
const imgPath = clipboard.readBuffer('FileNameW')?.toString('ucs2')?.replace(RegExp(String.fromCharCode(0), 'g'), '')
if (imgPath) {
return imgPath
}
}
} else {
if (process.platform === 'darwin') {
let imgPath = clipboard.read('public.file-url') // will get file://xxx/xxx
imgPath = ensureFilePath(imgPath)
if (imgPath) {
return imgPath.replace('file://', '')
}
}
}
return ''
export const getClipboardFilePathList = (): string[] => {
const { filePaths } = readClipboardFilePaths()
return filePaths
}
export const handleUrlEncodeWithSetting = (url: string) => {
+31
View File
@@ -0,0 +1,31 @@
import path from 'path'
import { app } from 'electron'
import { pathToFileURL } from 'url'
export const isDev = !app.isPackaged
const defaultStaticPath = process.env.STATIC_PATH || (isDev
? path.join(process.cwd(), 'public')
: path.join(process.resourcesPath, 'public'))
process.env.STATIC_PATH = defaultStaticPath
const rendererHtmlPath = path.join(__dirname, '../renderer/index.html')
export const initStaticPath = () => defaultStaticPath
export const getRendererBaseUrl = () => {
if (isDev && process.env.ELECTRON_RENDERER_URL) {
return process.env.ELECTRON_RENDERER_URL
}
return pathToFileURL(rendererHtmlPath).toString()
}
export const buildRendererUrl = (hash?: string) => {
const base = getRendererBaseUrl()
if (!hash) return base
const cleanedHash = hash.startsWith('#') ? hash : `#${hash}`
return `${base}${cleanedHash}`
}
export const getStaticPath = () => process.env.STATIC_PATH || defaultStaticPath
+13
View File
@@ -0,0 +1,13 @@
// temp no used
// will be refactor in future
import { contextBridge, webUtils } from 'electron'
const getFilePath = (file: File): string => webUtils.getPathForFile(file)
const electronApi = {
getFilePath
}
contextBridge.exposeInMainWorld('electronApi', electronApi)
export type ElectronApi = typeof electronApi
+10
View File
@@ -0,0 +1,10 @@
import { onBeforeMount, ref } from 'vue'
export const useOS = () => {
const os = ref<string>('')
onBeforeMount(() => {
os.value = process.platform
})
return os
}
+15
View File
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="referrer" content="never" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<title>PicGo</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./main.ts"></script>
</body>
</html>
+16 -18
View File
@@ -2,7 +2,6 @@
<div id="main-page">
<div
class="fake-title-bar"
:class="{ 'darwin': os === 'darwin' }"
>
<div class="fake-title-bar__title">
PicGo - {{ version }}
@@ -103,7 +102,6 @@
:offset="5"
style="height: 428px"
class="main-wrapper"
:class="{ 'darwin': os === 'darwin' }"
>
<router-view
v-slot="{ Component }"
@@ -236,11 +234,12 @@ import {
GET_PICBEDS
} from '~/universal/events/constants'
import { getConfig, sendToMain } from '@/utils/dataSender'
import { useOS } from '@/hooks/useOS'
const version = ref(process.env.NODE_ENV === 'production' ? pkg.version : 'Dev')
const routerConfig = reactive(config)
const defaultActive = ref(routerConfig.UPLOAD_PAGE)
const visible = ref(false)
const os = ref('')
const os = useOS()
const $router = useRouter()
const picBed: Ref<IPicBedType[]> = ref([])
const qrcodeVisible = ref(false)
@@ -250,7 +249,6 @@ const choosedPicBedForQRCode: Ref<string[]> = ref([])
const keepAlivePages = $router.getRoutes().filter(item => item.meta.keepAlive).map(item => item.name as string)
onBeforeMount(() => {
os.value = process.platform
sendToMain(GET_PICBEDS)
ipcRenderer.on(GET_PICBEDS, getPicBeds)
handleGetPicPeds()
@@ -350,7 +348,8 @@ export default {
}
</script>
<style lang='stylus'>
$darwinBg = transparentify(#172426, #000, 0.7)
$bg = transparentify(#172426, #000, 0.9)
$sideBg = transparentify(#000, 0.7)
.setting-list-scroll
height 425px
overflow-y auto
@@ -388,17 +387,16 @@ $darwinBg = transparentify(#172426, #000, 0.7)
line-height h
position fixed
z-index 100
&.darwin
background transparent
background-image linear-gradient(
to right,
transparent 0%,
transparent 167px,
$darwinBg 167px,
$darwinBg 100%
)
.fake-title-bar__title
padding-left 167px
background transparent
background-image linear-gradient(
to right,
$sideBg 0%,
$sideBg 170px,
$bg 170px,
$bg 100%
)
.fake-title-bar__title
padding-left 167px
.handle-bar
position absolute
top 2px
@@ -419,14 +417,14 @@ $darwinBg = transparentify(#172426, #000, 0.7)
&:hover
color #69C282
.main-wrapper
&.darwin
background $darwinBg
background $bg
.side-bar-menu
position fixed
height calc(100vh - 22px)
overflow-x hidden
overflow-y auto
width 170px
background $sideBg
.info-window
cursor pointer
position fixed
+10 -12
View File
@@ -1,27 +1,25 @@
import './renderer/assets/css/tailwind.css'
import './assets/css/tailwind.css'
import { createApp } from 'vue'
import App from './renderer/App.vue'
import router from './renderer/router'
import { webFrame } from 'electron'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-plus'
import 'element-plus/dist/index.css'
import { webFrame } from 'electron'
import VueLazyLoad from 'vue3-lazyload'
import axios from 'axios'
import { mainMixin } from './renderer/utils/mainMixin'
import { mainMixin } from './utils/mainMixin'
import { dragMixin } from '@/utils/mixin'
import { initTalkingData } from './renderer/utils/analytics'
import db from './renderer/utils/db'
import { i18nManager, T } from './renderer/i18n/index'
import { initTalkingData } from './utils/analytics'
import db from './utils/db'
import { i18nManager, T } from './i18n/index'
import { getConfig, saveConfig, sendToMain, triggerRPC } from '@/utils/dataSender'
import { store } from '@/store'
import vue3PhotoPreview from 'vue3-photo-preview'
import 'vue3-photo-preview/dist/index.css'
import { getRendererStaticFileUrl } from './utils/static'
webFrame.setVisualZoomLevelLimits(1, 1)
// do here before vue init
// handleURLParams()
const app = createApp(App)
app.config.globalProperties.$builtInPicBed = [
@@ -48,7 +46,7 @@ app.mixin(mainMixin)
app.mixin(dragMixin)
app.use(VueLazyLoad, {
error: `file://${__static.replace(/\\/g, '/')}/unknown-file-type.svg`
error: getRendererStaticFileUrl('unknown-file-type.svg')
})
app.use(ElementUI)
app.use(router)
+11 -7
View File
@@ -42,7 +42,10 @@ import {
isUrl
} from '~/universal/utils/common'
import { sendToMain } from '@/utils/dataSender'
const logo = require('../assets/squareLogo.png')
import { getFilePath } from '@/utils/common'
import { getRendererStaticFileUrl } from '@/utils/static'
import { useOS } from '@/hooks/useOS'
const logo = ref(getRendererStaticFileUrl('squareLogo.png'))
const dragover = ref(false)
const progress = ref(0)
const showProgress = ref(false)
@@ -52,10 +55,9 @@ const wX = ref(-1)
const wY = ref(-1)
const screenX = ref(-1)
const screenY = ref(-1)
const os = ref('')
const os = useOS()
onBeforeMount(() => {
os.value = process.platform
ipcRenderer.on('uploadProgress', (event: IpcRendererEvent, _progress: number) => {
if (_progress !== -1) {
showProgress.value = true
@@ -134,12 +136,14 @@ function onChange (e: any) {
function ipcSendFiles (files: FileList) {
const sendFiles: IFileWithPath[] = []
Array.from(files).forEach((item) => {
const obj = {
const filePath = getFilePath(item)
if (!filePath) return
sendFiles.push({
name: item.name,
path: item.path
}
sendFiles.push(obj)
path: filePath
})
})
if (!sendFiles.length) return
sendToMain('uploadChoosedFiles', sendFiles)
}
+1 -1
View File
@@ -131,7 +131,7 @@ function initLogLevel (logLevel: string | string[]) {
}
function goConfigPage () {
openURL('https://picgo.github.io/PicGo-Doc/zh/guide/config.html#picgo设置')
openURL('https://picgo.github.io/PicGo-Doc/guide/config.html#picgo设置')
}
</script>
+5 -10
View File
@@ -58,7 +58,6 @@
>
<div
class="plugin-item"
:class="{ 'darwin': os === 'darwin' }"
>
<div
v-if="!item.gui"
@@ -217,6 +216,7 @@ import { computed, ref, onBeforeMount, onBeforeUnmount, watch } from 'vue'
import { getConfig, saveConfig, sendRPC, sendToMain } from '@/utils/dataSender'
import { ElMessageBox } from 'element-plus'
import axios from 'axios'
import { getRendererStaticFileUrl } from '@/utils/static'
import { IRPCActionType } from '~/universal/types/enum'
const $confirm = ElMessageBox.confirm
const searchText = ref('')
@@ -231,8 +231,7 @@ const needReload = ref(false)
const pluginListToolTip = $T('PLUGIN_LIST')
const importLocalPluginToolTip = $T('PLUGIN_IMPORT_LOCAL')
// const id = ref('')
const os = ref('')
const defaultLogo = ref(`this.src="file://${__static.replace(/\\/g, '/')}/roundLogo.png"`)
const defaultLogo = ref(`this.src="${getRendererStaticFileUrl('roundLogo.png')}"`)
const $configForm = ref<InstanceType<typeof ConfigForm> | null>(null)
const npmSearchText = computed(() => {
return searchText.value.match('picgo-plugin-')
@@ -264,7 +263,6 @@ watch(dialogVisible, (val: boolean) => {
})
onBeforeMount(async () => {
os.value = process.platform
ipcRenderer.on('hideLoading', () => {
loading.value = false
})
@@ -549,7 +547,7 @@ export default {
}
</script>
<style lang='stylus'>
$darwinBg = #172426
$bg = #172426
#plugin-view
position relative
padding 0 20px 0
@@ -619,12 +617,9 @@ $darwinBg = #172426
padding 3px 8px
background #49B1F5
color #eee
&.darwin
background transparentify($darwinBg, #000, 0.75)
&:hover
background transparentify($darwinBg, #000, 0.85)
background transparentify($bg, #000, 0.75)
&:hover
background #333
background transparentify($bg, #000, 0.85)
&__logo
width 64px
height 64px
+2 -1
View File
@@ -103,9 +103,10 @@ import { IToolboxItemType, IToolboxItemCheckStatus, IRPCActionType } from '~/uni
import { T as $T } from '@/i18n'
import ToolboxStatusIcon from '@/components/ToolboxStatusIcon.vue'
import ToolboxHandler from '@/components/ToolboxHandler.vue'
import { getRendererStaticFileUrl } from '@/utils/static'
const $confirm = ElMessageBox.confirm
const defaultLogo = ref(`file://${__static.replace(/\\/g, '/')}/roundLogo.png`)
const defaultLogo = ref(getRendererStaticFileUrl('roundLogo.png'))
const activeTypes = ref<IToolboxItemType[]>([])
const fixList = reactive<IToolboxMap>({
[IToolboxItemType.IS_CONFIG_FILE_BROKEN]: {
+4 -3
View File
@@ -71,6 +71,7 @@ import { PASTE_TEXT, OPEN_WINDOW } from '#/events/constants'
import { IWindowList } from '#/types/enum'
import { sendToMain } from '@/utils/dataSender'
import { getRawData } from '@/utils/common'
import { IpcRendererEvent } from 'electron/renderer'
const files = ref<IResult<ImgInfo>[]>([])
const notification = reactive({
@@ -126,14 +127,14 @@ function uploadClipboardFiles () {
onBeforeMount(() => {
disableDragFile()
getData()
ipcRenderer.on('dragFiles', async (event: Event, _files: string[]) => {
ipcRenderer.on('dragFiles', async (event: IpcRendererEvent, _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: Event, files: ImgInfo[]) => {
ipcRenderer.on('clipboardFiles', (event: IpcRendererEvent, files: ImgInfo[]) => {
clipboardFiles.value = files
})
ipcRenderer.on('uploadFiles', async () => {
@@ -163,7 +164,6 @@ export default {
body::-webkit-scrollbar
width 0px
#tray-page
background-color transparent
.open-main-window
background #000
height 20px
@@ -204,6 +204,7 @@ body::-webkit-scrollbar
position absolute
top 20px
width 100%
background-color transparentify(#172426, #000, 0.9)
.img-list
padding 4px 8px
display flex
+8 -5
View File
@@ -102,6 +102,7 @@
// import { Component, Vue, Watch } from 'vue-property-decorator'
import { T as $T } from '@/i18n'
import $bus from '@/utils/bus'
import { getFilePath } from '@/utils/common'
import { getConfig, saveConfig, sendToMain } from '@/utils/dataSender'
import { CaretBottom, UploadFilled } from '@element-plus/icons-vue'
import {
@@ -218,12 +219,14 @@ function onChange (e: any) {
function ipcSendFiles (files: FileList) {
const sendFiles: IFileWithPath[] = []
Array.from(files).forEach((item) => {
const obj = {
const filePath = getFilePath(item)
if (!filePath) return
sendFiles.push({
name: item.name,
path: item.path
}
sendFiles.push(obj)
path: filePath
})
})
if (!sendFiles.length) return
sendToMain('uploadChoosedFiles', sendFiles)
}
@@ -272,7 +275,7 @@ async function getDefaultPicBed () {
configName.value = currentConfigName
}
function getPicBeds (event: Event, picBeds: IPicBedType[]) {
function getPicBeds (event: IpcRendererEvent, picBeds: IPicBedType[]) {
picBed.value = picBeds
getDefaultPicBed()
}
@@ -63,14 +63,15 @@
/>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { reactive } from 'vue'
import { T as $T } from '@/i18n/index'
import { ElMessage as $message } from 'element-plus'
import { sendRPC, sendToMain } from '@/utils/dataSender'
import { IRPCActionType } from '~/universal/types/enum'
import SwitchFormItem from '@/components/settings/SwitchFormItem.vue'
import { useOS } from '@/hooks/useOS'
const os = ref(process.platform)
const os = useOS()
interface IProps {
settings: ISettingForm
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

+5
View File
@@ -1,6 +1,7 @@
import { isReactive, isRef, toRaw, unref } from 'vue'
import { sendToMain } from './dataSender'
import { OPEN_URL, PICGO_OPEN_FILE } from '~/universal/events/constants'
import { webUtils } from 'electron'
const isDevelopment = process.env.NODE_ENV !== 'production'
/* eslint-disable camelcase */
@@ -70,3 +71,7 @@ export const openFile = (fileName: string) => {
export const openURL = (url: string) => {
sendToMain(OPEN_URL, url)
}
export const getFilePath = (file: File) => {
return webUtils.getPathForFile(file)
}
+1
View File
@@ -13,6 +13,7 @@ const isSpecialKey = (keyCode: number) => {
}
const keyDetect = (event: KeyboardEvent) => {
// TODO: remove process
const meta = process.platform === 'darwin' ? 'Cmd' : 'Super'
const specialKey = {
Ctrl: event.ctrlKey,
+3
View File
@@ -0,0 +1,3 @@
export const getRendererStaticFileUrl = (fileName: string) => {
return import.meta.env.BASE_URL + fileName
}
+5
View File
@@ -1,6 +1,10 @@
import Vue, { VNode } from 'vue'
declare global {
interface ElectronApi {
getFilePath: (file: File) => string
}
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
@@ -12,6 +16,7 @@ declare global {
}
interface Window {
electronApi: ElectronApi
TDAPP: {
onEvent: (EventId: string, Label?: string, MapKv?: IStringKeyMap) => void
}
+9 -2
View File
@@ -18,7 +18,13 @@ declare interface ErrnoException extends Error {
stack?: string;
}
declare let __static: string
declare namespace NodeJS {
interface ProcessEnv {
STATIC_PATH?: string
}
}
declare const __static: string
declare type ILogType = 'success' | 'info' | 'warn' | 'error'
@@ -101,6 +107,7 @@ interface IBrowserWindowOptions {
fullscreenable: boolean,
resizable: boolean,
webPreferences: {
preload?: string
nodeIntegration: boolean,
nodeIntegrationInWorker: boolean,
contextIsolation: boolean,
@@ -244,7 +251,7 @@ interface IShowInputBoxOption {
type IShowFileExplorerOption = IObj
type IUploadOption = string[]
type IUploadOption = string[] | ImgInfo[]
interface IShowNotificationOption {
title: string
+1 -1
View File
@@ -1,6 +1,6 @@
export const CLIPBOARD_IMAGE_FOLDER = 'picgo-clipboard-images'
export const FORM_IMAGE_FOLDER = 'picgo-form-images'
export const RELEASE_URL = 'https://api.github.com/repos/Molunerfinn/PicGo/releases'
export const RELEASE_URL_BACKUP = 'https://picgo-release.molunerfinn.com'
export const RELEASE_URL_BACKUP = 'https://release.picgo.app'
export const STABLE_RELEASE_URL = 'https://github.com/Molunerfinn/PicGo/releases/latest'
export const BETA_RELEASE_URL = 'https://github.com/Molunerfinn/PicGo/releases'
+5
View File
@@ -0,0 +1,5 @@
import path from 'path'
const staticBasePath = process.env.STATIC_PATH || path.join(process.cwd(), 'public')
export const getStaticPath = (...segments: string[]) => path.join(staticBasePath, ...segments)
+10 -7
View File
@@ -1,11 +1,11 @@
{
"compilerOptions": {
"target": "es2019", // https://github.com/TypeStrong/ts-loader/issues/1061
"target": "esnext", // https://github.com/TypeStrong/ts-loader/issues/1061
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"esModuleInterop": true,
"experimentalDecorators": true,
@@ -13,14 +13,15 @@
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env",
"vite/client",
"element-plus/global",
"vue3-photo-preview"
"vue3-photo-preview",
"electron"
],
"typeRoots": [
"./src/universal/types/",
"./node_modules/@types",
"./node_modules",
"./node_modules"
],
"paths": {
"@/*": [
@@ -54,7 +55,9 @@
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
"tests/**/*.tsx",
"electron.vite.config.ts",
"electron-builder.config.ts"
],
"exclude": [
"node_modules"
@@ -62,4 +65,4 @@
"vueCompilerOptions": {
"target": 3,
}
}
}
+2 -105
View File
@@ -3,9 +3,9 @@ function resolve (dir) {
return path.join(__dirname, dir)
}
const config = {
module.exports = {
configureWebpack: {
devtool: 'nosources-source-map'
devtool: process.env.NODE_ENV === 'development' ? 'source-map' : 'nosources-source-map'
},
chainWebpack: config => {
config.resolve.alias
@@ -13,108 +13,5 @@ const config = {
.set('~', resolve('src'))
.set('root', resolve('./'))
.set('#', resolve('src/universal'))
// define
// config.plugin('define')
// .tap(args => {
// return args
// })
},
pluginOptions: {
electronBuilder: {
nodeIntegration: true, // will remove in the future
customFileProtocol: 'picgo://./',
externals: ['picgo'],
chainWebpackMainProcess: config => {
config.resolve.alias
.set('@', resolve('src/renderer'))
.set('~', resolve('src'))
.set('root', resolve('./'))
.set('#', resolve('src/universal'))
.set('apis', resolve('src/main/apis'))
.set('@core', resolve('src/main/apis/core'))
config.resolve.mainFields
.clear()
.add('main') // fix some modules will use browser target
.add('module')
},
builderOptions: {
productName: 'PicGo',
appId: 'com.molunerfinn.picgo',
publish: [
{
provider: 'github',
owner: 'Molunerfinn',
repo: 'PicGo',
releaseType: 'draft'
}
],
dmg: {
contents: [
{
x: 410,
y: 150,
type: 'link',
path: '/Applications'
},
{
x: 130,
y: 150,
type: 'file'
}
]
},
mac: {
icon: 'build/icons/icon.icns',
extendInfo: {
LSUIElement: 0
},
target: [{
target: 'dmg',
arch: [
'x64',
'arm64'
]
}],
// eslint-disable-next-line no-template-curly-in-string
artifactName: 'PicGo-${version}-${arch}.dmg'
},
win: {
icon: 'build/icons/icon.ico',
// eslint-disable-next-line no-template-curly-in-string
artifactName: 'PicGo-Setup-${version}-${arch}.exe',
target: [{
target: 'nsis',
arch: [
'x64',
'ia32'
]
}]
},
nsis: {
shortcutName: 'PicGo',
oneClick: false,
allowToChangeInstallationDirectory: true,
include: 'build/installer.nsh'
},
linux: {
icon: 'build/icons/'
},
snap: {
publish: ['github']
}
}
}
}
}
if (process.env.NODE_ENV === 'development') {
config.configureWebpack = {
devtool: 'source-map'
}
// for dev main process hot reload
config.pluginOptions.electronBuilder.mainProcessWatch = ['src/main/**/*']
}
module.exports = {
...config
}
+2986 -5232
View File
File diff suppressed because it is too large Load Diff