Changed to having token edit permissions still allow you to place tokens

This commit is contained in:
Mitchell McCaffrey 2020-04-30 15:12:34 +10:00
parent 23e42aa115
commit 11671849f8
4 changed files with 58 additions and 25 deletions

View File

@ -33,7 +33,7 @@ function Map({
onFogDrawRedo, onFogDrawRedo,
allowMapDrawing, allowMapDrawing,
allowFogDrawing, allowFogDrawing,
allowTokenChange, disabledTokens,
}) { }) {
const mapSource = useDataSource(map, defaultMapSources); const mapSource = useDataSource(map, defaultMapSources);
@ -302,20 +302,18 @@ function Map({
{map && mapFog} {map && mapFog}
{map && mapTokens} {map && mapTokens}
</MapInteraction> </MapInteraction>
{allowTokenChange && ( <ProxyToken
<> tokenClassName={mapTokenProxyClassName}
<ProxyToken onProxyDragEnd={handleProxyDragEnd}
tokenClassName={mapTokenProxyClassName} tokens={mapState && mapState.tokens}
onProxyDragEnd={handleProxyDragEnd} disabledTokens={disabledTokens}
tokens={mapState && mapState.tokens} />
/> <TokenMenu
<TokenMenu tokenClassName={mapTokenMenuClassName}
tokenClassName={mapTokenMenuClassName} onTokenChange={onMapTokenStateChange}
onTokenChange={onMapTokenStateChange} tokens={mapState && mapState.tokens}
tokens={mapState && mapState.tokens} disabledTokens={disabledTokens}
/> />
</>
)}
</> </>
); );
} }

View File

@ -19,8 +19,15 @@ import TokenStatus from "./TokenStatus";
* @param {string} tokenClassName The class name to attach the interactjs handler to * @param {string} tokenClassName The class name to attach the interactjs handler to
* @param {onProxyDragEnd} onProxyDragEnd Called when the proxy token is dropped * @param {onProxyDragEnd} onProxyDragEnd Called when the proxy token is dropped
* @param {Object} tokens An optional mapping of tokens to use as a base when calling OnProxyDragEnd * @param {Object} tokens An optional mapping of tokens to use as a base when calling OnProxyDragEnd
* @param {Object} disabledTokens An optional mapping of tokens that shouldn't allow movement
*/ */
function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) { function ProxyToken({
tokenClassName,
onProxyDragEnd,
tokens,
disabledTokens,
}) {
const proxyContainer = usePortal("root"); const proxyContainer = usePortal("root");
const [imageSource, setImageSource] = useState(""); const [imageSource, setImageSource] = useState("");
@ -30,9 +37,11 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
// Store the tokens in a ref and access in the interactjs loop // Store the tokens in a ref and access in the interactjs loop
// This is needed to stop interactjs from creating multiple listeners // This is needed to stop interactjs from creating multiple listeners
const tokensRef = useRef(tokens); const tokensRef = useRef(tokens);
const disabledTokensRef = useRef(disabledTokens);
useEffect(() => { useEffect(() => {
tokensRef.current = tokens; tokensRef.current = tokens;
}, [tokens]); disabledTokensRef.current = disabledTokens;
}, [tokens, disabledTokens]);
const proxyOnMap = useRef(false); const proxyOnMap = useRef(false);
@ -41,10 +50,15 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
listeners: { listeners: {
start: (event) => { start: (event) => {
let target = event.target; let target = event.target;
const id = target.dataset.id;
if (id in disabledTokensRef.current) {
return;
}
// Hide the token and copy it's image to the proxy // Hide the token and copy it's image to the proxy
target.parentElement.style.opacity = "0.25"; target.parentElement.style.opacity = "0.25";
setImageSource(target.src); setImageSource(target.src);
setTokenId(target.dataset.id); setTokenId(id);
let proxy = proxyRef.current; let proxy = proxyRef.current;
if (proxy) { if (proxy) {
@ -90,6 +104,10 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
end: (event) => { end: (event) => {
let target = event.target; let target = event.target;
const id = target.dataset.id;
if (id in disabledTokensRef.current) {
return;
}
let proxy = proxyRef.current; let proxy = proxyRef.current;
if (proxy) { if (proxy) {
if (onProxyDragEnd) { if (onProxyDragEnd) {
@ -106,7 +124,6 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
y = y / (mapImageRect.bottom - mapImageRect.top); y = y / (mapImageRect.bottom - mapImageRect.top);
// Get the token from the supplied tokens if it exists // Get the token from the supplied tokens if it exists
const id = target.getAttribute("data-id");
const token = tokensRef.current[id] || {}; const token = tokensRef.current[id] || {};
onProxyDragEnd(proxyOnMap.current, { onProxyDragEnd(proxyOnMap.current, {
@ -172,6 +189,7 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
ProxyToken.defaultProps = { ProxyToken.defaultProps = {
tokens: {}, tokens: {},
disabledTokens: {},
}; };
export default ProxyToken; export default ProxyToken;

View File

@ -16,8 +16,9 @@ import colors, { colorOptions } from "../../helpers/colors";
* @param {string} tokenClassName The class name to attach the interactjs handler to * @param {string} tokenClassName The class name to attach the interactjs handler to
* @param {onProxyDragEnd} onTokenChange Called when the the token data is changed * @param {onProxyDragEnd} onTokenChange Called when the the token data is changed
* @param {Object} tokens An mapping of tokens to use as a base when calling onTokenChange * @param {Object} tokens An mapping of tokens to use as a base when calling onTokenChange
* @param {Object} disabledTokens An optional mapping of tokens that shouldn't allow interaction
*/ */
function TokenMenu({ tokenClassName, onTokenChange, tokens }) { function TokenMenu({ tokenClassName, onTokenChange, tokens, disabledTokens }) {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
function handleRequestClose() { function handleRequestClose() {
@ -27,9 +28,11 @@ function TokenMenu({ tokenClassName, onTokenChange, tokens }) {
// Store the tokens in a ref and access in the interactjs loop // Store the tokens in a ref and access in the interactjs loop
// This is needed to stop interactjs from creating multiple listeners // This is needed to stop interactjs from creating multiple listeners
const tokensRef = useRef(tokens); const tokensRef = useRef(tokens);
const disabledTokensRef = useRef(disabledTokens);
useEffect(() => { useEffect(() => {
tokensRef.current = tokens; tokensRef.current = tokens;
}, [tokens]); disabledTokensRef.current = disabledTokens;
}, [tokens, disabledTokens]);
const [currentToken, setCurrentToken] = useState({}); const [currentToken, setCurrentToken] = useState({});
const [menuLeft, setMenuLeft] = useState(0); const [menuLeft, setMenuLeft] = useState(0);
@ -67,6 +70,9 @@ function TokenMenu({ tokenClassName, onTokenChange, tokens }) {
function handleTokenMenuOpen(event) { function handleTokenMenuOpen(event) {
const target = event.target; const target = event.target;
const id = target.getAttribute("data-id"); const id = target.getAttribute("data-id");
if (id in disabledTokensRef.current) {
return;
}
const token = tokensRef.current[id] || {}; const token = tokensRef.current[id] || {};
setCurrentToken(token); setCurrentToken(token);

View File

@ -54,10 +54,21 @@ function Game() {
mapState !== null && mapState !== null &&
(mapState.editFlags.includes("fog") || map.owner === userId); (mapState.editFlags.includes("fog") || map.owner === userId);
const canEditTokens = const disabledMapTokens = {};
map !== null && // If we have a map and state and have the token permission disabled
// and are not the map owner
if (
mapState !== null && mapState !== null &&
(mapState.editFlags.includes("tokens") || map.owner === userId); map !== null &&
!mapState.editFlags.includes("tokens") &&
map.owner !== userId
) {
for (let token of Object.values(mapState.tokens)) {
if (token.owner !== userId) {
disabledMapTokens[token.id] = true;
}
}
}
// Sync the map state to the database after 500ms of inactivity // Sync the map state to the database after 500ms of inactivity
const debouncedMapState = useDebounce(mapState, 500); const debouncedMapState = useDebounce(mapState, 500);
@ -472,7 +483,7 @@ function Game() {
onFogDrawRedo={handleFogDrawRedo} onFogDrawRedo={handleFogDrawRedo}
allowMapDrawing={canEditMapDrawing} allowMapDrawing={canEditMapDrawing}
allowFogDrawing={canEditFogDrawing} allowFogDrawing={canEditFogDrawing}
allowTokenChange={canEditTokens} disabledTokens={disabledMapTokens}
/> />
<Tokens <Tokens
tokens={tokens} tokens={tokens}