Allow to show only for yourself
This commit is contained in:
parent
863936bd1c
commit
4c3e7e5359
7 changed files with 102 additions and 38 deletions
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in a new issue