realm-js/examples/ReactExample/components/todo-app.js

226 lines
6.4 KiB
JavaScript
Raw Normal View History

2016-02-18 19:59:34 +00:00
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////
2015-10-27 23:19:30 +00:00
2015-10-07 23:20:05 +00:00
'use strict';
import React from 'react';
import {
Navigator,
Platform,
StatusBar,
Text,
TouchableOpacity,
View,
} from 'react-native';
import TodoItem from './todo-item';
import TodoListView from './todo-listview';
import realm from './realm';
import styles from './styles';
2015-10-07 23:20:05 +00:00
export default class TodoApp extends React.Component {
constructor(props) {
super(props);
2015-10-07 23:20:05 +00:00
2016-10-04 22:02:51 +00:00
// This is a Results object, which will live-update.
this.todoLists = realm.objects('TodoList').sorted('creationDate');
if (this.todoLists.length < 1) {
2015-10-07 23:20:05 +00:00
realm.write(() => {
2016-10-04 22:02:51 +00:00
realm.create('TodoList', {name: 'Todo List', creationDate: new Date()});
2015-10-07 23:20:05 +00:00
});
}
2016-10-04 22:02:51 +00:00
this.todoLists.addListener((name, changes) => {
console.log("changed: " + JSON.stringify(changes));
});
console.log("registered listener");
2015-10-07 23:20:05 +00:00
// Bind all the methods that we will be passing as props.
this.renderScene = this.renderScene.bind(this);
this._addNewTodoList = this._addNewTodoList.bind(this);
this._onPressTodoList = this._onPressTodoList.bind(this);
this.state = {};
2015-10-07 23:20:05 +00:00
}
get currentListView() {
let refs = this.refs.nav.refs;
return refs.listItemView || refs.listView;
}
2015-10-07 23:20:05 +00:00
componentWillMount() {
if (Platform.OS == 'ios') {
StatusBar.setBarStyle('light-content');
}
}
render() {
2016-02-18 05:23:43 +00:00
let objects = realm.objects('Todo');
2015-10-27 10:08:18 +00:00
let extraItems = [
2016-02-18 05:23:43 +00:00
{name: 'Complete', items: objects.filtered('done = true')},
2016-02-18 05:34:41 +00:00
{name: 'Incomplete', items: objects.filtered('done = false')},
2015-10-27 10:08:18 +00:00
];
2015-10-07 23:20:05 +00:00
let route = {
title: 'My Todo Lists',
component: TodoListView,
2015-10-07 23:20:05 +00:00
passProps: {
ref: 'listView',
2015-10-27 10:08:18 +00:00
extraItems: extraItems,
onPressItem: this._onPressTodoList,
2015-10-07 23:20:05 +00:00
},
2015-10-27 10:08:18 +00:00
backButtonTitle: 'Lists',
2015-10-07 23:20:05 +00:00
rightButtonTitle: 'Add',
onRightButtonPress: this._addNewTodoList,
2015-10-07 23:20:05 +00:00
};
let navigationBar = (
<Navigator.NavigationBar routeMapper={RouteMapper} style={styles.navBar} />
);
2015-10-07 23:20:05 +00:00
return (
<Navigator
ref="nav"
initialRoute={route}
navigationBar={navigationBar}
renderScene={this.renderScene}
sceneStyle={styles.navScene}
style={styles.navigator}
/>
2015-10-07 23:20:05 +00:00
);
}
renderScene(route) {
2016-10-04 22:02:51 +00:00
console.log(this.todoLists);
return <route.component items={this.todoLists} {...route.passProps} />
}
_addNewTodoItem(list) {
let items = list.items;
if (!this._shouldAddNewItem(items)) {
return;
}
2015-10-07 23:20:05 +00:00
realm.write(() => {
items.push({text: ''});
2015-10-07 23:20:05 +00:00
});
this._setEditingRow(items.length - 1);
}
_addNewTodoList() {
let items = this.todoLists;
if (!this._shouldAddNewItem(items)) {
return;
}
realm.write(() => {
2016-10-04 22:02:51 +00:00
realm.create('TodoList', {name: '', creationDate: new Date()});
});
this._setEditingRow(items.length - 1);
}
_onPressTodoList(list) {
2015-10-27 10:08:18 +00:00
let items = list.items;
let route = {
title: list.name,
component: TodoListView,
passProps: {
ref: 'listItemView',
2015-10-27 10:08:18 +00:00
items: items,
rowClass: TodoItem,
},
2015-10-27 10:08:18 +00:00
};
// Check if the items are mutable (i.e. List rather than Results).
if (items.push) {
Object.assign(route, {
rightButtonTitle: 'Add',
onRightButtonPress: () => this._addNewTodoItem(list),
});
}
this.refs.nav.push(route);
}
_shouldAddNewItem(items) {
let editingRow = this.currentListView.state.editingRow;
let editingItem = editingRow != null && items[editingRow];
// Don't allow adding a new item if the one being edited is empty.
return !editingItem || !!editingItem.text || !!editingItem.name;
}
_setEditingRow(rowIndex) {
let listView = this.currentListView;
// Update the state on the currently displayed TodoList to edit this new item.
listView.setState({editingRow: rowIndex});
listView.updateDataSource();
2015-10-07 23:20:05 +00:00
}
}
const RouteMapper = {
LeftButton(route, navigator, index, navState) {
if (index == 0) {
return null;
}
let prevRoute = navState.routeStack[index - 1];
return (
<TouchableOpacity onPress={() => navigator.pop()}>
<View style={[styles.navBarView, styles.navBarLeftButton]}>
<Text style={styles.navBarLeftArrow}></Text>
<Text style={styles.navBarText}>
{prevRoute.backButtonTitle || prevRoute.title || 'Back'}
</Text>
</View>
</TouchableOpacity>
);
},
RightButton(route) {
if (!route.rightButtonTitle) {
return null;
}
return (
<TouchableOpacity onPress={route.onRightButtonPress}>
<View style={[styles.navBarView, styles.navBarRightButton]}>
<Text style={styles.navBarText}>
{route.rightButtonTitle}
</Text>
</View>
</TouchableOpacity>
);
},
Title(route) {
return (
<View style={styles.navBarView}>
<Text style={[styles.navBarText, styles.navBarTitleText]}>
{route.title}
</Text>
</View>
);
},
};