This commit is contained in:
2019-03-23 06:29:32 -05:00
parent 7cab0a39e5
commit a546f6de73
39 changed files with 974 additions and 331 deletions

View File

@@ -3,5 +3,6 @@ module.exports = {
"rules": {
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"import/prefer-default-export": false,
"react/prefer-stateless-function": false,
}
};

View File

@@ -21,23 +21,45 @@ import React from 'react';
import {
AppRegistry,
NavigatorIOS,
NativeModules,
NativeEventEmitter,
} from 'react-native';
import ListHabitsScene from './src/components/ListHabits/index';
import EditHabitScene from './src/components/EditHabit/index';
function RootComponent() {
return (
<NavigatorIOS
translucent={false}
initialRoute={{
component: ListHabitsScene,
title: 'Habits',
rightButtonSystemIcon: 'add',
}}
style={{ flex: 1 }}
/>
);
let navigator;
const routes = {
index: {
component: ListHabitsScene,
title: 'Habits',
rightButtonSystemIcon: 'add',
onRightButtonPress: () => navigator.push(routes.newHabit),
passProps: {
onClickHabit: () => navigator.push(routes.newHabit),
onClickCheckmark: () => {},
},
},
newHabit: {
component: EditHabitScene,
title: 'New Habit',
leftButtonTitle: 'Cancel',
rightButtonTitle: 'Save',
onLeftButtonPress: () => navigator.pop(),
onRightButtonPress: () => navigator.pop(),
},
};
class RootComponent extends React.Component {
render() {
return (
<NavigatorIOS
ref={(c) => { navigator = c; }}
translucent={false}
initialRoute={routes.index}
style={{ flex: 1 }}
/>
);
}
}
AppRegistry.registerComponent('LoopHabitTracker', () => RootComponent);

View File

@@ -4910,38 +4910,6 @@
"color": "^2.0.1"
}
},
"react-native-vector-icons": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-6.1.0.tgz",
"integrity": "sha512-1GF5I4VWgwnzBtVfAKNgEiR5ziHi5QaKL381wwApMzuiFgIJMNt5XIChuKwKoaiB86s+P5iMcYWxYCyENL96lA==",
"requires": {
"lodash": "^4.0.0",
"prop-types": "^15.6.2",
"yargs": "^8.0.2"
},
"dependencies": {
"yargs": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
"integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
"requires": {
"camelcase": "^4.1.0",
"cliui": "^3.2.0",
"decamelize": "^1.1.1",
"get-caller-file": "^1.0.1",
"os-locale": "^2.0.0",
"read-pkg-up": "^2.0.0",
"require-directory": "^2.1.1",
"require-main-filename": "^1.0.1",
"set-blocking": "^2.0.0",
"string-width": "^2.0.0",
"which-module": "^2.0.0",
"y18n": "^3.2.1",
"yargs-parser": "^7.0.0"
}
}
}
},
"react-proxy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/react-proxy/-/react-proxy-1.1.8.tgz",

View File

@@ -9,8 +9,7 @@
"prop-types": "^15.6.2",
"react": "^16.6.3",
"react-native": "^0.57.8",
"react-native-svg": "^9.0.0",
"react-native-vector-icons": "^6.1.0"
"react-native-svg": "^9.0.0"
},
"devDependencies": {
"eslint": "^5.12.1",

View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from 'react';
import {
StyleSheet,
TextInput,
View,
Text,
ScrollView,
TouchableOpacity,
TouchableHighlight,
} from 'react-native';
import FontAwesome from '../../helpers/FontAwesome';
import { Colors } from '../../helpers/Colors';
import ColorCircle from '../common/ColorCircle';
const styles = StyleSheet.create({
container: {
backgroundColor: Colors.appBackground,
flex: 1,
},
item: {
fontSize: 17,
paddingTop: 15,
paddingBottom: 15,
paddingRight: 15,
paddingLeft: 15,
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
label: {
fontSize: 17,
flex: 1,
},
value: {
fontSize: 17,
},
multiline: {
},
middle: {
borderBottomColor: Colors.headerBorderColor,
borderBottomWidth: StyleSheet.hairlineWidth,
},
section: {
backgroundColor: Colors.appBackground,
marginTop: 30,
borderTopColor: Colors.headerBorderColor,
borderTopWidth: StyleSheet.hairlineWidth,
borderBottomColor: Colors.headerBorderColor,
borderBottomWidth: StyleSheet.hairlineWidth,
},
icon: {
fontFamily: 'FontAwesome',
color: Colors.unchecked,
marginLeft: 10,
fontSize: 12,
paddingTop: 2,
},
text: {
borderWidth: 1,
padding: 25,
backgroundColor: '#fff',
},
});
export default class EditHabitsScene extends React.Component {
render() {
return (
<ScrollView style={styles.container}>
<View style={styles.section}>
<TextInput
autoFocus
style={[styles.item, styles.middle, { color: Colors[1] }]}
placeholder="Name"
/>
<TextInput
style={[styles.item]}
placeholder="Question (e.g. Did you exercise today?)"
multiline
/>
</View>
<View style={styles.section}>
<TouchableHighlight onPress={() => {}}>
<View style={[styles.item, styles.middle]}>
<Text style={styles.label}>Color</Text>
<ColorCircle size={20} color={Colors[1]} />
<Text style={styles.icon}>{FontAwesome.chevronRight}</Text>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={() => {}}>
<View style={[styles.item, styles.middle]}>
<Text style={styles.label}>Repeat</Text>
<Text style={styles.value}>Every Day</Text>
<Text style={styles.icon}>{FontAwesome.chevronRight}</Text>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={() => {}}>
<View style={[styles.item, styles.middle]}>
<Text style={styles.label}>Reminder</Text>
<Text style={styles.value}>12:30</Text>
<Text style={styles.icon}>{FontAwesome.chevronRight}</Text>
</View>
</TouchableHighlight>
</View>
</ScrollView>
);
}
}

View File

@@ -29,14 +29,14 @@ import { Colors } from '../../helpers/Colors';
const styles = StyleSheet.create({
checkmarkBox: {
width: 44,
height: 44,
width: 55,
height: 55,
justifyContent: 'center',
alignItems: 'center',
},
checkmark: {
fontFamily: 'FontAwesome',
fontSize: 14,
fontSize: 17,
},
});

View File

@@ -17,12 +17,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import PropTypes from 'prop-types';
import React from 'react';
import {
FlatList,
StyleSheet,
Text,
View,
TouchableHighlight,
TouchableOpacity,
} from 'react-native';
import { Colors } from '../../helpers/Colors';
import { Emitter, Backend } from '../../helpers/Backend';
@@ -32,23 +35,19 @@ import CheckmarkButton from './CheckmarkButton';
const styles = StyleSheet.create({
item: {
backgroundColor: Colors.itemBackground,
padding: 1,
marginTop: 0,
marginBottom: 1,
marginLeft: 0,
marginRight: 0,
elevation: 0,
borderBottomColor: Colors.headerBorderColor,
borderBottomWidth: StyleSheet.hairlineWidth,
flexDirection: 'row',
alignItems: 'stretch',
},
ringContainer: {
width: 35,
height: 45,
width: 40,
height: 55,
justifyContent: 'center',
alignItems: 'center',
},
labelContainer: {
width: 44,
width: 1,
flex: 1,
justifyContent: 'center',
},
@@ -69,38 +68,51 @@ export default class HabitList extends React.Component {
render() {
const { habits } = this.state;
const { onClickHabit, onClickCheckmark } = this.props;
return (
<FlatList
style={styles.container}
data={habits}
renderItem={({ item }) => (
<View style={styles.item}>
<View style={styles.ringContainer}>
<Ring
color={Colors[item.color]}
size={14}
strokeWidth={20}
percentage={Math.random()}
/>
<TouchableHighlight onPress={() => onClickHabit(item.key)}>
<View style={styles.item}>
<View style={styles.ringContainer}>
<Ring
color={Colors[item.color]}
size={14}
strokeWidth={20}
percentage={Math.random()}
/>
</View>
<View style={styles.labelContainer}>
<Text
numberOfLines={2}
style={{
fontSize: 17,
color: Colors[item.color],
}}
>
{item.name}
</Text>
</View>
<TouchableOpacity onPress={() => onClickCheckmark(item.key, 1)}>
<CheckmarkButton color={Colors[item.color]} />
</TouchableOpacity>
<TouchableOpacity onPress={() => onClickCheckmark(item.key, 2)}>
<CheckmarkButton color={Colors[item.color]} />
</TouchableOpacity>
<TouchableOpacity onPress={() => onClickCheckmark(item.key, 3)}>
<CheckmarkButton color={Colors[item.color]} />
</TouchableOpacity>
</View>
<View style={styles.labelContainer}>
<Text
numberOfLines={2}
style={{
fontSize: 14,
color: Colors[item.color],
}}
>
{item.name}
</Text>
</View>
<CheckmarkButton color={Colors[item.color]} />
<CheckmarkButton color={Colors[item.color]} />
<CheckmarkButton color={Colors[item.color]} />
<CheckmarkButton color={Colors[item.color]} />
</View>
</TouchableHighlight>
)}
/>
);
}
}
HabitList.propTypes = {
onClickHabit: PropTypes.func.isRequired,
onClickCheckmark: PropTypes.func.isRequired,
};

View File

@@ -24,7 +24,7 @@ import { Colors } from '../../helpers/Colors';
const styles = StyleSheet.create({
container: {
height: 50,
height: 55,
paddingRight: 1,
backgroundColor: Colors.headerBackground,
flexDirection: 'row',
@@ -35,7 +35,7 @@ const styles = StyleSheet.create({
borderBottomWidth: StyleSheet.hairlineWidth,
},
column: {
width: 44,
width: 55,
alignItems: 'center',
},
text: {
@@ -43,7 +43,7 @@ const styles = StyleSheet.create({
fontWeight: 'bold',
},
dayName: {
fontSize: 10,
fontSize: 12,
},
dayNumber: {
fontSize: 12,
@@ -81,11 +81,6 @@ export default class HabitListHeader extends React.Component {
dayName: 'Thu',
dayNumber: '3',
},
{
dayName: 'Wed',
dayNumber: '2',
},
].map((day) => {
const { dayName, dayNumber } = day;
return HabitListHeader.renderColumn(dayName, dayNumber);

View File

@@ -17,6 +17,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import PropTypes from 'prop-types';
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { Colors } from '../../helpers/Colors';
@@ -30,11 +31,22 @@ const styles = StyleSheet.create({
},
});
export default function ListHabitsScene() {
return (
<View style={styles.container}>
<HabitListHeader />
<HabitList />
</View>
);
export default class ListHabitsScene extends React.Component {
render() {
const { onClickHabit, onClickCheckmark } = this.props;
return (
<View style={styles.container}>
<HabitListHeader />
<HabitList
onClickHabit={onClickHabit}
onClickCheckmark={onClickCheckmark}
/>
</View>
);
}
}
ListHabitsScene.propTypes = {
onClickHabit: PropTypes.func.isRequired,
onClickCheckmark: PropTypes.func.isRequired,
};

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <isoron@gmail.com>
*
* This file is part of Loop Habit Tracker.
*
* Loop Habit Tracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Loop Habit Tracker is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from 'react';
import PropTypes from 'prop-types';
import Svg, { Circle } from 'react-native-svg';
import { Colors } from '../../helpers/Colors';
export default function ColorCircle(props) {
const { size, color } = props;
return (
<Svg height={size} width={size} viewBox="0 0 100 100">
<Circle cx={50} cy={50} r={50} fill={color} />
<Circle cx={50} cy={50} r={30} fill={Colors.itemBackground} />
</Svg>
);
}
ColorCircle.propTypes = {
size: PropTypes.number.isRequired,
color: PropTypes.string.isRequired,
};

View File

@@ -1,4 +1,5 @@
module.exports = {
check: '\uf00c',
times: '\uf00d',
chevronRight: '\uf054',
};