diff --git a/README.de-DE.md b/README.de-DE.md index 1e6d97d3..978779b9 100644 --- a/README.de-DE.md +++ b/README.de-DE.md @@ -69,9 +69,9 @@ pnpm run build:desktop ## Download -| OS | Windows | Linux | Macos | -| --- | --- | --- | --- | -| link | [Download](https://github.com/027xiguapi/pear-rec/releases/download/1.0.0-alpha/pear-rec_1.0.0-alpha.exe) | ◯ | ◯ | +| OS | Windows | Linux | Macos | +| ---- | ----------------------------------------------------------- | ----- | ----- | +| link | [Download](https://github.com/027xiguapi/pear-rec/releases) | ◯ | ◯ | ## Feedback diff --git a/README.md b/README.md index 04451635..2c9011c0 100644 --- a/README.md +++ b/README.md @@ -136,17 +136,11 @@ Features that have been ticked are the latest in the development process but may - [x] English - [x] German -## Test - -| OS | Windows | Linux | Macos | -| ---- | ------- | ----- | ----- | -| Test | 🟢 | ◯ | ◯ | - ## Download -| OS | Windows | Linux | Macos | -| --- | --- | --- | --- | -| link | [Download](https://github.com/027xiguapi/pear-rec/releases/download/1.0.0-alpha/pear-rec_1.0.0-alpha.exe) | ◯ | ◯ | +| OS | Windows | Linux | Macos | +| ---- | ----------------------------------------------------------- | ----- | ----- | +| link | [Download](https://github.com/027xiguapi/pear-rec/releases) | ◯ | ◯ | ## Feedback diff --git a/README.zh-CN.md b/README.zh-CN.md index 99a09aff..cc2986c8 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -144,17 +144,11 @@ pnpm run build:desktop - [x] 英语 - [x] 德语 -## 测试 - -| 系统 | Windows | Linux | Macos | -| ---- | ------- | ----- | ----- | -| 测试 | 🟢 | ◯ | ◯ | - ## Download -| 系统 | Windows | Linux | Macos | -| --- | --- | --- | --- | -| 链接 | [下载](https://github.com/027xiguapi/pear-rec/releases/download/1.0.0-alpha/pear-rec_1.0.0-alpha.exe) | ◯ | ◯ | +| 系统 | Windows | Linux | Macos | +| ---- | ------------------------------------------------------- | ----- | ----- | +| 链接 | [下载](https://github.com/027xiguapi/pear-rec/releases) | ◯ | ◯ | 国内可以用 [GitHub Proxy](https://ghproxy.com/) 加速下载 diff --git a/packages/desktop/CHANGELOG.md b/packages/desktop/CHANGELOG.md index 1634d5ad..f07e68e7 100644 --- a/packages/desktop/CHANGELOG.md +++ b/packages/desktop/CHANGELOG.md @@ -1,5 +1,9 @@ # @pear-rec/desktop +## 1.3.3 + +fix: 录屏 bug + ## 1.3.2 feat: 自动更新软件 diff --git a/packages/desktop/electron-builder.json5 b/packages/desktop/electron-builder.json5 index 2824aacb..509c4c28 100644 --- a/packages/desktop/electron-builder.json5 +++ b/packages/desktop/electron-builder.json5 @@ -3,19 +3,23 @@ */ { appId: 'com.electron.pear-rec', - asar: false, productName: 'pear-rec', copyright: 'Copyright © 2023 ${author}', + asar: false, + // asar: true, // extraResources: ['node_modules/sql.js', 'node_modules/typeorm'], + // asarUnpack: ['node_modules/sql.js', 'node_modules/typeorm'], directories: { output: 'release/${version}', }, files: ['dist-electron', 'dist'], mac: { + icon: 'build/mac/icon.icns', artifactName: '${productName}-Mac-${version}-Installer.${ext}', target: ['dmg', 'zip'], }, linux: { + icon: 'build/icons/png/1024x1024.png', target: ['AppImage'], artifactName: '${productName}-Linux-${version}.${ext}', }, diff --git a/packages/desktop/electron/win/clipScreenWin.ts b/packages/desktop/electron/win/clipScreenWin.ts index f9edfa54..5aebb140 100644 --- a/packages/desktop/electron/win/clipScreenWin.ts +++ b/packages/desktop/electron/win/clipScreenWin.ts @@ -1,129 +1,125 @@ -import { app, BrowserWindow, dialog, shell, screen } from "electron"; -import { join, dirname } from "node:path"; -import { ICON, preload, url, WEB_URL, DIST } from "../main/contract"; +import { app, BrowserWindow, dialog, shell, screen } from 'electron'; +import { join, dirname } from 'node:path'; +import { ICON, preload, url, WEB_URL, DIST } from '../main/contract'; import { - openRecorderScreenWin, - setBoundsRecorderScreenWin, - showRecorderScreenWin, - hideRecorderScreenWin, -} from "./recorderScreenWin"; + openRecorderScreenWin, + setBoundsRecorderScreenWin, + showRecorderScreenWin, + hideRecorderScreenWin, +} from './recorderScreenWin'; -const clipScreenHtml = join(DIST, "./clipScreen.html"); +const clipScreenHtml = join(DIST, './clipScreen.html'); let clipScreenWin: BrowserWindow | null = null; function createClipScreenWin(): BrowserWindow { - clipScreenWin = new BrowserWindow({ - title: "pear-rec_clipScreenWin", - icon: ICON, - autoHideMenuBar: true, // 自动隐藏菜单栏 - frame: false, // 无边框窗口 - resizable: true, // 窗口大小是否可调整 - transparent: true, // 使窗口透明 - fullscreenable: false, // 窗口是否可以进入全屏状态 - alwaysOnTop: true, // 窗口是否永远在别的窗口的上面 - // skipTaskbar: true, - webPreferences: { - preload, - }, - }); - - if (url) { - clipScreenWin.loadURL(WEB_URL + "clipScreen.html"); - // clipScreenWin.webContents.openDevTools(); - } else { - clipScreenWin.loadFile(clipScreenHtml); - } - - clipScreenWin.on("resize", () => { - const clipScreenWinBounds = getBoundsClipScreenWin(); - setBoundsRecorderScreenWin(clipScreenWinBounds); - }); - - clipScreenWin.on("move", () => { - const clipScreenWinBounds = getBoundsClipScreenWin(); - setBoundsRecorderScreenWin(clipScreenWinBounds); - }); - - clipScreenWin.on("restore", () => { - showRecorderScreenWin(); - }); - - clipScreenWin.on("minimize", () => { - hideRecorderScreenWin(); - }); - - return clipScreenWin; + clipScreenWin = new BrowserWindow({ + title: 'pear-rec_clipScreenWin', + icon: ICON, + autoHideMenuBar: true, // 自动隐藏菜单栏 + frame: false, // 无边框窗口 + resizable: true, // 窗口大小是否可调整 + transparent: true, // 使窗口透明 + fullscreenable: false, // 窗口是否可以进入全屏状态 + alwaysOnTop: true, // 窗口是否永远在别的窗口的上面 + // skipTaskbar: true, + webPreferences: { + preload, + }, + }); + + if (url) { + clipScreenWin.loadURL(WEB_URL + 'clipScreen.html'); + // clipScreenWin.webContents.openDevTools(); + } else { + clipScreenWin.loadFile(clipScreenHtml); + } + + clipScreenWin.on('resize', () => { + const clipScreenWinBounds = getBoundsClipScreenWin(); + setBoundsRecorderScreenWin(clipScreenWinBounds); + }); + + clipScreenWin.on('move', () => { + const clipScreenWinBounds = getBoundsClipScreenWin(); + setBoundsRecorderScreenWin(clipScreenWinBounds); + }); + + clipScreenWin.on('restore', () => { + showRecorderScreenWin(); + }); + + clipScreenWin.on('minimize', () => { + hideRecorderScreenWin(); + }); + + return clipScreenWin; } function closeClipScreenWin() { - clipScreenWin?.isDestroyed() || clipScreenWin?.close(); - clipScreenWin = null; + clipScreenWin?.isDestroyed() || clipScreenWin?.close(); + clipScreenWin = null; } function showClipScreenWin() { - clipScreenWin?.show(); + clipScreenWin?.show(); } function openClipScreenWin() { - if (!clipScreenWin || clipScreenWin?.isDestroyed()) { - clipScreenWin = createClipScreenWin(); - } + if (!clipScreenWin || clipScreenWin?.isDestroyed()) { + clipScreenWin = createClipScreenWin(); + } - clipScreenWin?.show(); - openRecorderScreenWin(); + clipScreenWin?.show(); + openRecorderScreenWin(); } function getBoundsClipScreenWin() { - return clipScreenWin?.getBounds(); + return clipScreenWin?.getBounds(); } function hideClipScreenWin() { - clipScreenWin?.hide(); + clipScreenWin?.hide(); } function setAlwaysOnTopClipScreenWin(isAlwaysOnTop: boolean) { - clipScreenWin?.setAlwaysOnTop(isAlwaysOnTop); + clipScreenWin?.setAlwaysOnTop(isAlwaysOnTop); } function setMovableClipScreenWin(movable: boolean) { - clipScreenWin?.setMovable(movable); + clipScreenWin?.setMovable(movable); } function setResizableClipScreenWin(resizable: boolean) { - clipScreenWin?.setResizable(resizable); + clipScreenWin?.setResizable(resizable); } function minimizeClipScreenWin() { - clipScreenWin?.minimize(); + clipScreenWin?.minimize(); } -function setIgnoreMouseEventsClipScreenWin( - event: any, - ignore: boolean, - options?: any, -) { - clipScreenWin?.setIgnoreMouseEvents(ignore, options); +function setIgnoreMouseEventsClipScreenWin(event: any, ignore: boolean, options?: any) { + clipScreenWin?.setIgnoreMouseEvents(ignore, options); } function setIsPlayClipScreenWin(isPlay: boolean) { - clipScreenWin?.webContents.send("cs:set-isPlay", isPlay); + clipScreenWin?.webContents.send('cs:set-isPlay', isPlay); } function setBoundsClipScreenWin(bounds: any) { - clipScreenWin?.setBounds({ ...bounds }); + clipScreenWin?.setBounds({ ...bounds }); } export { - showClipScreenWin, - closeClipScreenWin, - openClipScreenWin, - hideClipScreenWin, - getBoundsClipScreenWin, - setAlwaysOnTopClipScreenWin, - setIgnoreMouseEventsClipScreenWin, - setMovableClipScreenWin, - setResizableClipScreenWin, - setIsPlayClipScreenWin, - minimizeClipScreenWin, - setBoundsClipScreenWin, + showClipScreenWin, + closeClipScreenWin, + openClipScreenWin, + hideClipScreenWin, + getBoundsClipScreenWin, + setAlwaysOnTopClipScreenWin, + setIgnoreMouseEventsClipScreenWin, + setMovableClipScreenWin, + setResizableClipScreenWin, + setIsPlayClipScreenWin, + minimizeClipScreenWin, + setBoundsClipScreenWin, }; diff --git a/packages/desktop/electron/win/recorderFullScreenWin.ts b/packages/desktop/electron/win/recorderFullScreenWin.ts index 761c0ede..610131cc 100644 --- a/packages/desktop/electron/win/recorderFullScreenWin.ts +++ b/packages/desktop/electron/win/recorderFullScreenWin.ts @@ -2,7 +2,7 @@ import { app, BrowserWindow, dialog, shell, screen, Rectangle } from 'electron'; import { join, basename, dirname } from 'node:path'; import { preload, url, DIST, ICON, WEB_URL, DIST_ELECTRON } from '../main/contract'; -const recorderFullScreenHtml = join(DIST, './recordeFullScreen.html'); +const recorderFullScreenHtml = join(DIST, './recorderFullScreen.html'); let recorderFullScreenWin: BrowserWindow | null = null; function createRecorderFullScreenWin(): BrowserWindow { @@ -27,10 +27,10 @@ function createRecorderFullScreenWin(): BrowserWindow { recorderFullScreenWin?.setResizable(false); if (url) { recorderFullScreenWin.loadURL(WEB_URL + `recorderFullScreen.html`); - // recorderFullScreenWin.webContents.openDevTools(); } else { recorderFullScreenWin.loadFile(recorderFullScreenHtml); } + // recorderFullScreenWin.webContents.openDevTools(); return recorderFullScreenWin; } diff --git a/packages/desktop/electron/win/recorderScreenWin.ts b/packages/desktop/electron/win/recorderScreenWin.ts index 8984bc30..0413b76a 100644 --- a/packages/desktop/electron/win/recorderScreenWin.ts +++ b/packages/desktop/electron/win/recorderScreenWin.ts @@ -9,72 +9,46 @@ import { const recorderScreenHtml = join(DIST, './recorderScreen.html'); let recorderScreenWin: BrowserWindow | null = null; -let isFullScreen: boolean = false; function createRecorderScreenWin(search?: any): BrowserWindow { - isFullScreen = search?.isFullScreen || false; - if (!isFullScreen) { - const { x, y, width, height } = getBoundsClipScreenWin() as Rectangle; - let recorderScreenWinX = x; - let recorderScreenWinY = y + height; - - recorderScreenWin = new BrowserWindow({ - title: 'pear-rec 录屏', - icon: ICON, - x: recorderScreenWinX, - y: recorderScreenWinY, - width: width, - height: 34, - autoHideMenuBar: true, // 自动隐藏菜单栏 - frame: false, // 无边框窗口 - hasShadow: false, // 窗口是否有阴影 - fullscreenable: false, // 窗口是否可以进入全屏状态 - alwaysOnTop: true, // 窗口是否永远在别的窗口的上面 - skipTaskbar: true, - webPreferences: { - preload, - }, - }); - } else { - recorderScreenWin = new BrowserWindow({ - title: 'pear-rec 录屏', - icon: ICON, - height: 40, - width: 365, - center: true, - transparent: true, // 使窗口透明 - autoHideMenuBar: true, // 自动隐藏菜单栏 - frame: false, // 无边框窗口 - hasShadow: false, // 窗口是否有阴影 - fullscreenable: false, // 窗口是否可以进入全屏状态 - alwaysOnTop: true, // 窗口是否永远在别的窗口的上面 - skipTaskbar: true, - webPreferences: { - preload, - }, - }); - recorderScreenWin?.setBounds({ y: 0 }); - } + const { x, y, width, height } = getBoundsClipScreenWin() as Rectangle; + let recorderScreenWinX = x; + let recorderScreenWinY = y + height; + + recorderScreenWin = new BrowserWindow({ + title: 'pear-rec 录屏', + icon: ICON, + x: recorderScreenWinX, + y: recorderScreenWinY, + width: width, + height: 34, + autoHideMenuBar: true, // 自动隐藏菜单栏 + frame: false, // 无边框窗口 + hasShadow: false, // 窗口是否有阴影 + fullscreenable: false, // 窗口是否可以进入全屏状态 + alwaysOnTop: true, // 窗口是否永远在别的窗口的上面 + skipTaskbar: true, + webPreferences: { + preload, + }, + }); recorderScreenWin?.setResizable(false); if (url) { - recorderScreenWin.loadURL(WEB_URL + `recorderScreen.html?isFullScreen=${isFullScreen}`); + recorderScreenWin.loadURL(WEB_URL + `recorderScreen.html`); // recorderScreenWin.webContents.openDevTools(); } else { - recorderScreenWin.loadFile(recorderScreenHtml, { - search: `?isFullScreen=${isFullScreen}`, - }); + recorderScreenWin.loadFile(recorderScreenHtml); } recorderScreenWin.on('move', () => { const recorderScreenWinBounds = getBoundsRecorderScreenWin() as Rectangle; const clipScreenWinBounds = getBoundsClipScreenWin() as Rectangle; - isFullScreen || - setBoundsClipScreenWin({ - x: recorderScreenWinBounds.x, - y: recorderScreenWinBounds.y - clipScreenWinBounds.height, - width: clipScreenWinBounds.width, - height: clipScreenWinBounds.height, - }); + setBoundsClipScreenWin({ + x: recorderScreenWinBounds.x, + y: recorderScreenWinBounds.y - clipScreenWinBounds.height, + width: clipScreenWinBounds.width, + height: clipScreenWinBounds.height, + }); }); return recorderScreenWin; @@ -123,11 +97,11 @@ function getBoundsRecorderScreenWin() { } function setMovableRecorderScreenWin(movable: boolean) { - isFullScreen || recorderScreenWin?.setMovable(movable); + recorderScreenWin?.setMovable(movable); } function setResizableRecorderScreenWin(resizable: boolean) { - isFullScreen || recorderScreenWin?.setResizable(resizable); + recorderScreenWin?.setResizable(resizable); } function setAlwaysOnTopRecorderScreenWin(isAlwaysOnTop: boolean) { @@ -146,25 +120,6 @@ function getCursorScreenPointRecorderScreenWin() { return screen.getCursorScreenPoint(); } -function shotScreen(imgUrl: any) { - const { x, y, width, height } = getBoundsClipScreenWin() as Rectangle; - // const filePath = getFilePath() as any; - // const result = join(`${filePath}/ss`, `shotScreen_${+new Date()}.jpg`); - // Jimp.read(imgUrl, function (err, img) { - // if (err) { - // console.log(`err: shotScreen ${err}`); - // } else { - // img.crop(x + 1, y + 1, width - 2, height - 2).write(result); - - // setTimeout(() => { - // recorderScreenWin?.webContents.send('rs:get-shot-screen', result); - // // closeRecorderScreenWin(); - // // shell.showItemInFolder(result); - // }, 500); - // } - // }); -} - function setBoundsRecorderScreenWin(clipScreenWinBounds: any) { let { x, y, width, height } = clipScreenWinBounds; let recorderScreenWinX = x; @@ -199,5 +154,4 @@ export { isFocusedRecorderScreenWin, focusRecorderScreenWin, setBoundsRecorderScreenWin, - shotScreen, }; diff --git a/packages/desktop/package.json b/packages/desktop/package.json index d8623359..bdecccdb 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@pear-rec/desktop", - "version": "1.3.2", + "version": "1.3.3", "main": "dist-electron/main/index.js", "description": "pear-rec", "author": { diff --git a/packages/server/rollup.config.mjs b/packages/server/rollup.config.mjs index 48c2a3a6..5ba0f3b7 100644 --- a/packages/server/rollup.config.mjs +++ b/packages/server/rollup.config.mjs @@ -10,7 +10,7 @@ export default { format: 'es', }, context: 'window', - external: ['typeorm'], + external: ['typeorm', 'sql.js'], plugins: [ nodeResolve({ preferBuiltins: true }), commonjs({ ignoreDynamicRequires: true }), diff --git a/packages/timer/src/Timer/digit/index.module.scss b/packages/timer/src/Timer/digit/index.module.scss index 036b2cc8..10a83a19 100644 --- a/packages/timer/src/Timer/digit/index.module.scss +++ b/packages/timer/src/Timer/digit/index.module.scss @@ -1,45 +1,45 @@ .container { - display: flex; - flex-direction: column; - align-items: center; - margin: 0 5px; - &:first-child { - margin-left: 0; - } - :global { - .title { - font-size: 12px; - margin-bottom: 0px; - } - .digitContainer { - display: flex; - flex-direction: row; - padding: 0; - } - .singleDigit { - position: relative; - display: flex; - flex: 0 1 25%; - font-size: 20px; - background-color: #fff; - border-radius: 5px; - padding: 4px 1px; - color: #404549; - &:first-child { - margin-right: 2px; - } - &:after { - position: absolute; - left: 0px; - right: 0px; - top: 50%; - bottom: 50%; - content: ""; - width: 100%; - height: 2px; - background-color: #f0f0f0; - opacity: 0.4; - } - } - } + display: flex; + flex-direction: column; + align-items: center; + margin: 0 5px; + &:first-child { + margin-left: 0; + } + :global { + .title { + font-size: 12px; + margin-bottom: 0px; + } + .digitContainer { + display: flex; + flex-direction: row; + padding: 0; + } + .singleDigit { + position: relative; + display: flex; + flex: 0 1 25%; + font-size: 20px; + background-color: #fff; + border-radius: 5px; + padding: 4px 1px; + color: #404549; + &:first-child { + margin-right: 2px; + } + &:after { + position: absolute; + left: 0px; + right: 0px; + top: 50%; + bottom: 50%; + content: ''; + width: 100%; + height: 2px; + // background-color: #f0f0f0; + opacity: 0.4; + } + } + } } diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index f7e75385..fdccbb86 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -1,5 +1,9 @@ # @pear-rec/web +## 1.3.3 + +fix: 录屏 bug + ## 1.3.2 feat: 自动更新软件 diff --git a/packages/web/src/components/card/recordScreenCard.tsx b/packages/web/src/components/card/recordScreenCard.tsx index 722e83ec..123f2af7 100644 --- a/packages/web/src/components/card/recordScreenCard.tsx +++ b/packages/web/src/components/card/recordScreenCard.tsx @@ -12,7 +12,7 @@ const RecordScreenCard = forwardRef((props: any, ref: any) => { window.electronAPI.sendCsOpenWin(); window.electronAPI.sendMaCloseWin(); } else { - location.href = '/recorderFullScreen.html'; + location.href = '/recorderScreen.html'; } } diff --git a/packages/web/src/components/recorderScreen/ScreenRecorder.tsx b/packages/web/src/components/recorderScreen/ScreenRecorder.tsx index eb8e90af..67a7984e 100644 --- a/packages/web/src/components/recorderScreen/ScreenRecorder.tsx +++ b/packages/web/src/components/recorderScreen/ScreenRecorder.tsx @@ -118,32 +118,6 @@ const ScreenRecorder = (props) => { } } - async function cropMediaStream() { - const worker = new Worker(new URL('./worker.js', import.meta.url), { name: 'Crop worker' }); - const size = await window.electronAPI?.invokeRsGetBoundsClip(); - const [track] = mediaStream.current.getTracks(); - // @ts-ignore - const processor = new MediaStreamTrackProcessor({ track }); - const { readable } = processor; - // @ts-ignore - const generator = new MediaStreamTrackGenerator({ kind: 'video' }); - const { writable } = generator; - const _mediaStream = new MediaStream([generator]); - videoRef.current.srcObject = _mediaStream; - - worker.postMessage( - { - operation: 'crop', - readable, - writable, - size, - }, - [readable, writable], - ); - - return _mediaStream; - } - async function setMediaRecorder() { const _mediaStream = window.isElectron ? await initElectron() : mediaStream.current; mediaRecorder.current = new MediaRecorder(_mediaStream); @@ -155,6 +129,8 @@ const ScreenRecorder = (props) => { mediaRecorder.current.onstart = (event) => { timer.start(); + setIsRecording(true); + props.setIsRecording && props.setIsRecording(true); }; mediaRecorder.current.onstop = (event) => { @@ -194,8 +170,6 @@ const ScreenRecorder = (props) => { async function handleStartRecord() { await setMediaRecorder(); mediaRecorder.current.start(); - setIsRecording(true); - props.setIsRecording && props.setIsRecording(true); } // 暂停录制 @@ -213,8 +187,6 @@ const ScreenRecorder = (props) => { isSave.current = true; if (isRecording) { mediaRecorder.current.stop(); - // setIsRecording(false); - // props.setIsRecording(false); } } diff --git a/packages/web/src/components/recorderScreen/worker.js b/packages/web/src/components/recorderScreen/worker.js index aa8f5f2e..0497326d 100644 --- a/packages/web/src/components/recorderScreen/worker.js +++ b/packages/web/src/components/recorderScreen/worker.js @@ -29,10 +29,10 @@ onmessage = async (event) => { const { operation, size } = event.data; if (operation === 'crop') { const { readable, writable } = event.data; - x = size.x + 2; - y = size.y + 2; - width = size.width - 4; - height = size.height - 4; + x = size.x % 2 == 0 ? size.x + 2 : size.x + 1; + y = size.y % 2 == 0 ? size.y + 2 : size.y + 1; + width = size.width % 2 == 0 ? size.width - 4 : size.width - 3; + height = size.height % 2 == 0 ? size.height - 4 : size.height - 3; readable.pipeThrough(new TransformStream({ transform })).pipeTo(writable); } else { console.error('Unknown operation', operation);