Skip to content

Commit

Permalink
Improve: UI & code (#1179)
Browse files Browse the repository at this point in the history
* use frameless

* frame true

* fix UI

* disable whisper.cpp for darwin

* improve page UI

* clean code

* refactor shadowing cancel

* upgrade deps

* fix type

* update e2e

* downgrade echogarden to fix align error

* upgrade echogarden

* upgrade

* fix profile

* refactor login form

* may scan to login with Mixin

* refactor sidebar

* update sidebar ui

* update

* update UI

* update
  • Loading branch information
an-lee authored Nov 14, 2024
1 parent ab813da commit 437c133
Show file tree
Hide file tree
Showing 55 changed files with 1,069 additions and 750 deletions.
2 changes: 1 addition & 1 deletion 1000-hours/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"markdown-it-sub": "^2.0.0",
"markdown-it-sup": "^2.0.0",
"mermaid": "^11.4.0",
"sass": "^1.80.6",
"sass": "^1.80.7",
"vitepress": "^1.5.0",
"vitepress-plugin-mermaid": "^2.0.17",
"vue": "^3.5.12"
Expand Down
4 changes: 2 additions & 2 deletions 1000h-portal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
},
"devDependencies": {
"autoprefixer": "^10.4.20",
"postcss": "^8.4.48",
"sass": "^1.80.6",
"postcss": "^8.4.49",
"sass": "^1.80.7",
"tailwindcss": "^3.4.14"
}
}
2 changes: 1 addition & 1 deletion enjoy/e2e/main.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ test.afterAll(async () => {
await electronApp.close();
});

test("validate echogarden command", async () => {
test("validate echogarden recognition", async () => {
const res = await page.evaluate(() => {
return window.__ENJOY_APP__.echogarden.check({
engine: "whisper",
Expand Down
24 changes: 13 additions & 11 deletions enjoy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
"@types/unzipper": "^0.10.10",
"@types/validator": "^13.12.2",
"@types/wavesurfer.js": "^6.0.12",
"@typescript-eslint/eslint-plugin": "^8.13.0",
"@typescript-eslint/parser": "^8.13.0",
"@typescript-eslint/eslint-plugin": "^8.14.0",
"@typescript-eslint/parser": "^8.14.0",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"electron": "^33.2.0",
Expand All @@ -83,17 +83,17 @@
"ts-node": "^10.9.2",
"tslib": "^2.8.1",
"typescript": "^5.6.3",
"vite": "^5.4.10",
"vite": "^5.4.11",
"vite-plugin-static-copy": "^2.1.0",
"zx": "^8.2.1"
"zx": "^8.2.2"
},
"dependencies": {
"@andrkrn/ffprobe-static": "^5.2.0",
"@divisey/js-mdict": "^5.0.0",
"@electron-forge/publisher-s3": "^7.5.0",
"@hookform/resolvers": "^3.9.1",
"@langchain/community": "^0.3.12",
"@langchain/core": "^0.3.17",
"@langchain/community": "^0.3.14",
"@langchain/core": "^0.3.18",
"@langchain/ollama": "^0.1.2",
"@mozilla/readability": "^0.5.0",
"@radix-ui/react-accordion": "^1.2.1",
Expand All @@ -110,7 +110,7 @@
"@radix-ui/react-popover": "^1.1.2",
"@radix-ui/react-progress": "^1.1.0",
"@radix-ui/react-radio-group": "^1.2.1",
"@radix-ui/react-scroll-area": "^1.2.0",
"@radix-ui/react-scroll-area": "^1.2.1",
"@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slider": "^1.2.1",
Expand All @@ -119,7 +119,7 @@
"@radix-ui/react-tabs": "^1.1.1",
"@radix-ui/react-toast": "^1.2.2",
"@radix-ui/react-toggle": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
"@radix-ui/react-tooltip": "^1.1.4",
"@rails/actioncable": "8.0.0",
"@types/turndown": "^5.0.5",
"@uidotdev/usehooks": "^2.4.1",
Expand All @@ -141,7 +141,7 @@
"dayjs": "^1.11.13",
"decamelize": "^6.0.0",
"decamelize-keys": "^2.0.1",
"echogarden": "^2.0.0",
"echogarden": "2.0.3",
"electron-context-menu": "^4.0.4",
"electron-log": "^5.2.2",
"electron-settings": "^4.0.4",
Expand All @@ -154,20 +154,22 @@
"html-to-text": "^9.0.5",
"https-proxy-agent": "^7.0.5",
"i18next": "^23.16.5",
"input-otp": "^1.4.1",
"intl-tel-input": "^24.7.0",
"js-md5": "^0.8.3",
"langchain": "^0.3.5",
"lodash": "^4.17.21",
"lru-cache": "^11.0.2",
"lucide-react": "^0.456.0",
"mark.js": "^8.11.1",
"media-captions": "^0.0.18",
"microsoft-cognitiveservices-speech-sdk": "^1.41.0",
"mime-types": "^2.1.35",
"mustache": "^4.2.0",
"next-themes": "^0.4.3",
"openai": "^4.71.1",
"openai": "^4.72.0",
"pitchfinder": "^2.3.2",
"postcss": "^8.4.48",
"postcss": "^8.4.49",
"proxy-agent": "^6.4.0",
"react": "^18.3.1",
"react-activity-calendar": "^2.7.1",
Expand Down
4 changes: 4 additions & 0 deletions enjoy/src/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ export class Client {
return this.api.post("/api/sessions", decamelizeKeys(params));
}

oauthState(state: string): Promise<UserType> {
return this.api.post("/api/sessions/oauth_state", { state });
}

config(key: string): Promise<any> {
return this.api.get(`/api/config/${key}`);
}
Expand Down
4 changes: 3 additions & 1 deletion enjoy/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,9 @@
"phoneNumber": "Phone number",
"mixinId": "Mixin ID",
"inputMixinId": "Input your Mixin ID",
"dontHaveMixinAccount": "don't have Mixin account?",
"scanMixinQRCodeDescription": "Scan Mixin QR code in the popup window",
"createMixinAccount": "Create Mixin account",
"scanToLogin": "Scan to login",
"youCanAlsoLoginWith": "You can also login with",
"downloadTranscript": "Download transcript",
"downloadTranscriptFromCloud": "Download transcript from cloud",
Expand Down
4 changes: 3 additions & 1 deletion enjoy/src/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,9 @@
"phoneNumber": "手机号",
"mixinId": "Mixin 号",
"inputMixinId": "请输入您的 Mixin ID",
"dontHaveMixinAccount": "没有 Mixin 账号?",
"scanMixinQRCodeDescription": "请在弹出窗口中用 Mixin 扫码",
"createMixinAccount": "创建 Mixin 账号",
"scanToLogin": "扫码登录",
"youCanAlsoLoginWith": "您也可以使用以下方式登录",
"downloadTranscript": "下载字幕",
"downloadTranscriptFromCloud": "从云端下载字幕",
Expand Down
6 changes: 5 additions & 1 deletion enjoy/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,11 @@ app.on("ready", async () => {
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on("window-all-closed", () => {
app.quit();
// Respect the OSX convention of having the application in memory even
// after all windows have been closed
if (process.platform !== "darwin") {
app.quit();
}
});

app.on("activate", () => {
Expand Down
10 changes: 6 additions & 4 deletions enjoy/src/main/echogarden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ import settings from "@main/settings";
import fs from "fs-extra";
import ffmpegPath from "ffmpeg-static";
import { enjoyUrlToPath, pathToEnjoyUrl } from "./utils";
import { UserSetting } from "./db/models";
import { UserSettingKeyEnum } from "@/types/enums";
import { WHISPER_MODELS } from "@/constants";

Echogarden.setGlobalOption(
"ffmpegPath",
Expand Down Expand Up @@ -107,13 +104,18 @@ class EchogardenWrapper {
try {
logger.info("check:", options);
const result = await this.recognize(sampleFile, options);
logger.info(result?.transcript);
logger.info("transcript:", result?.transcript);
fs.writeJsonSync(
path.join(settings.cachePath(), "echogarden-check.json"),
result,
{ spaces: 2 }
);

const timeline = await this.align(sampleFile, result.transcript, {
language: "en",
});
logger.info("timeline:", !!timeline);

return { success: true, log: "" };
} catch (e) {
logger.error(e);
Expand Down
3 changes: 2 additions & 1 deletion enjoy/src/main/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,8 @@ ${log}

// Create the browser window.
const mainWindow = new BrowserWindow({
icon: "./assets/icon.png",
icon:
process.platform === "win32" ? "./assets/icon.ico" : "./assets/icon.png",
width: 1280,
height: 720,
minWidth: 800,
Expand Down
4 changes: 3 additions & 1 deletion enjoy/src/renderer/components/audios/audio-player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export const AudioPlayer = (props: {
id?: string;
md5?: string;
segmentIndex?: number;
onLoad?: (audio: AudioType) => void;
}) => {
const { id, md5, segmentIndex } = props;
const { id, md5, segmentIndex, onLoad } = props;
const { media, setMedia, setCurrentSegmentIndex, getCachedSegmentIndex } =
useContext(MediaShadowProviderContext);

Expand All @@ -21,6 +22,7 @@ export const AudioPlayer = (props: {

useEffect(() => {
setMedia(audio);
onLoad?.(audio);
}, [audio]);

useEffect(() => {
Expand Down
6 changes: 3 additions & 3 deletions enjoy/src/renderer/components/chats/chat-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ export const ChatHeader = (props: {
onClick={toggleSidePanel}
>
{sidePanelCollapsed ? (
<ChevronsRightIcon className="w-5 h-5" />
<ChevronsRightIcon className="size-4" />
) : (
<ChevronsLeftIcon className="w-5 h-5" />
<ChevronsLeftIcon className="size-4" />
)}
</Button>
{chat.type === ChatTypeEnum.CONVERSATION && (
Expand All @@ -59,7 +59,7 @@ export const ChatHeader = (props: {
<Dialog open={displayChatForm} onOpenChange={setDisplayChatForm}>
<DialogTrigger asChild>
<Button variant="ghost" size="icon" className="absolute right-4">
<SettingsIcon className="w-5 h-5" />
<SettingsIcon className="size-4" />
</Button>
</DialogTrigger>
<DialogContent className="max-w-screen-sm max-h-[70%] overflow-y-auto">
Expand Down
1 change: 1 addition & 0 deletions enjoy/src/renderer/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ export * from "./transcriptions";
export * from "./users";
export * from "./videos";
export * from "./widgets";
export * from "./login";
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ import {
SheetContent,
SheetHeader,
SheetTitle,
InputOTP,
InputOTPGroup,
InputOTPSlot,
} from "@renderer/components/ui";
import { useContext, useEffect, useRef, useState } from "react";
import { AppSettingsProviderContext } from "@renderer/context";
import { t } from "i18next";
import intlTelInput from "intl-tel-input/intlTelInputWithUtils";
import "intl-tel-input/build/css/intlTelInput.css";
import { REGEXP_ONLY_DIGITS } from "input-otp";

export const BanduLoginButton = () => {
const [open, setOpen] = useState(false);
Expand Down Expand Up @@ -117,30 +121,38 @@ export const BanduLoginForm = () => {
value={phoneNumber}
onInput={validatePhone}
onBlur={validatePhone}
disabled={countdown > 0}
className="border text-lg py-2 px-4 rounded w-80 dark:bg-background dark:text-foreground"
ref={ref}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="verrificationCode">{t("verificationCode")}</Label>
<Input
id="verrificationCode"
className="border py-2 h-10 px-4 rounded"
type="text"
minLength={5}
maxLength={5}
placeholder={t("verificationCode")}
value={code}
onChange={(e) => setCode(e.target.value)}
/>
</div>
{codeSent && (
<div className="grid gap-2">
<Label htmlFor="verrificationCode">{t("verificationCode")}</Label>
<InputOTP
id="verrificationCode"
maxLength={5}
value={code}
pattern={REGEXP_ONLY_DIGITS}
onChange={(value) => setCode(value)}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
</InputOTPGroup>
</InputOTP>
</div>
)}
</div>

<div className="grid grid-cols-2 gap-4">
<Button
variant="secondary"
size="lg"
className="w-full"
className="w-full px-2"
disabled={!phoneNumber || countdown > 0}
onClick={() => {
webApi
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { Button, toast, Input, Label } from "@renderer/components/ui";
import {
Button,
toast,
Input,
Label,
InputOTP,
InputOTPSlot,
InputOTPGroup,
} from "@renderer/components/ui";
import { useContext, useEffect, useState } from "react";
import { AppSettingsProviderContext } from "@renderer/context";
import { t } from "i18next";
import { REGEXP_ONLY_DIGITS } from "input-otp";

export const EmailLoginForm = () => {
const [email, setEmail] = useState<string>("");
Expand Down Expand Up @@ -41,27 +50,33 @@ export const EmailLoginForm = () => {
/>
</div>

<div className="grid gap-2">
<Label htmlFor="code">{t("verificationCode")}</Label>
<Input
id="code"
className="h-10"
type="text"
required
minLength={5}
maxLength={5}
placeholder={t("verificationCode")}
value={code}
onChange={(e) => setCode(e.target.value)}
/>
</div>
{codeSent && (
<div className="grid gap-2">
<Label htmlFor="code">{t("verificationCode")}</Label>
<InputOTP
id="code"
maxLength={5}
value={code}
pattern={REGEXP_ONLY_DIGITS}
onChange={(value) => setCode(value)}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
</InputOTPGroup>
</InputOTP>
</div>
)}
</div>

<div className="grid grid-cols-2 gap-4">
<Button
variant="secondary"
size="lg"
className="w-full"
className="w-full px-2"
disabled={!email || countdown > 0}
onClick={() => {
webApi
Expand All @@ -83,7 +98,7 @@ export const EmailLoginForm = () => {
<Button
variant="default"
size="lg"
className="w-full"
className="w-full px-2"
disabled={!code || code.length < 5 || !email}
onClick={() => {
webApi
Expand Down
5 changes: 5 additions & 0 deletions enjoy/src/renderer/components/login/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "./mixin-login-form";
export * from "./login-form";
export * from "./email-login-form";
export * from "./bandu-login-form";
export * from "./github-login-form";
Loading

0 comments on commit 437c133

Please sign in to comment.