diff --git a/App.js b/App.js index faeda8a..2d49ae4 100644 --- a/App.js +++ b/App.js @@ -1,20 +1,22 @@ -/** - * Sample React Native App - * https://github.com/facebook/react-native - * - * @format - * @flow - */ - import React, { useState } from "react"; +import PropTypes from "prop-types"; import { Appbar, BottomNavigation, Text, Card, + Dialog, + Portal, + Button, + Provider, + RadioButton, + TouchableRipple } from "react-native-paper"; +import { View, StatusBar, StyleSheet } from "react-native"; + import SubjectsContainer from "./containers/SubjectsContainer"; +import themes from "./themes"; function Dummy() { @@ -28,7 +30,32 @@ function Dummy() { ); } -const App = () => { +function ThemePicker({ onPress, selectionIdx }) { + return ( + <> + {themes.map((t, idx) => ( + onPress(t, idx)} + key={idx} + > + + + {t.name} + + + ))} + + ); +} + +ThemePicker.propTypes = { + onPress: PropTypes.func, + selectionIdx: PropTypes.number, +}; + +const App = ({ theme, setTheme }) => { const [ pane, setPane ] = useState({ index: 0, routes: [ @@ -38,30 +65,81 @@ const App = () => { { key: "subjects", title: "Subjects", icon: "book-open" }, ], }); + const [ showDialog, setShowDialog ] = useState(false); + const [ newTheme, setNewTheme ] = useState(themes.findIndex( + i => JSON.stringify(i.theme) === JSON.stringify(theme) + )); const renderScene = BottomNavigation.SceneMap({ add: Dummy, statistics: Dummy, timetable: Dummy, subjects: SubjectsContainer, }); + + function dialogSelection(theme, idx) { + setNewTheme(idx); + setTheme(theme.theme); + } return ( <> - - - - setPane({ - index, - routes: pane.routes - })} - renderScene={renderScene} - shifting={true} + + + + + setShowDialog(true)} + /> + + setPane({ + index, + routes: pane.routes + })} + renderScene={renderScene} + shifting={true} + /> + + setShowDialog(false)}> + Theme + + + + + + + + + ); }; +App.propTypes = { + theme: PropTypes.object, + setTheme: PropTypes.func, +}; + +const styles = StyleSheet.create({ + radio: { + flexDirection: "row", + alignItems: "center", + margin: 5 + } +}); + export default App; diff --git a/AppContainer.js b/AppContainer.js new file mode 100644 index 0000000..56fa097 --- /dev/null +++ b/AppContainer.js @@ -0,0 +1,19 @@ +import { connect } from "react-redux"; +import App from "./App"; +import { setTheme } from "./actions"; + +const mapStateToProps = state => { + return { + theme: state.theme, + }; +}; + +const mapDispatchToProps = dispatch => { + return { + setTheme: theme => dispatch(setTheme(theme)) + }; +}; + +const AppContainer = connect(mapStateToProps, mapDispatchToProps)(App); + +export default AppContainer; diff --git a/actions.js b/actions.js index 0b0e559..49ca980 100644 --- a/actions.js +++ b/actions.js @@ -13,3 +13,10 @@ export function removeSubject(id) { }; } + +export function setTheme(theme) { + return { + type: "SET_THEME", + theme: theme, + }; +} diff --git a/components/Subjects.js b/components/Subjects.js index 75e85bd..fb9d2ca 100644 --- a/components/Subjects.js +++ b/components/Subjects.js @@ -67,6 +67,8 @@ Subjects.propTypes = { const style = StyleSheet.create({ card: { marginTop: 12, + marginLeft: 10, + marginRight: 10, }, text: { marginTop: 12, diff --git a/index.js b/index.js index f41cd4a..02cfecc 100644 --- a/index.js +++ b/index.js @@ -1,40 +1,18 @@ import React from "react"; import {AppRegistry} from "react-native"; -import App from "./App"; +import AppContainer from "./AppContainer"; import {name as appName} from "./app.json"; -import { DarkTheme, Provider } from "react-native-paper"; import { Provider as ReduxProvider } from "react-redux"; import { PersistGate } from "redux-persist/integration/react"; import configureStore from "./configureStore"; const { store, persistor } = configureStore(); -const theme = { - ...DarkTheme, - mode: "exact", - colors: { - primary: "#ededed", - accent: "#1a237e", - backdrop: "rgba(0, 0, 0, 0.5)", - background: "#000000", - disabled: "rgba(255, 255, 255, 0.38)", - error: "#CF6679", - notification: "#ff80ab", - onBackground: "#FFFFFF", - onSurface: "#FFFFFF", - placeholder: "rgba(255, 255, 255, 0.54)", - surface: "#121212", - text: "#ffffff" - } -}; - export default function Main() { return ( - - - + ); diff --git a/reducers/index.js b/reducers/index.js index 5cc5567..30d9cd1 100644 --- a/reducers/index.js +++ b/reducers/index.js @@ -3,11 +3,13 @@ import { combineReducers } from "redux"; import timetable from "./timetable"; import classes from "./classes"; import subjects from "./subjects"; +import theme from "./theme"; const rootReducer = combineReducers({ timetable, classes, subjects, + theme, }); export default rootReducer; diff --git a/reducers/theme.js b/reducers/theme.js new file mode 100644 index 0000000..7b16ad8 --- /dev/null +++ b/reducers/theme.js @@ -0,0 +1,9 @@ +import themes from "../themes"; +export default function theme(state, action) { + if (typeof state === "undefined") + return themes[0].theme; + if (action.type === "SET_THEME") { + return action.theme; + } + return state; +} diff --git a/themes.js b/themes.js new file mode 100644 index 0000000..58c1120 --- /dev/null +++ b/themes.js @@ -0,0 +1,119 @@ +import { DefaultTheme, DarkTheme } from "react-native-paper"; +export default [ + { + "name": "Dark: Pink and Gray", + "theme": { + ...DarkTheme, + mode: "exact", + colors: { + primary: "#ff1744", + accent: "#e0e0e0", + backdrop: "rgba(0, 0, 0, 0.5)", + background: "#000000", + disabled: "rgba(255, 255, 255, 0.38)", + error: "#CF6679", + notification: "#ff80ab", + onBackground: "#FFFFFF", + onSurface: "#FFFFFF", + placeholder: "rgba(255, 255, 255, 0.54)", + surface: "#121212", + text: "#ffffff" + } + } + }, + { + "name": "Dark: Pastel Colors", + "theme": { + ...DarkTheme, + mode: "exact", + colors: { + primary: "#ef9a9a", + accent: "#fce4ec", + backdrop: "rgba(0, 0, 0, 0.5)", + background: "#000000", + disabled: "rgba(255, 255, 255, 0.38)", + error: "#CF6679", + notification: "#ff80ab", + onBackground: "#FFFFFF", + onSurface: "#FFFFFF", + placeholder: "rgba(255, 255, 255, 0.54)", + surface: "#121212", + text: "#ffffff" + } + } + }, + { + "name": "Dark: Pastel Colors 2", + "theme": { + ...DarkTheme, + mode: "exact", + colors: { + primary: "#e0f7fa", + accent: "#ffebee", + backdrop: "rgba(0, 0, 0, 0.5)", + background: "#000000", + disabled: "rgba(255, 255, 255, 0.38)", + error: "#CF6679", + notification: "#ff80ab", + onBackground: "#FFFFFF", + onSurface: "#FFFFFF", + placeholder: "rgba(255, 255, 255, 0.54)", + surface: "#121212", + text: "#ffffff" + } + } + }, + { + "name": "Absolute Dark: Pink and Gray", + "theme": { + ...DarkTheme, + colors: { + ...DarkTheme.colors, + primary: "#ff1744", + accent: "#e0e0e0", + } + } + }, + { + "name": "Absolute Dark: Purple and Gray", + "theme": DarkTheme + }, + { + "name": "Light: Pink and Gray", + "theme": { + ...DefaultTheme, + colors: { + ...DefaultTheme.colors, + primary: "#ff1744", + accent: "#e0e0e0", + } + } + }, + { + "name": "Light: Pastel Colors", + "theme": { + ...DefaultTheme, + mode: "exact", + colors: { + ...DefaultTheme.colors, + primary: "#ef9a9a", + accent: "#fce4ec", + } + } + }, + { + "name": "Light: Pastel Colors 2", + "theme": { + ...DefaultTheme, + colors: { + ...DefaultTheme.colors, + primary: "#ffcccb", + accent: "#fce4ec", + } + } + }, + { + "name": "Light: Purple and Green", + "theme": DefaultTheme + }, +];