Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saved Region To Record setting #490

Merged
merged 3 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/app/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ export const DEFAULT_SETTINGS = {
ultraFast: true,
audioDevicesToRecord: [] as string[],
seperateAudioTracks: false,
hardwareEncoding: false
hardwareEncoding: false,
regionToRecord: { x: 0, y: 0, width: 0, height: 0 }
},
key: {
startStopRecording: "F9",
startStopRecordingRegion: "F10",
startStopRecordingSavedRegion: "Shift+F10",
addBookmark: "F2"
}
} as Settings;
17 changes: 16 additions & 1 deletion src/common/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export type Icons =
| "bookmark"
| "film"
| "camera"
| "trash";
| "trash"
| "move";

export type IconDirection = "up" | "down" | "left" | "right";

Expand Down Expand Up @@ -460,6 +461,20 @@ function getIcon(name: Icons): { viewBox: string; el: JSX.Element } {
</>
)
};
case "move":
return {
viewBox: "0 0 512 512",
el: (
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="32"
d="M176 112l80-80 80 80M255.98 32l.02 448M176 400l80 80 80-80M400 176l80 80-80 80M112 176l-80 80 80 80M32 256h448"
/>
)
};
default:
return {
viewBox: "0 -10 1000 1000",
Expand Down
3 changes: 2 additions & 1 deletion src/common/RegionSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ipcRenderer } from "electron";
import { useEffect, useRef } from "react";
import { type CustomRegion } from "@/libs/recorder/argumentBuilder";

export default function RegionSelect() {
const dRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -97,7 +98,7 @@ export default function RegionSelect() {
console.log("stopDraw");
isDrawing = false;
const br = regionDiv.getBoundingClientRect();
ipcRenderer.send("region-selected", { x: br.x, y: br.y, width: br.width, height: br.height });
ipcRenderer.send("region-selected", { x: br.x, y: br.y, width: br.width, height: br.height } as CustomRegion);
} catch (err) {
ipcRenderer.send("region-select-cancelled", "stopDraw failed", err);
}
Expand Down
6 changes: 5 additions & 1 deletion src/common/TextBox.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import useDebouncer from "@/hooks/useDebouncer";
import { logger } from "@/libs/logger";
import { ipcRenderer } from "electron";
import { useState } from "react";
import { useEffect, useState } from "react";
import Icon, { type Icons } from "./Icon";
import { type CommonComponentProps } from "./types";

Expand Down Expand Up @@ -41,6 +41,10 @@ export default function TextBox(props: TextBoxProps) {
const { doDebounce } = useDebouncer(debounce);
const [curVal, setCurVal] = useState(value);

useEffect(() => {
setCurVal(value);
}, [value]);

// newVal param set as string becuase we get input value
// from onBlur event (e.target.value), which returns as only string.
// So no point having union type to include numbers as well.
Expand Down
17 changes: 17 additions & 0 deletions src/libs/recorder/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ ipcRenderer.on("startStopRecordingRegion-pressed", async () => {
await Recorder.auto(b);
});

ipcRenderer.on("startStopRecordingSavedRegion-pressed", async () => {
const r = store.getState().settings.recording.regionToRecord;
// A width and height at the very least is required.
if (!r.width || !r.height) {
logger.error("Recorder", "Cant record saved region", "a width and height must be set");
Notifications.popup({
id: "CANT-RECORD-SR",
title: "Can't Record Saved Region!",
message: "A width and or height has not been provided in settings!",
showCancel: true
}).catch((err) => logger.error("Recorder", "Failed to show CANT-RECORD-SR popup", err));
return;
}
logger.info("Recorder", "Saved Region", r);
await Recorder.auto(r);
});

ipcRenderer.on("addBookmark-pressed", async () => {
if (store.getState().recorder.recordingStatus !== 1) {
console.log("can't add bookmark when not recording");
Expand Down
18 changes: 16 additions & 2 deletions src/settings/keybind/KeyBindings.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { type RootState } from "@/app/store";
import { useDispatch, useSelector } from "react-redux";
import NamedContainer from "../../common/NamedContainer";
import { setAddBookmark, setStartStopRecording, setStartStopRecordingRegion } from "../settingsSlice";
import {
setAddBookmark,
setStartStopRecording,
setStartStopRecordingRegion,
setStartStopRecordingSavedRegion
} from "../settingsSlice";
import KeyBindButton from "./KeyBindButton";

export default function KeyBindings() {
Expand All @@ -19,7 +24,7 @@ export default function KeyBindings() {
}}
/>
</NamedContainer>
<NamedContainer title="Start/Stop Recording A Region">
<NamedContainer title="Record A Region">
<KeyBindButton
name="startStopRecordingRegion"
bind={state.startStopRecordingRegion}
Expand All @@ -28,6 +33,15 @@ export default function KeyBindings() {
}}
/>
</NamedContainer>
<NamedContainer title="Record Saved Region">
<KeyBindButton
name="startStopRecordingSavedRegion"
bind={state.startStopRecordingSavedRegion}
onUpdate={(newBind) => {
dispatch(setStartStopRecordingSavedRegion(newBind));
}}
/>
</NamedContainer>
<NamedContainer title="Add Bookmark To Recording">
<KeyBindButton
name="addBookmark"
Expand Down
57 changes: 57 additions & 0 deletions src/settings/pages/Recording.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
setFps,
setHardwareEncoding,
setMonitorToRecord,
setRegionToRecord,
setResolution,
setResolutionCustom,
setResolutionKeepAspectRatio,
Expand All @@ -25,6 +26,9 @@ import {
toggleAudioDeviceToRecord
} from "../settingsSlice";
import type { ResolutionScale } from "../types";
import Button from "@/common/Button";
import Tooltip from "@/common/Tooltip";
import { ipcRenderer } from "electron";

export default function Recording() {
const state = useSelector((store: RootState) => store.settings.recording);
Expand All @@ -51,6 +55,15 @@ export default function Recording() {
.catch((err) => logger.error("Recording", "Failed to get audio devices!", err));
}, []);

async function dragRegionToRecord() {
try {
const b = await ipcRenderer.invoke("select-region-win");
dispatch(setRegionToRecord({ x: b.x, y: b.y, width: b.width, height: b.height }));
} catch (err) {
logger.error("Settings/Recording", "Failed to drag new region", err);
}
}

return (
<>
<NamedContainer title="Video Device">
Expand All @@ -69,6 +82,50 @@ export default function Recording() {
/>
</NamedContainer>

<NamedContainer title="Region To Record" desc="Save a custom region so you don't always have to drag one.">
<div className="flex row gap-3 items-center">
<b>X</b>
<TextBox
type="number"
value={state.regionToRecord.x}
placeholder={0}
onChange={(s) => {
dispatch(setRegionToRecord({ x: s }));
}}
/>
<b>Y</b>
<TextBox
type="number"
value={state.regionToRecord?.y ?? ""}
placeholder={0}
onChange={(s) => {
dispatch(setRegionToRecord({ y: s }));
}}
/>
<b>W</b>
<TextBox
type="number"
value={state.regionToRecord?.width ?? ""}
placeholder={0}
onChange={(s) => {
dispatch(setRegionToRecord({ width: s }));
}}
/>
<b>H</b>
<TextBox
type="number"
value={state.regionToRecord?.height ?? ""}
placeholder={0}
onChange={(s) => {
dispatch(setRegionToRecord({ height: s }));
}}
/>
<Tooltip text="Drag Region">
<Button icon="move" onClick={dragRegionToRecord} />
</Tooltip>
</div>
</NamedContainer>

<NamedContainer title="Format">
<DropDown
activeItem={state.format}
Expand Down
11 changes: 11 additions & 0 deletions src/settings/settingsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ const settingsSlice = createSlice({
setHardwareEncoding(state, action: PayloadAction<boolean>) {
state.recording.hardwareEncoding = action.payload;
},
setRegionToRecord(state, action: PayloadAction<{ x?: number; y?: number; width?: number; height?: number }>) {
if (typeof action.payload.x === "number") state.recording.regionToRecord.x = action.payload.x;
if (typeof action.payload.y === "number") state.recording.regionToRecord.y = action.payload.y;
if (typeof action.payload.width === "number") state.recording.regionToRecord.width = action.payload.width;
if (typeof action.payload.height === "number") state.recording.regionToRecord.height = action.payload.height;
},

//
// Key Binding Settings
Expand All @@ -95,6 +101,9 @@ const settingsSlice = createSlice({
setStartStopRecordingRegion(state, action: PayloadAction<string>) {
state.key.startStopRecordingRegion = action.payload;
},
setStartStopRecordingSavedRegion(state, action: PayloadAction<string>) {
state.key.startStopRecordingSavedRegion = action.payload;
},
setAddBookmark(state, action: PayloadAction<string>) {
state.key.addBookmark = action.payload;
}
Expand Down Expand Up @@ -124,9 +133,11 @@ export const {
removeAudioDevicesToRecord,
setSeperateAudioTracks,
setHardwareEncoding,
setRegionToRecord,

setStartStopRecording,
setStartStopRecordingRegion,
setStartStopRecordingSavedRegion,
setAddBookmark
} = settingsSlice.actions;

Expand Down
11 changes: 11 additions & 0 deletions src/settings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,22 @@ export interface RecordingSettings {
* If we should offload encoding to GPU.
*/
hardwareEncoding: boolean;

/**
* Saved custom region of screen to record.
* If a user only records a certain space of
* their screen always, this will help by saving that region.
*/
regionToRecord: { x: number; y: number; width: number; height: number };
}

export interface KeyBindingSettings {
startStopRecording: string;
startStopRecordingRegion: string;
/**
* Start/stop recording the `regionToRecord` setting if set.
*/
startStopRecordingSavedRegion: string;
addBookmark: string;
}

Expand Down
Loading