Skip to content

Commit

Permalink
add keystrokes for skipping and playing/stopping a hit
Browse files Browse the repository at this point in the history
  • Loading branch information
Timtam committed Nov 5, 2024
1 parent 4268ba0 commit 4773a4a
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 10 deletions.
3 changes: 3 additions & 0 deletions client/src/locale/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"noHitAvailable": "Kein Hit verfügbar",
"stopHit": "Hit stoppen",
"playHit": "Hit abspielen",
"playOrStopHit": "Hit abspielen oder stoppen",
"playOrStopHitShortcut": "Alt+Umschalt+H",
"and": "und",
"gameNotStarted": "Das Spiel hat noch nicht begonnen.",
"waitingForPlayerHeading_one": "Du wartest noch auf <0>{{player}}</0>",
Expand Down Expand Up @@ -84,6 +86,7 @@
"youClaimedHit": "Du hast dir einen Hit genommen. Das war <0>{{title}}</0> von <1>{{artist}}</1> aus dem Jahr <2>{{year}}</2>. Der Hit stammt aus dem <3>{{pack}}</3> Pack.",
"youClaimedHitBelonging": "Du hast dir einen Hit genommen. Das war <0>{{title}}</0> von <1>{{artist}}</1> aus dem Jahr <2>{{year}}</2>. Der Hit ist bekannt aus <3>{{belongs_to}}</3> und stammt aus dem <4>{{pack}}</4> Pack.",
"skipHit": "Überspringe diesen Hit, indem du einen Chip bezahlst",
"skipHitShortcut": "Alt+Umschalt+I",
"skipHitNotGuessing": "Nur der Zugspieler kann einen Hit überspringen",
"skipHitNoToken": "Du musst einen Chip bezahlen können, um einen Hit zu überspringen",
"cannotSkipHit": "Du kannst derzeit keinen Hit überspringen",
Expand Down
3 changes: 3 additions & 0 deletions client/src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"noHitAvailable": "No hit available",
"stopHit": "Stop hit",
"playHit": "Play hit",
"playOrStopHit": "Play or stop hit",
"playOrStopHitShortcut": "Alt+Shift+H",
"and": "and",
"gameNotStarted": "The game hasn't started yet.",
"waitingForPlayerHeading_one": "You are waiting for <0>{{player}}</0> to make their move",
Expand Down Expand Up @@ -84,6 +86,7 @@
"youClaimedHit": "You claimed a hit. This was <0>{{title}}</0> by <1>{{artist}}</1> from <2>{{year}}</2>. This song belongs to the <3>{{pack}}</3> pack.",
"youClaimedHitBelonging": "You claimed a hit. This was <0>{{title}}</0> by <1>{{artist}}</1> from <2>{{year}}</2>. You might know this song from <3>{{belongs_to}}</3> and it belongs to the <3>{{pack}}</3> pack.",
"skipHit": "Skip this hit by paying one token",
"skipHitShortcut": "Alt+Shift+I",
"skipHitNotGuessing": "Only the guessing player can skip a hit",
"skipHitNoToken": "You need to pay a token to skip a hit",
"cannotSkipHit": "You cannot skip a hit right now",
Expand Down
39 changes: 32 additions & 7 deletions client/src/pages/game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ export function Game() {
return p && p.tokens >= 3
}

const skipHit = async () =>
await gameService.skip(
game.id,
game.mode === GameMode.Local
? game.players.find((p) => p.turn_player)?.id
: undefined,
)

useEffect(() => {
let eventSource = new EventSource(`/api/games/${game.id}/events`)

Expand Down Expand Up @@ -302,6 +310,11 @@ export function Game() {
setShowSettings(true)
},
}
let handleSkipHit = {
onPressed: () => {
skipHit()
},
}

if (!modalShown) {
bindKeyCombo("alt + shift + j", handleJoinGame)
Expand All @@ -316,13 +329,17 @@ export function Game() {
if (canStartOrStopGame()) {
bindKeyCombo("alt + shift + s", handleStartOrStopGame)
}
if (canSkip()) {
bindKeyCombo("alt + shift + i", handleSkipHit)
}
}

return () => {
unbindKeyCombo("alt + shift + j", handleJoinGame)
unbindKeyCombo("alt + shift + q", handleLeaveGame)
unbindKeyCombo("alt + shift + e", handleShowSettings)
unbindKeyCombo("alt + shift + s", handleStartOrStopGame)
unbindKeyCombo("alt + shift + i", handleSkipHit)
}
}, [game, user, modalShown])

Expand Down Expand Up @@ -569,18 +586,26 @@ export function Game() {
duration={
game.state === GameState.Confirming ? 0 : game.hit_duration
}
shortcut={t("playOrStopHitShortcut")}
/>
<Button
className="me-2"
disabled={!canSkip()}
onClick={async () =>
await gameService.skip(
game.id,
game.mode === GameMode.Local
? game.players.find((p) => p.turn_player)?.id
: undefined,
)
aria-keyshortcuts={canSkip() ? t("skipHitShortcut") : ""}
aria-label={
detect()?.name === "firefox"
? canSkip()
? `${t("skipHitShortcut")} ${t("skipHit")}`
: game.players.find((p) => p.id === user?.id)
?.state === PlayerState.Guessing
? t("skipHitNotGuessing")
: game.players.find((p) => p.id === user?.id)
?.tokens === 0
? t("skipHitNoToken")
: t("cannotSkipHit")
: ""
}
onClick={skipHit}
>
{canSkip()
? t("skipHit")
Expand Down
30 changes: 28 additions & 2 deletions client/src/pages/game/hit-player.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import EventManager from "@lomray/event-manager"
import { bindKeyCombo, unbindKeyCombo } from "@rwh/keystrokes"
import { useLocalStorage } from "@uidotdev/usehooks"
import { detect } from "detect-browser"
import { Howl } from "howler"
import {
forwardRef,
Expand All @@ -11,6 +13,7 @@ import {
import Button from "react-bootstrap/Button"
import { useTranslation } from "react-i18next"
import { Events, Sfx } from "../../events"
import { useModalShown } from "../../hooks"

interface HitPlayerTimers {
sfxTimer: ReturnType<typeof setTimeout> | null
Expand All @@ -22,6 +25,7 @@ export type HitPlayerProps = {
duration: number
onPlay?: () => void
autoplay?: boolean
shortcut?: string
}

export type HitPlayerRef = {
Expand All @@ -31,7 +35,7 @@ export type HitPlayerRef = {

export const HitPlayer = forwardRef<HitPlayerRef, HitPlayerProps>(
function HitPlayer(
{ src, duration, onPlay, autoplay }: HitPlayerProps,
{ src, duration, onPlay, autoplay, shortcut }: HitPlayerProps,
ref,
) {
let player = useRef<Howl | null>(null)
Expand All @@ -43,6 +47,7 @@ export const HitPlayer = forwardRef<HitPlayerRef, HitPlayerProps>(
let { t } = useTranslation()
let [volume] = useLocalStorage("musicVolume", "1.0")
let [sfxVolume] = useLocalStorage("sfxVolume", "1.0")
let modalShown = useModalShown()

const play = () => {
if (timers.current.stopTimer) {
Expand Down Expand Up @@ -122,7 +127,22 @@ export const HitPlayer = forwardRef<HitPlayerRef, HitPlayerProps>(
}
player.current = null
}
}, [src, playing])

let handlePlayOrStopHit = {
onPressed: () => {
if (playing) setPlaying(false)
else setPlaying(true)
},
}

if (shortcut !== undefined && src !== "" && !modalShown) {
bindKeyCombo("alt + shift + h", handlePlayOrStopHit)
}

return () => {
unbindKeyCombo("alt + shift + h", handlePlayOrStopHit)
}
}, [src, playing, shortcut, modalShown])

useEffect(() => {
player.current?.volume(parseFloat(volume))
Expand All @@ -148,6 +168,12 @@ export const HitPlayer = forwardRef<HitPlayerRef, HitPlayerProps>(
<Button
className="me-2"
disabled={src === ""}
aria-keyshortcuts={shortcut !== undefined ? shortcut : ""}
aria-label={
detect()?.name === "firefox" && shortcut !== undefined
? shortcut
: ""
}
onClick={() => {
if (playing === true) {
setPlaying(false)
Expand Down
10 changes: 9 additions & 1 deletion client/src/shortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function Shortcuts({
<td>{t("localGameShortcut")}</td>
</tr>
<tr>
<th rowSpan={22}>{t("game")}</th>
<th rowSpan={24}>{t("game")}</th>
</tr>
<tr>
<td>{t("joinGame")}</td>
Expand Down Expand Up @@ -93,6 +93,14 @@ export default function Shortcuts({
<td>{t("submitGuess")}</td>
<td>{t("submitGuessShortcut")}</td>
</tr>
<tr>
<td>{t("skipHit")}</td>
<td>{t("skipHitShortcut")}</td>
</tr>
<tr>
<td>{t("playOrStopHit")}</td>
<td>{t("playOrStopHitShortcut")}</td>
</tr>
{Array.from({ length: 10 }, (_, i) => (
<tr>
<td>
Expand Down

0 comments on commit 4773a4a

Please sign in to comment.