Fixes new tag creation logic
This commit is contained in:
@@ -269,7 +269,7 @@ class FooterCtrl extends PureCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
syncUpdated() {
|
syncUpdated() {
|
||||||
this.lastSyncDate = dateToLocalizedString(new Date());
|
this.lastSyncDate = dateToLocalizedString(this.application.getLastSyncDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
onNewUpdateAvailable() {
|
onNewUpdateAvailable() {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import _ from 'lodash';
|
|
||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
import template from '%/notes.pug';
|
import template from '%/notes.pug';
|
||||||
import { ApplicationEvents, ContentTypes } from 'snjs';
|
import { ApplicationEvents, ContentTypes, removeFromArray } from 'snjs';
|
||||||
import { PureCtrl } from '@Controllers';
|
import { PureCtrl } from '@Controllers';
|
||||||
import { AppStateEvents } from '@/state';
|
import { AppStateEvents } from '@/state';
|
||||||
import { KeyboardModifiers, KeyboardKeys } from '@/services/keyboardManager';
|
import { KeyboardModifiers, KeyboardKeys } from '@/services/keyboardManager';
|
||||||
@@ -104,32 +103,35 @@ class NotesCtrl extends PureCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
onAppEvent(eventName) {
|
async onAppEvent(eventName) {
|
||||||
if (eventName === ApplicationEvents.SignedIn) {
|
if (eventName === ApplicationEvents.SignedIn) {
|
||||||
/** Delete dummy note if applicable */
|
/** Delete dummy note if applicable */
|
||||||
if (this.state.selectedNote && this.state.selectedNote.dummy) {
|
if (this.state.selectedNote && this.state.selectedNote.dummy) {
|
||||||
this.application.deleteItemLocally({ item: this.state.selectedNote });
|
this.application.deleteItemLocally({ item: this.state.selectedNote });
|
||||||
this.selectNote(null).then(() => {
|
await this.selectNote(null);
|
||||||
this.reloadNotes();
|
await 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;
|
|
||||||
}
|
}
|
||||||
} else if (eventName === ApplicationEvents.CompletedSync) {
|
} else if (eventName === ApplicationEvents.CompletedSync) {
|
||||||
if (this.state.notes.length === 0) {
|
if (this.state.notes.length === 0) {
|
||||||
this.createNewNote();
|
await this.createPlaceholderNote();
|
||||||
}
|
}
|
||||||
if (this.createDummyOnSynCompletionIfNoNotes && this.state.notes.length === 0) {
|
} else if (eventName === ApplicationEvents.LocalDataLoaded) {
|
||||||
this.createDummyOnSynCompletionIfNoNotes = false;
|
if (this.application.getLastSyncDate() && this.state.notes.length === 0) {
|
||||||
this.createNewNote();
|
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() {
|
streamNotesAndTags() {
|
||||||
this.application.streamItems({
|
this.application.streamItems({
|
||||||
contentType: [ContentTypes.Note, ContentTypes.Tag],
|
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) {
|
async handleTagChange(tag, previousTag) {
|
||||||
if (this.state.selectedNote && this.state.selectedNote.dummy) {
|
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) {
|
if (previousTag) {
|
||||||
_.pull(previousTag.notes, this.state.selectedNote);
|
removeFromArray(previousTag.notes, this.state.selectedNote);
|
||||||
}
|
}
|
||||||
await this.selectNote(null);
|
await this.selectNote(null);
|
||||||
}
|
}
|
||||||
await this.setState({
|
await this.setState({ tag: tag });
|
||||||
tag: tag
|
|
||||||
});
|
|
||||||
|
|
||||||
this.resetScrollPosition();
|
this.resetScrollPosition();
|
||||||
this.setShowMenuFalse();
|
this.setShowMenuFalse();
|
||||||
await this.setNoteFilterText('');
|
await this.setNoteFilterText('');
|
||||||
this.desktopManager.searchText();
|
this.desktopManager.searchText();
|
||||||
this.resetPagination();
|
this.resetPagination();
|
||||||
|
|
||||||
/* Capture db load state before beginning reloadNotes, since this status may change during reload */
|
/* Capture db load state before beginning reloadNotes, since this status may change during reload */
|
||||||
const dbLoaded = this.application.isDatabaseLoaded();
|
const dbLoaded = this.application.isDatabaseLoaded();
|
||||||
await this.reloadNotes();
|
await this.reloadNotes();
|
||||||
@@ -182,7 +220,7 @@ class NotesCtrl extends PureCtrl {
|
|||||||
this.selectFirstNote();
|
this.selectFirstNote();
|
||||||
} else if (dbLoaded) {
|
} else if (dbLoaded) {
|
||||||
if (!tag.isSmartTag() || tag.content.isAllTag) {
|
if (!tag.isSmartTag() || tag.content.isAllTag) {
|
||||||
this.createNewNote();
|
this.createPlaceholderNote();
|
||||||
} else if (
|
} else if (
|
||||||
this.state.selectedNote &&
|
this.state.selectedNote &&
|
||||||
!this.state.notes.includes(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) {
|
async removeNoteFromList(note) {
|
||||||
const notes = this.state.notes;
|
const notes = this.state.notes;
|
||||||
_.pull(notes, note);
|
removeFromArray(notes, note);
|
||||||
await this.setState({
|
await this.setState({
|
||||||
notes: notes,
|
notes: notes,
|
||||||
renderedNotes: notes.slice(0, this.notesToDisplay)
|
renderedNotes: notes.slice(0, this.notesToDisplay)
|
||||||
@@ -253,12 +283,12 @@ class NotesCtrl extends PureCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleNoteSelection(note) {
|
async handleNoteSelection(note) {
|
||||||
if (this.state.selectedNote === note) {
|
const previousNote = this.state.selectedNote;
|
||||||
|
if (previousNote === note) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const previousNote = this.state.selectedNote;
|
|
||||||
if (previousNote && previousNote.dummy) {
|
if (previousNote && previousNote.dummy) {
|
||||||
this.application.deleteItemLocally({ item: previousNote });
|
await this.application.deleteItemLocally({ item: previousNote });
|
||||||
this.removeNoteFromList(previousNote);
|
this.removeNoteFromList(previousNote);
|
||||||
}
|
}
|
||||||
await this.setState({
|
await this.setState({
|
||||||
@@ -267,7 +297,6 @@ class NotesCtrl extends PureCtrl {
|
|||||||
if (!note) {
|
if (!note) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selectedIndex = Math.max(0, this.displayableNotes().indexOf(note));
|
this.selectedIndex = Math.max(0, this.displayableNotes().indexOf(note));
|
||||||
if (note.content.conflict_of) {
|
if (note.content.conflict_of) {
|
||||||
note.content.conflict_of = null;
|
note.content.conflict_of = null;
|
||||||
@@ -499,7 +528,7 @@ class NotesCtrl extends PureCtrl {
|
|||||||
if (note) {
|
if (note) {
|
||||||
this.selectNote(note);
|
this.selectNote(note);
|
||||||
} else if (!this.state.tag || !this.state.tag.isSmartTag()) {
|
} else if (!this.state.tag || !this.state.tag.isSmartTag()) {
|
||||||
this.createNewNote();
|
this.createPlaceholderNote();
|
||||||
} else {
|
} else {
|
||||||
this.selectNote(null);
|
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() {
|
isFiltering() {
|
||||||
return this.state.noteFilter.text &&
|
return this.state.noteFilter.text &&
|
||||||
this.state.noteFilter.text.length > 0;
|
this.state.noteFilter.text.length > 0;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class TagsPanelCtrl extends PureCtrl {
|
|||||||
super.onAppStart();
|
super.onAppStart();
|
||||||
this.registerComponentHandler();
|
this.registerComponentHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAppLaunch() {
|
onAppLaunch() {
|
||||||
super.onAppLaunch();
|
super.onAppLaunch();
|
||||||
this.loadPreferences();
|
this.loadPreferences();
|
||||||
@@ -47,18 +47,29 @@ class TagsPanelCtrl extends PureCtrl {
|
|||||||
});
|
});
|
||||||
this.selectTag(smartTags[0]);
|
this.selectTag(smartTags[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAppSync() {
|
onAppSync() {
|
||||||
super.onAppSync();
|
super.onAppSync();
|
||||||
this.reloadNoteCounts();
|
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() {
|
beginStreamingItems() {
|
||||||
this.application.streamItems({
|
this.application.streamItems({
|
||||||
contentType: ContentTypes.Tag,
|
contentType: ContentTypes.Tag,
|
||||||
stream: async ({ items }) => {
|
stream: async ({ items }) => {
|
||||||
await this.setState({
|
await this.setState({
|
||||||
tags: this.application.getItems({ contentType: ContentTypes.Tag }),
|
tags: this.getMappedTags(),
|
||||||
smartTags: this.application.getSmartTags(),
|
smartTags: this.application.getSmartTags(),
|
||||||
});
|
});
|
||||||
this.reloadNoteCounts();
|
this.reloadNoteCounts();
|
||||||
@@ -107,7 +118,7 @@ class TagsPanelCtrl extends PureCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadPreferences() {
|
loadPreferences() {
|
||||||
if(!this.panelPuppet.ready) {
|
if (!this.panelPuppet.ready) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const width = this.preferencesManager.getValue(PrefKeys.TagsPanelWidth);
|
const width = this.preferencesManager.getValue(PrefKeys.TagsPanelWidth);
|
||||||
@@ -183,18 +194,16 @@ class TagsPanelCtrl extends PureCtrl {
|
|||||||
if (this.state.editingTag) {
|
if (this.state.editingTag) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const newTag = await this.application.createItem({
|
const newTag = await this.application.createTemplateItem({
|
||||||
contentType: ContentTypes.Tag
|
contentType: ContentTypes.Tag
|
||||||
});
|
});
|
||||||
this.setState({
|
this.setState({
|
||||||
|
tags: [newTag].concat(this.state.tags),
|
||||||
previousTag: this.state.selectedTag,
|
previousTag: this.state.selectedTag,
|
||||||
selectedTag: newTag,
|
selectedTag: newTag,
|
||||||
editingTag: newTag,
|
editingTag: newTag,
|
||||||
newTag: 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) {
|
tagTitleDidChange(tag) {
|
||||||
@@ -206,21 +215,22 @@ class TagsPanelCtrl extends PureCtrl {
|
|||||||
async saveTag($event, tag) {
|
async saveTag($event, tag) {
|
||||||
$event.target.blur();
|
$event.target.blur();
|
||||||
await this.setState({
|
await this.setState({
|
||||||
editingTag: null
|
editingTag: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!tag.title || tag.title.length === 0) {
|
if (!tag.title || tag.title.length === 0) {
|
||||||
|
let newSelectedTag = this.state.selectedTag;
|
||||||
if (this.state.editingTag) {
|
if (this.state.editingTag) {
|
||||||
tag.title = this.editingOriginalName;
|
tag.title = this.editingOriginalName;
|
||||||
this.editingOriginalName = null;
|
this.editingOriginalName = null;
|
||||||
} else if (this.state.newTag) {
|
} else if (this.state.newTag) {
|
||||||
/** @todo Should not be accessing internal function */
|
newSelectedTag = this.state.previousTag;
|
||||||
/** Rely on local state instead of adding to global state */
|
|
||||||
this.application.modelManager.removeItemLocally(tag);
|
|
||||||
this.setState({
|
|
||||||
selectedTag: this.state.previousTag
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
this.setState({ newTag: null });
|
this.setState({
|
||||||
|
newTag: null,
|
||||||
|
selectedTag: newSelectedTag,
|
||||||
|
tags: this.getMappedTags()
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,10 +242,11 @@ class TagsPanelCtrl extends PureCtrl {
|
|||||||
this.application.alertService.alert({
|
this.application.alertService.alert({
|
||||||
text: "A tag with this name already exists."
|
text: "A tag with this name already exists."
|
||||||
});
|
});
|
||||||
/** @todo Should not be accessing internal function */
|
this.setState({
|
||||||
/** Rely on local state instead of adding to global state */
|
newTag: null,
|
||||||
this.application.modelManager.removeItemLocally(tag);
|
tags: this.getMappedTags(),
|
||||||
this.setState({ newTag: null });
|
selectedTag: this.state.previousTag
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +267,6 @@ class TagsPanelCtrl extends PureCtrl {
|
|||||||
|
|
||||||
selectedDeleteTag(tag) {
|
selectedDeleteTag(tag) {
|
||||||
this.removeTag(tag);
|
this.removeTag(tag);
|
||||||
this.selectTag(this.state.smartTags[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeTag(tag) {
|
removeTag(tag) {
|
||||||
@@ -265,6 +275,7 @@ class TagsPanelCtrl extends PureCtrl {
|
|||||||
destructive: true,
|
destructive: true,
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
this.application.deleteItem({ item: tag });
|
this.application.deleteItem({ item: tag });
|
||||||
|
this.selectTag(this.state.smartTags[0]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class RevisionPreviewModalCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async configure() {
|
async configure() {
|
||||||
this.note = await this.application.createItem({
|
this.note = await this.application.createTemplateItem({
|
||||||
contentType: ContentTypes.Note,
|
contentType: ContentTypes.Note,
|
||||||
content: this.content
|
content: this.content
|
||||||
});
|
});
|
||||||
@@ -46,7 +46,7 @@ class RevisionPreviewModalCtrl {
|
|||||||
* interfere with active editor. Be sure to copy only the content, as the top level
|
* 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
|
* 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,
|
contentType: ContentTypes.Component,
|
||||||
content: editorForNote.content
|
content: editorForNote.content
|
||||||
});
|
});
|
||||||
@@ -80,7 +80,7 @@ class RevisionPreviewModalCtrl {
|
|||||||
if (contentCopy.title) {
|
if (contentCopy.title) {
|
||||||
contentCopy.title += " (copy)";
|
contentCopy.title += " (copy)";
|
||||||
}
|
}
|
||||||
item = await this.application.createItem({
|
item = await this.application.createManagedItem({
|
||||||
contentType: 'Note',
|
contentType: 'Note',
|
||||||
content: contentCopy,
|
content: contentCopy,
|
||||||
needsSync: true
|
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