mirror of
https://github.com/Molunerfinn/PicGo.git
synced 2026-09-20 11:17:32 +00:00
Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f695e7ccaf | ||
|
|
366ac11ee2 | ||
|
|
9d4ea8277d | ||
|
|
56f61d458e | ||
|
|
8e94b2a4d4 | ||
|
|
db627a450f | ||
|
|
070ce2b666 | ||
|
|
b421c4b42a | ||
|
|
d6c0a85a0f | ||
|
|
ca805f36f8 | ||
|
|
cccd2954db | ||
|
|
cfb6146de5 | ||
|
|
45b3227456 | ||
|
|
2450a524ff | ||
|
|
4a29bf2b50 | ||
|
|
24e4a829d8 | ||
|
|
e0d45fa7a2 | ||
|
|
de441a892e |
+1
-1
@@ -1 +1 @@
|
||||
custom: ["https://paypal.me/Molunerfinn"]
|
||||
github: ["Molunerfinn"]
|
||||
|
||||
+116
-41
@@ -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
|
||||
|
||||
@@ -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
@@ -21,4 +21,6 @@ test.js
|
||||
scripts/*.yml
|
||||
|
||||
#Electron-builder output
|
||||
/dist_electron
|
||||
/dist_electron
|
||||
.serena/
|
||||
dist/*
|
||||
@@ -0,0 +1 @@
|
||||
22
|
||||
Vendored
+11
-3
@@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
PicGo is an Electron + Vue 3 desktop client. Source lives in `src/`: `src/main` for main-process and IPC logic, `src/renderer` for Vue views, and `src/universal` for shared helpers (`types/`, `events/constants.ts`). `background.ts` wires Electron Builder. Static assets and locale YAML files stay in `public/` (add languages under `public/i18n/`), while `docs/` hosts user-facing guides. Automation scripts live in `scripts/`, and legacy tests sit under `test/unit` (Karma) and `test/e2e` (Spectron).
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
- `yarn install` — install dependencies; `npm install` is unsupported because native modules are patched for Yarn.
|
||||
- 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. 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.
|
||||
|
||||
## Commit & Pull Request Guidelines
|
||||
Commits follow the PicGo conventional preset enforced by Husky (`yarn lint:dpdm` + Commitlint). Stage your changes and run `yarn cz` to craft messages that pass CI. Pull requests should explain the change, link related issues, and attach UI screenshots or recordings. Note how you validated the work (dev server, build, Karma, Spectron) and call out migration or configuration steps reviewers must perform.
|
||||
|
||||
## Internationalization Tips
|
||||
Add locales by creating `public/i18n/<locale>.yml`, exposing its `LANG_DISPLAY_LABEL`, and registering it in `src/universal/i18n/index.ts`. Finish with `yarn gen-i18n` so the generated typings stay in sync.
|
||||
@@ -1,3 +1,43 @@
|
||||
## :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)
|
||||
|
||||
|
||||
### :pencil: Documentation
|
||||
|
||||
* add 2.4.0 changelog ([cccd295](https://github.com/Molunerfinn/PicGo/commit/cccd295))
|
||||
* add warp sponsor shoutout ([e0d45fa](https://github.com/Molunerfinn/PicGo/commit/e0d45fa))
|
||||
* add warp sponsor shoutout ([de441a8](https://github.com/Molunerfinn/PicGo/commit/de441a8))
|
||||
* update docs ([4a29bf2](https://github.com/Molunerfinn/PicGo/commit/4a29bf2))
|
||||
* update docs ([24e4a82](https://github.com/Molunerfinn/PicGo/commit/24e4a82))
|
||||
* update readme & warp sponsor link ([45b3227](https://github.com/Molunerfinn/PicGo/commit/45b3227))
|
||||
|
||||
|
||||
### :package: Chore
|
||||
|
||||
* change funding yml ([2450a52](https://github.com/Molunerfinn/PicGo/commit/2450a52))
|
||||
* update picgo core to 1.5.11 to solve url encode bug ([cfb6146](https://github.com/Molunerfinn/PicGo/commit/cfb6146))
|
||||
|
||||
|
||||
|
||||
# :tada: 2.4.0-beta.10 (2025-06-08)
|
||||
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
PicGo is an Electron-based cross-platform image upload tool that supports multiple image hosting services (图床) including SMMS, GitHub, Aliyun OSS, Qiniu, Tencent COS, and more. It's built with Vue 3 + TypeScript for the renderer process and Node.js for the main process.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Structure
|
||||
- **Main Process**: `src/main/` - Electron main process with Node.js capabilities
|
||||
- **Renderer Process**: `src/renderer/` - Vue 3 frontend (no direct Node.js access)
|
||||
- **Universal Code**: `src/universal/` - Shared code between processes
|
||||
- **Entry Points**:
|
||||
- `src/background.ts` - Main process bootstrap
|
||||
- `src/main.ts` - Renderer process entry
|
||||
|
||||
### Key Directories
|
||||
- `src/main/apis/` - Main process APIs (uploader, system, window management)
|
||||
- `src/main/server/` - HTTP server for external uploads
|
||||
- `src/renderer/pages/` - Vue components for different views
|
||||
- `src/renderer/store/` - Vuex-like state management
|
||||
- `public/i18n/` - Internationalization files
|
||||
- `test/` - Unit and e2e tests
|
||||
|
||||
### Data Storage
|
||||
- **Config**: JSON file at `~/.picgo/config.json` (via `@picgo/store`)
|
||||
- **Gallery**: Separate DB for uploaded images history
|
||||
- **Settings**: Stored in config with namespaced keys (`settings.*`)
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Setup & Install
|
||||
```bash
|
||||
yarn install # Use yarn, NOT npm install
|
||||
```
|
||||
|
||||
### Development
|
||||
```bash
|
||||
yarn dev # Start development mode with hot reload
|
||||
yarn electron:serve # Alias for dev
|
||||
```
|
||||
|
||||
### Build & Release
|
||||
```bash
|
||||
yarn build # Build for production
|
||||
yarn electron:build # Build for production
|
||||
yarn release # Build and publish release
|
||||
```
|
||||
|
||||
### Code Quality
|
||||
```bash
|
||||
yarn lint # Run ESLint
|
||||
yarn lint:fix # Auto-fix lint issues
|
||||
yarn lint:dpdm # Check circular dependencies
|
||||
yarn gen-i18n # Generate i18n type definitions
|
||||
```
|
||||
|
||||
### Testing
|
||||
```bash
|
||||
# Unit tests
|
||||
yarn test:unit # Run unit tests with Karma
|
||||
|
||||
# E2E tests
|
||||
yarn test:e2e # Run end-to-end tests
|
||||
```
|
||||
|
||||
### Git Workflow
|
||||
```bash
|
||||
yarn cz # Commit with conventional commits
|
||||
```
|
||||
|
||||
## Key Development Patterns
|
||||
|
||||
### Process Communication
|
||||
- Use IPC events for cross-process communication
|
||||
- Event names defined in `src/universal/events/constants.ts`
|
||||
- Main process handles Node.js operations, renderer sends requests
|
||||
|
||||
### Configuration
|
||||
- Settings stored in namespaced config keys
|
||||
- Use `saveConfig()` and `getConfig()` from renderer
|
||||
- Main process uses direct picgo instance APIs
|
||||
|
||||
### Internationalization
|
||||
- Translation files in `public/i18n/*.yml`
|
||||
- Run `yarn gen-i18n` after modifying translations
|
||||
- Use `T()` function for translations in renderer
|
||||
|
||||
### File Organization
|
||||
- **Main**: Node.js operations, file system, native features
|
||||
- **Renderer**: UI, Vue components, user interactions
|
||||
- **Universal**: Types, constants, shared utilities
|
||||
|
||||
## Build Configuration
|
||||
- **Electron Builder**: Configured in `vue.config.js`
|
||||
- **Platforms**: macOS (dmg), Windows (exe), Linux (AppImage, snap)
|
||||
- **Auto-updater**: Disabled (commented out in background.ts)
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Adding a new feature
|
||||
1. Determine if it belongs in main or renderer process
|
||||
2. Add events to `src/universal/events/constants.ts` if needed
|
||||
3. For Node.js operations, add IPC handlers in main process
|
||||
4. For UI, add Vue components in renderer
|
||||
|
||||
### Modifying i18n
|
||||
1. Update `public/i18n/[lang].yml`
|
||||
2. Run `yarn gen-i18n`
|
||||
3. Add language option in `src/universal/i18n/index.ts`
|
||||
|
||||
### Adding new picbed support
|
||||
1. Use picgo plugin system (external to core)
|
||||
2. Core picbed configs are in `src/renderer/pages/picbeds/`
|
||||
|
||||
## Environment Notes
|
||||
- **Development**: Uses `vue-cli-plugin-electron-builder`
|
||||
- **Production**: Built with `electron-builder`
|
||||
- **Testing**: Karma for unit tests, Spectron for e2e
|
||||
- **Hot reload**: Available for both main and renderer processes
|
||||
@@ -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://`前缀
|
||||
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
<div align="center" markdown="1">
|
||||
<sup>Special thanks to:</sup>
|
||||
<br>
|
||||
<a href="https://go.warp.dev/picgo">
|
||||
<img alt="Warp sponsorship" width="400" src="https://raw.githubusercontent.com/warpdotdev/brand-assets/refs/heads/main/Github/Sponsor/Warp-Github-LG-03.png">
|
||||
</a>
|
||||
|
||||
### [Warp, the intelligent terminal for developers](https://go.warp.dev/picgo)
|
||||
[Available for MacOS, Linux, & Windows](https://go.warp.dev/picgo)<br>
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<img src="https://raw.githubusercontent.com/Molunerfinn/test/master/picgo/New%20LOGO-150.png" alt="">
|
||||
<h1>PicGo</h1>
|
||||
@@ -50,19 +64,18 @@ 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)。**
|
||||
|
||||
## 下载安装
|
||||
|
||||
| 下载源 | 地址/安装方式 | 平台 | 备注 |
|
||||
|---|---|---|---|
|
||||
| GitHub Release | https://github.com/Molunerfinn/PicGo/releases | All | 国内下载速度可能会慢 |
|
||||
| [腾讯云COS](https://cloud.tencent.com/product/cos) | https://github.com/Molunerfinn/PicGo/releases 附在更新日志结尾 | All | 感谢 [腾讯云COS](https://cloud.tencent.com/product/cos) 提供的赞助支持 |
|
||||
| [山东大学镜像站](https://mirrors.sdu.edu.cn/) | https://mirrors.sdu.edu.cn/github-release/Molunerfinn_PicGo | All | 感谢 [山东大学镜像站](https://mirrors.sdu.edu.cn/) 提供的镜像支持 |
|
||||
| [Scoop](https://scoop.sh/) | `scoop bucket add extras` & `scoop install picgo` | Windows | 感谢 @huangnauh 和 @Gladtbam 的贡献 |
|
||||
| [Chocolatey](https://chocolatey.org/) | `choco install picgo` | Windows | 感谢 @iYato 的贡献 |
|
||||
| [Homebrew](https://brew.sh/) | `brew install picgo --cask` | macOS | 感谢 @womeimingzi11 的贡献 |
|
||||
| [AUR](https://aur.archlinux.org/packages/yay) | `yay -S picgo-appimage` | Arch-Linux | 感谢 @houbaron 的贡献 |
|
||||
| 下载源 | 地址/安装方式 | 平台 | 备注 |
|
||||
| --------------------------------------------- | ----------------------------------------------------------- | ---------- | ----------------------------------------------------------------- |
|
||||
| GitHub Release | https://github.com/Molunerfinn/PicGo/releases | All | 国内下载速度可能会慢 |
|
||||
| [山东大学镜像站](https://mirrors.sdu.edu.cn/) | https://mirrors.sdu.edu.cn/github-release/Molunerfinn_PicGo | All | 感谢 [山东大学镜像站](https://mirrors.sdu.edu.cn/) 提供的镜像支持 |
|
||||
| [Scoop](https://scoop.sh/) | `scoop bucket add extras` & `scoop install picgo` | Windows | 感谢 @huangnauh 和 @Gladtbam 的贡献 |
|
||||
| [Chocolatey](https://chocolatey.org/) | `choco install picgo` | Windows | 感谢 @iYato 的贡献 |
|
||||
| [Homebrew](https://brew.sh/) | `brew install picgo --cask` | macOS | 感谢 @womeimingzi11 的贡献 |
|
||||
| [AUR](https://aur.archlinux.org/packages/yay) | `yay -S picgo-appimage` | Arch-Linux | 感谢 @houbaron 的贡献 |
|
||||
|
||||
## 应用截图
|
||||
|
||||
@@ -90,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` 二进制文件。
|
||||
|
||||
@@ -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 |
@@ -0,0 +1,131 @@
|
||||
# PicGo 2.4.0 Changelog
|
||||
|
||||
## Features
|
||||
- 新增 相册页新增文件名展示,参考 #1050
|
||||
- 新增 相册中和顶部栏窗口中无法展示的图片或者 url 将会展示默认图片,参考#1050
|
||||

|
||||
- 新增 macOS 顶部栏窗口新增文件名展示,参考 #1054
|
||||
- 新增 同种类型图床支持多份配置,上传时可以指定某一份配置进行上传。感谢 @STDSuperman ,参考 #1016
|
||||

|
||||
- 新增 选择图床的菜单可以支持选择该图床类型某一项具体配置
|
||||

|
||||
- 新增 显示 dock 栏图标选项,参考 #1045
|
||||
<img width="787" alt="image" src="https://github.com/Molunerfinn/PicGo/assets/12621342/bb9492f1-6522-45ce-ae5d-c614901d8b06" />
|
||||
- 新增 PicGo 修复工具箱,可以自行排查一些问题
|
||||
<img width="324" alt="image" src="https://github.com/Molunerfinn/PicGo/assets/12621342/98cf6e64-7313-4ebe-83d0-aa86e4514109" />
|
||||
- 新增 对输出的 URL 进行 encode 转义的选项,参考 #731
|
||||
<img width="775" alt="image" src="https://github.com/Molunerfinn/PicGo/assets/12621342/6e0c13dd-3404-4b07-9c99-412321835b27" />
|
||||
- 新增 支持拖拽任意格式文件上传,参考 #1052
|
||||
- 新增 腾讯云 COS 支持 `Endpoint` 配置 和 `极智压缩` 配置。 感谢 @palmcivet @yc910920 的贡献!
|
||||

|
||||
- 新增 `tips` 配置渲染的支持,可以动态渲染 Uploader config 的 tips。支持 markdown 格式。参考 [tcyun uploader config](https://github.com/PicGo/PicGo-Core/blob/dev/src/plugins/uploader/tcyun.ts#L280)
|
||||

|
||||
- 新增 上传界面展示当前图床使用的配置名
|
||||

|
||||
- 新增 相册页工具栏,目前内置 `批量修改图片 URL HOST 的功能` 。参考 #875
|
||||
注意:需要先选中指定的图片,然后会根据已选中的图片进行修改,你可以通过图床筛选功能只筛选出需要修改的图片。
|
||||
例如,你有一批图片都是 `https://www.a.com/...` 打头的 URL,你想把 `www.a.com` 批量修改成 `www.b.com` ,就可以用这个功能
|
||||

|
||||
- 新增 `启动模式`,可以设置启动的时候是否要打开窗口。全平台支持 `静默启动`(默认值) & `打开主窗口`,Windows 和 Linux 额外支持 `打开 Mini 窗口`。参考 #915
|
||||
<img width="577" alt="image" src="https://github.com/Molunerfinn/PicGo/assets/12621342/7e63bb5c-44b0-480e-824f-3c2edbed4fbb" />
|
||||
- 新增 PicGo Server 支持表单形式上传图片。参考 #428 ,感谢 @happy-game
|
||||
表单字段为 files。参考截图:
|
||||
<img width="951" alt="image" src="https://github.com/user-attachments/assets/14244f1d-60f5-487f-bde6-6d0e009645fb" />
|
||||
|
||||
## Bug Fixes
|
||||
- 修复 windows 右键菜单配置生成脚本,参考 #1019
|
||||
- 修复 自定义链接 URL encode 问题,参考 #1112
|
||||
- 修复 日志写入可能存在死循环问题,参考 #1101
|
||||
- 修复 拖拽文件到顶部栏图标报错问题,参考 #1107
|
||||
- 修复 文件名 encode 问题。参考 #1121
|
||||
- 修复 GitHub 重名文件上传不再报错。
|
||||
- 修复 beta.2 版本部分样式问题
|
||||
- 修复 重命名窗口某些情况下显示文件名过慢的问题,参考 #1130
|
||||
- 修复 打开配置文件打开的是日志文件的 bug,参考 #1163
|
||||
- 修复 插件配置弹窗打开后无法正确读取和保存配置的问题。
|
||||
- 修复 无法新增图床配置的问题(新增变成了编辑)。参考 #1198,#1196
|
||||
- 修复 macOS 右键菜单消失问题。感谢 @muwoo 。参考 #1179
|
||||
- 修复 macOS 顶部栏窗口右键之后一闪而过的问题。 感谢 @QThans。 参考 #1217
|
||||
- 修复 图床配置页面配置项过多时无法滚动到底部的问题。参考 #1237
|
||||
- 修复 腾讯云 COS URL encode 的问题。参考 #1265
|
||||
- 修复 插件列表无法搜索的问题。 参考 #1297
|
||||
- 修复 剪贴板文件名丢失 `秒` 的问题。 参考 #1293
|
||||
- 修复 macOS 顶部栏点击图片复制链接失效的问题。 参考 #1280 , #1210
|
||||
- 修复 自动复制 URL 这个开关无法被关闭的问题。参考 #1294 ,感谢 @happy-game
|
||||
- 修复 wayland 里无法使用剪贴板图片的问题。参考 #1261 ,感谢 @happy-game
|
||||
- 修复 直接通过 URL 上传图片的时候,带有汉字的 URL 上传后,文件名被 encode 的问题。 参考 #1339
|
||||
|
||||
## Other
|
||||
- 由于 PicGo 存储的 COS 空间被恶意刷大量流量导致欠费,暂时停止 COS 渠道的 PicGo 分发。
|
||||
- 更新至 Vue3
|
||||
- 重构部分代码
|
||||
- 重构部分代码
|
||||
- 补充更详细的快捷键相关日志,参考 #1031
|
||||
- 已知问题:部分按钮样式有点问题,下个版本会修复
|
||||
- 更新 README中的 scoop 下载安装的部分,感谢 @wuhang2003
|
||||
|
||||
----------
|
||||
|
||||
# PicGo 2.4.0 Changelog
|
||||
|
||||
## Features
|
||||
- Add filename display in the gallery (#1050).
|
||||
- Add default placeholders when images/URLs cannot be shown in the gallery or tray window (#1050).
|
||||

|
||||
- Add filename display in the macOS tray window (#1054).
|
||||
- Allow multiple configs per uploader type and choose one for upload (thanks @STDSuperman, #1016).
|
||||

|
||||
- Allow the uploader selection menu to pick a specific config entry for that uploader type.
|
||||

|
||||
- Add Dock icon visibility option (#1045).
|
||||
<img width="787" alt="image" src="https://github.com/Molunerfinn/PicGo/assets/12621342/bb9492f1-6522-45ce-ae5d-c614901d8b06" />
|
||||
- Add PicGo Repair Toolbox for self-diagnosis.
|
||||
<img width="324" alt="image" src="https://github.com/Molunerfinn/PicGo/assets/12621342/98cf6e64-7313-4ebe-83d0-aa86e4514109" />
|
||||
- Add option to encode/escape output URLs (#731).
|
||||
<img width="775" alt="image" src="https://github.com/Molunerfinn/PicGo/assets/12621342/6e0c13dd-3404-4b07-9c99-412321835b27" />
|
||||
- Support drag-and-drop uploads for arbitrary file formats (#1052).
|
||||
- Tencent COS: add Endpoint and Intelligent Compression settings (thanks @palmcivet @yc910920).
|
||||

|
||||
- Add Markdown-rendered tips for uploader config (see tcyun uploader config).
|
||||

|
||||
- Show the active uploader config name in the upload screen.
|
||||

|
||||
- Gallery toolbar: bulk replace image URL host (#875).
|
||||
Note: select images first; you can filter by uploader; e.g., replace `https://www.a.com/...` with `https://www.b.com/...`.
|
||||

|
||||
- Add “Startup Mode”: Silent (default) / Main Window; Windows/Linux also support Mini Window (#915).
|
||||
<img width="577" alt="image" src="https://github.com/Molunerfinn/PicGo/assets/12621342/7e63bb5c-44b0-480e-824f-3c2edbed4fbb" />
|
||||
- PicGo Server: support multipart form uploads (field `files`, #428, thanks @happy-game).
|
||||
<img width="951" alt="image" src="https://github.com/user-attachments/assets/14244f1d-60f5-487f-bde6-6d0e009645fb" />
|
||||
|
||||
## Bug Fixes
|
||||
- Fix Windows context-menu config script generation (#1019).
|
||||
- Fix custom link URL encoding (#1112).
|
||||
- Fix potential logging dead loop (#1101).
|
||||
- Fix drag-to-tray upload error (#1107).
|
||||
- Fix filename encoding (#1121).
|
||||
- Prevent errors on GitHub uploads with duplicate filenames.
|
||||
- Fix beta.2 style issues.
|
||||
- Fix slow filename display in the rename window (#1130).
|
||||
- Fix “open config file” actually opening the log file (#1163).
|
||||
- Fix plugin config dialog not reading/saving correctly.
|
||||
- Fix inability to add new uploader configs (created as edit) (#1198, #1196).
|
||||
- Fix macOS context menu disappearing (thanks @muwoo, #1179).
|
||||
- Fix macOS tray window flashing after right-click (thanks @QThans, #1217).
|
||||
- Fix uploader config page not scrollable when many fields (#1237).
|
||||
- Fix Tencent COS URL encoding (#1265).
|
||||
- Fix plugin list search not working (#1297).
|
||||
- Fix clipboard filename losing “seconds” (#1293).
|
||||
- Fix macOS tray copy-link failing on click (#1280, #1210).
|
||||
- Fix auto-copy URL toggle not turning off (#1294, thanks @happy-game).
|
||||
- Fix Wayland clipboard image upload issue (#1261, thanks @happy-game).
|
||||
- Fix URL uploads with Chinese characters being encoded in filenames (#1339).
|
||||
|
||||
## Other
|
||||
- COS distribution paused due to malicious traffic charges.
|
||||
- Upgrade to Vue3.
|
||||
- Refactor parts of the code.
|
||||
- Refactor parts of the code (again).
|
||||
- Add more detailed hotkey logs (#1031).
|
||||
- Known issue: some button styles were incorrect (fixed in later betas).
|
||||
- Update README scoop installation section (thanks @wuhang2003).
|
||||
@@ -0,0 +1,48 @@
|
||||
# gen_changelog.md
|
||||
|
||||
This guide describes how to generate a consolidated changelog for any PicGo release series (e.g., 2.4.0, 2.5.0) from the GitHub release notes of its betas and finals.
|
||||
|
||||
## Source of truth
|
||||
- Use GitHub release pages only (e.g., `https://github.com/Molunerfinn/PicGo/releases/tag/vX.Y.Z-beta.N` and `vX.Y.Z` if present). You can fetch these via MCP GitHub APIs (e.g., `get_release_by_tag`, `list_releases`) instead of manual browsing.
|
||||
- Do **not** use `CHANGELOG.md` in the repo.
|
||||
- Preserve all text and images exactly as written in the releases.
|
||||
|
||||
## Structure
|
||||
- Target file: `changelog/X.Y.Z.md` (replace with the series version).
|
||||
- Three top-level sections: `## Features`, `## Bug Fixes`, `## Other`.
|
||||
- Do **not** nest content under individual beta version headers; merge all items into these sections.
|
||||
- Keep items in chronological order (early → late) within each section, mirroring the beta sequence.
|
||||
- Keep inline issue references, thanks, and notes as-is.
|
||||
- Remove download-link sections entirely.
|
||||
- After the Chinese sections, insert a line with `----------`, then add a full English translation with the same structure/content (including images).
|
||||
|
||||
## Formatting rules
|
||||
- Markdown, plain ASCII.
|
||||
- Bullet lists only; no numbered lists required.
|
||||
- Indent images under their bullet with two spaces to keep association clear.
|
||||
- Keep inline HTML image tags from the releases (e.g., `<img width="...">`) untouched.
|
||||
- Keep line breaks and multi-line notes intact.
|
||||
- Do not reword or summarize; copy content verbatim except for removing beta headers and download sections.
|
||||
- English translation must mirror the Chinese bullets in order and content (keep images alongside the translated bullets).
|
||||
|
||||
## Regeneration steps
|
||||
1) Collect all release bodies for the target series (e.g., `vX.Y.Z-beta.0…N` and, if present, `vX.Y.Z`) from GitHub releases.
|
||||
2) For each release, copy bullets and images into the appropriate section:
|
||||
- Features ↔ “Feature(s)” or “Features” blocks.
|
||||
- Bug Fixes ↔ “Bug Fixes” blocks.
|
||||
- Other ↔ “Other”, “Notice”, or misc notes that are not features/bugs.
|
||||
3) Omit “国内可下载链接” (or any download links) entirely.
|
||||
4) Drop beta subheadings; keep only section-level bullets in chronological order.
|
||||
5) Ensure images remain adjacent to their bullets with indentation.
|
||||
6) After the Chinese sections are complete, insert `----------` on its own line.
|
||||
7) Append the English translation, preserving bullet order and images, under `## Features`, `## Bug Fixes`, `## Other` again (same section titles, just English content; no “(English)” suffix).
|
||||
8) Save the result to `changelog/X.Y.Z.md`.
|
||||
|
||||
## Quick checklist
|
||||
- [ ] All features present with images kept.
|
||||
- [ ] All bug fixes present.
|
||||
- [ ] All “Other” notes present.
|
||||
- [ ] No beta headers.
|
||||
- [ ] No download links.
|
||||
- [ ] Chronological ordering preserved.
|
||||
- [ ] English translation present with matching bullets/images after `----------`.
|
||||
+207
-836
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PicGo - The Ultimate Image Upload & Management Tool</title>
|
||||
<meta name="description" content="Seamlessly upload images to multiple cloud storage services with a beautiful, cross-platform interface. Supports 20+ image hosting services." />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
"nav": {
|
||||
"home": "Home",
|
||||
"features": "Features",
|
||||
"plugins": "Plugins",
|
||||
"download": "Download",
|
||||
"docs": "Docs",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"hero": {
|
||||
"title": "PicGo",
|
||||
"subtitle": "The Ultimate Image Upload & Management Tool",
|
||||
"description": "Seamlessly upload images to multiple cloud storage services with a beautiful, cross-platform interface. Supports 20+ image hosting services with powerful plugin system.",
|
||||
"download": "Download Free",
|
||||
"viewDocs": "View Documentation",
|
||||
"currentVersion": "Current Version"
|
||||
},
|
||||
"features": {
|
||||
"title": "Powerful Features",
|
||||
"subtitle": "Everything you need for efficient image management",
|
||||
"multiPicbed": {
|
||||
"title": "Multi-Picbed Support",
|
||||
"description": "Support for 20+ image hosting services including GitHub, SMMS, Aliyun OSS, Qiniu, Tencent COS, and more. Switch between different picbeds seamlessly."
|
||||
},
|
||||
"pluginSystem": {
|
||||
"title": "Plugin System",
|
||||
"description": "Extend PicGo's functionality with powerful plugins. From custom uploaders to advanced image processing, the possibilities are endless."
|
||||
},
|
||||
"crossPlatform": {
|
||||
"title": "Cross-Platform",
|
||||
"description": "Available on macOS, Windows, and Linux with native performance and consistent user experience across all platforms."
|
||||
},
|
||||
"clipboardUpload": {
|
||||
"title": "Clipboard Upload",
|
||||
"description": "Upload images directly from your clipboard with a single shortcut. Perfect for quick screenshots and captures."
|
||||
},
|
||||
"batchUpload": {
|
||||
"title": "Batch Operations",
|
||||
"description": "Upload multiple images at once, rename files automatically, and manage your uploads efficiently with batch operations."
|
||||
},
|
||||
"galleryManagement": {
|
||||
"title": "Gallery Management",
|
||||
"description": "Keep track of all your uploaded images with a built-in gallery. Search, preview, and manage your image history with ease."
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"title": "Plugin Ecosystem",
|
||||
"subtitle": "Extend PicGo beyond imagination",
|
||||
"description": "With our powerful plugin system, you can add new image hosting services, customize upload workflows, integrate with other tools, and much more.",
|
||||
"viewPlugins": "Browse Plugins",
|
||||
"createPlugin": "Create Your Own Plugin"
|
||||
},
|
||||
"supportedServices": {
|
||||
"title": "Supported Services",
|
||||
"subtitle": "Connect with your favorite image hosting services",
|
||||
"github": "GitHub",
|
||||
"smms": "SM.MS",
|
||||
"aliyun": "Aliyun OSS",
|
||||
"qiniu": "Qiniu",
|
||||
"tencent": "Tencent COS",
|
||||
"upyun": "Upyun",
|
||||
"imgur": "Imgur",
|
||||
"weibo": "Weibo",
|
||||
"andMore": "And 15+ more..."
|
||||
},
|
||||
"download": {
|
||||
"title": "Download PicGo",
|
||||
"subtitle": "Available for all major platforms",
|
||||
"macos": "Download for macOS",
|
||||
"windows": "Download for Windows",
|
||||
"linux": "Download for Linux",
|
||||
"or": "or",
|
||||
"viewReleases": "View all releases"
|
||||
},
|
||||
"footer": {
|
||||
"copyright": "© 2017-2024 PicGo. Open source project maintained by",
|
||||
"author": "Molunerfinn",
|
||||
"license": "Licensed under MIT License",
|
||||
"links": {
|
||||
"github": "GitHub",
|
||||
"issues": "Issues",
|
||||
"discussions": "Discussions",
|
||||
"sponsor": "Sponsor"
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"switch": "Switch Language",
|
||||
"english": "English",
|
||||
"chinese": "中文"
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
"nav": {
|
||||
"home": "ホーム",
|
||||
"features": "機能",
|
||||
"plugins": "プラグイン",
|
||||
"download": "ダウンロード",
|
||||
"docs": "ドキュメント",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"hero": {
|
||||
"title": "PicGo",
|
||||
"subtitle": "究極の画像アップロード&管理ツール",
|
||||
"description": "美しいクロスプラットフォームインターフェースで、複数のクラウドストレージサービスに画像をシームレスにアップロード。20以上の画像ホスティングサービスをサポートし、強力なプラグインシステムを搭載。",
|
||||
"download": "無料ダウンロード",
|
||||
"viewDocs": "ドキュメントを見る",
|
||||
"currentVersion": "現在のバージョン"
|
||||
},
|
||||
"features": {
|
||||
"title": "強力な機能",
|
||||
"subtitle": "効率的な画像管理に必要なすべて",
|
||||
"multiPicbed": {
|
||||
"title": "マルチピクベッドサポート",
|
||||
"description": "GitHub、SMMS、Alibaba Cloud OSS、Qiniu、Tencent COSなど、20以上の画像ホスティングサービスをサポート。異なるピクベッド間をシームレスに切り替え。"
|
||||
},
|
||||
"pluginSystem": {
|
||||
"title": "プラグインシステム",
|
||||
"description": "強力なプラグインでPicGoの機能を拡張。カスタムアップローダーから高度な画像処理まで、可能性は無限大。"
|
||||
},
|
||||
"crossPlatform": {
|
||||
"title": "クロスプラットフォーム",
|
||||
"description": "macOS、Windows、Linuxで利用可能。すべてのプラットフォームでネイティブパフォーマンスと一貫したユーザー体験を提供。"
|
||||
},
|
||||
"clipboardUpload": {
|
||||
"title": "クリップボードアップロード",
|
||||
"description": "単一のショートカットでクリップボードから画像を直接アップロード。スクリーンショットやキャプチャーに最適。"
|
||||
},
|
||||
"batchUpload": {
|
||||
"title": "バッチ操作",
|
||||
"description": "複数の画像を一度にアップロードし、ファイルを自動的にリネーム。バッチ操作で効率的にアップロードを管理。"
|
||||
},
|
||||
"galleryManagement": {
|
||||
"title": "ギャラリー管理",
|
||||
"description": "内蔵ギャラリーですべてのアップロード画像を追跡。検索、プレビュー、画像履歴を簡単に管理。"
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"title": "プラグインエコシステム",
|
||||
"subtitle": "想像を超えてPicGoを拡張",
|
||||
"description": "強力なプラグインシステムにより、新しい画像ホスティングサービスを追加したり、アップロードワークフローをカスタマイズしたり、他のツールと統合したり、さらに多くのことが可能。",
|
||||
"viewPlugins": "プラグインを見る",
|
||||
"createPlugin": "独自のプラグインを作成"
|
||||
},
|
||||
"supportedServices": {
|
||||
"title": "サポートされているサービス",
|
||||
"subtitle": "お気に入りの画像ホスティングサービスと接続",
|
||||
"github": "GitHub",
|
||||
"smms": "SM.MS",
|
||||
"aliyun": "Alibaba Cloud OSS",
|
||||
"qiniu": "Qiniu",
|
||||
"tencent": "Tencent COS",
|
||||
"upyun": "Upyun",
|
||||
"imgur": "Imgur",
|
||||
"weibo": "Weibo",
|
||||
"andMore": "さらに15以上..."
|
||||
},
|
||||
"download": {
|
||||
"title": "PicGoをダウンロード",
|
||||
"subtitle": "すべての主要プラットフォームで利用可能",
|
||||
"macos": "macOS版をダウンロード",
|
||||
"windows": "Windows版をダウンロード",
|
||||
"linux": "Linux版をダウンロード",
|
||||
"or": "または",
|
||||
"viewReleases": "すべてのリリースを見る"
|
||||
},
|
||||
"footer": {
|
||||
"copyright": "© 2017-2024 PicGo。オープンソースプロジェクト、メンテナ:",
|
||||
"author": "Molunerfinn",
|
||||
"license": "MITライセンスの下で提供",
|
||||
"links": {
|
||||
"github": "GitHub",
|
||||
"issues": "問題報告",
|
||||
"discussions": "ディスカッション",
|
||||
"sponsor": "スポンサー"
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"switch": "言語を切り替え",
|
||||
"english": "English",
|
||||
"chinese": "中文"
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
"nav": {
|
||||
"home": "首页",
|
||||
"features": "特性",
|
||||
"plugins": "插件",
|
||||
"download": "下载",
|
||||
"docs": "文档",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"hero": {
|
||||
"title": "PicGo",
|
||||
"subtitle": "终极图片上传与管理工具",
|
||||
"description": "无缝上传图片到多个云存储服务,拥有美观的跨平台界面。支持20多种图床服务,配备强大的插件系统。",
|
||||
"download": "免费下载",
|
||||
"viewDocs": "查看文档",
|
||||
"currentVersion": "当前版本"
|
||||
},
|
||||
"features": {
|
||||
"title": "强大特性",
|
||||
"subtitle": "高效图片管理所需的一切",
|
||||
"multiPicbed": {
|
||||
"title": "多图床支持",
|
||||
"description": "支持20多种图床服务,包括GitHub、SMMS、阿里云OSS、七牛云、腾讯云COS等。无缝切换不同图床。"
|
||||
},
|
||||
"pluginSystem": {
|
||||
"title": "插件系统",
|
||||
"description": "通过强大的插件系统扩展PicGo功能。从自定义上传器到高级图片处理,可能性无限。"
|
||||
},
|
||||
"crossPlatform": {
|
||||
"title": "跨平台",
|
||||
"description": "支持macOS、Windows和Linux,原生性能,所有平台提供一致的用户体验。"
|
||||
},
|
||||
"clipboardUpload": {
|
||||
"title": "剪贴板上传",
|
||||
"description": "通过快捷键直接从剪贴板上传图片。完美适用于快速截图和捕获。"
|
||||
},
|
||||
"batchUpload": {
|
||||
"title": "批量操作",
|
||||
"description": "一次性上传多张图片,自动重命名文件,通过批量操作高效管理上传。"
|
||||
},
|
||||
"galleryManagement": {
|
||||
"title": "相册管理",
|
||||
"description": "通过内置相册跟踪所有上传图片。轻松搜索、预览和管理图片历史记录。"
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"title": "插件生态",
|
||||
"subtitle": "让PicGo超越想象",
|
||||
"description": "凭借强大的插件系统,您可以添加新的图床服务、自定义上传工作流、集成其他工具等等。",
|
||||
"viewPlugins": "浏览插件",
|
||||
"createPlugin": "创建您的插件"
|
||||
},
|
||||
"supportedServices": {
|
||||
"title": "支持的服务",
|
||||
"subtitle": "连接您喜爱的图床服务",
|
||||
"github": "GitHub",
|
||||
"smms": "SM.MS",
|
||||
"aliyun": "阿里云OSS",
|
||||
"qiniu": "七牛云",
|
||||
"tencent": "腾讯云COS",
|
||||
"upyun": "又拍云",
|
||||
"imgur": "Imgur",
|
||||
"weibo": "微博图床",
|
||||
"andMore": "以及15+更多..."
|
||||
},
|
||||
"download": {
|
||||
"title": "下载PicGo",
|
||||
"subtitle": "支持所有主流平台",
|
||||
"macos": "下载macOS版",
|
||||
"windows": "下载Windows版",
|
||||
"linux": "下载Linux版",
|
||||
"or": "或",
|
||||
"viewReleases": "查看所有版本"
|
||||
},
|
||||
"footer": {
|
||||
"copyright": "© 2017-2024 PicGo。由",
|
||||
"author": "Molunerfinn",
|
||||
"license": "维护的开源项目,MIT许可证",
|
||||
"links": {
|
||||
"github": "GitHub",
|
||||
"issues": "问题反馈",
|
||||
"discussions": "讨论",
|
||||
"sponsor": "赞助"
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"switch": "切换语言",
|
||||
"english": "English",
|
||||
"chinese": "中文"
|
||||
}
|
||||
}
|
||||
+6
-20
@@ -1,24 +1,10 @@
|
||||
import { createApp } from 'vue'
|
||||
import Vue from 'vue'
|
||||
import App from './APP.vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import en from './locales/en.json'
|
||||
import zhCN from './locales/zh-CN.json'
|
||||
import 'tailwindcss/tailwind.css'
|
||||
import 'melody.css'
|
||||
import axios from 'axios'
|
||||
|
||||
const messages = {
|
||||
en,
|
||||
'zh-CN': zhCN
|
||||
}
|
||||
Vue.prototype.$http = axios
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
fallbackLocale: 'en',
|
||||
messages
|
||||
})
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(i18n)
|
||||
app.config.globalProperties.$http = axios
|
||||
app.mount('#app')
|
||||
new Vue({
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "picgo-website",
|
||||
"version": "1.0.0",
|
||||
"description": "Modern PicGo official website",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"serve": "npx serve ."
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.4.31",
|
||||
"vue-i18n": "^9.13.1",
|
||||
"axios": "^1.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"vite": "^5.3.4",
|
||||
"tailwindcss": "^3.4.6",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"postcss": "^8.4.39",
|
||||
"serve": "^14.2.3"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
Generated
-1998
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{vue,js,ts,jsx,tsx}",
|
||||
"./**/*.{vue,js,ts,jsx,tsx}"
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
'sans': ['Inter', 'system-ui', 'sans-serif'],
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
+1
-4
@@ -4,10 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>PicGo - The Ultimate Image Upload & Management Tool</title>
|
||||
<meta name="description" content="Seamlessly upload images to multiple cloud storage services with a beautiful, cross-platform interface. Supports 20+ image hosting services.">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||
<title>PicGo</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
server: {
|
||||
port: 3000,
|
||||
open: true
|
||||
},
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
assetsDir: 'assets',
|
||||
sourcemap: true,
|
||||
target: 'es2022'
|
||||
},
|
||||
optimizeDeps: {
|
||||
include: ['vue', 'vue-i18n', 'axios']
|
||||
}
|
||||
})
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
})
|
||||
+26
-25
@@ -1,28 +1,36 @@
|
||||
{
|
||||
"name": "picgo",
|
||||
"version": "2.4.0-beta.10",
|
||||
"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",
|
||||
@@ -35,7 +43,7 @@
|
||||
"marked": "^7.0.4",
|
||||
"mitt": "^3.0.0",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"picgo": "^1.5.9",
|
||||
"picgo": "^1.5.11",
|
||||
"qrcode.vue": "^3.3.3",
|
||||
"shell-path": "2.1.0",
|
||||
"uuid": "^9.0.0",
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,4 +26,9 @@ elif [ "$XDG_SESSION_TYPE" = "wayland" ]; then
|
||||
echo "no image"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# fallback for unsupported session types
|
||||
echo >&2 "Error: Unsupported session type '$XDG_SESSION_TYPE'."
|
||||
echo >&2 "Solution: The variable of XDG_SESSION_TYPE must set as 'x11' or 'wayland'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
+25
-9
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { initStaticPath } from '~/main/utils/env'
|
||||
import { bootstrap } from '~/main/lifeCycle'
|
||||
|
||||
initStaticPath()
|
||||
bootstrap.launchApp()
|
||||
|
||||
/**
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -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, () => {
|
||||
|
||||
@@ -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'>[] = []
|
||||
|
||||
@@ -105,7 +105,9 @@ const buildMainPageMenu = (win: BrowserWindow) => {
|
||||
{
|
||||
label: T('SHOW_DEVTOOLS'),
|
||||
click () {
|
||||
win?.webContents?.openDevTools()
|
||||
win?.webContents?.openDevTools({
|
||||
mode: 'detach'
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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,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'
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,10 @@
|
||||
import { onBeforeMount, ref } from 'vue'
|
||||
|
||||
export const useOS = () => {
|
||||
const os = ref<string>('')
|
||||
|
||||
onBeforeMount(() => {
|
||||
os.value = process.platform
|
||||
})
|
||||
return os
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]: {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export const getRendererStaticFileUrl = (fileName: string) => {
|
||||
return import.meta.env.BASE_URL + fileName
|
||||
}
|
||||
Vendored
+5
@@ -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
|
||||
}
|
||||
|
||||
Vendored
+9
-2
@@ -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,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'
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user