app.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import React, { Component } from "react";
  2. import {
  3. AsyncStorage,
  4. Keyboard,
  5. ListView,
  6. Platform,
  7. StyleSheet,
  8. Text,
  9. View
  10. } from "react-native";
  11. import Header from "./header";
  12. import Footer from "./footer";
  13. import Row from "./row";
  14. const styles = StyleSheet.create({
  15. container: {
  16. flex: 1,
  17. backgroundColor: "#F5F5F5",
  18. ...Platform.select({
  19. ios: {
  20. paddingTop: 30
  21. }
  22. })
  23. },
  24. content: {
  25. flex: 1
  26. },
  27. list: {
  28. backgroundColor: "#fff"
  29. },
  30. separator: {
  31. borderWidth: 2,
  32. borderColor: "#eee"
  33. }
  34. });
  35. const filterItems = (filter, items) => {
  36. return items.filter((item) => {
  37. if ((filter === 'ACTIVE' && item.complete) || (filter === 'COMPLETED' && !item.complete)) {
  38. return false;
  39. }
  40. return true;
  41. });
  42. };
  43. class App extends Component {
  44. constructor(props) {
  45. super(props);
  46. const ds = new ListView.DataSource({
  47. rowHasChanged: (r1, r2) => r1 !== r2
  48. });
  49. this.state = {
  50. allComplete: false,
  51. dataSource: ds.cloneWithRows([]),
  52. filter: "ALL",
  53. items: [],
  54. value: ""
  55. };
  56. this.handleAddItem = this.handleAddItem.bind(this);
  57. this.handleClearComplete = this.handleClearComplete.bind(this);
  58. this.handleFilter = this.handleFilter.bind(this);
  59. this.handleRemoveItem = this.handleRemoveItem.bind(this);
  60. this.handleToggleAllComplete = this.handleToggleAllComplete.bind(this);
  61. this.handleToggleComplete = this.handleToggleComplete.bind(this);
  62. this.setSource = this.setSource.bind(this);
  63. }
  64. componentWillMount() {
  65. AsyncStorage.getItem("items").then((json) => {
  66. try {
  67. const items = JSON.parse(json);
  68. this.setSource(items, items);
  69. }
  70. catch (e) {
  71. }
  72. });
  73. }
  74. handleAddItem() {
  75. if (!this.state.value) {
  76. return;
  77. }
  78. const newItems = [
  79. ...this.state.items,
  80. {
  81. key: Date.now(),
  82. text: this.state.value,
  83. complete: false
  84. }
  85. ];
  86. this.setSource(newItems, newItems, { value: "" });
  87. }
  88. handleClearComplete() {
  89. const newItems = filterItems('ACTIVE', this.state.items);
  90. this.setSource(newItems, filterItems(this.state.filter, newItems));
  91. }
  92. handleFilter(filter) {
  93. this.setSource(this.state.items, filterItems(filter, this.state.items), { filter });
  94. }
  95. handleRemoveItem(key) {
  96. const newItems = this.state.items.filter((item) => item.key !== key);
  97. this.setSource(newItems, filterItems(this.state.filter, newItems));
  98. }
  99. handleToggleAllComplete() {
  100. const complete = !this.state.allComplete;
  101. const newItems = this.state.items.map((item) => ({
  102. ...item,
  103. complete
  104. }));
  105. // console.table(newItems);
  106. this.setSource(newItems, filterItems(this.state.filter, newItems), { allComplete: complete });
  107. }
  108. handleToggleComplete(key, complete) {
  109. const newItems = this.state.items.map((item) => {
  110. if (item.key !== key) {
  111. return item;
  112. }
  113. return {
  114. ...item,
  115. complete
  116. };
  117. });
  118. this.setSource(newItems, filterItems(this.state.filter, newItems));
  119. }
  120. render() {
  121. // console.log("App state", this.state);
  122. return (
  123. <View style={styles.container}>
  124. <Header
  125. onAddItem={this.handleAddItem}
  126. onChange={(value) => this.setState({ value })}
  127. onToggleAllComplete={this.handleToggleAllComplete}
  128. value={this.state.value}
  129. />
  130. <View style={styles.content}>
  131. <ListView
  132. enableEmptySections
  133. dataSource={this.state.dataSource}
  134. onScroll={() => Keyboard.dismiss()}
  135. renderRow={({ key, ...value }) => {
  136. // console.log("renderRow", key, value);
  137. return (
  138. <Row
  139. key={key}
  140. onComplete={(complete) => this.handleToggleComplete(key, complete)}
  141. onRemove={() => this.handleRemoveItem(key)}
  142. { ...value }
  143. />
  144. );
  145. }}
  146. renderSeparator={(sectionId, rowId) => {
  147. // console.log('renderSeparator', sectionId, rowId);
  148. return <View key={rowId} style={styles.separator} />;
  149. }}
  150. style={styles.list}
  151. />
  152. </View>
  153. <Footer
  154. count={filterItems("ACTIVE", this.state.items).length}
  155. filter={this.state.filter}
  156. onClearComplete={this.handleClearComplete}
  157. onFilter={this.handleFilter}
  158. />
  159. </View>
  160. );
  161. }
  162. setSource(items, itemsDataSource, otherState = {}) {
  163. this.setState({
  164. items,
  165. dataSource: this.state.dataSource.cloneWithRows(itemsDataSource),
  166. ...otherState
  167. });
  168. AsyncStorage.setItem("items", JSON.stringify(items));
  169. }
  170. }
  171. export default App;