Skip to content

Commit ba115c7

Browse files
huoxin233imorland
andauthored
fix: mobile discussion total post count not updating on reply (#4684)
The scrubber's "viewing X of Y" label was built once as a vnode tree and rendered in two places (the dropdown toggle and the Scrubber-info strong). Reusing a single vnode instance in two positions breaks Mithril's diffing, leaving one copy stale on redraw. The current post index is force-written to the DOM via jQuery on scroll, so it always updated; the total count is only rendered through Mithril's view, so the stale copy (the dropdown toggle shown in the mobile header) never refreshed after posting a reply. Build the label as a function that returns a fresh vnode tree per usage so both render sites diff correctly. Backport fix #4678 Co-authored-by: IanM <16573496+imorland@users.noreply.github.com>
1 parent 4ecf267 commit ba115c7

1 file changed

Lines changed: 12 additions & 8 deletions

File tree

framework/core/js/src/forum/components/PostStreamScrubber.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@ export default class PostStreamScrubber extends Component {
2626
view() {
2727
const count = this.stream.count();
2828

29-
// Index is left blank for performance reasons, it is filled in in updateScubberValues
30-
const viewing = app.translator.trans('core.forum.post_scrubber.viewing_text', {
31-
count,
32-
index: <span className="Scrubber-index"></span>,
33-
formattedCount: <span className="Scrubber-count">{formatNumber(count)}</span>,
34-
});
29+
// Index is left blank for performance reasons, it is filled in in updateScubberValues.
30+
// Built as a function so each usage renders its own vnode tree — reusing a single vnode
31+
// instance in two places breaks Mithril's diffing and leaves one copy stale (e.g. the
32+
// total count in the mobile header not updating after posting a reply).
33+
const viewing = () =>
34+
app.translator.trans('core.forum.post_scrubber.viewing_text', {
35+
count,
36+
index: <span className="Scrubber-index"></span>,
37+
formattedCount: <span className="Scrubber-count">{formatNumber(count)}</span>,
38+
});
3539

3640
const unreadCount = this.stream.discussion.unreadCount();
3741
const unreadPercent = count ? Math.min(count - this.stream.index, unreadCount) / count : 0;
@@ -58,7 +62,7 @@ export default class PostStreamScrubber extends Component {
5862
return (
5963
<div className={classNames.join(' ')}>
6064
<button className="Button Dropdown-toggle" data-toggle="dropdown">
61-
{viewing} {icon('fas fa-sort')}
65+
{viewing()} {icon('fas fa-sort')}
6266
</button>
6367

6468
<div className="Dropdown-menu dropdown-menu">
@@ -72,7 +76,7 @@ export default class PostStreamScrubber extends Component {
7276
<div className="Scrubber-handle">
7377
<div className="Scrubber-bar" />
7478
<div className="Scrubber-info">
75-
<strong>{viewing}</strong>
79+
<strong>{viewing()}</strong>
7680
<span className="Scrubber-description"></span>
7781
</div>
7882
</div>

0 commit comments

Comments
 (0)