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,
allowMapDrawing,
allowFogDrawing,
allowTokenChange,
disabledTokens,
}) {
const mapSource = useDataSource(map, defaultMapSources);
@ -302,20 +302,18 @@ function Map({
{map && mapFog}
{map && mapTokens}
</MapInteraction>
{allowTokenChange && (
<>
<ProxyToken
tokenClassName={mapTokenProxyClassName}
onProxyDragEnd={handleProxyDragEnd}
tokens={mapState && mapState.tokens}
/>
<TokenMenu
tokenClassName={mapTokenMenuClassName}
onTokenChange={onMapTokenStateChange}
tokens={mapState && mapState.tokens}
/>
</>
)}
<ProxyToken
tokenClassName={mapTokenProxyClassName}
onProxyDragEnd={handleProxyDragEnd}
tokens={mapState && mapState.tokens}
disabledTokens={disabledTokens}
/>
<TokenMenu
tokenClassName={mapTokenMenuClassName}
onTokenChange={onMapTokenStateChange}
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 {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} 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 [imageSource, setImageSource] = useState("");
@ -30,9 +37,11 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
// Store the tokens in a ref and access in the interactjs loop
// This is needed to stop interactjs from creating multiple listeners
const tokensRef = useRef(tokens);
const disabledTokensRef = useRef(disabledTokens);
useEffect(() => {
tokensRef.current = tokens;
}, [tokens]);
disabledTokensRef.current = disabledTokens;
}, [tokens, disabledTokens]);
const proxyOnMap = useRef(false);
@ -41,10 +50,15 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
listeners: {
start: (event) => {
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
target.parentElement.style.opacity = "0.25";
setImageSource(target.src);
setTokenId(target.dataset.id);
setTokenId(id);
let proxy = proxyRef.current;
if (proxy) {
@ -90,6 +104,10 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
end: (event) => {
let target = event.target;
const id = target.dataset.id;
if (id in disabledTokensRef.current) {
return;
}
let proxy = proxyRef.current;
if (proxy) {
if (onProxyDragEnd) {
@ -106,7 +124,6 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
y = y / (mapImageRect.bottom - mapImageRect.top);
// Get the token from the supplied tokens if it exists
const id = target.getAttribute("data-id");
const token = tokensRef.current[id] || {};
onProxyDragEnd(proxyOnMap.current, {
@ -172,6 +189,7 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
ProxyToken.defaultProps = {
tokens: {},
disabledTokens: {},
};
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 {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} 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);
function handleRequestClose() {
@ -27,9 +28,11 @@ function TokenMenu({ tokenClassName, onTokenChange, tokens }) {
// Store the tokens in a ref and access in the interactjs loop
// This is needed to stop interactjs from creating multiple listeners
const tokensRef = useRef(tokens);
const disabledTokensRef = useRef(disabledTokens);
useEffect(() => {
tokensRef.current = tokens;
}, [tokens]);
disabledTokensRef.current = disabledTokens;
}, [tokens, disabledTokens]);
const [currentToken, setCurrentToken] = useState({});
const [menuLeft, setMenuLeft] = useState(0);
@ -67,6 +70,9 @@ function TokenMenu({ tokenClassName, onTokenChange, tokens }) {
function handleTokenMenuOpen(event) {
const target = event.target;
const id = target.getAttribute("data-id");
if (id in disabledTokensRef.current) {
return;
}
const token = tokensRef.current[id] || {};
setCurrentToken(token);

View File

@ -54,10 +54,21 @@ function Game() {
mapState !== null &&
(mapState.editFlags.includes("fog") || map.owner === userId);
const canEditTokens =
map !== null &&
const disabledMapTokens = {};
// If we have a map and state and have the token permission disabled
// and are not the map owner
if (
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
const debouncedMapState = useDebounce(mapState, 500);
@ -472,7 +483,7 @@ function Game() {
onFogDrawRedo={handleFogDrawRedo}
allowMapDrawing={canEditMapDrawing}
allowFogDrawing={canEditFogDrawing}
allowTokenChange={canEditTokens}
disabledTokens={disabledMapTokens}
/>
<Tokens
tokens={tokens}