Skip to content
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
6 changes: 0 additions & 6 deletions apps/desktop/src-tauri/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub async fn export_video(
app: AppHandle,
path: PathBuf,
progress: tauri::ipc::Channel<RenderProgress>,
force: bool,
fps: u32,
resolution_base: XY<u32>,
) -> Result<PathBuf, String> {
Expand Down Expand Up @@ -39,11 +38,6 @@ pub async fn export_video(

let output_path = editor_instance.meta().output_path();

// If the file exists and we're not forcing a re-render, return it
if output_path.exists() && !force {
return Ok(output_path);
}

progress
.send(RenderProgress::EstimatedTotalFrames { total_frames })
.ok();
Expand Down
1 change: 0 additions & 1 deletion apps/desktop/src-tauri/src/recording.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ pub async fn start_recording(
// Allow the recording to proceed without error for any signed-in user
_ => {
// User is not signed in
let _ = ShowCapWindow::SignIn.show(&app).await;
return Err("Please sign in to use instant recording".to_string());
}
}
Expand Down
15 changes: 0 additions & 15 deletions apps/desktop/src-tauri/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ pub enum CapWindowId {
Camera,
InProgressRecording,
Upgrade,
SignIn,
ModeSelect,
}

Expand All @@ -53,7 +52,6 @@ impl FromStr for CapWindowId {
"in-progress-recording" => Self::InProgressRecording,
"recordings-overlay" => Self::RecordingsOverlay,
"upgrade" => Self::Upgrade,
"signin" => Self::SignIn,
"mode-select" => Self::ModeSelect,
s if s.starts_with("editor-") => Self::Editor {
id: s
Expand Down Expand Up @@ -86,7 +84,6 @@ impl std::fmt::Display for CapWindowId {
Self::InProgressRecording => write!(f, "in-progress-recording"),
Self::RecordingsOverlay => write!(f, "recordings-overlay"),
Self::Upgrade => write!(f, "upgrade"),
Self::SignIn => write!(f, "signin"),
Self::ModeSelect => write!(f, "mode-select"),
Self::Editor { id } => write!(f, "editor-{id}"),
}
Expand All @@ -106,7 +103,6 @@ impl CapWindowId {
Self::CaptureArea => "Cap Capture Area".to_string(),
Self::InProgressRecording => "Cap In Progress Recording".to_string(),
Self::Editor { .. } => "Cap Editor".to_string(),
Self::SignIn => "Cap Sign In".to_string(),
Self::ModeSelect => "Cap Mode Selection".to_string(),
Self::Camera => "Cap Camera".to_string(),
Self::RecordingsOverlay => "Cap Recordings Overlay".to_string(),
Expand All @@ -122,7 +118,6 @@ impl CapWindowId {
| Self::Editor { .. }
| Self::Settings
| Self::Upgrade
| Self::SignIn
| Self::ModeSelect
)
}
Expand All @@ -149,7 +144,6 @@ impl CapWindowId {
Some(match self {
Self::Setup => (600.0, 600.0),
Self::Main => (300.0, 360.0),
Self::SignIn => (300.0, 360.0),
Self::Editor { .. } => (1275.0, 800.0),
Self::Settings => (600.0, 450.0),
Self::Camera => (460.0, 920.0),
Expand All @@ -172,7 +166,6 @@ pub enum ShowCapWindow {
Camera { ws_port: u16 },
InProgressRecording { position: Option<(f64, f64)> },
Upgrade,
SignIn,
ModeSelect,
}

Expand Down Expand Up @@ -239,13 +232,6 @@ impl ShowCapWindow {
Box::pin(Self::Setup.show(app)).await?
}
}
Self::SignIn => self
.window_builder(app, "/signin")
.resizable(false)
.maximized(false)
.maximizable(false)
.center()
.build()?,
Self::Settings { page } => self
.window_builder(
app,
Expand Down Expand Up @@ -568,7 +554,6 @@ impl ShowCapWindow {
ShowCapWindow::Camera { .. } => CapWindowId::Camera,
ShowCapWindow::InProgressRecording { .. } => CapWindowId::InProgressRecording,
ShowCapWindow::Upgrade => CapWindowId::Upgrade,
ShowCapWindow::SignIn => CapWindowId::SignIn,
ShowCapWindow::ModeSelect => CapWindowId::ModeSelect,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import { clientEnv } from "~/utils/env";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { commands } from "~/utils/tauri";
import { identifyUser, trackEvent } from "~/utils/analytics";
import { ComponentProps } from "solid-js";

export default function Page() {
export function SignInButton(
props: Omit<ComponentProps<typeof Button>, "onClick">
) {
const signIn = createMutation(() => ({
mutationFn: async (abort: AbortController) => {
const platform = import.meta.env.DEV ? "web" : "desktop";
Expand All @@ -28,45 +31,27 @@ export default function Page() {

await processAuthData(await session.complete());

await commands.showWindow("Main");

// Add a small delay to ensure window is ready
await new Promise((resolve) => setTimeout(resolve, 500));

const mainWindow = await Window.getByLabel("main");
mainWindow?.setFocus();

getCurrentWindow().close();
getCurrentWindow().setFocus();
},
}));

return (
<div class="flex flex-col p-[1rem] gap-[0.75rem] text-[0.875rem] font-[400] flex-1 bg-gray-100">
<div class="space-y-[0.375rem] flex-1">
<IconCapLogo class="size-[3rem]" />
<h1 class="text-[1rem] font-[700] text-black-transparent-80">
Sign in to Cap
</h1>
<p class="text-gray-400">Beautiful screen recordings, owned by you.</p>
</div>
{signIn.isPending ? (
<Button
variant="secondary"
onClick={() => {
signIn.variables.abort();
signIn.reset();
}}
>
Cancel sign in
</Button>
) : (
<div class="flex flex-col gap-2">
<Button onClick={() => signIn.mutate(new AbortController())}>
Sign in with your browser
</Button>
</div>
)}
</div>
<Button
size="md"
class="flex flex-grow justify-center items-center"
{...props}
variant={signIn.isPending ? "secondary" : props.variant}
onClick={() => {
if (signIn.isPending) {
signIn.variables.abort();
signIn.reset();
} else {
signIn.mutate(new AbortController());
}
}}
>
{signIn.isPending ? "Cancel Sign In" : props.children ?? "Sign In"}
</Button>
);
}

Expand Down
59 changes: 59 additions & 0 deletions apps/desktop/src/components/callback.template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
export default `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<title>Cap Auth</title>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-weight: 400;
}
body {
display: flex;
align-items: center;
justify-content: center;
font-family: sans-serif;
text-align: center;
background-color: #f8f9fa;
}
.container {
padding: 30px;
width: 100%;
max-width: 400px;
margin: 0 auto;
}
.logo {
width: 130px;
height: auto;
margin-bottom: 20px;
}
p {
font-size: 21px;
line-height: 26px;
color: #12161F;
margin: 0;
}
.error {
color: #dc2626;
margin-top: 12px;
font-size: 16px;
}
</style>
</head>
<body>
<div class="container">
<svg class="logo" viewBox="0 0 103 40" fill="none" xmlns="http://www.w3.org/2000/svg"> <rect x="0.25" y="0.25" width="39.5" height="39.5" rx="7.75" fill="white"/> <rect x="0.25" y="0.25" width="39.5" height="39.5" rx="7.75" stroke="#E7EAF0" stroke-width="0.5"/> <path d="M20 36C28.8365 36 36 28.8365 36 20C36 11.1635 28.8365 4 20 4C11.1635 4 4 11.1635 4 20C4 28.8365 11.1635 36 20 36Z" fill="#4785FF"/> <path d="M20.0001 33C27.1797 33 33 27.1797 33 20.0001C33 12.8203 27.1797 7 20.0001 7C12.8203 7 7 12.8204 7 20.0001C7 27.1797 12.8204 33 20.0001 33Z" fill="#ADC9FF"/> <path d="M20.0001 30.0002C25.5229 30.0002 30.0002 25.5229 30.0002 20.0001C30.0002 14.4773 25.5229 10.0002 20.0001 10.0002C14.4773 10.0002 10.0002 14.4773 10.0002 20.0001C10.0002 25.5229 14.4773 30.0002 20.0001 30.0002Z" fill="white"/> <path d="M58.416 30.448C53.012 30.448 49.204 26.584 49.204 20.088C49.204 13.704 52.872 9.672 58.472 9.672C63.54 9.672 66.256 12.332 67.096 16.84L63.288 17.036C62.812 14.432 61.216 12.836 58.472 12.836C55.084 12.836 52.984 15.664 52.984 20.088C52.984 24.568 55.14 27.284 58.444 27.284C61.384 27.284 62.952 25.576 63.4 22.72L67.208 22.916C66.424 27.592 63.456 30.448 58.416 30.448ZM74.6451 30.336C71.5091 30.336 69.4371 28.852 69.4371 26.248C69.4371 23.672 71.0331 22.3 74.3091 21.656L79.2651 20.676C79.2651 18.576 78.2851 17.484 76.4091 17.484C74.6451 17.484 73.6931 18.296 73.3571 19.808L69.6891 19.64C70.2771 16.504 72.6851 14.712 76.4091 14.712C80.6651 14.712 82.8491 16.952 82.8491 20.928V26.36C82.8491 27.172 83.1291 27.396 83.6891 27.396H84.1651V30C83.9411 30.056 83.3531 30.112 82.8771 30.112C81.2531 30.112 80.0491 29.524 79.7411 27.676C79.0131 29.272 77.1091 30.336 74.6451 30.336ZM75.3731 27.732C77.7531 27.732 79.2651 26.22 79.2651 23.952V23.112L75.4011 23.896C73.8051 24.204 73.1611 24.876 73.1611 25.912C73.1611 27.088 73.9451 27.732 75.3731 27.732ZM86.8741 34.2V15.048H90.3181L90.3741 17.26C91.2421 15.608 92.8941 14.712 94.8541 14.712C99.1101 14.712 101.21 18.212 101.21 22.524C101.21 26.836 99.0821 30.336 94.8261 30.336C92.9221 30.336 91.2701 29.412 90.4581 27.956V34.2H86.8741ZM93.9861 27.424C96.1701 27.424 97.4861 25.604 97.4861 22.524C97.4861 19.444 96.1701 17.624 93.9861 17.624C91.8021 17.624 90.4581 19.276 90.4581 22.524C90.4581 25.772 91.7741 27.424 93.9861 27.424Z" fill="#12161F"/> </svg>
<p id="message">You are now signed in. Please re-open the Cap desktop app to continue.</p>
<div id="error-container"></div>
</div>
</body>
</html>
`;
49 changes: 29 additions & 20 deletions apps/desktop/src/routes/(window-chrome)/(main).tsx
Original file line number Diff line number Diff line change
Expand Up @@ -293,26 +293,34 @@ export default function () {
<SystemAudio options={options.data} setOptions={setOptions} />
)}
<div class="flex items-center space-x-1 w-full">
<Button
disabled={toggleRecording.isPending}
variant={isRecording() ? "destructive" : "primary"}
size="md"
onClick={() => toggleRecording.mutate()}
class="flex flex-grow justify-center items-center"
>
{isRecording() ? (
"Stop Recording"
) : (
<>
{options.data?.mode === "instant" ? (
<IconCapInstant class="w-[0.8rem] h-[0.8rem] mr-1.5" />
) : (
<IconCapFilmCut class="w-[0.8rem] h-[0.8rem] mr-2 -mt-[1.5px]" />
)}
Start Recording
</>
)}
</Button>
{options.data?.mode === "instant" && !auth.data ? (
<SignInButton>
Sign In for{" "}
<IconCapInstant class="size-[0.8rem] ml-[0.14rem] mr-0.5" />
Instant Mode
</SignInButton>
) : (
<Button
disabled={toggleRecording.isPending}
variant={isRecording() ? "destructive" : "primary"}
size="md"
onClick={() => toggleRecording.mutate()}
class="flex flex-grow justify-center items-center"
>
{isRecording() ? (
"Stop Recording"
) : (
<>
{options.data?.mode === "instant" ? (
<IconCapInstant class="size-[0.8rem] mr-1.5" />
) : (
<IconCapFilmCut class="size-[0.8rem] mr-2 -mt-[1.5px]" />
)}
Start Recording
</>
)}
</Button>
)}
{/* <Button
disabled={isRecording()}
variant="secondary"
Expand Down Expand Up @@ -362,6 +370,7 @@ import { Transition } from "solid-transition-group";
import { apiClient } from "~/utils/web-api";
import { useWindowChrome } from "./Context";
import { authStore, generalSettingsStore } from "~/store";
import { SignInButton } from "~/components/SignInButton";

let hasChecked = false;
function createUpdateCheck() {
Expand Down
15 changes: 9 additions & 6 deletions apps/desktop/src/routes/(window-chrome)/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getVersion } from "@tauri-apps/api/app";
import "@total-typescript/ts-reset/filter-boolean";
import { createResource, For, Show, Suspense } from "solid-js";
import toast from "solid-toast";
import { SignInButton } from "~/components/SignInButton";

import { authStore } from "~/store";
import { trackEvent } from "~/utils/analytics";
Expand All @@ -23,8 +24,6 @@ export default function Settings(props: RouteSectionProps) {
if (auth.data) {
trackEvent("user_signed_out", { platform: "desktop" });
authStore.set(undefined);
} else {
commands.showWindow("SignIn");
}
};

Expand Down Expand Up @@ -136,13 +135,17 @@ export default function Settings(props: RouteSectionProps) {
)}
</For>
</ul>
<div class="p-[0.625rem]">
<div class="p-[0.625rem] text-left flex flex-col">
<Show when={version()}>
{(v) => <p class="mb-1 text-xs text-gray-400">v{v()}</p>}
</Show>
<Button onClick={handleAuth} variant="secondary" class="w-full">
{auth.data ? "Sign Out" : "Sign In"}
</Button>
{auth.data ? (
<Button onClick={handleAuth} variant="secondary" class="w-full">
Sign Out
</Button>
) : (
<SignInButton>Sign In</SignInButton>
)}
</div>
</div>
<div class="overflow-y-hidden flex-1 bg-gray-50 animate-in">
Expand Down
6 changes: 1 addition & 5 deletions apps/desktop/src/routes/editor/ExportDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ const ExportDialog = () => {
const outputPath = await commands.exportVideo(
path,
progress,
true,
settings.fps,
{
x: settings.resolution.width,
Expand Down Expand Up @@ -238,7 +237,6 @@ const ExportDialog = () => {
const videoPath = await commands.exportVideo(
path,
progress,
true,
settings.fps,
{
x: settings.resolution.width,
Expand Down Expand Up @@ -285,7 +283,6 @@ const ExportDialog = () => {
// Check authentication first
const existingAuth = await authStore.get();
if (!existingAuth) {
await commands.showWindow("SignIn");
throw new Error("You need to sign in to share recordings");
}

Expand Down Expand Up @@ -360,7 +357,7 @@ const ExportDialog = () => {
);
};

await commands.exportVideo(path, progress, true, settings.fps, {
await commands.exportVideo(path, progress, settings.fps, {
x: settings.resolution.width,
y: settings.resolution.height,
});
Expand All @@ -375,7 +372,6 @@ const ExportDialog = () => {
});

if (result === "NotAuthenticated") {
await commands.showWindow("SignIn");
throw new Error("You need to sign in to share recordings");
} else if (result === "PlanCheckFailed")
throw new Error("Failed to verify your subscription status");
Expand Down
Loading