mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-11 18:24:43 +02:00
Support for tags
This commit is contained in:
parent
e128077326
commit
d5e39d153f
@ -31,7 +31,7 @@ class Command extends BaseCommand {
|
||||
|
||||
let tags = await Tag.all();
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
tags[i].notes_ = await Tag.tagNoteIds(tags[i].id);
|
||||
tags[i].notes_ = await Tag.noteIds(tags[i].id);
|
||||
}
|
||||
|
||||
items = items.concat(tags);
|
||||
|
@ -511,24 +511,24 @@ describe('Synchronizer', function() {
|
||||
expect(remoteTag.id).toBe(tag.id);
|
||||
await Tag.addNote(remoteTag.id, n1.id);
|
||||
await Tag.addNote(remoteTag.id, n2.id);
|
||||
let noteIds = await Tag.tagNoteIds(tag.id);
|
||||
let noteIds = await Tag.noteIds(tag.id);
|
||||
expect(noteIds.length).toBe(2);
|
||||
await synchronizer().start();
|
||||
|
||||
await switchClient(1);
|
||||
|
||||
await synchronizer().start();
|
||||
let remoteNoteIds = await Tag.tagNoteIds(tag.id);
|
||||
let remoteNoteIds = await Tag.noteIds(tag.id);
|
||||
expect(remoteNoteIds.length).toBe(2);
|
||||
await Tag.removeNote(tag.id, n1.id);
|
||||
remoteNoteIds = await Tag.tagNoteIds(tag.id);
|
||||
remoteNoteIds = await Tag.noteIds(tag.id);
|
||||
expect(remoteNoteIds.length).toBe(1);
|
||||
await synchronizer().start();
|
||||
|
||||
await switchClient(2);
|
||||
|
||||
await synchronizer().start();
|
||||
noteIds = await Tag.tagNoteIds(tag.id);
|
||||
noteIds = await Tag.noteIds(tag.id);
|
||||
expect(noteIds.length).toBe(1);
|
||||
expect(remoteNoteIds[0]).toBe(noteIds[0]);
|
||||
|
||||
|
@ -307,6 +307,10 @@ class BaseModel {
|
||||
return this.db_;
|
||||
}
|
||||
|
||||
static isReady() {
|
||||
return !!this.db_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BaseModel.TYPE_NOTE = 1;
|
||||
|
@ -5,7 +5,7 @@ const globalStyle = {
|
||||
colorFaded: "#777777", // For less important text
|
||||
fontSize: 10,
|
||||
dividerColor: "#dddddd",
|
||||
selectedColor: '#eeeeee',
|
||||
selectedColor: '#e5e5e5',
|
||||
disabledOpacity: 0.3,
|
||||
|
||||
// For WebView - must correspond to the properties above
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux'
|
||||
import { ListView, Text, TouchableHighlight, Switch, View, StyleSheet } from 'react-native';
|
||||
import { ListView, Text, TouchableHighlight, View, StyleSheet } from 'react-native';
|
||||
import { Log } from 'lib/log.js';
|
||||
import { _ } from 'lib/locale.js';
|
||||
import { Checkbox } from 'lib/components/checkbox.js';
|
||||
@ -39,10 +39,29 @@ class NoteItemComponent extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
async todoCheckbox_change(checked) {
|
||||
if (!this.props.note) return;
|
||||
|
||||
const newNote = {
|
||||
id: this.props.note.id,
|
||||
todo_completed: checked ? time.unixMs() : 0,
|
||||
}
|
||||
await Note.save(newNote);
|
||||
}
|
||||
|
||||
onPress() {
|
||||
if (!this.props.note) return;
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Note',
|
||||
noteId: this.props.note.id,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const note = this.props.note ? this.props.note : {};
|
||||
const onPress = this.props.onPress;
|
||||
const onLongPress = this.props.onLongPress;
|
||||
const onCheckboxChange = this.props.onCheckboxChange;
|
||||
|
||||
const checkboxStyle = !Number(note.is_todo) ? { display: 'none' } : { color: globalStyle.color };
|
||||
@ -51,9 +70,14 @@ class NoteItemComponent extends Component {
|
||||
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">
|
||||
<TouchableHighlight onPress={() => this.onPress()} underlayColor="#0066FF">
|
||||
<View style={ listItemStyle }>
|
||||
<Checkbox style={checkboxStyle} checked={checkboxChecked} onChange={(checked) => { onCheckboxChange(note, checked) }}/><Text style={styles.listItemText}>{note.title}</Text>
|
||||
<Checkbox
|
||||
style={checkboxStyle}
|
||||
checked={checkboxChecked}
|
||||
onChange={(checked) => this.todoCheckbox_change(checked)}
|
||||
/>
|
||||
<Text style={styles.listItemText}>{note.title}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
|
@ -66,21 +66,6 @@ class NoteListComponent extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
async todoCheckbox_change(itemId, checked) {
|
||||
let note = await Note.load(itemId);
|
||||
await Note.save({ id: note.id, todo_completed: checked ? time.unixMs() : 0 });
|
||||
}
|
||||
|
||||
listView_itemPress(noteId) {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Note',
|
||||
noteId: noteId,
|
||||
});
|
||||
}
|
||||
|
||||
listView_itemLongPress(itemId) {}
|
||||
|
||||
render() {
|
||||
// `enableEmptySections` is to fix this warning: https://github.com/FaridSafi/react-native-gifted-listview/issues/39
|
||||
|
||||
@ -89,11 +74,8 @@ class NoteListComponent extends Component {
|
||||
<ListView
|
||||
dataSource={this.state.dataSource}
|
||||
renderRow={(note) => {
|
||||
return <NoteItem
|
||||
note={note}
|
||||
onPress={(note) => this.listView_itemPress(note.id) }
|
||||
onCheckboxChange={(note, checked) => this.todoCheckbox_change(note.id, checked) }
|
||||
/> }}
|
||||
return <NoteItem note={note}/>
|
||||
}}
|
||||
enableEmptySections={true}
|
||||
/>
|
||||
);
|
||||
|
@ -5,6 +5,7 @@ import { reg } from 'lib/registry.js';
|
||||
import { Log } from 'lib/log.js'
|
||||
import { NoteList } from 'lib/components/note-list.js'
|
||||
import { Folder } from 'lib/models/folder.js'
|
||||
import { Tag } from 'lib/models/tag.js'
|
||||
import { Note } from 'lib/models/note.js'
|
||||
import { ScreenHeader } from 'lib/components/screen-header.js';
|
||||
import { MenuOption, Text } from 'react-native-popup-menu';
|
||||
@ -27,7 +28,9 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
async componentWillReceiveProps(newProps) {
|
||||
if (newProps.notesOrder.orderBy != this.props.notesOrder.orderBy ||
|
||||
newProps.notesOrder.orderByDir != this.props.notesOrder.orderByDir ||
|
||||
newProps.selectedFolderId != this.props.selectedFolderId) {
|
||||
newProps.selectedFolderId != this.props.selectedFolderId ||
|
||||
newProps.selectedTagId != this.props.selectedTagId ||
|
||||
newProps.notesParentType != this.props.notesParentType) {
|
||||
await this.refreshNotes(newProps);
|
||||
}
|
||||
}
|
||||
@ -40,16 +43,26 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
orderByDir: props.notesOrder.orderByDir,
|
||||
};
|
||||
|
||||
const parent = this.parentItem(props);
|
||||
|
||||
const source = JSON.stringify({
|
||||
options: options,
|
||||
selectedFolderId: props.selectedFolderId,
|
||||
parentId: parent.id,
|
||||
});
|
||||
|
||||
let folder = Folder.byId(props.folders, props.selectedFolderId);
|
||||
if (source == props.notesSource) {
|
||||
console.info('NO SOURCE CHAGNE');
|
||||
console.info(source);
|
||||
console.info(props.notesSource);
|
||||
return;
|
||||
}
|
||||
|
||||
if (source == props.notesSource) return;
|
||||
|
||||
const notes = await Note.previews(props.selectedFolderId, options);
|
||||
let notes = [];
|
||||
if (props.notesParentType == 'Folder') {
|
||||
notes = await Note.previews(props.selectedFolderId, options);
|
||||
} else {
|
||||
notes = await Tag.notes(props.selectedTagId); // TODO: should also return previews
|
||||
}
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NOTES_UPDATE_ALL',
|
||||
@ -82,18 +95,36 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
menuOptions() {
|
||||
if (this.props.selectedFolderId == Folder.conflictFolderId()) return [];
|
||||
|
||||
return [
|
||||
{ title: _('Delete notebook'), onPress: () => { this.deleteFolder_onPress(this.props.selectedFolderId); } },
|
||||
{ title: _('Edit notebook'), onPress: () => { this.editFolder_onPress(this.props.selectedFolderId); } },
|
||||
];
|
||||
if (this.props.notesParentType == 'Folder') {
|
||||
if (this.props.selectedFolderId == Folder.conflictFolderId()) return [];
|
||||
|
||||
return [
|
||||
{ title: _('Delete notebook'), onPress: () => { this.deleteFolder_onPress(this.props.selectedFolderId); } },
|
||||
{ title: _('Edit notebook'), onPress: () => { this.editFolder_onPress(this.props.selectedFolderId); } },
|
||||
];
|
||||
} else {
|
||||
return []; // TODO
|
||||
}
|
||||
}
|
||||
|
||||
parentItem(props = null) {
|
||||
if (!props) props = this.props;
|
||||
|
||||
let output = null;
|
||||
if (props.notesParentType == 'Folder') {
|
||||
output = Folder.byId(props.folders, props.selectedFolderId);
|
||||
} else if (props.notesParentType == 'Tag') {
|
||||
output = Tag.byId(props.tags, props.selectedTagId);
|
||||
} else {
|
||||
throw new Error('Invalid parent type: ' + props.notesParentType);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
render() {
|
||||
let folder = Folder.byId(this.props.folders, this.props.selectedFolderId);
|
||||
const parent = this.parentItem();
|
||||
|
||||
if (!folder) {
|
||||
if (!parent) {
|
||||
return (
|
||||
<View style={this.styles().screen}>
|
||||
<ScreenHeader title={title} menuOptions={this.menuOptions()} />
|
||||
@ -101,8 +132,8 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
)
|
||||
}
|
||||
|
||||
let title = folder ? folder.title : null;
|
||||
const addFolderNoteButtons = folder.id != Folder.conflictFolderId();
|
||||
let title = parent ? parent.title : null;
|
||||
const addFolderNoteButtons = this.props.selectedFolderId && this.props.selectedFolderId != Folder.conflictFolderId();
|
||||
|
||||
const { navigate } = this.props.navigation;
|
||||
return (
|
||||
@ -120,7 +151,10 @@ const NotesScreen = connect(
|
||||
(state) => {
|
||||
return {
|
||||
folders: state.folders,
|
||||
tags: state.tags,
|
||||
selectedFolderId: state.selectedFolderId,
|
||||
selectedTagId: state.selectedTagId,
|
||||
notesParentType: state.notesParentType,
|
||||
notes: state.notes,
|
||||
notesOrder: state.notesOrder,
|
||||
notesSource: state.notesSource,
|
||||
|
@ -134,9 +134,7 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
<FlatList
|
||||
data={this.state.notes}
|
||||
keyExtractor={(item, index) => item.id}
|
||||
renderItem={(event) => <NoteItem
|
||||
note={event.item}
|
||||
/>}
|
||||
renderItem={(event) => <NoteItem note={event.item}/>}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
76
ReactNativeClient/lib/components/screens/tag.js
Normal file
76
ReactNativeClient/lib/components/screens/tag.js
Normal file
@ -0,0 +1,76 @@
|
||||
import React, { Component } from 'react';
|
||||
import { ListView, StyleSheet, View, TextInput, FlatList, TouchableHighlight } from 'react-native';
|
||||
import { connect } from 'react-redux'
|
||||
import { ScreenHeader } from 'lib/components/screen-header.js';
|
||||
import Icon from 'react-native-vector-icons/Ionicons';
|
||||
import { _ } from 'lib/locale.js';
|
||||
import { Note } from 'lib/models/note.js';
|
||||
import { NoteItem } from 'lib/components/note-item.js';
|
||||
import { BaseScreenComponent } from 'lib/components/base-screen.js';
|
||||
import { globalStyle } from 'lib/components/global-style.js';
|
||||
|
||||
let styles = {
|
||||
body: {
|
||||
flex: 1,
|
||||
},
|
||||
}
|
||||
|
||||
class TagScreenComponent extends BaseScreenComponent {
|
||||
|
||||
static navigationOptions(options) {
|
||||
return { header: null };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.refreshNotes();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
if (newProps.selectedTagId !== this.props.selectedTagId) {
|
||||
this.refreshNotes(newProps);
|
||||
}
|
||||
}
|
||||
|
||||
async refreshNotes(props = null) {
|
||||
if (props === null) props = this.props;
|
||||
|
||||
const source = JSON.stringify({ selectedTagId: props.selectedTagId });
|
||||
if (source == props.tagNotesSource) return;
|
||||
|
||||
const notes = await Tag.notes(props.selectedTagId);
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NOTES_UPDATE_ALL',
|
||||
notes: notes,
|
||||
notesSource: source,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let title = tag ? tag.title : '';
|
||||
|
||||
// <ActionButton addFolderNoteButtons={true} parentFolderId={this.props.selectedFolderId}></ActionButton>
|
||||
|
||||
const { navigate } = this.props.navigation;
|
||||
return (
|
||||
<View style={this.styles().screen}>
|
||||
<ScreenHeader title={title} menuOptions={this.menuOptions()} />
|
||||
<NoteList style={{flex: 1}}/>
|
||||
<DialogBox ref={dialogbox => { this.dialogbox = dialogbox }}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const TagScreen = connect(
|
||||
(state) => {
|
||||
return {
|
||||
tag: tag,
|
||||
notes: state.notes,
|
||||
notesSource: state.notesSource,
|
||||
};
|
||||
}
|
||||
)(TagScreenComponent)
|
||||
|
||||
export { TagScreen };
|
@ -3,6 +3,7 @@ import { TouchableOpacity , Button, Text, Image, StyleSheet, ScrollView, View }
|
||||
import { connect } from 'react-redux'
|
||||
import Icon from 'react-native-vector-icons/Ionicons';
|
||||
import { Log } from 'lib/log.js';
|
||||
import { Tag } from 'lib/models/tag.js';
|
||||
import { Note } from 'lib/models/note.js';
|
||||
import { Setting } from 'lib/models/setting.js';
|
||||
import { FoldersScreenUtils } from 'lib/components/screens/folders-utils.js'
|
||||
@ -11,7 +12,7 @@ import { reg } from 'lib/registry.js';
|
||||
import { _ } from 'lib/locale.js';
|
||||
import { globalStyle } from 'lib/components/global-style.js';
|
||||
|
||||
const styleObject = {
|
||||
let styles = {
|
||||
menu: {
|
||||
flex: 1,
|
||||
backgroundColor: globalStyle.backgroundColor,
|
||||
@ -43,24 +44,39 @@ const styleObject = {
|
||||
paddingRight: globalStyle.marginRight,
|
||||
color: globalStyle.colorFaded,
|
||||
},
|
||||
tagItemList: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap'
|
||||
},
|
||||
};
|
||||
|
||||
styleObject.folderButton = Object.assign({}, styleObject.button);
|
||||
styleObject.folderButtonText = Object.assign({}, styleObject.buttonText);
|
||||
styleObject.folderIcon = Object.assign({}, globalStyle.icon);
|
||||
styleObject.folderIcon.color = '#0072d5';
|
||||
styleObject.syncButton = Object.assign({}, styleObject.button);
|
||||
styleObject.syncButtonText = Object.assign({}, styleObject.buttonText);
|
||||
styleObject.folderButtonSelected = Object.assign({}, styleObject.folderButton);
|
||||
styleObject.folderButtonSelected.backgroundColor = globalStyle.selectedColor;
|
||||
styles.folderButton = Object.assign({}, styles.button);
|
||||
styles.folderButtonText = Object.assign({}, styles.buttonText);
|
||||
styles.folderButtonSelected = Object.assign({}, styles.folderButton);
|
||||
styles.folderButtonSelected.backgroundColor = globalStyle.selectedColor;
|
||||
styles.folderIcon = Object.assign({}, globalStyle.icon);
|
||||
styles.folderIcon.color = '#0072d5';
|
||||
|
||||
const styles = StyleSheet.create(styleObject);
|
||||
styles.tagButton = Object.assign({}, styles.button);
|
||||
styles.tagButtonSelected = Object.assign({}, styles.tagButton);
|
||||
styles.tagButtonSelected.backgroundColor = globalStyle.selectedColor;
|
||||
styles.tagButtonSelected.borderRadius = 1000;
|
||||
styles.tagButtonText = Object.assign({}, styles.buttonText);
|
||||
styles.tagButtonText.flex = 0;
|
||||
|
||||
styles.syncButton = Object.assign({}, styles.button);
|
||||
styles.syncButtonText = Object.assign({}, styles.buttonText);
|
||||
|
||||
styles = StyleSheet.create(styles);
|
||||
|
||||
class SideMenuContentComponent extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { syncReportText: '' };
|
||||
this.state = { syncReportText: '',
|
||||
//width: 0,
|
||||
};
|
||||
}
|
||||
|
||||
folder_press(folder) {
|
||||
@ -73,6 +89,16 @@ class SideMenuContentComponent extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
tag_press(tag) {
|
||||
this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Notes',
|
||||
tagId: tag.id,
|
||||
});
|
||||
}
|
||||
|
||||
async synchronize_press() {
|
||||
if (Setting.value('sync.target') == Setting.SYNC_TARGET_ONEDRIVE && !reg.oneDriveApi().auth()) {
|
||||
this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||
@ -107,6 +133,20 @@ class SideMenuContentComponent extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
tagItem(tag, selected) {
|
||||
const iconComp = <Icon name='md-pricetag' style={styles.folderIcon} />
|
||||
const tagButtonStyle = selected ? styles.tagButtonSelected : styles.tagButton;
|
||||
|
||||
return (
|
||||
<TouchableOpacity key={tag.id} onPress={() => { this.tag_press(tag) }}>
|
||||
<View style={tagButtonStyle}>
|
||||
{ iconComp }
|
||||
<Text numberOfLines={1} style={styles.tagButtonText}>{tag.title}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
synchronizeButton(state) {
|
||||
const title = state == 'sync' ? _('Synchronize') : _('Cancel synchronization');
|
||||
const iconComp = state == 'sync' ? <Icon name='md-sync' style={globalStyle.icon} /> : <Icon name='md-close' style={globalStyle.icon} />;
|
||||
@ -121,6 +161,16 @@ class SideMenuContentComponent extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
makeDivider(key) {
|
||||
return <View style={{ marginTop: 15, marginBottom: 15, flex: -1, borderBottomWidth: 1, borderBottomColor: globalStyle.dividerColor }} key={key}></View>
|
||||
}
|
||||
|
||||
// onLayout(event) {
|
||||
// const newWidth = event.nativeEvent.layout.width;
|
||||
// if (this.state.width == newWidth) return;
|
||||
// this.setState({ width: newWidth });
|
||||
// }
|
||||
|
||||
render() {
|
||||
let items = [];
|
||||
|
||||
@ -130,10 +180,24 @@ class SideMenuContentComponent extends Component {
|
||||
|
||||
for (let i = 0; i < this.props.folders.length; i++) {
|
||||
let folder = this.props.folders[i];
|
||||
items.push(this.folderItem(folder, this.props.selectedFolderId == folder.id));
|
||||
items.push(this.folderItem(folder, this.props.selectedFolderId == folder.id && this.props.notesParentType == 'Folder'));
|
||||
}
|
||||
|
||||
if (items.length) items.push(<View style={{ height: 30, flex: -1 }} key='divider_1'></View>); // DIVIDER
|
||||
if (items.length) items.push(this.makeDivider('divider_1'));
|
||||
|
||||
let tagItems = [];
|
||||
for (let i = 0; i < this.props.tags.length; i++) {
|
||||
const tag = this.props.tags[i];
|
||||
tagItems.push(this.tagItem(tag, this.props.selectedTagId == tag.id && this.props.notesParentType == 'Tag'));
|
||||
}
|
||||
|
||||
items.push(
|
||||
<View style={styles.tagItemList} key="tag_items">
|
||||
{tagItems}
|
||||
</View>
|
||||
);
|
||||
|
||||
if (items.length) items.push(this.makeDivider('divider_2'));
|
||||
|
||||
let lines = Synchronizer.reportToLines(this.props.syncReport);
|
||||
const syncReportText = lines.join("\n");
|
||||
@ -144,6 +208,8 @@ class SideMenuContentComponent extends Component {
|
||||
|
||||
items.push(<View style={{ height: globalStyle.marginBottom }} key='bottom_padding_hack'/>);
|
||||
|
||||
// onLayout={(event) => this.onLayout(event)}
|
||||
|
||||
return (
|
||||
<View style={{flex:1}}>
|
||||
<View style={{flexDirection:'row'}}>
|
||||
@ -161,9 +227,12 @@ const SideMenuContent = connect(
|
||||
(state) => {
|
||||
return {
|
||||
folders: state.folders,
|
||||
tags: state.tags,
|
||||
syncStarted: state.syncStarted,
|
||||
syncReport: state.syncReport,
|
||||
selectedFolderId: state.selectedFolderId,
|
||||
selectedTagId: state.selectedTagId,
|
||||
notesParentType: state.notesParentType,
|
||||
};
|
||||
}
|
||||
)(SideMenuContentComponent)
|
||||
|
@ -21,7 +21,7 @@ class Tag extends BaseItem {
|
||||
return super.serialize(item, 'tag', fieldNames);
|
||||
}
|
||||
|
||||
static async tagNoteIds(tagId) {
|
||||
static async noteIds(tagId) {
|
||||
let rows = await this.db().selectAll('SELECT note_id FROM note_tags WHERE tag_id = ?', [tagId]);
|
||||
let output = [];
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
@ -31,7 +31,7 @@ class Tag extends BaseItem {
|
||||
}
|
||||
|
||||
static async notes(tagId) {
|
||||
let noteIds = await this.tagNoteIds(tagId);
|
||||
let noteIds = await this.noteIds(tagId);
|
||||
if (!noteIds.length) return [];
|
||||
|
||||
return Note.search({
|
||||
|
@ -38,10 +38,13 @@ import { PoorManIntervals } from 'lib/poor-man-intervals.js';
|
||||
let defaultState = {
|
||||
notes: [],
|
||||
notesSource: '',
|
||||
notesParentType: null,
|
||||
folders: [],
|
||||
tags: [],
|
||||
selectedNoteId: null,
|
||||
selectedItemType: 'note',
|
||||
selectedFolderId: null,
|
||||
selectedTagId: null,
|
||||
selectedItemType: 'note',
|
||||
showSideMenu: false,
|
||||
screens: {},
|
||||
loading: true,
|
||||
@ -148,6 +151,12 @@ const reducer = (state = defaultState, action) => {
|
||||
|
||||
if ('folderId' in action) {
|
||||
newState.selectedFolderId = action.folderId;
|
||||
newState.notesParentType = 'Folder';
|
||||
}
|
||||
|
||||
if ('tagId' in action) {
|
||||
newState.selectedTagId = action.tagId;
|
||||
newState.notesParentType = 'Tag';
|
||||
}
|
||||
|
||||
if ('itemType' in action) {
|
||||
@ -229,6 +238,12 @@ const reducer = (state = defaultState, action) => {
|
||||
newState.folders = action.folders;
|
||||
break;
|
||||
|
||||
case 'TAGS_UPDATE_ALL':
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState.tags = action.tags;
|
||||
break;
|
||||
|
||||
case 'FOLDERS_UPDATE_ONE':
|
||||
|
||||
var newFolders = state.folders.splice(0);
|
||||
@ -414,6 +429,13 @@ async function initialize(dispatch, backButtonHandler) {
|
||||
|
||||
await FoldersScreenUtils.refreshFolders();
|
||||
|
||||
const tags = await Tag.all();
|
||||
|
||||
dispatch({
|
||||
type: 'TAGS_UPDATE_ALL',
|
||||
tags: tags,
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: 'APPLICATION_LOADING_DONE',
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user