1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-09-16 08:56:40 +02:00

handle todos

This commit is contained in:
Laurent Cozic
2017-05-24 20:51:50 +00:00
parent 40dca4348f
commit 607805162a
7 changed files with 116 additions and 36 deletions

View File

@@ -15,12 +15,23 @@ const styles = StyleSheet.create({
class ActionButtonComponent extends React.Component { class ActionButtonComponent extends React.Component {
newTodo_press() {
this.props.dispatch({
type: 'Navigation/NAVIGATE',
routeName: 'Note',
noteId: null,
folderId: this.props.parentFolderId,
itemType: 'todo',
});
}
newNote_press() { newNote_press() {
this.props.dispatch({ this.props.dispatch({
type: 'Navigation/NAVIGATE', type: 'Navigation/NAVIGATE',
routeName: 'Note', routeName: 'Note',
noteId: null, noteId: null,
folderId: this.props.parentFolderId, folderId: this.props.parentFolderId,
itemType: 'note',
}); });
} }
@@ -35,12 +46,19 @@ class ActionButtonComponent extends React.Component {
render() { render() {
return ( return (
<ReactNativeActionButton buttonColor="rgba(231,76,60,1)"> <ReactNativeActionButton buttonColor="rgba(231,76,60,1)">
<ReactNativeActionButton.Item buttonColor='#9b59b6' title="New todo" onPress={() => { this.newTodo_press() }}>
<Icon name="md-checkbox-outline" style={styles.actionButtonIcon} />
</ReactNativeActionButton.Item>
<ReactNativeActionButton.Item buttonColor='#9b59b6' title="New note" onPress={() => { this.newNote_press() }}> <ReactNativeActionButton.Item buttonColor='#9b59b6' title="New note" onPress={() => { this.newNote_press() }}>
<Icon name="md-document" style={styles.actionButtonIcon} /> <Icon name="md-document" style={styles.actionButtonIcon} />
</ReactNativeActionButton.Item> </ReactNativeActionButton.Item>
<ReactNativeActionButton.Item buttonColor='#3498db' title="New folder" onPress={() => { this.newFolder_press() }}> <ReactNativeActionButton.Item buttonColor='#3498db' title="New folder" onPress={() => { this.newFolder_press() }}>
<Icon name="md-folder" style={styles.actionButtonIcon} /> <Icon name="md-folder" style={styles.actionButtonIcon} />
</ReactNativeActionButton.Item> </ReactNativeActionButton.Item>
</ReactNativeActionButton> </ReactNativeActionButton>
); );
} }

View File

@@ -1,36 +1,44 @@
// https://hellokoding.com/todo-app-with-react-native/
import React, { Component } from 'react'; import React, { Component } from 'react';
import Icon from 'react-native-vector-icons/MaterialIcons'; import { StyleSheet, TouchableHighlight } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
const styles = StyleSheet.create({
checkboxIcon: {
fontSize: 20,
height: 22,
marginRight: 10,
},
});
class Checkbox extends Component { class Checkbox extends Component {
constructor(props) {
super(props);
this.state = {
data: this.props.data
};
}
render() { constructor() {
let iconName = 'check-box'; //this.state.data.completed ? 'check-box' : 'check-box-outline-blank'; super();
let color = this.props.color || '#000'; this.state = {
checked: false,
}
}
componentWillMount() {
this.state = { checked: this.props.checked };
}
onPress = () => {
let newChecked = !this.state.checked;
this.setState({ checked: newChecked });
if (this.props.onChange) this.props.onChange(newChecked);
}
render() {
const iconName = this.state.checked ? 'md-checkbox-outline' : 'md-square-outline';
return (
<TouchableHighlight onPress={this.onPress} style={{justifyContent: 'center', alignItems: 'center'}}>
<Icon name={iconName} style={styles.checkboxIcon}/>
</TouchableHighlight>
);
}
return (
<Icon.Button
data={this.state.data}
name={iconName}
backgroundColor='rgba(0,0,0,0)'
color={color}
underlayColor='rgba(0,0,0,0)'
size={20}
iconStyle={{marginLeft: -10, marginRight: 0}}
activeOpacity={1}
borderRadius={5}
onPress={this.props.onCheckboxPressed}
>
</Icon.Button>
);
}
} }
export { Checkbox } export { Checkbox };

View File

@@ -2,8 +2,10 @@ import React, { Component } from 'react';
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { ListView, Text, TouchableHighlight, Switch, View } from 'react-native'; import { ListView, Text, TouchableHighlight, Switch, View } from 'react-native';
import { Log } from 'src/log.js'; import { Log } from 'src/log.js';
import Checkbox from 'react-native-checkbox';
import { _ } from 'src/locale.js'; import { _ } from 'src/locale.js';
import { Checkbox } from 'src/components/checkbox.js';
import { NoteFolderService } from 'src/services/note-folder-service.js';
import { Note } from 'src/models/note.js';
class ItemListComponent extends Component { class ItemListComponent extends Component {
@@ -31,6 +33,14 @@ class ItemListComponent extends Component {
}); });
} }
todoCheckbox_change(itemId, checked) {
Note.load(itemId).then((oldNote) => {
let newNote = Object.assign({}, oldNote);
newNote.todo_completed = checked;
return NoteFolderService.save('note', newNote, oldNote);
});
}
listView_itemPress = (itemId) => {} listView_itemPress = (itemId) => {}
render() { render() {
@@ -41,10 +51,11 @@ class ItemListComponent extends Component {
let onLongPress = () => { let onLongPress = () => {
this.listView_itemLongPress(item.id); this.listView_itemLongPress(item.id);
} }
return ( return (
<TouchableHighlight onPress={onPress} onLongPress={onLongPress}> <TouchableHighlight onPress={onPress} onLongPress={onLongPress}>
<View> <View style={{flexDirection: 'row'}}>
<Text>{item.title} [{item.id}]</Text> { !!Number(item.is_todo) && <Checkbox checked={!!Number(item.todo_completed)} onChange={(checked) => { this.todoCheckbox_change(item.id, checked) }}/> }<Text>{item.title} [{item.id}]</Text>
</View> </View>
</TouchableHighlight> </TouchableHighlight>
); );

View File

@@ -5,6 +5,7 @@ import { Log } from 'src/log.js'
import { Note } from 'src/models/note.js' import { Note } from 'src/models/note.js'
import { Registry } from 'src/registry.js' import { Registry } from 'src/registry.js'
import { ScreenHeader } from 'src/components/screen-header.js'; import { ScreenHeader } from 'src/components/screen-header.js';
import { Checkbox } from 'src/components/checkbox.js'
import { NoteFolderService } from 'src/services/note-folder-service.js'; import { NoteFolderService } from 'src/services/note-folder-service.js';
class NoteScreenComponent extends React.Component { class NoteScreenComponent extends React.Component {
@@ -21,7 +22,9 @@ class NoteScreenComponent extends React.Component {
componentWillMount() { componentWillMount() {
if (!this.props.noteId) { if (!this.props.noteId) {
this.setState({ note: Note.new(this.props.folderId) }); let note = this.props.itemType == 'todo' ? Note.newTodo(this.props.folderId) : Note.new(this.props.folderId);
Log.info(note);
this.setState({ note: note });
} else { } else {
Note.load(this.props.noteId).then((note) => { Note.load(this.props.noteId).then((note) => {
this.originalNote = Object.assign({}, note); this.originalNote = Object.assign({}, note);
@@ -54,11 +57,26 @@ class NoteScreenComponent extends React.Component {
} }
render() { render() {
const note = this.state.note;
const isTodo = !!Number(note.is_todo);
let todoComponents = null;
if (note.is_todo) {
todoComponents = (
<View>
<Button title="test" onPress={this.saveNoteButton_press} />
</View>
);
}
return ( return (
<View style={{flex: 1}}> <View style={{flex: 1}}>
<ScreenHeader navState={this.props.navigation.state} /> <ScreenHeader navState={this.props.navigation.state} />
<TextInput value={this.state.note.title} onChangeText={this.title_changeText} /> <View style={{ flexDirection: 'row' }}>
<TextInput style={{flex: 1, textAlignVertical: 'top'}} multiline={true} value={this.state.note.body} onChangeText={this.body_changeText} /> { isTodo && <Checkbox checked={!!Number(note.todo_completed)} /> }<TextInput style={{flex:1}} value={note.title} onChangeText={this.title_changeText} />
</View>
<TextInput style={{flex: 1, textAlignVertical: 'top'}} multiline={true} value={note.body} onChangeText={this.body_changeText} />
{ todoComponents }
<Button title="Save note" onPress={this.saveNoteButton_press} /> <Button title="Save note" onPress={this.saveNoteButton_press} />
</View> </View>
); );
@@ -71,6 +89,7 @@ const NoteScreen = connect(
return { return {
noteId: state.selectedNoteId, noteId: state.selectedNoteId,
folderId: state.selectedFolderId, folderId: state.selectedFolderId,
itemType: state.selectedItemType,
}; };
} }
)(NoteScreenComponent) )(NoteScreenComponent)

View File

@@ -26,8 +26,14 @@ class Note extends BaseModel {
return output; return output;
} }
static newTodo(parentId = '') {
let output = this.new(parentId);
output.is_todo = true;
return output;
}
static previews(parentId) { static previews(parentId) {
return this.db().selectAll('SELECT id, title, body, parent_id, updated_time FROM notes WHERE parent_id = ?', [parentId]).then((r) => { return this.db().selectAll('SELECT id, title, body, is_todo, todo_completed, parent_id, updated_time FROM notes WHERE parent_id = ?', [parentId]).then((r) => {
let output = []; let output = [];
for (let i = 0; i < r.rows.length; i++) { for (let i = 0; i < r.rows.length; i++) {
output.push(r.rows.item(i)); output.push(r.rows.item(i));

View File

@@ -30,6 +30,7 @@ let defaultState = {
notes: [], notes: [],
folders: [], folders: [],
selectedNoteId: null, selectedNoteId: null,
selectedItemType: 'note',
selectedFolderId: null, selectedFolderId: null,
user: { email: 'laurent@cozic.net', session: null }, user: { email: 'laurent@cozic.net', session: null },
showSideMenu: false, showSideMenu: false,
@@ -62,6 +63,10 @@ const reducer = (state = defaultState, action) => {
newState.selectedFolderId = action.folderId; newState.selectedFolderId = action.folderId;
} }
if ('itemType' in action) {
newState.selectedItemType = action.itemType;
}
if (currentRouteName == action.routeName) { if (currentRouteName == action.routeName) {
// If the current screen is already the requested screen, don't do anything // If the current screen is already the requested screen, don't do anything
} else { } else {
@@ -84,6 +89,8 @@ const reducer = (state = defaultState, action) => {
// update it within the note array if it already exists. // update it within the note array if it already exists.
case 'NOTES_UPDATE_ONE': case 'NOTES_UPDATE_ONE':
Log.info('NOITTEOJTNEONTOE', action.note);
let newNotes = state.notes.splice(0); let newNotes = state.notes.splice(0);
var found = false; var found = false;
for (let i = 0; i < newNotes.length; i++) { for (let i = 0; i < newNotes.length; i++) {

View File

@@ -36,6 +36,17 @@ class NoteFolderService extends BaseService {
}); });
} }
// static setField(type, itemId, fieldName, fieldValue, oldValue = undefined) {
// // TODO: not really consistent as the promise will return 'null' while
// // this.save will return the note or folder. Currently not used, and maybe not needed.
// if (oldValue !== undefined && fieldValue === oldValue) return Promise.resolve();
// let item = { id: itemId };
// item[fieldName] = fieldValue;
// let oldItem = { id: itemId };
// return this.save(type, item, oldItem);
// }
static openNoteList(folderId) { static openNoteList(folderId) {
return Note.previews(folderId).then((notes) => { return Note.previews(folderId).then((notes) => {
this.dispatch({ this.dispatch({