(refactor) add i18n to frontend and refactor
This commit is contained in:
parent
02277287d0
commit
66b61215c1
@ -2,3 +2,4 @@ export * from './models/index'
|
||||
export * from './rtmt/index'
|
||||
export * from './theme/index'
|
||||
export * from './storage/storage'
|
||||
export * from './localization/index'
|
||||
40
core/src/localization/en.ts
Normal file
40
core/src/localization/en.ts
Normal file
@ -0,0 +1,40 @@
|
||||
export const en = {
|
||||
Mancala: "Mancala",
|
||||
Leave: "Leave The Game",
|
||||
NewGame: "New Game",
|
||||
YourTurn: "Your Turn",
|
||||
OpponentTurn: "Opponent Turn",
|
||||
GameEnded: "Game Ended",
|
||||
InternalErrorOccurred: "An internal error has occurred",
|
||||
YouWon: "You Won",
|
||||
Won: "Won",
|
||||
YouLost: "You Lost",
|
||||
Connecting: "Connecting",
|
||||
Connected: "Connected",
|
||||
CannotConnect: "Can't Connect",
|
||||
ConnectionLost: "Network Connection Lost",
|
||||
ConnectingAgain: "Connecting Again",
|
||||
ServerError: "Server Error",
|
||||
SearchingOpponet: "Searching Opponet",
|
||||
OpponentLeftTheGame: "Opponent Leaves The Game",
|
||||
YouLeftTheGame: "You Left The Game",
|
||||
UserLeftTheGame: "Left The Game",
|
||||
SearchingOpponent: "Searching Opponent",
|
||||
PleaseWait: "Please Wait",
|
||||
GameDraw: "Draw",
|
||||
Anonymous: "Anonymous",
|
||||
GameNotFound: "Game Not Found",
|
||||
Loading: "Loading",
|
||||
Playing: "Playing",
|
||||
Error: "Error",
|
||||
ErrorWhenRetrievingInformation: "An error occured when retrieving information!",
|
||||
UCanOnlyPlayYourOwnPits: "You can only play your own pits",
|
||||
UMustWaitUntilCurrentMoveComplete: "You must wait until the current move is complete",
|
||||
UCanNotPlayEmptyPit: "You can not play empty pit",
|
||||
AreYouSureToLeaveGame: "Are you sure to leave game?",
|
||||
Yes: "Yes",
|
||||
Cancel: "Cancel",
|
||||
Help: "Help",
|
||||
WebApp: "Goto WebApp",
|
||||
Privacy: "Open Privacy Policy"
|
||||
}
|
||||
2
core/src/localization/index.ts
Normal file
2
core/src/localization/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './en'
|
||||
export * from './tr'
|
||||
40
core/src/localization/tr.ts
Normal file
40
core/src/localization/tr.ts
Normal file
@ -0,0 +1,40 @@
|
||||
export const tr = {
|
||||
Mancala: "Köçürme",
|
||||
Leave: "Oyundan Ayrıl",
|
||||
NewGame: "Yeni Oyun",
|
||||
YourTurn: "Sıra Sende",
|
||||
OpponentTurn: "Sıra Rakipte",
|
||||
GameEnded: "Oyun Bitti",
|
||||
InternalErrorOccurred: "Dahili bir hata oluştu",
|
||||
YouWon: "Kazandın",
|
||||
Won: "Kazandı",
|
||||
YouLost: "Kaybettin",
|
||||
Connecting: "Bağlanılıyor",
|
||||
Connected: "Bağlandı",
|
||||
CannotConnect: "Bağlanılamadı",
|
||||
ConnectionLost: "Ağ Bağlantısı Koptu",
|
||||
ConnectingAgain: "Tekrar Bağlanılıyor",
|
||||
ServerError: "Sunucu Hatası",
|
||||
SearchingOpponet: "Rakip Aranıyor",
|
||||
OpponentLeftTheGame: "Rakip Oyundan Ayrıldı",
|
||||
YouLeftTheGame: "Sen Oyundan Ayrıldın",
|
||||
UserLeftTheGame: "Oyundan Ayrıldı",
|
||||
SearchingOpponent: "Rakip Aranıyor",
|
||||
PleaseWait: "Lütfen Bekleyin",
|
||||
GameDraw: "Berabere",
|
||||
Anonymous: "Anonim",
|
||||
GameNotFound: "Oyun Bulunamadı",
|
||||
Loading: "Yükleniyor",
|
||||
Playing: "Oynuyor",
|
||||
Error: "Hata",
|
||||
ErrorWhenRetrievingInformation: "Bilgiler toplanırken bir hata oluştu!",
|
||||
UCanOnlyPlayYourOwnPits: "Sadece sana ait olan kuyular ile oynayabilirsin",
|
||||
UMustWaitUntilCurrentMoveComplete: "Devam eden haraketin bitmesini beklemelisin",
|
||||
UCanNotPlayEmptyPit: "Boş kuyu ile oynayamazsın",
|
||||
AreYouSureToLeaveGame: "Oyundan ayrılmak istediğine emin misin?",
|
||||
Yes: "Evet",
|
||||
Cancel: "İptal",
|
||||
Help: "Yardım",
|
||||
WebApp: "Web Uygulamasına Git",
|
||||
Privacy: "Gizlilik Politikasını Göster"
|
||||
};
|
||||
@ -2,5 +2,6 @@ import * as React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
const container = document.getElementById('main');
|
||||
const root = createRoot(container!);
|
||||
import './localization/i18n';
|
||||
import MancalaApp from './MancalaApp';
|
||||
root.render(<MancalaApp/>);
|
||||
@ -12,17 +12,20 @@ import Home from './routes/Home';
|
||||
import { initContext } from './context/context';
|
||||
import { RTMTWS, ConnectionState } from '@mancala/core';
|
||||
import { getColorByBrightness } from './util/ColorUtil';
|
||||
import { Theme } from './theme/Theme';
|
||||
import { Theme } from '@mancala/core';
|
||||
import LobyPage from './routes/LobyPage';
|
||||
import PrivacyPage from './routes/PrivacyPage';
|
||||
import swal from 'sweetalert';
|
||||
import Util from './util/Util';
|
||||
import { server } from './const/config';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const context = initContext();
|
||||
|
||||
const MancalaApp: FunctionComponent = () => {
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [userKey, setUserKey] = useState<string | undefined>(undefined);
|
||||
|
||||
const [connectionState, setConnetionState] = useState<ConnectionState>("connecting");
|
||||
@ -50,7 +53,7 @@ const MancalaApp: FunctionComponent = () => {
|
||||
connectRTMT(userKey);
|
||||
}).catch((error) => {
|
||||
//TODO: check if it is network error!
|
||||
swal(context.texts.Error + "!", context.texts.ErrorWhenRetrievingInformation, "error");
|
||||
swal(t("Error") + "!", t("ErrorWhenRetrievingInformation"), "error");
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
@ -88,7 +91,7 @@ const MancalaApp: FunctionComponent = () => {
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
<FloatingPanel context={context} color={context.themeManager.theme.boardColor} visible={connectionState != "connected"}>
|
||||
<span style={{ color: textColorOnBoard, transition: 'color 0.5s' }}>{Util.getTextByConnectionState(context, connectionState)}</span>
|
||||
<span style={{ color: textColorOnBoard, transition: 'color 0.5s' }}>{Util.getTextByConnectionState(context, connectionState, t)}</span>
|
||||
</FloatingPanel>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -4,9 +4,11 @@ import { Context } from "../context/context";
|
||||
import { Game, User } from "@mancala/core";
|
||||
import { getColorByBrightness } from "../util/ColorUtil";
|
||||
import CircularPanel from "./CircularPanel";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
function getInfoPanelTextByGameState(params: {
|
||||
context: Context;
|
||||
t: (text: string) => string;
|
||||
game?: Game;
|
||||
currentUser: User;
|
||||
whitePlayer: User;
|
||||
@ -16,6 +18,7 @@ function getInfoPanelTextByGameState(params: {
|
||||
}): string | undefined {
|
||||
const {
|
||||
context,
|
||||
t,
|
||||
game,
|
||||
currentUser,
|
||||
whitePlayer,
|
||||
@ -25,8 +28,8 @@ function getInfoPanelTextByGameState(params: {
|
||||
} = params;
|
||||
|
||||
if (leftPlayer) {
|
||||
return isSpectator ? `${leftPlayer.name} ${context.texts.UserLeftTheGame}` :
|
||||
leftPlayer.id == currentUser.id ? context.texts.YouLeftTheGame : context.texts.OpponentLeftTheGame;
|
||||
return isSpectator ? `${leftPlayer.name} ${t("UserLeftTheGame")}` :
|
||||
leftPlayer.id == currentUser.id ? t("YouLeftTheGame") : t("OpponentLeftTheGame");
|
||||
}
|
||||
|
||||
const isGameEnded = game?.mancalaGame.state == "ended";
|
||||
@ -35,21 +38,21 @@ function getInfoPanelTextByGameState(params: {
|
||||
let whoWon;
|
||||
if (wonPlayerID) {
|
||||
const wonPlayer = wonPlayerID == whitePlayer.id ? whitePlayer : blackPlayer;
|
||||
whoWon = isSpectator ? `${wonPlayer.name} ${context.texts.Won}` :
|
||||
whoWon = isSpectator ? `${wonPlayer.name} ${t("Won")}` :
|
||||
game.mancalaGame.getWonPlayerId() === currentUser.id
|
||||
? context.texts.YouWon
|
||||
: context.texts.YouLost;
|
||||
? t("YouWon")
|
||||
: t("YouLost");
|
||||
} else {
|
||||
whoWon = context.texts.GameDraw;
|
||||
whoWon = t("GameDraw");
|
||||
}
|
||||
return context.texts.GameEnded + " " + whoWon;
|
||||
return t("GameEnded") + " " + whoWon;
|
||||
}
|
||||
|
||||
if (game) {
|
||||
const playingPlayer = game.mancalaGame.checkIsPlayerTurn(whitePlayer.id) ? whitePlayer : blackPlayer;
|
||||
return isSpectator ? `${playingPlayer.name} ${context.texts.Playing}` : game.mancalaGame.checkIsPlayerTurn(currentUser.id)
|
||||
? context.texts.YourTurn
|
||||
: context.texts.OpponentTurn;
|
||||
return isSpectator ? `${playingPlayer.name} ${t("Playing")}` : game.mancalaGame.checkIsPlayerTurn(currentUser.id)
|
||||
? t("YourTurn")
|
||||
: t("OpponentTurn");
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@ -76,6 +79,9 @@ const InfoPanel: FunctionComponent<{
|
||||
visible,
|
||||
isSpectator
|
||||
}) => {
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (visible === false) return <></>;
|
||||
const isUserTurn = currentUser.id ? game?.mancalaGame.checkIsPlayerTurn(currentUser.id) : false;
|
||||
const containerColor = isUserTurn
|
||||
@ -88,6 +94,7 @@ const InfoPanel: FunctionComponent<{
|
||||
);
|
||||
const text = getInfoPanelTextByGameState({
|
||||
context,
|
||||
t,
|
||||
game,
|
||||
currentUser,
|
||||
whitePlayer,
|
||||
|
||||
@ -4,8 +4,12 @@ import { Context } from '../context/context';
|
||||
import { LoadingState } from "@mancala/core";
|
||||
import { getColorByBrightness } from '../util/ColorUtil';
|
||||
import CircularPanel from './CircularPanel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const LoadingComponent: FunctionComponent<{ context: Context, loadingState: LoadingState<any> }> = ({ context, loadingState }) => {
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (loadingState.isUnset() || loadingState.isLoaded()) {
|
||||
return <></>
|
||||
}
|
||||
@ -15,7 +19,7 @@ const LoadingComponent: FunctionComponent<{ context: Context, loadingState: Load
|
||||
context.themeManager.theme.textColor,
|
||||
context.themeManager.theme.textLightColor
|
||||
);
|
||||
const text = loadingState.isLoading() ? context.texts.Loading +"..." : loadingState.errorMessage;
|
||||
const text = loadingState.isLoading() ? t("Loading") +"..." : loadingState.errorMessage;
|
||||
return (
|
||||
<CircularPanel color={context.themeManager.theme.boardColor}>
|
||||
<h4 style={{ margin: "0", color: textColorOnBoard }}>{`${text}`}</h4>
|
||||
|
||||
@ -4,6 +4,7 @@ import { Context } from '../context/context';
|
||||
import { User } from "@mancala/core";
|
||||
import { getColorByBrightness } from '../util/ColorUtil';
|
||||
import Space from './Space';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export type LayoutMode = "right" | "left";
|
||||
|
||||
@ -15,6 +16,9 @@ const UserStatus: FunctionComponent<{
|
||||
style?: React.CSSProperties
|
||||
}> = ({ context, user, layoutMode, visible, style }) => {
|
||||
if (visible === false) return <></>;
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const textColorOnBoard = getColorByBrightness(
|
||||
context.themeManager.theme.background,
|
||||
context.themeManager.theme.textColor,
|
||||
@ -22,7 +26,7 @@ const UserStatus: FunctionComponent<{
|
||||
);
|
||||
return (
|
||||
<div style={style} className={layoutMode === "right" ? "flex-rtl" : "flex-ltr"}>
|
||||
<span style={{color: textColorOnBoard, transition: 'color 0.5s'}} className='text'>{user.isAnonymous ? context.texts.Anonymous : user.name}</span>
|
||||
<span style={{color: textColorOnBoard, transition: 'color 0.5s'}} className='text'>{user.isAnonymous ? t("Anonymous") : user.name}</span>
|
||||
<Space width='5px' />
|
||||
<div className={"circle " + (user.isOnline ? "online" : "offline")}></div>
|
||||
<style jsx>{`
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { FunctionComponent } from 'react';
|
||||
import { Context } from '../../context/context';
|
||||
|
||||
const HeaderbarTitle: FunctionComponent<{ title: string, color: string }> = ({ title, color }) => {
|
||||
return (
|
||||
|
||||
@ -1,114 +0,0 @@
|
||||
|
||||
export type Texts = {
|
||||
Mancala: string,
|
||||
Leave: string,
|
||||
NewGame: string,
|
||||
YourTurn: string,
|
||||
OpponentTurn: string,
|
||||
GameEnded: string,
|
||||
InternalErrorOccurred: string,
|
||||
YouWon: string,
|
||||
Won: string,
|
||||
YouLost: string,
|
||||
Connecting: string,
|
||||
Connected: string,
|
||||
CannotConnect: string,
|
||||
ConnectionLost: string,
|
||||
ConnectingAgain: string,
|
||||
ServerError: string,
|
||||
SearchingOpponet: string,
|
||||
OpponentLeftTheGame: string,
|
||||
YouLeftTheGame: string,
|
||||
UserLeftTheGame: string,
|
||||
SearchingOpponent: string,
|
||||
PleaseWait: string,
|
||||
GameDraw: string,
|
||||
Anonymous: string,
|
||||
GameNotFound: string,
|
||||
Loading: string,
|
||||
Playing: string,
|
||||
Error: string,
|
||||
ErrorWhenRetrievingInformation: string,
|
||||
UCanOnlyPlayYourOwnPits: string,
|
||||
UMustWaitUntilCurrentMoveComplete: string,
|
||||
UCanNotPlayEmptyPit: string,
|
||||
AreYouSureToLeaveGame: string,
|
||||
Yes: string,
|
||||
Cancel: string,
|
||||
}
|
||||
|
||||
export const EnUs: Texts = {
|
||||
Mancala: "Mancala",
|
||||
Leave: "Leave The Game",
|
||||
NewGame: "New Game",
|
||||
YourTurn: "Your Turn",
|
||||
OpponentTurn: "Opponent Turn",
|
||||
GameEnded: "Game Ended",
|
||||
InternalErrorOccurred: "An internal error has occurred",
|
||||
YouWon: "You Won",
|
||||
Won: "Won",
|
||||
YouLost: "You Lost",
|
||||
Connecting: "Connecting",
|
||||
Connected: "Connected",
|
||||
CannotConnect: "Can't Connect",
|
||||
ConnectionLost: "Network Connection Lost",
|
||||
ConnectingAgain: "Connecting Again",
|
||||
ServerError: "Server Error",
|
||||
SearchingOpponet: "Searching Opponet",
|
||||
OpponentLeftTheGame: "Opponent Leaves The Game",
|
||||
YouLeftTheGame: "You Left The Game",
|
||||
UserLeftTheGame: "Left The Game",
|
||||
SearchingOpponent: "Searching Opponent",
|
||||
PleaseWait: "Please Wait",
|
||||
GameDraw: "Draw",
|
||||
Anonymous: "Anonymous",
|
||||
GameNotFound: "Game Not Found",
|
||||
Loading: "Loading",
|
||||
Playing: "Playing",
|
||||
Error: "Error",
|
||||
ErrorWhenRetrievingInformation: "An error occured when retrieving information!",
|
||||
UCanOnlyPlayYourOwnPits: "You can only play your own pits",
|
||||
UMustWaitUntilCurrentMoveComplete: "You must wait until the current move is complete",
|
||||
UCanNotPlayEmptyPit: "You can not play empty pit",
|
||||
AreYouSureToLeaveGame: "Are you sure to leave game?",
|
||||
Yes: "Yes",
|
||||
Cancel: "Cancel",
|
||||
}
|
||||
|
||||
export const TrTr: Texts = {
|
||||
Mancala: "Köçürme",
|
||||
Leave: "Oyundan Ayrıl",
|
||||
NewGame: "Yeni Oyun",
|
||||
YourTurn: "Sıra Sende",
|
||||
OpponentTurn: "Sıra Rakipte",
|
||||
GameEnded: "Oyun Bitti",
|
||||
InternalErrorOccurred: "Dahili bir hata oluştu",
|
||||
YouWon: "Kazandın",
|
||||
Won: "Kazandı",
|
||||
YouLost: "Kaybettin",
|
||||
Connecting: "Bağlanılıyor",
|
||||
Connected: "Bağlandı",
|
||||
CannotConnect: "Bağlanılamadı",
|
||||
ConnectionLost: "Ağ Bağlantısı Koptu",
|
||||
ConnectingAgain: "Tekrar Bağlanılıyor",
|
||||
ServerError: "Sunucu Hatası",
|
||||
SearchingOpponet: "Rakip Aranıyor",
|
||||
OpponentLeftTheGame: "Rakip Oyundan Ayrıldı",
|
||||
YouLeftTheGame: "Sen Oyundan Ayrıldın",
|
||||
UserLeftTheGame: "Oyundan Ayrıldı",
|
||||
SearchingOpponent: "Rakip Aranıyor",
|
||||
PleaseWait: "Lütfen Bekleyin",
|
||||
GameDraw: "Berabere",
|
||||
Anonymous: "Anonim",
|
||||
GameNotFound: "Oyun Bulunamadı",
|
||||
Loading: "Yükleniyor",
|
||||
Playing: "Oynuyor",
|
||||
Error: "Hata",
|
||||
ErrorWhenRetrievingInformation: "Bilgiler toplanırken bir hata oluştu!",
|
||||
UCanOnlyPlayYourOwnPits: "Sadece sana ait olan kuyular ile oynayabilirsin",
|
||||
UMustWaitUntilCurrentMoveComplete: "Devam eden haraketin bitmesini beklemelisin",
|
||||
UCanNotPlayEmptyPit: "Boş kuyu ile oynayamazsın",
|
||||
AreYouSureToLeaveGame: "Oyundan ayrılmak istediğine emin misin?",
|
||||
Yes: "Evet",
|
||||
Cancel: "İptal"
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
import { server } from "../const/config";
|
||||
import { Texts, TrTr } from "../const/texts";
|
||||
import { RTMT, RTMTWS, ThemeManager } from "@mancala/core";
|
||||
import { HttpServiceImpl } from "../service/HttpService";
|
||||
import { GameStore, GameStoreImpl } from "../store/GameStore";
|
||||
@ -10,7 +9,6 @@ import { Storage } from '@mancala/core'
|
||||
export type Context = {
|
||||
rtmt: RTMT;
|
||||
userKeyStore: UserKeyStore;
|
||||
texts: Texts;
|
||||
themeManager: ThemeManager;
|
||||
gameStore: GameStore;
|
||||
storage: Storage;
|
||||
@ -21,13 +19,11 @@ export const initContext = (): Context => {
|
||||
const httpService = new HttpServiceImpl(server.serverAdress);
|
||||
const userKeyStore = new UserKeyStoreImpl({ httpService });
|
||||
const gameStore = new GameStoreImpl({ httpService });
|
||||
const texts = TrTr;
|
||||
const storage = new LocalStorage();
|
||||
const themeManager = new ThemeManager(storage);
|
||||
return {
|
||||
rtmt: rtmt,
|
||||
userKeyStore: userKeyStore,
|
||||
texts: texts,
|
||||
themeManager,
|
||||
gameStore,
|
||||
storage
|
||||
|
||||
24
frontend/src/localization/i18n.ts
Normal file
24
frontend/src/localization/i18n.ts
Normal file
@ -0,0 +1,24 @@
|
||||
// https://medium.com/@yashpalraj/implement-i18n-in-react-native-application-a4c573e2e2a6
|
||||
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import { en, tr } from '@mancala/core';
|
||||
const resources = { // list of languages
|
||||
en: {
|
||||
translation: en
|
||||
},
|
||||
tr: {
|
||||
translation: tr
|
||||
}
|
||||
};
|
||||
i18n.use(initReactI18next) // passes i18n down to react-i18next
|
||||
.init({
|
||||
compatibilityJSON: 'v3', //To make it work for Android devices, add this line.
|
||||
resources,
|
||||
lng: 'en', // default language to use.
|
||||
// if you're using a language detector, do not define the lng option
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
});
|
||||
export default i18n;
|
||||
@ -21,13 +21,14 @@ import { channel_on_game_update, channel_on_game_crashed, channel_on_game_user_l
|
||||
import { Context } from '../context/context';
|
||||
import useWindowDimensions from '../hooks/useWindowDimensions';
|
||||
import { GameMove, LoadingState, Game, GameUsersConnectionInfo } from "@mancala/core";
|
||||
import { Theme } from '../theme/Theme';
|
||||
import { Theme } from '@mancala/core';
|
||||
import { getColorByBrightness } from '../util/ColorUtil';
|
||||
import BoardViewModel from '../viewmodel/BoardViewModel';
|
||||
import Center from '../components/Center';
|
||||
import notyf from '../util/Notyf';
|
||||
import swal from 'sweetalert';
|
||||
import Util from '../util/Util';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const GamePage: FunctionComponent<{
|
||||
context: Context,
|
||||
@ -56,6 +57,8 @@ const GamePage: FunctionComponent<{
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [gameLoadingState, setLoadingStateGame] = useState<LoadingState<Game>>(LoadingState.Unset());
|
||||
|
||||
|
||||
@ -88,7 +91,7 @@ const GamePage: FunctionComponent<{
|
||||
}
|
||||
const onGameCrashed = (message: any) => {
|
||||
const newCrashMessage = message as string;
|
||||
notyf.error(context.texts.InternalErrorOccurred);
|
||||
notyf.error(t("InternalErrorOccurred"));
|
||||
console.error("on_game_crash");
|
||||
console.error(newCrashMessage);
|
||||
}
|
||||
@ -136,11 +139,11 @@ const GamePage: FunctionComponent<{
|
||||
const checkHasAnOngoingAction = () => hasOngoingAction;
|
||||
|
||||
const onLeaveGameClick = () => {
|
||||
if (Util.checkConnectionAndMaybeAlert(context)) return;
|
||||
if (Util.checkConnectionAndMaybeAlert(context, t)) return;
|
||||
swal({
|
||||
title: context.texts.AreYouSureToLeaveGame,
|
||||
title: t("AreYouSureToLeaveGame"),
|
||||
icon: "warning",
|
||||
buttons: [context.texts.Yes, context.texts.Cancel],
|
||||
buttons: [t("Yes"), t("Cancel")],
|
||||
dangerMode: true,
|
||||
})
|
||||
.then((cancel) => {
|
||||
@ -151,7 +154,7 @@ const GamePage: FunctionComponent<{
|
||||
};
|
||||
|
||||
const onNewGameClick = () => {
|
||||
if (Util.checkConnectionAndMaybeAlert(context)) return;
|
||||
if (Util.checkConnectionAndMaybeAlert(context, t)) return;
|
||||
navigate("/loby")
|
||||
};
|
||||
|
||||
@ -160,31 +163,31 @@ const GamePage: FunctionComponent<{
|
||||
return;
|
||||
}
|
||||
if(userKeyWhoLeave) {
|
||||
notyf.error(context.texts.GameEnded);
|
||||
notyf.error(t("GameEnded"));
|
||||
return;
|
||||
}
|
||||
if(game.mancalaGame.state === "ended") {
|
||||
notyf.error(context.texts.GameEnded);
|
||||
notyf.error(t("GameEnded"));
|
||||
return;
|
||||
}
|
||||
if (Util.checkConnectionAndMaybeAlert(context)) return;
|
||||
if (Util.checkConnectionAndMaybeAlert(context, t)) return;
|
||||
if (game.mancalaGame.getPlayerIdByIndex(index) !== userKey) {
|
||||
notyf.error(context.texts.UCanOnlyPlayYourOwnPits);
|
||||
notyf.error(t("UCanOnlyPlayYourOwnPits"));
|
||||
return;
|
||||
}
|
||||
const pitIndexForUser = index % (game.mancalaGame.board.totalPitCount() / 2);
|
||||
if (!game.mancalaGame.canPlayerMove(userKey, pitIndexForUser)) {
|
||||
notyf.error(context.texts.OpponentTurn);
|
||||
notyf.error(t("OpponentTurn"));
|
||||
return;
|
||||
}
|
||||
if (checkHasAnOngoingAction()) {
|
||||
notyf.error(context.texts.UMustWaitUntilCurrentMoveComplete);
|
||||
notyf.error(t("UMustWaitUntilCurrentMoveComplete"));
|
||||
return;
|
||||
}
|
||||
if (!boardViewModel) return;
|
||||
//TODO: this check should be in mancala.js
|
||||
if (pit.stoneCount === 0) {
|
||||
notyf.error(context.texts.UCanNotPlayEmptyPit);
|
||||
notyf.error(t("UCanNotPlayEmptyPit"));
|
||||
return;
|
||||
}
|
||||
setHasOngoingAction(true);
|
||||
@ -207,7 +210,7 @@ const GamePage: FunctionComponent<{
|
||||
unlistenMessages = listenMessages(game, pitAnimator);
|
||||
setLoadingStateGame(LoadingState.Loaded({ value: game }))
|
||||
} else {
|
||||
setLoadingStateGame(LoadingState.Error({ errorMessage: context.texts.GameNotFound }))
|
||||
setLoadingStateGame(LoadingState.Error({ errorMessage: t("GameNotFound") }))
|
||||
}
|
||||
})
|
||||
return () => {
|
||||
@ -273,7 +276,7 @@ const GamePage: FunctionComponent<{
|
||||
<HeaderbarIcon />
|
||||
</Link>
|
||||
<Link style={{ textDecoration: 'none' }} to={"/"}>
|
||||
<HeaderbarTitle title={context.texts.Mancala} color={textColorOnAppBar} />
|
||||
<HeaderbarTitle title={t("Mancala")} color={textColorOnAppBar} />
|
||||
</Link>
|
||||
</Row>
|
||||
<Row>
|
||||
@ -281,7 +284,7 @@ const GamePage: FunctionComponent<{
|
||||
<Button
|
||||
context={context}
|
||||
color={context.themeManager.theme.pitColor}
|
||||
text={renderNewGameBtn ? context.texts.NewGame : context.texts.Leave}
|
||||
text={renderNewGameBtn ? t("NewGame") : t("Leave")}
|
||||
onClick={renderNewGameBtn ? onNewGameClick : onLeaveGameClick} />
|
||||
</Row>
|
||||
</HeaderBar>;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import * as React from "react";
|
||||
import { FunctionComponent, useEffect, useState } from "react";
|
||||
import { getColorByBrightness } from "../util/ColorUtil";
|
||||
import { Theme } from "../theme/Theme";
|
||||
import { Theme } from "@mancala/core";
|
||||
import HeaderBar from "../components/headerbar/HeaderBar";
|
||||
import PageContainer from "../components/PageContainer";
|
||||
import Row from "../components/Row";
|
||||
@ -12,6 +12,7 @@ import Button from "../components/Button";
|
||||
import { Context } from "../context/context";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import Util from "../util/Util";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Home: FunctionComponent<{
|
||||
context: Context,
|
||||
@ -21,8 +22,10 @@ const Home: FunctionComponent<{
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const onNewGameClick = () => {
|
||||
if(Util.checkConnectionAndMaybeAlert(context)) return;
|
||||
if(Util.checkConnectionAndMaybeAlert(context, t)) return;
|
||||
navigate("/loby")
|
||||
};
|
||||
|
||||
@ -39,7 +42,7 @@ const Home: FunctionComponent<{
|
||||
<HeaderbarIcon />
|
||||
</Link>
|
||||
<Link style={{ textDecoration: 'none' }} to={"/"}>
|
||||
<HeaderbarTitle title={context.texts.Mancala} color={textColorOnAppBar} />
|
||||
<HeaderbarTitle title={t("Mancala")} color={textColorOnAppBar} />
|
||||
</Link>
|
||||
</Row>
|
||||
<Row>
|
||||
@ -47,7 +50,7 @@ const Home: FunctionComponent<{
|
||||
<Button
|
||||
context={context}
|
||||
color={context.themeManager.theme.pitColor}
|
||||
text={context.texts.NewGame}
|
||||
text={t("NewGame")}
|
||||
onClick={onNewGameClick} />
|
||||
</Row>
|
||||
</HeaderBar>
|
||||
|
||||
@ -12,9 +12,10 @@ import PageContainer from '../components/PageContainer';
|
||||
import Row from '../components/Row';
|
||||
import { channel_cancel_new_game, channel_on_game_start } from '@mancala/core';
|
||||
import { Context } from '../context/context';
|
||||
import { Theme } from '../theme/Theme';
|
||||
import { Theme } from '@mancala/core';
|
||||
import { getColorByBrightness } from '../util/ColorUtil';
|
||||
import Button from "../components/Button";
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const LobyPage: FunctionComponent<{
|
||||
context: Context,
|
||||
@ -24,6 +25,8 @@ const LobyPage: FunctionComponent<{
|
||||
|
||||
let navigate = useNavigate();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const onGameStart = (message: Object) => {
|
||||
const newGame: CommonMancalaGame = message as CommonMancalaGame;
|
||||
navigate(`/game/${newGame.id}`)
|
||||
@ -61,7 +64,7 @@ const LobyPage: FunctionComponent<{
|
||||
<HeaderbarIcon />
|
||||
</Link>
|
||||
<Link style={{ textDecoration: 'none' }} to={"/"}>
|
||||
<HeaderbarTitle title={context.texts.Mancala} color={textColorOnAppBar} />
|
||||
<HeaderbarTitle title={t("Mancala")} color={textColorOnAppBar} />
|
||||
</Link>
|
||||
</Row>
|
||||
<Row>
|
||||
@ -75,12 +78,12 @@ const LobyPage: FunctionComponent<{
|
||||
alignContent: "center"
|
||||
}}>
|
||||
<CircularPanel color={context.themeManager.theme.boardColor}>
|
||||
<h4 style={{ margin: "0", color: textColorOnBoard }}>{`${context.texts.SearchingOpponent} ${context.texts.PleaseWait}...`}</h4>
|
||||
<h4 style={{ margin: "0", color: textColorOnBoard }}>{`${t("SearchingOpponent")} ${t("PleaseWait")}...`}</h4>
|
||||
</CircularPanel>
|
||||
<Button
|
||||
context={context}
|
||||
color={context.themeManager.theme.boardColor}
|
||||
text={context.texts.Cancel}
|
||||
text={t("Cancel")}
|
||||
onClick={onCancelNewGameClick} />
|
||||
</div>
|
||||
|
||||
|
||||
@ -8,8 +8,9 @@ import ThemeSwitchMenu from '../components/headerbar/ThemeSwitchMenu';
|
||||
import PageContainer from '../components/PageContainer';
|
||||
import Row from '../components/Row';
|
||||
import { Context } from '../context/context';
|
||||
import { Theme } from '../theme/Theme';
|
||||
import { Theme } from '@mancala/core';
|
||||
import { getColorByBrightness } from '../util/ColorUtil';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const PrivacyPage: FunctionComponent<{
|
||||
context: Context,
|
||||
@ -17,6 +18,8 @@ const PrivacyPage: FunctionComponent<{
|
||||
theme: Theme
|
||||
}> = ({ context, userKey, theme }) => {
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const textColorOnAppBar = getColorByBrightness(
|
||||
context.themeManager.theme.appBarBgColor,
|
||||
context.themeManager.theme.textColor,
|
||||
@ -35,7 +38,7 @@ const PrivacyPage: FunctionComponent<{
|
||||
<HeaderbarIcon />
|
||||
</Link>
|
||||
<Link style={{ textDecoration: 'none' }} to={"/"}>
|
||||
<HeaderbarTitle title={context.texts.Mancala} color={textColorOnAppBar} />
|
||||
<HeaderbarTitle title={t("Mancala")} color={textColorOnAppBar} />
|
||||
</Link>
|
||||
</Row>
|
||||
<Row>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Context } from "../context/context";
|
||||
import { ConnectionState } from "../rtmt/rtmt";
|
||||
import { ConnectionState } from "@mancala/core";
|
||||
import notyf from "./Notyf";
|
||||
|
||||
export default class Util {
|
||||
@ -11,21 +11,21 @@ export default class Util {
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static checkConnectionAndMaybeAlert(context: Context): boolean {
|
||||
public static checkConnectionAndMaybeAlert(context: Context, t: (text: string) => string): boolean {
|
||||
if (context.rtmt.connectionState !== "connected") {
|
||||
notyf.error(context.texts.ConnectionLost);
|
||||
notyf.error(t("ConnectionLost"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static getTextByConnectionState(context: Context, connectionState: ConnectionState): string {
|
||||
public static getTextByConnectionState(context: Context, connectionState: ConnectionState, t: (text: string) => string): string {
|
||||
const map: { [key: string]: string } = {
|
||||
connecting: context.texts.Connecting,
|
||||
connected: context.texts.Connected,
|
||||
error: context.texts.CannotConnect,
|
||||
closed: context.texts.ConnectingAgain,
|
||||
reconnecting: context.texts.ConnectingAgain,
|
||||
connecting: t("Connecting"),
|
||||
connected: t("Connected"),
|
||||
error: t("CannotConnect"),
|
||||
closed: t("ConnectingAgain"),
|
||||
reconnecting: t("ConnectingAgain"),
|
||||
};
|
||||
return map[connectionState];
|
||||
}
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
export default {
|
||||
translation: {
|
||||
Mancala: "Mancala",
|
||||
Leave: "Leave The Game",
|
||||
NewGame: "New Game",
|
||||
YourTurn: "Your Turn",
|
||||
OpponentTurn: "Opponent Turn",
|
||||
GameEnded: "Game Ended",
|
||||
InternalErrorOccurred: "An internal error has occurred",
|
||||
YouWon: "You Won",
|
||||
Won: "Won",
|
||||
YouLost: "You Lost",
|
||||
Connecting: "Connecting",
|
||||
Connected: "Connected",
|
||||
CannotConnect: "Can't Connect",
|
||||
ConnectionLost: "Network Connection Lost",
|
||||
ConnectingAgain: "Connecting Again",
|
||||
ServerError: "Server Error",
|
||||
SearchingOpponet: "Searching Opponet",
|
||||
OpponentLeftTheGame: "Opponent Leaves The Game",
|
||||
YouLeftTheGame: "You Left The Game",
|
||||
UserLeftTheGame: "Left The Game",
|
||||
SearchingOpponent: "Searching Opponent",
|
||||
PleaseWait: "Please Wait",
|
||||
GameDraw: "Draw",
|
||||
Anonymous: "Anonymous",
|
||||
GameNotFound: "Game Not Found",
|
||||
Loading: "Loading",
|
||||
Playing: "Playing",
|
||||
Error: "Error",
|
||||
ErrorWhenRetrievingInformation: "An error occured when retrieving information!",
|
||||
UCanOnlyPlayYourOwnPits: "You can only play your own pits",
|
||||
UMustWaitUntilCurrentMoveComplete: "You must wait until the current move is complete",
|
||||
UCanNotPlayEmptyPit: "You can not play empty pit",
|
||||
AreYouSureToLeaveGame: "Are you sure to leave game?",
|
||||
Yes: "Yes",
|
||||
Cancel: "Cancel",
|
||||
Help: "Help",
|
||||
WebApp: "Goto WebApp",
|
||||
Privacy: "Open Privacy Policy "
|
||||
}
|
||||
};
|
||||
@ -2,11 +2,14 @@
|
||||
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import en from './en';
|
||||
import tr from './tr';
|
||||
import { en, tr } from '@mancala/core';
|
||||
const resources = { // list of languages
|
||||
en,
|
||||
tr,
|
||||
en: {
|
||||
translation: en
|
||||
},
|
||||
tr: {
|
||||
translation: tr
|
||||
}
|
||||
};
|
||||
i18n.use(initReactI18next) // passes i18n down to react-i18next
|
||||
.init({
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
export default {
|
||||
translation: {
|
||||
Mancala: "Köçürme",
|
||||
Leave: "Oyundan Ayrıl",
|
||||
NewGame: "Yeni Oyun",
|
||||
YourTurn: "Sıra Sende",
|
||||
OpponentTurn: "Sıra Rakipte",
|
||||
GameEnded: "Oyun Bitti",
|
||||
InternalErrorOccurred: "Dahili bir hata oluştu",
|
||||
YouWon: "Kazandın",
|
||||
Won: "Kazandı",
|
||||
YouLost: "Kaybettin",
|
||||
Connecting: "Bağlanılıyor",
|
||||
Connected: "Bağlandı",
|
||||
CannotConnect: "Bağlanılamadı",
|
||||
ConnectionLost: "Ağ Bağlantısı Koptu",
|
||||
ConnectingAgain: "Tekrar Bağlanılıyor",
|
||||
ServerError: "Sunucu Hatası",
|
||||
SearchingOpponet: "Rakip Aranıyor",
|
||||
OpponentLeftTheGame: "Rakip Oyundan Ayrıldı",
|
||||
YouLeftTheGame: "Sen Oyundan Ayrıldın",
|
||||
UserLeftTheGame: "Oyundan Ayrıldı",
|
||||
SearchingOpponent: "Rakip Aranıyor",
|
||||
PleaseWait: "Lütfen Bekleyin",
|
||||
GameDraw: "Berabere",
|
||||
Anonymous: "Anonim",
|
||||
GameNotFound: "Oyun Bulunamadı",
|
||||
Loading: "Yükleniyor",
|
||||
Playing: "Oynuyor",
|
||||
Error: "Hata",
|
||||
ErrorWhenRetrievingInformation: "Bilgiler toplanırken bir hata oluştu!",
|
||||
UCanOnlyPlayYourOwnPits: "Sadece sana ait olan kuyular ile oynayabilirsin",
|
||||
UMustWaitUntilCurrentMoveComplete: "Devam eden haraketin bitmesini beklemelisin",
|
||||
UCanNotPlayEmptyPit: "Boş kuyu ile oynayamazsın",
|
||||
AreYouSureToLeaveGame: "Oyundan ayrılmak istediğine emin misin?",
|
||||
Yes: "Evet",
|
||||
Cancel: "İptal",
|
||||
Help: "Yardım",
|
||||
WebApp: "Web Uygulamasına Git",
|
||||
Privacy: "Gizlilik Politikasını Göster"
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user