1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-11 18:24:43 +02:00

Refactoring note list

This commit is contained in:
Laurent Cozic 2017-05-15 19:10:00 +00:00
parent e4c0345f4b
commit ae0eac0f3b
11 changed files with 180 additions and 68 deletions

View File

@ -13,6 +13,13 @@ class BaseModel {
return false; return false;
} }
static byId(items, id) {
for (let i = 0; i < items.length; i++) {
if (items[i].id == id) return items[i];
}
return null;
}
static save(o) { static save(o) {
let isNew = !o.id; let isNew = !o.id;
let query = ''; let query = '';

View File

@ -1,31 +0,0 @@
// import React, { Component } from 'react';
// import { connect } from 'react-redux'
// import { Button } from 'react-native';
// import { _ } from 'src/locale.js';
// class CreateNoteButtonComponent extends Component {
// render() {
// return <Button onPress={this.props.onPress} title={_("Create note")} />
// }
// }
// const CreateNoteButton = connect(
// (state) => {
// return {
// selectedNoteId: selectedNoteId,
// };
// },
// (dispatch) => {
// return {
// onPress: function() {
// dispatch({
// type: 'VIEW_NOTE'
// });
// }
// }
// }
// )(CreateNoteButtonComponent)
// export { CreateNoteButton };

View File

@ -13,13 +13,13 @@ class ItemListComponent extends Component {
} }
componentWillMount() { componentWillMount() {
const newDataSource = this.state.dataSource.cloneWithRows(this.props.notes); const newDataSource = this.state.dataSource.cloneWithRows(this.props.items);
this.state = { dataSource: newDataSource }; this.state = { dataSource: newDataSource };
} }
componentWillReceiveProps(newProps) { componentWillReceiveProps(newProps) {
// https://stackoverflow.com/questions/38186114/react-native-redux-and-listview // https://stackoverflow.com/questions/38186114/react-native-redux-and-listview
this.setState({ dataSource: this.state.dataSource.cloneWithRows(newProps.notes) }); this.setState({ dataSource: this.state.dataSource.cloneWithRows(newProps.items) });
} }
render() { render() {
@ -45,21 +45,4 @@ class ItemListComponent extends Component {
} }
} }
const ItemList = connect( export { ItemListComponent };
(state) => {
return { notes: state.notes };
},
(dispatch) => {
return {
onItemClick: (noteId) => {
dispatch({
type: 'Navigation/NAVIGATE',
routeName: 'Note',
noteId: noteId,
});
}
}
}
)(ItemListComponent)
export { ItemList };

View File

@ -0,0 +1,27 @@
import React, { Component } from 'react';
import { connect } from 'react-redux'
import { ListView, Text, TouchableHighlight } from 'react-native';
import { Log } from 'src/log.js';
import { ItemListComponent } from 'src/components/item-list.js';
import { _ } from 'src/locale.js';
class NoteListComponent extends ItemListComponent {}
const NoteList = connect(
(state) => {
return { items: state.notes };
},
(dispatch) => {
return {
onItemClick: (noteId) => {
dispatch({
type: 'Navigation/NAVIGATE',
routeName: 'Note',
noteId: noteId,
});
}
}
}
)(NoteListComponent)
export { NoteList };

View File

@ -0,0 +1,64 @@
import React, { Component } from 'react';
import { View, Button, TextInput } from 'react-native';
import { connect } from 'react-redux'
import { Log } from 'src/log.js'
import { Folder } from 'src/models/folder.js'
class FolderScreenComponent extends React.Component {
static navigationOptions = {
title: 'Folder',
};
constructor() {
super();
this.state = { folder: Folder.newFolder() }
}
componentWillMount() {
this.setState({ folder: this.props.folder });
}
folderComponent_change = (propName, propValue) => {
this.setState((prevState, props) => {
let folder = Object.assign({}, prevState.folder);
folder[propName] = propValue;
return { folder: folder }
});
}
title_changeText = (text) => {
this.folderComponent_change('title', text);
}
saveFolderButton_press = () => {
Folder.save(this.state.folder).then((folder) => {
this.props.dispatch({
type: 'FOLDERS_UPDATE_ONE',
folder: folder,
});
}).catch((error) => {
Log.warn('Cannot save folder', error);
});
}
render() {
return (
<View style={{flex: 1}}>
<TextInput value={this.state.folder.title} onChangeText={this.title_changeText} />
<Button title="Save folder" onPress={this.saveFolderButton_press} />
</View>
);
}
}
const FolderScreen = connect(
(state) => {
return {
folder: state.selectedFolderId ? Folder.byId(state.folders, state.selectedFolderId) : Folder.newFolder(),
};
}
)(FolderScreenComponent)
export { FolderScreen };

View File

@ -61,7 +61,7 @@ class NoteScreenComponent extends React.Component {
const NoteScreen = connect( const NoteScreen = connect(
(state) => { (state) => {
return { return {
note: state.selectedNoteId ? Note.noteById(state.notes, state.selectedNoteId) : Note.newNote(), note: state.selectedNoteId ? Note.byId(state.notes, state.selectedNoteId) : Note.newNote(),
}; };
} }
)(NoteScreenComponent) )(NoteScreenComponent)

View File

@ -1,8 +1,8 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { View, Button } from 'react-native'; import { View, Button, Picker } from 'react-native';
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { Log } from 'src/log.js' import { Log } from 'src/log.js'
import { ItemList } from 'src/components/item-list.js' import { NoteList } from 'src/components/note-list.js'
class NotesScreenComponent extends React.Component { class NotesScreenComponent extends React.Component {
@ -17,6 +17,13 @@ class NotesScreenComponent extends React.Component {
}); });
} }
createFolderButton_press = () => {
this.props.dispatch({
type: 'Navigation/NAVIGATE',
routeName: 'Folder',
});
}
loginButton_press = () => { loginButton_press = () => {
this.props.dispatch({ this.props.dispatch({
type: 'Navigation/NAVIGATE', type: 'Navigation/NAVIGATE',
@ -32,9 +39,10 @@ class NotesScreenComponent extends React.Component {
const { navigate } = this.props.navigation; const { navigate } = this.props.navigation;
return ( return (
<View style={{flex: 1}}> <View style={{flex: 1}}>
<ItemList style={{flex: 1}}/> <NoteList style={{flex: 1}}/>
<View style={{flexDirection: 'row'}}> <View style={{flexDirection: 'row'}}>
<Button title="Create note" onPress={this.createNoteButton_press} /> <Button title="Create note" onPress={this.createNoteButton_press} />
<Button title="Create folder" onPress={this.createFolderButton_press} />
<Button title="Login" onPress={this.loginButton_press} /> <Button title="Login" onPress={this.loginButton_press} />
<Button title="Sync" onPress={this.syncButton_press} /> <Button title="Sync" onPress={this.syncButton_press} />
</View> </View>
@ -45,7 +53,9 @@ class NotesScreenComponent extends React.Component {
const NotesScreen = connect( const NotesScreen = connect(
(state) => { (state) => {
return {}; return {
folders: state.folders
};
} }
)(NotesScreenComponent) )(NotesScreenComponent)

View File

@ -0,0 +1,33 @@
import { BaseModel } from 'src/base-model.js';
import { Log } from 'src/log.js';
class Folder extends BaseModel {
static tableName() {
return 'folders';
}
static useUuid() {
return true;
}
static newFolder() {
return {
id: null,
title: '',
}
}
static all() {
return this.db().selectAll('SELECT * FROM folders').then((r) => {
let output = [];
for (let i = 0; i < r.rows.length; i++) {
output.push(r.rows.item(i));
}
return output;
});
}
}
export { Folder };

View File

@ -11,13 +11,6 @@ class Note extends BaseModel {
return true; return true;
} }
static noteById(notes, id) {
for (let i = 0; i < notes.length; i++) {
if (notes[i].id == id) return notes[i];
}
return null;
}
static newNote() { static newNote() {
return { return {
id: null, id: null,

View File

@ -13,13 +13,21 @@ import { Registry } from 'src/registry.js'
import { ItemList } from 'src/components/item-list.js' import { ItemList } from 'src/components/item-list.js'
import { NotesScreen } from 'src/components/screens/notes.js' import { NotesScreen } from 'src/components/screens/notes.js'
import { NoteScreen } from 'src/components/screens/note.js' import { NoteScreen } from 'src/components/screens/note.js'
import { FolderScreen } from 'src/components/screens/folder.js'
import { LoginScreen } from 'src/components/screens/login.js' import { LoginScreen } from 'src/components/screens/login.js'
import { Setting } from 'src/models/setting.js' import { Setting } from 'src/models/setting.js'
let defaultState = { let defaultState = {
defaultText: 'bla', defaultText: 'bla',
notes: [], notes: [],
folders: [
{ id: 'abcdabcdabcdabcdabcdabcdabcdab01', title: "un" },
{ id: 'abcdabcdabcdabcdabcdabcdabcdab02', title: "deux" },
{ id: 'abcdabcdabcdabcdabcdabcdabcdab03', title: "trois" },
{ id: 'abcdabcdabcdabcdabcdabcdabcdab04', title: "quatre" },
],
selectedNoteId: null, selectedNoteId: null,
selectedFolderId: null,
}; };
const reducer = (state = defaultState, action) => { const reducer = (state = defaultState, action) => {
@ -62,7 +70,7 @@ const reducer = (state = defaultState, action) => {
case 'NOTES_UPDATE_ONE': case 'NOTES_UPDATE_ONE':
let newNotes = state.notes.splice(0); let newNotes = state.notes.splice(0);
let found = false; var found = false;
for (let i = 0; i < newNotes.length; i++) { for (let i = 0; i < newNotes.length; i++) {
let n = newNotes[i]; let n = newNotes[i];
if (n.id == action.note.id) { if (n.id == action.note.id) {
@ -78,6 +86,25 @@ const reducer = (state = defaultState, action) => {
newState.notes = newNotes; newState.notes = newNotes;
break; break;
case 'FOLDERS_UPDATE_ONE':
let newFolders = state.folders.splice(0);
var found = false;
for (let i = 0; i < newFolders.length; i++) {
let n = newFolders[i];
if (n.id == action.folder.id) {
newFolders[i] = action.folder;
found = true;
break;
}
}
if (!found) newFolders.push(action.folder);
newState = Object.assign({}, state);
newState.folders = newFolders;
break;
} }
return newState; return newState;
@ -88,6 +115,7 @@ let store = createStore(reducer);
const AppNavigator = StackNavigator({ const AppNavigator = StackNavigator({
Notes: {screen: NotesScreen}, Notes: {screen: NotesScreen},
Note: {screen: NoteScreen}, Note: {screen: NoteScreen},
Folder: {screen: FolderScreen},
Login: {screen: LoginScreen}, Login: {screen: LoginScreen},
}); });

View File

@ -53,13 +53,11 @@ class WebApi {
let responseClone = response.clone(); let responseClone = response.clone();
return response.json().then(function(data) { return response.json().then(function(data) {
if (data && data.error) { if (data && data.error) {
let e = new Error(data.error); reject(new Error(data.error));
reject(e);
} else { } else {
resolve(data); resolve(data);
} }
}) }).catch(function(error) {
.catch(function(error) {
responseClone.text().then(function(text) { responseClone.text().then(function(text) {
reject(new Error('Cannot parse JSON: ' + text)); reject(new Error('Cannot parse JSON: ' + text));
}); });