Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
150 commits
Select commit Hold shift + click to select a range
9667f2b
move reconnct
Kitenite Sep 26, 2025
5bdf732
wip: integrate new fs system
Kitenite Sep 26, 2025
a1e9a3f
save sandbox setup
Kitenite Sep 26, 2025
ad812f8
saving
Kitenite Sep 26, 2025
c15304a
refactor code tab
Kitenite Sep 26, 2025
c9cc777
restore file tree functionality
Kitenite Sep 26, 2025
7967d5f
file tree update
Kitenite Sep 26, 2025
5cd47ae
selecting file
Kitenite Sep 26, 2025
e6669c8
better hover
Kitenite Sep 26, 2025
fdd56dc
refactor
Kitenite Sep 26, 2025
8287347
more refactor and cleanup
Kitenite Sep 26, 2025
71f4683
update viewing
Kitenite Sep 26, 2025
22c3783
working file tree
Kitenite Sep 26, 2025
c44beaf
flatten file tree
Kitenite Sep 26, 2025
282cc83
remove tree node
Kitenite Sep 26, 2025
25726e6
fix icons
Kitenite Sep 26, 2025
07248c3
use local fs
Kitenite Sep 26, 2025
b569aeb
clean up file node
Kitenite Sep 26, 2025
796a5bc
more cleanup
Kitenite Sep 26, 2025
a89b5e5
remove load modal
Kitenite Sep 26, 2025
bc6da3c
save
Kitenite Sep 26, 2025
2dcc8ee
working file writing
Kitenite Sep 26, 2025
aae7228
discard changes
Kitenite Sep 26, 2025
9f9d70c
use file paths
Kitenite Sep 26, 2025
79d0b79
better pathing
Kitenite Sep 26, 2025
1669910
clean rerender
Kitenite Sep 26, 2025
11b50d2
merge main
Kitenite Sep 27, 2025
3a4eb51
fix: remove duplicate condition check in handleToolCall (#2929)
anand-106 Sep 27, 2025
a8364cc
merge main
Kitenite Sep 27, 2025
e45e941
remove dead code
Kitenite Sep 27, 2025
898d104
remove more dead code
Kitenite Sep 27, 2025
2c9c76e
clean up ide manager
Kitenite Sep 28, 2025
bd882ac
reduce ide manager to nothing
Kitenite Sep 28, 2025
a869bb9
slightly unfuck the image tab
Kitenite Sep 28, 2025
3794efb
use fs
Kitenite Sep 28, 2025
a11e57d
restore styling
Kitenite Sep 28, 2025
d519aba
simplify image tab
Kitenite Sep 28, 2025
e2509c8
simplified image
Kitenite Sep 28, 2025
c9e2294
add image viewer
Kitenite Sep 28, 2025
2ce9005
handle svg
Kitenite Sep 28, 2025
87ef4a9
handle filtering
Kitenite Sep 28, 2025
30c9fdb
refactor
Kitenite Sep 29, 2025
f759b3e
refactor
Kitenite Sep 29, 2025
7cdb8f7
add kinda dragging
Kitenite Sep 29, 2025
8f8503e
working image transfer
Kitenite Sep 29, 2025
f39e645
file url instead
Kitenite Sep 29, 2025
eb3b63d
animate sidebar
Kitenite Sep 29, 2025
b5e2276
styling
Kitenite Sep 29, 2025
4edd7b6
add ide delete rename
Kitenite Sep 29, 2025
2791932
working rename and delete
Kitenite Sep 29, 2025
b98f10d
working not rerender
Kitenite Sep 29, 2025
acfc83c
input focus
Kitenite Sep 29, 2025
adbc0d8
small ui fix
Kitenite Sep 29, 2025
7bc2cc0
update
Kitenite Sep 29, 2025
3269ac3
code controls
Kitenite Sep 29, 2025
245fd5e
update controls
Kitenite Sep 29, 2025
7a965ab
update controls
Kitenite Sep 29, 2025
676a005
working create and upload
Kitenite Sep 29, 2025
3719653
warn before delete
Kitenite Sep 29, 2025
114e496
file icon
Kitenite Sep 29, 2025
bcd9197
update tools
Kitenite Sep 30, 2025
4c610d8
fixing fonts
Kitenite Sep 30, 2025
94033f2
read file tool
Kitenite Sep 30, 2025
f2cd7da
fix typechecks
Kitenite Sep 30, 2025
0d770c7
Merge branch 'main' into feat/integrate-sync-eng
Kitenite Sep 30, 2025
9f5016e
mock root layout path
Kitenite Sep 30, 2025
10a7c79
working pages
Kitenite Sep 30, 2025
17e0a1f
using layouts
Kitenite Sep 30, 2025
b4f0fc9
scan pages
Kitenite Sep 30, 2025
12a4720
working pages tab
Kitenite Sep 30, 2025
5661778
working fonts setup
Kitenite Sep 30, 2025
ed62540
working fonts
Kitenite Sep 30, 2025
14cebae
cleaning up
Kitenite Sep 30, 2025
10d5b76
Push plan for CodeEditorApi
saddlepaddle Sep 29, 2025
3816d2f
WIP
saddlepaddle Sep 30, 2025
0d50998
WIP
saddlepaddle Oct 1, 2025
c4ad1b4
WIP - forking working
saddlepaddle Oct 1, 2025
52c0f85
WIP - kinda working
saddlepaddle Oct 1, 2025
ae9996a
WIP - trying to fix sidepanel
saddlepaddle Oct 1, 2025
79e4ff0
WIP - at least it works
saddlepaddle Oct 1, 2025
ad4efa9
WIP - need to find why new project flow is broken
saddlepaddle Oct 1, 2025
c5aee59
WIP
saddlepaddle Oct 1, 2025
5b6d2b6
WIP
saddlepaddle Oct 1, 2025
1755fce
Few more issues
saddlepaddle Oct 1, 2025
97f5b22
Ensure injection only ran once
saddlepaddle Oct 1, 2025
ee0690a
Kinda working - saw some sandboxes not load but clicking is now immed…
saddlepaddle Oct 1, 2025
31bad4b
Updated a bunch to include branchId for operations
saddlepaddle Oct 1, 2025
ebfff2c
Handle paths correctly in fs, start fixing downstream consumers to fi…
saddlepaddle Oct 1, 2025
46c5211
Ensure code highlighting still works
saddlepaddle Oct 1, 2025
a435fb0
Fix fonts by ensuring we write first to local state
saddlepaddle Oct 1, 2025
656d134
Ensure file names are sanitized when users upload files
saddlepaddle Oct 2, 2025
905b611
Found issue - need to use code-editor-api not fs
saddlepaddle Oct 2, 2025
dfce627
Replace usages of fs
saddlepaddle Oct 2, 2025
7a5620b
WIP - fixes for the missing page.tsx + not being able to click on ele…
saddlepaddle Oct 2, 2025
7bf1fbf
merge main
Kitenite Oct 3, 2025
8716eb4
highlight styling
Kitenite Oct 3, 2025
61601a6
highlight on correct file
Kitenite Oct 3, 2025
cc30779
fix frame loading
Kitenite Oct 3, 2025
8acb3fa
Merge branch 'main' into feat/integrate-sync-eng
Kitenite Oct 3, 2025
b7e7426
refactor preload script
Kitenite Oct 3, 2025
7beb5ad
font scan
Kitenite Oct 3, 2025
fb270ac
handle code controls
Kitenite Oct 3, 2025
ba406a3
use correct file system
Kitenite Oct 3, 2025
0d91716
use router config and better init
Kitenite Oct 3, 2025
4105a34
refactor create branch
Kitenite Oct 3, 2025
505a6c6
only use code fs
Kitenite Oct 3, 2025
52b4c77
clean up
Kitenite Oct 4, 2025
03879ef
fix dnd backend crash react-arbonist
Kitenite Oct 4, 2025
13eb3af
save file
Kitenite Oct 4, 2025
b04152e
handle reconnect
Kitenite Oct 4, 2025
b0ba790
handle reconnect
Kitenite Oct 4, 2025
b46bba8
clean up
Kitenite Oct 4, 2025
c8ddcb7
update tests
Kitenite Oct 4, 2025
680c59c
update ui
Kitenite Oct 4, 2025
b83e7e6
fix tests
Kitenite Oct 4, 2025
d92dae5
fix tests
Kitenite Oct 4, 2025
e520ad8
remove tests
Kitenite Oct 4, 2025
50f1e55
remove test routes
Kitenite Oct 4, 2025
abb4e4c
clean up
Kitenite Oct 4, 2025
b839148
clean up
Kitenite Oct 4, 2025
1323252
clamp highlight
Kitenite Oct 4, 2025
1726923
remove unused functions
Kitenite Oct 4, 2025
dd32ecd
update file icon extension
Kitenite Oct 4, 2025
9c8c941
clean up
Kitenite Oct 4, 2025
120bb4e
copy dir
Kitenite Oct 5, 2025
cb6e5a6
copy dir
Kitenite Oct 5, 2025
bf0da9e
bulk write files
Kitenite Oct 5, 2025
4efd3dc
fix preload script location
Kitenite Oct 5, 2025
91debaa
fix tests
Kitenite Oct 5, 2025
59d6053
fix type
Kitenite Oct 5, 2025
cc89adc
fix type
Kitenite Oct 5, 2025
3053de1
keep index in memory
Kitenite Oct 5, 2025
13e6d0a
working component detection
Kitenite Oct 5, 2025
c9b1c57
needs fixing idemanager
Kitenite Oct 5, 2025
098e25d
needs fixing idemanager
Kitenite Oct 5, 2025
5d106d8
allow overriding
Kitenite Oct 5, 2025
1aa23e8
allow overrides
Kitenite Oct 5, 2025
032bb8d
update
Kitenite Oct 5, 2025
336dcc7
document the ast algorithm
Kitenite Oct 5, 2025
a4fc99f
update void
Kitenite Oct 5, 2025
f67c75b
update use-file
Kitenite Oct 5, 2025
e38d38f
clean up
Kitenite Oct 5, 2025
d1034cb
rebuild index
Kitenite Oct 5, 2025
c220663
get preload script
Kitenite Oct 5, 2025
355299f
add snappiness
Kitenite Oct 5, 2025
b11b001
snapshot commit preload script
Kitenite Oct 5, 2025
29a3ba8
deprecate main cdn
Kitenite Oct 5, 2025
c2a0f36
update template for new preload url
Kitenite Oct 6, 2025
5012335
fix test and login button
Kitenite Oct 6, 2025
6148c01
DRY
Kitenite Oct 6, 2025
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
42 changes: 21 additions & 21 deletions apps/web/client/public/onlook-preload-script.js

Large diffs are not rendered by default.

20 changes: 17 additions & 3 deletions apps/web/client/src/app/_components/auth-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import {
import { Button } from '@onlook/ui/button';
import { useTranslations } from 'next-intl';
import { useAuthContext } from '../auth/auth-context';
import { GithubLoginButton, GoogleLoginButton } from './login-button';
import { LoginButton } from './login-button';
import { SignInMethod } from '@onlook/models/auth';
import { Icons } from '@onlook/ui/icons';

export function AuthModal() {
const { setIsAuthModalOpen, isAuthModalOpen } = useAuthContext();
Expand All @@ -28,8 +30,20 @@ export function AuthModal() {
</AlertDialogDescription>
</AlertDialogHeader>
<div className="space-y-2 flex flex-col">
<GithubLoginButton className="!bg-black" />
<GoogleLoginButton className="!bg-black" />
<LoginButton
className="!bg-black"
method={SignInMethod.GITHUB}
icon={<Icons.GitHubLogo className="w-4 h-4 mr-2" />}
translationKey="github"
providerName="GitHub"
/>
<LoginButton
className="!bg-black"
method={SignInMethod.GOOGLE}
icon={<Icons.GoogleLogo viewBox="0 0 24 24" className="w-4 h-4 mr-2" />}
translationKey="google"
providerName="Google"
/>
</div>
<AlertDialogFooter className="flex !justify-center w-full">
<Button variant={'ghost'} onClick={() => setIsAuthModalOpen(false)}>
Expand Down
76 changes: 30 additions & 46 deletions apps/web/client/src/app/_components/login-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,41 @@ import { Button } from '@onlook/ui/button';
import { Icons } from '@onlook/ui/icons';
import { cn } from '@onlook/ui/utils';
import { useTranslations } from 'next-intl';
import { toast } from 'sonner';
import { useAuthContext } from '../auth/auth-context';

export const GithubLoginButton = ({
className,
returnUrl,
}: {
interface LoginButtonProps {
className?: string;
returnUrl?: string | null;
}) => {
const t = useTranslations();
const { lastSignInMethod, handleLogin, signingInMethod } = useAuthContext();
const isLastSignInMethod = lastSignInMethod === SignInMethod.GITHUB;
const isSigningIn = signingInMethod === SignInMethod.GITHUB;

return (
<div className={cn('flex flex-col items-center w-full', className)}>
<Button
variant="outline"
className={cn(
'w-full items-center justify-center text-active text-small',
isLastSignInMethod
? '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'
: 'bg-background-onlook',
)}
onClick={() => handleLogin(SignInMethod.GITHUB, returnUrl ?? null)}
disabled={!!signingInMethod}
>
{isSigningIn ? (
<Icons.LoadingSpinner className="w-4 h-4 mr-2 animate-spin" />
) : (
<Icons.GitHubLogo className="w-4 h-4 mr-2" />
)}
{t(transKeys.welcome.login.github)}
</Button>
{isLastSignInMethod && (
<p className="text-teal-500 text-small mt-1">{t(transKeys.welcome.login.lastUsed)}</p>
)}
</div>
);
};
method: SignInMethod.GITHUB | SignInMethod.GOOGLE;
icon: React.ReactNode;
translationKey: keyof typeof transKeys.welcome.login;
providerName: string;
}

export const GoogleLoginButton = ({
export const LoginButton = ({
className,
returnUrl,
}: {
className?: string;
returnUrl?: string | null;
}) => {
method,
icon,
translationKey,
providerName,
}: LoginButtonProps) => {
const t = useTranslations();
const { lastSignInMethod, handleLogin, signingInMethod } = useAuthContext();
const isLastSignInMethod = lastSignInMethod === SignInMethod.GOOGLE;
const isSigningIn = signingInMethod === SignInMethod.GOOGLE;
const isLastSignInMethod = lastSignInMethod === method;
const isSigningIn = signingInMethod === method;

const handleLoginClick = async () => {
try {
await handleLogin(method, returnUrl ?? null);
} catch (error) {
console.error(`Error signing in with ${providerName}:`, error);
toast.error(`Error signing in with ${providerName}`, {
description: error instanceof Error ? error.message : 'Please try again.',
});
Comment on lines +37 to +39
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Localize the toast copy.

The toast title/description are hardcoded English strings. Per our app guidelines, user-facing text must come from next-intl. Please move these messages into the translations bundle (e.g., transKeys.welcome.login.error) and fetch them via t(...), passing providerName as an interpolation if needed. This keeps the UI localizable.

As per coding guidelines

}
};

return (
<div className={cn('flex flex-col items-center w-full', className)}>
Expand All @@ -67,15 +50,15 @@ export const GoogleLoginButton = ({
? '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'
: 'bg-background-onlook',
)}
onClick={() => handleLogin(SignInMethod.GOOGLE, returnUrl ?? null)}
onClick={handleLoginClick}
disabled={!!signingInMethod}
>
{isSigningIn ? (
<Icons.LoadingSpinner className="w-4 h-4 mr-2 animate-spin" />
) : (
<Icons.GoogleLogo viewBox="0 0 24 24" className="w-4 h-4 mr-2" />
icon
)}
{t(transKeys.welcome.login.google)}
{t(transKeys.welcome.login[translationKey])}
</Button>
{isLastSignInMethod && (
<p className="text-teal-500 text-small mt-1">{t(transKeys.welcome.login.lastUsed)}</p>
Expand All @@ -84,6 +67,7 @@ export const GoogleLoginButton = ({
);
};


export const DevLoginButton = ({
className,
returnUrl,
Expand Down
8 changes: 2 additions & 6 deletions apps/web/client/src/app/auth/auth-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { LocalForageKeys } from '@/utils/constants';
import { SignInMethod } from '@onlook/models/auth';
import { toast } from '@onlook/ui/sonner';
import localforage from 'localforage';
import type { ReactNode } from 'react';
import { createContext, useContext, useEffect, useState } from 'react';
Expand Down Expand Up @@ -43,11 +42,8 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
await localforage.setItem(LAST_SIGN_IN_METHOD_KEY, method);
await login(method);
} catch (error) {
toast.error('Error signing in with password', {
description: error instanceof Error ? error.message : 'Please try again.',
});
console.error('Error signing in with password:', error);
throw new Error('Error signing in with password');
console.error('Error signing in with method:', method, error);
throw error;
} finally {
setSigningInMethod(null);
}
Expand Down
19 changes: 16 additions & 3 deletions apps/web/client/src/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import { useGetBackground } from '@/hooks/use-get-background';
import { transKeys } from '@/i18n/keys';
import { LocalForageKeys, Routes } from '@/utils/constants';
import { SignInMethod } from '@onlook/models/auth';
import { Icons } from '@onlook/ui/icons';
import { useTranslations } from 'next-intl';
import Image from 'next/image';
import Link from 'next/link';
import { useSearchParams } from 'next/navigation';
import { DevLoginButton, GithubLoginButton, GoogleLoginButton } from '../_components/login-button';
import { DevLoginButton, LoginButton } from '../_components/login-button';

export default function LoginPage() {
const isDev = process.env.NODE_ENV === 'development';
Expand All @@ -34,8 +35,20 @@ export default function LoginPage() {
</p>
</div>
<div className="space-y-2 md:space-y-0 md:space-x-2 flex flex-col md:flex-row">
<GithubLoginButton returnUrl={returnUrl} />
<GoogleLoginButton returnUrl={returnUrl} />
<LoginButton
returnUrl={returnUrl}
method={SignInMethod.GITHUB}
icon={<Icons.GitHubLogo className="w-4 h-4 mr-2" />}
translationKey="github"
providerName="GitHub"
/>
<LoginButton
returnUrl={returnUrl}
method={SignInMethod.GOOGLE}
icon={<Icons.GoogleLogo viewBox="0 0 24 24" className="w-4 h-4 mr-2" />}
translationKey="google"
providerName="Google"
/>
</div>
{isDev && <DevLoginButton returnUrl={returnUrl} />}
<p className="text-small text-foreground-onlook">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { cn } from '@onlook/ui/utils';
import throttle from 'lodash/throttle';
import { observer } from 'mobx-react-lite';
import { useCallback, useEffect, useMemo } from 'react';
import { RightClickMenu } from './right-click';
import { RightClickMenu } from '../../right-click-menu';

export const GestureScreen = observer(({ frame, isResizing }: { frame: Frame, isResizing: boolean }) => {
const editorEngine = useEditorEngine();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { colors } from '@onlook/ui/tokens';
import { debounce } from 'lodash';
import { observer } from 'mobx-react-lite';
import { useEffect, useRef, useState } from 'react';
import { RightClickMenu } from '../../right-click-menu';
import { GestureScreen } from './gesture';
import { ResizeHandles } from './resize-handles';
import { RightClickMenu } from './right-click';
import { TopBar } from './top-bar';
import { FrameComponent, type IFrameView } from './view';

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

// Check if sandbox is connecting for this frame's branch
const branchData = editorEngine.branches.getBranchDataById(frame.branchId);
const isConnecting = branchData?.sandbox?.session?.isConnecting || branchData?.sandbox?.isIndexing || false;
const isConnecting = branchData?.sandbox?.session?.isConnecting ?? false;

const preloadScriptReady = branchData?.sandbox?.preloadScriptInjected ?? false;
const isFrameReady = preloadScriptReady && !(isConnecting && !hasTimedOut);

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

const timeoutId = setTimeout(() => {
const currentBranchData = editorEngine.branches.getBranchDataById(frame.branchId);
const stillConnecting = currentBranchData?.sandbox?.session?.isConnecting || currentBranchData?.sandbox?.isIndexing || false;
const stillConnecting = currentBranchData?.sandbox?.session?.isConnecting ?? false;

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

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