Skip to content

Commit 33a0b9e

Browse files
authored
Fix bugs (#1274)
* handle client error ref #1255 * use bugsnag & remove unhandled modal * fix upload storage * fix assessment play origin * upgrade deps * try to fix JavaScript heap out of memory when package * update github action * fix workflow * try to fix CI in linux
1 parent 931bfeb commit 33a0b9e

23 files changed

+1222
-591
lines changed

.github/workflows/test-enjoy-app.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,18 @@ jobs:
4343
brew install sdl2
4444
4545
- name: Package App
46-
run: yarn enjoy:package
46+
shell: bash
47+
env:
48+
NODE_OPTIONS: "--max-old-space-size=8192"
49+
run: |
50+
set -e
51+
yarn enjoy:package
52+
53+
- name: Configure Chrome sandbox for Linux
54+
if: contains(matrix.os, 'ubuntu')
55+
run: |
56+
sudo chown root:root enjoy/out/Enjoy-linux-x64/chrome-sandbox
57+
sudo chmod 4755 enjoy/out/Enjoy-linux-x64/chrome-sandbox
4758
4859
- name: Run main tests with xvfb-run on Ubuntu
4960
# continue-on-error: true

1000-hours/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"markdown-it-sub": "^2.0.0",
1010
"markdown-it-sup": "^2.0.0",
1111
"mermaid": "^11.4.1",
12-
"sass": "^1.83.1",
12+
"sass": "^1.83.4",
1313
"vitepress": "^1.5.0",
1414
"vitepress-plugin-mermaid": "^2.0.17",
1515
"vue": "^3.5.13"

1000h-portal/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
"postinstall": "nuxt prepare"
1111
},
1212
"dependencies": {
13-
"@nuxtjs/seo": "^2.0.2",
13+
"@nuxtjs/seo": "^2.0.3",
1414
"nuxt": "^3.15.1",
15-
"nuxt-og-image": "^4.0.2",
15+
"nuxt-og-image": "^4.0.3",
1616
"vue": "^3.5.13",
1717
"vue-router": "^4.5.0"
1818
},
1919
"devDependencies": {
2020
"autoprefixer": "^10.4.20",
21-
"postcss": "^8.4.49",
22-
"sass": "^1.83.1",
21+
"postcss": "^8.5.1",
22+
"sass": "^1.83.4",
2323
"tailwindcss": "^3.4.17"
2424
}
2525
}

enjoy/package.json

+19-17
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@
1111
"predev": "yarn run download",
1212
"dev": "rimraf .vite && yarn run download && WEB_API_URL=http://localhost:3000 WS_URL=ws://localhost:3000 SETTINGS_PATH=${PWD}/enjoy/tmp LIBRARY_PATH=${PWD}/enjoy/tmp electron-forge start",
1313
"start": "rimraf .vite && yarn run download && electron-forge start",
14-
"package": "rimraf .vite && yarn run download && electron-forge package",
15-
"make": "rimraf .vite && yarn run download && electron-forge make",
16-
"publish": "rimraf .vite && yarn run download && electron-forge publish",
14+
"package": "NODE_OPTIONS='--max-old-space-size=8192' rimraf .vite && yarn run download && electron-forge package",
15+
"make": "NODE_OPTIONS='--max-old-space-size=8192' rimraf .vite && yarn run download && electron-forge make",
16+
"publish": "NODE_OPTIONS='--max-old-space-size=8192' rimraf .vite && yarn run download && electron-forge publish",
1717
"lint": "eslint --ext .ts,.tsx .",
1818
"test": "yarn run package && yarn run playwright test",
1919
"test:main": "yarn run playwright test e2e/main.spec.ts",
2020
"test:renderer": "yarn run playwright test e2e/renderer.spec.ts",
2121
"create-migration": "zx ./src/main/db/create-migration.mjs",
2222
"download-dictionaries": "zx ./scripts/download-dictionaries.mjs",
23-
"download": "yarn run download-dictionaries"
23+
"download": "yarn run download-dictionaries",
24+
"sourcemap": "bugsnag-source-maps upload-node --directory .vite/build --app-version 0.7.6"
2425
},
2526
"keywords": [],
2627
"author": {
@@ -29,6 +30,7 @@
2930
},
3031
"license": "MIT",
3132
"devDependencies": {
33+
"@bugsnag/source-maps": "^2.3.3",
3234
"@divisey/js-mdict": "^5.0.0",
3335
"@electron-forge/cli": "^7.6.0",
3436
"@electron-forge/maker-deb": "^7.6.0",
@@ -44,7 +46,7 @@
4446
"@electron/fuses": "^1.8.0",
4547
"@hookform/resolvers": "^3.10.0",
4648
"@langchain/community": "^0.3.24",
47-
"@langchain/core": "^0.3.29",
49+
"@langchain/core": "^0.3.30",
4850
"@langchain/ollama": "^0.1.4",
4951
"@mozilla/readability": "^0.5.0",
5052
"@playwright/test": "^1.49.1",
@@ -85,7 +87,7 @@
8587
"@types/mark.js": "^8.11.12",
8688
"@types/mime-types": "^2.1.4",
8789
"@types/mustache": "^4.2.5",
88-
"@types/node": "^22.10.5",
90+
"@types/node": "^22.10.6",
8991
"@types/prop-types": "^15.7.14",
9092
"@types/rails__actioncable": "^6.1.11",
9193
"@types/react": "^18.3.18",
@@ -95,8 +97,8 @@
9597
"@types/unzipper": "^0.10.10",
9698
"@types/validator": "^13.12.2",
9799
"@types/wavesurfer.js": "^6.0.12",
98-
"@typescript-eslint/eslint-plugin": "^8.19.1",
99-
"@typescript-eslint/parser": "^8.19.1",
100+
"@typescript-eslint/eslint-plugin": "^8.20.0",
101+
"@typescript-eslint/parser": "^8.20.0",
100102
"@uidotdev/usehooks": "^2.4.1",
101103
"@vidstack/react": "^1.12.12",
102104
"@vitejs/plugin-react": "^4.3.4",
@@ -119,14 +121,13 @@
119121
"decamelize": "^6.0.0",
120122
"decamelize-keys": "^2.0.1",
121123
"dependencies-tree": "^2.0.0",
122-
"electron": "^33.3.1",
124+
"electron": "^34.0.0",
123125
"electron-context-menu": "^4.0.4",
124-
"electron-devtools-installer": "^3.2.1",
126+
"electron-devtools-installer": "^4.0.0",
125127
"electron-forge-plugin-dependencies": "^1.0.0",
126128
"electron-log": "^5.2.4",
127129
"electron-playwright-helpers": "^1.7.1",
128130
"electron-squirrel-startup": "^1.0.1",
129-
"electron-unhandled": "^5.0.0",
130131
"eslint": "^9.18.0",
131132
"eslint-import-resolver-typescript": "^3.7.0",
132133
"eslint-plugin-import": "^2.31.0",
@@ -141,23 +142,22 @@
141142
"langchain": "^0.3.11",
142143
"lodash": "^4.17.21",
143144
"lru-cache": "^11.0.2",
144-
"lucide-react": "^0.471.0",
145+
"lucide-react": "^0.471.1",
145146
"mark.js": "^8.11.1",
146147
"media-captions": "^0.0.18",
147148
"microsoft-cognitiveservices-speech-sdk": "^1.42.0",
148149
"mime-types": "^2.1.35",
149150
"mustache": "^4.2.0",
150-
"new-github-issue-url": "^1.0.0",
151151
"next-themes": "^0.4.4",
152152
"octokit": "^4.1.0",
153153
"openai": "^4.78.1",
154154
"pitchfinder": "^2.3.2",
155-
"postcss": "^8.4.49",
155+
"postcss": "^8.5.1",
156156
"progress": "^2.0.3",
157157
"prop-types": "^15.8.1",
158158
"proxy-agent": "^6.5.0",
159159
"react": "^18.3.1",
160-
"react-activity-calendar": "^2.7.6",
160+
"react-activity-calendar": "^2.7.7",
161161
"react-audio-visualize": "^1.2.0",
162162
"react-audio-voice-recorder": "^2.2.0",
163163
"react-dom": "^18.3.1",
@@ -176,7 +176,7 @@
176176
"sonner": "^1.7.1",
177177
"tailwind-merge": "^2.6.0",
178178
"tailwind-scrollbar": "^3.1.0",
179-
"tailwind-scrollbar-hide": "^1.3.1",
179+
"tailwind-scrollbar-hide": "^2.0.0",
180180
"tailwindcss": "^3.4.17",
181181
"tailwindcss-animate": "^1.0.7",
182182
"ts-node": "^10.9.2",
@@ -185,13 +185,15 @@
185185
"typescript": "^5.7.3",
186186
"vite": "^6.0.7",
187187
"vite-plugin-static-copy": "^2.2.0",
188-
"wavesurfer.js": "^7.8.15",
188+
"wavesurfer.js": "^7.8.16",
189189
"zod": "^3.24.1",
190190
"zod-to-json-schema": "^3.24.1",
191191
"zx": "^8.3.0"
192192
},
193193
"dependencies": {
194194
"@andrkrn/ffprobe-static": "^5.2.0",
195+
"@bugsnag/electron": "^8.1.2",
196+
"@bugsnag/plugin-react": "^8.1.1",
195197
"echogarden": "^1.8.7",
196198
"electron-settings": "^4.0.4",
197199
"ffmpeg-static": "^5.2.0",

enjoy/src/constants/index.ts

+12
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,15 @@ export const AGENT_FIXTURE_ANDREW = {
118118
ttsVoice: "en-US-AndrewNeural",
119119
},
120120
};
121+
122+
export const BUGSNAG_API_KEY = "828ee1de10c079a250be7fd05177662f";
123+
124+
export const MIME_TYPES: Record<string, string> = {
125+
".mp3": "audio/mpeg",
126+
".wav": "audio/wav",
127+
".ogg": "audio/ogg",
128+
".m4a": "audio/mp4",
129+
".aac": "audio/aac",
130+
".flac": "audio/flac",
131+
".wma": "audio/x-ms-wma",
132+
};

enjoy/src/main.ts

+6-41
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
import { app, BrowserWindow, protocol, net, shell } from "electron";
1+
import { app, BrowserWindow, protocol, net } from "electron";
22
import path from "path";
33
import fs from "fs-extra";
44
import settings from "@main/settings";
55
import log from "@main/logger";
66
import mainWindow from "@main/window";
77
import ElectronSquirrelStartup from "electron-squirrel-startup";
88
import contextMenu from "electron-context-menu";
9+
import Bugsnag from "@bugsnag/electron";
910
import { t } from "i18next";
10-
import unhandled from "electron-unhandled";
11-
import newGithubIssueUrl from "new-github-issue-url";
11+
import { BUGSNAG_API_KEY } from "./constants";
1212

1313
const logger = log.scope("main");
1414

1515
app.commandLine.appendSwitch("enable-features", "SharedArrayBuffer");
1616

17-
if (!app.isPackaged) {
17+
if (app.isPackaged) {
18+
Bugsnag.start({ apiKey: BUGSNAG_API_KEY });
19+
} else {
1820
app.disableHardwareAcceleration();
1921
app.commandLine.appendSwitch("disable-software-rasterizer");
2022
}
@@ -121,43 +123,6 @@ app.on("ready", async () => {
121123
});
122124

123125
mainWindow.init();
124-
125-
unhandled({
126-
showDialog: true,
127-
logger: logger.error,
128-
reportButton: (error) => {
129-
const url = newGithubIssueUrl({
130-
user: "ZuodaoTech",
131-
repo: "everyone-can-use-english",
132-
title: "Unhandled Error",
133-
body: `
134-
## Node.js error stack
135-
136-
**Message:**
137-
138-
\`\`\`
139-
${error.message}
140-
\`\`\`
141-
142-
**Stack:**
143-
144-
\`\`\`
145-
${error.stack}
146-
\`\`\`
147-
148-
**Environment:**
149-
150-
\`\`\`
151-
${app.name} ${app.getVersion()}
152-
Electron ${process.versions.electron}
153-
${process.platform} ${process.arch}
154-
Locale: ${app.getLocale()}
155-
\`\`\``,
156-
});
157-
158-
shell.openExternal(url);
159-
},
160-
});
161126
});
162127

163128
// Quit when all windows are closed, except on macOS. There, it's common

enjoy/src/main/db/models/audio.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
Video,
2222
} from "@main/db/models";
2323
import settings from "@main/settings";
24-
import { AudioFormats, VideoFormats } from "@/constants";
24+
import { AudioFormats, MIME_TYPES, VideoFormats } from "@/constants";
2525
import { hashFile } from "@main/utils";
2626
import path from "path";
2727
import fs from "fs-extra";
@@ -159,6 +159,14 @@ export class Audio extends Model<Audio> {
159159
return this.getDataValue("md5") + this.extname;
160160
}
161161

162+
get mimeType(): string {
163+
if (this.metadata?.mimeType) {
164+
return this.metadata.mimeType;
165+
}
166+
167+
return MIME_TYPES[this.extname.toLowerCase()] || "audio/mpeg";
168+
}
169+
162170
get extname(): string {
163171
return (
164172
this.getDataValue("metadata")?.extname ||
@@ -204,7 +212,7 @@ export class Audio extends Model<Audio> {
204212
if (this.isUploaded && !force) return;
205213

206214
return storage
207-
.put(this.md5, this.filePath)
215+
.put(this.md5, this.filePath, this.mimeType)
208216
.then((result) => {
209217
logger.debug("upload result:", result.data);
210218
if (result.data.success) {

enjoy/src/main/db/models/document.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export class Document extends Model<Document> {
146146
if (this.isUploaded && !force) return;
147147

148148
return storage
149-
.put(this.md5, this.filePath)
149+
.put(this.md5, this.filePath, this.metadata.mimeType)
150150
.then((result) => {
151151
logger.debug("upload result:", result.data);
152152
if (result.data.success) {

enjoy/src/main/db/models/note.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ export class Note extends Model<Note> {
9797

9898
@AfterCreate
9999
static syncAndUploadAfterCreate(note: Note) {
100-
note.sync();
100+
note.sync().catch((err) => {
101+
logger.error("sync note error", note.id, err);
102+
});
101103
}
102104

103105
@AfterCreate
@@ -113,7 +115,7 @@ export class Note extends Model<Note> {
113115
@AfterUpdate
114116
static syncAfterUpdate(note: Note) {
115117
note.sync().catch((err) => {
116-
logger.error("sync error", err);
118+
logger.error("sync note error", note.id, err);
117119
});
118120
}
119121

enjoy/src/main/db/models/recording.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { t } from "i18next";
3434
import { Attributes, Op, Transaction } from "sequelize";
3535
import { v5 as uuidv5 } from "uuid";
3636
import FfmpegWrapper from "@main/ffmpeg";
37+
import { MIME_TYPES } from "@/constants";
3738

3839
const logger = log.scope("db/models/recording");
3940

@@ -141,6 +142,15 @@ export class Recording extends Model<Recording> {
141142
)}`;
142143
}
143144

145+
@Column(DataType.VIRTUAL)
146+
get mimeType(): string {
147+
return MIME_TYPES[this.extname.toLowerCase()] || "audio/mpeg";
148+
}
149+
150+
get extname(): string {
151+
return path.extname(this.filePath);
152+
}
153+
144154
get filePath(): string {
145155
const file = path.join(
146156
settings.userDataPath(),
@@ -169,7 +179,7 @@ export class Recording extends Model<Recording> {
169179
}
170180

171181
return storage
172-
.put(this.md5, this.filePath)
182+
.put(this.md5, this.filePath, this.mimeType)
173183
.then((result) => {
174184
logger.debug("upload result:", result.data);
175185
if (result.data.success) {

0 commit comments

Comments
 (0)