From 8b7b4f7fb466f31f7c379255ec11d74dfdda39ff Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Mon, 6 Nov 2023 14:58:54 +0100 Subject: [PATCH] [FIX] web_editor: properly update grid/col buttons on mobile view toggle Commit [1] introduced the grid mode for multi-column snippets, with discriminating behavior between mobile and desktop previews. When toggling multiple times the mobile view, the buttons above the block sometimes remain in their previous state. The `updateUIVisibility` trigger doesn't seem to go through. Step to reproduce: - Drop an Image - Text snippet - Activate the grid mode - Click on a column - Toggle the mobile view until either of the following happens: - When going from desktop to mobile: the buttons are still the ones that should appear on desktop (send to front, send to back, move handle and delete). - When going from mobile to desktop: the buttons are still the ones that should appear on mobile (left/right arrows and delete). [1]: https://github.com/odoo/odoo/commit/ca215a5bdf20a1a665cfa87fb4fab0d9b3a0ae2b task-3551537 closes odoo/odoo#141359 X-original-commit: 174e9fe0d8665d1a81c90a6f7bf5cc9e3361f161 Signed-off-by: Quentin Smetz (qsm) --- .../static/src/js/editor/snippets.editor.js | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 38f71319d10..0b4fcbac982 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -4441,16 +4441,38 @@ var SnippetsMenu = Widget.extend({ * Preview on mobile. */ _onMobilePreviewClick() { - this.trigger_up('request_mobile_preview'); - // TODO refactor things to make this more understandable -> on mobile // edition, update the UI. But to do it properly and inside the mutex // this simulates what happens when a snippet option is used. this._execWithLoadingEffect(async () => { + const initialBodySize = this.$body[0].clientWidth; + this.trigger_up('request_mobile_preview'); + // TODO needed so that mobile edition is considered before updating // the UI but this is clearly random. The trigger_up above should - // properly await for the rerender somehow. - await new Promise(resolve => setTimeout(resolve)); + // properly await for the rerender somehow or, better, the UI update + // should not depend on the mobile re-render entirely. + let count = 0; + do { + await new Promise(resolve => setTimeout(resolve, 1)); + // Technically, should not be possible to fall into an infinite loop + // but extra safety as a stable fix. + } while (count++ < 1000 && Math.abs(this.$body[0].clientWidth - initialBodySize) < 1); + + // Reload images inside grid items so that no image disappears when + // activating mobile preview. + const $gridItemEls = this.getEditableArea().find('div.o_grid_item'); + for (const gridItemEl of $gridItemEls) { + gridUtils._reloadLazyImages(gridItemEl); + } + + for (const invisibleOverrideEl of this.getEditableArea().find('.o_snippet_mobile_invisible, .o_snippet_desktop_invisible')) { + invisibleOverrideEl.classList.remove('o_snippet_override_invisible'); + invisibleOverrideEl.dataset.invisible = '1'; + } + + // This is async but using the main editor mutex, currently locked. + this._updateInvisibleDOM(); return new Promise(resolve => { this.trigger_up('snippet_option_update', { @@ -4458,19 +4480,6 @@ var SnippetsMenu = Widget.extend({ }); }); }, false); - - // Reload images inside grid items so that no image disappears when - // activating mobile preview. - const $gridItemEls = this.getEditableArea().find('div.o_grid_item'); - for (const gridItemEl of $gridItemEls) { - gridUtils._reloadLazyImages(gridItemEl); - } - for (const invisibleOverrideEl of this.getEditableArea().find('.o_snippet_mobile_invisible, .o_snippet_desktop_invisible')) { - invisibleOverrideEl.classList.remove('o_snippet_override_invisible'); - invisibleOverrideEl.dataset.invisible = '1'; - } - // This is async but using the main editor mutex. - this._updateInvisibleDOM(); }, /** * Undo..