Skip to content

Commit

Permalink
Merge pull request #9 from migue1s/task/theme
Browse files Browse the repository at this point in the history
Task/theme
  • Loading branch information
migue1s committed May 29, 2020
2 parents e2a3309 + 7c95470 commit fb6cf95
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 22 deletions.
23 changes: 15 additions & 8 deletions src/components/ResourceRow.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import React from 'react';
import {Text, View} from 'react-native';
import {ResourceType} from '../types';
import {useResourceCount, useResource} from '../hooks';
import ThemedText from './ThemedText';
import ThemedView from './ThemedView';

const ResourceRow = ({type}: {type: ResourceType}) => {
const data = useResource(type);
const count = useResourceCount(type);

return (
<View style={{flexDirection: 'row', padding: 8}}>
<Text style={{flex: 1}}>Icon</Text>
<Text style={{flex: 2, textAlign: 'left'}}>{data.name} </Text>
<Text style={{flex: 2, textAlign: 'center'}}>{count.perSecond}/Sec</Text>
<Text style={{flex: 2, textAlign: 'right'}}>
<ThemedView style={{flexDirection: 'row', padding: 8}}>
<ThemedText variant="body" style={{flex: 1}}>
Icon
</ThemedText>
<ThemedText variant="body" style={{flex: 2, textAlign: 'left'}}>
{data.name}{' '}
</ThemedText>
<ThemedText variant="body" style={{flex: 2, textAlign: 'center'}}>
{count.perSecond}/Sec
</ThemedText>
<ThemedText variant="body" style={{flex: 2, textAlign: 'right'}}>
{count.current}/{count.capacity}
</Text>
</View>
</ThemedText>
</ThemedView>
);
};

Expand Down
48 changes: 48 additions & 0 deletions src/components/ThemedText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import {StyleSheet, Text, ViewProps, TextStyle} from 'react-native';
import {TextVariant, ThemeVariant} from '../types';
import {useTheme} from '../hooks';

const styles = StyleSheet.create<{[x in TextVariant]: TextStyle}>({
heading: {
fontSize: 32,
},
title: {
fontSize: 24,
},
body: {
fontSize: 18,
},
caption: {
fontSize: 16,
},
});

const themeStyles = StyleSheet.create<{[x in ThemeVariant]: TextStyle}>({
dark: {
color: 'white',
},
light: {
color: 'black',
},
});

const ThemedText = ({
style = {},
children,
variant,
...rest
}: ViewProps & {
children: React.ReactNode | React.ReactNode[];
variant: TextVariant;
}) => {
const theme = useTheme();

return (
<Text style={[style, styles[variant], themeStyles[theme]]} {...rest}>
{children}
</Text>
);
};

export default ThemedText;
28 changes: 28 additions & 0 deletions src/components/ThemedView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import {StyleSheet, View, ViewProps, ViewStyle} from 'react-native';
import {useTheme} from '../hooks';
import {ThemeVariant} from '../types';

const styles = StyleSheet.create<{[x in ThemeVariant]: ViewStyle}>({
dark: {
backgroundColor: 'black',
},
light: {
backgroundColor: 'white',
},
});

const ThemedView = ({
style = {},
children,
...rest
}: ViewProps & {children: React.ReactNode | React.ReactNode[]}) => {
const theme = useTheme();
return (
<View style={[style, styles[theme]]} {...rest}>
{children}
</View>
);
};

export default ThemedView;
4 changes: 4 additions & 0 deletions src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import {chain} from 'lodash';
import {ReduxState} from './redux/store';
import {ResourceType} from './types';

export const useTheme = () => {
return useSelector((state: ReduxState) => state.global.theme);
};

export const useResource = (resourceId: ResourceType) => {
return useSelector((state: ReduxState) => state.game.resources[resourceId]);
};
Expand Down
22 changes: 22 additions & 0 deletions src/redux/globalSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {createSlice, PayloadAction} from '@reduxjs/toolkit';
import {ThemeVariant} from '../types';

const initialState = {
theme: 'light' as ThemeVariant,
};

export type GlobalState = typeof initialState;

const globalSlice = createSlice({
name: 'global',
initialState,
reducers: {
setTheme: (state, action: PayloadAction<ThemeVariant>) => {
state.theme = action.payload;
},
},
});

export const {setTheme} = globalSlice.actions;

export default globalSlice.reducer;
9 changes: 9 additions & 0 deletions src/redux/rootReducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import gameSlice from './gameSlice';
import globalSlice from './globalSlice';

export default {
reducer: {
game: gameSlice,
global: globalSlice,
},
};
12 changes: 6 additions & 6 deletions src/redux/store.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {configureStore} from '@reduxjs/toolkit';
import {startLoop} from '../utils/TickLoop';
import gameSlice, {tick, GameState} from './gameSlice';
import {GameState, tick} from './gameSlice';
import {GlobalState} from './globalSlice';
import rootReducer from './rootReducer';
export interface ReduxState {
game: GameState;
global: GlobalState;
}
const store = configureStore({
reducer: {
game: gameSlice,
},
});

const store = configureStore(rootReducer);

startLoop(
(delta: number) => {
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export type TextVariant = 'heading' | 'title' | 'body' | 'caption';
export type ThemeVariant = 'dark' | 'light';
export interface Resource {
name: string;
category: string;
Expand Down
37 changes: 29 additions & 8 deletions storybook/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,45 @@
import React from 'react';
import {View} from 'react-native';
import {View, Text} from 'react-native';
import {AppRegistry} from 'react-native';
import {getStorybookUI, configure} from '@storybook/react-native';
import {addDecorator} from '@storybook/react';

import './rn-addons';
import {configureStore} from '@reduxjs/toolkit';
import {Provider} from 'react-redux';
import rootReducer from '../src/redux/rootReducer';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {setTheme} from '../src/redux/globalSlice';

// import stories
configure(() => {
require('../src/components/Resource.stories');
}, module);

const reduxStore = configureStore(rootReducer);

addDecorator((fn) => (
<View
style={{
padding: 20,
width: '100%',
}}>
{fn()}
</View>
<Provider store={reduxStore}>
<TouchableOpacity
onPress={() => {
const state = reduxStore.getState();
if (state.global.theme === 'light') {
reduxStore.dispatch(setTheme('dark'));
} else {
reduxStore.dispatch(setTheme('light'));
}
}}>
<Text>Toggle theme</Text>
</TouchableOpacity>
<View
style={{
paddingTop: 40,
padding: 20,
width: '100%',
}}>
{fn()}
</View>
</Provider>
));

// Refer to https://github.com/storybookjs/storybook/tree/master/app/react-native#start-command-parameters
Expand Down

0 comments on commit fb6cf95

Please sign in to comment.