Skip to content

Commit 0b234ca

Browse files
authored
feat: integrate sync eng (#2924)
1 parent d3887f2 commit 0b234ca

File tree

202 files changed

+5052
-15955
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

202 files changed

+5052
-15955
lines changed

apps/web/client/src/app/_components/auth-modal.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import {
1010
import { Button } from '@onlook/ui/button';
1111
import { useTranslations } from 'next-intl';
1212
import { useAuthContext } from '../auth/auth-context';
13-
import { GithubLoginButton, GoogleLoginButton } from './login-button';
13+
import { LoginButton } from './login-button';
14+
import { SignInMethod } from '@onlook/models/auth';
15+
import { Icons } from '@onlook/ui/icons';
1416

1517
export function AuthModal() {
1618
const { setIsAuthModalOpen, isAuthModalOpen } = useAuthContext();
@@ -28,8 +30,20 @@ export function AuthModal() {
2830
</AlertDialogDescription>
2931
</AlertDialogHeader>
3032
<div className="space-y-2 flex flex-col">
31-
<GithubLoginButton className="!bg-black" />
32-
<GoogleLoginButton className="!bg-black" />
33+
<LoginButton
34+
className="!bg-black"
35+
method={SignInMethod.GITHUB}
36+
icon={<Icons.GitHubLogo className="w-4 h-4 mr-2" />}
37+
translationKey="github"
38+
providerName="GitHub"
39+
/>
40+
<LoginButton
41+
className="!bg-black"
42+
method={SignInMethod.GOOGLE}
43+
icon={<Icons.GoogleLogo viewBox="0 0 24 24" className="w-4 h-4 mr-2" />}
44+
translationKey="google"
45+
providerName="Google"
46+
/>
3347
</div>
3448
<AlertDialogFooter className="flex !justify-center w-full">
3549
<Button variant={'ghost'} onClick={() => setIsAuthModalOpen(false)}>

apps/web/client/src/app/_components/login-button.tsx

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,41 @@ import { Button } from '@onlook/ui/button';
44
import { Icons } from '@onlook/ui/icons';
55
import { cn } from '@onlook/ui/utils';
66
import { useTranslations } from 'next-intl';
7+
import { toast } from 'sonner';
78
import { useAuthContext } from '../auth/auth-context';
89

9-
export const GithubLoginButton = ({
10-
className,
11-
returnUrl,
12-
}: {
10+
interface LoginButtonProps {
1311
className?: string;
1412
returnUrl?: string | null;
15-
}) => {
16-
const t = useTranslations();
17-
const { lastSignInMethod, handleLogin, signingInMethod } = useAuthContext();
18-
const isLastSignInMethod = lastSignInMethod === SignInMethod.GITHUB;
19-
const isSigningIn = signingInMethod === SignInMethod.GITHUB;
20-
21-
return (
22-
<div className={cn('flex flex-col items-center w-full', className)}>
23-
<Button
24-
variant="outline"
25-
className={cn(
26-
'w-full items-center justify-center text-active text-small',
27-
isLastSignInMethod
28-
? 'bg-teal-100 dark:bg-teal-950 border-teal-300 dark:border-teal-700 text-teal-900 dark:text-teal-100 text-small hover:bg-teal-200/50 dark:hover:bg-teal-800 hover:border-teal-500/70 dark:hover:border-teal-500'
29-
: 'bg-background-onlook',
30-
)}
31-
onClick={() => handleLogin(SignInMethod.GITHUB, returnUrl ?? null)}
32-
disabled={!!signingInMethod}
33-
>
34-
{isSigningIn ? (
35-
<Icons.LoadingSpinner className="w-4 h-4 mr-2 animate-spin" />
36-
) : (
37-
<Icons.GitHubLogo className="w-4 h-4 mr-2" />
38-
)}
39-
{t(transKeys.welcome.login.github)}
40-
</Button>
41-
{isLastSignInMethod && (
42-
<p className="text-teal-500 text-small mt-1">{t(transKeys.welcome.login.lastUsed)}</p>
43-
)}
44-
</div>
45-
);
46-
};
13+
method: SignInMethod.GITHUB | SignInMethod.GOOGLE;
14+
icon: React.ReactNode;
15+
translationKey: keyof typeof transKeys.welcome.login;
16+
providerName: string;
17+
}
4718

48-
export const GoogleLoginButton = ({
19+
export const LoginButton = ({
4920
className,
5021
returnUrl,
51-
}: {
52-
className?: string;
53-
returnUrl?: string | null;
54-
}) => {
22+
method,
23+
icon,
24+
translationKey,
25+
providerName,
26+
}: LoginButtonProps) => {
5527
const t = useTranslations();
5628
const { lastSignInMethod, handleLogin, signingInMethod } = useAuthContext();
57-
const isLastSignInMethod = lastSignInMethod === SignInMethod.GOOGLE;
58-
const isSigningIn = signingInMethod === SignInMethod.GOOGLE;
29+
const isLastSignInMethod = lastSignInMethod === method;
30+
const isSigningIn = signingInMethod === method;
31+
32+
const handleLoginClick = async () => {
33+
try {
34+
await handleLogin(method, returnUrl ?? null);
35+
} catch (error) {
36+
console.error(`Error signing in with ${providerName}:`, error);
37+
toast.error(`Error signing in with ${providerName}`, {
38+
description: error instanceof Error ? error.message : 'Please try again.',
39+
});
40+
}
41+
};
5942

6043
return (
6144
<div className={cn('flex flex-col items-center w-full', className)}>
@@ -67,15 +50,15 @@ export const GoogleLoginButton = ({
6750
? 'bg-teal-100 dark:bg-teal-950 border-teal-300 dark:border-teal-700 text-teal-900 dark:text-teal-100 text-small hover:bg-teal-200/50 dark:hover:bg-teal-800 hover:border-teal-500/70 dark:hover:border-teal-500'
6851
: 'bg-background-onlook',
6952
)}
70-
onClick={() => handleLogin(SignInMethod.GOOGLE, returnUrl ?? null)}
53+
onClick={handleLoginClick}
7154
disabled={!!signingInMethod}
7255
>
7356
{isSigningIn ? (
7457
<Icons.LoadingSpinner className="w-4 h-4 mr-2 animate-spin" />
7558
) : (
76-
<Icons.GoogleLogo viewBox="0 0 24 24" className="w-4 h-4 mr-2" />
59+
icon
7760
)}
78-
{t(transKeys.welcome.login.google)}
61+
{t(transKeys.welcome.login[translationKey])}
7962
</Button>
8063
{isLastSignInMethod && (
8164
<p className="text-teal-500 text-small mt-1">{t(transKeys.welcome.login.lastUsed)}</p>
@@ -84,6 +67,7 @@ export const GoogleLoginButton = ({
8467
);
8568
};
8669

70+
8771
export const DevLoginButton = ({
8872
className,
8973
returnUrl,

apps/web/client/src/app/auth/auth-context.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import { LocalForageKeys } from '@/utils/constants';
44
import { SignInMethod } from '@onlook/models/auth';
5-
import { toast } from '@onlook/ui/sonner';
65
import localforage from 'localforage';
76
import type { ReactNode } from 'react';
87
import { createContext, useContext, useEffect, useState } from 'react';
@@ -43,11 +42,8 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
4342
await localforage.setItem(LAST_SIGN_IN_METHOD_KEY, method);
4443
await login(method);
4544
} catch (error) {
46-
toast.error('Error signing in with password', {
47-
description: error instanceof Error ? error.message : 'Please try again.',
48-
});
49-
console.error('Error signing in with password:', error);
50-
throw new Error('Error signing in with password');
45+
console.error('Error signing in with method:', method, error);
46+
throw error;
5147
} finally {
5248
setSigningInMethod(null);
5349
}

apps/web/client/src/app/login/page.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
import { useGetBackground } from '@/hooks/use-get-background';
44
import { transKeys } from '@/i18n/keys';
55
import { LocalForageKeys, Routes } from '@/utils/constants';
6+
import { SignInMethod } from '@onlook/models/auth';
67
import { Icons } from '@onlook/ui/icons';
78
import { useTranslations } from 'next-intl';
89
import Image from 'next/image';
910
import Link from 'next/link';
1011
import { useSearchParams } from 'next/navigation';
11-
import { DevLoginButton, GithubLoginButton, GoogleLoginButton } from '../_components/login-button';
12+
import { DevLoginButton, LoginButton } from '../_components/login-button';
1213

1314
export default function LoginPage() {
1415
const isDev = process.env.NODE_ENV === 'development';
@@ -34,8 +35,20 @@ export default function LoginPage() {
3435
</p>
3536
</div>
3637
<div className="space-y-2 md:space-y-0 md:space-x-2 flex flex-col md:flex-row">
37-
<GithubLoginButton returnUrl={returnUrl} />
38-
<GoogleLoginButton returnUrl={returnUrl} />
38+
<LoginButton
39+
returnUrl={returnUrl}
40+
method={SignInMethod.GITHUB}
41+
icon={<Icons.GitHubLogo className="w-4 h-4 mr-2" />}
42+
translationKey="github"
43+
providerName="GitHub"
44+
/>
45+
<LoginButton
46+
returnUrl={returnUrl}
47+
method={SignInMethod.GOOGLE}
48+
icon={<Icons.GoogleLogo viewBox="0 0 24 24" className="w-4 h-4 mr-2" />}
49+
translationKey="google"
50+
providerName="Google"
51+
/>
3952
</div>
4053
{isDev && <DevLoginButton returnUrl={returnUrl} />}
4154
<p className="text-small text-foreground-onlook">

apps/web/client/src/app/project/[id]/_components/canvas/frame/gesture.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { cn } from '@onlook/ui/utils';
88
import throttle from 'lodash/throttle';
99
import { observer } from 'mobx-react-lite';
1010
import { useCallback, useEffect, useMemo } from 'react';
11-
import { RightClickMenu } from './right-click';
11+
import { RightClickMenu } from '../../right-click-menu';
1212

1313
export const GestureScreen = observer(({ frame, isResizing }: { frame: Frame, isResizing: boolean }) => {
1414
const editorEngine = useEditorEngine();

apps/web/client/src/app/project/[id]/_components/canvas/frame/index.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import { colors } from '@onlook/ui/tokens';
66
import { debounce } from 'lodash';
77
import { observer } from 'mobx-react-lite';
88
import { useEffect, useRef, useState } from 'react';
9+
import { RightClickMenu } from '../../right-click-menu';
910
import { GestureScreen } from './gesture';
1011
import { ResizeHandles } from './resize-handles';
11-
import { RightClickMenu } from './right-click';
1212
import { TopBar } from './top-bar';
1313
import { FrameComponent, type IFrameView } from './view';
1414

@@ -20,11 +20,12 @@ export const FrameView = observer(({ frame, isInDragSelection = false }: { frame
2020
const [hasTimedOut, setHasTimedOut] = useState(false);
2121
const isSelected = editorEngine.frames.isSelected(frame.id);
2222

23-
// Check if sandbox is connecting for this frame's branch
2423
const branchData = editorEngine.branches.getBranchDataById(frame.branchId);
25-
const isConnecting = branchData?.sandbox?.session?.isConnecting || branchData?.sandbox?.isIndexing || false;
24+
const isConnecting = branchData?.sandbox?.session?.isConnecting ?? false;
25+
26+
const preloadScriptReady = branchData?.sandbox?.preloadScriptInjected ?? false;
27+
const isFrameReady = preloadScriptReady && !(isConnecting && !hasTimedOut);
2628

27-
// Timeout for connection attempts
2829
useEffect(() => {
2930
if (!isConnecting) {
3031
setHasTimedOut(false);
@@ -33,7 +34,7 @@ export const FrameView = observer(({ frame, isInDragSelection = false }: { frame
3334

3435
const timeoutId = setTimeout(() => {
3536
const currentBranchData = editorEngine.branches.getBranchDataById(frame.branchId);
36-
const stillConnecting = currentBranchData?.sandbox?.session?.isConnecting || currentBranchData?.sandbox?.isIndexing || false;
37+
const stillConnecting = currentBranchData?.sandbox?.session?.isConnecting ?? false;
3738

3839
if (stillConnecting) {
3940
setHasTimedOut(true);
@@ -70,12 +71,12 @@ export const FrameView = observer(({ frame, isInDragSelection = false }: { frame
7071
<FrameComponent key={reloadKey} frame={frame} reloadIframe={reloadIframe} isInDragSelection={isInDragSelection} ref={iFrameRef} />
7172
<GestureScreen frame={frame} isResizing={isResizing} />
7273

73-
{isConnecting && !hasTimedOut && (
74+
{!isFrameReady && (
7475
<div
7576
className="absolute inset-0 bg-background/80 backdrop-blur-sm flex items-center justify-center z-50 rounded-md"
7677
style={{ width: frame.dimension.width, height: frame.dimension.height }}
7778
>
78-
<div className="flex flex-col items-center gap-3 text-foreground" style={{ transform: `scale(${1 / editorEngine.canvas.scale})` }}>
79+
<div className="flex items-center gap-3 text-foreground" style={{ transform: `scale(${1 / editorEngine.canvas.scale})` }}>
7980
<Icons.LoadingSpinner className="animate-spin h-8 w-8" />
8081
</div>
8182
</div>

0 commit comments

Comments
 (0)