Fixes new tag creation logic
This commit is contained in:
@@ -269,7 +269,7 @@ class FooterCtrl extends PureCtrl {
|
||||
}
|
||||
|
||||
syncUpdated() {
|
||||
this.lastSyncDate = dateToLocalizedString(new Date());
|
||||
this.lastSyncDate = dateToLocalizedString(this.application.getLastSyncDate());
|
||||
}
|
||||
|
||||
onNewUpdateAvailable() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
904
dist/javascripts/app.js
vendored
904
dist/javascripts/app.js
vendored
File diff suppressed because one or more lines are too long
2
dist/javascripts/app.js.map
vendored
2
dist/javascripts/app.js.map
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user