Remove `viewStateChanged()` method from gr-change-view The deed is done. This was the ultimate target of a large chain of refactorings: Do not let the change view handle view state updates in a complicated tree of paths, but instead let the change model react in specific independent subscriptions. And let the view just subscribe to model updates. The major missing change that was still needed, was the handling of firing and handling reload events. Unfortunately clearing the patchset and forcing a reload was also been handled by a `reload` event, but clearing the patchset is a view state change, so this should be a direct command to the model. So we have looked at all `fireReload()` and `fireReload(true)` instances and checked which one is more appropriate: Keeping firing the "soft" reload or requesting a new view state. One issue was that the `forceReload` URL parameter was only handled by the change view. We are handling this now in the change view model. We have unified the entire reload handling in the change view model: The `reload` event, the `reload()` method of the view model and the `forceReload` URL parameter all end up in the same place: We are always resetting the view state to `undefined` in order to trigger a reload. That is very robust and reliable and allows us to also get rid of some dedicated `reload$` observables that we don't need anymore. Stop logging `change-view-re-rendered`. We don't need that anymore. Release-Notes: skip Change-Id: Ie6319089dee7586c04c01b2ae91c18bc75f0d85d
diff --git a/polygerrit-ui/app/models/views/change.ts b/polygerrit-ui/app/models/views/change.ts index 5799bbd..713d401 100644 --- a/polygerrit-ui/app/models/views/change.ts +++ b/polygerrit-ui/app/models/views/change.ts
@@ -69,9 +69,16 @@ /** for scrolling a Change Log message into view in gr-change-view */ messageHash?: string; - /** for logging where the user came from */ + /** + * For logging where the user came from. This is handled by the router, so + * this is not inspected by the model. + */ usp?: string; - /** triggers all change related data to be reloaded */ + /** + * Triggers all change related data to be reloaded. This is implemented by + * intercepting change view state updates and `forceReload` causing the view + * state to be wiped clean as `undefined` in an intermediate update. + */ forceReload?: boolean; /** triggers opening the reply dialog */ openReplyDialog?: boolean; @@ -328,6 +335,39 @@ }); } }); + document.addEventListener('reload', this.reload); + } + + override finalize(): void { + document.removeEventListener('reload', this.reload); + } + + /** + * Calling this is the same as firing the 'reload' event. This is also the + * same as adding `forceReload` parameter in the URL. See below. + */ + reload = () => { + const state = this.getState(); + if (state !== undefined) this.forceLoad(state); + }; + + /** + * This is the destination of where the `reload()` method, the `reload` event + * and the `forceReload` URL parameter all end up. + */ + private forceLoad(state: ChangeViewState) { + this.setState(undefined); + // We have to do this in a timeout, because we need the `undefined` value to + // be processed by all observers first and thus have the "reset" completed. + setTimeout(() => this.setState({...state, forceReload: undefined})); + } + + override setState(state: ChangeViewState | undefined): void { + if (state?.forceReload) { + this.forceLoad(state); + } else { + super.setState(state); + } } toggleSelectedCheckRun(checkName: string) {