Skip to content
This repository has been archived by the owner on Nov 11, 2021. It is now read-only.

Commit

Permalink
toggle themes
Browse files Browse the repository at this point in the history
  • Loading branch information
lochungtin committed May 31, 2021
1 parent 8d80145 commit a440e9f
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 75 deletions.
14 changes: 9 additions & 5 deletions src/components/Board/Tile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@ import React from 'react';
import { Text, View } from 'react-native';
import { connect } from 'react-redux';

import { darktheme } from '../../../data/color';
import { ColorSchemeType } from '../../../utils/types';
import { screenWidth, TileStyles } from './styles';

interface ReduxProps {
colortheme: ColorSchemeType,
}

interface TileProps {
dim: number
number: number
}

class Tile extends React.Component<TileProps> {
class Tile extends React.Component<ReduxProps & TileProps> {
render() {
let backgroundColor = darktheme.tileColors[this.props.number.toString()] || darktheme.tileColors.large;
let backgroundColor = this.props.colortheme.tileColors[this.props.number.toString()] || this.props.colortheme.tileColors.large;
let sides = (screenWidth * 0.8) / this.props.dim;

return (
<View style={{ ...TileStyles.root, backgroundColor, height: sides, width: sides }}>
<Text style={{ ...TileStyles.text, color: darktheme.textColor }}>
<Text style={{ ...TileStyles.text, color: this.props.colortheme.textColor }}>
{this.props.number === -1 ? '' : this.props.number}
</Text>
</View>
Expand All @@ -26,7 +30,7 @@ class Tile extends React.Component<TileProps> {
}

const mapStateToProps = state => ({

colortheme: state.colortheme,
});

export default connect(mapStateToProps)(Tile);
11 changes: 6 additions & 5 deletions src/components/Board/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import React from 'react';
import { View } from 'react-native';
import { Directions, FlingGestureHandler } from 'react-native-gesture-handler';
import { Directions, FlingGestureHandler, } from 'react-native-gesture-handler';
import { connect } from 'react-redux';

import GameoverModal from '../GameoverModal';
import Tile from './Tile';

import { darktheme } from '../../data/color';
import { BoardStyles } from './styles';

import Board from '../../game/board';
import { store } from '../../redux/store';
import { updateGame, updateHistory, updateRecords } from '../../redux/action';
import { updateGame, updateHistory, updateRecords, } from '../../redux/action';
import { keygen } from '../../utils/keygen';
import { Direction } from '../../utils/enums';
import { GameConfig, RecordType } from '../../utils/types';
import { ColorSchemeType, GameConfig, RecordType, } from '../../utils/types';

interface ReduxProps {
colortheme: ColorSchemeType,
game: GameConfig,
records: Array<RecordType>
}
Expand Down Expand Up @@ -77,7 +77,7 @@ class BoardView extends React.Component<ReduxProps> {
<FlingGestureHandler direction={Directions.DOWN} onEnded={() => this.swipe(Direction.down)} >
<FlingGestureHandler direction={Directions.LEFT} onEnded={() => this.swipe(Direction.left)}>
<FlingGestureHandler direction={Directions.RIGHT} onEnded={() => this.swipe(Direction.right)}>
<View style={{ ...BoardStyles.root, backgroundColor: darktheme.boardColor }}>
<View style={{ ...BoardStyles.root, backgroundColor: this.props.colortheme.boardColor }}>
{this.props.game.board.map(row => {
return (
<View key={keygen()} style={BoardStyles.row}>
Expand Down Expand Up @@ -107,6 +107,7 @@ class BoardView extends React.Component<ReduxProps> {
}

const mapStateToProps = state => ({
colortheme: state.colortheme,
game: state.game,
records: state.records,
});
Expand Down
27 changes: 15 additions & 12 deletions src/components/GameoverModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { Text, TouchableOpacity, View, } from 'react-native';
import Modal from 'react-native-modal';
import { connect } from 'react-redux';

import { darktheme } from '../../data/color';
import { ModalStyles } from './styles';

import { GameConfig } from '../../utils/types';
import { ColorSchemeType } from '../../utils/types';

interface ReduxProps {
colortheme: ColorSchemeType,
}

interface ModalProps {
onSaveGame: () => void,
Expand All @@ -16,7 +19,7 @@ interface ModalProps {
open: boolean,
}

class BoardView extends React.Component<ModalProps> {
class BoardView extends React.Component<ReduxProps & ModalProps> {

render() {
return (
Expand All @@ -25,35 +28,35 @@ class BoardView extends React.Component<ModalProps> {
isVisible={this.props.open}
>
<View style={ModalStyles.modalRoot}>
<Text style={{ ...ModalStyles.text, color: darktheme.textColor }}>
<Text style={{ color: darktheme.accentColor }}>G A M E</Text> O V E R
<Text style={{ ...ModalStyles.text, color: this.props.colortheme.textColor }}>
<Text style={{ color: this.props.colortheme.accentColor }}>G A M E</Text> O V E R
</Text>
<View style={ModalStyles.statsContainer}>
<View style={ModalStyles.statsRow}>
<Text style={{ ...ModalStyles.text, color: darktheme.accentColor }}>
<Text style={{ ...ModalStyles.text, color: this.props.colortheme.accentColor }}>
Score :
</Text>
<Text style={{ ...ModalStyles.text, color: darktheme.textColor }}>
<Text style={{ ...ModalStyles.text, color: this.props.colortheme.textColor }}>
{this.props.score}
</Text>
</View>
<View style={ModalStyles.statsRow}>
<Text style={{ ...ModalStyles.text, color: darktheme.accentColor }}>
<Text style={{ ...ModalStyles.text, color: this.props.colortheme.accentColor }}>
Highest Tile :
</Text>
<Text style={{ ...ModalStyles.text, color: darktheme.textColor }}>
<Text style={{ ...ModalStyles.text, color: this.props.colortheme.textColor }}>
{this.props.highestTile}
</Text>
</View>
</View>
<View style={ModalStyles.optionBar}>
<TouchableOpacity onPress={this.props.onSaveGame}>
<Text style={{ ...ModalStyles.text, color: darktheme.accentColor }}>
<Text style={{ ...ModalStyles.text, color: this.props.colortheme.accentColor }}>
SAVE RECORD
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.props.onNewGame}>
<Text style={{ ...ModalStyles.text, color: darktheme.textColor }}>
<Text style={{ ...ModalStyles.text, color: this.props.colortheme.textColor }}>
NEW GAME
</Text>
</TouchableOpacity>
Expand All @@ -65,7 +68,7 @@ class BoardView extends React.Component<ModalProps> {
}

const mapStateToProps = state => ({

colortheme: state.colortheme
});

export default connect(mapStateToProps)(BoardView);
52 changes: 35 additions & 17 deletions src/data/color.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
import { ColorSchemeType } from "../utils/types";
import { ColorSchemeType, TileColorSchemeType, } from "../utils/types";

const tileColors: TileColorSchemeType = {
'-1': '#1c1b1b',
'2': '#a3948b',
'4': '#c2a899',
'8': '#dbb49e',
'16': '#ebaf8d',
'32': '#ed9b6d',
'64': '#eb864d',
'128': '#f07b3a',
'256': '#eb702d',
'512': '#cf5d1f',
'1024': '#b84e14',
'2048': '#9e3f0b',
large: '#3d3934',
}

export const darktheme: ColorSchemeType = {
name: 'dark',
bgColor: '#1E1E1E',
boardColor: '#151515',
tileColors: {
'-1': '#1c1b1b',
'2': '#a3948b',
'4': '#c2a899',
'8': '#dbb49e',
'16': '#ebaf8d',
'32': '#ed9b6d',
'64': '#eb864d',
'128': '#f07b3a',
'256': '#eb702d',
'512': '#cf5d1f',
'1024': '#b84e14',
'2048': '#9e3f0b',
large: '#3d3934',
},
tileColors,
textColor: '#E0E0E0',
textboxColor: '#272727',
btnColor: '#A0A0A0',
accentColor: '#EB864D'
}
}

export const light: ColorSchemeType = {
name: 'light',
bgColor: '#EFEFEF',
boardColor: '#CFCFCF',
tileColors: {
...tileColors,
'-1': '#DFDFDF',
'2': '#C7BAB3',
},
textColor: '#0F0F0F',
textboxColor: '#CFCFCF',
btnColor: '#4F4F4F',
accentColor: '#EB864D'
}
8 changes: 7 additions & 1 deletion src/redux/action.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { ActionType, GameConfig, RecordType, } from '../utils/types';
import { ActionType, ColorSchemeType, GameConfig, RecordType, } from '../utils/types';

export enum ActionName {
SAVE_COLOR_CONFIG,
SAVE_GAME_STATE,
SAVE_HISTORY,
SAVE_RECORDS,
}

export const updateColors = (payload: ColorSchemeType): ActionType => ({
type: ActionName.SAVE_COLOR_CONFIG,
payload,
});

export const updateGame = (payload: GameConfig): ActionType => ({
type: ActionName.SAVE_GAME_STATE,
payload,
Expand Down
11 changes: 8 additions & 3 deletions src/redux/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@ import { combineReducers } from 'redux';

import { ActionName } from './action';

import { ActionType, GameConfig, RecordType } from '../utils/types';
import { ActionType, ColorSchemeType, GameConfig, RecordType } from '../utils/types';
import { darktheme } from '../data/color';

const saveHistory = (board: GameConfig = null, action: ActionType) =>
action.type === ActionName.SAVE_HISTORY ? action.payload : board;
const saveColors = (theme: ColorSchemeType = darktheme, action: ActionType) =>
action.type === ActionName.SAVE_COLOR_CONFIG ? action.payload : theme;

const saveGame = (board: GameConfig = null, action: ActionType) =>
action.type === ActionName.SAVE_GAME_STATE ? action.payload : board;

const saveHistory = (board: GameConfig = null, action: ActionType) =>
action.type === ActionName.SAVE_HISTORY ? action.payload : board;

const saveRecords = (records: Array<RecordType> = [], action: ActionType) =>
action.type === ActionName.SAVE_RECORDS ? action.payload : records;

export default combineReducers({
colortheme: saveColors,
game: saveGame,
history: saveHistory,
records: saveRecords,
Expand Down
44 changes: 25 additions & 19 deletions src/screens/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ import { connect } from 'react-redux';

import BoardView from '../components/Board';

import { darktheme } from '../data/color';
import { MainStyles, ScreenStyles } from './styles';
import { darktheme, lighttheme } from '../data/color';
import { MainStyles, ScreenStyles, } from './styles';

import Board from '../game/board';
import { updateGame, updateHistory } from '../redux/action';
import { updateColors, updateGame, updateHistory } from '../redux/action';
import { store } from '../redux/store';
import { GameConfig, RecordType } from '../utils/types';
import { ColorSchemeType, GameConfig, RecordType, } from '../utils/types';

interface NavProps {
navigation: StackNavigationProp<any, any>,
}

interface ReduxProps {
colortheme: ColorSchemeType,
game: GameConfig,
history: GameConfig,
records: Array<RecordType>
Expand Down Expand Up @@ -46,43 +47,47 @@ class Screen extends React.Component<NavProps & ReduxProps> {
store.dispatch(updateHistory(null));
}

toggleTheme = () => {
store.dispatch(updateColors(this.props.colortheme.name === 'dark' ? lighttheme : darktheme))
}

render() {
return (
<View style={{ ...ScreenStyles.screen, backgroundColor: darktheme.bgColor }}>
<Text style={{ ...MainStyles.titleText, color: darktheme.textColor }}>
<Text style={{ color: darktheme.accentColor }}>2</Text> 0 4 8
<View style={{ ...ScreenStyles.screen, backgroundColor: this.props.colortheme.bgColor }}>
<Text style={{ ...MainStyles.titleText, color: this.props.colortheme.textColor }}>
<Text style={{ color: this.props.colortheme.accentColor }}>2</Text> 0 4 8
</Text>
<View style={MainStyles.scoreBar}>
<View style={{ ...MainStyles.scoreContainer, backgroundColor: darktheme.textboxColor }}>
<Text style={{ ...MainStyles.scoreLabelText, color: darktheme.accentColor }}>
<View style={{ ...MainStyles.scoreContainer, backgroundColor: this.props.colortheme.textboxColor }}>
<Text style={{ ...MainStyles.scoreLabelText, color: this.props.colortheme.accentColor }}>
Score
</Text>
<Text style={{ ...MainStyles.scoreText, color: darktheme.textColor }}>
<Text style={{ ...MainStyles.scoreText, color: this.props.colortheme.textColor }}>
{this.props.game.score}
</Text>
</View>
<View style={{ ...MainStyles.scoreContainer, backgroundColor: darktheme.textboxColor }}>
<Text style={{ ...MainStyles.scoreLabelText, color: darktheme.accentColor }}>
<View style={{ ...MainStyles.scoreContainer, backgroundColor: this.props.colortheme.textboxColor }}>
<Text style={{ ...MainStyles.scoreLabelText, color: this.props.colortheme.accentColor }}>
High Score
</Text>
<Text style={{ ...MainStyles.scoreText, color: darktheme.textColor }}>
{this.props.records[0].score}
<Text style={{ ...MainStyles.scoreText, color: this.props.colortheme.textColor }}>
{this.props.records.length === 0 ? 0 : this.props.records[0].score}
</Text>
</View>
</View>
<View style={MainStyles.functionBarOuter}>
<View style={MainStyles.functionBar}>
<TouchableOpacity onPress={this.back}>
<Icon color={darktheme.btnColor} name='backup-restore' size={40} />
<Icon color={this.props.colortheme.btnColor} name='backup-restore' size={40} />
</TouchableOpacity>
<TouchableOpacity onPress={this.newGame}>
<Icon color={darktheme.btnColor} name='sync' size={40} />
<Icon color={this.props.colortheme.btnColor} name='sync' size={40} />
</TouchableOpacity>
<TouchableOpacity onPress={() => { }}>
<Icon color={darktheme.btnColor} name='lightbulb-outline' size={40} />
<TouchableOpacity onPress={this.toggleTheme}>
<Icon color={this.props.colortheme.btnColor} name='lightbulb-outline' size={40} />
</TouchableOpacity>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Records')}>
<Icon color={darktheme.accentColor} name='text-box-outline' size={40} />
<Icon color={this.props.colortheme.accentColor} name='text-box-outline' size={40} />
</TouchableOpacity>
</View>
</View>
Expand All @@ -93,6 +98,7 @@ class Screen extends React.Component<NavProps & ReduxProps> {
}

const mapStateToProps = state => ({
colortheme: state.colortheme,
game: state.game,
history: state.history,
records: state.records,
Expand Down
Loading

0 comments on commit a440e9f

Please sign in to comment.