Skip to content

Commit

Permalink
prefer throwing over typesafe errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendonovich committed Nov 14, 2024
1 parent 98b5f9a commit f97c860
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 332 deletions.
Binary file added apps/desktop/src-tauri/icons/dmg-background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion apps/desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ async fn start_recording(app: AppHandle, state: MutableState<'_, App>) -> Result
Ok(recording) => state.set_current_recording(recording),
Err(error) => {
eprintln!("{error}");
return Err("Failed to set up recording".into());
return Err(format!("Failed to set up recording: {error}"));
}
};

Expand Down Expand Up @@ -2470,6 +2470,7 @@ pub async fn run() {
AuthenticationInvalid,
audio_meter::AudioInputLevelChange
])
.error_handling(tauri_specta::ErrorHandlingMode::Throw)
.typ::<ProjectConfiguration>()
.typ::<AuthStore>()
.typ::<hotkeys::HotkeysStore>()
Expand Down
9 changes: 7 additions & 2 deletions apps/desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"build": {
"beforeDevCommand": "node scripts/prepareSidecars.js && pnpm localdev",
"devUrl": "http://localhost:3001",
"beforeBuildCommand": "node scripts/prepareSidecars.js && pnpm build",
"beforeBuildCommand": "node scripts/prepareSidecars.js && pnpm turbo build --filter @cap/desktop",
"frontendDist": "../.output/public"
},
"app": {
Expand Down Expand Up @@ -40,6 +40,11 @@
"icons/icon.icns",
"icons/icon.ico"
],
"externalBin": ["../../../target/binaries/ffmpeg"]
"externalBin": ["../../../target/binaries/ffmpeg"],
"macOS": {
"dmg": {
"background": "./src-tauri/icons/dmg-background.png"
}
}
}
}
3 changes: 3 additions & 0 deletions apps/desktop/src/routes/(window-chrome)/(main).tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ export default function () {
await commands.stopRecording();
}
},
onError: (e) => {
alert("An error occurred, here are the details:\n" + e.toString());
},
}));

createAsync(() => getAuth());
Expand Down
46 changes: 21 additions & 25 deletions apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,28 @@ export default function Recordings() {
const fetchRecordings = createQuery(() => ({
queryKey: ["recordings"],
queryFn: async () => {
try {
const result = await commands.listRecordings();
if (result.status === "ok") {
const recordings = await Promise.all(
result.data.map(async (file) => {
const [id, path, meta] = file;
const thumbnailPath = `${path}/screenshots/display.jpg`;
const result = await commands
.listRecordings()
.then(
() =>
Promise.resolve([]) as ReturnType<typeof commands.listRecordings>
);

return {
id,
path,
prettyName: meta.pretty_name,
isNew: false,
thumbnailPath,
};
})
);
return recordings;
} else {
console.error("Failed to list recordings:", result.error);
return [];
}
} catch (error) {
console.error("Error fetching recordings:", error);
return [];
}
const recordings = await Promise.all(
result.map(async (file) => {
const [id, path, meta] = file;
const thumbnailPath = `${path}/screenshots/display.jpg`;

return {
id,
path,
prettyName: meta.pretty_name,
isNew: false,
thumbnailPath,
};
})
);
return recordings;
},
}));

Expand Down
37 changes: 19 additions & 18 deletions apps/desktop/src/routes/(window-chrome)/settings/screenshots.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,26 @@ export default function Screenshots() {
const fetchScreenshots = createQuery(() => ({
queryKey: ["screenshots"],
queryFn: async () => {
const result = await commands.listScreenshots();
if (result.status === "ok") {
const screenshots = await Promise.all(
result.data.map(async (file) => {
const [id, pngPath, meta] = file;

return {
id,
path: pngPath,
prettyName: meta.pretty_name,
isNew: false,
thumbnailPath: pngPath,
};
})
const result = await commands
.listScreenshots()
.catch(
() =>
Promise.resolve([]) as ReturnType<typeof commands.listScreenshots>
);
return screenshots;
} else {
return [];
}
const screenshots = await Promise.all(
result.map(async (file) => {
const [id, pngPath, meta] = file;

return {
id,
path: pngPath,
prettyName: meta.pretty_name,
isNew: false,
thumbnailPath: pngPath,
};
})
);
return screenshots;
},
}));

Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/routes/(window-chrome)/upgrade.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export default function Page() {

const checkUpgradeStatus = async () => {
const result = await commands.checkUpgradedAndUpdate();
if (result.status === "ok" && result.data === true) {
if (result) {
setUpgradeComplete(true);
}
};
Expand Down
7 changes: 2 additions & 5 deletions apps/desktop/src/routes/editor/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ export function Header() {
)}
>
<div class="flex flex-row items-center gap-[0.5rem] text-[0.875rem]"></div>
<div
class="flex flex-row gap-2 font-medium items-center"
>
<div class="flex flex-row gap-2 font-medium items-center">
<ShareButton />
<ExportButton />
</div>
Expand Down Expand Up @@ -170,14 +168,13 @@ function ShareButton() {

const uploadVideo = createMutation(() => ({
mutationFn: async () => {
const res = await commands.uploadRenderedVideo(
await commands.uploadRenderedVideo(
videoId,
project
? project
: presets.getDefaultConfig() ?? DEFAULT_PROJECT_CONFIG,
null
);
if (res.status !== "ok") throw new Error(res.error);
},
onSuccess: () => metaActions.refetch(),
}));
Expand Down
5 changes: 2 additions & 3 deletions apps/desktop/src/routes/editor/editorInstanceContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ export const [EditorInstanceContextProvider, useEditorInstanceContext] =

const [editorInstance] = createResource(async () => {
const instance = await commands.createEditorInstance(props.videoId);
if (instance.status !== "ok") throw new Error("Failed to start editor");

const [ws, isConnected] = createImageDataWS(
instance.data.framesSocketUrl,
instance.framesSocketUrl,
setLatestFrame
);

Expand All @@ -33,7 +32,7 @@ export const [EditorInstanceContextProvider, useEditorInstanceContext] =
}
});

return instance.data;
return instance;
});

return {
Expand Down
77 changes: 24 additions & 53 deletions apps/desktop/src/routes/prev-recordings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,12 @@ export default function () {
const allMedia = createMemo(() => [...recordings, ...screenshots]);

return (
<div class="w-screen h-[100vh] bg-transparent relative" style={{
"scrollbar-color": "auto transparent"
}}>
<div
class="w-screen h-[100vh] bg-transparent relative"
style={{
"scrollbar-color": "auto transparent",
}}
>
<div class="w-full relative left-0 bottom-0 flex flex-col-reverse pl-[40px] pb-[80px] gap-4 h-full overflow-y-auto">
<div class="pt-12 w-full flex flex-col gap-4">
<TransitionGroup
Expand All @@ -99,7 +102,7 @@ export default function () {
const [ref, setRef] = createSignal<HTMLElement | null>(null);
const normalizedPath = media.path.replace(/\\/g, "/");
const mediaId = normalizedPath.split("/").pop()?.split(".")[0]!;

const type = media.type ?? "recording";
const fileId =
type === "recording"
Expand All @@ -123,16 +126,12 @@ export default function () {
const copyMedia = createMutation(() => ({
mutationFn: async () => {
if (isRecording) {
const res = await commands.copyRenderedVideoToClipboard(
await commands.copyRenderedVideoToClipboard(
mediaId,
presets.getDefaultConfig() ?? DEFAULT_PROJECT_CONFIG
);
if (res.status !== "ok") throw new Error(res.error);
} else {
const res = await commands.copyScreenshotToClipboard(
media.path
);
if (res.status !== "ok") throw new Error(res.error);
await commands.copyScreenshotToClipboard(media.path);
}
},
}));
Expand All @@ -156,57 +155,36 @@ export default function () {
? suggestedName
: `${suggestedName}${extension}`;

const savePathResult = await commands.saveFileDialog(
const savePath = await commands.saveFileDialog(
fullFileName,
fileType
);

if (
savePathResult.status !== "ok" ||
!savePathResult.data
) {
if (!savePath) {
return false;
}

const savePath = savePathResult.data;

if (isRecording) {
const renderedPath = await commands.getRenderedVideo(
mediaId,
presets.getDefaultConfig() ?? DEFAULT_PROJECT_CONFIG
);

if (renderedPath.status !== "ok" || !renderedPath.data) {
if (!renderedPath) {
throw new Error("Failed to get rendered video path");
}

const copyResult = await commands.copyFileToPath(
renderedPath.data,
savePath
);
if (copyResult.status !== "ok") {
throw new Error(
`Failed to copy file: ${copyResult.error}`
);
}
await commands.copyFileToPath(renderedPath, savePath);
} else {
const copyResult = await commands.copyFileToPath(
media.path,
savePath
);
if (copyResult.status !== "ok") {
throw new Error(
`Failed to copy file: ${copyResult.error}`
);
}
await commands.copyFileToPath(media.path, savePath);
}

return true;
},
}));
const uploadMedia = createMutation(() => ({
mutationFn: async () => {
let res: Result<UploadResult, string>;
let res: UploadResult;
if (isRecording) {
res = await commands.uploadRenderedVideo(
mediaId,
Expand All @@ -217,11 +195,7 @@ export default function () {
res = await commands.uploadScreenshot(media.path);
}

if (res.status === "error") {
throw new Error(res.error);
}

switch (res.data) {
switch (res) {
case "NotAuthenticated":
throw new Error("Not authenticated");
case "PlanCheckFailed":
Expand All @@ -239,17 +213,14 @@ export default function () {

const [metadata] = createResource(async () => {
if (isRecording) {
const result = await commands.getVideoMetadata(
media.path,
null
);

if (result.status !== "ok") {
console.error(`Failed to get metadata: ${result.status}`);
return;
}

const [duration, size] = result.data;
const result = await commands
.getVideoMetadata(media.path, null)
.catch((e) => {
console.error(`Failed to get metadata: ${e}`);
});
if (!result) return;

const [duration, size] = result;
console.log(
`Metadata for ${media.path}: duration=${duration}, size=${size}`
);
Expand Down
19 changes: 5 additions & 14 deletions apps/desktop/src/utils/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,12 @@ export const listScreens = queryOptions({

const getOptions = queryOptions({
queryKey: ["recordingOptions"] as const,
queryFn: async () => {
const o = await commands.getRecordingOptions();
if (o.status === "ok") return o.data;
},
queryFn: () => commands.getRecordingOptions(),
});

const getCurrentRecording = queryOptions({
queryKey: ["currentRecording"] as const,
queryFn: async () => {
const o = await commands.getCurrentRecording();
if (o.status === "ok") return o.data[0];
},
queryFn: () => commands.getCurrentRecording().then((d) => d[0]),
});

const listVideoDevices = queryOptions({
Expand All @@ -57,9 +51,8 @@ export function createVideoDevicesQuery() {
export const listAudioDevices = queryOptions({
queryKey: ["audioDevices"] as const,
queryFn: async () => {
const r = await commands.listAudioDevices();
if (r.status === "ok")
return r.data.map((name) => ({ name, deviceId: name }));
const devices = await commands.listAudioDevices();
return devices.map((name) => ({ name, deviceId: name }));
},
reconcile: "name",
refetchInterval: 1000,
Expand Down Expand Up @@ -99,9 +92,7 @@ export function createOptionsQuery() {
const options = createQuery(() => ({
...getOptions,
select: (data) => {
if (data && state) {
return { ...data, ...state };
}
return { ...data, ...state };
},
}));

Expand Down
Loading

1 comment on commit f97c860

@vercel
Copy link

@vercel vercel bot commented on f97c860 Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.