link map widget always rendered centered map

This commit is contained in:
zadam 2020-03-07 20:41:03 +01:00
parent 62da383623
commit 81ec85083a
8 changed files with 718 additions and 574 deletions

File diff suppressed because it is too large Load Diff

View File

@ -184,18 +184,36 @@ export default class LinkMap {
} }
moveToCenterOfElement(element) { moveToCenterOfElement(element) {
const elemBounds = element.getBoundingClientRect(); const owner = this.pzInstance.getOwner();
const containerBounds = this.pzInstance.getOwner().getBoundingClientRect();
const centerX = -elemBounds.left + containerBounds.left + (containerBounds.width / 2) - (elemBounds.width / 2); const center = () => {
const centerY = -elemBounds.top + containerBounds.top + (containerBounds.height / 2) - (elemBounds.height / 2); const elemBounds = element.getBoundingClientRect();
const containerBounds = owner.getBoundingClientRect();
const transform = this.pzInstance.getTransform(); const centerX = -elemBounds.left + containerBounds.left + (containerBounds.width / 2) - (elemBounds.width / 2);
const centerY = -elemBounds.top + containerBounds.top + (containerBounds.height / 2) - (elemBounds.height / 2);
const newX = transform.x + centerX; const transform = this.pzInstance.getTransform();
const newY = transform.y + centerY;
this.pzInstance.moveTo(newX, newY); const newX = transform.x + centerX;
const newY = transform.y + centerY;
this.pzInstance.moveTo(newX, newY);
};
let shown = false;
const observer = new IntersectionObserver(entries => {
if (!shown && entries[0].isIntersecting) {
shown = true;
center();
}
}, {
rootMargin: '0px',
threshold: 0.1
});
observer.observe(owner);
} }
initPanZoom() { initPanZoom() {

View File

@ -244,7 +244,7 @@ export default class TabManager extends Component {
if (this.tabContexts.length <= 1) { if (this.tabContexts.length <= 1) {
this.openAndActivateEmptyTab(); this.openAndActivateEmptyTab();
} }
else { else if (tabContextToRemove.isActive()) {
const idx = this.tabContexts.findIndex(tc => tc.tabId === tabId); const idx = this.tabContexts.findIndex(tc => tc.tabId === tabId);
if (idx === this.tabContexts.length - 1) { if (idx === this.tabContexts.length - 1) {

View File

@ -18,8 +18,7 @@ const WIDGET_TPL = `
<div id="[to be set]" class="collapse body-wrapper" style="transition: none; "> <div id="[to be set]" class="collapse body-wrapper" style="transition: none; ">
<div class="card-body"></div> <div class="card-body"></div>
</div> </div>
</div> </div>`;
`;
export default class CollapsibleWidget extends TabAwareWidget { export default class CollapsibleWidget extends TabAwareWidget {
getWidgetTitle() { return "Untitled widget"; } getWidgetTitle() { return "Untitled widget"; }
@ -68,10 +67,10 @@ export default class CollapsibleWidget extends TabAwareWidget {
this.$headerActions = this.$widget.find('.widget-header-actions'); this.$headerActions = this.$widget.find('.widget-header-actions');
this.$headerActions.append(...this.getHeaderActions()); this.$headerActions.append(...this.getHeaderActions());
this.decorateWidget();
this.initialized = this.doRenderBody(); this.initialized = this.doRenderBody();
this.decorateWidget();
return this.$widget; return this.$widget;
} }

View File

@ -88,6 +88,7 @@ const RIGHT_PANE_CSS = `
border: 0; border: 0;
height: 100%; height: 100%;
overflow: auto; overflow: auto;
max-height: 300px;
} }
#right-pane .card-body ul { #right-pane .card-body ul {

View File

@ -4,7 +4,7 @@ let linkMapContainerIdCtr = 1;
const TPL = ` const TPL = `
<div class="link-map-widget"> <div class="link-map-widget">
<div class="link-map-container"></div> <div class="link-map-container" style="height: 300px;"></div>
</div> </div>
`; `;
@ -28,25 +28,43 @@ export default class LinkMapWidget extends CollapsibleWidget {
return [$showFullButton]; return [$showFullButton];
} }
noteSwitched() { decorateWidget() {
this.$body.css("max-height", "400px");
}
async refreshWithNote(note) {
const noteId = this.noteId; const noteId = this.noteId;
let shown = false;
// avoid executing this expensive operation multiple times when just going through notes (with keyboard especially) // avoid executing this expensive operation multiple times when just going through notes (with keyboard especially)
// until the users settles on a note // until the users settles on a note
setTimeout(() => { setTimeout(() => {
if (this.noteId === noteId) { if (this.noteId === noteId) {
this.refresh(); // there's a problem with centering the rendered link map before it is actually shown on the screen
// that's why we make the whole process lazy and with the help of IntersectionObserver wait until the
// tab is really shown and only then render
const observer = new IntersectionObserver(entries => {
if (!shown && entries[0].isIntersecting) {
shown = true;
this.displayLinkMap(note);
}
}, {
rootMargin: '0px',
threshold: 0.1
});
observer.observe(this.$body[0]);
} }
}, 1000); }, 1000);
} }
async refreshWithNote(note) { async displayLinkMap(note) {
this.$body.css('opacity', 0); this.$body.css('opacity', 0);
this.$body.html(TPL); this.$body.html(TPL);
const $linkMapContainer = this.$body.find('.link-map-container'); const $linkMapContainer = this.$body.find('.link-map-container');
$linkMapContainer.attr("id", "link-map-container-" + linkMapContainerIdCtr++); $linkMapContainer.attr("id", "link-map-container-" + linkMapContainerIdCtr++);
$linkMapContainer.css("height", "300px");
const LinkMapServiceClass = (await import('../services/link_map.js')).default; const LinkMapServiceClass = (await import('../services/link_map.js')).default;
@ -69,7 +87,7 @@ export default class LinkMapWidget extends CollapsibleWidget {
entitiesReloadedEvent({loadResults}) { entitiesReloadedEvent({loadResults}) {
if (loadResults.getAttributes().find(attr => attr.type === 'relation' && (attr.noteId === this.noteId || attr.value === this.noteId))) { if (loadResults.getAttributes().find(attr => attr.type === 'relation' && (attr.noteId === this.noteId || attr.value === this.noteId))) {
this.refresh(); this.noteSwitched();
} }
} }
} }

View File

@ -17,9 +17,22 @@ export default class TabCachingWidget extends TabAwareWidget {
// stop propagation of the event to the children, individual tab widget should not know about tab switching // stop propagation of the event to the children, individual tab widget should not know about tab switching
// since they are per-tab // since they are per-tab
if (name === 'tabNoteSwitchedAndActivated') { if (name === 'tabNoteSwitchedAndActivated') {
return super.handleEventInChildren('tabNoteSwitched', data); name = 'tabNoteSwitched';
} }
else if (name !== 'activeTabChanged') {
if (name === 'tabNoteSwitched') {
// this event is propagated only to the widgets of a particular tab
const widget = this.widgets[data.tabContext.tabId];
if (widget) {
return widget.handleEvent(name, data);
}
else {
return Promise.resolve();
}
}
if (name !== 'activeTabChanged') {
return super.handleEventInChildren(name, data); return super.handleEventInChildren(name, data);
} }

View File

@ -411,9 +411,13 @@ export default class TabRowWidget extends BasicWidget {
} }
activeTabChangedEvent() { activeTabChangedEvent() {
const newActiveTabId = appContext.tabManager.getActiveTabContext().tabId; const activeTabContext = appContext.tabManager.getActiveTabContext();
const tabEl = this.getTabById(newActiveTabId)[0]; if (!activeTabContext) {
return;
}
const tabEl = this.getTabById(activeTabContext.tabId)[0];
const activeTabEl = this.activeTabEl; const activeTabEl = this.activeTabEl;
if (activeTabEl === tabEl) return; if (activeTabEl === tabEl) return;
if (activeTabEl) activeTabEl.removeAttribute('active'); if (activeTabEl) activeTabEl.removeAttribute('active');