From cc5129c35d0dc3cd9080944707edf5c099f835f2 Mon Sep 17 00:00:00 2001 From: fzk <458813868@qq.com> Date: Mon, 4 Dec 2023 11:39:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=92=89=E5=9B=BE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++- README.zh-CN.md | 14 ++- package.json | 8 +- packages/desktop/CHANGELOG.md | 4 + packages/desktop/electron/main/ipcMain.ts | 16 ++++ .../desktop/electron/preload/electronAPI.ts | 6 ++ packages/desktop/electron/win/pinImageWin.ts | 75 ++++++++++++++++ packages/desktop/package.json | 4 +- packages/server/src/index.ts | 4 + packages/web/CHANGELOG.md | 4 + packages/web/package.json | 2 +- packages/web/src/pages/pinImage.html | 16 ++++ .../web/src/pages/pinImage/index.module.scss | 9 ++ packages/web/src/pages/pinImage/index.tsx | 86 +++++++++++++++++++ packages/web/src/pages/viewImage/index.tsx | 12 ++- packages/web/vite.config.ts | 1 + 16 files changed, 252 insertions(+), 19 deletions(-) create mode 100644 packages/desktop/electron/win/pinImageWin.ts create mode 100644 packages/web/src/pages/pinImage.html create mode 100644 packages/web/src/pages/pinImage/index.module.scss create mode 100644 packages/web/src/pages/pinImage/index.tsx diff --git a/README.md b/README.md index fbe71631..04451635 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,16 @@ git clone https://github.com/027xiguapi/pear-rec.git cd pear-rec # Install dependencies pnpm install -# Rebuild electron -pnpm run rebuild:desktop # Run the web pnpm run dev:web +# Run the server +pnpm run dev:server +# Run the desktop +pnpm run dev:desktop +# Run the web +pnpm run start:web +# Run the desktop +pnpm run start:desktop # Build the web pnpm run build:web # Build the desktop diff --git a/README.zh-CN.md b/README.zh-CN.md index faf445f5..99a09aff 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -62,19 +62,17 @@ git clone https://gitee.com/xiguapi027/pear-rec.git cd pear-rec # 安装依赖 pnpm install -# 重新打包 electron -pnpm run rebuild:desktop # 调试页面 pnpm run dev:web -# 编译页面 -pnpm run build:web -# 查看页面 -pnpm run preview:web # 调试服务 pnpm run dev:server -# 调试 +# 调试软件 pnpm run dev:desktop -# 编译 +# 运行页面 +pnpm run start:web +# 运行软件 +pnpm run start:desktop +# 编译软件 pnpm run build:desktop ``` diff --git a/package.json b/package.json index d7ff00f4..80a14188 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,13 @@ "version": "1.1.0", "description": "pear-rec is a cross platform screenshot, screen recording, audio recording, and video recording software.", "scripts": { - "dev:desktop": "concurrently --names \"WEB,DESKTOP\" -c \"red,blue\" \"pnpm run -C packages/web dev\" \"wait-on tcp:9191 && pnpm run -C packages/desktop dev\"", + "start:desktop": "concurrently --names \"WEB,DESKTOP\" -c \"red,blue\" \"npm run dev:web\" \"wait-on tcp:9191 && pnpm run dev:desktop\"", + "dev:desktop": "pnpm run -C packages/desktop dev", "build:desktop": "pnpm run -C packages/desktop build && pnpm run project:desktop && pnpm run -C packages/desktop build:win", "project:desktop": "pnpm run -C packages/web build && node tools/copy-files-web2desktop.js", "rebuild:server": "pnpm run -C packages/server rebuild && pnpm run -C packages/desktop rebuild", - "dev:web": "concurrently --names \"SERVER,WEB\" -c \"red,auto\" \"pnpm run dev:server\" \"wait-on tcp:9190 && pnpm run -C packages/web dev\"", + "start:web": "concurrently --names \"SERVER,WEB\" -c \"red,auto\" \"npm run dev:server\" \"wait-on tcp:9190 && npm run dev:web\"", + "dev:web": "pnpm run -C packages/web dev", "build:web": "concurrently -s \"pnpm run -C packages/server dev\" \"pnpm run project:web\"", "only-build:web": "pnpm run -C packages/web build", "watch:web": "pnpm run -C packages/web watch", @@ -63,4 +65,4 @@ "url": "https://github.com/027xiguapi/pear-rec/issues" }, "license": "Apache-2.0" -} +} \ No newline at end of file diff --git a/packages/desktop/CHANGELOG.md b/packages/desktop/CHANGELOG.md index bb358fcb..a6cdb53c 100644 --- a/packages/desktop/CHANGELOG.md +++ b/packages/desktop/CHANGELOG.md @@ -1,5 +1,9 @@ # @pear-rec/desktop +## 1.3.0 + +feat: 增加钉图功能 + ## 1.2.11 feat: 打包发布到 git diff --git a/packages/desktop/electron/main/ipcMain.ts b/packages/desktop/electron/main/ipcMain.ts index eb32bc84..129f9696 100644 --- a/packages/desktop/electron/main/ipcMain.ts +++ b/packages/desktop/electron/main/ipcMain.ts @@ -11,6 +11,7 @@ import * as viewVideoWin from '../win/viewVideoWin'; import * as viewAudioWin from '../win/viewAudioWin'; import * as settingWin from '../win/settingWin'; import * as recordsWin from '../win/recordsWin'; +import * as pinImageWin from '../win/pinImageWin'; import * as utils from './utils'; import { editConfig } from './config'; @@ -367,6 +368,21 @@ function initIpcMain() { recordsWin.closeRecordsWin(); recordsWin.openRecordsWin(); }); + + // 钉图 + ipcMain.on('pi:open-win', (e, search) => { + console.log(111, search); + pinImageWin.openPinImageWin(search); + }); + ipcMain.on('pi:close-win', () => { + pinImageWin.closePinImageWin(); + }); + ipcMain.on('pi:minimize-win', () => { + pinImageWin.maximizePinImageWin(); + }); + ipcMain.on('pi:maximize-win', () => { + pinImageWin.maximizePinImageWin(); + }); } initIpcMain(); diff --git a/packages/desktop/electron/preload/electronAPI.ts b/packages/desktop/electron/preload/electronAPI.ts index bfb3c22e..f7de2e8d 100644 --- a/packages/desktop/electron/preload/electronAPI.ts +++ b/packages/desktop/electron/preload/electronAPI.ts @@ -97,4 +97,10 @@ contextBridge.exposeInMainWorld('electronAPI', { //re sendReOpenWin: () => ipcRenderer.send('re:open-win'), + + //pi + sendPiOpenWin: (search?: any) => ipcRenderer.send('pi:open-win', search), + sendPiCloseWin: () => ipcRenderer.send('pi:close-win'), + sendPiMinimizeWin: () => ipcRenderer.send('pi:minimize-win'), + sendPiMaximizeWin: () => ipcRenderer.send('pi:maximize-win'), }); diff --git a/packages/desktop/electron/win/pinImageWin.ts b/packages/desktop/electron/win/pinImageWin.ts new file mode 100644 index 00000000..a85f16d6 --- /dev/null +++ b/packages/desktop/electron/win/pinImageWin.ts @@ -0,0 +1,75 @@ +import { app, BrowserWindow, shell } from 'electron'; +import { join } from 'node:path'; +import { ICON, preload, url, DIST, WEB_URL } from '../main/contract'; + +const pinImageHtml = join(DIST, './pinImage.html'); +let pinImageWin: BrowserWindow | null = null; + +function createPinImageWin(search?: any): BrowserWindow { + pinImageWin = new BrowserWindow({ + title: 'pear-rec 图片', + icon: ICON, + height: 450, + width: 600, + frame: false, // 无边框窗口 + resizable: true, // 窗口大小是否可调整 + transparent: true, // 使窗口透明 + fullscreenable: false, // 窗口是否可以进入全屏状态 + alwaysOnTop: true, // 窗口是否永远在别的窗口的上面 + autoHideMenuBar: true, // 自动隐藏菜单栏 + webPreferences: { + preload, + }, + }); + + const imgUrl = search?.imgUrl || ''; + // pinImageWin.webContents.openDevTools(); + if (url) { + pinImageWin.loadURL(WEB_URL + `pinImage.html?imgUrl=${imgUrl}`); + } else { + pinImageWin.loadFile(pinImageHtml, { + search: `?imgUrl=${imgUrl}`, + }); + } + + return pinImageWin; +} + +// 打开关闭录屏窗口 +function closePinImageWin() { + pinImageWin?.isDestroyed() || pinImageWin?.close(); + pinImageWin = null; +} + +function openPinImageWin(search?: any) { + if (!pinImageWin || pinImageWin?.isDestroyed()) { + pinImageWin = createPinImageWin(search); + } + pinImageWin?.show(); +} + +function showPinImageWin() { + pinImageWin?.show(); +} + +function hidePinImageWin() { + pinImageWin?.hide(); +} + +function minimizePinImageWin() { + pinImageWin?.minimize(); +} + +function maximizePinImageWin() { + pinImageWin?.maximize(); +} + +export { + createPinImageWin, + closePinImageWin, + openPinImageWin, + showPinImageWin, + hidePinImageWin, + minimizePinImageWin, + maximizePinImageWin, +}; diff --git a/packages/desktop/package.json b/packages/desktop/package.json index f19a857f..7d2400b3 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@pear-rec/desktop", - "version": "1.2.11", + "version": "1.3.0", "main": "dist-electron/main/index.js", "description": "pear-rec", "author": { @@ -47,4 +47,4 @@ "engines": { "node": "^14.18.0 || >=16.0.0" } -} +} \ No newline at end of file diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 09816c6e..3180af01 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -16,6 +16,10 @@ export default function initApp() { app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); + app.use(function (err, req, res, next) { + console.error('server:', err.stack); + res.status(500).send('服务器内部错误'); + }); initConfig(); initApi(app); diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index 1b3fb844..b2b86183 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -1,5 +1,9 @@ # @pear-rec/web +## 1.3.0 + +feat: 增加钉图功能 + ## 1.2.14 fix: 录音选择格式 diff --git a/packages/web/package.json b/packages/web/package.json index 6ade1838..25879626 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@pear-rec/web", "private": true, - "version": "1.2.13", + "version": "1.3.0", "scripts": { "dev": "vite", "build": "rimraf dist && tsc && vite build", diff --git a/packages/web/src/pages/pinImage.html b/packages/web/src/pages/pinImage.html new file mode 100644 index 00000000..0e9d89a5 --- /dev/null +++ b/packages/web/src/pages/pinImage.html @@ -0,0 +1,16 @@ + + + + + + + + pear-rec | 图片 + + + +
+ + + + \ No newline at end of file diff --git a/packages/web/src/pages/pinImage/index.module.scss b/packages/web/src/pages/pinImage/index.module.scss new file mode 100644 index 00000000..a3e64fc8 --- /dev/null +++ b/packages/web/src/pages/pinImage/index.module.scss @@ -0,0 +1,9 @@ +.pinImage { + width: 100%; + height: 100vh; + overflow: hidden; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + -webkit-app-region: drag; +} diff --git a/packages/web/src/pages/pinImage/index.tsx b/packages/web/src/pages/pinImage/index.tsx new file mode 100644 index 00000000..a802637e --- /dev/null +++ b/packages/web/src/pages/pinImage/index.tsx @@ -0,0 +1,86 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import type { MenuProps } from 'antd'; +import ininitApp from '../../pages/main'; +import { Dropdown, theme } from 'antd'; +import { MinusOutlined, BorderOutlined, CloseOutlined } from '@ant-design/icons'; +import { useApi } from '../../api'; +import { useUserApi } from '../../api/user'; +import styles from './index.module.scss'; +const defaultImg = './imgs/th.webp'; + +const items: MenuProps['items'] = [ + { + label: '关闭', + key: '1', + icon: , + }, + { + label: '最小化', + key: '2', + icon: , + }, + { + label: '最大化', + key: '3', + icon: , + }, +]; + +const PinImage: React.FC = () => { + const { t } = useTranslation(); + const userApi = useUserApi(); + const userRef = useRef({} as any); + const [imgUrl, setImgUrl] = useState(''); + + useEffect(() => { + init(); + userRef.current.id || getCurrentUser(); + }, []); + + async function getCurrentUser() { + try { + const res = (await userApi.getCurrentUser()) as any; + if (res.code == 0) { + userRef.current = res.data; + } + } catch (err) { + console.log(err); + } + } + + async function init() { + const paramsString = location.search; + const searchParams = new URLSearchParams(paramsString); + let _imgUrl = searchParams.get('imgUrl') || defaultImg; + fetch(_imgUrl) + .then((response) => response.blob()) // 将获取到的图片转为 Blob + .then((blob) => { + setImgUrl(`url(${URL.createObjectURL(blob)})`); + }); + } + + const onClick: MenuProps['onClick'] = ({ key }) => { + if (key == '1') { + window.electronAPI.sendPiCloseWin(); + } else if (key == '2') { + window.electronAPI.sendPiMinimizeWin(); + } else { + window.electronAPI.sendPiMaximizeWin(); + } + }; + + return ( + +
+
+ ); +}; + +ininitApp(PinImage); +export default PinImage; diff --git a/packages/web/src/pages/viewImage/index.tsx b/packages/web/src/pages/viewImage/index.tsx index 9b582ba4..0f0c4868 100644 --- a/packages/web/src/pages/viewImage/index.tsx +++ b/packages/web/src/pages/viewImage/index.tsx @@ -201,9 +201,15 @@ const ViewImage = () => { } async function handleToggleAlwaysOnTopWin() { - const isAlwaysOnTop = await window.electronAPI?.invokeViSetIsAlwaysOnTop(); - const icon = document.querySelector('.viewer-always-on-top-win'); - isAlwaysOnTop ? icon.classList.add('current') : icon.classList.remove('current'); + const imgUrl = imgs[initialViewIndex]?.url; + if (window.isElectron) { + window.electronAPI.sendPiOpenWin({ imgUrl }); + } else { + window.open(`/pinImage.html?imgUrl=${imgUrl}`); + } + // const isAlwaysOnTop = await window.electronAPI?.invokeViSetIsAlwaysOnTop(); + // const icon = document.querySelector('.viewer-always-on-top-win'); + // isAlwaysOnTop ? icon.classList.add('current') : icon.classList.remove('current'); } async function initImgs() { diff --git a/packages/web/vite.config.ts b/packages/web/vite.config.ts index 08812499..c9433d6b 100644 --- a/packages/web/vite.config.ts +++ b/packages/web/vite.config.ts @@ -13,6 +13,7 @@ const buildOptionsProject = { recorderVideo: resolve(__dirname, 'src/pages/recorderVideo.html'), recorderAudio: resolve(__dirname, 'src/pages/recorderAudio.html'), viewImage: resolve(__dirname, 'src/pages/viewImage.html'), + pinImage: resolve(__dirname, 'src/pages/pinImage.html'), viewVideo: resolve(__dirname, 'src/pages/viewVideo.html'), setting: resolve(__dirname, 'src/pages/setting.html'), clipScreen: resolve(__dirname, 'src/pages/clipScreen.html'),