From af76c11be68c0f62250afb7f8b15555d9c8d91d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Sadzi=C5=84ski?= Date: Wed, 9 Jun 2021 17:07:16 +0200 Subject: [PATCH] (core) Cursor position observable on a GristDoc wasn't triggered when a view was changed. Summary: Cursor position observable was created using GrainJS, but the fields it was using were created using knockout observables. In a result the cursor position wasn't recomputed when a view was changed or an active section was deleted. Test Plan: Browser tests Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2850 --- app/client/components/GristDoc.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/client/components/GristDoc.ts b/app/client/components/GristDoc.ts index 13549f07..053e90b1 100644 --- a/app/client/components/GristDoc.ts +++ b/app/client/components/GristDoc.ts @@ -248,16 +248,25 @@ export class GristDoc extends DisposableWithEvents { // create current view observer this.currentView = Observable.create(this, null); - // first create a computed observable for current view + + // create computed observable for viewInstance - if it is loaded or not + + // Add an artificial intermediary computed only to delay the evaluation of currentView, so + // that it happens after section.viewInstance is set. If it happens before, then + // section.viewInstance is seen as null, and as it gets updated, GrainJS refuses to + // recalculate this computed since it was already calculated in the same tick. + const activeViewId = Computed.create(this, (use) => use(this.activeViewId)); const viewInstance = Computed.create(this, (use) => { const section = use(this.viewModel.activeSection); + const viewId = use(activeViewId); const view = use(section.viewInstance); - return view; + return (typeof viewId === 'number') ? view : null; }); // then listen if the view is present, because we still need to wait for it load properly this.autoDispose(viewInstance.addListener(async (view) => { if (!view) { return; } await view.getLoadingDonePromise(); + // finally set the current view as fully loaded this.currentView.set(view); }));