diff --git a/desktop/plugins/public/rn-tic-tac-toe/index.tsx b/desktop/plugins/public/rn-tic-tac-toe/index.tsx index 98e167c83..cb54a8550 100644 --- a/desktop/plugins/public/rn-tic-tac-toe/index.tsx +++ b/desktop/plugins/public/rn-tic-tac-toe/index.tsx @@ -8,20 +8,17 @@ */ import React from 'react'; -import { - FlipperPlugin, - RoundedSection, - Button, - produce, - CenteredView, - Info, - colors, - styled, - FlexRow, - Text, - brandColors, -} from 'flipper'; +import {Typography, Button, Alert, Space} from 'antd'; import {Draft} from 'immer'; +import { + createState, + PluginClient, + usePlugin, + useValue, + styled, + theme, + Layout, +} from 'flipper-plugin'; type Player = ' ' | 'X' | 'O'; @@ -53,13 +50,12 @@ function initialState(): State { } as const; } -const computeNextState = produce( - (draft: Draft, cell: number, player: 'X' | 'O') => { +const computeNextState = + (cell: number, player: 'X' | 'O') => (draft: Draft) => { draft.cells[cell] = player; draft.turn = player === 'X' ? 'O' : 'X'; draft.winner = computeWinner(draft.cells); - }, -); + }; function computeWinner(c: State['cells']): Player { // check the 2 diagonals @@ -79,110 +75,119 @@ function computeWinner(c: State['cells']): Player { return ' '; } -export default class ReactNativeTicTacToe extends FlipperPlugin< - State, - any, - any -> { - state = initialState(); +type Events = { + XMove: {move: number}; + GetState: never; +}; - componentDidMount() { - this.client.subscribe('XMove', ({move}: {move: number}) => { - this.makeMove('X', move); - }); - this.client.subscribe('GetState', () => { - this.sendUpdate(); - }); - this.sendUpdate(); - } +type Methods = { + SetState: (state: State) => Promise; +}; - makeMove(player: 'X' | 'O', move: number) { - if (this.state.turn === player && this.state.cells[move] === ' ') { - this.setState(computeNextState(this.state, move, player), () => - this.sendUpdate(), - ); +export const plugin = (client: PluginClient) => { + const state = createState(initialState()); + + const sendUpdate = () => { + client.send('SetState', state.get()); + }; + + const makeMove = (player: 'X' | 'O', move: number) => { + if (state.get().turn === player && state.get().cells[move] === ' ') { + state.update(computeNextState(move, player)); + sendUpdate(); } - } + }; - sendUpdate() { - this.client.call('SetState', this.state); - } + const reset = () => { + state.set(initialState()); + sendUpdate(); + }; - handleCellClick(move: number) { - this.makeMove('O', move); - } + client.onConnect(() => { + client.onMessage('XMove', ({move}) => { + makeMove('X', move); + }); + client.onMessage('GetState', () => { + sendUpdate(); + }); + sendUpdate(); + }); - handleReset() { - this.setState(initialState(), () => this.sendUpdate()); - } + return { + makeMove, + reset, + state, + }; +}; - render() { - const {winner, turn, cells} = this.state; - return ( - - - - This plugin demonstrates how to create pure JavaScript Flipper - plugins for React Native. Find out how to create a similar plugin at{' '} - - fbflipper.com - - . - - - Flipper Tic-Tac-Toe -
-
- - {winner !== ' ' - ? `Winner! ${winner}` - : turn === 'O' - ? 'Your turn' - : 'Mobile players turn..'} - - - {cells.map((c, idx) => ( - this.handleCellClick(idx)}> - {c} - - ))} - - -
-
-
- ); - } -} +const desktopPlayer = 'O'; -const Container = styled('div')({ - border: `4px solid ${brandColors.Flipper}`, - borderRadius: 4, - padding: 20, - marginTop: 20, -}); +export const Component = () => { + const pluginInstance = usePlugin(plugin); + const {winner, turn, cells} = useValue(pluginInstance.state); -const GameBoard = styled(FlexRow)({ - flexWrap: 'wrap', - justifyContent: 'space-between', - marginTop: 20, - marginBottom: 20, + return ( + + + + This plugin demonstrates how to create pure JavaScript Flipper + plugins for React Native. Find out how to create a similar plugin + at{' '} + + fbflipper.com + + . + + } + type="info" + /> + Flipper Tic-Tac-Toe + + {winner !== ' ' + ? `Winner! ${winner}` + : turn === 'O' + ? 'Your turn' + : 'Mobile players turn..'} + + + {cells.map((c, idx) => ( + pluginInstance.makeMove(desktopPlayer, idx)}> + {c} + + ))} + + + + + ); +}; + +const GameBoard = styled('div')({ + display: 'grid', + gridTemplateColumns: 'repeat(3, 80px)', + gridTemplateRows: 'repeat(3, 80px)', + justifyContent: 'center', + gap: 10, }); const Cell = styled('button')({ padding: 20, - height: 80, + width: '100%', + height: '100%', minWidth: 80, fontSize: 24, - margin: 20, flex: 0, borderRadius: 4, - backgroundColor: colors.highlight, + backgroundColor: theme.backgroundDefault, color: 'white', ':disabled': { - backgroundColor: colors.grayTint2, + backgroundColor: theme.disabledColor, }, }); diff --git a/desktop/plugins/public/rn-tic-tac-toe/package.json b/desktop/plugins/public/rn-tic-tac-toe/package.json index a20bc0117..9ca950a05 100644 --- a/desktop/plugins/public/rn-tic-tac-toe/package.json +++ b/desktop/plugins/public/rn-tic-tac-toe/package.json @@ -14,5 +14,8 @@ "category": "Examples", "bugs": { "url": "https://github.com/facebook/flipper/issues" + }, + "peerDependencies": { + "flipper-plugin": "*" } }