Skip to content

Commit

Permalink
feat: refactored available values progress coloring through theme
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalyiegorov committed May 21, 2023
1 parent 3e318cc commit b86c3ee
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 99 deletions.
10 changes: 7 additions & 3 deletions app/game/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import * as Haptics from 'expo-haptics';
import { ImpactFeedbackStyle } from 'expo-haptics';
import { useRouter } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
import { useEffect } from 'react';
import { useCallback, useEffect } from 'react';
import { Alert, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';

import { AvailableValues } from '../../components/available-values/available-values';
import { BlackButton } from '../../components/black-button/black-button';
import { Field } from '../../components/field/field';
import { MaxMistakesConstant } from '../../constants/max-mistakes.constant';
import { useAppSelector } from '../../hooks/redux.hook';
import { useAppDispatch, useAppSelector } from '../../hooks/redux.hook';
import { type CellInterface } from '../../interfaces/cell.interface';
import { appRootSelectCellAction } from '../../store/app-root/app-root.actions';
import { appRootFieldSelector, appRootMistakesSelector, appRootSelectedCellSelector } from '../../store/app-root/app-root.selectors';
import { hasBlankCells } from '../../utils/field/has-blank-cells.util';

Expand All @@ -19,6 +21,7 @@ import { GameStyles as styles } from './game.styles';
export default function Game() {
const router = useRouter();

const dispatch = useAppDispatch();
const field = useAppSelector(appRootFieldSelector);
const selectedCell = useAppSelector(appRootSelectedCellSelector);
const mistakes = useAppSelector(appRootMistakesSelector);
Expand All @@ -45,6 +48,7 @@ export default function Game() {
{ text: 'OK', onPress: () => void router.push('/') }
]);
};
const handleSelectCell = useCallback((cell: CellInterface | undefined) => void dispatch(appRootSelectCellAction(cell)), []);

return (
<SafeAreaView style={styles.container}>
Expand All @@ -55,7 +59,7 @@ export default function Game() {
</Text>
<BlackButton text="Exit" onPress={handleExit} />
</View>
<Field field={field} selectedCell={selectedCell} />
<Field field={field} selectedCell={selectedCell} onSelect={handleSelectCell} />
<AvailableValues />
</SafeAreaView>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ const progressHeight = 2;
export const AvailableValuesItemStyles = StyleSheet.create({
button: {
alignItems: 'center',
borderBottomColor: Colors.black,
borderColor: Colors.cell.highlighted,
borderBottomColor: Colors.value.progress,
borderBottomWidth: progressHeight,
borderColor: Colors.value.border,
borderWidth: 1,
height: CellSizeConstant,
justifyContent: 'center',
Expand All @@ -25,7 +26,7 @@ export const AvailableValuesItemStyles = StyleSheet.create({
position: 'absolute',
top: CellSizeConstant - progressHeight
},
text: { color: Colors.black },
text: { color: Colors.value.text },
textActive: {
color: Colors.cell.activeValueText
},
Expand Down
51 changes: 0 additions & 51 deletions components/cell/cell.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ export const CellStyles = StyleSheet.create({
justifyContent: 'center',
width: CellSizeConstant
},
cellActive: {
backgroundColor: Colors.cell.active
},
cellActiveText: {
color: Colors.white
},
Expand Down
58 changes: 58 additions & 0 deletions components/field-cell/cell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { cs, type OnEventFn } from '@rnw-community/shared';
import { memo } from 'react';
import { Pressable, Text } from 'react-native';
import Reanimated, { interpolateColor, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import { BlankCellValueContant } from '../../constants/blank-cell-value.contant';
import { type CellInterface } from '../../interfaces/cell.interface';
import { isGroupEnd } from '../../utils/cell/is-group-end.util';
import { Colors } from '../theme';

import { CellStyles as styles } from './cell.styles';

const ReanimatedPressable = Reanimated.createAnimatedComponent(Pressable);

interface Props {
cell: CellInterface;
onSelect: OnEventFn<CellInterface | undefined>;
isActive: boolean;
isActiveValue: boolean;
isCellHighlighted: boolean;
}

const CellComponent = ({ cell, onSelect, isActive, isActiveValue, isCellHighlighted }: Props) => {
const value = cell.value === BlankCellValueContant ? '' : cell.value.toString();
const isLastRow = cell.y === 8;
const isLastCol = cell.x === 8;

const progress = useSharedValue(0);
const animatedStyles = useAnimatedStyle(() => ({
backgroundColor: interpolateColor(progress.value, [0, 1], [Colors.white, Colors.cell.active])
}));

const handlePress = () => {
progress.value = withTiming(isActive ? 0 : 1, { duration: 500 });

onSelect(isActive ? undefined : cell);
};

const cellStyles = [
styles.cell,
cs(isGroupEnd(cell.x), styles.cellGroupXEnd),
cs(isGroupEnd(cell.y), styles.cellGroupYEnd),
cs(isCellHighlighted, styles.cellHighlighted),
cs(isLastRow, styles.cellLastRow),
cs(isLastCol, styles.cellLastCol),
cs(isActiveValue, styles.cellHighlightedValue),
cs(isActive, animatedStyles)
];
const textStyles = [styles.cellText, cs(isActiveValue, styles.cellHighlightedText), cs(isActive, styles.cellActiveText)];

return (
<ReanimatedPressable style={cellStyles} onPress={handlePress}>
<Text style={textStyles}>{value}</Text>
</ReanimatedPressable>
);
};

export const Cell = memo(CellComponent);
3 changes: 3 additions & 0 deletions components/field/field.styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { StyleSheet } from 'react-native';

export const FieldStyles = StyleSheet.create({
row: {
flexDirection: 'row'
},
wrapper: {
alignItems: 'center',
flex: 5,
Expand Down
22 changes: 19 additions & 3 deletions components/field/field.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import { type OnEventFn } from '@rnw-community/shared';
import { View } from 'react-native';

import { type CellInterface } from '../../interfaces/cell.interface';
import { Row } from '../row/row';
import { isCellHighlighted } from '../../utils/cell/is-cell-highlighted.util';
import { isSameCellValue } from '../../utils/cell/is-same-cell-value.util';
import { isSameCell } from '../../utils/cell/is-same-cell.util';
import { Cell } from '../field-cell/cell';

import { FieldStyles as styles } from './field.styles';

interface Props {
field: CellInterface[][];
selectedCell?: CellInterface;
onSelect: OnEventFn<CellInterface | undefined>;
}

export const Field = ({ field, selectedCell }: Props) => {
export const Field = ({ field, selectedCell, onSelect }: Props) => {
return (
<View style={styles.wrapper}>
{field.map((row, i) => (
<Row key={`row-${i}`} selectedCell={selectedCell} cells={row} />
<View key={`row-${i}`} style={styles.row}>
{row.map(cell => (
<Cell
key={`${cell.x}-${cell.y}`}
cell={cell}
onSelect={onSelect}
isActive={isSameCell(cell, selectedCell)}
isActiveValue={isSameCellValue(cell, selectedCell)}
isCellHighlighted={isCellHighlighted(cell, selectedCell)}
/>
))}
</View>
))}
</View>
);
Expand Down
7 changes: 0 additions & 7 deletions components/row/row.styles.ts

This file was deleted.

25 changes: 0 additions & 25 deletions components/row/row.tsx

This file was deleted.

12 changes: 12 additions & 0 deletions components/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export const WhiteTheme = {
highlighted: 'rgba(0,0,0,0.05)',
highlightedText: 'rgba(0, 255, 0, 1)',
activeValueText: 'rgba(201, 242, 155, 0.5)'
},
value: {
border: 'rgba(0,0,0,0.15)',
progress: 'rgba(0, 255, 0, 0.3)',
progressActive: 'rgba(0, 255, 0, 0.7)',
text: 'rgba(0, 0, 0,1)'
}
}
};
Expand All @@ -27,6 +33,12 @@ export const BlackTheme = {
highlighted: 'rgba(255,255,255,0.15)',
highlightedText: 'rgba(0, 255, 0, 1)',
activeValueText: 'rgba(201, 242, 155, 0.5)'
},
value: {
border: 'rgba(255,255,255,0.15)',
progress: 'rgba(0, 255, 0, 0.3)',
progressActive: 'rgba(0, 255, 0, 0.7)',
text: 'rgba(255, 255, 255,1)'
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions utils/cell/is-cell-highlighted.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { isDefined } from '@rnw-community/shared';

import { type CellInterface } from '../../interfaces/cell.interface';

export const isCellHighlighted = (cell: CellInterface, activeCell?: CellInterface): boolean => {
return isDefined(activeCell) && (activeCell.x === cell.x || activeCell.y === cell.y || activeCell.group === cell.group);
export const isCellHighlighted = (cell: CellInterface, selectedCell?: CellInterface): boolean => {
return isDefined(selectedCell) && (selectedCell.x === cell.x || selectedCell.y === cell.y || selectedCell.group === cell.group);
};
7 changes: 7 additions & 0 deletions utils/cell/is-same-cell-value.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { isDefined } from '@rnw-community/shared';

import { BlankCellValueContant } from '../../constants/blank-cell-value.contant';
import { type CellInterface } from '../../interfaces/cell.interface';

export const isSameCellValue = (cell: CellInterface, selectedCell?: CellInterface): boolean =>
isDefined(selectedCell) && cell.value === selectedCell?.value && cell.value !== BlankCellValueContant;
4 changes: 2 additions & 2 deletions utils/cell/is-same-cell.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import { isDefined } from '@rnw-community/shared';

import { type CellInterface } from '../../interfaces/cell.interface';

export const isSameCell = (cell: CellInterface, comparedCell?: CellInterface): boolean =>
isDefined(comparedCell) && cell.x === comparedCell.x && cell.y === comparedCell.y;
export const isSameCell = (cell: CellInterface, selectedCell?: CellInterface): boolean =>
isDefined(selectedCell) && cell.x === selectedCell.x && cell.y === selectedCell.y;

0 comments on commit b86c3ee

Please sign in to comment.