Skip to content

Commit

Permalink
show victory reason (#84); add copy button; fix all unusable tip
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchen committed Feb 6, 2025
1 parent 76b7089 commit 25b9007
Show file tree
Hide file tree
Showing 24 changed files with 284 additions and 69 deletions.
4 changes: 2 additions & 2 deletions __test__/components/Pref.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ it('renders Pref', () => {
target: { value: '4b0e835d-002f-4478-8d89-e384f19cd999' },
})
const buttonConnect = screen.find('div.multiplayer button')
expect(buttonConnect.length).toBe(1)
buttonConnect.simulate('click')
expect(buttonConnect.length).toBe(2)
buttonConnect.at(0).simulate('click')
const buttonsResetApply = screen.find('div.button-wrapper button')
expect(buttonsResetApply.length > 0).toBeTruthy()
buttonsResetApply.forEach((button) => {
Expand Down
12 changes: 10 additions & 2 deletions src/components/TableP.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ const TableP = () => {
const cardsInHand = useAppSelector((state) => state.settings.cardsInHand)
const discardMode = useAppSelector((state) => state.game.discardMode)

const playersTurn = useAppSelector((state) => state.game.playersTurn)
const locked = useAppSelector((state) => state.game.locked).some(
(l) => l === true,
)

const size = useContext(GameSizeContext)
const winHeight = size.height
const winWidth = size.width
Expand Down Expand Up @@ -56,8 +61,11 @@ const TableP = () => {
winWidth={winWidth}
>
<TooltipAll
// TODO allUnusableTip should only be shown when player is able to select card
title={allUnusable && !discardMode ? _.i18n('allUnusableTip') : ''}
title={
allUnusable && playersTurn && !locked && !discardMode
? _.i18n('allUnusableTip')
: ''
}
placement="top"
enterTouchDelay={0}
>
Expand Down
20 changes: 15 additions & 5 deletions src/components/screens/EndScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CLOSE_SCREEN_END_INIT } from '../../constants/ActionTypes'
import useKeyDown from '../../utils/hooks/gamecontrols/useKeyDown'
import { endScreenExitableDelay } from '../../constants/visuals'
import { EndScreenNoCloseStateType } from '../../types/state'
import { reasonTranslate } from '../../utils/checkVictory'
// import { GameSizeContext } from '../../utils/contexts/GameSizeContext'

const textMap = { lose: 'You Lose!', tie: 'Tie Game', win: 'You Win!' }
Expand Down Expand Up @@ -96,8 +97,8 @@ const useStyles = createUseStyles<string, EndScreenNoCloseStateType>({
notetext: {
top: '62%',
height: '5em',
'font-size': '5vh',
'line-height': '5vh',
'font-size': '4vh',
'line-height': '4vh',
},

text: {
Expand Down Expand Up @@ -128,7 +129,7 @@ const EndScreen = (endScreenState: EndScreenNoCloseStateType) => {
const _ = useContext(I18nContext)
const classes = useStyles(endScreenState)

const { type, surrender } = endScreenState
const { type, surrender, reasons } = endScreenState

// const size = useContext(GameSizeContext)

Expand All @@ -145,7 +146,17 @@ const EndScreen = (endScreenState: EndScreenNoCloseStateType) => {
)

let noteText: string | null = null
if (surrender) {
if (reasons) {
const reasonTexts = [
...(reasons.win
? reasons.win.map((reason) => reasonTranslate(reason, true, _))
: []),
...(reasons.lose
? reasons.lose.map((reason) => reasonTranslate(reason, false, _))
: []),
]
noteText = reasonTexts.join(_.i18n('. '))
} else if (surrender) {
switch (type) {
case 'win':
noteText = _.i18n(
Expand Down Expand Up @@ -252,5 +263,4 @@ const EndScreen = (endScreenState: EndScreenNoCloseStateType) => {
</div>
)
}

export default memo(EndScreen)
42 changes: 17 additions & 25 deletions src/components/screens/Pref.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ const Pref = () => {
const _ = useContext(I18nContext)
const dispatch = useAppDispatch()

const copied = useRef<HTMLDivElement | null>(null)
const yourIdInputRef = useRef<HTMLInputElement>(null)
const copiedTimer = useRef<NodeJS.Timeout | null>(null)
const [copied, setCopied] = useState<boolean>(false)

const isMultiplayer = useAppSelector((state) => state.multiplayer.on)
const yourId = useAppSelector((state) => state.multiplayer.yourId)
Expand Down Expand Up @@ -757,6 +758,7 @@ const Pref = () => {
{_.i18n(': ')}
</span>
<input
ref={yourIdInputRef}
type="text"
name="yourId"
id="yourId"
Expand All @@ -768,38 +770,28 @@ const Pref = () => {
target.select()
copy(target.value)
.then(() => {
if (copied.current !== null) {
copied.current.classList.add('copied-shown')
if (copiedTimer.current !== null) {
clearTimeout(copiedTimer.current)
}
copiedTimer.current = setTimeout(() => {
if (copied.current !== null) {
copied.current.classList.remove('copied-shown')
}
}, copiedDuration)
setCopied(true)
if (copiedTimer.current !== null) {
clearTimeout(copiedTimer.current)
}
copiedTimer.current = setTimeout(() => {
setCopied(false)
}, copiedDuration)
})
.catch((error) => {
console.error('Failed to copy text: ', error)
})
if (copied.current !== null) {
copied.current.classList.add('copied-shown')
if (copiedTimer.current !== null) {
clearTimeout(copiedTimer.current)
}
copiedTimer.current = setTimeout(() => {
if (copied.current !== null) {
copied.current.classList.remove('copied-shown')
}
}, copiedDuration)
}
}
}}
/>
<span ref={copied} className="copied emoji">
{_.i18n('Copied 📋✅')}
</span>
<button
disabled={!isMultiplayer}
onClick={() => {
yourIdInputRef.current?.click()
}}
>
{copied ? _.i18n('Copied 📋✅') : _.i18n('Copy')}
</button>
</label>
</div>
<div className="multiplayer">
Expand Down
1 change: 1 addition & 0 deletions src/epics/game_general/checkSurrenderEpic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ export default (
}
}),
)
// TODO: fix: multiplayer mode, opponent surrenders, game freezes
27 changes: 4 additions & 23 deletions src/epics/game_general/checkVictoryEpic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { withLatestFrom, filter, mergeMap, takeUntil } from 'rxjs/operators'
import { isOfType } from 'typesafe-actions'
import { ofType, StateObservable } from 'redux-observable'
import { RootStateType } from '../../types/state'
import { resNames } from '../../constants/resourceNames'
import { EMPTY, Observable, of } from 'rxjs'
import { getWinState } from '../../utils/startWinState'
import { checkVictory } from '../../utils/checkVictory'

export default (
action$: Observable<RootActionType>,
Expand All @@ -23,31 +23,12 @@ export default (
const { winTower, winResource } = getWinState(state.settings)
const { player, opponent } = state.status

const playerWin =
player.tower >= winTower ||
opponent.tower <= 0 ||
resNames.some((resName) => player[resName] >= winResource)
const opponentWin =
opponent.tower >= winTower ||
player.tower <= 0 ||
resNames.some((resName) => opponent[resName] >= winResource)
const res = checkVictory(player, opponent, winTower, winResource)

if (playerWin && !opponentWin) {
if (res) {
return of<RootActionType>({
type: SCREEN_END,
payload: { type: 'win' },
}).pipe(takeUntil(action$.pipe(ofType(ABORT_ALL))))
}
if (!playerWin && opponentWin) {
return of<RootActionType>({
type: SCREEN_END,
payload: { type: 'lose' },
}).pipe(takeUntil(action$.pipe(ofType(ABORT_ALL))))
}
if (playerWin && opponentWin) {
return of<RootActionType>({
type: SCREEN_END,
payload: { type: 'tie' },
payload: res,
}).pipe(takeUntil(action$.pipe(ofType(ABORT_ALL))))
}

Expand Down
6 changes: 6 additions & 0 deletions src/i18n/main/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export const i18n = {
'You Win!': 'فزت!',
'You Lose!': 'خسرت!',
'Tie Game': 'لعبة التعادل',
'%s has reached the victory condition': 'لقد وصل %s إلى حالة النصر', // %s = 'Your tower', "Opponent's tower"
'%s have reached the victory condition': 'لقد وصل %s إلى حالة النصر', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ...
'Your opponent has no tower left': 'لم يتبق لخصمك أي برج',
'You have no tower left': 'لم يتبق لك أي برج',
'. ': '. ',
Preferences: 'التفضيلات',
': ': ':',
'Your Name': 'اسمك',
Expand Down Expand Up @@ -60,6 +65,7 @@ export const i18n = {
'Your ID': 'معرفك',
"Enter your opponent's ID": 'أدخل معرف خصمك',
Connect: 'الاتصال',
Copy: 'نسخ',
'Copied 📋✅': 'تم النسخ 📋✅',
'Connecting to the network ⌛': 'الاتصال بالشبكة ⌛',
'Connected to the network (but not to anyone) 🟡':
Expand Down
8 changes: 8 additions & 0 deletions src/i18n/main/cs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ export const i18n = {
'You Lose!': 'Prohrál jsi!',
'Tie Game': 'Remízová hra',

'%s has reached the victory condition': '%s dosáhla vítězné podmínky', // %s = 'Your tower', "Opponent's tower"
'%s have reached the victory condition': '%s dosáhly vítězné podmínky', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ...
'Your opponent has no tower left': 'Vašemu protivníkovi nezbyla žádná věž',
'You have no tower left': 'Nezbyla ti žádná věž',

'. ': '. ',

Preferences: 'Předvolby',
': ': ': ',
'Your Name': 'Vaše jméno',
Expand Down Expand Up @@ -80,6 +87,7 @@ export const i18n = {
'Your ID': 'Vaše ID',
"Enter your opponent's ID": 'Zadejte ID soupeře',
Connect: 'Připojit',
Copy: 'Kopie',
'Copied 📋✅': 'Zkopírováno 📋✅',

'Connecting to the network ⌛': 'Připojení k síti ⌛',
Expand Down
9 changes: 9 additions & 0 deletions src/i18n/main/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ export const i18n = {
'You Lose!': 'Sie verlieren!',
'Tie Game': 'Unentschieden Spiel',

'%s has reached the victory condition': '%s hat die Siegbedingung erreicht', // %s = 'Your tower', "Opponent's tower"
'%s have reached the victory condition':
'%s haben die Siegbedingung erreicht', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ...
'Your opponent has no tower left': 'Ihr Gegner hat keinen Turm mehr',
'You have no tower left': 'Sie haben keinen Turm mehr',

'. ': '. ',

Preferences: 'Voreinstellungen',
': ': ': ',
'Your Name': 'Ihr Name',
Expand Down Expand Up @@ -80,6 +88,7 @@ export const i18n = {
'Your ID': 'Ihre ID',
"Enter your opponent's ID": 'Geben Sie die ID Ihres Gegners ein',
Connect: 'Verbinden',
Copy: 'Kopieren',
'Copied 📋✅': 'Kopiert 📋✅',

'Connecting to the network ⌛': 'Verbindung zum Netzwerk herstellen ⌛',
Expand Down
10 changes: 10 additions & 0 deletions src/i18n/main/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const i18n = {
'You Lose!': 'You Lose!',
'Tie Game': 'Tie Game',

'%s has reached the victory condition':
'%s has reached the victory condition', // %s = 'Your tower', "Opponent's tower"
'%s have reached the victory condition':
'%s have reached the victory condition', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ...
'Your opponent has no tower left': 'Your opponent has no tower left',
'You have no tower left': 'You have no tower left',

'. ': '. ',

Preferences: 'Preferences',
': ': ': ',
'Your Name': 'Your Name',
Expand Down Expand Up @@ -80,6 +89,7 @@ export const i18n = {
'Your ID': 'Your ID',
"Enter your opponent's ID": "Enter your opponent's ID",
Connect: 'Connect',
Copy: 'Copy',
'Copied 📋✅': 'Copied 📋✅',

'Connecting to the network ⌛': 'Connecting to the network ⌛',
Expand Down
10 changes: 10 additions & 0 deletions src/i18n/main/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const i18n = {
'You Lose!': '¡Tú pierdes!',
'Tie Game': 'Juego empatado',

'%s has reached the victory condition':
'%s ha alcanzado la condición de victoria', // %s = 'Your tower', "Opponent's tower"
'%s have reached the victory condition':
'%s han alcanzado la condición de victoria', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ...
'Your opponent has no tower left': 'A tu oponente no le quedan torres',
'You have no tower left': 'A ti no te quedan torres',

'. ': '. ',

Preferences: 'Preferencias',
': ': ': ',
'Your Name': 'Tu nombre',
Expand Down Expand Up @@ -80,6 +89,7 @@ export const i18n = {
'Your ID': 'Tu ID',
"Enter your opponent's ID": 'Introduce el ID de tu oponente',
Connect: 'Conectar',
Copy: 'Copiar',
'Copied 📋✅': 'Copiado 📋✅',

'Connecting to the network ⌛': 'Conectando a la red ⌛',
Expand Down
10 changes: 10 additions & 0 deletions src/i18n/main/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const i18n = {
'You Lose!': 'Vous avez perdu',
'Tie Game': 'Match nul',

'%s has reached the victory condition':
'%s a atteint la condition de victoire', // %s = 'Your tower', "Opponent's tower"
'%s have reached the victory condition':
'%s ont atteint la condition de victoire', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ...
'Your opponent has no tower left': 'Votre adversaire n’a plus de tour',
'You have no tower left': 'Vous n’avez plus de tour',

'. ': '. ',

Preferences: 'Préférences',
': ': '\u00A0: ',
'Your Name': 'Votre nom',
Expand Down Expand Up @@ -80,6 +89,7 @@ export const i18n = {
'Your ID': 'Votre ID',
"Enter your opponent's ID": 'Entrez l’ID de votre adversaire',
Connect: 'Connectez',
Copy: 'Copier',
'Copied 📋✅': 'Copié 📋✅',

'Connecting to the network ⌛': 'Connexion au réseau en cours ⌛',
Expand Down
10 changes: 10 additions & 0 deletions src/i18n/main/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const i18n = {
'You Lose!': 'Tu perdi!',
'Tie Game': 'Gioco del pareggio',

'%s has reached the victory condition':
'%s ha raggiunto la condizione di vittoria', // %s = 'Your tower', "Opponent's tower"
'%s have reached the victory condition':
'%s hanno raggiunto la condizione di vittoria', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ...
'Your opponent has no tower left': 'Il tuo avversario non ha più torri',
'You have no tower left': 'Tu non hai più torri',

'. ': '. ',

Preferences: 'Preferenze',
': ': ': ',
'Your Name': 'Il tuo nome',
Expand Down Expand Up @@ -80,6 +89,7 @@ export const i18n = {
'Your ID': 'Il tuo ID',
"Enter your opponent's ID": "Inserisci l'ID del tuo avversario",
Connect: 'Collega',
Copy: 'Copia',
'Copied 📋✅': 'Copiato 📋✅',

'Connecting to the network ⌛': 'Connettendo alla rete ⌛',
Expand Down
8 changes: 8 additions & 0 deletions src/i18n/main/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ export const i18n = {
'You Lose!': '負け!',
'Tie Game': '引き分け',

'%s has reached the victory condition': '%sは勝利条件に達しました', // %s = 'Your tower', "Opponent's tower"
'%s have reached the victory condition': '%sは勝利条件に達しました', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ...
'Your opponent has no tower left': '対戦相手にはタワーが残っていません',
'You have no tower left': 'あなたにはタワーが残っていません',

'. ': '。',

Preferences: '設定',
': ': ':',
'Your Name': 'あなたの名前',
Expand Down Expand Up @@ -79,6 +86,7 @@ export const i18n = {
'Your ID': 'あなたのID',
"Enter your opponent's ID": '相手のIDを入力する',
Connect: '接続',
Copy: 'コピー',
'Copied 📋✅': 'コピー済み 📋✅',

'Connecting to the network ⌛': 'ネットワークに接続する ⌛',
Expand Down
Loading

0 comments on commit 25b9007

Please sign in to comment.