Skip to content

Commit

Permalink
[feat] add link sharing
Browse files Browse the repository at this point in the history
  • Loading branch information
LeahHirst committed Nov 12, 2024
1 parent c24395b commit a793f65
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 7 deletions.
1 change: 1 addition & 0 deletions apps/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@types/react": "^18.3.7",
"@types/react-dom": "^18.3.0",
"astro": "^4.16.10",
"lz-string": "^1.5.0",
"monaco-editor": "^0.51.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
8 changes: 7 additions & 1 deletion apps/site/src/components/playground/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import type { editor } from 'monaco-editor';
import { Typechecker } from '@repo/typecheck/index';
import { getProgram, serializeProgram } from './utils/program';
import { getSharedCode } from './utils/share';

const Container = styled.div`
display: flex;
Expand Down Expand Up @@ -45,6 +46,7 @@ export default function Editor() {
const monaco = useMonaco();
const [language, setLanguage] = useState('Nospace');
const [[lnNumber, colNumber], setCursorPos] = useState([1, 1]);
const { code } = useMemo(() => getSharedCode(), []);

useEffect(() => {
if (!monaco) {
Expand Down Expand Up @@ -205,7 +207,11 @@ export default function Editor() {
</Dropdown>
</Flex>
</Toolbar>
<MonacoEditor defaultValue="" theme="vs-dark" options={monacoOptions} />
<MonacoEditor
defaultValue={code}
theme="vs-dark"
options={monacoOptions}
/>
<Toolbar>
<div />
Ln {lnNumber}, Col {colNumber}
Expand Down
34 changes: 31 additions & 3 deletions apps/site/src/components/playground/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useCallback, useRef, useState } from 'react';
import styled from '@emotion/styled';
import Dropdown, { DropdownAction } from './Dropdown';
import Button from './Button';
Expand Down Expand Up @@ -31,8 +31,35 @@ const RightActions = styled.div`
padding-right: 16px;
`;

const ShareToast = styled.div`
position: absolute;
left: 50%;
top: 50%;
background-color: rgba(0, 0, 0, 0.8);
color: white;
border-radius: 35px;
padding: 20px 40px;
margin-left: -142px;
margin-top: -31px;
font-size: 1.2rem;
z-index: 100000;
`;

export default function Header() {
const { run } = usePlaygroundContext();
const { run, share } = usePlaygroundContext();
const [showToast, setShowToast] = useState(false);
const timeoutRef = useRef<NodeJS.Timeout>();

const shareCode = useCallback(() => {
setShowToast(true);
timeoutRef.current = setTimeout(() => {
setShowToast(false);
}, 2000);
share();
return () => {
clearTimeout(timeoutRef.current);
};
}, [share]);

return (
<Base>
Expand All @@ -45,8 +72,9 @@ export default function Header() {
</Flex>
<RightActions>
<Button onClick={run}>Run</Button>
<Button>Share</Button>
<Button onClick={shareCode}>Share</Button>
</RightActions>
{showToast && <ShareToast>URL copied to clipboard</ShareToast>}
</Base>
);
}
20 changes: 18 additions & 2 deletions apps/site/src/components/playground/PlaygroundContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { getProgram } from './utils/program';
import { Typechecker } from '@repo/typecheck/index';
import { Program } from '@repo/nose/index';
import { generateShareHashParameter, getSharedCode } from './utils/share';

export type CompilerMessage = {
message: string;
Expand All @@ -22,6 +23,7 @@ export type PlaygroundContextType = {
programOutput: string;
compilerOutput: CompilerMessage[];
run: () => void;
share: () => void;
};

const PlaygroundContext = createContext<PlaygroundContextType>({
Expand All @@ -30,6 +32,7 @@ const PlaygroundContext = createContext<PlaygroundContextType>({
programOutput: '',
compilerOutput: [],
run: () => {},
share: () => {},
});

export const usePlaygroundContext = () => useContext(PlaygroundContext);
Expand All @@ -39,7 +42,8 @@ export const PlaygroundContextProvider = ({
}: {
children: ReactNode;
}) => {
const [programInput, setProgramInput] = useState('');
const { input } = useMemo(() => getSharedCode(), []);
const [programInput, setProgramInput] = useState(input);
const [programOutput, setProgramOutput] = useState('');
const [compilerOutput, setCompilerOutput] = useState<CompilerMessage[]>([]);

Expand Down Expand Up @@ -91,15 +95,27 @@ export const PlaygroundContextProvider = ({
setProgramOutput(output);
}, [monaco]);

const share = useCallback(() => {
if (!monaco) {
return;
}

const editor = monaco.editor.getEditors()[0];

const hash = generateShareHashParameter(editor.getValue(), programInput);
location.hash = hash;
}, [monaco, programInput]);

const value = useMemo(
() => ({
programInput,
setProgramInput,
programOutput,
compilerOutput,
run,
share,
}),
[programInput, programOutput, compilerOutput, run],
[programInput, programOutput, compilerOutput, run, share],
);

return (
Expand Down
27 changes: 27 additions & 0 deletions apps/site/src/components/playground/utils/share.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import lzstring from 'lz-string';

export function generateShareHashParameter(code: string, input?: string) {
return `#code/${[code, input]
.filter(Boolean)
.map((x) => lzstring.compressToEncodedURIComponent(x!))
.join('/')}`;
}

export function getSharedCode() {
if (typeof window !== 'undefined' && location.hash.startsWith('#code')) {
const [code, input] = location.hash
.replace('#code/', '')
.trim()
.split('/')
.map((x) => lzstring.decompressFromEncodedURIComponent(x));
return {
code,
input,
};
}

return {
code: '',
input: '',
};
}
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6557,7 +6557,7 @@ lru-cache@^7.14.1:

lz-string@^1.5.0:
version "1.5.0"
resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==

magic-string@^0.27.0:
Expand Down

0 comments on commit a793f65

Please sign in to comment.