Fixes new tag creation logic

This commit is contained in:
Mo Bitar
2020-03-21 11:39:25 -05:00
parent c5d86f16a9
commit ed9da96c3f
6 changed files with 579 additions and 523 deletions

View File

@@ -269,7 +269,7 @@ class FooterCtrl extends PureCtrl {
}
syncUpdated() {
this.lastSyncDate = dateToLocalizedString(new Date());
this.lastSyncDate = dateToLocalizedString(this.application.getLastSyncDate());
}
onNewUpdateAvailable() {

View File

@@ -1,7 +1,6 @@
import _ from 'lodash';
import angular from 'angular';
import template from '%/notes.pug';
import { ApplicationEvents, ContentTypes } from 'snjs';
import { ApplicationEvents, ContentTypes, removeFromArray } from 'snjs';
import { PureCtrl } from '@Controllers';
import { AppStateEvents } from '@/state';
import { KeyboardModifiers, KeyboardKeys } from '@/services/keyboardManager';
@@ -104,32 +103,35 @@ class NotesCtrl extends PureCtrl {
}
/** @override */
onAppEvent(eventName) {
async onAppEvent(eventName) {
if (eventName === ApplicationEvents.SignedIn) {
/** Delete dummy note if applicable */
if (this.state.selectedNote && this.state.selectedNote.dummy) {
this.application.deleteItemLocally({ item: this.state.selectedNote });
this.selectNote(null).then(() => {
this.reloadNotes();
});
/**
* We want to see if the user will download any items from the server.
* If the next sync completes and our notes are still 0,
* we need to create a dummy.
*/
this.createDummyOnSynCompletionIfNoNotes = true;
await this.selectNote(null);
await this.reloadNotes();
}
} else if (eventName === ApplicationEvents.CompletedSync) {
if (this.state.notes.length === 0) {
this.createNewNote();
await this.createPlaceholderNote();
}
if (this.createDummyOnSynCompletionIfNoNotes && this.state.notes.length === 0) {
this.createDummyOnSynCompletionIfNoNotes = false;
this.createNewNote();
} else if (eventName === ApplicationEvents.LocalDataLoaded) {
if (this.application.getLastSyncDate() && this.state.notes.length === 0) {
await this.createPlaceholderNote();
}
}
}
/**
* Triggered programatically to create a new placeholder note
* when conditions allow for it. This is as opposed to creating a new note
* as part of user interaction (pressing the + button).
* @access private
*/
async createPlaceholderNote() {
return this.createNewNote();
}
streamNotesAndTags() {
this.application.streamItems({
contentType: [ContentTypes.Note, ContentTypes.Tag],
@@ -156,24 +158,60 @@ class NotesCtrl extends PureCtrl {
});
}
async selectNote(note) {
this.appState.setSelectedNote(note);
}
async createNewNote() {
const selectedTag = this.appState.getSelectedTag();
if (!selectedTag) {
throw 'Attempting to create note with no selected tag';
}
let title;
let isDummyNote = true;
if (this.isFiltering()) {
title = this.state.noteFilter.text;
isDummyNote = false;
} else if (this.state.selectedNote && this.state.selectedNote.dummy) {
return;
} else {
title = `Note ${this.state.notes.length + 1}`;
}
const newNote = await this.application.createManagedItem({
contentType: ContentTypes.Note,
content: {
text: '',
title: title
},
override: {
dummy: isDummyNote,
client_updated_at: new Date()
}
});
this.application.setItemNeedsSync({ item: newNote });
if (!selectedTag.isSmartTag()) {
selectedTag.addItemAsRelationship(newNote);
this.application.setItemNeedsSync({ item: selectedTag });
}
this.selectNote(newNote);
}
async handleTagChange(tag, previousTag) {
if (this.state.selectedNote && this.state.selectedNote.dummy) {
this.application.deleteItemLocally({ item: this.state.selectedNote });
await this.application.deleteItemLocally({ item: this.state.selectedNote });
if (previousTag) {
_.pull(previousTag.notes, this.state.selectedNote);
removeFromArray(previousTag.notes, this.state.selectedNote);
}
await this.selectNote(null);
}
await this.setState({
tag: tag
});
await this.setState({ tag: tag });
this.resetScrollPosition();
this.setShowMenuFalse();
await this.setNoteFilterText('');
this.desktopManager.searchText();
this.resetPagination();
/* Capture db load state before beginning reloadNotes, since this status may change during reload */
const dbLoaded = this.application.isDatabaseLoaded();
await this.reloadNotes();
@@ -182,7 +220,7 @@ class NotesCtrl extends PureCtrl {
this.selectFirstNote();
} else if (dbLoaded) {
if (!tag.isSmartTag() || tag.content.isAllTag) {
this.createNewNote();
this.createPlaceholderNote();
} else if (
this.state.selectedNote &&
!this.state.notes.includes(this.state.selectedNote)
@@ -200,17 +238,9 @@ class NotesCtrl extends PureCtrl {
}
}
/**
* @template
* @internal
*/
async selectNote(note) {
this.appState.setSelectedNote(note);
}
async removeNoteFromList(note) {
const notes = this.state.notes;
_.pull(notes, note);
removeFromArray(notes, note);
await this.setState({
notes: notes,
renderedNotes: notes.slice(0, this.notesToDisplay)
@@ -253,12 +283,12 @@ class NotesCtrl extends PureCtrl {
}
async handleNoteSelection(note) {
if (this.state.selectedNote === note) {
const previousNote = this.state.selectedNote;
if (previousNote === note) {
return;
}
const previousNote = this.state.selectedNote;
if (previousNote && previousNote.dummy) {
this.application.deleteItemLocally({ item: previousNote });
await this.application.deleteItemLocally({ item: previousNote });
this.removeNoteFromList(previousNote);
}
await this.setState({
@@ -267,7 +297,6 @@ class NotesCtrl extends PureCtrl {
if (!note) {
return;
}
this.selectedIndex = Math.max(0, this.displayableNotes().indexOf(note));
if (note.content.conflict_of) {
note.content.conflict_of = null;
@@ -499,7 +528,7 @@ class NotesCtrl extends PureCtrl {
if (note) {
this.selectNote(note);
} else if (!this.state.tag || !this.state.tag.isSmartTag()) {
this.createNewNote();
this.createPlaceholderNote();
} else {
this.selectNote(null);
}
@@ -516,38 +545,6 @@ class NotesCtrl extends PureCtrl {
}
}
async createNewNote() {
const selectedTag = this.appState.getSelectedTag();
if (!selectedTag) {
throw 'Attempting to create note with no selected tag';
}
let title;
let isDummyNote = true;
if (this.isFiltering()) {
title = this.state.noteFilter.text;
isDummyNote = false;
} else if (this.state.selectedNote && this.state.selectedNote.dummy) {
return;
} else {
title = `Note ${this.state.notes.length + 1}`;
}
const newNote = await this.application.createItem({
contentType: ContentTypes.Note,
content: {
text: '',
title: title
}
});
newNote.client_updated_at = new Date();
newNote.dummy = isDummyNote;
this.application.setItemNeedsSync({ item: newNote });
if (!selectedTag.isSmartTag()) {
selectedTag.addItemAsRelationship(newNote);
this.application.setItemNeedsSync({ item: selectedTag });
}
this.selectNote(newNote);
}
isFiltering() {
return this.state.noteFilter.text &&
this.state.noteFilter.text.length > 0;

View File

@@ -36,7 +36,7 @@ class TagsPanelCtrl extends PureCtrl {
super.onAppStart();
this.registerComponentHandler();
}
onAppLaunch() {
super.onAppLaunch();
this.loadPreferences();
@@ -47,18 +47,29 @@ class TagsPanelCtrl extends PureCtrl {
});
this.selectTag(smartTags[0]);
}
onAppSync() {
super.onAppSync();
this.reloadNoteCounts();
}
/**
* Returns all officially saved tags as reported by the model manager.
* @access private
*/
getMappedTags() {
const tags = this.application.getItems({ contentType: ContentTypes.Tag });
return tags.sort((a, b) => {
return a.content.title < b.content.title ? -1 : 1;
});
}
beginStreamingItems() {
this.application.streamItems({
contentType: ContentTypes.Tag,
stream: async ({ items }) => {
await this.setState({
tags: this.application.getItems({ contentType: ContentTypes.Tag }),
tags: this.getMappedTags(),
smartTags: this.application.getSmartTags(),
});
this.reloadNoteCounts();
@@ -107,7 +118,7 @@ class TagsPanelCtrl extends PureCtrl {
}
loadPreferences() {
if(!this.panelPuppet.ready) {
if (!this.panelPuppet.ready) {
return;
}
const width = this.preferencesManager.getValue(PrefKeys.TagsPanelWidth);
@@ -183,18 +194,16 @@ class TagsPanelCtrl extends PureCtrl {
if (this.state.editingTag) {
return;
}
const newTag = await this.application.createItem({
const newTag = await this.application.createTemplateItem({
contentType: ContentTypes.Tag
});
this.setState({
tags: [newTag].concat(this.state.tags),
previousTag: this.state.selectedTag,
selectedTag: newTag,
editingTag: newTag,
newTag: newTag
});
/** @todo Should not be accessing internal function */
/** Rely on local state instead of adding to global state */
this.application.modelManager.insertItems({ items: [newTag] });
}
tagTitleDidChange(tag) {
@@ -206,21 +215,22 @@ class TagsPanelCtrl extends PureCtrl {
async saveTag($event, tag) {
$event.target.blur();
await this.setState({
editingTag: null
editingTag: null,
});
if (!tag.title || tag.title.length === 0) {
let newSelectedTag = this.state.selectedTag;
if (this.state.editingTag) {
tag.title = this.editingOriginalName;
this.editingOriginalName = null;
} else if (this.state.newTag) {
/** @todo Should not be accessing internal function */
/** Rely on local state instead of adding to global state */
this.application.modelManager.removeItemLocally(tag);
this.setState({
selectedTag: this.state.previousTag
});
newSelectedTag = this.state.previousTag;
}
this.setState({ newTag: null });
this.setState({
newTag: null,
selectedTag: newSelectedTag,
tags: this.getMappedTags()
});
return;
}
@@ -232,10 +242,11 @@ class TagsPanelCtrl extends PureCtrl {
this.application.alertService.alert({
text: "A tag with this name already exists."
});
/** @todo Should not be accessing internal function */
/** Rely on local state instead of adding to global state */
this.application.modelManager.removeItemLocally(tag);
this.setState({ newTag: null });
this.setState({
newTag: null,
tags: this.getMappedTags(),
selectedTag: this.state.previousTag
});
return;
}
@@ -256,7 +267,6 @@ class TagsPanelCtrl extends PureCtrl {
selectedDeleteTag(tag) {
this.removeTag(tag);
this.selectTag(this.state.smartTags[0]);
}
removeTag(tag) {
@@ -265,6 +275,7 @@ class TagsPanelCtrl extends PureCtrl {
destructive: true,
onConfirm: () => {
this.application.deleteItem({ item: tag });
this.selectTag(this.state.smartTags[0]);
}
});
}

View File

@@ -28,7 +28,7 @@ class RevisionPreviewModalCtrl {
}
async configure() {
this.note = await this.application.createItem({
this.note = await this.application.createTemplateItem({
contentType: ContentTypes.Note,
content: this.content
});
@@ -46,7 +46,7 @@ class RevisionPreviewModalCtrl {
* interfere with active editor. Be sure to copy only the content, as the top level
* editor object has non-copyable properties like .window, which cannot be transfered
*/
const editorCopy = await this.application.createItem({
const editorCopy = await this.application.createTemplateItem({
contentType: ContentTypes.Component,
content: editorForNote.content
});
@@ -80,7 +80,7 @@ class RevisionPreviewModalCtrl {
if (contentCopy.title) {
contentCopy.title += " (copy)";
}
item = await this.application.createItem({
item = await this.application.createManagedItem({
contentType: 'Note',
content: contentCopy,
needsSync: true

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long