Skip to content

Commit

Permalink
feat: add translates
Browse files Browse the repository at this point in the history
  • Loading branch information
sanua356 committed Aug 10, 2024
1 parent 91a01b2 commit c44ebb3
Show file tree
Hide file tree
Showing 21 changed files with 321 additions and 57 deletions.
5 changes: 3 additions & 2 deletions src/entites/settings/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { setActivateSound, settingsReducer } from './model';
export type { TSettingsSliceState, TSettingsSliceStore } from './model';
export { useTranslates } from './lib';
export { changeCurrentLangugage, setActivateSound, settingsReducer } from './model';
export type { TAvailableLanguages, TSettingsSliceState, TSettingsSliceStore } from './model';
export { PlaySoundButton } from './ui';

1 change: 1 addition & 0 deletions src/entites/settings/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useTranslates } from './useTranslates';
146 changes: 146 additions & 0 deletions src/entites/settings/lib/translates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
export const TRANSLATES = {
startGame: {
'en-US': 'Start game',
'ru-RU': 'Начать игру',
},
rules: {
'en-US': 'About game',
'ru-RU': 'Об игре',
},
authors: {
'en-US': 'About authors',
'ru-RU': 'Об авторах',
},
authorsSubtitle: {
'en-US': 'INFORMATION ABOUT THE AUTHORS',
'ru-RU': 'ИНФОРМАЦИЯ О АВТОРАХ',
},
authorsTitle: {
'en-US': 'Authors',
'ru-RU': 'Авторы',
},
authorsNoofficial: {
'en-US': 'THIS IS AN UNOFFICIAL PROJECT! THE AUTHORS OF THE VISUAL NOVEL HAVE NOTHING TO DO WITH THIS PROJECT!',
'ru-RU': 'ЭТО НЕОФИЦИАЛЬНЫЙ ПРОЕКТ! АВТОРЫ ВИЗУАЛЬНОЙ НОВЕЛЛЫ НЕ ИМЕЮТ К ДАННОМУ ПРОЕКТУ НИКАКОГО ОТНОШЕНИЯ!',
},
authorsDescription: {
'en-US': 'All audiovisual intellectual property belongs to the author of the visual novel:',
'ru-RU': 'Вся аудиовизуальная интеллектуальная собственность принадлежит автору визуальной новеллы:',
},
authorsSubdescription: {
'en-US': '"IP Startsev Anton Yurievich"',
'ru-RU': '"ИП Старцев Антон Юрьевич"',
},
authorNovelButtonLink: {
'en-US': 'Link to the author of the visual novel:',
'ru-RU': 'Ссылка на автора визуальной новеллы:',
},
authorProjectButtonLink: {
'en-US': 'Link to the developer of this project:',
'ru-RU': 'Ссылка на разаботчика этого проекта:',
},
rulesSubtitle: {
'en-US': 'RULES OF THE GAME',
'ru-RU': 'ПРАВИЛА ИГРЫ',
},
rulesTitle: {
'en-US': 'About the game',
'ru-RU': 'Об игре',
},
rulesDescription1: {
'en-US': 'This is a classic card game called "21 points". There are 11 cards in the deck, with values ​​ranging from 2 to 11. The player must score more points than the opponent, but not more than 21.',
'ru-RU': 'Это классическая карточная игра "21 очко". В колоде имеется 11 карт номиналом от 2 до 11. Игроку необходимо набрать больше очков, чем у оппонента, но не более 21.',
},
rulesDescription2: {
'en-US': 'If a player or a player and an opponent score more than 21 points, they are automatically considered losers.',
'ru-RU': 'Если игрок или игрок и оппонент набрали более 21 очка, они автоматически считаются проигравшими.',
},
rulesDescription3: {
'en-US': 'If both the player and the opponent score more than 21 points, or they both score the same number of points, the game ends in a draw.',
'ru-RU': 'Если и игрок и оппонент набрали более 21 очка, либо они оба набрали одинаковое количество очков, игра заканчивается ничьей.',
},
moreTventyOne: {
'en-US': 'You have 21 or more points. You cannot take more cards. Pass the turn to your opponent.',
'ru-RU': 'У Вас равно или более 21 очка. Больше карт взять нельзя. Передайте ход оппоненту.',
},
nextStepButton: {
'en-US': 'Pass the move',
'ru-RU': 'Передать ход',
},
getCardButton: {
'en-US': 'Take a card',
'ru-RU': 'Взять карту',
},
endGameButton: {
'en-US': 'Show cards',
'ru-RU': 'Вскрыть карты',
},
sum: {
'en-US': 'Sum',
'ru-RU': 'Сумма',
},
gameStage: {
'en-US': 'Game stage:',
'ru-RU': 'Стадия игры:',
},
cardsAvailable: {
'en-US': 'Cards remaining:',
'ru-RU': 'Осталось карт:',
},
cardsUnits: {
'en-US': 'pcs.',
'ru-RU': 'шт.',
},
gameResults: {
'en-US': 'GAME RESULTS',
'ru-RU': 'РЕЗУЛЬТАТЫ ИГРЫ',
},
repeatGameButton: {
'en-US': 'Repeat the game',
'ru-RU': 'Повторить игру',
},
goHomeButton: {
'en-US': 'Go home',
'ru-RU': 'На главную',
},
playerWinnerTitle: {
'en-US': 'Win!',
'ru-RU': 'Победа!',
},
playerWinnerDescription: {
'en-US': 'You beat the forest master! Want to play again?',
'ru-RU': 'Вы обыграли хозяниа леса! Хотите повторить игру?',
},
opponentWinnerTitle: {
'en-US': 'Lose',
'ru-RU': 'Поражение',
},
opponentWinnerDescription: {
'en-US': 'The forest master has beaten you! Do you want to play again?',
'ru-RU': 'Хозяин леса обыграл Вас! Хотите повторить игру?',
},
drawWinnerTitle: {
'en-US': 'Draw',
'ru-RU': 'Ничья',
},
drawWinnerDescription: {
'en-US': 'There is no winner in this game! Do you want to play again?',
'ru-RU': 'В данной партии нет победителя! Хотите повторить игру?',
},
emptyTranslate: {
'en-US': '',
'ru-RU': '',
},
playerStep: {
'en-US': 'Player step',
'ru-RU': 'Ход игрока',
},
opponentStep: {
'en-US': 'Opponent step',
'ru-RU': 'Ход оппонента',
},
endGameStep: {
'en-US': 'Show results',
'ru-RU': 'Показ результатов',
},
}
27 changes: 27 additions & 0 deletions src/entites/settings/lib/useTranslates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useSelector } from "react-redux";
import { TAvailableLanguages, TSettingsSliceStore } from "../model";
import { TRANSLATES } from "./translates";

type TResponse = {
currentLanguage: TAvailableLanguages;
t: (key: string) => string;
}

export const useTranslates = (): TResponse => {
const currentLanguage = useSelector<TSettingsSliceStore>((state) => state.sound.currentLanguage) as TAvailableLanguages;

const t = (key: string): string => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const keyset = (TRANSLATES as any)[key];
if (keyset[currentLanguage]) {
return keyset[currentLanguage];
} else {
return keyset['ru-RU'];
}
};

return {
currentLanguage,
t
}
}
4 changes: 2 additions & 2 deletions src/entites/settings/model/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { setActivateSound, default as settingsReducer } from './settings.slice';
export { changeCurrentLangugage, setActivateSound, default as settingsReducer } from './settings.slice';
export type { TSettingsSliceState } from './settings.slice';
export type { TSettingsSliceStore } from './types';
export type { TAvailableLanguages, TSettingsSliceStore } from './types';

23 changes: 22 additions & 1 deletion src/entites/settings/model/settings.slice.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
import { createSlice } from '@reduxjs/toolkit';

import { TAvailableLanguages } from './types';

export type TSettingsSliceState = {
isActivatedSound: boolean;
currentLanguage: TAvailableLanguages;
}

const getCurrentLang = () => {
const savedLang = localStorage.getItem('current_language');
if (savedLang) {
return savedLang as TAvailableLanguages;
}
let language = window.navigator.language;
if (language !== 'ru-RU' && language !== 'en-US') {
language = 'en-US';
}
localStorage.setItem('current_language', language);
return language as TAvailableLanguages;
}

const initialState: TSettingsSliceState = {
isActivatedSound: localStorage.getItem('sound_is_activated') === 'true',
currentLanguage: getCurrentLang(),
}

const settingsSlice = createSlice({
Expand All @@ -16,8 +33,12 @@ const settingsSlice = createSlice({
state.isActivatedSound = action.payload;
localStorage.setItem('sound_is_activated', String(action.payload));
},
changeCurrentLangugage(state, action) {
state.currentLanguage = action.payload;
localStorage.setItem('current_language', String(action.payload));
}
},
})

export const { setActivateSound } = settingsSlice.actions;
export const { setActivateSound, changeCurrentLangugage } = settingsSlice.actions;
export default settingsSlice.reducer;
2 changes: 2 additions & 0 deletions src/entites/settings/model/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ import { TSettingsSliceState } from "./settings.slice";
export type TSettingsSliceStore = ReturnType<Reducer<{
sound: TSettingsSliceState;
}>>

export type TAvailableLanguages = 'ru-RU' | 'en-US';
16 changes: 8 additions & 8 deletions src/pages/game/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,26 @@ export enum GameWinners {

export const END_GAME_STATE = {
[GameWinners.Player]: {
title: 'Победа!',
description: 'Вы обыграли хозяниа леса! Хотите повторить игру?',
title: 'playerWinnerTitle',
description: 'playerWinnerDescription',
images: [win1, win2, win3, win4],
sounds: [win1sound, win2sound, win3sound, win4sound, win5sound],
},
[GameWinners.Opponent]: {
title: 'Поражение',
description: 'Хозяин леса обыграл Вас! Хотите повторить игру?',
title: 'opponentWinnerTitle',
description: 'opponentWinnerDescription',
images: [lose1, lose2, lose3, lose4],
sounds: [lose1sound, lose2sound, lose3sound, lose4sound, lose5sound, lose6sound],
},
[GameWinners.Draw]: {
title: 'Ничья',
description: 'В данной партии нет победителя! Хотите повторить игру?',
title: 'drawWinnerTitle',
description: 'drawWinnerDescription',
images: [draw1],
sounds: [draw1sound, draw2sound, draw3sound],
},
[GameWinners.Nobody]: {
title: '',
description: '',
title: 'emptyTranslate',
description: 'emptyTranslate',
images: [],
sounds: [],
}
Expand Down
6 changes: 3 additions & 3 deletions src/pages/game/model/desk.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { GameStatuses, GameWinners, shuffleArray } from '../lib';
import { TGameStatus, TWinnerGame } from './types';

export const GAME_STEP_TRANSLATE = {
[GameStatuses.StepPlayer]: 'Ход игрока',
[GameStatuses.StepOpponent]: 'Ход оппонента',
[GameStatuses.End]: 'Показ результатов',
[GameStatuses.StepPlayer]: 'playerStep',
[GameStatuses.StepOpponent]: 'opponentStep',
[GameStatuses.End]: 'endGameStep',
}

export type TDeskSliceState = {
Expand Down
14 changes: 8 additions & 6 deletions src/pages/game/ui/endGameModal/EndGameModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';

import { HatchButton } from '@/entites/hatchButton';
import { TSettingsSliceStore } from '@/entites/settings';
import { TSettingsSliceStore, useTranslates } from '@/entites/settings';
import endGameSound from '@/shared/assets/sounds/end_game.ogg';
import { Modal } from '@/shared/ui/Modal';

Expand All @@ -17,6 +17,8 @@ export const EndGameModal = () => {
const dispatch = useDispatch();
const navigate = useNavigate();

const { t } = useTranslates();

const gameWinner = useSelector<TDeskSliceStore>((state) => state.desk.winner) as TWinnerGame;
const isActivatedSound = useSelector<TSettingsSliceStore>((state) => state.sound.isActivatedSound) as boolean;

Expand Down Expand Up @@ -66,21 +68,21 @@ export const EndGameModal = () => {
>
<div className={s.winner}>
<div className={s.info}>
<span className={s.subtitle}>РЕЗУЛЬТАТЫ ИГРЫ</span>
<h2 className={s.title}>{winnerData.title}</h2>
<span className={s.description}>{winnerData.description}</span>
<span className={s.subtitle}>{t('gameResults')}</span>
<h2 className={s.title}>{t(winnerData.title)}</h2>
<span className={s.description}>{t(winnerData.description)}</span>
<div className={s.buttons}>
<HatchButton
onClick={onRefreshGameHandler}
hoverSound={isActivatedSound ? endGameSound : undefined}
>
Повторить игру
{t('repeatGameButton')}
</HatchButton>
<HatchButton
onClick={onHomePageHandler}
hoverSound={isActivatedSound ? endGameSound : undefined}
>
На главную
{t('goHomeButton')}
</HatchButton>
</div>
</div>
Expand Down
12 changes: 7 additions & 5 deletions src/pages/game/ui/playerActions/PlayerActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { toast } from 'react-toastify';

import { TGameCard } from '@/entites/gameCards';
import { HatchButton } from '@/entites/hatchButton';
import { TSettingsSliceStore } from '@/entites/settings';
import { TSettingsSliceStore, useTranslates } from '@/entites/settings';
import getCardSound from '@/shared/assets/sounds/get_card.ogg';
import hoverSound from '@/shared/assets/sounds/hover.ogg';
import nextStepSound from '@/shared/assets/sounds/next_step.ogg';
Expand All @@ -23,6 +23,8 @@ import s from './PlayerActions.module.css';
export const PlayerActions = () => {
const dispatch = useDispatch();

const { t } = useTranslates();

const gameStatus = useSelector<TDeskSliceStore>((state) => state.desk.status) as TGameStatus;
const unusedCards = useSelector<TDeskSliceStore>((state) => state.desk.unusedCards) as TGameCard[];
const playerCards = useSelector<TDeskSliceStore>((state) => state.desk.playerCards) as TGameCard[];
Expand Down Expand Up @@ -52,7 +54,7 @@ export const PlayerActions = () => {
const onGetCardHandler = () => {
const playerCardsAmount = playerCards.reduce((acc, card) => acc + card.value, 0);
if (playerCardsAmount >= 21) {
toast("У Вас равно или более 21 очка. Больше карт взять нельзя. Передайте ход оппоненту.");
toast(t('moreTventyOne'));
return;
}
dispatch(getCard());
Expand All @@ -72,7 +74,7 @@ export const PlayerActions = () => {
clickSound={isActivatedSound ? nextStepSound : undefined}
hoverSound={isActivatedSound ? hoverSound : undefined}
>
Передать ход
{t('nextStepButton')}
</HatchButton>
<HatchButton
className={s.button}
Expand All @@ -81,7 +83,7 @@ export const PlayerActions = () => {
clickSound={isActivatedSound ? getCardSound : undefined}
hoverSound={isActivatedSound ? hoverSound : undefined}
>
Взять карту
{t('getCardButton')}
</HatchButton>
<HatchButton
className={s.button}
Expand All @@ -90,7 +92,7 @@ export const PlayerActions = () => {
clickSound={isActivatedSound ? viewCardsSound : undefined}
hoverSound={isActivatedSound ? hoverSound : undefined}
>
Вскрыть карты
{t('endGameButton')}
</HatchButton>
</div>
)
Expand Down
Loading

0 comments on commit c44ebb3

Please sign in to comment.