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;