From 7f769e9e7620faeae00266650d7c6c0a6b44cc58 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Mon, 13 Sep 2021 15:45:31 -0400 Subject: [PATCH] FIX: Optimistically fix topic timeline state issues This is my second try at this. The first b246a63a592 raised an issue with the event delegation not working because the topic id changed. This adds support for delegating events to dynamic keys by passing a function where a static key would normally be needed. This means that each timeline will have its own unique state key and events will only delegate to the proper topic. --- .../discourse/app/components/mount-widget.js | 1 + .../app/components/topic-timeline.js | 5 ++++- .../discourse/app/widgets/topic-timeline.js | 22 +++++++++---------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/mount-widget.js b/app/assets/javascripts/discourse/app/components/mount-widget.js index cc29cfb1ce3..9ad0535d374 100644 --- a/app/assets/javascripts/discourse/app/components/mount-widget.js +++ b/app/assets/javascripts/discourse/app/components/mount-widget.js @@ -83,6 +83,7 @@ export default Component.extend({ afterPatch() {}, eventDispatched(eventName, key, refreshArg) { + key = typeof key === "function" ? key(refreshArg) : key; const onRefresh = camelize(eventName.replace(/:/, "-")); this.dirtyKeys.keyDirty(key, { onRefresh, refreshArg }); this.queueRerender(); diff --git a/app/assets/javascripts/discourse/app/components/topic-timeline.js b/app/assets/javascripts/discourse/app/components/topic-timeline.js index 09fbfcd78a9..a9cd6bee136 100644 --- a/app/assets/javascripts/discourse/app/components/topic-timeline.js +++ b/app/assets/javascripts/discourse/app/components/topic-timeline.js @@ -105,7 +105,10 @@ export default MountWidget.extend(Docking, { }); } - this.dispatch("topic:current-post-scrolled", "timeline-scrollarea"); + this.dispatch( + "topic:current-post-scrolled", + () => `timeline-scrollarea-${this.topic.id}` + ); this.dispatch("topic:toggle-actions", "topic-admin-menu-button"); if (!this.site.mobileView) { this.appEvents.on("composer:opened", this, this.queueRerender); diff --git a/app/assets/javascripts/discourse/app/widgets/topic-timeline.js b/app/assets/javascripts/discourse/app/widgets/topic-timeline.js index 03149812e00..578fe95910b 100644 --- a/app/assets/javascripts/discourse/app/widgets/topic-timeline.js +++ b/app/assets/javascripts/discourse/app/widgets/topic-timeline.js @@ -2,7 +2,6 @@ import ComponentConnector from "discourse/widgets/component-connector"; import I18n from "I18n"; import RawHtml from "discourse/widgets/raw-html"; import { createWidget } from "discourse/widgets/widget"; -import { deepMerge } from "discourse-common/lib/object"; import { h } from "virtual-dom"; import { iconNode } from "discourse-common/lib/icon-library"; import { later } from "@ember/runloop"; @@ -76,7 +75,7 @@ function timelineDate(date) { createWidget("timeline-scroller", { tagName: "div.timeline-scroller", - buildKey: () => `timeline-scroller`, + buildKey: (attrs) => `timeline-scroller-${attrs.topicId}`, defaultState() { return { dragging: false }; @@ -144,7 +143,7 @@ createWidget("timeline-padding", { createWidget("timeline-scrollarea", { tagName: "div.timeline-scrollarea", - buildKey: () => `timeline-scrollarea`, + buildKey: (attrs) => `timeline-scrollarea-${attrs.topic.id}`, buildAttributes() { return { style: `height: ${scrollareaHeight()}px` }; @@ -239,15 +238,15 @@ createWidget("timeline-scrollarea", { before + SCROLLER_HEIGHT - 5 < lastReadTop || before > lastReadTop + 25; } + let scrollerAttrs = position; + scrollerAttrs.showDockedButton = + !attrs.mobileView && hasBackPosition && !showButton; + scrollerAttrs.fullScreen = attrs.fullScreen; + scrollerAttrs.topicId = attrs.topic.id; + const result = [ this.attach("timeline-padding", { height: before }), - this.attach( - "timeline-scroller", - deepMerge(position, { - showDockedButton: !attrs.mobileView && hasBackPosition && !showButton, - fullScreen: attrs.fullScreen, - }) - ), + this.attach("timeline-scroller", scrollerAttrs), this.attach("timeline-padding", { height: after }), ]; @@ -410,8 +409,7 @@ createWidget("timeline-footer-controls", { export default createWidget("topic-timeline", { tagName: "div.topic-timeline", - - buildKey: () => "topic-timeline-area", + buildKey: (attrs) => `topic-timeline-area-${attrs.topic.id}`, defaultState() { return { position: null, excerpt: null };