Skip to content

Commit

Permalink
New dropdown menu
Browse files Browse the repository at this point in the history
  • Loading branch information
ProLoser committed Sep 26, 2024
1 parent 6dd66ae commit 2f49979
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 63 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "Backgammon",
"name": "backgammon.family",
"description": "Open Source Backgammon with auto-translation to enable meaningful conversations across generations",
"version": "1.0.0",
"private": "true",
"type": "module",
"repository": "https://github.com/ProLoser/PeaceInTheMiddleEast",
"license": "MIT",
"scripts": {
"dev": "vite",
"start": "vite",
"build": "vite build",
"tsc": "tsc",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
Expand Down
2 changes: 1 addition & 1 deletion src/Game/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function Game() {
vibrate()
const newDice = [rollDie(), rollDie()]
if (match?.game)
database.ref(`games/${match.game}`).update({ dice: newDice })
database.ref(`games/${match.game}/dice`).set(newDice)
setGame(game => ({...game, dice: newDice}))
}, [match])

Expand Down
1 change: 1 addition & 0 deletions src/Online/Contexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const MultiplayerContext = createContext({
load: (userId: UserData["uid"]) => { },
move: (game: GameType, move: string) => { },
chat: (message: string) => { },
reset: () => { },
});
export const ChatContext = createContext<SnapshotOrNullType>(null);
export const MatchContext = createContext<Match|null>(null);
Expand Down
81 changes: 65 additions & 16 deletions src/Online/Friends/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,27 @@
width: 100%;
padding: 5px;
}
ul {
#people ul {
list-style: none;
padding: 0;
}
li {
display: flex;
align-items: center;
margin-bottom: 1em;
h3 {
margin-bottom: 0;
li {
display: flex;
align-items: center;
margin-bottom: 1em;

h3 {
margin-bottom: 0;
}
}

img {
width: 5em;
height: 5em;
border-radius: 50%;
margin-right: 1em;
/* border: 2px solid #AAA; */
object-fit: cover;
}
}
img {
width: 5em;
height: 5em;
border-radius: 50%;
margin-right: 1em;
/* border: 2px solid #AAA; */
object-fit: cover;
}
h1 {
vertical-align: text-top;
Expand All @@ -38,4 +40,51 @@
}
}
}
[aria-haspopup="menu"] {
float: right;
}
}

/* Base styles for the button that triggers the popup menu */
[aria-haspopup="menu"] {
padding: 5px 10px;
background: none;
border: none;
color: black;
cursor: pointer;

&:hover {
color: blue;
}

&+menu,
&+[role="menu"] {
display: none;
background-color: rgba(255, 255, 255, 0.9);
border: 1px solid #ccc;
border-radius: 4px;
position: absolute;
padding: 0;
right: 0;
margin: 2em 0 0;
list-style-type: none;
}

/* active */
&[aria-expanded="true"] {

&+menu,
&+[role="menu"] {
display: block;
}
}
}

/* Styles for menu items */
[role="menuitem"],
menu>li {
padding: .5em;
text-decoration: none;
display: block;
white-space: nowrap;
}
73 changes: 51 additions & 22 deletions src/Online/Friends/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,30 @@ import { MultiplayerContext, Match, ModalContext } from '../Contexts';
import { Avatar } from '../Profile';
import { formatDistance } from 'date-fns';

const toggleFullscreen = () => document.fullscreenElement
? document.exitFullscreen()
: document.documentElement.requestFullscreen()

type Users = {[key: string]: UserData}

export default function Friends() {
const searchRef = useRef<HTMLInputElement>(null);
const authUser = useContext(AuthContext); // Local signed-in state.
const [users, setUsers] = useState<Users>({});
const { load } = useContext(MultiplayerContext);
const [isExpanded, setIsExpanded] = useState(false);
const { load, reset } = useContext(MultiplayerContext);
const { toggle } = useContext(ModalContext);
const [matches, setMatches] = useState<firebase.database.DataSnapshot>([]);
const [searchResults, setSearchResults] = useState<firebase.database.DataSnapshot>([]);
const [fullscreen, setFullscreen] = useState(!!document.fullscreenElement);

// Synchronize Fullscreen Icon
useEffect(() => {
const fullscreenchange = () => setFullscreen(!!document.fullscreenElement);
document.addEventListener('fullscreenchange', fullscreenchange);
return () => document.removeEventListener('fullscreenchange', fullscreenchange);
})


// Synchronize Matches
useEffect(() => {
Expand Down Expand Up @@ -97,32 +111,47 @@ export default function Friends() {
})

return <div id="friends" className='modal'>
<button
aria-haspopup="menu"
aria-expanded={isExpanded}
onClick={() => setIsExpanded(!isExpanded)}
className="material-icons"
>
settings
</button>
<menu>
{document.fullscreenEnabled ?
<li>
<a onClick={toggleFullscreen}>
<span className="material-icons">{fullscreen ? 'fullscreen_exit' : 'fullscreen'}</span>
Fullscreen
</a>
</li>
: null}
<li>
<a onClick={() => toggle('profile')}>
<span className="material-icons">manage_accounts</span>
Edit Profile
</a>
</li>
<li>
<a onClick={reset}>
<span className="material-icons">restart_alt</span>
Reset Match
</a>
</li>
<li>
<a onClick={() => firebase.auth().signOut()}>
<span className="material-icons">logout</span>
Logout
</a>
</li>
</menu>
<h1>
<a onClick={() => toggle('profile')}>
<svg className="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" strokeLinecap="square" strokeLinejoin="round" strokeWidth="2" d="M7 19H5a1 1 0 0 1-1-1v-1a3 3 0 0 1 3-3h1m4-6a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm7.441 1.559a1.907 1.907 0 0 1 0 2.698l-6.069 6.069L10 19l.674-3.372 6.07-6.07a1.907 1.907 0 0 1 2.697 0Z" />
</svg>
</a>
<span>
<span>{authUser.val().name}'s</span>
Matches
</span>
<a onClick={() => firebase.auth().signOut()}>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2" />
<path d="M9 12h12l-3 -3" />
<path d="M18 15l3 -3" />
</svg>
</a>
<a>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
</svg>
</a>
</h1>
<div id="people">
<input name="search" ref={searchRef} type="search" autoComplete="off" placeholder="Search for Friends" onChange={onSearch} />
Expand Down
12 changes: 11 additions & 1 deletion src/Online/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ export function Provider({ children }: PropsWithChildren) {
toggle(false);
}, [user]);

const reset = useCallback(async () => {
if (match?.game) {
if (confirm('Are you sure you want to reset the match?')) {
console.log('Resetting', match.game);
database.ref(`games/${match.game}`).remove();
// TODO: update state
}
}
}, [match]);

// Autoload Match upon Login
useEffect(() => {
if (!user) return;
Expand Down Expand Up @@ -160,7 +170,7 @@ export function Provider({ children }: PropsWithChildren) {
return (
<AuthContext.Provider value={user}>
<ModalContext.Provider value={useMemo(() => ({ toggle, state }), [toggle, state])}>
<MultiplayerContext.Provider value={useMemo(() => ({ load, move, chat }), [load, move, chat])}>
<MultiplayerContext.Provider value={useMemo(() => ({ load, move, chat, reset }), [load, move, chat, reset])}>
<FriendContext.Provider value={friend}>
<ChatContext.Provider value={chats}>
<MatchContext.Provider value={match}>
Expand Down
21 changes: 1 addition & 20 deletions src/Toolbar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,16 @@
import { useCallback, useState, useEffect, useContext } from 'react'
import { useCallback, useContext } from 'react'
import './index.css'
import { FriendContext, ModalContext } from '../Online/Contexts'

export default function Toolbar() {
const {state, toggle} = useContext(ModalContext)
const toggleFullscreen = useCallback(() => {
if (document.fullscreenElement)
document.exitFullscreen()
else
document.documentElement.requestFullscreen()
}, [])
const [isFullscreen, setFullscreen] = useState(false);

// Mirror the document.fullscreenElement to react state
useEffect(() => {
const handleFullscreenChange = () => {
setFullscreen(!!document.fullscreenElement);
};
document.addEventListener('fullscreenchange', handleFullscreenChange);
return () => {
document.removeEventListener('fullscreenchange', handleFullscreenChange);
};
}, []);
const friend = useContext(FriendContext);

const renderFriend = friend ? <h2>{friend.val().name}</h2> : null;

const toggleFriends = useCallback(() => { toggle(!state) }, [state])

return <div id="toolbar">
{document.fullscreenEnabled ? <a className="material-icons" onClick={toggleFullscreen}>{isFullscreen ?'fullscreen_exit':'fullscreen'}</a> : null}
<a className={`material-icons ${state&&'active'||''}`} onClick={toggleFriends}>account_circle</a>
{renderFriend}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ body,
@media (max-aspect-ratio: 1) {
top: 100px;
left: 40px;
:first-child {
> :first-child {
margin-top: 0;
}
}
Expand Down

0 comments on commit 2f49979

Please sign in to comment.