浏览代码

Update the view according to the start index.

Ian Rose 8 年之前
父节点
当前提交
6d4d6bae6a
共有 1 个文件被更改,包括 52 次插入16 次删除
  1. 52 16
      packages/chatbox/src/chatbox.ts

+ 52 - 16
packages/chatbox/src/chatbox.ts

@@ -544,29 +544,65 @@ class Chatbox extends Widget {
     switch (args.type) {
       case 'add':
         index = args.newIndex;
-        each(args.newValues, entry => {
-          let entryWidget = this._entryWidgetFromModel(entry);
-          layout.insertWidget(index++, entryWidget);
-        });
+        if (index < this._start) {
+          // If it is inserted before the view,
+          // just update the `_start` index.
+          this._start += args.newValues.length;
+        } else {
+          // Otherwise insert the widgets into the view.
+          each(args.newValues, entry => {
+            let entryWidget = this._entryWidgetFromModel(entry);
+            layout.insertWidget(index++, entryWidget);
+          });
+        }
         break;
       case 'remove':
-        each(args.oldValues, entry => {
-          let widget = layout.widgets[args.oldIndex];
-          layout.removeWidgetAt(args.oldIndex);
-          widget.dispose();
-        });
+        index = args.oldIndex;
+        if (index < this._start) {
+          // If the removal is before the view,
+          // just update the `_start` index.
+          this._start -= args.oldValues.length;
+        } else {
+          // Otherwise remove the widgets from the view.
+          each(args.oldValues, entry => {
+            let widget = layout.widgets[args.oldIndex];
+            layout.removeWidgetAt(args.oldIndex);
+            widget.dispose();
+          });
+        }
         break;
       case 'move':
-        layout.insertWidget(args.newIndex, layout.widgets[args.oldIndex]);
+        if (args.newIndex >= this._start && args.oldIndex >= this._start) {
+          // If both are in the view, it is a straightforward move.
+          let fromIndex = args.oldIndex - this._start;
+          let toIndex = args.newIndex - this._start;
+          layout.insertWidget(toIndex, layout.widgets[fromIndex]);
+        } else if (args.newIndex >= this._start) {
+          // If it is moving into the view, create the widget and
+          // update the `_start` index.
+          let entry = args.oldValues[0];
+          let entryWidget = this._entryWidgetFromModel(entry);
+          layout.insertWidget(args.newIndex - this._start, entryWidget);
+          this._start--;
+        } else if (args.oldIndex >= this._start) {
+          // If it is moving out of the view, remove the widget
+          // and update the `_start index.`
+          layout.removeWidgetAt(args.oldIndex - this._start);
+          this._start++;
+        }
+        // If both are before `_start`, this is a no-op.
         break;
       case 'set':
         index = args.newIndex;
-        each(args.newValues, entry => {
-          let entryWidget = this._entryWidgetFromModel(entry);
-          layout.insertWidget(index, entryWidget);
-          layout.removeWidgetAt(index+1);
-          index++;
-        });
+        if (index >= this._start) {
+          // Only need to update the widgets if they are in the view.
+          each(args.newValues, entry => {
+            let entryWidget = this._entryWidgetFromModel(entry);
+            layout.insertWidget(index, entryWidget);
+            layout.removeWidgetAt(index+1);
+            index++;
+          });
+        }
         break;
     }
   }