diff --git a/src/components/Board/Items/Item/Image.js b/src/components/Board/Items/Item/Image.js index d9905ae..3dd3caa 100644 --- a/src/components/Board/Items/Item/Image.js +++ b/src/components/Board/Items/Item/Image.js @@ -2,18 +2,29 @@ import React, { memo } from "react"; import { useUsers } from "../../../../components/users"; import styled from "styled-components"; -const OnlyYouLabel = styled.div` +import eye from "../../../../images/eye.svg"; + +const UnflippedFor = styled.div` position: absolute; - top: -20px; + top: -34px; right: 2px; color: #555; font-size: 0.6em; + display: flex; + justify-content: center; + align-items: center; - background-color: #cccccca0; pointer-events: none; line-height: 1.5em; `; +const UnflippedForUser = styled.img` + background-color: ${({ color }) => color}; + border-radius: 2px; + padding: 2px; + margin: 2px; +`; + const Label = styled.div` position: absolute; top: 1px; @@ -68,8 +79,10 @@ const Image = ({ backText, overlay, }) => { - const { currentUser } = useUsers(); + const { currentUser, users } = useUsers(); + const size = {}; + if (width) { size.width = width; } @@ -77,12 +90,27 @@ const Image = ({ size.height = height; } + const unflippedForUsers = React.useMemo(() => { + if (Array.isArray(unflippedFor)) { + return unflippedFor + .filter((userId) => users.find(({ id }) => userId === id)) + .map((userId) => users.find(({ id }) => userId === id)); + } + return []; + }, [unflippedFor, users]); + const flippedForMe = - backContent && flipped && unflippedFor !== currentUser.id; + backContent && + flipped && + (!Array.isArray(unflippedFor) || !unflippedFor.includes(currentUser.id)); return ( - {unflippedFor === currentUser.id && Only you} + + {unflippedForUsers.map(({ color, id }) => { + return ; + })} + {flippedForMe && backText && } {(!flippedForMe || !backText) && text && } { ); // Reveal for player only - const revealForMe = React.useCallback(() => { - batchUpdateItems(selectedItems, (item) => ({ - ...item, - flipped: true, - unflippedFor: currentUser.id, - })); - }, [batchUpdateItems, selectedItems, currentUser.id]); + const toggleFlipSelf = useRecoilCallback( + async (snapshot) => { + const selectedItemList = await getSelectedItemList(snapshot); + const flippedSelfCount = selectedItemList.filter( + ({ unflippedFor }) => + Array.isArray(unflippedFor) && unflippedFor.includes(currentUser.id) + ).length; + + let flipSelf = true; + if (flippedSelfCount > selectedItems.length / 2) { + flipSelf = false; + } + + batchUpdateItems(selectedItems, (item) => { + let unflippedFor; + if (!Array.isArray(item.unflippedFor)) { + unflippedFor = []; + } else { + unflippedFor = [...item.unflippedFor]; + } + if (flipSelf && !unflippedFor.includes(currentUser.id)) { + unflippedFor.push(currentUser.id); + } + if (!flipSelf && unflippedFor.includes(currentUser.id)) { + unflippedFor = unflippedFor.filter((id) => id !== currentUser.id); + } + return { + ...item, + flipped: true, + unflippedFor, + }; + }); + }, + [batchUpdateItems, selectedItems, currentUser.id] + ); // Remove selected items const removeItems = React.useCallback( @@ -184,8 +212,8 @@ export const useItemActions = () => { return { align, remove: removeItems, - revealForMe, toggleFlip, + toggleFlipSelf, toggleLock, toggleTap, shuffle: shuffleSelectedItems, diff --git a/src/components/SelectedItemsPane.js b/src/components/SelectedItemsPane.js index 920ec36..6ff136a 100644 --- a/src/components/SelectedItemsPane.js +++ b/src/components/SelectedItemsPane.js @@ -37,8 +37,8 @@ export const SelectedItems = ({ edit }) => { const { align, remove, - revealForMe, toggleFlip, + toggleFlipSelf, toggleLock, toggleTap, shuffle, @@ -58,7 +58,7 @@ export const SelectedItems = ({ edit }) => { shortcut: "f", }, flipSelf: { - action: revealForMe, + action: toggleFlipSelf, label: t("Reveal for me"), shortcut: "o", }, @@ -109,7 +109,7 @@ export const SelectedItems = ({ edit }) => { [ align, remove, - revealForMe, + toggleFlipSelf, rotate, shuffle, t, diff --git a/src/i18n/en.json b/src/i18n/en.json index 5f0f264..e1a311f 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -73,5 +73,8 @@ "welcomeText": "<0>Airboardgame is a tabletop simulator to play your favorite board games with your friends online.", "InviteFriends": "<0>To invite other players to play with you, share the following links with your friends.", "moreInformation": "<0>For more informations, visit <2>github repository.", - "I want play...": "I want play..." + "I want play...": "I want play...", + "Zone": "Zone", + "Reveal for me": "Reveal for me", + "Waiting for connection…": "Waiting for connection…" } diff --git a/src/i18n/fr.json b/src/i18n/fr.json index 786ab44..da7bf16 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -73,5 +73,8 @@ "welcomeText": "<0>Airboardgame est un simulateur de table de jeu qui vous permet de jouer en ligne avec vos amis à vos jeux de société préférés.", "InviteFriends": "<0>Pour inviter d'autres joueurs, partagez le lien suivant avec vos amis.", "moreInformation": "<0>Pour plus d'informations, visitez le <2>dépôt github.", - "I want play...": "Je veux jouer..." + "I want play...": "Je veux jouer...", + "Zone": "Zone", + "Reveal for me": "Retourner pour moi", + "Waiting for connection…": "En attente d'une connection…" } diff --git a/src/images/eye.svg b/src/images/eye.svg new file mode 100644 index 0000000..534baf4 --- /dev/null +++ b/src/images/eye.svg @@ -0,0 +1,7 @@ + + + + eye + + + \ No newline at end of file