1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-11-24 08:12:24 +02:00
joplin/ReactNativeClient/src/root.js

222 lines
4.8 KiB
JavaScript
Raw Normal View History

2017-05-09 21:59:14 +02:00
import React, { Component } from 'react';
2017-05-09 22:46:54 +02:00
import { View, Button, TextInput } from 'react-native';
2017-05-09 21:59:14 +02:00
import { connect } from 'react-redux'
import { Provider } from 'react-redux'
import { createStore } from 'redux';
import { combineReducers } from 'redux';
import { StackNavigator } from 'react-navigation';
import { addNavigationHelpers } from 'react-navigation';
2017-05-09 22:46:54 +02:00
import { Log } from 'src/log.js'
2017-05-10 21:21:09 +02:00
import { Note } from 'src/models/note.js'
2017-05-09 22:46:54 +02:00
import { ItemList } from 'src/components/item-list.js'
let defaultState = {
defaultText: 'bla',
notes: [
{ id: 1, title: "hello", body: "just testing\nmultiple\nlines" },
{ id: 2, title: "hello2", body: "2 just testing\nmultiple\nlines" },
{ id: 3, title: "hello3", body: "3 just testing\nmultiple\nlines" },
{ id: 4, title: "hello4", body: "4 just testing\nmultiple\nlines" },
],
selectedNoteId: null,
};
const reducer = (state = defaultState, action) => {
Log.info('Reducer action', action);
2017-05-10 21:21:09 +02:00
let newState = state;
2017-05-09 22:46:54 +02:00
switch (action.type) {
2017-05-10 20:58:02 +02:00
case 'Navigation/NAVIGATE':
case 'Navigation/BACK':
2017-05-09 22:46:54 +02:00
2017-05-10 21:21:09 +02:00
const nextStateNav = AppNavigator.router.getStateForAction(action, state.nav);
newState = Object.assign({}, state);
if (nextStateNav) {
newState.nav = nextStateNav;
}
if (action.noteId) {
newState.selectedNoteId = action.noteId;
}
break;
2017-05-09 22:46:54 +02:00
// Replace all the notes with the provided array
case 'NOTES_UPDATE_ALL':
2017-05-09 22:46:54 +02:00
2017-05-10 21:21:09 +02:00
newState = Object.assign({}, state);
2017-05-11 22:14:01 +02:00
newState.notes = action.notes;
break;
// Insert the note into the note list if it's new, or
// update it if it already exists.
case 'NOTES_UPDATE_ONE':
let newNotes = state.notes.splice(0);
let found = false;
for (let i = 0; i < newNotes.length; i++) {
let n = newNotes[i];
if (n.id == action.note.id) {
newNotes[i] = action.note;
found = true;
break;
}
}
2017-05-10 21:21:09 +02:00
if (!found) newNotes.push(action.note);
2017-05-11 22:14:01 +02:00
newState = Object.assign({}, state);
newState.notes = newNotes;
2017-05-11 22:14:01 +02:00
break;
2017-05-09 22:46:54 +02:00
}
2017-05-10 21:21:09 +02:00
return newState;
2017-05-09 22:46:54 +02:00
}
let store = createStore(reducer);
2017-05-10 21:21:09 +02:00
class NotesScreenComponent extends React.Component {
2017-05-09 22:46:54 +02:00
static navigationOptions = {
title: 'Notes',
};
render() {
const { navigate } = this.props.navigation;
return (
<View style={{flex: 1}}>
<ItemList style={{flex: 1}}/>
<Button
title="Create note"
onPress={() =>
navigate('Note')
}
/>
</View>
);
}
}
2017-05-10 21:21:09 +02:00
const NotesScreen = connect(
(state) => {
return {};
},
(dispatch) => {
return {};
}
)(NotesScreenComponent)
class NoteScreenComponent extends React.Component {
2017-05-10 21:51:43 +02:00
2017-05-09 22:46:54 +02:00
static navigationOptions = {
title: 'Note',
};
2017-05-10 21:51:43 +02:00
constructor() {
super();
this.state = { note: Note.newNote() }
}
componentWillMount() {
this.setState({ note: this.props.note });
}
2017-05-11 22:14:01 +02:00
noteComponent_change = (propName, propValue) => {
2017-05-10 21:51:43 +02:00
this.setState((prevState, props) => {
let note = Object.assign({}, prevState.note);
note[propName] = propValue;
return { note: note }
});
}
2017-05-11 22:14:01 +02:00
title_changeText = (text) => {
this.noteComponent_change('title', text);
2017-05-10 21:51:43 +02:00
}
2017-05-11 22:14:01 +02:00
body_changeText = (text) => {
this.noteComponent_change('body', text);
2017-05-10 21:51:43 +02:00
}
2017-05-11 22:14:01 +02:00
saveNoteButton_press = () => {
// TODO: if state changes are asynchronous, how to be sure that, when
// the button is presssed, this.state.note contains the actual note?
Note.save(this.state.note).then((note) => {
this.props.dispatch({
type: 'NOTES_UPDATE_ONE',
note: note,
});
2017-05-11 22:14:01 +02:00
}).catch((error) => {
Log.warn('Cannot save note', error);
2017-05-11 22:14:01 +02:00
});
}
2017-05-10 21:51:43 +02:00
2017-05-11 22:14:01 +02:00
render() {
2017-05-09 22:46:54 +02:00
return (
<View style={{flex: 1}}>
2017-05-11 22:14:01 +02:00
<TextInput value={this.state.note.title} onChangeText={this.title_changeText} />
<TextInput style={{flex: 1, textAlignVertical: 'top'}} multiline={true} value={this.state.note.body} onChangeText={this.body_changeText} />
<Button title="Save note" onPress={this.saveNoteButton_press} />
2017-05-09 22:46:54 +02:00
</View>
);
}
2017-05-10 21:51:43 +02:00
2017-05-09 21:59:14 +02:00
}
2017-05-10 21:21:09 +02:00
const NoteScreen = connect(
(state) => {
2017-05-10 21:51:43 +02:00
return {
note: state.selectedNoteId ? Note.noteById(state.notes, state.selectedNoteId) : Note.newNote(),
};
2017-05-10 21:21:09 +02:00
}
)(NoteScreenComponent)
2017-05-09 21:59:14 +02:00
const AppNavigator = StackNavigator({
2017-05-09 22:46:54 +02:00
Notes: {screen: NotesScreen},
Note: {screen: NoteScreen},
2017-05-09 21:59:14 +02:00
});
2017-05-10 20:58:02 +02:00
class AppComponent extends React.Component {
2017-05-11 22:14:01 +02:00
componentDidMount() {
Note.previews().then((notes) => {
this.props.dispatch({
type: 'NOTES_UPDATE_ALL',
2017-05-11 22:14:01 +02:00
notes: notes,
});
}).catch((error) => {
Log.warn('Cannot load notes', error);
});
}
render() {
return (
<AppNavigator navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav,
})} />
);
}
2017-05-10 20:58:02 +02:00
}
defaultState.nav = AppNavigator.router.getStateForAction(AppNavigator.router.getActionForPathAndParams('Notes'));
const mapStateToProps = (state) => {
return {
nav: state.nav
};
};
const App = connect(mapStateToProps)(AppComponent);
2017-05-09 22:46:54 +02:00
class Root extends React.Component {
render() {
return (
<Provider store={store}>
2017-05-10 20:58:02 +02:00
<App />
2017-05-09 22:46:54 +02:00
</Provider>
);
}
2017-05-09 21:59:14 +02:00
}
export { Root };