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
125 changes: 0 additions & 125 deletions apps/website/src/app/(editor)/playgrounds/[playground]/content.tsx

This file was deleted.

13 changes: 13 additions & 0 deletions apps/website/src/app/(editor)/playgrounds/[playground]/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { EditorWrapperSkeleton } from './wrapper/skeleton';

export default function EditorLoadingPage() {
return (
<>
<style>{`
body{overflow-y:hidden!important;}
body[data-scroll-locked]{margin-right:0px!important;}
`}</style>
<EditorWrapperSkeleton className="m-1.5 mt-0" />
</>
);
}
48 changes: 28 additions & 20 deletions apps/website/src/app/(editor)/playgrounds/[playground]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,56 @@
import { fetchRuntimes, getRuntime } from '@evaluate/engine/runtimes';
import { notFound } from 'next/navigation';
import { generateBaseMetadata } from '~/app/metadata';
import { Editor } from '~/components/editor';
import { Explorer } from '~/components/explorer';
import { ExplorerProvider } from '~/components/explorer/use';
import { Terminal } from '~/components/terminal';
import { TerminalProvider } from '~/components/terminal/use';
import type { PageProps } from '~/types';
import EditorContent from './content';
import { EditorWrapper } from './wrapper';

export async function generateStaticParams() {
const runtimes = await fetchRuntimes();
return runtimes
.reduce<string[]>((ids, runtime) => {
for (const version of runtime.versions)
ids.push(`${runtime.id}@${version}`);
ids.push(runtime.id);
return ids;
}, [])
.map((id) => ({ runtime: id }));
return runtimes.map((r) => ({ playground: r.id }));
}

export async function generateMetadata(p: PageProps<['playground']>) {
const id = decodeURIComponent(p.params.playground);
const runtime = await getRuntime(id);
export async function generateMetadata({
params: { playground },
}: PageProps<['playground']>) {
const runtime = await getRuntime(decodeURIComponent(playground));
if (!runtime) notFound();

return generateBaseMetadata(`/playground/${id}`, {
return generateBaseMetadata(`/playground/${playground}`, {
title: `${runtime.name} Playground on Evaluate`,
description: `Run code in ${runtime.name} and other programming languages effortlessly with Evaluate. Input your code, optional arguments, and get instant results. Debug, optimize, and elevate your coding experience with our versatile evaluation tools.`,
keywords: [runtime.name, ...runtime.aliases, ...runtime.tags] //
.map((k) => k.toLowerCase()),
});
}

export default async function PlaygroundEditorPage(
p: PageProps<['playground']>,
) {
const id = decodeURIComponent(p.params.playground);
const runtime = await getRuntime(id);
export default async function EditorPage({
params: { playground },
}: PageProps<['playground']>) {
const runtime = await getRuntime(decodeURIComponent(playground));
if (!runtime) notFound();

return (
<>
<style>{`
body{overflow-y:hidden!important;}
body[data-scroll-locked]{margin-right: 0px !important;}
body[data-scroll-locked]{margin-right:0px!important;}
`}</style>
<EditorContent runtime={{ ...runtime }} />
<div className="m-1.5 mt-0 h-[calc(-3.5rem_+_100vh_-_12px)] lg:h-[calc(-3.5rem_+_100vh_-_6px)]">
<ExplorerProvider runtime={runtime}>
<TerminalProvider>
<EditorWrapper>
<Explorer />
<Editor runtime={runtime} />
<Terminal runtime={runtime} />
</EditorWrapper>
</TerminalProvider>
</ExplorerProvider>
</div>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from '@evaluate/components/resizable';
import { Children } from 'react';

export function DesktopWrapper({ children }: React.PropsWithChildren) {
const [explorer, editor, terminal] = Children.toArray(children);

return (
<ResizablePanelGroup direction="horizontal">
<ResizablePanel
defaultSize={15}
minSize={10}
collapsible={false}
className="m-1.5 rounded-xl border-2 bg-card"
>
{explorer}
</ResizablePanel>

<ResizableHandle className="bg-transparent" />

<ResizablePanel
defaultSize={55}
minSize={35}
collapsible={false}
className="m-1.5 rounded-xl border-2 bg-card"
>
{editor}
</ResizablePanel>

<ResizableHandle className="bg-transparent" />

<ResizablePanel
defaultSize={30}
minSize={10}
collapsible={false}
className="m-1.5 rounded-xl border-2 bg-card"
>
{terminal}
</ResizablePanel>
</ResizablePanelGroup>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use client';

import { useMediaQuery } from '@evaluate/hooks/media-query';
import { Children } from 'react';
import { DesktopWrapper } from './desktop';
import { MobileWrapper } from './mobile';
import { EditorWrapperSkeleton } from './skeleton';

export function EditorWrapper({ children }: React.PropsWithChildren) {
if (Children.count(children) !== 3) throw new Error('Invalid children');
const isDesktop = useMediaQuery('lg');

if (isDesktop === undefined) return <EditorWrapperSkeleton />;
if (isDesktop) return <DesktopWrapper>{children}</DesktopWrapper>;
return <MobileWrapper>{children}</MobileWrapper>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use client';

import { Sheet, SheetContent } from '@evaluate/components/sheet';
import { useEventListener } from '@evaluate/hooks/event-listener';
import { Children, useState } from 'react';

export function MobileWrapper({ children }: React.PropsWithChildren) {
const [explorer, editor, terminal] = Children.toArray(children);

const [explorerOpen, setExplorerOpen] = useState(false);
useEventListener('mobile-explorer-open-change' as never, setExplorerOpen);
const [terminalOpen, setTerminalOpen] = useState(false);
useEventListener('mobile-terminal-open-change' as never, setTerminalOpen);

return (
<>
<Sheet open={explorerOpen} onOpenChange={setExplorerOpen}>
<SheetContent
side="right"
className="border-l-0 bg-transparent"
onClick={() => setExplorerOpen(false)}
>
<div
onClick={(e) => e.stopPropagation()}
onKeyUp={(e) => e.stopPropagation()}
className="h-full rounded-xl border-2 bg-card"
>
{explorer}
</div>
</SheetContent>
</Sheet>

<div className="m-1.5 h-full rounded-xl border-2 bg-card">{editor}</div>

<Sheet open={terminalOpen} onOpenChange={setTerminalOpen}>
<SheetContent
side="right"
className="border-l-0 bg-transparent"
onClick={() => setExplorerOpen(false)}
>
<div
onClick={(e) => e.stopPropagation()}
onKeyUp={(e) => e.stopPropagation()}
className="h-full rounded-xl border-2 bg-card"
>
{terminal}
</div>
</SheetContent>
</Sheet>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Skeleton } from '@evaluate/components/skeleton';
import { twMerge as cn } from 'tailwind-merge';

export function EditorWrapperSkeleton({ className }: { className?: string }) {
return (
<div
className={cn(
'flex h-[calc(-3.5rem_+_100vh_-_12px)] lg:h-[calc(-3.5rem_+_100vh_-_6px)]',
className,
)}
>
<Skeleton className="m-1.5 hidden w-[15vw] rounded-xl border-2 bg-card lg:block" />
<Skeleton className="m-1.5 w-[55vw] rounded-xl border-2 bg-card" />
<Skeleton className="m-1.5 hidden w-[30vw] rounded-xl border-2 bg-card lg:block" />
</div>
);
}
Loading