From f20621dd07415f15edd63774326da7fcec4dc10b Mon Sep 17 00:00:00 2001 From: kim jeong yong Date: Mon, 15 Jun 2026 18:03:05 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[fix]=20Sortable=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=88=9C=EC=84=9C=20=EB=B3=80=EA=B2=BD=20=EC=8B=9C?= =?UTF-8?q?=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=9C=84=EC=B9=98=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 모양/소리/장면 리스트에서 아이템 순서를 바꾸면 setData 리렌더 과정에서 내부 스크롤 컨테이너(.rcs-inner-container)의 스크롤이 맨 위로 초기화되던 문제를 수정. setData 호출 전후로 scrollTop/scrollLeft를 보존하는 Entry.Utils.runWithScrollPreserved 헬퍼를 추가하고 각 updateView에 적용. Co-Authored-By: Claude Fable 5 --- src/class/playground.js | 14 +++++++++----- src/class/scene.js | 6 +++++- src/util/utils.js | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/class/playground.js b/src/class/playground.js index 525d375a5a..ed3f147943 100644 --- a/src/class/playground.js +++ b/src/class/playground.js @@ -704,9 +704,11 @@ Entry.Playground = class Playground { updatePictureView() { if (this.pictureSortableListWidget) { - this.pictureSortableListWidget.setData({ items: [] }); - this.pictureSortableListWidget.setData({ - items: this._getSortablePictureList(), + Entry.Utils.runWithScrollPreserved(this.pictureListView_, () => { + this.pictureSortableListWidget.setData({ items: [] }); + this.pictureSortableListWidget.setData({ + items: this._getSortablePictureList(), + }); }); } this.reloadPlayground(); @@ -1102,8 +1104,10 @@ Entry.Playground = class Playground { updateSoundsView() { if (this.soundSortableListWidget) { - this.soundSortableListWidget.setData({ - items: this._getSortableSoundList(), + Entry.Utils.runWithScrollPreserved(this.soundListView_, () => { + this.soundSortableListWidget.setData({ + items: this._getSortableSoundList(), + }); }); } diff --git a/src/class/scene.js b/src/class/scene.js index e2ca9da4c9..b58c91f27a 100644 --- a/src/class/scene.js +++ b/src/class/scene.js @@ -172,7 +172,11 @@ Entry.Scene = class { updateSceneView() { const items = this._getSortableSceneList(); if (this.sceneSortableListWidget) { - setTimeout(() => this.sceneSortableListWidget.setData({ items }), 0); + setTimeout(() => { + Entry.Utils.runWithScrollPreserved(this.listView_, () => { + this.sceneSortableListWidget.setData({ items }); + }); + }, 0); } } diff --git a/src/util/utils.js b/src/util/utils.js index 4864044255..7073ebfde1 100644 --- a/src/util/utils.js +++ b/src/util/utils.js @@ -479,6 +479,28 @@ Entry.Utils.generateId = function () { return `0000${((Math.random() * Math.pow(36, 4)) << 0).toString(36)}`.substr(-4); }; +/** + * Sortable 위젯의 setData 등 리렌더 콜백 실행 중에도 + * 내부 스크롤 컨테이너(.rcs-inner-container)의 스크롤 위치를 유지한다. + * @param {HTMLElement} containerEl Sortable이 마운트된 컨테이너 + * @param {Function} callback 리스트를 갱신하는 동기 콜백 + */ +Entry.Utils.runWithScrollPreserved = function (containerEl, callback) { + const getScrollEl = () => + containerEl && containerEl.querySelector('.rcs-inner-container'); + const before = getScrollEl(); + const top = before ? before.scrollTop : 0; + const left = before ? before.scrollLeft : 0; + + callback(); + + const after = getScrollEl(); + if (after) { + after.scrollTop = top; + after.scrollLeft = left; + } +}; + Entry.Utils.randomColor = function () { const letters = '0123456789ABCDEF'; let color = '#'; From 4c9637f56779bafbb566858c5ba28a611ee99b82 Mon Sep 17 00:00:00 2001 From: JY Kim Date: Mon, 15 Jun 2026 18:25:24 +0900 Subject: [PATCH 2/2] Update src/util/utils.js Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/util/utils.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/util/utils.js b/src/util/utils.js index 7073ebfde1..b2e6176d62 100644 --- a/src/util/utils.js +++ b/src/util/utils.js @@ -486,8 +486,7 @@ Entry.Utils.generateId = function () { * @param {Function} callback 리스트를 갱신하는 동기 콜백 */ Entry.Utils.runWithScrollPreserved = function (containerEl, callback) { - const getScrollEl = () => - containerEl && containerEl.querySelector('.rcs-inner-container'); + const getScrollEl = () => containerEl && containerEl.querySelector('.rcs-inner-container'); const before = getScrollEl(); const top = before ? before.scrollTop : 0; const left = before ? before.scrollLeft : 0;