forked from movesthatmatter/movex
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(movex-docs movex-demo): ✨ wIP - Making progress with the examples
- Loading branch information
1 parent
e0745c3
commit 61c4146
Showing
11 changed files
with
508 additions
and
208 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,4 +45,6 @@ yalc.lock | |
.next | ||
|
||
# Typescript | ||
tsconfig.tsbuildinfo | ||
tsconfig.tsbuildinfo | ||
|
||
.movex |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
export const x = 1; | ||
|
||
// import React, { useRef, useEffect, useState } from "react"; | ||
// import * as runtime from "react/jsx-runtime"; | ||
// // import { compile, run } from "@mdx-js/mdx"; | ||
// // import { remarkCodeHike } from "@code-hike/mdx"; | ||
// // import { CH } from "@code-hike/mdx/components"; | ||
// import "@code-hike/mdx/styles.css"; | ||
// // import { ErrorBoundary } from "react-error-boundary"; | ||
// // import { toHash } from "./hash"; | ||
|
||
// export function Preview(props) { | ||
// return ( | ||
// <div className={`preview ${props.standalone ? "standalone" : ""}`}> | ||
// {/* <ErrorBoundary */} | ||
// {/* resetKeys={[props.input.mdx, props.input.css, props.input.config]} | ||
// FallbackComponent={ErrorFallback} | ||
// > */} | ||
// <InnerPreview {...props} /> | ||
// {/* </ErrorBoundary> */} | ||
// </div> | ||
// ); | ||
// } | ||
// function ErrorFallback({ error }) { | ||
// return ( | ||
// <div className="preview-error"> | ||
// <h3>Runtime Error:</h3> | ||
// <pre>{String(error)}</pre> | ||
// </div> | ||
// ); | ||
// } | ||
|
||
// async function compileAndRun(input) { | ||
// try { | ||
// const c = await compile(input.mdx, { | ||
// outputFormat: "function-body", | ||
// remarkPlugins: [ | ||
// [ | ||
// // remarkCodeHike, | ||
// { | ||
// ...input.config, | ||
// autoImport: false, | ||
// theme: input.config.theme, | ||
// }, | ||
// ], | ||
// ], | ||
// }); | ||
// const x = await run(String(c), runtime); | ||
// return { content: x.default, error: undefined }; | ||
// } catch (e) { | ||
// return { content: undefined, error: e.message }; | ||
// } | ||
// } | ||
|
||
// let effectId = 0; | ||
|
||
// function useInput(input) { | ||
// const [{ Content, error }, setState] = useState({ | ||
// Content: undefined, | ||
// error: undefined, | ||
// }); | ||
// const [loading, setLoading] = useState(true); | ||
// useEffect(() => { | ||
// const id = effectId; | ||
// // console.log("compiling...", id); | ||
// setLoading(true); | ||
// compileAndRun(input).then(({ content, error }) => { | ||
// // console.log("compiled", id, error); | ||
// if (id !== effectId) { | ||
// // console.log("skipping", id); | ||
// return; | ||
// } | ||
// setState((state) => ({ | ||
// Content: content || state.Content, | ||
// error, | ||
// })); | ||
// setLoading(false); | ||
// }); | ||
// return () => { | ||
// // console.log("cancelling", id); | ||
// effectId++; | ||
// }; | ||
// }, [input.mdx, input.css, input.config]); | ||
|
||
// return { Content, error, loading }; | ||
// } | ||
|
||
// function InnerPreview({ input, standalone, refreshKey }) { | ||
// const { Content, error, loading } = useInput(input); | ||
// // console.log(error); | ||
// return ( | ||
// <> | ||
// <style>{input.css}</style> | ||
// {error ? ( | ||
// <div className="compile-error"> | ||
// <h3>Compliation Error:</h3> | ||
// <pre>{error}</pre> | ||
// </div> | ||
// ) : null} | ||
// {/* {standalone ? ( | ||
// <a href={`/#${toHash(input)}`} className="standalone-link"> | ||
// <PlaygroundIcon /> | ||
// </a> | ||
// ) : ( | ||
// <a href={`/?preview=1#${toHash(input)}`} className="standalone-link"> | ||
// <ExternalIcon /> | ||
// </a> | ||
// )} */} | ||
// <div className={`preview-container ${error ? "with-error" : ""}`}> | ||
// <div style={{ opacity: loading ? 1 : 0 }} className="loading-border" /> | ||
// {Content ? <Content components={{ CH }} key={refreshKey} /> : null} | ||
// </div> | ||
// </> | ||
// ); | ||
// } | ||
|
||
// function ExternalIcon() { | ||
// return ( | ||
// <svg | ||
// className="icon" | ||
// fill="none" | ||
// stroke="currentColor" | ||
// viewBox="0 0 24 24" | ||
// xmlns="http://www.w3.org/2000/svg" | ||
// > | ||
// <title>Open in new window</title> | ||
// <path | ||
// strokeLinecap="round" | ||
// strokeLinejoin="round" | ||
// strokeWidth={2} | ||
// d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" | ||
// /> | ||
// </svg> | ||
// ); | ||
// } | ||
// function PlaygroundIcon() { | ||
// return ( | ||
// <svg | ||
// className="icon" | ||
// fill="none" | ||
// stroke="currentColor" | ||
// viewBox="0 0 24 24" | ||
// xmlns="http://www.w3.org/2000/svg" | ||
// > | ||
// <title>Open playground</title> | ||
// <path | ||
// strokeLinecap="round" | ||
// strokeLinejoin="round" | ||
// strokeWidth={2} | ||
// d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" | ||
// /> | ||
// </svg> | ||
// ); | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import { MovexBoundResourceFromConfig } from 'movex-react'; | ||
import { useCallback, useEffect, useMemo } from 'react'; | ||
import { Rps, movexConfig } from 'movex-examples'; | ||
import { invoke, logsy, toResourceIdentifierStr } from 'movex-core-util'; | ||
|
||
const { selectAvailableLabels, toOppositeLabel } = Rps; | ||
|
||
type Props = { | ||
boundResource: MovexBoundResourceFromConfig< | ||
typeof movexConfig['resources'], | ||
'rps' | ||
>; | ||
userId: string; | ||
buttonClassName?: string; | ||
containerClassName?: string; | ||
}; | ||
|
||
export const RPSUi: React.FC<Props> = ({ boundResource, userId, ...props }) => { | ||
const { state, dispatch, dispatchPrivate } = boundResource; | ||
|
||
const myPlayerLabel = useMemo((): Rps.PlayerLabel | undefined => { | ||
if (state.players.playerA?.id === userId) { | ||
return 'playerA'; | ||
} | ||
|
||
if (state.players.playerB?.id === userId) { | ||
return 'playerB'; | ||
} | ||
|
||
return undefined; | ||
}, [state.players, userId]); | ||
|
||
const oppnentPlayerLabel = useMemo(() => { | ||
return myPlayerLabel ? toOppositeLabel(myPlayerLabel) : undefined; | ||
}, [myPlayerLabel]); | ||
|
||
// Add Player | ||
useEffect(() => { | ||
// TODO: here there is a major issue, as selectAvailableLables works with local state | ||
// but it needs to check on the actual (master) state. How to solve this? | ||
// add an api to be able to read master state seperately? | ||
|
||
// Or in this case change the strategy altogether, and work with master generated values, in which case | ||
// the local optimistic state udate gets turned off by default, so that means it will wait for the real staet to update. | ||
// Kinda like a dispatchAndWait | ||
const availableLabels = selectAvailableLabels(state); | ||
|
||
if ( | ||
state.players.playerA?.id === userId || | ||
state.players.playerB?.id === userId | ||
) { | ||
return; | ||
} | ||
|
||
if (availableLabels.length === 0) { | ||
logsy.warn('Player Slots taken'); | ||
|
||
return; | ||
} | ||
|
||
dispatch({ | ||
type: 'addPlayer', | ||
payload: { | ||
id: userId, | ||
playerLabel: availableLabels[0], | ||
atTimestamp: new Date().getTime(), | ||
}, | ||
}); | ||
}, [userId, state]); | ||
|
||
const submit = useCallback( | ||
(play: Rps.RPS) => { | ||
if (!myPlayerLabel) { | ||
console.warn('Not A Player'); | ||
return; | ||
} | ||
|
||
dispatchPrivate( | ||
{ | ||
type: 'submit', | ||
payload: { | ||
playerLabel: myPlayerLabel, | ||
rps: play, | ||
}, | ||
isPrivate: true, | ||
}, | ||
{ | ||
type: 'setReadySubmission', | ||
payload: { | ||
playerLabel: myPlayerLabel, | ||
}, | ||
} | ||
); | ||
}, | ||
[dispatchPrivate, myPlayerLabel] | ||
); | ||
|
||
const winner = useMemo(() => { | ||
if (!state.winner) { | ||
return undefined; | ||
} | ||
|
||
if (state.winner === '1/2') { | ||
return '1/2'; | ||
} | ||
|
||
const { | ||
submissions: { playerA }, | ||
} = state; | ||
|
||
if (playerA.play === state.winner) { | ||
return state.players.playerA.label; | ||
} | ||
|
||
return state.players.playerB.label; | ||
}, [state.winner]); | ||
|
||
return ( | ||
<div className="w-full"> | ||
{state.winner ? ( | ||
<div> | ||
<h3> | ||
{winner === '1/2' | ||
? 'Draw' | ||
: winner === myPlayerLabel | ||
? 'You Won' | ||
: 'You Lost'} | ||
</h3> | ||
<button | ||
onClick={() => { | ||
dispatch({ | ||
type: 'playAgain', | ||
}); | ||
}} | ||
> | ||
Play Again | ||
</button> | ||
</div> | ||
) : ( | ||
<div className='flex align-stretch'> | ||
{oppnentPlayerLabel && | ||
state.submissions[oppnentPlayerLabel]?.play && ( | ||
<div>Opponent Submitted</div> | ||
)} | ||
<div > | ||
<button className="text-7xl hover:text-8xl" onClick={() => submit('rock')}> | ||
👊 | ||
</button> | ||
</div> | ||
<button className="text-7xl hover:text-8xl" onClick={() => submit('paper')}>✋</button> | ||
<button className="text-7xl hover:text-8xl" onClick={() => submit('scissors')}>✌️</button> | ||
</div> | ||
)} | ||
{/* <br /> */} | ||
{/* <div> | ||
<pre>rid: {toResourceIdentifierStr(boundResource.rid)}</pre> | ||
<pre>{JSON.stringify(state, null, 2)}</pre> | ||
</div> */} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ export function Index() { | |
*/ | ||
return ( | ||
<StyledPage> | ||
yeeeep | ||
<div | ||
style={{ | ||
display: 'flex', | ||
|
Oops, something went wrong.