Merge pull request #88 from an-lee/main

Add some default Hotkeys & fix some bugs
This commit is contained in:
an-lee
2024-01-10 22:03:24 +08:00
committed by GitHub
18 changed files with 117 additions and 23 deletions

View File

@@ -135,7 +135,6 @@
"sequelize-typescript": "^2.1.6",
"sqlite3": "^5.1.7",
"tailwind-scrollbar-hide": "^1.1.7",
"ts-key-enum": "^2.0.12",
"umzug": "^3.5.0",
"wavesurfer.js": "^7.6.3",
"zod": "^3.22.4"

View File

@@ -201,6 +201,10 @@
"resetAll": "Reset All",
"resetAllConfirmation": "It will remove all of your personal data, are you sure?",
"logoutAndRemoveAllPersonalData": "Logout and remove all personal data",
"hotkeys": "Hotkeys",
"quitApp": "Quit APP",
"openPreferences": "Open preferences",
"playOrPause": "Play or pause",
"about": "About",
"currentVersion": "Current version",
"checkUpdate": "Check update",

View File

@@ -201,6 +201,10 @@
"resetAll": "重置所有",
"resetAllConfirmation": "这将删除您的所有个人数据, 您确定要重置吗?",
"logoutAndRemoveAllPersonalData": "退出登录并删除所有个人数据",
"hotkeys": "快捷键",
"quitApp": "退出应用",
"openPreferences": "打开设置",
"playOrPause": "播放/暂停",
"about": "关于",
"currentVersion": "当前版本",
"checkUpdate": "检查更新",

View File

@@ -50,10 +50,6 @@ app.on("ready", async () => {
});
mainWindow.init();
globalShortcut.register("CommandOrControl+Shift+I", () => {
mainWindow.win.webContents.toggleDevTools();
});
});
// Quit when all windows are closed, except on macOS. There, it's common

View File

@@ -208,6 +208,12 @@ export class Audio extends Model<Audio> {
@AfterDestroy
static cleanupFile(audio: Audio) {
fs.remove(audio.filePath);
Recording.destroy({
where: {
targetId: audio.id,
targetType: "Audio",
},
});
}
static async buildFromLocalFile(

View File

@@ -1,4 +1,3 @@
import { app } from "electron";
import {
AfterCreate,
AfterUpdate,
@@ -28,6 +27,8 @@ import webApi from "@main/web-api";
import { AzureSpeechSdk } from "@main/azure-speech-sdk";
import camelcaseKeys from "camelcase-keys";
const logger = log.scope("db/models/recording");
@Table({
modelName: "Recording",
tableName: "recordings",
@@ -119,7 +120,7 @@ export class Recording extends Model<Recording> {
return storage
.put(this.md5, this.filePath)
.then((result) => {
log.debug("[RECORDING]", "upload result:", result.data);
logger.debug("upload result:", result.data);
if (result.data.success) {
this.update({ uploadedAt: new Date() });
} else {
@@ -127,7 +128,7 @@ export class Recording extends Model<Recording> {
}
})
.catch((err) => {
log.error("[RECORDING]", "upload failed:", err.message);
logger.error("upload failed:", err.message);
throw err;
});
}
@@ -187,10 +188,10 @@ export class Recording extends Model<Recording> {
if (!Array.isArray(findResult)) findResult = [findResult];
for (const instance of findResult) {
if (instance.targetType === "Audio" && instance.audio !== undefined) {
if (instance.targetType === "Audio" && instance.audio) {
instance.target = instance.audio.toJSON();
}
if (instance.targetType === "Video" && instance.video !== undefined) {
if (instance.targetType === "Video" && instance.video) {
instance.target = instance.video.toJSON();
}
// To prevent mistakes:
@@ -243,6 +244,13 @@ export class Recording extends Model<Recording> {
by: recording.duration,
});
});
} else if (recording.targetType === "Video") {
Video.findByPk(recording.targetId).then((video) => {
video.decrement("recordingsCount");
video.decrement("recordingsDuration", {
by: recording.duration,
});
});
}
}

View File

@@ -37,7 +37,7 @@ const logger = log.scope("db/models/video");
timestamps: true,
})
export class Video extends Model<Video> {
@IsUUID('all')
@IsUUID("all")
@Default(DataType.UUIDV4)
@Column({ primaryKey: true, type: DataType.UUID })
id: string;
@@ -230,6 +230,12 @@ export class Video extends Model<Video> {
@AfterDestroy
static cleanupFile(video: Video) {
fs.remove(video.filePath);
Recording.destroy({
where: {
targetId: video.id,
targetType: "Video",
},
});
}
static async buildFromLocalFile(

View File

@@ -247,6 +247,14 @@ main.init = () => {
return process.env.WEB_API_URL || WEB_API_URL;
});
ipcMain.handle("app-quit", () => {
app.quit();
});
ipcMain.handle("app-open-dev-tools", () => {
mainWindow.webContents.openDevTools();
});
// Shell
ipcMain.handle("shell-open-external", (_event, url) => {
shell.openExternal(url);

View File

@@ -20,6 +20,12 @@ contextBridge.exposeInMainWorld("__ENJOY_APP__", {
apiUrl: () => {
return ipcRenderer.invoke("app-api-url");
},
quit: () => {
ipcRenderer.invoke("app-quit");
},
openDevTools: () => {
ipcRenderer.invoke("app-open-dev-tools");
},
version,
},
providers: {

View File

@@ -9,6 +9,7 @@ import { RouterProvider } from "react-router-dom";
import { Toaster, useToast } from "@renderer/components/ui";
import { t } from "i18next";
import { Tooltip } from "react-tooltip";
import { useHotkeys } from "react-hotkeys-hook";
function App() {
const { toast } = useToast();
@@ -20,6 +21,22 @@ function App() {
});
});
const ControlOrCommand = navigator.platform.includes("Mac")
? "Meta"
: "Control";
useHotkeys(`${ControlOrCommand}+Comma`, () => {
document.getElementById("preferences-button")?.click();
});
useHotkeys(`${ControlOrCommand}+Q`, () => {
window.__ENJOY_APP__.app.quit();
});
useHotkeys(`${ControlOrCommand}+Shift+I`, () => {
window.__ENJOY_APP__.app.openDevTools();
});
return (
<ThemeProvider defaultTheme="light" storageKey="vite-ui-theme">
<AppSettingsProvider>

View File

@@ -27,7 +27,6 @@ import {
defaultLayoutIcons,
} from "@vidstack/react/player/layouts/default";
import { useHotkeys } from "react-hotkeys-hook";
import { Key } from "ts-key-enum";
const minPxPerSecBase = 150;

View File

@@ -0,0 +1,36 @@
import { t } from "i18next";
import { Separator } from "@renderer/components/ui";
export const Hotkeys = () => {
const commandOrCtrl = navigator.platform.includes("Mac") ? "Cmd" : "Ctrl";
return (
<>
<div className="font-semibold mb-4 capitilized">{t("hotkeys")}</div>
<div className="flex items-center justify-between py-4">
<div className="flex items-center space-x-2">{t("quitApp")}</div>
<kbd className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground">
{commandOrCtrl} + Q
</kbd>
</div>
<Separator />
<div className="flex items-center justify-between py-4">
<div className="flex items-center space-x-2">{t("openPreferences")}</div>
<kbd className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground">
{commandOrCtrl} + ,
</kbd>
</div>
<Separator />
<div className="flex items-center justify-between py-4">
<div className="flex items-center space-x-2">{t("playOrPause")}</div>
<kbd className="bg-muted px-2 py-1 rounded-md text-sm text-muted-foreground">
Space
</kbd>
</div>
<Separator />
</>
);
};

View File

@@ -2,3 +2,4 @@ export * from './preferences';
export * from './basic-settings';
export * from './advanced-settings';
export * from './about';
export * from './hotkeys';

View File

@@ -1,6 +1,6 @@
import { t } from "i18next";
import { Button, ScrollArea } from "@renderer/components/ui";
import { BasicSettings, AdvancedSettings, About } from "@renderer/components";
import { BasicSettings, AdvancedSettings, About, Hotkeys } from "@renderer/components";
import { useState } from "react";
export const Preferences = () => {
@@ -15,6 +15,11 @@ export const Preferences = () => {
label: t("advancedSettings"),
component: () => <AdvancedSettings />,
},
{
value: "hotkeys",
label: t("hotkeys"),
component: () => <Hotkeys />,
},
{
value: "about",
label: t("about"),

View File

@@ -28,7 +28,7 @@ export const RecordingActivities = (props: { from: string; to: string }) => {
to,
})
.then((_activities) => {
setActitivies(_activities);
setActitivies(_activities || []);
})
.finally(() => {
setLoading(false);
@@ -88,6 +88,11 @@ const Activity = (props: {
};
}) => {
const { activity, displayDate } = props;
if (!activity.target) {
return null;
}
return (
<>
{displayDate && (

View File

@@ -11,7 +11,6 @@ import {
HeadphonesIcon,
VideoIcon,
NewspaperIcon,
BookOpenTextIcon,
BookMarkedIcon,
UserIcon,
BotIcon,
@@ -210,6 +209,7 @@ export const Sidebar = () => {
? "secondary"
: "ghost"
}
id="preferences-button"
className="w-full xl:justify-start"
data-tooltip-id="sidebar-tooltip"
data-tooltip-content={t("sidebar.preferences")}

View File

@@ -5,6 +5,8 @@ type EnjoyAppType = {
reload: () => Promise<void>;
isPackaged: () => Promise<boolean>;
apiUrl: () => Promise<string>;
quit: () => Promise<void>;
openDevTools: () => Promise<void>;
version: string;
};
providers: {

View File

@@ -5840,7 +5840,6 @@ __metadata:
tailwind-scrollbar-hide: "npm:^1.1.7"
tailwindcss: "npm:^3.4.1"
tailwindcss-animate: "npm:^1.0.7"
ts-key-enum: "npm:^2.0.12"
ts-node: "npm:^10.9.2"
tslib: "npm:^2.6.2"
typescript: "npm:^5.3.3"
@@ -12163,13 +12162,6 @@ __metadata:
languageName: node
linkType: hard
"ts-key-enum@npm:^2.0.12":
version: 2.0.12
resolution: "ts-key-enum@npm:2.0.12"
checksum: 1d9cf8085785bdc324827c5c38f6359b09d9438deab81dfab7fa6d8315c618280ba7527e98d06b68c11066a5a81b06ef84eb378a48bf80ca5772ab0e4c6683d5
languageName: node
linkType: hard
"ts-node@npm:^10.9.2":
version: 10.9.2
resolution: "ts-node@npm:10.9.2"