improve: compatibility for windows

This commit is contained in:
alikia2x (寒寒) 2024-12-08 00:43:56 +08:00
parent 7dac731479
commit 95f982f245
15 changed files with 740 additions and 60 deletions

View 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

View File

@ -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"

View File

@ -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'));

View File

@ -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",

View File

@ -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>
</>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

View File

@ -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() {

View File

@ -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;

View File

@ -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();
});

View File

@ -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", {});
}
});

View 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
View File

@ -12,5 +12,8 @@ interface Window {
api: {
send: (channel: any, data: any) => void,
receive: (channel: any, func: any) => void
},
settingsWindow: {
close: () => void,
}
}

View File

@ -3,7 +3,7 @@
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"outDir": "./dist/dev",
"outDir": "./dist/electron",
"rootDir": "./src/electron",
"strict": true,
"esModuleInterop": true,