Allow to show only for yourself

This commit is contained in:
Jeremie Pardou-Piquemal 2020-06-14 21:18:51 +02:00
parent 863936bd1c
commit 4c3e7e5359
7 changed files with 102 additions and 38 deletions

5
package-lock.json generated
View file

@ -11664,6 +11664,11 @@
}
}
},
"react-use-localstorage": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/react-use-localstorage/-/react-use-localstorage-3.4.1.tgz",
"integrity": "sha512-OKKAQT3CeDWGhoboE78XchXRJkxCYIFNZBM5gfiBxOcaMQU+CSP7d3iyBHwpgdSen2DlIdy2ZvExwIk4oci3pg=="
},
"react-zoom-pan-pinch": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-1.6.1.tgz",

View file

@ -19,6 +19,7 @@
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"react-use-localstorage": "^3.4.1",
"react-zoom-pan-pinch": "^1.6.1",
"recoil": "0.0.7",
"socket.io": "^2.3.0",

View file

@ -6,17 +6,24 @@ import { nanoid } from 'nanoid';
import { ItemListAtom } from '../components/Items';
import { useRecoilValue } from 'recoil';
import useLocalStorage from 'react-use-localstorage';
import tiktok from '../games/tiktok';
import card from '../games/card';
import gloomhaven from '../games/gloomhaven';
export const GameLoader = ({
export const GameController = ({
itemList,
setItemList,
boardConfig,
setBoardConfig,
}) => {
const [c2c, joined, isMaster] = useC2C();
/*const [gameSave, setGameSave] = useLocalStorage('savedGame', {
items: [],
board: {},
});*/
const gameRef = React.useRef({ items: itemList, board: boardConfig });
// Not very efficient way to do it
const allItems = useRecoilValue(ItemListAtom);
@ -95,6 +102,14 @@ export const GameLoader = ({
c2c.publish('loadGame', gloomhaven, true);
};
/*const loadLastGame = () => {
gameSave.items = gameSave.items.map((item) => ({
...item,
id: nanoid(),
}));
c2c.publish('loadGame', gameSave, true);
};*/
if (!isMaster) {
return null;
}
@ -107,6 +122,7 @@ export const GameLoader = ({
display: 'block',
}}
>
<button onClick={() => {}}>Load last game</button>
<button onClick={loadTikTok}>TikTok</button>
<button onClick={loadCard}>Card</button>
<button onClick={loadGloomhaven}>Gloomhaven</button>
@ -114,4 +130,4 @@ export const GameLoader = ({
);
};
export default GameLoader;
export default GameController;

View file

@ -3,6 +3,7 @@ import { useC2C } from '../hooks/useC2C';
import { PanZoomRotateState } from '../components/PanZoomRotate';
import { useRecoilValue } from 'recoil';
import { selectedItemsAtom } from './Selector';
import { userAtom } from '../hooks/useUser';
const Rect = ({ width, height, color }) => {
return (
@ -38,7 +39,9 @@ const Image = ({
backContent,
flipped,
updateState,
unflippedFor,
}) => {
const user = useRecoilValue(userAtom);
const size = {};
if (width) {
size.width = width;
@ -47,33 +50,49 @@ const Image = ({
size.height = height;
}
const onDblClick = (e) => {
updateState((prevItem) => ({ ...prevItem, flipped: !prevItem.flipped }));
};
const onDblClick = React.useCallback(
(e) => {
if (e.ctrlKey) {
updateState((prevItem) => {
if (prevItem.unflippedFor !== null) {
return { ...prevItem, unflippedFor: null };
} else {
return { ...prevItem, unflippedFor: user.id, flipped: false };
}
});
} else {
updateState((prevItem) => ({
...prevItem,
flipped: !prevItem.flipped,
unflippedFor: null,
}));
}
},
[updateState, user.id]
);
if (flipped && backContent) {
return (
<div onDoubleClick={onDblClick}>
<img
src={backContent}
draggable={false}
{...size}
style={{ userSelect: 'none', pointerEvents: 'none' }}
/>
</div>
let image;
if (backContent && (flipped || (unflippedFor && unflippedFor !== user.id))) {
image = (
<img
src={backContent}
draggable={false}
{...size}
style={{ userSelect: 'none', pointerEvents: 'none' }}
/>
);
}
return (
<div onDoubleClick={onDblClick}>
} else {
image = (
<img
src={content}
draggable={false}
{...size}
style={{ userSelect: 'none', pointerEvents: 'none' }}
onDoubleClick={onDblClick}
/>
</div>
);
);
}
return <div onDoubleClick={onDblClick}>{image}</div>;
};
const getComponent = (type) => {
@ -132,8 +151,8 @@ const Item = ({ setState, state }) => {
const rotation = state.rotation || 0;
const updateState = React.useCallback(
(callbackOrItem) => {
setState(state.id, callbackOrItem);
(callbackOrItem, sync = true) => {
setState(state.id, callbackOrItem, sync);
},
[setState, state]
);
@ -146,11 +165,14 @@ const Item = ({ setState, state }) => {
if (entry.contentBoxSize) {
const { inlineSize: width, blockSize: height } = entry.contentBoxSize;
if (state.actualWidth !== width || state.actualHeight !== height) {
updateState((prevState) => ({
...prevState,
actualWidth: width,
actualHeight: height,
}));
updateState(
(prevState) => ({
...prevState,
actualWidth: width,
actualHeight: height,
}),
false // Don't need to sync that.
);
}
}
});
@ -203,7 +225,16 @@ const SyncedItem = ({ setState, state }) => {
const unsub = c2c.subscribe(
`itemStateUpdate.${state.id}`,
(newItemState) => {
setState(state.id, newItemState, false);
setState(
state.id,
(prevState) => ({
...newItemState,
// Ignore some modifications
actualWidth: prevState.actualWidth,
actualHeight: prevState.actualHeight,
}),
false
);
}
);
return unsub;

View file

@ -25,7 +25,9 @@ const Items = ({}) => {
...callback(item),
id: item.id, // Prevent id modification
};
sync && c2c.publish(`itemStateUpdate.${id}`, newItem);
if (sync) {
c2c.publish(`itemStateUpdate.${newItem.id}`, newItem);
}
return newItem;
}
return item;

View file

@ -3,6 +3,7 @@ import { useC2C } from './useC2C';
import randomColor from 'randomcolor';
import debounce from 'lodash.debounce';
import { nanoid } from 'nanoid';
import { atom, useRecoilState } from 'recoil';
const getUser = () => {
if (localStorage.user) {
@ -28,8 +29,13 @@ const persistUser = (user) => {
localStorage.setItem('user', JSON.stringify(user));
};
export const userAtom = atom({
key: 'user',
default: getUser(),
});
function useUser() {
const [user, setUserState] = React.useState(getUser());
const [user, setUserState] = useRecoilState(userAtom);
const [c2c, joined] = useC2C();
React.useEffect(() => {
@ -39,12 +45,15 @@ function useUser() {
id: c2c.userId,
}));
}
}, [joined, c2c.userId]);
}, [joined, c2c.userId, setUserState]);
const setUser = React.useCallback((newUser) => {
setUserState((prevUser) => ({ ...newUser, id: prevUser.id }));
persistUser(newUser);
}, []);
const setUser = React.useCallback(
(newUser) => {
setUserState((prevUser) => ({ ...newUser, id: prevUser.id }));
persistUser(newUser);
},
[setUserState]
);
// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedEmitUpdateUser = React.useCallback(

View file

@ -1,7 +1,7 @@
import React from 'react';
import Users from '../components/Users';
import GameLoader from '../components/GameLoader';
import GameController from '../components/GameController';
import ZoomPanRotate from '../components/PanZoomRotate';
import Board from '../components/Board';
import { ItemListAtom } from '../components/Items';
@ -25,7 +25,7 @@ export const BoardView = () => {
<Users user={user} setUser={setUser} users={users} userId={user.id} />
<SelectedItems />
<GameLoader
<GameController
itemList={itemList}
setItemList={setItemList}
boardConfig={boardConfig}