mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 17:18:52 -06:00
Update
This commit is contained in:
@@ -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,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
32
react-native/package-lock.json
generated
32
react-native/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
128
react-native/src/components/EditHabit/index.js
vendored
Normal file
128
react-native/src/components/EditHabit/index.js
vendored
Normal 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>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
26
react-native/src/components/ListHabits/index.js
vendored
26
react-native/src/components/ListHabits/index.js
vendored
@@ -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,
|
||||
};
|
||||
|
||||
38
react-native/src/components/common/ColorCircle.js
vendored
Normal file
38
react-native/src/components/common/ColorCircle.js
vendored
Normal 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,
|
||||
};
|
||||
1
react-native/src/helpers/FontAwesome.js
vendored
1
react-native/src/helpers/FontAwesome.js
vendored
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
check: '\uf00c',
|
||||
times: '\uf00d',
|
||||
chevronRight: '\uf054',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user