diff --git a/apps/desktop/src-tauri/tauri.conf.json b/apps/desktop/src-tauri/tauri.conf.json
index a46efd26..197adcb4 100644
--- a/apps/desktop/src-tauri/tauri.conf.json
+++ b/apps/desktop/src-tauri/tauri.conf.json
@@ -1,6 +1,6 @@
{
"build": {
- "beforeDevCommand": "next dev -p 3001",
+ "beforeDevCommand": "next dev -p 3001 --turbo",
"beforeBuildCommand": "next build",
"devPath": "http://localhost:3001",
"distDir": "../out",
diff --git a/apps/desktop/src/app/page.tsx b/apps/desktop/src/app/page.tsx
index 9e02d4f5..dcc746da 100644
--- a/apps/desktop/src/app/page.tsx
+++ b/apps/desktop/src/app/page.tsx
@@ -6,7 +6,7 @@ import { Recorder } from "@/components/windows/inner/Recorder";
import { WindowActions } from "@/components/WindowActions";
import { Permissions } from "@/components/windows/Permissions";
import { LogoSpinner } from "@cap/ui";
-import { getPermissions, savePermissions } from "@/utils/helpers";
+import { getPermissions } from "@/utils/helpers";
import { initializeCameraWindow } from "@/utils/recording/utils";
import { getVersion } from "@tauri-apps/api/app";
import { invoke } from "@tauri-apps/api/tauri";
@@ -19,6 +19,8 @@ export default function CameraPage() {
const [permissions, setPermissions] = useState(getPermissions());
const [permissionsLoaded, setPermissionsLoaded] = useState(false);
+ if (typeof window === "undefined") return null;
+
useEffect(() => {
const checkVersion = async () => {
const storedVersion = localStorage.getItem("cap_test_build_version");
diff --git a/apps/desktop/src/components/WindowActions.tsx b/apps/desktop/src/components/WindowActions.tsx
index 23d594d7..c36e41a8 100644
--- a/apps/desktop/src/components/WindowActions.tsx
+++ b/apps/desktop/src/components/WindowActions.tsx
@@ -1,6 +1,7 @@
+"use client";
+
import { exit } from "@tauri-apps/api/process";
import { Home } from "@/components/icons/Home";
-// import { Settings } from "@/components/icons/Settings";
import { openLinkInBrowser } from "@/utils/helpers";
export const WindowActions = () => {
diff --git a/apps/desktop/src/components/windows/Camera.tsx b/apps/desktop/src/components/windows/Camera.tsx
index a0de0e25..b5f1f486 100644
--- a/apps/desktop/src/components/windows/Camera.tsx
+++ b/apps/desktop/src/components/windows/Camera.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import React, { useEffect, useRef, useState } from "react";
import { useMediaDevices } from "@/utils/recording/MediaDeviceContext";
import { CloseX } from "@/components/icons/CloseX";
@@ -19,6 +21,8 @@ export const Camera = () => {
},
};
+ if (typeof navigator === "undefined") return;
+
navigator.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
@@ -41,6 +45,8 @@ export const Camera = () => {
}, [selectedVideoDevice]);
const setWindowSize = async (type: "sm" | "lg") => {
+ if (typeof window === "undefined") return;
+
tauriWindowImport.then(
({ currentMonitor, appWindow, LogicalSize, LogicalPosition }) => {
currentMonitor().then((monitor) => {
@@ -70,7 +76,9 @@ export const Camera = () => {
};
const closeWindow = () => {
- import("@tauri-apps/api/window").then(async ({ appWindow }) => {
+ if (typeof window === "undefined") return;
+
+ tauriWindowImport.then(async ({ appWindow }) => {
await emit("change-device", {
type: "video",
device: {
diff --git a/apps/desktop/src/components/windows/Options.tsx b/apps/desktop/src/components/windows/Options.tsx
index 88dcb443..b4e249e5 100644
--- a/apps/desktop/src/components/windows/Options.tsx
+++ b/apps/desktop/src/components/windows/Options.tsx
@@ -1,23 +1,5 @@
"use client";
-
-// import { Recorder } from "@/components/windows/inner/Recorder";
import { SignIn } from "@/components/windows/inner/SignIn";
-import { listen } from "@tauri-apps/api/event";
-import { appWindow } from "@tauri-apps/api/window";
-// import { useAuth } from "@/utils/database/AuthContext";
-
export const Options = () => {
- // async function setupWindowReShow() {
- // await listen("tauri://focus", () => {
- // if (appWindow.isVisible) return;
-
- // appWindow
- // .show()
- // .catch((err) => console.error("Error showing window:", err));
- // });
- // }
-
- // setupWindowReShow();
-
return ;
};
diff --git a/apps/desktop/src/components/windows/Permissions.tsx b/apps/desktop/src/components/windows/Permissions.tsx
index c808a0cc..28902e94 100644
--- a/apps/desktop/src/components/windows/Permissions.tsx
+++ b/apps/desktop/src/components/windows/Permissions.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { Button, LogoBadge } from "@cap/ui";
import { useEffect, useState } from "react";
import { savePermissions, getPermissions } from "@/utils/helpers";
diff --git a/apps/desktop/src/components/windows/inner/Recorder.tsx b/apps/desktop/src/components/windows/inner/Recorder.tsx
index cb34f1c4..8af0a81c 100644
--- a/apps/desktop/src/components/windows/inner/Recorder.tsx
+++ b/apps/desktop/src/components/windows/inner/Recorder.tsx
@@ -15,9 +15,6 @@ import { getLatestVideoId, saveLatestVideoId } from "@/utils/database/utils";
import { openLinkInBrowser } from "@/utils/helpers";
import toast, { Toaster } from "react-hot-toast";
import { authFetch } from "@/utils/auth/helpers";
-import { appDataDir, join } from "@tauri-apps/api/path";
-import { open } from "@tauri-apps/api/shell";
-import * as Tauri from "@tauri-apps/api";
declare global {
interface Window {
@@ -42,6 +39,7 @@ export const Recorder = () => {
const [recordingTime, setRecordingTime] = useState("00:00");
const [canStopRecording, setCanStopRecording] = useState(false);
const [hasStartedRecording, setHasStartedRecording] = useState(false);
+ const tauriWindow = import("@tauri-apps/api/window");
const handleContextClick = async (option: "video" | "audio") => {
const { showMenu } = await import("tauri-plugin-context-menu");
@@ -52,37 +50,39 @@ export const Recorder = () => {
? selectedVideoDevice === null
: selectedAudioDevice === null;
}
-
+
return deviceKind === "videoinput"
? device.index === selectedVideoDevice?.index
: device.index === selectedAudioDevice?.index;
- }
+ };
const select = async (device: Device | null) => {
// if (isSelected(device)) {
// return
// }
- emit("change-device", { type: deviceKind, device: device }).catch((error) => {
- console.log("Failed to emit change-device event:", error);
- });
- }
+ emit("change-device", { type: deviceKind, device: device }).catch(
+ (error) => {
+ console.log("Failed to emit change-device event:", error);
+ }
+ );
+ };
- const devicesOfKind = devices.filter((device) => device.kind === deviceKind);
+ const devicesOfKind = devices.filter(
+ (device) => device.kind === deviceKind
+ );
const menuItems = [
{
label: "None",
checked: isSelected(null),
- event: async() => select(null)
+ event: async () => select(null),
},
- ...devicesOfKind.map((device) => (
- {
- label: device.label,
- checked: isSelected(device),
- event: async() => select(device)
- }
- ))
- ]
-
+ ...devicesOfKind.map((device) => ({
+ label: device.label,
+ checked: isSelected(device),
+ event: async () => select(device),
+ })),
+ ];
+
await showMenu({
items: [...menuItems],
...(devicesOfKind.length === 0 && {
@@ -137,18 +137,20 @@ export const Recorder = () => {
useEffect(() => {
let unlistenFn: UnlistenFn | null = null;
-
+
const setupListener = async () => {
unlistenFn = await listen("tray-on-left-click", (_) => {
if (isRecording) {
handleStopAllRecordings();
}
- const currentWindow = Tauri.window.getCurrent();
- if (!currentWindow.isVisible) {
- currentWindow.show();
- }
- currentWindow.setFocus();
+ tauriWindow.then(({ getCurrent }) => {
+ const currentWindow = getCurrent();
+ if (!currentWindow.isVisible) {
+ currentWindow.show();
+ }
+ currentWindow.setFocus();
+ });
});
};
@@ -178,12 +180,13 @@ export const Recorder = () => {
if (window.fathom !== undefined) {
window.fathom.trackEvent("start_recording");
}
- Tauri.window.getAll().forEach((window) => {
- if (window.label !== "camera") {
- window.hide();
- }
+ tauriWindow.then(({ getAll }) => {
+ getAll().forEach((window) => {
+ if (window.label !== "camera") {
+ window.hide();
+ }
+ });
});
-
emit("toggle-recording", true);
await invoke("start_dual_recording", {
options: {
@@ -376,7 +379,11 @@ export const Recorder = () => {
width="full"
handler={() => handleContextClick("video")}
icon={}
- label={devices.length === 0 ? "Video" : selectedVideoDevice?.label || "None"}
+ label={
+ devices.length === 0
+ ? "Video"
+ : selectedVideoDevice?.label || "None"
+ }
active={selectedVideoDevice !== null}
recordingOption={true}
optionName="Video"
@@ -385,7 +392,11 @@ export const Recorder = () => {
width="full"
handler={() => handleContextClick("audio")}
icon={}
- label={devices.length === 0 ? "Mic" : selectedAudioDevice?.label || "None"}
+ label={
+ devices.length === 0
+ ? "Mic"
+ : selectedAudioDevice?.label || "None"
+ }
active={selectedAudioDevice !== null}
recordingOption={true}
optionName="Audio"
diff --git a/apps/desktop/src/utils/recording/MediaDeviceContext.tsx b/apps/desktop/src/utils/recording/MediaDeviceContext.tsx
index 63c51389..ed9e7031 100644
--- a/apps/desktop/src/utils/recording/MediaDeviceContext.tsx
+++ b/apps/desktop/src/utils/recording/MediaDeviceContext.tsx
@@ -47,10 +47,12 @@ export const MediaDeviceContext = createContext<
export const MediaDeviceProvider: React.FC> = ({
children,
}) => {
- const [selectedVideoDevice, setSelectedVideoDevice] =
- useState(null);
- const [selectedAudioDevice, setSelectedAudioDevice] =
- useState(null);
+ const [selectedVideoDevice, setSelectedVideoDevice] = useState(
+ null
+ );
+ const [selectedAudioDevice, setSelectedAudioDevice] = useState(
+ null
+ );
const [selectedDisplayType, setSelectedDisplayType] = useState<
"screen" | "window" | "area"
>("screen");
@@ -58,6 +60,7 @@ export const MediaDeviceProvider: React.FC> = ({
const [isRecording, setIsRecording] = useState(false);
const [startingRecording, setStartingRecording] = useState(false);
const getDevicesCalled = useRef(false);
+ const tauriWindowImport = import("@tauri-apps/api/window");
const getDevices = useCallback(async () => {
await enumerateAndStoreDevices();
@@ -111,29 +114,40 @@ export const MediaDeviceProvider: React.FC> = ({
if (!type) {
return;
}
+
+ if (typeof window === "undefined") return;
+
if (window.fathom !== undefined) {
- window.fathom.trackEvent(`${type === "videoinput" ? "video" : "audio"}_device_change`);
+ window.fathom.trackEvent(
+ `${type === "videoinput" ? "video" : "audio"}_device_change`
+ );
}
if (type === "videoinput") {
- import("@tauri-apps/api/window").then(({ WebviewWindow }) => {
+ tauriWindowImport.then(({ WebviewWindow }) => {
if (WebviewWindow.getByLabel("camera")) {
WebviewWindow.getByLabel("camera").close();
} else if (type === "videoinput" && device) {
initializeCameraWindow();
}
});
-
- if ((!device && selectedVideoDevice) || (selectedVideoDevice?.index !== device?.index)) {
+
+ if (
+ (!device && selectedVideoDevice) ||
+ selectedVideoDevice?.index !== device?.index
+ ) {
setSelectedVideoDevice(device);
}
}
if (type === "audioinput") {
- if ((!device && selectedAudioDevice) || (selectedAudioDevice?.index !== device?.index)) {
+ if (
+ (!device && selectedAudioDevice) ||
+ selectedAudioDevice?.index !== device?.index
+ ) {
setSelectedAudioDevice(device);
}
}
- }
+ };
useEffect(() => {
let unlistenFnChangeDevice: any;
@@ -141,18 +155,29 @@ export const MediaDeviceProvider: React.FC> = ({
const setupListeners = async () => {
try {
- unlistenFnChangeDevice = await listen<{ type: string, device: Device | null }>("change-device", (event) => {
- updateSelectedDevice(event.payload.type as DeviceKind, event.payload.device);
+ unlistenFnChangeDevice = await listen<{
+ type: string;
+ device: Device | null;
+ }>("change-device", (event) => {
+ updateSelectedDevice(
+ event.payload.type as DeviceKind,
+ event.payload.device
+ );
});
} catch (error) {
console.error("Error setting up change-device listener:", error);
}
try {
- unlistenFnTraySetDevice = await listen<{ type: string, id: string | null }>("tray-set-device-id", (event) => {
+ unlistenFnTraySetDevice = await listen<{
+ type: string;
+ id: string | null;
+ }>("tray-set-device-id", (event) => {
const id = event.payload.id;
const kind = event.payload.type as DeviceKind;
- const newDevice = id ? devices.find((device) => kind === device.kind && id === device.id) : null;
+ const newDevice = id
+ ? devices.find((device) => kind === device.kind && id === device.id)
+ : null;
updateSelectedDevice(kind, newDevice);
});
} catch (error) {
@@ -164,9 +189,7 @@ export const MediaDeviceProvider: React.FC> = ({
if (devices.length !== 0) {
emit("media-devices-set", {
- mediaDevices: [
- ...(devices as Omit[])
- ],
+ mediaDevices: [...(devices as Omit[])],
selectedVideo: selectedVideoDevice,
selectedAudio: selectedAudioDevice,
});
diff --git a/apps/desktop/src/utils/recording/utils.ts b/apps/desktop/src/utils/recording/utils.ts
index 384e21d3..c05e19b9 100644
--- a/apps/desktop/src/utils/recording/utils.ts
+++ b/apps/desktop/src/utils/recording/utils.ts
@@ -1,6 +1,5 @@
"use client";
-import { emit } from "@tauri-apps/api/event";
import { invoke } from "@tauri-apps/api/tauri";
export const enumerateAndStoreDevices = async () => {
@@ -51,6 +50,7 @@ export const getSelectedVideoProperties = async () => {
};
export const initializeCameraWindow = async () => {
+ if (typeof window === "undefined") return;
import("@tauri-apps/api/window").then(({ currentMonitor, WebviewWindow }) => {
currentMonitor().then((monitor) => {
const windowWidth = 230;
diff --git a/apps/web/package.json b/apps/web/package.json
index 199d1231..9a3bfee9 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -3,7 +3,7 @@
"version": "0.2.0",
"private": true,
"scripts": {
- "dev": "next dev",
+ "dev": "next dev --turbo",
"build": "next build",
"start": "next start",
"lint": "next lint"