1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Started config screen

This commit is contained in:
Laurent Cozic 2017-07-23 19:26:50 +01:00
parent d05c62f69f
commit 04cd9a1e7b
7 changed files with 206 additions and 11 deletions

View File

@ -7,6 +7,7 @@ import { Checkbox } from 'lib/components/checkbox.js';
import { NoteItem } from 'lib/components/note-item.js';
import { reg } from 'lib/registry.js';
import { Note } from 'lib/models/note.js';
import { Setting } from 'lib/models/setting.js';
import { time } from 'lib/time-utils.js';
import { globalStyle } from 'lib/components/global-style.js';
@ -33,15 +34,35 @@ class ItemListComponent extends Component {
};
}
filterNotes(notes) {
const todoFilter = Setting.value('todoFilter');
if (todoFilter == 'all') return notes;
const now = time.unixMs();
const maxInterval = 1000 * 60 * 60 * 24 * 2;
const notRecentTime = now - maxInterval;
let output = [];
for (let i = 0; i < notes.length; i++) {
const note = notes[i];
if (note.is_todo) {
if (todoFilter == 'recent' && note.updated_time < notRecentTime) continue;
if (todoFilter == 'nonCompleted' && !!note.todo_completed) continue;
}
output.push(note);
}
return output;
}
componentWillMount() {
const newDataSource = this.state.dataSource.cloneWithRows(this.props.items);
const newDataSource = this.state.dataSource.cloneWithRows(this.filterNotes(this.props.items));
this.state = { dataSource: newDataSource };
}
componentWillReceiveProps(newProps) {
// https://stackoverflow.com/questions/38186114/react-native-redux-and-listview
this.setState({
dataSource: this.state.dataSource.cloneWithRows(newProps.items),
dataSource: this.state.dataSource.cloneWithRows(this.filterNotes(newProps.items)),
});
}
@ -49,7 +70,6 @@ class ItemListComponent extends Component {
let note = await Note.load(itemId);
await Note.save({ id: note.id, todo_completed: checked ? time.unixMs() : 0 });
reg.scheduleSync();
}
listView_itemLongPress(itemId) {}

View File

@ -9,7 +9,7 @@ import { Note } from 'lib/models/note.js';
import { time } from 'lib/time-utils.js';
import { globalStyle } from 'lib/components/global-style.js';
const styleObject = {
let styles = {
listItem: {
flexDirection: 'row',
height: 40,
@ -24,7 +24,10 @@ const styleObject = {
},
};
const styles = StyleSheet.create(styleObject);
styles.listItemFadded = Object.assign({}, styles.listItem);
styles.listItemFadded.opacity = 0.4;
styles = StyleSheet.create(styles);
class NoteItemComponent extends Component {
@ -45,9 +48,11 @@ class NoteItemComponent extends Component {
const checkboxStyle = !Number(note.is_todo) ? { display: 'none' } : { color: globalStyle.color };
const checkboxChecked = !!Number(note.todo_completed);
const listItemStyle = !!Number(note.is_todo) && checkboxChecked ? styles.listItemFadded : styles.listItem;
return (
<TouchableHighlight onPress={() => onPress ? onPress(note) : this.noteItem_press(note.id)} onLongPress={() => onLongPress(note)} underlayColor="#0066FF">
<View style={ styles.listItem }>
<View style={ listItemStyle }>
<Checkbox style={checkboxStyle} checked={checkboxChecked} onChange={(checked) => { onCheckboxChange(note, checked) }}/><Text style={styles.listItemText}>{note.title}</Text>
</View>
</TouchableHighlight>

View File

@ -144,6 +144,13 @@ class ScreenHeaderComponent extends Component {
});
}
config_press() {
this.props.dispatch({
type: 'Navigation/NAVIGATE',
routeName: 'Config',
});
}
render() {
function sideMenuButton(styles, onPress) {
@ -213,6 +220,15 @@ class ScreenHeaderComponent extends Component {
<Text style={styles.contextMenuItemText}>{_('Status')}</Text>
</MenuOption>);
if (menuOptionComponents.length) {
menuOptionComponents.push(<View key={'menuOption_' + key++} style={styles.divider}/>);
}
menuOptionComponents.push(
<MenuOption value={() => this.config_press()} key={'menuOption_' + key++} style={styles.contextMenuItem}>
<Text style={styles.contextMenuItemText}>{_('Configuration')}</Text>
</MenuOption>);
const createTitleComponent = () => {
const p = this.props.titlePicker;
if (p) {

View File

@ -0,0 +1,114 @@
import React, { Component } from 'react';
import { View, StyleSheet, Picker, Text, Button } from 'react-native';
import { connect } from 'react-redux'
import { ScreenHeader } from 'lib/components/screen-header.js';
import { _ } from 'lib/locale.js';
import { BaseScreenComponent } from 'lib/components/base-screen.js';
import { globalStyle } from 'lib/components/global-style.js';
import { Setting } from 'lib/models/setting.js';
let styles = {
body: {}
}
styles = StyleSheet.create(styles);
class ConfigScreenComponent extends BaseScreenComponent {
static navigationOptions(options) {
return { header: null };
}
constructor() {
super();
this.state = {
values: {},
};
}
componentWillMount() {
const settings = Setting.publicSettings(Setting.value('appType'));
let values = {};
for (let key in settings) {
if (!settings.hasOwnProperty(key)) continue;
values[key] = settings[key].value;
}
this.setState({ values: values });
}
settingToComponent(key, setting) {
let output = null;
const updateSettingValue = (key, value) => {
let values = this.state.values;
values[key] = value;
this.setState({ values: values });
}
const value = this.state.values[key];
if (setting.type == 'enum') {
let items = [];
const settingOptions = setting.options();
for (let k in settingOptions) {
if (!settingOptions.hasOwnProperty(k)) continue;
items.push(<Picker.Item label={settingOptions[k]} value={k} key={k}/>);
}
return (
<View key={key}>
<Text key="label">{setting.label()}</Text>
<Picker key="control" selectedValue={value} onValueChange={(itemValue, itemIndex) => updateSettingValue(key, itemValue)} >
{ items }
</Picker>
</View>
);
} else {
//throw new Error('Unsupported setting type: ' + setting.type);
}
return output;
}
saveButton_press() {
const values = this.state.values;
for (let key in values) {
if (!values.hasOwnProperty(key)) continue;
Setting.setValue(key, values[key]);
}
Setting.saveAll();
}
render() {
const settings = Setting.publicSettings(Setting.value('appType'));
let settingComps = [];
for (let key in settings) {
if (!settings.hasOwnProperty(key)) continue;
const comp = this.settingToComponent(key, settings[key]);
if (!comp) continue;
settingComps.push(comp);
}
return (
<View style={this.styles().screen}>
<ScreenHeader navState={this.props.navigation.state} />
<View style={styles.body}>
{ settingComps }
</View>
<Button title={_('Save')} onPress={() => this.saveButton_press()} />
</View>
);
}
}
const ConfigScreen = connect(
(state) => {
return {};
}
)(ConfigScreenComponent)
export { ConfigScreen };

View File

@ -90,8 +90,16 @@ class SearchScreenComponent extends BaseScreenComponent {
let notes = []
if (query) {
let p = query.split(' ');
let temp = [];
for (let i = 0; i < p.length; i++) {
let t = p[i].trim();
if (!t) continue;
temp.push(t);
}
notes = await Note.previews(null, {
anywherePattern: '*' + query + '*',
anywherePattern: '*' + temp.join('*') + '*',
});
}
@ -112,6 +120,7 @@ class SearchScreenComponent extends BaseScreenComponent {
<View style={styles.searchContainer}>
<TextInput
style={styles.searchTextInput}
autoFocus={true}
underlineColorAndroid="#ffffff00"
onSubmitEditing={() => { this.searchTextInput_submit() }}
onChangeText={(text) => this.searchTextInput_changeText(text) }

View File

@ -1,5 +1,6 @@
import { BaseModel } from 'lib/base-model.js';
import { Database } from 'lib/database.js';
import { _ } from 'lib/locale.js';
class Setting extends BaseModel {
@ -120,6 +121,9 @@ class Setting extends BaseModel {
for (let i = 0; i < this.cache_.length; i++) {
let s = Object.assign({}, this.cache_[i]);
delete s.public;
delete s.appTypes;
delete s.label;
delete s.options;
queries.push(Database.insertQuery(this.tableName(), s));
}
@ -141,17 +145,37 @@ class Setting extends BaseModel {
this.updateTimeoutId_ = null;
}
static publicSettings(appType) {
if (!appType) throw new Error('appType is required');
let output = {};
for (let key in Setting.defaults_) {
if (!Setting.defaults_.hasOwnProperty(key)) continue;
let s = Object.assign({}, Setting.defaults_[key]);
if (!s.public) continue;
if (s.appTypes && s.appTypes.indexOf(appType) < 0) continue;
s.value = this.value(key);
output[key] = s;
}
return output;
}
}
Setting.defaults_ = {
'activeFolderId': { value: '', type: 'string', public: false },
'sync.onedrive.auth': { value: '', type: 'string', public: false },
'sync.filesystem.path': { value: '', type: 'string', public: true },
'sync.target': { value: 'onedrive', type: 'string', public: true },
'sync.filesystem.path': { value: '', type: 'string', public: true, appTypes: ['cli'] },
'sync.target': { value: 'onedrive', type: 'string', public: true, label: () => _('Synchronisation target') },
'sync.context': { value: '', type: 'string', public: false },
'editor': { value: '', type: 'string', public: true },
'editor': { value: '', type: 'string', public: true, appTypes: ['cli'] },
'locale': { value: 'en_GB', type: 'string', public: true },
'aliases': { value: '', type: 'string', public: true },
//'aliases': { value: '', type: 'string', public: true },
'todoFilter': { value: 'all', type: 'enum', public: true, appTypes: ['mobile'], label: () => _('Todo filter'), options: () => ({
all: _('Show all'),
recent: _('Non-completed and recently completed ones'),
nonCompleted: _('Non-completed ones only'),
})},
};
// Contains constants that are set by the application and

View File

@ -20,6 +20,7 @@ import { ItemList } from 'lib/components/item-list.js'
import { NotesScreen } from 'lib/components/screens/notes.js'
import { NotesScreenUtils } from 'lib/components/screens/notes-utils.js'
import { NoteScreen } from 'lib/components/screens/note.js'
import { ConfigScreen } from 'lib/components/screens/config.js'
import { FolderScreen } from 'lib/components/screens/folder.js'
import { FoldersScreen } from 'lib/components/screens/folders.js'
import { LogScreen } from 'lib/components/screens/log.js'
@ -409,6 +410,11 @@ async function initialize(dispatch, backButtonHandler) {
let folderId = Setting.value('activeFolderId');
let folder = await Folder.load(folderId);
// dispatch({
// type: 'Navigation/NAVIGATE',
// routeName: 'Config',
// });
if (folder) {
await NotesScreenUtils.openNoteList(folderId);
} else {
@ -490,6 +496,7 @@ class AppComponent extends React.Component {
Log: { screen: LogScreen },
Status: { screen: StatusScreen },
Search: { screen: SearchScreen },
Config: { screen: ConfigScreen },
};
return (