mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Desktop: New: Display selected tags under a note title (#2217)
Follow up to #893 Now using middleware to set the tags when a note is selected This avoids the ugly code in the NoteTextComponent where we determine if tags are to be fetched, identify if they have been modified, fetch them and then dispatch an action to update the store which might again re-render the component. Also implements style related fixes from #1000 Signed-off-by: Abijeet <abijeetpatro@gmail.com> Fixes: #469
This commit is contained in:
parent
42ada7123c
commit
ae3a278ac4
@ -4,7 +4,6 @@ const BaseItem = require('lib/models/BaseItem.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const InteropServiceHelper = require('../InteropServiceHelper.js');
|
||||
@ -81,7 +80,7 @@ class CustomMdMode extends ace.acequire('ace/mode/markdown').Mode {
|
||||
}
|
||||
}
|
||||
|
||||
const NOTE_TAG_BAR_FEATURE_ENABLED = false;
|
||||
const NOTE_TAG_BAR_FEATURE_ENABLED = true;
|
||||
|
||||
class NoteTextComponent extends React.Component {
|
||||
constructor() {
|
||||
@ -539,7 +538,6 @@ class NoteTextComponent extends React.Component {
|
||||
let note = null;
|
||||
let loadingNewNote = true;
|
||||
let parentFolder = null;
|
||||
let noteTags = [];
|
||||
let scrollPercent = 0;
|
||||
|
||||
if (props.newNote) {
|
||||
@ -554,7 +552,6 @@ class NoteTextComponent extends React.Component {
|
||||
if (!scrollPercent) scrollPercent = 0;
|
||||
|
||||
loadingNewNote = stateNoteId !== noteId;
|
||||
noteTags = await Tag.tagsByNoteId(noteId);
|
||||
this.lastLoadedNoteId_ = noteId;
|
||||
note = noteId ? await Note.load(noteId) : null;
|
||||
if (noteId !== this.lastLoadedNoteId_) return defer(); // Race condition - current note was changed while this one was loading
|
||||
@ -633,7 +630,6 @@ class NoteTextComponent extends React.Component {
|
||||
webviewReady: webviewReady,
|
||||
folder: parentFolder,
|
||||
lastKeys: [],
|
||||
noteTags: noteTags,
|
||||
showRevisions: false,
|
||||
};
|
||||
|
||||
@ -654,22 +650,6 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
this.setState(newState);
|
||||
|
||||
// https://github.com/laurent22/joplin/pull/893#discussion_r228025210
|
||||
// @Abijeet: Had to add this check. If not, was going into an infinite loop where state was getting updated repeatedly.
|
||||
// Since I'm updating the state, the componentWillReceiveProps was getting triggered again, where nextProps.newNote was still true, causing reloadNote to trigger again and again.
|
||||
// Notes from Laurent: The selected note tags are part of the global Redux state because they need to be updated whenever tags are changed or deleted
|
||||
// anywhere in the app. Thus it's not possible simple to load the tags here (as we won't have a way to know if they're updated afterwards).
|
||||
// Perhaps a better way would be to move that code in the middleware, check for TAGS_DELETE, TAGS_UPDATE, etc. actions and update the
|
||||
// selected note tags accordingly.
|
||||
if (NOTE_TAG_BAR_FEATURE_ENABLED) {
|
||||
if (!this.props.newNote) {
|
||||
this.props.dispatch({
|
||||
type: 'SET_NOTE_TAGS',
|
||||
items: noteTags,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// if (newState.note) await shared.refreshAttachedResources(this, newState.note.body);
|
||||
|
||||
await this.updateHtml(newState.note ? newState.note.markup_language : null, newState.note ? newState.note.body : '');
|
||||
@ -721,6 +701,18 @@ class NoteTextComponent extends React.Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
canDisplayTagBar() {
|
||||
if (!NOTE_TAG_BAR_FEATURE_ENABLED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.state.noteTags || this.state.noteTags.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async noteRevisionViewer_onBack() {
|
||||
// When coming back from the revision viewer, the webview has been
|
||||
// unmounted so will need to reload. We set webviewReady to false
|
||||
@ -1939,10 +1931,10 @@ class NoteTextComponent extends React.Component {
|
||||
const searchBarHeight = this.state.showLocalSearch ? 35 : 0;
|
||||
|
||||
let bottomRowHeight = 0;
|
||||
if (NOTE_TAG_BAR_FEATURE_ENABLED) {
|
||||
if (this.canDisplayTagBar()) {
|
||||
bottomRowHeight = rootStyle.height - titleBarStyle.height - titleBarStyle.marginBottom - titleBarStyle.marginTop - theme.toolbarHeight - tagStyle.height - tagStyle.marginBottom;
|
||||
} else {
|
||||
toolbarStyle.marginBottom = 10;
|
||||
toolbarStyle.marginBottom = tagStyle.marginBottom,
|
||||
bottomRowHeight = rootStyle.height - titleBarStyle.height - titleBarStyle.marginBottom - titleBarStyle.marginTop - theme.toolbarHeight - toolbarStyle.marginBottom;
|
||||
}
|
||||
|
||||
@ -2061,7 +2053,7 @@ class NoteTextComponent extends React.Component {
|
||||
/>
|
||||
);
|
||||
|
||||
const tagList = !NOTE_TAG_BAR_FEATURE_ENABLED ? null : <TagList style={tagStyle} items={this.state.noteTags} />;
|
||||
const tagList = this.canDisplayTagBar() ? <TagList style={tagStyle} items={this.state.noteTags} /> : null;
|
||||
|
||||
const titleBarMenuButton = (
|
||||
<IconButton
|
||||
|
@ -16,7 +16,7 @@ class TagListComponent extends React.Component {
|
||||
style.fontSize = theme.fontSize;
|
||||
|
||||
const tagItems = [];
|
||||
if (tags || tags.length > 0) {
|
||||
if (tags && tags.length > 0) {
|
||||
// Sort by id for now, but probably needs to be changed in the future.
|
||||
tags.sort((a, b) => {
|
||||
return a.title < b.title ? -1 : +1;
|
||||
@ -31,10 +31,6 @@ class TagListComponent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
if (tagItems.length === 0) {
|
||||
style.visibility = 'hidden';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="tag-list" style={style}>
|
||||
{tagItems}
|
||||
|
@ -28,6 +28,26 @@ const reduxSharedMiddleware = async function(store, next, action) {
|
||||
refreshTags = true;
|
||||
}
|
||||
|
||||
if (action.type === 'NOTE_SELECT' ||
|
||||
action.type === 'NOTE_SELECT_TOGGLE' ||
|
||||
action.type === 'NOTE_SET_NEW_ONE') {
|
||||
let noteTags = [];
|
||||
|
||||
// We don't need to show tags unless only one note is selected.
|
||||
// For new notes, the old note is still selected, but we don't want to show any tags.
|
||||
if (action.type !== 'NOTE_SET_NEW_ONE' &&
|
||||
newState.selectedNoteIds &&
|
||||
newState.selectedNoteIds.length === 1) {
|
||||
noteTags = await Tag.tagsByNoteId(newState.selectedNoteIds[0]);
|
||||
}
|
||||
|
||||
store.dispatch({
|
||||
type: 'SET_NOTE_TAGS',
|
||||
items: noteTags,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (refreshTags) {
|
||||
store.dispatch({
|
||||
type: 'TAG_UPDATE_ALL',
|
||||
@ -37,3 +57,4 @@ const reduxSharedMiddleware = async function(store, next, action) {
|
||||
};
|
||||
|
||||
module.exports = reduxSharedMiddleware;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user