FIX: Dirty keys should become to a widget, not global
This commit is contained in:
parent
287cb4bfc5
commit
1a02f5154f
|
@ -1,8 +1,8 @@
|
|||
import { keyDirty } from 'discourse/widgets/widget';
|
||||
import { diff, patch } from 'virtual-dom';
|
||||
import { WidgetClickHook } from 'discourse/widgets/hooks';
|
||||
import { renderedKey, queryRegistry } from 'discourse/widgets/widget';
|
||||
import { queryRegistry } from 'discourse/widgets/widget';
|
||||
import { getRegister } from 'discourse-common/lib/get-owner';
|
||||
import DirtyKeys from 'discourse/lib/dirty-keys';
|
||||
|
||||
const _cleanCallbacks = {};
|
||||
export function addWidgetCleanCallback(widgetName, fn) {
|
||||
|
@ -18,6 +18,7 @@ export default Ember.Component.extend({
|
|||
_renderCallback: null,
|
||||
_childEvents: null,
|
||||
_dispatched: null,
|
||||
dirtyKeys: null,
|
||||
|
||||
init() {
|
||||
this._super();
|
||||
|
@ -34,6 +35,7 @@ export default Ember.Component.extend({
|
|||
this._childEvents = [];
|
||||
this._connected = [];
|
||||
this._dispatched = [];
|
||||
this.dirtyKeys = new DirtyKeys(name);
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
|
@ -73,7 +75,7 @@ export default Ember.Component.extend({
|
|||
|
||||
eventDispatched(eventName, key, refreshArg) {
|
||||
const onRefresh = Ember.String.camelize(eventName.replace(/:/, '-'));
|
||||
keyDirty(key, { onRefresh, refreshArg });
|
||||
this.dirtyKeys.keyDirty(key, { onRefresh, refreshArg });
|
||||
this.queueRerender();
|
||||
},
|
||||
|
||||
|
@ -104,7 +106,10 @@ export default Ember.Component.extend({
|
|||
|
||||
const t0 = new Date().getTime();
|
||||
const args = this.get('args') || this.buildArgs();
|
||||
const opts = { model: this.get('model') };
|
||||
const opts = {
|
||||
model: this.get('model'),
|
||||
dirtyKeys: this.dirtyKeys,
|
||||
};
|
||||
const newTree = new this._widgetClass(args, this.register, opts);
|
||||
|
||||
newTree._rerenderable = this;
|
||||
|
@ -122,8 +127,8 @@ export default Ember.Component.extend({
|
|||
this._renderCallback = null;
|
||||
}
|
||||
this.afterRender();
|
||||
this.dirtyKeys.renderedKey('*');
|
||||
|
||||
Ember.run.scheduleOnce('afterRender', () => renderedKey('*'));
|
||||
if (this.profileWidget) {
|
||||
console.log(new Date().getTime() - t0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import DiscourseURL from 'discourse/lib/url';
|
||||
import { keyDirty } from 'discourse/widgets/widget';
|
||||
import MountWidget from 'discourse/components/mount-widget';
|
||||
import { cloak, uncloak } from 'discourse/widgets/post-stream';
|
||||
import { isWorkaroundActive } from 'discourse/lib/safari-hacks';
|
||||
|
@ -245,13 +244,13 @@ export default MountWidget.extend({
|
|||
this.appEvents.on('post-stream:refresh', args => {
|
||||
if (args) {
|
||||
if (args.id) {
|
||||
keyDirty(`post-${args.id}`);
|
||||
this.dirtyKeys.keyDirty(`post-${args.id}`);
|
||||
|
||||
if (args.refreshLikes) {
|
||||
keyDirty(`post-menu-${args.id}`, { onRefresh: 'refreshLikes' });
|
||||
this.dirtyKeys.keyDirty(`post-menu-${args.id}`, { onRefresh: 'refreshLikes' });
|
||||
}
|
||||
} else if (args.force) {
|
||||
keyDirty(`*`);
|
||||
this.dirtyKeys.forceAll();
|
||||
}
|
||||
}
|
||||
this.queueRerender();
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
export default class DirtyKeys {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
this._keys = {};
|
||||
}
|
||||
|
||||
keyDirty(key, options) {
|
||||
options = options || {};
|
||||
options.dirty = true;
|
||||
this._keys[key] = options;
|
||||
}
|
||||
|
||||
forceAll() {
|
||||
this.keyDirty('*');
|
||||
}
|
||||
|
||||
allDirty() {
|
||||
return !!this._keys['*'];
|
||||
}
|
||||
|
||||
optionsFor(key) {
|
||||
return this._keys[key] || { dirty: false };
|
||||
}
|
||||
|
||||
renderedKey(key) {
|
||||
if (key === '*') {
|
||||
this._keys = {};
|
||||
} else {
|
||||
delete this._keys[key];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { diff, patch } from 'virtual-dom';
|
||||
import { queryRegistry } from 'discourse/widgets/widget';
|
||||
import DirtyKeys from 'discourse/lib/dirty-keys';
|
||||
|
||||
export default class WidgetGlue {
|
||||
|
||||
|
@ -9,6 +10,7 @@ export default class WidgetGlue {
|
|||
this.register = register;
|
||||
this.attrs = attrs;
|
||||
this._timeout = null;
|
||||
this.dirtyKeys = new DirtyKeys(name);
|
||||
|
||||
this._widgetClass = queryRegistry(name) || this.register.lookupFactory(`widget:${name}`);
|
||||
if (!this._widgetClass) {
|
||||
|
@ -27,7 +29,11 @@ export default class WidgetGlue {
|
|||
|
||||
rerenderWidget() {
|
||||
Ember.run.cancel(this._timeout);
|
||||
const newTree = new this._widgetClass(this.attrs, this.register);
|
||||
const newTree = new this._widgetClass(
|
||||
this.attrs,
|
||||
this.register,
|
||||
{ dirtyKeys: this.dirtyKeys }
|
||||
);
|
||||
const patches = diff(this._tree || this._rootNode, newTree);
|
||||
|
||||
newTree._rerenderable = this;
|
||||
|
|
|
@ -2,7 +2,6 @@ import { createWidget } from 'discourse/widgets/widget';
|
|||
import transformPost from 'discourse/lib/transform-post';
|
||||
import { Placeholder } from 'discourse/lib/posts-with-placeholders';
|
||||
import { addWidgetCleanCallback } from 'discourse/components/mount-widget';
|
||||
import { keyDirty } from 'discourse/widgets/widget';
|
||||
|
||||
let transformCallbacks = null;
|
||||
function postTransformCallbacks(transformed) {
|
||||
|
@ -36,14 +35,15 @@ export function cloak(post, component) {
|
|||
const $post = $(`#post_${post.post_number}`);
|
||||
_cloaked[post.id] = true;
|
||||
_heights[post.id] = $post.outerHeight();
|
||||
keyDirty(`post-${post.id}`);
|
||||
|
||||
component.dirtyKeys.keyDirty(`post-${post.id}`);
|
||||
Ember.run.debounce(component, 'queueRerender', 1000);
|
||||
}
|
||||
|
||||
export function uncloak(post, component) {
|
||||
if (!CLOAKING_ENABLED || !_cloaked[post.id]) { return; }
|
||||
_cloaked[post.id] = null;
|
||||
keyDirty(`post-${post.id}`);
|
||||
component.dirtyKeys.keyDirty(`post-${post.id}`);
|
||||
component.queueRerender();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,21 +9,6 @@ import DecoratorHelper from 'discourse/widgets/decorator-helper';
|
|||
function emptyContent() { }
|
||||
|
||||
const _registry = {};
|
||||
let _dirty = {};
|
||||
|
||||
export function keyDirty(key, options) {
|
||||
options = options || {};
|
||||
options.dirty = true;
|
||||
_dirty[key] = options;
|
||||
}
|
||||
|
||||
export function renderedKey(key) {
|
||||
if (key === '*') {
|
||||
_dirty = {};
|
||||
} else {
|
||||
delete _dirty[key];
|
||||
}
|
||||
}
|
||||
|
||||
export function queryRegistry(name) {
|
||||
return _registry[name];
|
||||
|
@ -149,6 +134,7 @@ export default class Widget {
|
|||
this.mergeState = opts.state;
|
||||
this.model = opts.model;
|
||||
this.register = register;
|
||||
this.dirtyKeys = opts.dirtyKeys;
|
||||
|
||||
register.deprecateContainer(this);
|
||||
|
||||
|
@ -188,6 +174,8 @@ export default class Widget {
|
|||
}
|
||||
|
||||
render(prev) {
|
||||
const { dirtyKeys } = this;
|
||||
|
||||
if (prev && prev.key && prev.key === this.key) {
|
||||
this.state = prev.state;
|
||||
} else {
|
||||
|
@ -200,16 +188,16 @@ export default class Widget {
|
|||
}
|
||||
|
||||
if (prev) {
|
||||
const dirtyOpts = _dirty[prev.key] || { dirty: false };
|
||||
const dirtyOpts = dirtyKeys.optionsFor(prev.key);
|
||||
|
||||
if (prev.shadowTree) {
|
||||
this.shadowTree = true;
|
||||
if (!dirtyOpts.dirty && !_dirty['*']) {
|
||||
if (!dirtyOpts.dirty && !dirtyKeys.allDirty()) {
|
||||
return prev.vnode;
|
||||
}
|
||||
}
|
||||
if (prev.key) {
|
||||
renderedKey(prev.key);
|
||||
dirtyKeys.renderedKey(prev.key);
|
||||
}
|
||||
|
||||
const refreshAction = dirtyOpts.onRefresh;
|
||||
|
@ -256,6 +244,7 @@ export default class Widget {
|
|||
if (WidgetClass) {
|
||||
const result = new WidgetClass(attrs, this.register, opts);
|
||||
result.parentWidget = this;
|
||||
result.dirtyKeys = this.dirtyKeys;
|
||||
return result;
|
||||
} else {
|
||||
throw `Couldn't find ${widgetName} factory`;
|
||||
|
@ -266,7 +255,7 @@ export default class Widget {
|
|||
let widget = this;
|
||||
while (widget) {
|
||||
if (widget.shadowTree) {
|
||||
keyDirty(widget.key);
|
||||
this.dirtyKeys.keyDirty(widget.key);
|
||||
}
|
||||
|
||||
const rerenderable = widget._rerenderable;
|
||||
|
|
Loading…
Reference in New Issue