[mobile] add help page for privacy policy

This commit is contained in:
Halit Aksoy 2024-04-05 01:41:42 +03:00
parent 2823a9b020
commit e112cda719
14 changed files with 272 additions and 14 deletions

View File

@ -23,6 +23,7 @@
"react-native-safe-area-context": "^4.9.0",
"react-native-screens": "^3.29.0",
"react-native-snackbar": "^2.6.2",
"react-native-svg": "^15.1.0",
"tiny-emitter": "^2.1.0",
"uuid": "^9.0.1"
},

View File

@ -15,6 +15,8 @@ import { NativeModules, I18nManager, Platform } from 'react-native'
// https://github.com/uuidjs/uuid/issues/514#issuecomment-691475020
import 'react-native-get-random-values';
import HelpScreen from './screens/HelpScreen';
import { getColorByBrightness } from './util/ColorUtil';
const Stack = createNativeStackNavigator<RootStackParamList>();
@ -96,15 +98,26 @@ function App() {
// context.themeManager.theme.textColor,
// context.themeManager.theme.textLightColor
//);
const textColorOnAppBar = getColorByBrightness(
context.themeManager.theme.appBarBgColor,
context.themeManager.theme.textColor,
context.themeManager.theme.textLightColor
);
const headerStyle = { backgroundColor: context.themeManager.theme.appBarBgColor };
const headerTintColor = textColorOnAppBar;
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} initialParams={{ context }}
options={{ title: t("Mancala"), headerStyle: { backgroundColor: context.themeManager.theme.appBarBgColor } }} />
options={{ title: t("Mancala"), headerStyle, headerTintColor }} />
<Stack.Screen name="Loby" component={LobyScreen}
options={{ title: t("Mancala"), headerStyle: { backgroundColor: context.themeManager.theme.appBarBgColor } }} />
options={{ title: t("Mancala"), headerStyle, headerTintColor }} />
<Stack.Screen name="Game" component={GameScreen}
options={{ title: t("Mancala"), headerStyle: { backgroundColor: context.themeManager.theme.appBarBgColor }, headerTintColor: '#fff', }} />
options={{ title: t("Mancala"), headerStyle, headerTintColor }} />
<Stack.Screen name="Help" component={HelpScreen}
options={{ title: t("Help"), headerStyle, headerTintColor }} />
</Stack.Navigator>
</NavigationContainer>
);

View File

@ -15,3 +15,7 @@ export const server: Server = useLocalServer ? {
};
export const RTMT_WS_PING_INTERVAL = 1000, RTMT_WS_PING_INTERVAL_BUFFER_TIME = 2000;
export const WEB_APP_URL = "https://playmancala.app";
export const PRIVAcY_URL = "https://playmancala.app/privacy";

View File

@ -35,5 +35,8 @@ export default {
AreYouSureToLeaveGame: "Are you sure to leave game?",
Yes: "Yes",
Cancel: "Cancel",
Help: "Help",
WebApp: "Goto WebApp",
Privacy: "Open Privacy Policy "
}
};

View File

@ -34,6 +34,9 @@ export default {
UCanNotPlayEmptyPit: "Boş kuyu ile oynayamazsın",
AreYouSureToLeaveGame: "Oyundan ayrılmak istediğine emin misin?",
Yes: "Evet",
Cancel: "İptal"
Cancel: "İptal",
Help: "Yardım",
WebApp: "Web Uygulamasına Git",
Privacy: "Gizlilik Politikasını Göster"
}
};

View File

@ -22,6 +22,8 @@ import UserStatus from '../components/UserStatus';
import BoardToolbar from '../components/board/BoardToolbar';
import BoardView from '../components/board/BoardView';
import CircularPanel from '../components/CircularPanel';
import { SvgXml } from 'react-native-svg';
import helpSvg from '../svg/help';
export function GameScreen({ navigation, route }: GameScreenProps) {
const { context, gameId, userKey } = route.params;
@ -215,15 +217,28 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
const isGameEnded = game?.mancalaGame.state === "ended" || leftPlayer;
navigation.setOptions({
headerRight: () => (
<Pressable onPress={() => {
if (isGameEnded) {
onNewGameClick();
} else {
onLeaveGameClick();
}
<View style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
gap: 5
}}>
<CircularPanel color={context.themeManager.theme?.background} children={<Text style={{ color: context.themeManager.theme.textColor }}>{isGameEnded ? t('NewGame') : t('Leave')}</Text>} />
</Pressable>
<Pressable onPress={() => {
if (isGameEnded) {
onNewGameClick();
} else {
onLeaveGameClick();
}
}}>
<CircularPanel color={context.themeManager.theme?.background} children={<Text style={{ color: context.themeManager.theme.textColor }}>{isGameEnded ? t('NewGame') : t('Leave')}</Text>} />
</Pressable>
<Pressable onPress={() => {
navigation.push("Help", { context })
}}>
<SvgXml xml={helpSvg.replaceAll("customColor", textColorOnAppBar)} width="24" height="24" />
</Pressable>
</View>
),
});
}

View File

@ -0,0 +1,42 @@
import * as React from 'react';
import { View, Text, Button, Pressable, Linking } from 'react-native';
import { useTranslation } from 'react-i18next';
import { HelpScreenProps } from '../types';
import Snackbar from 'react-native-snackbar';
import { PRIVAcY_URL, WEB_APP_URL } from '../const/config';
export default function HelpScreen({ navigation, route }: HelpScreenProps) {
const { context } = route.params;
const { t } = useTranslation();
const onGotoWebAppClick = () => {
Linking.openURL(WEB_APP_URL).catch(()=>{
Snackbar.show({text: t("InternalErrorOccurred")});
})
}
const onGotoPrivacyClick = () => {
Linking.openURL(PRIVAcY_URL).catch(()=>{
Snackbar.show({text: t("InternalErrorOccurred")});
})
}
return (
<View style={{
flex: 1,
backgroundColor: context.themeManager.theme?.background,
padding: 20,
gap: 5,
alignContent: "center",
justifyContent: "center"
}}>
<Pressable onPress={onGotoWebAppClick}>
<Text style={{ textAlign: "center", color: context.themeManager.theme.textColor }}>{t('WebApp')}</Text>
</Pressable>
<Pressable onPress={onGotoPrivacyClick}>
<Text style={{ textAlign: "center", color: context.themeManager.theme.textColor }}>{t('Privacy')}</Text>
</Pressable>
</View>
);
}

View File

@ -3,16 +3,41 @@ import { View, Button, Pressable, Text } from 'react-native';
import { useTranslation } from 'react-i18next';
import { HomeScreenProps } from '../types';
import CircularPanel from '../components/CircularPanel';
import { SvgXml } from 'react-native-svg';
import helpSvg from '../svg/help';
import { getColorByBrightness } from '../util/ColorUtil';
export function HomeScreen({ navigation, route }: HomeScreenProps) {
const { context } = route.params;
const { t } = useTranslation();
const textColorOnAppBar = getColorByBrightness(
context.themeManager.theme.appBarBgColor,
context.themeManager.theme.textColor,
context.themeManager.theme.textLightColor
);
const updateHeaderButton = () => {
navigation.setOptions({
headerRight: () => (
<Pressable onPress={() => {
navigation.push("Help", { context })
}}>
<SvgXml xml={helpSvg.replaceAll("customColor", textColorOnAppBar)} width="24" height="24" />
</Pressable>
),
});
}
React.useEffect(() => {
updateHeaderButton();
}, []);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: context.themeManager.theme?.background }}>
<Pressable onPress={() => navigation.replace('Loby', { context })}>
<CircularPanel color={context.themeManager.theme?.boardColor} children={<Text style={{color: context.themeManager.theme.textColor}}>{t('NewGame')}</Text>}/>
<CircularPanel color={context.themeManager.theme?.boardColor} children={<Text style={{ color: context.themeManager.theme.textColor }}>{t('NewGame')}</Text>} />
</Pressable>
</View>
);

View File

@ -6,6 +6,9 @@ import { useEffect } from 'react';
import { CommonMancalaGame } from 'mancala.js';
import { channel_cancel_new_game, channel_on_game_start } from '../const/channel_names';
import CircularPanel from '../components/CircularPanel';
import { getColorByBrightness } from '../util/ColorUtil';
import { SvgXml } from 'react-native-svg';
import helpSvg from '../svg/help';
export default function LobyScreen({ navigation, route }: LobyScreenProps) {
@ -34,6 +37,28 @@ export default function LobyScreen({ navigation, route }: LobyScreenProps) {
}
}, []);
const textColorOnAppBar = getColorByBrightness(
context.themeManager.theme.appBarBgColor,
context.themeManager.theme.textColor,
context.themeManager.theme.textLightColor
);
const updateHeaderButton = () => {
navigation.setOptions({
headerRight: () => (
<Pressable onPress={() => {
navigation.push("Help", { context })
}}>
<SvgXml xml={helpSvg.replaceAll("customColor", textColorOnAppBar)} width="24" height="24" />
</Pressable>
),
});
}
React.useEffect(() => {
updateHeaderButton();
}, []);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: context.themeManager.theme?.background }}>
<CircularPanel color={context.themeManager.theme?.boardColor} children={<Text style={{ color: "#000" }}>{t('SearchingOpponent') + " " + t('PleaseWait') + "..."}</Text>} />

12
mobile/src/svg/help.tsx Normal file
View File

@ -0,0 +1,12 @@
import Svg, { G, Path } from "react-native-svg";
const helpSvg =
`
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="customColor" fill="none" stroke-width="2"/>
<path d="M10.5 8.67709C10.8665 8.26188 11.4027 8 12 8C13.1046 8 14 8.89543 14 10C14 10.9337 13.3601 11.718 12.4949 11.9383C12.2273 12.0064 12 12.2239 12 12.5V12.5V13" stroke="customColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 16H12.01" stroke="customColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
`;
export default helpSvg;

View File

@ -0,0 +1,8 @@
const lightModeSvg =
`
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 3V4M12 20V21M4 12H3M6.31412 6.31412L5.5 5.5M17.6859 6.31412L18.5 5.5M6.31412 17.69L5.5 18.5001M17.6859 17.69L18.5 18.5001M21 12H20M16 12C16 14.2091 14.2091 16 12 16C9.79086 16 8 14.2091 8 12C8 9.79086 9.79086 8 12 8C14.2091 8 16 9.79086 16 12Z" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
`;
export default lightModeSvg;

View File

@ -0,0 +1,20 @@
const settingsSvg =
`
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 489.802 489.802" xml:space="preserve">
<g>
<path d="M20.701,281.901l32.1,0.2c4.8,24.7,14.3,48.7,28.7,70.5l-22.8,22.6c-8.2,8.1-8.2,21.2-0.2,29.4l24.6,24.9
c8.1,8.2,21.2,8.2,29.4,0.2l22.8-22.6c21.6,14.6,45.5,24.5,70.2,29.5l-0.2,32.1c-0.1,11.5,9.2,20.8,20.7,20.9l35,0.2
c11.5,0.1,20.8-9.2,20.9-20.7l0.2-32.1c24.7-4.8,48.7-14.3,70.5-28.7l22.6,22.8c8.1,8.2,21.2,8.2,29.4,0.2l24.9-24.6
c8.2-8.1,8.2-21.2,0.2-29.4l-22.6-22.8c14.6-21.6,24.5-45.5,29.5-70.2l32.1,0.2c11.5,0.1,20.8-9.2,20.9-20.7l0.2-35
c0.1-11.5-9.2-20.8-20.7-20.9l-32.1-0.2c-4.8-24.7-14.3-48.7-28.7-70.5l22.8-22.6c8.2-8.1,8.2-21.2,0.2-29.4l-24.6-24.9
c-8.1-8.2-21.2-8.2-29.4-0.2l-22.8,22.6c-21.6-14.6-45.5-24.5-70.2-29.5l0.2-32.1c0.1-11.5-9.2-20.8-20.7-20.9l-35-0.2
c-11.5-0.1-20.8,9.2-20.9,20.7l-0.3,32.1c-24.8,4.8-48.8,14.3-70.5,28.7l-22.6-22.8c-8.1-8.2-21.2-8.2-29.4-0.2l-24.8,24.6
c-8.2,8.1-8.2,21.2-0.2,29.4l22.6,22.8c-14.6,21.6-24.5,45.5-29.5,70.2l-32.1-0.2c-11.5-0.1-20.8,9.2-20.9,20.7l-0.2,35
C-0.099,272.401,9.201,281.801,20.701,281.901z M179.301,178.601c36.6-36.2,95.5-35.9,131.7,0.7s35.9,95.5-0.7,131.7
s-95.5,35.9-131.7-0.7S142.701,214.801,179.301,178.601z"/>
</g>
</svg>
`;
export default settingsSvg;

View File

@ -5,6 +5,7 @@ export type RootStackParamList = {
Home: { context: Context },
Loby: { context: Context },
Game: { context: Context, gameId: string, userKey: string }
Help: { context: Context }
};
export type HomeScreenProps = NativeStackScreenProps<RootStackParamList, 'Home'>;
@ -12,3 +13,5 @@ export type HomeScreenProps = NativeStackScreenProps<RootStackParamList, 'Home'>
export type LobyScreenProps = NativeStackScreenProps<RootStackParamList, 'Loby'>;
export type GameScreenProps = NativeStackScreenProps<RootStackParamList, 'Game'>;
export type HelpScreenProps = NativeStackScreenProps<RootStackParamList, 'Help'>;

View File

@ -2500,6 +2500,11 @@ bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@ -2846,6 +2851,30 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
css-select@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
dependencies:
boolbase "^1.0.0"
css-what "^6.1.0"
domhandler "^5.0.2"
domutils "^3.0.1"
nth-check "^2.0.1"
css-tree@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
dependencies:
mdn-data "2.0.14"
source-map "^0.6.1"
css-what@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
csstype@^3.0.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
@ -3002,6 +3031,36 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"
domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"
domutils@^3.0.1:
version "3.1.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -3027,6 +3086,11 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
entities@^4.2.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
envinfo@^7.10.0:
version "7.11.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.1.tgz#2ffef77591057081b0129a8fd8cf6118da1b94e1"
@ -4881,6 +4945,11 @@ marky@^1.2.2:
resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.5.tgz#55796b688cbd72390d2d399eaaf1832c9413e3c0"
integrity sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==
mdn-data@2.0.14:
version "2.0.14"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
memoize-one@^5.0.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
@ -5230,6 +5299,13 @@ npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
nth-check@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
dependencies:
boolbase "^1.0.0"
nullthrows@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1"
@ -5684,6 +5760,14 @@ react-native-snackbar@^2.6.2:
resolved "https://registry.yarnpkg.com/react-native-snackbar/-/react-native-snackbar-2.6.2.tgz#7c0d0d93bfb5822fb1f41f00d29383f522c02185"
integrity sha512-edAubZJiBowwQUXJV5oXbMqitQ9vw7JzWUCczeTPVo6lRa+FzsUjiCQBHdWBbCw/N8/Q7jgKg4juNXU/bXZdXg==
react-native-svg@^15.1.0:
version "15.1.0"
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.1.0.tgz#07c75f29b1d641faba50144c7ccd21604b368420"
integrity sha512-p0Sx0EpQNk1nu6UcMEiB8K9P04n3J7s+pNYUwf1d/Yz+v4hk961VjuVqjyndgiEbHZyWiKWLZRVNuvLpwjPY2A==
dependencies:
css-select "^5.1.0"
css-tree "^1.1.3"
react-native@0.73.6:
version "0.73.6"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.73.6.tgz#ed4c675e205a34bd62c4ce8b9bd1ca5c85126d5b"