Skip to content

Commit

Permalink
Merge pull request #418 from wyne/color-selection
Browse files Browse the repository at this point in the history
Color Palettes
  • Loading branch information
wyne authored Apr 18, 2024
2 parents fefdc3d + cff1d6c commit 2067168
Show file tree
Hide file tree
Showing 40 changed files with 485 additions and 239 deletions.
11 changes: 6 additions & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@ module.exports = {
'prettier',
],
rules: {
'quotes': ['error', 'single'],
'@typescript-eslint/no-var-requires': 0,
'jest/no-disabled-tests': 0,
'semi': ['error', 'always'],
'eol-last': ['error', 'always'],
'import/order': ['error', {
"pathGroups": [
'pathGroups': [
{
"pattern": "react",
"group": "builtin",
"position": "before"
'pattern': 'react',
'group': 'builtin',
'position': 'before'
}
],
"pathGroupsExcludedImportTypes": ["react"],
'pathGroupsExcludedImportTypes': ['react'],
'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
'alphabetize': {
'order': 'asc',
Expand Down
2 changes: 1 addition & 1 deletion App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { AddendModalContextProvider } from './src/components/Sheets/AddendModalC
import { GameSheetContextProvider } from './src/components/Sheets/GameSheetContext';
import { Navigation } from './src/Navigation';

if (process.env.EXPO_PUBLIC_FIREBASE_ANALYTICS == "false") {
if (process.env.EXPO_PUBLIC_FIREBASE_ANALYTICS == 'false') {
analytics().setAnalyticsCollectionEnabled(false);
}

Expand Down
88 changes: 44 additions & 44 deletions app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,116 +2,116 @@ const variant = process.env.APP_VARIANT;

let packageName;
switch (variant) {
case "development":
packageName = "com.wyne.scorepad.dev";
case 'development':
packageName = 'com.wyne.scorepad.dev';
break;
case "preview":
packageName = "com.wyne.scorepad.preview";
case 'preview':
packageName = 'com.wyne.scorepad.preview';
break;
default:
packageName = "com.wyne.scorepad";
packageName = 'com.wyne.scorepad';
break;
}

let name;
switch (variant) {
case "development":
name = "ScorePad with Rounds (dev)";
case 'development':
name = 'ScorePad with Rounds (dev)';
break;
case "preview":
name = "ScorePad with Rounds (preview)";
case 'preview':
name = 'ScorePad with Rounds (preview)';
break;
default:
name = "ScorePad with Rounds";
name = 'ScorePad with Rounds';
break;
}

let icon;
switch (variant) {
case "development":
icon = "./assets/icon-dev.png";
case 'development':
icon = './assets/icon-dev.png';
break;
case "preview":
icon = "./assets/icon-preview.png";
case 'preview':
icon = './assets/icon-preview.png';
break;
default:
icon = "./assets/icon.png";
icon = './assets/icon.png';
break;
}

let androidIcon;
let androidIconBg;
switch (variant) {
case "development":
androidIcon = "./assets/adaptive-icon-dev.png";
androidIconBg = "./assets/adaptive-icon-bg-dev.png";
case 'development':
androidIcon = './assets/adaptive-icon-dev.png';
androidIconBg = './assets/adaptive-icon-bg-dev.png';
break;
case "preview":
androidIcon = "./assets/adaptive-icon-preview.png";
androidIconBg = "./assets/adaptive-icon-bg-preview.png";
case 'preview':
androidIcon = './assets/adaptive-icon-preview.png';
androidIconBg = './assets/adaptive-icon-bg-preview.png';
break;
default:
androidIcon = "./assets/adaptive-icon.png";
androidIconBg = "./assets/adaptive-icon-bg.png";
androidIcon = './assets/adaptive-icon.png';
androidIconBg = './assets/adaptive-icon-bg.png';
break;
}

export default {
name: name,
slug: "scorepad",
version: "2.5.2",
orientation: "default",
slug: 'scorepad',
version: '2.5.2',
orientation: 'default',
icon: icon,
assetBundlePatterns: ["assets/*"],
backgroundColor: "#000000",
assetBundlePatterns: ['assets/*'],
backgroundColor: '#000000',
ios: {
bundleIdentifier: packageName,
supportsTablet: true,
requireFullScreen: false,
buildNumber: "76",
buildNumber: '76',
infoPlist: {
RCTAsyncStorageExcludeFromBackup: false,
},
googleServicesFile: "./GoogleService-Info.plist",
googleServicesFile: './GoogleService-Info.plist',
},
android: {
icon: androidIcon,
adaptiveIcon: {
foregroundImage: "./assets/adaptive-icon-fg.png",
foregroundImage: './assets/adaptive-icon-fg.png',
backgroundImage: androidIconBg,
},
package: packageName,
permissions: [],
versionCode: 76,
googleServicesFile: "./google-services.json",
googleServicesFile: './google-services.json',
},
userInterfaceStyle: "dark",
userInterfaceStyle: 'dark',
web: {
favicon: "./assets/favicon.png",
favicon: './assets/favicon.png',
},
extra: {
eas: {
projectId: "fc8859ea-b320-41cd-a091-36b3ec7f9b1f",
projectId: 'fc8859ea-b320-41cd-a091-36b3ec7f9b1f',
},
},
updates: {
fallbackToCacheTimeout: 0,
url: "https://u.expo.dev/fc8859ea-b320-41cd-a091-36b3ec7f9b1f",
url: 'https://u.expo.dev/fc8859ea-b320-41cd-a091-36b3ec7f9b1f',
},
runtimeVersion: {
policy: "sdkVersion",
policy: 'sdkVersion',
},
description: "",
githubUrl: "https://github.com/wyne/scorepad-react-native",
owner: "wyne",
description: '',
githubUrl: 'https://github.com/wyne/scorepad-react-native',
owner: 'wyne',
plugins: [
"@react-native-firebase/app",
"@react-native-firebase/crashlytics",
'@react-native-firebase/app',
'@react-native-firebase/crashlytics',
[
"expo-build-properties",
'expo-build-properties',
{
ios: {
useFrameworks: "static",
useFrameworks: 'static',
},
},
],
Expand Down
4 changes: 2 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ module.exports = {
'^.+\\.tsx?$': 'babel-jest',
},
transformIgnorePatterns: [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)'
],
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
setupFilesAfterEnv: [
"@testing-library/jest-native/extend-expect"
'@testing-library/jest-native/extend-expect'
]
};
25 changes: 25 additions & 0 deletions redux/GamesSlice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import analytics from '@react-native-firebase/analytics';
import { PayloadAction, createAsyncThunk, createEntityAdapter, createSelector, createSlice } from '@reduxjs/toolkit';
import { getContrastRatio } from 'colorsheet';
import * as Crypto from 'expo-crypto';

import { getPalette } from '../src/ColorPalette';
import logger from '../src/Logger';

import { ScoreState, playerAdd, selectAllPlayers, selectPlayerById } from './PlayersSlice';
Expand All @@ -16,6 +18,7 @@ export interface GameState {
roundTotal: number;
playerIds: string[];
locked?: boolean;
palette?: string;
}

const gamesAdapter = createEntityAdapter({
Expand Down Expand Up @@ -184,6 +187,28 @@ export const selectSortedPlayers = createSelector(
}
);

const selectPaletteName = (state: RootState, gameId: string) => state.games.entities[gameId]?.palette;
const selectPlayerIndex = (_: RootState, __: string, playerIndex: number) => playerIndex;

export const selectPlayerColors = createSelector(
[selectPaletteName, selectPlayerIndex],
(paletteName, playerIndex) => {
// TODO: Get player color if it exists

const palette = getPalette(paletteName || 'original');

const bg = palette[playerIndex % palette.length];

const blackContrast = getContrastRatio(bg, '#000').number;
const whiteContrast = getContrastRatio(bg, '#fff').number;

// +1 to give a slight preference to white
const fg = blackContrast >= whiteContrast + 1 ? '#000000' : '#FFFFFF';

return [bg, fg];
}
);

export const {
updateGame,
roundNext,
Expand Down
1 change: 1 addition & 0 deletions redux/PlayersSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface ScoreState {
id: string;
playerName: string;
scores: number[];
color?: string;
}

const playersAdapter = createEntityAdapter({
Expand Down
5 changes: 5 additions & 0 deletions redux/SettingsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface SettingsState {
onboarded: string | undefined;
showPointParticles: boolean;
showPlayerIndex: boolean;
showColorPalettes?: boolean;
interactionType: InteractionType;
lastStoreReviewPrompt: number;
};
Expand Down Expand Up @@ -48,6 +49,9 @@ const settingsSlice = createSlice({
toggleShowPlayerIndex(state) {
state.showPlayerIndex = !state.showPlayerIndex;
},
toggleShowColorPalettes(state) {
state.showColorPalettes = !state.showColorPalettes;
},
setMultiplier(state, action: PayloadAction<number>) {
state.multiplier = action.payload;
},
Expand Down Expand Up @@ -80,6 +84,7 @@ export const {
setOnboardedVersion,
toggleShowPointParticles,
toggleShowPlayerIndex,
toggleShowColorPalettes,
setInteractionType,
setLastStoreReviewPrompt,
} = settingsSlice.actions;
Expand Down
3 changes: 2 additions & 1 deletion redux/store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { configureStore } from "@reduxjs/toolkit";
import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistReducer } from 'redux-persist';

import gamesReducer from './GamesSlice';
Expand All @@ -19,6 +19,7 @@ const settingsPersistConfig = {
'onboarded',
'showPointParticles',
'showPlayerIndex',
'showColorPalettes',
'interactionType',
'lastStoreReviewPrompt',
],
Expand Down
Loading

0 comments on commit 2067168

Please sign in to comment.