improve: compatibility for windows
This commit is contained in:
parent
7dac731479
commit
95f982f245
16
docs/build-instructions.md
Normal file
16
docs/build-instructions.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Build Instructions
|
||||
|
||||
## Binaries & Libraries
|
||||
|
||||
### Simple
|
||||
|
||||
Simple is a SQLite3 FTS extension for indexing Chinese, OpenRewind use it to improve searching experience for Chinese users.
|
||||
|
||||
Before building, you need to download latest release of Simple at their [GitHub Release](https://github.com/wangfenjin/simple/releases),
|
||||
decompress all files in the zip into `[PROJECT_ROOT]/bin/[PLATFORM]/libsimple/`, in which:
|
||||
|
||||
- [PROJECT_ROOT] is the root directory of OpenRewind you pulled.
|
||||
- [PLATFORM] refers to the specific platform you are targeting:
|
||||
- win32: Windows
|
||||
- darwin: macOS
|
||||
- linux: Linux
|
@ -12,14 +12,17 @@
|
||||
"output": "dist/release"
|
||||
},
|
||||
"files": [
|
||||
"dist/dev/**/*",
|
||||
"dist/dev/assets/*",
|
||||
"dist/dev/i18n/*",
|
||||
"dist/electron/**/*",
|
||||
"dist/electron/assets/*",
|
||||
"dist/electron/i18n/*",
|
||||
"dist/renderer/**/*",
|
||||
"dist/renderer/assets/*"
|
||||
],
|
||||
"win": {
|
||||
"target": "nsis"
|
||||
"target": "nsis",
|
||||
"files": [
|
||||
"bin/win32"
|
||||
]
|
||||
},
|
||||
"linux": {
|
||||
"target": "AppImage"
|
||||
|
17
gulpfile.ts
17
gulpfile.ts
@ -1,19 +1,18 @@
|
||||
import gulp from "gulp";
|
||||
import ts from "gulp-typescript";
|
||||
// @ts-ignore
|
||||
import clean from "gulp-clean";
|
||||
import fs from "fs";
|
||||
|
||||
const tsProject = ts.createProject('tsconfig.json');
|
||||
|
||||
gulp.task('clean', function () {
|
||||
return gulp.src('dist/dev', {read: false, allowEmpty: true})
|
||||
return gulp.src('dist/electron', {read: false, allowEmpty: true})
|
||||
.pipe(clean());
|
||||
});
|
||||
|
||||
gulp.task('scripts', () => {
|
||||
if (!fs.existsSync("dist/dev")) {
|
||||
fs.mkdirSync("dist/dev", { recursive: true });
|
||||
if (!fs.existsSync("dist/electron")) {
|
||||
fs.mkdirSync("dist/electron", { recursive: true });
|
||||
}
|
||||
const tsResult = tsProject.src()
|
||||
.pipe(tsProject());
|
||||
@ -21,25 +20,25 @@ gulp.task('scripts', () => {
|
||||
const jsFiles = gulp.src(['src/electron/**/*.js', 'src/electron/**/*.cjs']);
|
||||
|
||||
return tsResult.js
|
||||
.pipe(gulp.dest('dist/dev'))
|
||||
.pipe(gulp.dest('dist/electron'))
|
||||
.on('end', () => {
|
||||
jsFiles.pipe(gulp.dest('dist/dev'));
|
||||
jsFiles.pipe(gulp.dest('dist/electron'));
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('assets', () => {
|
||||
return gulp.src('src/electron/assets/**/*', { encoding: false })
|
||||
.pipe(gulp.dest('dist/dev/assets'));
|
||||
.pipe(gulp.dest('dist/electron/assets'));
|
||||
});
|
||||
|
||||
gulp.task('binary', () => {
|
||||
return gulp.src('bin/**/*', { encoding: false })
|
||||
.pipe(gulp.dest('dist/dev/bin'));
|
||||
.pipe(gulp.dest('dist/electron/bin'));
|
||||
});
|
||||
|
||||
gulp.task("locales", () => {
|
||||
return gulp.src('i18n/**/*')
|
||||
.pipe(gulp.dest('dist/dev/i18n'));
|
||||
.pipe(gulp.dest('dist/electron/i18n'));
|
||||
})
|
||||
|
||||
gulp.task('build', gulp.series('clean', 'scripts', 'assets', 'binary', 'locales'));
|
15
package.json
15
package.json
@ -1,23 +1,23 @@
|
||||
{
|
||||
"name": "openrewind",
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.1",
|
||||
"type": "module",
|
||||
"description": "Your second brain, superpowered.",
|
||||
"main": "dist/dev/index.js",
|
||||
"main": "dist/electron/index.js",
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=dev bun run dev:all",
|
||||
"dev:all": "concurrently -n=react,electron -c='#ff3e00',blue \"bun run dev:react\" \"bun run dev:electron\"",
|
||||
"dev:react": "vite dev",
|
||||
"dev:electron": "bunx gulp build && electron dist/dev/index.js",
|
||||
"dev:electron": "bunx gulp build && electron dist/electron/index.js",
|
||||
"build:react": "vite build",
|
||||
"build:app": "bunx gulp build",
|
||||
"build:electron": "electron-builder",
|
||||
"start": "cross-env NODE_ENV=production bun run start:all"
|
||||
"build:electron": "electron-builder"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.1.2",
|
||||
"@unly/universal-language-detector": "^2.0.3",
|
||||
"better-sqlite3": "^11.6.0",
|
||||
"electron-context-menu": "^4.0.4",
|
||||
@ -39,7 +39,8 @@
|
||||
"react-router-dom": "^7.0.1",
|
||||
"sqlite3": "^5.1.7",
|
||||
"sqlstring": "^2.3.3",
|
||||
"vite-tsconfig-paths": "^5.1.3"
|
||||
"vite-tsconfig-paths": "^5.1.3",
|
||||
"screenshot-desktop": "^1.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/rebuild": "^3.7.1",
|
||||
@ -57,6 +58,7 @@
|
||||
"cross-env": "^7.0.3",
|
||||
"del": "^8.0.0",
|
||||
"electron": "^33.2.0",
|
||||
"electron-build": "^0.0.3",
|
||||
"electron-builder": "^25.1.8",
|
||||
"eslint": "^9.13.0",
|
||||
"eslint-plugin-react-hooks": "^5.0.0",
|
||||
@ -66,7 +68,6 @@
|
||||
"gulp-clean": "^0.4.0",
|
||||
"gulp-typescript": "6.0.0-alpha.1",
|
||||
"postcss": "^8.4.38",
|
||||
"screenshot-desktop": "^1.15.0",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"typescript": "~5.6.2",
|
||||
"typescript-eslint": "^8.11.0",
|
||||
|
@ -8,10 +8,59 @@ import Title from "components/settings/Title.tsx";
|
||||
import OpenSourceNote from "components/settings/OpenSourceNote.tsx";
|
||||
import EnvironmentDetails from "components/settings/EnvironmentDetails.tsx";
|
||||
|
||||
function showFrame() {
|
||||
return navigator.userAgent.includes("Mac");
|
||||
}
|
||||
|
||||
interface SettingsGroupRefs {
|
||||
[key: string]: HTMLDivElement;
|
||||
}
|
||||
|
||||
function TitleBar() {
|
||||
const { t } = useTranslation();
|
||||
if (showFrame()) {
|
||||
return (
|
||||
<div className="w-full flex items-center justify-center h-9" id="title-bar">
|
||||
{t("settings.title")}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="w-full h-9">
|
||||
<div
|
||||
className="w-[calc(100%-44px)] h-9 absolute left-[22px] flex justify-center"
|
||||
id="title-bar"
|
||||
>
|
||||
<span className="self-center">{t("settings.title")}</span>
|
||||
</div>
|
||||
<div
|
||||
className="z-50 absolute right-2.5 top-2.5 bg-red-500 hover:bg-rose-400 h-3 w-3 rounded-full"
|
||||
onClick={() => {
|
||||
console.log(window.settingsWindow)
|
||||
window.settingsWindow.close();
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className="hover:opacity-100 opacity-0"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="2"
|
||||
d="m8.464 15.535l7.072-7.07m-7.072 0l7.072 7.07"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default function SettingsPage() {
|
||||
const { t } = useTranslation();
|
||||
const [groupRefs, setGroupRefs] = useState<SettingsGroupRefs>({});
|
||||
@ -29,18 +78,20 @@ export default function SettingsPage() {
|
||||
const key = groupName as keyof typeof groupRefs;
|
||||
console.log(groupRefs[key]);
|
||||
if (!groupRefs[key]) return;
|
||||
containerRef.current!.scrollTop = groupRefs[key].getBoundingClientRect().top -
|
||||
containerRef.current!.scrollTop =
|
||||
groupRefs[key].getBoundingClientRect().top -
|
||||
titleBarRef.current!.getBoundingClientRect().height;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<title>{t("settings.title")}</title>
|
||||
<div className="w-full h-auto bg-white dark:bg-gray-800 !bg-opacity-80 flex flex-col
|
||||
dark:text-white font-semibold fixed z-10 backdrop-blur-lg text-[.9rem]" ref={titleBarRef}>
|
||||
<div className="w-full flex items-center justify-center h-9" id="title-bar">
|
||||
{t("settings.title")}
|
||||
</div>
|
||||
<div
|
||||
className="w-full h-auto bg-white dark:bg-gray-800 !bg-opacity-80 flex flex-col
|
||||
dark:text-white font-semibold fixed z-10 backdrop-blur-lg text-[.9rem]"
|
||||
ref={titleBarRef}
|
||||
>
|
||||
<TitleBar />
|
||||
<div className="h-[4.5rem] pt-0 pb-2">
|
||||
<div className="w-full h-full px-20 flex items-center justify-center gap-2">
|
||||
<MenuItem
|
||||
@ -56,19 +107,23 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-full bg-slate-100 dark:bg-gray-900 w-full scroll-smooth
|
||||
relative dark:text-white pt-28 pb-12 px-10 overflow-auto" ref={containerRef} id="settings-scroll-container">
|
||||
<div
|
||||
className="h-full bg-slate-100 dark:bg-gray-900 w-full scroll-smooth
|
||||
relative dark:text-white pt-28 pb-12 px-10 overflow-auto"
|
||||
ref={containerRef}
|
||||
id="settings-scroll-container"
|
||||
>
|
||||
<SettingsGroup groupName="screen" addGroupRef={addGroupRef}>
|
||||
<Title i18nKey="settings.screen-recording"/>
|
||||
<Title i18nKey="settings.screen-recording" />
|
||||
<div className="flex">
|
||||
<p>Nothing yet.</p>
|
||||
</div>
|
||||
</SettingsGroup>
|
||||
<SettingsGroup groupName="about" addGroupRef={addGroupRef}>
|
||||
<Title i18nKey={"settings.about"}/>
|
||||
<IconWithText/>
|
||||
<OpenSourceNote/>
|
||||
<EnvironmentDetails/>
|
||||
<Title i18nKey={"settings.about"} />
|
||||
<IconWithText />
|
||||
<OpenSourceNote />
|
||||
<EnvironmentDetails />
|
||||
</SettingsGroup>
|
||||
</div>
|
||||
</>
|
||||
|
580
pnpm-lock.yaml
580
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
BIN
src/electron/assets/icon.ico
Normal file
BIN
src/electron/assets/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 449 KiB |
BIN
src/electron/assets/icon.png
Normal file
BIN
src/electron/assets/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 454 KiB |
@ -3,8 +3,17 @@ import Database from "better-sqlite3";
|
||||
import { __dirname } from "../dirname.js";
|
||||
import { getDatabasePath } from "../utils/backend.js";
|
||||
|
||||
function getLibSimpleExtensionPath(): string {
|
||||
return path.join(__dirname, "bin", process.platform, "libsimple/libsimple.dylib");
|
||||
function getLibSimpleExtensionPath() {
|
||||
switch (process.platform) {
|
||||
case "win32":
|
||||
return path.join(__dirname, "bin", process.platform, "libsimple", "simple.dll");
|
||||
case "darwin":
|
||||
return path.join(__dirname, "bin", process.platform, "libsimple", "libsimple.dylib");
|
||||
case "linux":
|
||||
return path.join(__dirname, "bin", process.platform, "libsimple", "libsimple.so");
|
||||
default:
|
||||
throw new Error("Unsupported platform");
|
||||
}
|
||||
}
|
||||
|
||||
export function initDatabase() {
|
||||
|
@ -2,6 +2,7 @@ import { app, BrowserWindow, screen } from "electron";
|
||||
import { join } from "path";
|
||||
import { __dirname } from "./dirname.js";
|
||||
import windowStateManager from "electron-window-state";
|
||||
import { hideDock, showDock } from "./utils/electron.js";
|
||||
|
||||
function loadURL(window: BrowserWindow, path = "", vitePort: string) {
|
||||
const dev = !app.isPackaged;
|
||||
@ -24,6 +25,21 @@ export function createSettingsWindow(vitePort: string, closeCallBack: Function)
|
||||
defaultWidth: 650,
|
||||
defaultHeight: 550
|
||||
});
|
||||
const enableFrame = process.platform === "darwin";
|
||||
let icon
|
||||
switch (process.platform) {
|
||||
case "darwin":
|
||||
icon = undefined;
|
||||
break;
|
||||
case "win32":
|
||||
icon = join(__dirname, "assets/icon.ico");
|
||||
break;
|
||||
case "linux":
|
||||
icon = join(__dirname, "assets/icon.png");
|
||||
break;
|
||||
default:
|
||||
icon = undefined;
|
||||
}
|
||||
const window = new BrowserWindow({
|
||||
width: 650,
|
||||
height: 550,
|
||||
@ -35,10 +51,12 @@ export function createSettingsWindow(vitePort: string, closeCallBack: Function)
|
||||
titleBarStyle: "hiddenInset",
|
||||
resizable: false,
|
||||
show: false,
|
||||
frame: enableFrame,
|
||||
icon: icon,
|
||||
});
|
||||
windowState.manage(window);
|
||||
window.on("show", () => {
|
||||
app.dock.show();
|
||||
showDock();
|
||||
});
|
||||
window.on("close", (e) => {
|
||||
window.hide();
|
||||
@ -47,7 +65,7 @@ export function createSettingsWindow(vitePort: string, closeCallBack: Function)
|
||||
});
|
||||
window.once("close", () => {
|
||||
window.hide();
|
||||
app.dock.hide();
|
||||
hideDock();
|
||||
});
|
||||
loadURL(window, "settings", vitePort);
|
||||
return window;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { app, BrowserWindow, globalShortcut, Menu, nativeImage, screen, Tray } from "electron";
|
||||
import { app, BrowserWindow, globalShortcut, ipcMain, Menu, nativeImage, screen, Tray } from "electron";
|
||||
import contextMenu from "electron-context-menu";
|
||||
import { join } from "path";
|
||||
import initI18n from "./i18n.js";
|
||||
@ -7,6 +7,7 @@ import { initDatabase } from "./backend/init.js";
|
||||
import { Database } from "better-sqlite3";
|
||||
import { startScreenshotLoop } from "./backend/screenshot.js";
|
||||
import { __dirname } from "./dirname.js";
|
||||
import { hideDock } from "./utils/electron.js";
|
||||
|
||||
const i18n = initI18n();
|
||||
|
||||
@ -66,7 +67,7 @@ contextMenu({
|
||||
});
|
||||
|
||||
app.once("ready", () => {
|
||||
app.dock.hide();
|
||||
hideDock();
|
||||
});
|
||||
app.on("activate", () => {});
|
||||
|
||||
@ -84,3 +85,7 @@ app.on("ready", () => {
|
||||
// app.on("window-all-closed", () => {
|
||||
// if (process.platform !== "darwin") app.quit();
|
||||
// });
|
||||
|
||||
ipcMain.on('close-settings', () => {
|
||||
settingsWindow?.hide();
|
||||
});
|
@ -1,8 +1,8 @@
|
||||
const { contextBridge } = require('electron')
|
||||
const os = require('os');
|
||||
const osName = require('./os-name.cjs');
|
||||
const { contextBridge, ipcRenderer } = require("electron");
|
||||
const os = require("os");
|
||||
const osName = require("./os-name.cjs");
|
||||
|
||||
contextBridge.exposeInMainWorld('versions', {
|
||||
contextBridge.exposeInMainWorld("versions", {
|
||||
node: () => process.versions.node,
|
||||
chrome: () => process.versions.chrome,
|
||||
electron: () => process.versions.electron,
|
||||
@ -10,4 +10,10 @@ contextBridge.exposeInMainWorld('versions', {
|
||||
return `${os.platform()} ${os.release()}`;
|
||||
},
|
||||
osDisplay: osName
|
||||
})
|
||||
});
|
||||
|
||||
contextBridge.exposeInMainWorld("settingsWindow", {
|
||||
close: () => {
|
||||
ipcRenderer.send("close-settings", {});
|
||||
}
|
||||
});
|
||||
|
15
src/electron/utils/electron.ts
Normal file
15
src/electron/utils/electron.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { app } from "electron";
|
||||
|
||||
export function hideDock(){
|
||||
if (process.platform === 'darwin') {
|
||||
// Hide the dock icon on macOS
|
||||
app.dock.hide();
|
||||
}
|
||||
}
|
||||
|
||||
export function showDock(){
|
||||
if (process.platform === 'darwin') {
|
||||
// Show the dock icon on macOS
|
||||
app.dock.show();
|
||||
}
|
||||
}
|
3
src/global.d.ts
vendored
3
src/global.d.ts
vendored
@ -12,5 +12,8 @@ interface Window {
|
||||
api: {
|
||||
send: (channel: any, data: any) => void,
|
||||
receive: (channel: any, func: any) => void
|
||||
},
|
||||
settingsWindow: {
|
||||
close: () => void,
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "./dist/dev",
|
||||
"outDir": "./dist/electron",
|
||||
"rootDir": "./src/electron",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
|
Loading…
Reference in New Issue
Block a user