basic bookmark support

This commit is contained in:
zadam 2021-10-05 22:08:02 +02:00
parent 0654dc855f
commit 8d42ffca6d
9 changed files with 214 additions and 31 deletions

38
package-lock.json generated
View file

@ -1602,16 +1602,16 @@
"integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
},
"browserslist": {
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.2.tgz",
"integrity": "sha512-jSDZyqJmkKMEMi7SZAgX5UltFdR5NAO43vY0AwTpu4X3sGH7GLLQ83KiUomgrnvZRCeW0yPPnKqnxPqQOER9zQ==",
"version": "4.17.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz",
"integrity": "sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001261",
"electron-to-chromium": "^1.3.854",
"caniuse-lite": "^1.0.30001264",
"electron-to-chromium": "^1.3.857",
"escalade": "^3.1.1",
"nanocolors": "^0.2.12",
"node-releases": "^1.1.76"
"node-releases": "^1.1.77",
"picocolors": "^0.2.1"
}
},
"buffer": {
@ -3578,9 +3578,9 @@
}
},
"electron-to-chromium": {
"version": "1.3.857",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.857.tgz",
"integrity": "sha512-a5kIr2lajm4bJ5E4D3fp8Y/BRB0Dx2VOcCRE5Gtb679mXIME/OFhWler8Gy2ksrf8gFX+EFCSIGA33FB3gqYpg==",
"version": "1.3.859",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.859.tgz",
"integrity": "sha512-gXRXKNWedfdiKIzwr0Mg/VGCvxXzy+4SuK9hp1BDvfbCwx0O5Ot+2f4CoqQkqEJ3Zj/eAV/GoAFgBVFgkBLXuQ==",
"dev": true
},
"electron-window-state": {
@ -5824,12 +5824,6 @@
"xtend": "^4.0.0"
}
},
"nanocolors": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.12.tgz",
"integrity": "sha512-SFNdALvzW+rVlzqexid6epYdt8H9Zol7xDoQarioEFcFN0JHo4CYNztAxmtfgGTVRCmFlEOqqhBpoFGKqSAMug==",
"dev": true
},
"nanoid": {
"version": "3.1.25",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz",
@ -6363,6 +6357,12 @@
"resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz",
"integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA=="
},
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
"dev": true
},
"picomatch": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
@ -8098,9 +8098,9 @@
"integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w=="
},
"webpack": {
"version": "5.56.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.56.1.tgz",
"integrity": "sha512-MRbTPooHJuSAfbx7Lh/qEMRUe/d0p4cRj2GPo/fq+4JUeR/+Q1EfLvS1lexslbMcJZyPXxxz/k/NzVepkA5upA==",
"version": "5.57.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.57.0.tgz",
"integrity": "sha512-kbKX1HOJpEhX9GZDFgHauU/7HfgGeGzUzjSUV+wZjGxP3PFeau7BgYFtm5+UTtJJSqmXYKFuBpWRDrSdQ3d8zA==",
"dev": true,
"requires": {
"@types/eslint-scope": "^3.7.0",

View file

@ -90,7 +90,7 @@
"jsdoc": "3.6.7",
"lorem-ipsum": "2.0.4",
"rcedit": "3.0.1",
"webpack": "5.56.1",
"webpack": "5.57.0",
"webpack-cli": "4.8.0"
},
"optionalDependencies": {

View file

@ -140,6 +140,10 @@ function getSomePathInner(note, path, respectHoisting) {
path.push(note.noteId);
path.reverse();
if (path.includes("hidden")) {
return false;
}
if (respectHoisting && !path.includes(cls.getHoistedNoteId())) {
return false;
}

View file

@ -44,6 +44,7 @@ import CalendarMenuWidget from "../widgets/buttons/calendar_menu.js";
import EditedNotesWidget from "../widgets/ribbon_widgets/edited_notes.js";
import OpenNoteButtonWidget from "../widgets/buttons/open_note_button_widget.js";
import MermaidWidget from "../widgets/mermaid.js";
import BookmarkButtons from "../widgets/bookmark_buttons.js";
export default class DesktopLayout {
constructor(customWidgets) {
@ -72,8 +73,6 @@ export default class DesktopLayout {
.title("Jump to note")
.command("jumpToNote"))
.child(new OpenNoteButtonWidget()
.icon("bx-map-alt")
.title("Global note map")
.targetNote('globalnotemap'))
.child(new ButtonWidget()
.icon("bx-history")
@ -84,6 +83,7 @@ export default class DesktopLayout {
.child(new FlexContainer("column")
.id("plugin-buttons")
.contentSized())
.child(new BookmarkButtons())
.child(new SpacerWidget(0, 1000))
.child(new ProtectedSessionStatusWidget())
.child(new SyncStatusWidget())

View file

@ -0,0 +1,52 @@
import FlexContainer from "./containers/flex_container.js";
import searchService from "../services/search.js";
import OpenNoteButtonWidget from "./buttons/open_note_button_widget.js";
export default class BookmarkButtons extends FlexContainer {
constructor() {
super("column");
this.contentSized();
}
async refresh() {
const bookmarkedNotes = await searchService.searchForNotes("#bookmarked");
this.$widget.empty();
this.children = [];
this.noteIds = [];
for (const note of bookmarkedNotes) {
this.noteIds.push(note.noteId);
const buttonWidget = new OpenNoteButtonWidget().targetNote(note.noteId);
this.child(buttonWidget);
this.$widget.append(buttonWidget.render());
buttonWidget.refreshIcon();
}
}
initialRenderCompleteEvent() {
this.refresh();
}
entitiesReloadedEvent({loadResults}) {
if (loadResults.getAttributes().find(attr => attr.type === 'label' && attr.name === 'bookmarked')) {
this.refresh();
}
if (loadResults.getNoteIds().find(noteId => this.noteIds.includes(noteId))) {
this.refresh();
}
if (loadResults.getAttributes().find(attr => attr.type === 'label'
&& ['iconClass', 'workspaceIconClass'].includes(attr.name)
&& this.noteIds.includes(attr.noteId))
) {
this.refresh();
}
}
}

View file

@ -0,0 +1,107 @@
import NoteContextAwareWidget from "./note_context_aware_widget.js";
import protectedSessionService from "../services/protected_session.js";
import attributeService from "../services/attributes.js";
const TPL = `
<div class="bookmark-switch">
<style>
/* The switch - the box around the slider */
.bookmark-switch .switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
float: right;
}
/* The slider */
.bookmark-switch .slider {
border-radius: 24px;
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--more-accented-background-color);
transition: .4s;
}
.bookmark-switch .slider:before {
border-radius: 50%;
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: 4px;
background-color: var(--main-background-color);
-webkit-transition: .4s;
transition: .4s;
}
.bookmark-switch .slider.checked {
background-color: var(--main-text-color);
}
.bookmark-switch .slider.checked:before {
transform: translateX(26px);
}
</style>
<div class="add-bookmark-button">
Bookmark
&nbsp;
<span title="Bookmark this note to the left side panel">
<label class="switch">
<span class="slider"></span>
</span>
</div>
<div class="remove-bookmark-button">
Bookmark
&nbsp;
<span title="Remove bookmark">
<label class="switch">
<span class="slider checked"></span>
</span>
</div>
</div>`;
export default class BookmarkSwitchWidget extends NoteContextAwareWidget {
doRender() {
this.$widget = $(TPL);
this.$addBookmarkButton = this.$widget.find(".add-bookmark-button");
this.$addBookmarkButton.on('click', () => attributeService.setLabel(this.noteId, 'bookmarked'));
this.$removeBookmarkButton = this.$widget.find(".remove-bookmark-button");
this.$removeBookmarkButton.on('click', async () => {
for (const label of this.note.getLabels('bookmarked')) {
await attributeService.removeAttributeById(this.noteId, label.attributeId);
}
});
}
refreshWithNote(note) {
const isBookmarked = note.hasLabel('bookmarked');
this.$addBookmarkButton.toggle(!isBookmarked);
this.$removeBookmarkButton.toggle(isBookmarked);
}
entitiesReloadedEvent({loadResults}) {
for (const attr of loadResults.getAttributes()) {
if (attr.type === 'label'
&& attr.name === 'bookmarked'
&& attributeService.isAffecting(attr, this.note)) {
this.refresh();
break;
}
}
}
}

View file

@ -1,12 +1,22 @@
import ButtonWidget from "./button_widget.js";
import appContext from "../../services/app_context.js";
// TODO: here we could read icon and title of the target note and use it for tooltip and displayed icon
import froca from "../../services/froca.js";
export default class OpenNoteButtonWidget extends ButtonWidget {
targetNote(noteId) {
froca.getNote(noteId).then(note => {
this.icon(note.getIcon());
this.title(note.title);
this.refreshIcon();
});
this.onClick(() => appContext.tabManager.openTabWithNoteWithHoisting(noteId, true));
return this;
}
initialRenderCompleteEvent() {
// we trigger refresh above
}
}

View file

@ -5,7 +5,7 @@ const TPL = `
<div class="protected-note-switch">
<style>
/* The switch - the box around the slider */
.switch {
.protected-note-switch .switch {
position: relative;
display: inline-block;
width: 50px;
@ -14,7 +14,7 @@ const TPL = `
}
/* The slider */
.slider {
.protected-note-switch .slider {
border-radius: 24px;
position: absolute;
cursor: pointer;
@ -26,7 +26,7 @@ const TPL = `
transition: .4s;
}
.slider:before {
.protected-note-switch .slider:before {
border-radius: 50%;
position: absolute;
content: "";
@ -39,11 +39,11 @@ const TPL = `
transition: .4s;
}
.slider.checked {
.protected-note-switch .slider.checked {
background-color: var(--main-text-color);
}
.slider.checked:before {
.protected-note-switch .slider.checked:before {
transform: translateX(26px);
}
</style>

View file

@ -2,6 +2,7 @@ import NoteContextAwareWidget from "../note_context_aware_widget.js";
import NoteTypeWidget from "../note_type.js";
import ProtectedNoteSwitchWidget from "../protected_note_switch.js";
import EditabilitySelectWidget from "../editability_select.js";
import BookmarkSwitchWidget from "../bookmark_switch.js";
const TPL = `
<div class="basic-properties-widget">
@ -33,6 +34,8 @@ const TPL = `
<div class="editability-select-container">
<span>Editable:</span> &nbsp;
</div>
<div class="bookmark-switch-container"></div>
</div>`;
export default class BasicPropertiesWidget extends NoteContextAwareWidget {
@ -42,8 +45,14 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget {
this.noteTypeWidget = new NoteTypeWidget().contentSized();
this.protectedNoteSwitchWidget = new ProtectedNoteSwitchWidget().contentSized();
this.editabilitySelectWidget = new EditabilitySelectWidget().contentSized();
this.bookmarkSwitchWidget = new BookmarkSwitchWidget().contentSized();
this.child(this.noteTypeWidget, this.protectedNoteSwitchWidget, this.editabilitySelectWidget);
this.child(
this.noteTypeWidget,
this.protectedNoteSwitchWidget,
this.editabilitySelectWidget,
this.bookmarkSwitchWidget
);
}
get name() {
@ -55,7 +64,7 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget {
}
isEnabled() {
return this.note && (this.note.type === 'text' || this.note.type === 'code' || this.note.type == 'mermaid');
return this.note && (this.note.type === 'text' || this.note.type === 'code' || this.note.type === 'mermaid');
}
getTitle() {
@ -73,5 +82,6 @@ export default class BasicPropertiesWidget extends NoteContextAwareWidget {
this.$widget.find(".note-type-container").append(this.noteTypeWidget.render());
this.$widget.find(".protected-note-switch-container").append(this.protectedNoteSwitchWidget.render());
this.$widget.find(".editability-select-container").append(this.editabilitySelectWidget.render());
this.$widget.find(".bookmark-switch-container").append(this.bookmarkSwitchWidget.render());
}
}