diff --git a/addons/mail/static/src/components/emoji/emoji.js b/addons/mail/static/src/components/emoji/emoji.js index a1176ac215c..86c4effb3e3 100644 --- a/addons/mail/static/src/components/emoji/emoji.js +++ b/addons/mail/static/src/components/emoji/emoji.js @@ -4,12 +4,17 @@ import { registerMessagingComponent } from '@mail/utils/messaging_component'; const { Component } = owl; -export class Emoji extends Component {} +export class Emoji extends Component { + /** + * @returns {EmojiView} + */ + get emojiView() { + return this.props.record; + } +} Object.assign(Emoji, { - props: { - emojiView: Object, - }, + props: { record: Object }, template: 'mail.Emoji', }); diff --git a/addons/mail/static/src/components/emoji/emoji.xml b/addons/mail/static/src/components/emoji/emoji.xml index e9d08c395a9..9008585e8b1 100644 --- a/addons/mail/static/src/components/emoji/emoji.xml +++ b/addons/mail/static/src/components/emoji/emoji.xml @@ -2,8 +2,8 @@ - - + + diff --git a/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.js b/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.js new file mode 100644 index 00000000000..a340034b845 --- /dev/null +++ b/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.js @@ -0,0 +1,21 @@ +/** @odoo-module **/ + +import { registerMessagingComponent } from '@mail/utils/messaging_component'; + +const { Component } = owl; + +export class EmojiCategoryBarView extends Component { + /** + * @returns {EmojiCategoryBarView} + */ + get emojiCategoryBarView() { + return this.props.record; + } +} + +Object.assign(EmojiCategoryBarView, { + props: { record: Object }, + template: 'mail.EmojiCategoryBarView', +}); + +registerMessagingComponent(EmojiCategoryBarView); diff --git a/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.xml b/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.xml new file mode 100644 index 00000000000..7b4b0d39f8e --- /dev/null +++ b/addons/mail/static/src/components/emoji_category_bar_view/emoji_category_bar_view.xml @@ -0,0 +1,12 @@ + + + + +
+ + + +
+
+ +
diff --git a/addons/mail/static/src/components/emoji_category_view/emoji_category_view.js b/addons/mail/static/src/components/emoji_category_view/emoji_category_view.js new file mode 100644 index 00000000000..b5db3c90008 --- /dev/null +++ b/addons/mail/static/src/components/emoji_category_view/emoji_category_view.js @@ -0,0 +1,21 @@ +/** @odoo-module **/ + +import { registerMessagingComponent } from '@mail/utils/messaging_component'; + +const { Component } = owl; + +export class EmojiCategoryView extends Component { + /** + * @returns {EmojiCategoryView} + */ + get emojiCategoryView() { + return this.props.record; + } +} + +Object.assign(EmojiCategoryView, { + props: { record: Object }, + template: 'mail.EmojiCategoryView', +}); + +registerMessagingComponent(EmojiCategoryView); diff --git a/addons/mail/static/src/components/emoji_category_view/emoji_category_view.xml b/addons/mail/static/src/components/emoji_category_view/emoji_category_view.xml new file mode 100644 index 00000000000..875f726b8c1 --- /dev/null +++ b/addons/mail/static/src/components/emoji_category_view/emoji_category_view.xml @@ -0,0 +1,10 @@ + + + + + + + + + + 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 new file mode 100644 index 00000000000..be25e92201a --- /dev/null +++ b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.js @@ -0,0 +1,21 @@ +/** @odoo-module **/ + +import { registerMessagingComponent } from '@mail/utils/messaging_component'; + +const { Component } = owl; + +export class EmojiGridView extends Component { + /** + * @returns {EmojiGridView} + */ + get emojiGridView() { + return this.props.record; + } +} + +Object.assign(EmojiGridView, { + props: { record: Object }, + template: 'mail.EmojiGridView', +}); + +registerMessagingComponent(EmojiGridView); diff --git a/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.scss b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.scss new file mode 100644 index 00000000000..2cfa00244f2 --- /dev/null +++ b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.scss @@ -0,0 +1,8 @@ +// ------------------------------------------------------------------ +// Layout +// ------------------------------------------------------------------ + +.o_EmojiGridView { + display: grid; + grid-template-columns: repeat(9, 1fr); +} diff --git a/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.xml b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.xml new file mode 100644 index 00000000000..823ebe8634e --- /dev/null +++ b/addons/mail/static/src/components/emoji_grid_view/emoji_grid_view.xml @@ -0,0 +1,12 @@ + + + + +
+ + + +
+
+ +
diff --git a/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.js b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.js index 97bb2cc3ac4..434b02083b0 100644 --- a/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.js +++ b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.js @@ -1,52 +1,16 @@ /** @odoo-module **/ -import { useUpdate } from '@mail/component_hooks/use_update'; import { registerMessagingComponent } from '@mail/utils/messaging_component'; -import { LegacyComponent } from '@web/legacy/legacy_component'; -export class EmojiPickerView extends LegacyComponent { +const { Component } = owl; +export class EmojiPickerView extends Component { /** - * @override + * @returns {EmojiPickerView} */ - setup() { - super.setup(); - useUpdate({ func: () => this._update() }); - } - get emojiPickerView() { return this.props.record; } - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @private - */ - _update() { - this.trigger('o-popover-compute'); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - close() { - this.trigger('o-popover-close'); - } - - /** - * Returns whether the given node is self or a children of self. - * - * @param {Node} node - * @returns {boolean} - */ - contains(node) { - return Boolean(this.root.el && this.root.el.contains(node)); - } - } Object.assign(EmojiPickerView, { diff --git a/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.scss b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.scss index 3f0d8b7c481..31da23ef5e3 100644 --- a/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.scss +++ b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.scss @@ -1,9 +1,3 @@ -// ------------------------------------------------------------------ -// Layout -// ------------------------------------------------------------------ - .o_EmojiPickerView { - // Could be replaced by "d-grid" class after migration to BS5 - display: grid; - grid-template-columns: repeat(9, 1fr); + height: Min(80vh, 340px); } diff --git a/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.xml b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.xml index 6036aa8b892..e6ed2dc393f 100644 --- a/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.xml +++ b/addons/mail/static/src/components/emoji_picker_view/emoji_picker_view.xml @@ -2,12 +2,9 @@ -
- - - - - +
+ +
diff --git a/addons/mail/static/src/models/emoji_category.js b/addons/mail/static/src/models/emoji_category.js index 6cf51185522..980a9732d73 100644 --- a/addons/mail/static/src/models/emoji_category.js +++ b/addons/mail/static/src/models/emoji_category.js @@ -1,21 +1,11 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr, many, one } from '@mail/model/model_field'; -import { replace } from '@mail/model/model_field_command'; +import { attr, many } from '@mail/model/model_field'; registerModel({ name: 'EmojiCategory', identifyingFields: ['categoryName'], - recordMethods: { - /** - * @private - * @returns {FieldCommand} - */ - _computeEmojiRegistry() { - return replace(this.messaging.emojiRegistry); - }, - }, fields: { allEmojis: many('Emoji', { inverse: 'emojiCategories', @@ -26,13 +16,7 @@ registerModel({ }), emojiCategoryViews: many('EmojiCategoryView', { inverse: 'emojiCategory', - readonly: true, isCausal: true, }), - emojiRegistry: one('EmojiRegistry', { - compute: '_computeEmojiRegistry', - inverse: 'allCategories', - required: true, - }), }, }); diff --git a/addons/mail/static/src/models/emoji_category_bar_view.js b/addons/mail/static/src/models/emoji_category_bar_view.js new file mode 100644 index 00000000000..ab2faa19c38 --- /dev/null +++ b/addons/mail/static/src/models/emoji_category_bar_view.js @@ -0,0 +1,66 @@ +/** @odoo-module **/ + +import { registerModel } from '@mail/model/model_core'; +import { many, one } from '@mail/model/model_field'; +import { insertAndReplace, replace } from '@mail/model/model_field_command'; + +registerModel({ + name: 'EmojiCategoryBarView', + identifyingFields: ['emojiPickerViewOwner'], + recordMethods: { + /** + * @private + * @returns {FieldCommand} + */ + _computeActiveCategoryView() { + if (!this.activeByUserCategoryView) { + return replace(this.defaultActiveCategoryView); + } + return replace(this.activeByUserCategoryView); + }, + /** + * @private + * @returns {FieldCommand} + */ + _computeDefaultActiveCategoryView() { + return insertAndReplace({ + emojiCategory: insertAndReplace({ categoryName: "all" }), + emojiCategoryBarViewOwner: replace(this), + }); + }, + /** + * @private + * @returns {FieldCommand} + */ + _computeEmojiCategoryViews() { + return insertAndReplace( + this.messaging.emojiRegistry.allCategories.map(emojiCategory => { + return { emojiCategory: replace(emojiCategory) }; + }) + ); + }, + }, + fields: { + activeByUserCategoryView: one('EmojiCategoryView', { + inverse: 'emojiCategoryBarViewOwnerAsActiveByUser', + }), + activeCategoryView: one('EmojiCategoryView', { + compute: '_computeActiveCategoryView', + inverse: 'emojiCategoryBarViewOwnerAsActive', + required: true, + }), + defaultActiveCategoryView: one('EmojiCategoryView', { + compute: '_computeDefaultActiveCategoryView', + }), + emojiCategoryViews: many('EmojiCategoryView', { + compute: '_computeEmojiCategoryViews', + inverse: 'emojiCategoryBarViewOwner', + isCausal: true, + }), + emojiPickerViewOwner: one('EmojiPickerView', { + inverse: 'emojiCategoryBarView', + readonly: true, + required: true, + }), + }, +}); diff --git a/addons/mail/static/src/models/emoji_category_view.js b/addons/mail/static/src/models/emoji_category_view.js index 561ebe23ca4..d060659cf01 100644 --- a/addons/mail/static/src/models/emoji_category_view.js +++ b/addons/mail/static/src/models/emoji_category_view.js @@ -1,21 +1,51 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { one } from '@mail/model/model_field'; +import { attr, one } from '@mail/model/model_field'; +import { replace } from '@mail/model/model_field_command'; registerModel({ name: 'EmojiCategoryView', - identifyingFields: ['emojiCategory', 'emojiPickerView'], + identifyingFields: ['emojiCategoryBarViewOwner', 'emojiCategory'], + recordMethods: { + /** + * @param {MouseEvent} ev + */ + onClick() { + this.update({ emojiCategoryBarViewOwnerAsActiveByUser: replace(this.emojiCategoryBarViewOwner) }); + }, + /** + * @param {MouseEvent} ev + */ + onMouseenter(ev) { + this.update({ isHovered: true }); + }, + /** + * @param {MouseEvent} ev + */ + onMouseleave(ev) { + this.update({ isHovered: false }); + }, + }, fields: { emojiCategory: one('EmojiCategory', { inverse: 'emojiCategoryViews', readonly: true, required: true, }), - emojiPickerView: one('EmojiPickerView', { + emojiCategoryBarViewOwner: one('EmojiCategoryBarView', { inverse: 'emojiCategoryViews', readonly: true, required: true, }), + emojiCategoryBarViewOwnerAsActiveByUser: one('EmojiCategoryBarView', { + inverse: 'activeByUserCategoryView', + }), + emojiCategoryBarViewOwnerAsActive: one('EmojiCategoryBarView', { + inverse: 'activeCategoryView', + }), + isHovered: attr({ + default: false, + }), } }); diff --git a/addons/mail/static/src/models/emoji_grid_view.js b/addons/mail/static/src/models/emoji_grid_view.js new file mode 100644 index 00000000000..bf82755d27a --- /dev/null +++ b/addons/mail/static/src/models/emoji_grid_view.js @@ -0,0 +1,39 @@ +/** @odoo-module **/ + +import { registerModel } from '@mail/model/model_core'; +import { many, one } from '@mail/model/model_field'; +import { clear, insertAndReplace, replace } from '@mail/model/model_field_command'; + +registerModel({ + name: 'EmojiGridView', + identifyingFields: ['emojiPickerViewOwner'], + recordMethods: { + /** + * @private + * @returns {FieldCommand} + */ + _computeEmojiViews() { + if (!this.emojiPickerViewOwner.emojiCategoryBarView.activeCategoryView) { + return clear(); + } + return insertAndReplace( + this.emojiPickerViewOwner.emojiCategoryBarView.activeCategoryView.emojiCategory.allEmojis.map(emoji => { + return { emoji: replace(emoji) }; + }) + ); + }, + }, + fields: { + emojiPickerViewOwner: one('EmojiPickerView', { + inverse: 'emojiGridView', + readonly: true, + required: true, + }), + emojiViews: many('EmojiView', { + compute: '_computeEmojiViews', + inverse: 'emojiGridView', + readonly: true, + isCausal: true, + }), + }, +}); diff --git a/addons/mail/static/src/models/emoji_picker_view.js b/addons/mail/static/src/models/emoji_picker_view.js index c3e6d5e314a..2b44269ec6a 100644 --- a/addons/mail/static/src/models/emoji_picker_view.js +++ b/addons/mail/static/src/models/emoji_picker_view.js @@ -1,59 +1,25 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { many, one } from '@mail/model/model_field'; -import { insertAndReplace, replace } from '@mail/model/model_field_command'; +import { one } from '@mail/model/model_field'; +import { insertAndReplace } from '@mail/model/model_field_command'; registerModel({ name: 'EmojiPickerView', identifyingFields: ['popoverViewOwner'], - recordMethods: { - /** - * @param {MouseEvent} ev - */ - onClickEmoji(ev) { - if (this.popoverViewOwner.messageActionListOwnerAsReaction) { - this.popoverViewOwner.messageActionListOwnerAsReaction.onClickReaction(ev); - } else if (this.popoverViewOwner.composerViewOwnerAsEmoji) { - this.popoverViewOwner.composerViewOwnerAsEmoji.onClickEmoji(ev); - } - }, - - /** - * @private - * @returns {FieldCommand} - */ - _computeEmojiViews() { - return insertAndReplace( - this.messaging.emojiRegistry.allEmojis.map(emoji => { - return { emoji: replace(emoji) }; - }) - ); - }, - - /** - * @private - * @returns {FieldCommand} - */ - _computeEmojiCategoryViews() { - return insertAndReplace( - this.messaging.emojiRegistry.allCategories.map(emojiCategory => { - return { emojiCategory: replace(emojiCategory) }; - }) - ); - }, - }, fields: { - emojiCategoryViews: many('EmojiCategoryView', { - compute: '_computeEmojiCategoryViews', - inverse: 'emojiPickerView', + emojiCategoryBarView: one('EmojiCategoryBarView', { + default: insertAndReplace(), + inverse: 'emojiPickerViewOwner', readonly: true, + required: true, isCausal: true, }), - emojiViews: many('EmojiView', { - compute: '_computeEmojiViews', - inverse: 'emojiPickerView', + emojiGridView: one('EmojiGridView', { + default: insertAndReplace(), + inverse: 'emojiPickerViewOwner', readonly: true, + required: true, isCausal: true, }), popoverViewOwner: one('PopoverView', { diff --git a/addons/mail/static/src/models/emoji_registry.js b/addons/mail/static/src/models/emoji_registry.js index d5aed909aec..2320dedff47 100644 --- a/addons/mail/static/src/models/emoji_registry.js +++ b/addons/mail/static/src/models/emoji_registry.js @@ -105,7 +105,6 @@ registerModel({ { categoryName: "⚽️", allEmojis: insertAndReplace(["🏃", "🚲", "⚽️", "🏈", "🎱", "🎬", "🎤"].map(unicode => ({ unicode }))) }, ]), - inverse: 'emojiRegistry', }), }, }); diff --git a/addons/mail/static/src/models/emoji_view.js b/addons/mail/static/src/models/emoji_view.js index 27e3f46f06c..a95f292a26c 100644 --- a/addons/mail/static/src/models/emoji_view.js +++ b/addons/mail/static/src/models/emoji_view.js @@ -1,21 +1,51 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { one } from '@mail/model/model_field'; +import { attr, one } from '@mail/model/model_field'; registerModel({ name: 'EmojiView', - identifyingFields: ['emoji', 'emojiPickerView'], + identifyingFields: ['emojiGridView', 'emoji'], + recordMethods: { + /** + * @param {MouseEvent} ev + */ + onClick(ev) { + if (this.emojiGridView.emojiPickerViewOwner.popoverViewOwner.messageActionListOwnerAsReaction) { + this.emojiGridView.emojiPickerViewOwner.popoverViewOwner.messageActionListOwnerAsReaction.onClickReaction(ev); + return; + } + if (this.emojiGridView.emojiPickerViewOwner.popoverViewOwner.composerViewOwnerAsEmoji) { + this.emojiGridView.emojiPickerViewOwner.popoverViewOwner.composerViewOwnerAsEmoji.onClickEmoji(ev); + return; + } + }, + /** + * @param {MouseEvent} ev + */ + onMouseenter(ev) { + this.update({ isHovered: true }); + }, + /** + * @param {MouseEvent} ev + */ + onMouseleave(ev) { + this.update({ isHovered: false }); + }, + }, fields: { emoji: one('Emoji', { inverse: 'emojiViews', readonly: true, required: true, }), - emojiPickerView: one('EmojiPickerView', { + emojiGridView: one('EmojiGridView', { inverse: 'emojiViews', readonly: true, required: true, }), + isHovered: attr({ + default: false, + }), } }); diff --git a/addons/mail/static/src/models/popover_view.js b/addons/mail/static/src/models/popover_view.js index 6937e1d0dd8..03ec734d4a0 100644 --- a/addons/mail/static/src/models/popover_view.js +++ b/addons/mail/static/src/models/popover_view.js @@ -106,7 +106,7 @@ registerModel({ return 'ChannelInvitationForm'; } if (this.emojiPickerView) { - return 'EmojiPicker'; + return 'EmojiPickerView'; } return clear(); },