From 1a28201956736e0f108bb50d8484d8c5e7800a57 Mon Sep 17 00:00:00 2001 From: Nemael Date: Wed, 28 Sep 2022 15:15:02 +0000 Subject: [PATCH] [FIX] mail: emoji picker additional rendered rows not working On the emoji picker, additional rendered rows on top and bottom were not loaded correctly on top. This commit fixes the top rendered rows not working properly. Also fixes computation of some fields that should contain integer values (index) but had float instead, which required late rounding. Task-3000424 X-original-commit: 24d9b970d032709b8f80cf49da057156ccd7fde5 Part-of: odoo/odoo#103124 --- .../emoji_grid_view/emoji_grid_view.js | 5 +- .../mail/static/src/models/emoji_grid_view.js | 71 +++++++++++-------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.js b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.js index 3be0228da2d..5fdd97c2f41 100644 --- a/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.js +++ b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.js @@ -4,7 +4,7 @@ import { registerMessagingComponent } from '@mail/utils/messaging_component'; import { useRefToModel } from '@mail/component_hooks/use_ref_to_model'; import { useUpdateToModel } from '@mail/component_hooks/use_update_to_model'; -const { Component, onMounted } = owl; +const { Component } = owl; export class EmojiGridView extends Component { setup() { @@ -12,9 +12,6 @@ export class EmojiGridView extends Component { useRefToModel({ fieldName: 'listRef', refName: 'listRef'}); useRefToModel({ fieldName: 'viewBlockRef', refName: 'viewBlockRef'}); useUpdateToModel({ methodName: 'onComponentUpdate' }); - onMounted(() => { - this.emojiGridView.calculateDimensions(); - }); } /** diff --git a/addons/mail/static/src/models/emoji_grid_view.js b/addons/mail/static/src/models/emoji_grid_view.js index 485f0f38f53..32b746453cf 100644 --- a/addons/mail/static/src/models/emoji_grid_view.js +++ b/addons/mail/static/src/models/emoji_grid_view.js @@ -7,17 +7,6 @@ import { clear, increment } from '@mail/model/model_field_command'; registerModel({ name: 'EmojiGridView', recordMethods: { - calculateDimensions() { - if (!this.containerRef.el || !this.viewBlockRef.el) { - return; - } - const fittingAmount = this.containerRef.el.clientHeight / this.rowHeight; - const amountToDisplay = fittingAmount + this.additionalRowsToRender; - this.update({ - amountToDisplay, - scrollRecomputeCount: increment() - }); - }, doJumpToCategorySelectedByUser() { this.containerRef.el.scrollTo({ top: this.rowHeight * this.categorySelectedByUser.emojiGridRowView.index, @@ -64,24 +53,25 @@ registerModel({ }, }, fields: { - additionalRowsToRender: attr({ - default: 4, - }), amountOfItemsPerRow: attr({ default: 9, }), - amountToDisplay: attr({ - default: 50, - }), categorySelectedByUser: one('EmojiPickerView.Category'), containerRef: attr(), + /** + * Distance of the rendered rows from top. + * This is from the PoV of 1st rendered row, including extra rendered rows! + */ distanceFromTop: attr({ compute() { this.scrollRecomputeCount; // observe scroll changes if (!this.listRef || !this.listRef.el) { return clear(); } - return this.scrollPercentage * this.listRef.el.clientHeight; + return Math.max( + (this.scrollPercentage * this.listRef.el.clientHeight - this.extraRenderRowsAmount * this.rowHeight), + 0, + ); }, default: 0, }), @@ -95,16 +85,20 @@ registerModel({ identifying: true, inverse: 'emojiGridView', }), + /** + * Extra rows above and below the visible part. + * 10 means 10 rows above and 10 rows below. + */ + extraRenderRowsAmount: attr({ + default: 10, + }), firstRenderedRowIndex: attr({ compute() { this.scrollRecomputeCount; // observe scroll changes - let value; - if (this.scrollIndex - this.amountToDisplay >= this.rows.length) { - value = this.scrollIndex - this.amountToDisplay; - } else { - value = this.scrollIndex; - } - return Math.floor(value); + return Math.max( + this.scrollIndex - this.extraRenderRowsAmount, + 0, + ); }, default: 0, }), @@ -123,12 +117,12 @@ registerModel({ compute() { this.scrollRecomputeCount; // observe scroll changes let value; - if (this.firstRenderedRowIndex + this.amountToDisplay >= this.rows.length) { + if (this.firstRenderedRowIndex + this.renderedMaxAmount >= this.rows.length) { value = Math.max(this.rows.length - 1, 0); } else { - value = this.firstRenderedRowIndex + this.amountToDisplay; + value = this.firstRenderedRowIndex + this.renderedMaxAmount; } - return Math.floor(value); + return Math.ceil(value); }, default: 0, }), @@ -149,6 +143,11 @@ registerModel({ }, inverse: 'emojiGridViewAsOnScroll', }), + renderedMaxAmount: attr({ + compute() { + return this.extraRenderRowsAmount * 2 + Math.ceil(this.visibleMaxAmount); + }, + }), renderedRows: many('EmojiGridRowView', { compute() { if (this.lastRenderedRowIndex + 1 - this.firstRenderedRowIndex < 0) { @@ -176,13 +175,19 @@ registerModel({ return this.nonSearchRowRegistry.rows; }, }), + /** + * Scroll index of the 1st visible rendered rows (so excluding the extra rendered rendered rows). + */ scrollIndex: attr({ compute() { this.scrollRecomputeCount; // observe scroll changes - return (this.scrollPercentage * this.rows.length); + return Math.floor(this.scrollPercentage * this.rows.length); }, default: 0, }), + /** + * Scroll percentage of the 1st visible rendered rows. + */ scrollPercentage: attr({ compute() { this.scrollRecomputeCount; // observe scroll changes @@ -213,6 +218,14 @@ registerModel({ inverse: 'emojiGridViewOwnerAsSearch', }), viewBlockRef: attr(), + /** + * Amount of emoji that are visibly rendered in emoji grid. + * Decimal determines the partial visibility of the last emoji. + * For example, 9.5 means 9 emojis fully visible, and the last is half visible. + */ + visibleMaxAmount: attr({ + default: 9.5, + }), width: attr({ compute() { return this.itemWidth * this.amountOfItemsPerRow + this.scrollbarThresholdWidth;