Skip to content

Commit ce89ff3

Browse files
authored
Merge branch 'CapSoftware:main' into main
2 parents df68315 + 62f69ae commit ce89ff3

File tree

14 files changed

+116
-132
lines changed

14 files changed

+116
-132
lines changed

apps/desktop/src-tauri/src/windows.rs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -263,17 +263,6 @@ impl ShowCapWindow {
263263
.shadow(true)
264264
.center();
265265

266-
#[cfg(target_os = "windows")]
267-
{
268-
if !id.should_have_decorations() {
269-
builder = builder.transparent(true);
270-
}
271-
}
272-
#[cfg(not(target_os = "windows"))]
273-
{
274-
builder = builder.transparent(true);
275-
}
276-
277266
builder.build()?
278267
}
279268
Self::ModeSelect => {
@@ -293,17 +282,6 @@ impl ShowCapWindow {
293282
.focused(true)
294283
.shadow(true);
295284

296-
#[cfg(target_os = "windows")]
297-
{
298-
if !id.should_have_decorations() {
299-
builder = builder.transparent(true);
300-
}
301-
}
302-
#[cfg(not(target_os = "windows"))]
303-
{
304-
builder = builder.transparent(true);
305-
}
306-
307285
builder.build()?
308286
}
309287
Self::Camera => {
@@ -424,9 +402,7 @@ impl ShowCapWindow {
424402

425403
window
426404
}
427-
Self::InProgressRecording {
428-
position: _position,
429-
} => {
405+
Self::InProgressRecording { countdown } => {
430406
let mut width = 180.0 + 32.0;
431407

432408
let height = 40.0;
@@ -447,6 +423,10 @@ impl ShowCapWindow {
447423
(monitor.size().height as f64) / monitor.scale_factor() - height - 120.0,
448424
)
449425
.skip_taskbar(true)
426+
.initialization_script(format!(
427+
"window.COUNTDOWN = {};",
428+
countdown.unwrap_or_default()
429+
))
450430
.build()?;
451431

452432
#[cfg(target_os = "macos")]

apps/web/actions/video/upload.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
CreateInvalidationCommand,
1313
} from "@aws-sdk/client-cloudfront";
1414
import { revalidatePath } from "next/cache";
15+
import { userIsPro } from "@cap/utils";
1516

1617
async function getVideoUploadPresignedUrl({
1718
fileKey,
@@ -170,9 +171,7 @@ export async function createVideoAndGetUploadUrl({
170171
}
171172

172173
try {
173-
const isUpgraded = user.stripeSubscriptionStatus === "active";
174-
175-
if (!isUpgraded && duration && duration > 300) {
174+
if (!userIsPro(user) && duration && duration > 300) {
176175
throw new Error("upgrade_required");
177176
}
178177

apps/web/app/(org)/dashboard/caps/components/UploadCapButton.tsx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { Button } from "@cap/ui";
55
import { createVideoAndGetUploadUrl } from "@/actions/video/upload";
66
import { useRouter } from "next/navigation";
77
import { toast } from "sonner";
8-
import { isUserOnProPlan } from "@cap/utils";
98
import { UpgradeModal } from "@/components/UpgradeModal";
109
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
1110
import { faUpload } from "@fortawesome/free-solid-svg-icons";
1211
import { useDashboardContext } from "@/app/(org)/dashboard/Contexts";
1312
import { useUploadingContext } from "@/app/(org)/dashboard/caps/UploadingContext";
13+
import { userIsPro } from "@cap/utils";
1414

1515
export const UploadCapButton = ({
1616
onStart,
@@ -26,22 +26,17 @@ export const UploadCapButton = ({
2626
grey?: boolean;
2727
folderId?: string;
2828
}) => {
29-
const { user, isSubscribed } = useDashboardContext();
29+
const { user } = useDashboardContext();
3030
const inputRef = useRef<HTMLInputElement>(null);
31-
const {
32-
isUploading,
33-
setIsUploading,
34-
setUploadProgress,
35-
} = useUploadingContext();
31+
const { isUploading, setIsUploading, setUploadProgress } =
32+
useUploadingContext();
3633
const [upgradeModalOpen, setUpgradeModalOpen] = useState(false);
3734
const router = useRouter();
3835

3936
const handleClick = () => {
4037
if (!user) return;
4138

42-
const isCapPro = isUserOnProPlan({
43-
subscriptionStatus: user.stripeSubscriptionStatus,
44-
});
39+
const isCapPro = userIsPro(user);
4540

4641
if (!isCapPro) {
4742
setUpgradeModalOpen(true);
@@ -191,7 +186,7 @@ export const UploadCapButton = ({
191186
resolve(false);
192187
});
193188

194-
testVideo.addEventListener("loadstart", () => { });
189+
testVideo.addEventListener("loadstart", () => {});
195190

196191
testVideo.src = URL.createObjectURL(optimizedBlob);
197192
});
@@ -282,7 +277,7 @@ export const UploadCapButton = ({
282277
resolve(null);
283278
});
284279

285-
video.addEventListener("loadstart", () => { });
280+
video.addEventListener("loadstart", () => {});
286281
});
287282
};
288283

apps/web/app/api/desktop/[...route]/root.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { db } from "@cap/database";
22
import { organizations, users } from "@cap/database/schema";
33
import { buildEnv, serverEnv } from "@cap/env";
4-
import { isUserOnProPlan, stripe } from "@cap/utils";
4+
import { stripe, userIsPro } from "@cap/utils";
55
import { zValidator } from "@hono/zod-validator";
66
import { eq } from "drizzle-orm";
77
import { Hono } from "hono";
@@ -95,9 +95,7 @@ app.get("/org-custom-domain", async (c) => {
9595
app.get("/plan", async (c) => {
9696
const user = c.get("user");
9797

98-
let isSubscribed = isUserOnProPlan({
99-
subscriptionStatus: user.stripeSubscriptionStatus,
100-
});
98+
let isSubscribed = userIsPro(user);
10199

102100
if (user.thirdPartyStripeSubscriptionId) {
103101
isSubscribed = true;
@@ -149,9 +147,7 @@ app.post(
149147
const { priceId } = c.req.valid("json");
150148
const user = c.get("user");
151149

152-
if (
153-
isUserOnProPlan({ subscriptionStatus: user.stripeSubscriptionStatus })
154-
) {
150+
if (userIsPro(user)) {
155151
console.log("[POST] Error: User already on Pro plan");
156152
return c.json({ error: true, subscription: true }, { status: 400 });
157153
}

apps/web/app/api/settings/billing/subscribe/route.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isUserOnProPlan, stripe } from "@cap/utils";
1+
import { stripe, userIsPro } from "@cap/utils";
22
import { getCurrentUser } from "@cap/database/auth/session";
33
import { NextRequest } from "next/server";
44
import { eq } from "drizzle-orm";
@@ -26,11 +26,7 @@ export async function POST(request: NextRequest) {
2626
return Response.json({ error: true, auth: false }, { status: 401 });
2727
}
2828

29-
if (
30-
isUserOnProPlan({
31-
subscriptionStatus: user.stripeSubscriptionStatus as string,
32-
})
33-
) {
29+
if (userIsPro(user)) {
3430
console.error("User already has pro plan");
3531
return Response.json({ error: true, subscription: true }, { status: 400 });
3632
}

apps/web/app/api/settings/billing/usage/GET.ts

Whitespace-only changes.

apps/web/app/api/settings/billing/usage/route.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { isUserOnProPlan } from "@cap/utils";
1+
import { userIsPro } from "@cap/utils";
22
import { getCurrentUser } from "@cap/database/auth/session";
3-
import { NextRequest } from "next/server";
3+
44
import { count, eq } from "drizzle-orm";
55
import { db } from "@cap/database";
66
import { videos } from "@cap/database/schema";
@@ -26,11 +26,7 @@ export async function GET() {
2626
);
2727
}
2828

29-
if (
30-
isUserOnProPlan({
31-
subscriptionStatus: user.stripeSubscriptionStatus as string,
32-
})
33-
) {
29+
if (userIsPro(user)) {
3430
return Response.json(
3531
{
3632
subscription: true,

apps/web/app/api/video/transcribe/status/route.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { isUserOnProPlan } from "@cap/utils";
21
import { getCurrentUser } from "@cap/database/auth/session";
32
import { NextRequest } from "next/server";
43
import { count, eq } from "drizzle-orm";
@@ -37,12 +36,14 @@ export async function GET(request: NextRequest) {
3736
if (video[0].transcriptionStatus === "COMPLETE") {
3837
if (await isAiGenerationEnabled(user)) {
3938
Promise.resolve().then(() => {
40-
generateAiMetadata(videoId, user.id).catch(error => {
39+
generateAiMetadata(videoId, user.id).catch((error) => {
4140
console.error("Error generating AI metadata:", error);
4241
});
4342
});
4443
} else {
45-
console.log(`[transcribe-status] AI generation feature disabled for user ${user.id} (email: ${user.email}, pro: ${user.stripeSubscriptionStatus})`);
44+
console.log(
45+
`[transcribe-status] AI generation feature disabled for user ${user.id} (email: ${user.email}, pro: ${user.stripeSubscriptionStatus})`
46+
);
4647
}
4748
}
4849

apps/web/app/s/[videoId]/_components/ShareHeader.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Copy, Globe2 } from "lucide-react";
1313
import { buildEnv } from "@cap/env";
1414
import { editTitle } from "@/actions/videos/edit-title";
1515
import { usePublicEnv } from "@/utils/public-env";
16-
import { isUserOnProPlan } from "@cap/utils";
16+
import { userIsPro } from "@cap/utils";
1717
import { UpgradeModal } from "@/components/UpgradeModal";
1818
import clsx from "clsx";
1919
import { useDashboardContext } from "@/app/(org)/dashboard/Contexts";
@@ -95,7 +95,11 @@ export const ShareHeader = ({
9595
return `${webUrl}/s/${data.id}`;
9696
} else if (buildEnv.NEXT_PUBLIC_IS_CAP && customDomain && domainVerified) {
9797
return `https://${customDomain}/s/${data.id}`;
98-
} else if (buildEnv.NEXT_PUBLIC_IS_CAP && !customDomain && !domainVerified) {
98+
} else if (
99+
buildEnv.NEXT_PUBLIC_IS_CAP &&
100+
!customDomain &&
101+
!domainVerified
102+
) {
99103
return `https://cap.link/${data.id}`;
100104
} else {
101105
return `${webUrl}/s/${data.id}`;
@@ -109,18 +113,18 @@ export const ShareHeader = ({
109113
return `${webUrl}/s/${data.id}`;
110114
} else if (buildEnv.NEXT_PUBLIC_IS_CAP && customDomain && domainVerified) {
111115
return `${customDomain}/s/${data.id}`;
112-
} else if (buildEnv.NEXT_PUBLIC_IS_CAP && !customDomain && !domainVerified) {
116+
} else if (
117+
buildEnv.NEXT_PUBLIC_IS_CAP &&
118+
!customDomain &&
119+
!domainVerified
120+
) {
113121
return `cap.link/${data.id}`;
114122
} else {
115123
return `${webUrl}/s/${data.id}`;
116124
}
117125
};
118126

119-
const isUserPro = user
120-
? isUserOnProPlan({
121-
subscriptionStatus: user.stripeSubscriptionStatus,
122-
})
123-
: false;
127+
const isUserPro = userIsPro(user);
124128

125129
const handleSharingUpdated = () => {
126130
refresh();

apps/web/app/s/[videoId]/_components/ShareVideo.tsx

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@ import { userSelectProps } from "@cap/database/auth/session";
44
import { comments as commentsSchema, videos } from "@cap/database/schema";
55
import { NODE_ENV } from "@cap/env";
66
import { Logo } from "@cap/ui";
7-
import { isUserOnProPlan } from "@cap/utils";
8-
import { forwardRef, useImperativeHandle, useRef, useState, useEffect } from "react";
9-
import { formatChaptersAsVTT, formatTranscriptAsVTT, TranscriptEntry } from "./utils/transcript-utils";
7+
import { userIsPro } from "@cap/utils";
8+
import {
9+
forwardRef,
10+
useImperativeHandle,
11+
useRef,
12+
useState,
13+
useEffect,
14+
} from "react";
15+
import {
16+
formatChaptersAsVTT,
17+
formatTranscriptAsVTT,
18+
TranscriptEntry,
19+
} from "./utils/transcript-utils";
1020
import { useTranscript } from "hooks/use-transcript";
1121
import { parseVTT } from "./utils/transcript-utils";
1222
import { CapVideoPlayer } from "./CapVideoPlayer";
@@ -32,7 +42,6 @@ export const ShareVideo = forwardRef<
3242
aiProcessing?: boolean;
3343
}
3444
>(({ data, user, comments, chapters = [], aiProcessing = false }, ref) => {
35-
3645
const videoRef = useRef<HTMLVideoElement | null>(null);
3746
useImperativeHandle(ref, () => videoRef.current as HTMLVideoElement);
3847

@@ -60,7 +69,11 @@ export const ShareVideo = forwardRef<
6069

6170
// Handle subtitle URL creation
6271
useEffect(() => {
63-
if (data.transcriptionStatus === "COMPLETE" && transcriptData && transcriptData.length > 0) {
72+
if (
73+
data.transcriptionStatus === "COMPLETE" &&
74+
transcriptData &&
75+
transcriptData.length > 0
76+
) {
6477
const vttContent = formatTranscriptAsVTT(transcriptData);
6578
const blob = new Blob([vttContent], { type: "text/vtt" });
6679
const newUrl = URL.createObjectURL(blob);
@@ -133,7 +146,6 @@ export const ShareVideo = forwardRef<
133146

134147
return (
135148
<>
136-
137149
<div className="relative h-full">
138150
{data.source.type === "desktopMP4" ? (
139151
<CapVideoPlayer
@@ -155,32 +167,29 @@ export const ShareVideo = forwardRef<
155167
)}
156168
</div>
157169

158-
{user &&
159-
!isUserOnProPlan({
160-
subscriptionStatus: user.stripeSubscriptionStatus,
161-
}) && (
162-
<div className="absolute top-4 left-4 z-30">
163-
<div
164-
className="block cursor-pointer"
165-
onClick={(e) => {
166-
e.stopPropagation();
167-
setUpgradeModalOpen(true);
168-
}}
169-
>
170-
<div className="relative">
171-
<div className="opacity-50 transition-opacity hover:opacity-100 peer">
172-
<Logo className="w-auto h-4 sm:h-8" white={true} />
173-
</div>
174-
175-
<div className="absolute left-0 top-8 transition-transform duration-300 ease-in-out origin-top scale-y-0 peer-hover:scale-y-100">
176-
<p className="text-white text-xs font-medium whitespace-nowrap bg-black bg-opacity-50 px-2 py-0.5 rounded">
177-
Remove watermark
178-
</p>
179-
</div>
170+
{!userIsPro(user) && (
171+
<div className="absolute top-4 left-4 z-30">
172+
<div
173+
className="block cursor-pointer"
174+
onClick={(e) => {
175+
e.stopPropagation();
176+
setUpgradeModalOpen(true);
177+
}}
178+
>
179+
<div className="relative">
180+
<div className="opacity-50 transition-opacity hover:opacity-100 peer">
181+
<Logo className="w-auto h-4 sm:h-8" white={true} />
182+
</div>
183+
184+
<div className="absolute left-0 top-8 transition-transform duration-300 ease-in-out origin-top scale-y-0 peer-hover:scale-y-100">
185+
<p className="text-white text-xs font-medium whitespace-nowrap bg-black bg-opacity-50 px-2 py-0.5 rounded">
186+
Remove watermark
187+
</p>
180188
</div>
181189
</div>
182190
</div>
183-
)}
191+
</div>
192+
)}
184193
<UpgradeModal
185194
open={upgradeModalOpen}
186195
onOpenChange={setUpgradeModalOpen}

0 commit comments

Comments
 (0)