diff options
| author | Robot Odoo <xmo+roboto@odoo.com> | 2018-12-07 09:33:01 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-07 09:33:01 +0100 |
| commit | 9f6f9c71d3258ce3652b4a5793b7dcfef6f01d25 (patch) | |
| tree | 8b092fb030790b77ebc1c4061bac08c8edc3befa /addons/mail/static/src/xml | |
| parent | 37212fe655e7e2b2df6fcdfb9d08fcc970e7735b (diff) | |
| parent | 844fb2b51ea7cfa557b19466c0a53dde19433e7a (diff) | |
[MERGE] mail, *: several UX/UI improvements
*: bus, im_livechat, mail_bot, website_livechat
Several improvements for Discuss app:
1. Improved "is typing..." notification
2. Merged private & public channels
3. Quick channel search
4. No push notification right after accepting them, and transparent odoo bot icon in native notification
5. Selected emojis are inserted in composer based on cursor position
6. Set surname to people for DMs name
7. Discard replying to a message in Inbox
8. Broadcast "seen" notification ('v' and 'vv' on messages)
[1] [image1](https://drive.google.com/file/d/11_H6ZJh0wFaegAV0fTLdc68z37nhVKnW/view?usp=sharing), [image2](https://drive.google.com/file/d/1s9g_hUCMesuTLAqpeGMwLWzHCYnzanr6/view?usp=sharing)
[2] [image1](https://drive.google.com/file/d/1WUBqc2lScfWV8Yrtq6Zk4MO4jC0CdaiG/view?usp=sharing), [image2](https://drive.google.com/file/d/13XVcW0Nookwea_4xz02mIwPi5dPhXu18/view?usp=sharing)
[3] [image1](https://drive.google.com/file/d/1FuV3xH9cK6qR7ljd5vELOHc4icvHIJTF/view?usp=sharing), [image2](https://drive.google.com/file/d/1hwuu5ejlj9ou02NF5XmL-XHTiD-Ty6XT/view?usp=sharing)
[4] [image](https://drive.google.com/file/d/1si1TYtCpdyOgw9IRaMWmxuUb1d8M4ccF/view?usp=sharing)
[5] [video](https://drive.google.com/file/d/19knQ47F1wzlNvxT2nJH3A9V34wO1D9Bn/view?usp=sharing)
[6] [image1](https://drive.google.com/file/d/11ot_DtySN2cIN_bM8n7fhFV2JXNoz0lH/view?usp=sharing), [image2](https://drive.google.com/file/d/1aNyapzKePIRg903woCo3kXJhy-ZFwfEG/view?usp=sharing), [image3](https://drive.google.com/file/d/1AtVlOG67YjsS8ax1ErWhXfSDOtKhLQhC/view?usp=sharing)
[7] [image](https://drive.google.com/file/d/1U-VEut7M7-t9WzdKVagfyy6ZrbOJrflp/view?usp=sharing)
[8] [image1](https://drive.google.com/file/d/1_32q8iqPBhW4sPhAtY5mIO968gj1o9o-/view?usp=sharing), [image2](https://drive.google.com/file/d/1Ne6HMEgJxHAWYN3e3SlrF6Qqg70LDvAW/view?usp=sharing)
Task-ID 1881001
closes odoo/odoo#29191
Diffstat (limited to 'addons/mail/static/src/xml')
| -rw-r--r-- | addons/mail/static/src/xml/abstract_thread_window.xml | 3 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/composer.xml | 9 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/discuss.xml | 168 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/thread.xml | 96 |
4 files changed, 188 insertions, 88 deletions
diff --git a/addons/mail/static/src/xml/abstract_thread_window.xml b/addons/mail/static/src/xml/abstract_thread_window.xml index de0418af3df..89c45323c7a 100644 --- a/addons/mail/static/src/xml/abstract_thread_window.xml +++ b/addons/mail/static/src/xml/abstract_thread_window.xml @@ -11,6 +11,7 @@ <t t-set="status" t-value="widget.getThreadStatus()"/> <t t-set="title" t-value="widget.getTitle()"/> <t t-set="unreadCounter" t-value="widget.getUnreadCounter()"/> + <t t-set="thread" t-value="widget.getThread()"/> </t> </div> <div class="o_thread_window_content"> @@ -58,6 +59,7 @@ name of the document. @param {integer} [unreadCounter] the number of unread messages on the thread. + @param {mail.model.Thread|undefined} thread @param {Object} widget @param {function} widget.isMobile function without any param that states whether it should render for desktop or mobile screen. @@ -70,6 +72,7 @@ <t t-if="status" t-call="mail.UserStatus"/> <t t-esc="title"/> <span t-if="unreadCounter"> (<t t-esc="unreadCounter"/>)</span> + <t t-if="thread and thread.hasTypingNotification() and thread.isSomeoneTyping()" t-call="mail.ThreadTypingIcon"/> </span> <span t-if="!widget.isMobile()" class="o_thread_window_buttons"> <a href="#" class="o_thread_window_close fa fa-close"/> diff --git a/addons/mail/static/src/xml/composer.xml b/addons/mail/static/src/xml/composer.xml index 883c9752035..ec95a6d5b61 100644 --- a/addons/mail/static/src/xml/composer.xml +++ b/addons/mail/static/src/xml/composer.xml @@ -24,9 +24,11 @@ </div> </div> <div class="o_composer_attachments_list"/> + <div class="o_composer_thread_typing"/> </div> <div class="o_composer_send"> <button tabindex="3" class="btn btn-primary o_composer_button_send d-none d-md-inline-block" type="button"><t t-esc="widget.options.sendText"/></button> + <button tabindex="3" class="btn btn-secondary o_composer_button_discard d-none" type="button">Discard</button> </div> <span class="d-none"> <t t-call="HiddenInputFile"> @@ -40,6 +42,13 @@ </span> </div> + <!-- + @param {mail.model.Thread} thread + --> + <t t-name="mail.Composer.ThreadTyping"> + <t t-esc="thread.getTypingMembersToText()"/> + </t> + <div t-name="mail.Composer.emojis" class="o_mail_emoji_container"> <t t-foreach="emojis" t-as="emoji"> <button t-att-data-emoji="emoji.sources[0]" class="btn btn-link o_mail_emoji" t-att-title="emoji.description" t-att-aria-label="emoji.description"> diff --git a/addons/mail/static/src/xml/discuss.xml b/addons/mail/static/src/xml/discuss.xml index 605dcb53956..98430c81ce1 100644 --- a/addons/mail/static/src/xml/discuss.xml +++ b/addons/mail/static/src/xml/discuss.xml @@ -16,62 +16,82 @@ <!-- @param {string|integer} activeThreadID - @param {integer} moderationCounter - @param {integer} needactionCounter - @param {integer} starredCounter + @param {mail.model.Channel[]} channels + @param {boolean} isMyselfModerator + @param {mail.model.Mailbox} inbox + @param {mail.model.Mailbox} starred + @param {mail.model.Mailbox|undefined} moderation set if current user is moderator + @param {boolean} displayQuickSearch + @param {Object} options --> <t t-name="mail.discuss.Sidebar"> <div class="o_mail_discuss_sidebar"> - <div t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID === 'mailbox_inbox') ? 'o_active': ''}" - data-thread-id="mailbox_inbox"> - <span class="o_thread_name"><i class="fa fa-inbox mr8"/>Inbox</span> - <t t-set="counter" t-value="needactionCounter"/> - <t t-call="mail.discuss.SidebarCounter"/> + <div class="o_mail_discuss_sidebar_mailboxes"> + <t t-call="mail.discuss.SidebarMailboxes"/> </div> - <div t-attf-class="o_mail_discuss_title_main o_mail_mailbox_title_starred o_mail_discuss_item #{(activeThreadID === 'mailbox_starred') ? 'o_active': ''}" - data-thread-id="mailbox_starred"> - <span class="o_thread_name"><i class="fa fa-star-o mr8"/>Starred</span> - <t t-set="counter" t-value="starredCounter"/> - <t t-call="mail.discuss.SidebarCounter"/> + <hr class="mb8"/> + <div t-if="displayQuickSearch" class="o_discuss_sidebar_quick_search"> + <t t-set="inputPlaceholder">Quick search...</t> + <input t-att-placeholder="inputPlaceholder"/> </div> - <div t-if="isMyselfModerator" t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID == 'mailbox_moderation') ? 'o_active': ''}" - data-thread-id="mailbox_moderation"> - <span class="o_thread_name"> <i class="fa fa-envelope mr8"/>Moderation Queue</span> - <t t-set="counter" t-value="moderationCounter"/> - <t t-call="mail.discuss.SidebarCounter"/> + <div class="o_mail_discuss_sidebar_channels"> + <t t-call="mail.discuss.SidebarChannels"/> </div> - <hr class="mb8"/> + </div> + </t> - <t t-set="type" t-value="'public'"/> - <t t-call="mail.discuss.SidebarTitle"> - <t t-set="title">Channels</t> - <t t-set="icon" t-value="fa-users"/> - </t> - <t t-call="mail.discuss.SidebarItems"> - <t t-set="displayHash" t-value="true"/> - <t t-set="inputPlaceholder">Add a channel</t> - </t> + <!-- + @param {string|integer} activeThreadID + @param {boolean} isMyselfModerator + @param {mail.model.Mailbox} inbox + @param {mail.model.Mailbox} starred + @param {mail.model.Mailbox|undefined} moderation set if current user is moderator + --> + <t t-name="mail.discuss.SidebarMailboxes"> + <div t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID === 'mailbox_inbox') ? 'o_active': ''}" + data-thread-id="mailbox_inbox"> + <span class="o_thread_name"><i class="fa fa-inbox mr8"/>Inbox</span> + <t t-set="counter" t-value="inbox.getMailboxCounter()"/> + <t t-call="mail.discuss.SidebarCounter"/> + </div> + <div t-attf-class="o_mail_discuss_title_main o_mail_mailbox_title_starred o_mail_discuss_item #{(activeThreadID === 'mailbox_starred') ? 'o_active': ''}" + data-thread-id="mailbox_starred"> + <span class="o_thread_name"><i class="fa fa-star-o mr8"/>Starred</span> + <t t-set="counter" t-value="starred.getMailboxCounter()"/> + <t t-call="mail.discuss.SidebarCounter"/> + </div> + <div t-if="isMyselfModerator" t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID == 'mailbox_moderation') ? 'o_active': ''}" + data-thread-id="mailbox_moderation"> + <span class="o_thread_name"> <i class="fa fa-envelope mr8"/>Moderation Queue</span> + <t t-set="counter" t-value="moderation.getMailboxCounter()"/> + <t t-call="mail.discuss.SidebarCounter"/> + </div> + </t> - <t t-set="type" t-value="'dm_chat'"/> - <t t-call="mail.discuss.SidebarTitle"> - <t t-set="title">Direct Messages</t> - <t t-set="icon" t-value="fa-user"/> - </t> - <t t-call="mail.discuss.SidebarItems"> - <t t-set="displayStatus" t-value="true"/> - <t t-set="inputPlaceholder">User name</t> - </t> + <!-- + @param {string|integer} activeThreadID + @param {mail.model.Channel[]} channels + --> + <t t-name="mail.discuss.SidebarChannels"> + <t t-set="type" t-value="'multi_user_channel'"/> + <t t-call="mail.discuss.SidebarTitle"> + <t t-set="title">Channels</t> + <t t-set="icon" t-value="fa-users"/> + </t> + <t t-call="mail.discuss.SidebarItems"> + <t t-set="displayHash" t-value="true"/> + <t t-set="inputPlaceholder">Add a channel</t> + </t> - <t t-set="type" t-value="'private'"/> - <t t-call="mail.discuss.SidebarTitle"> - <t t-set="title">Private Channels</t> - <t t-set="icon" t-value="fa-eye-slash"/> - </t> - <t t-call="mail.discuss.SidebarItems"> - <t t-set="inputPlaceholder">Add a private channel</t> - <t t-set="displayHash" t-value="true"/> - </t> - </div> + <t t-set="type" t-value="'dm_chat'"/> + <t t-call="mail.discuss.SidebarTitle"> + <t t-set="title">Direct Messages</t> + <t t-set="icon" t-value="fa-user"/> + </t> + <t t-call="mail.discuss.SidebarItems"> + <t t-set="displayStatus" t-value="true"/> + <t t-set="inputPlaceholder">User name</t> + </t> </t> <!-- @@ -87,24 +107,24 @@ Don't display the thread type if there is no thread of such type and the 'add a thread' option is disabled for this type - @param {mail.model.Thread[]} threads + @param {mail.model.Channel[]} channels @param {boolean} [disableAddThread] whether the 'Add thread' action should disabled or not for the considered discuss item category @param {string} [icon] classname to add on title to display icon - @param {string} title the displayed type of the discuss items (e.g. "Private Channels") + @param {string} title the displayed type of the discuss items (e.g. "Channels") @param {string} type the type of the thread --> <t t-name="mail.discuss.SidebarTitle"> <t t-if="disableAddThread"> <t t-set="empty" t-value="true"/> - <t t-foreach="threads" t-as="thread"> - <t t-if="thread.getType() === type"> + <t t-foreach="channels" t-as="channel"> + <t t-if="channel.getType() === type"> <t t-set="empty" t-value="false"/> </t> </t> </t> <t t-if="!disableAddThread || !empty"> <div class="o_mail_sidebar_title"> - <h4 t-att-class="type == 'public' ? 'o_mail_open_channels' : ''"> + <h4 t-att-class="type == 'multi_user_channel' ? 'o_mail_open_channels' : ''"> <i t-if="icon" t-attf-class="mr4 fa-fw fa #{icon}" role="img" aria-label="Channel" title="Channel"></i> <b><t t-esc="title"/></b> </h4> @@ -115,7 +135,7 @@ <!-- @param {string|integer} activeThreadID - @param {mail.model.Thread[]} threads + @param {mail.model.Channel[]} channels @param {boolean} disableAddThread whether the 'Add thread' action should be disable or not for the considered discuss item category @param {boolean} [displayHash] whether the hash ('#') character should be displayed as a prefix for item's name @param {boolean} [displayStatus] whether the item should display its status (should be the case only for chats) @@ -126,25 +146,30 @@ <span t-if="displayHash">#</span> <input type="text" class="o_input" t-attf-placeholder="#{inputPlaceholder}"/> </div> - <t t-foreach="threads" t-as="thread"> - <t t-set="counter" t-value="thread.getType() === 'mailbox' ? thread.getMailboxCounter() : thread.isTwoUserThread() ? thread.getUnreadCounter() : thread.getNeedactionCounter()"/> - <div t-if="thread.getType() === type" t-att-data-thread-id="thread.getID()" t-att-title="thread.getName()" - t-attf-class="o_mail_discuss_item #{thread.hasUnreadMessages() ? ' o_unread_message' : ''} #{(activeThreadID == thread.getID()) ? 'o_active': ''}"> + <t t-foreach="channels" t-as="channel"> + <t t-set="counter" t-value="channel.isTwoUserThread() ? channel.getUnreadCounter() : channel.getNeedactionCounter()"/> + <div t-if="channel.getType() === type" t-att-data-thread-id="channel.getID()" t-att-title="channel.getName()" + t-attf-class="o_mail_discuss_item #{channel.hasUnreadMessages() ? ' o_unread_message' : ''} #{(activeThreadID == channel.getID()) ? 'o_active': ''}"> <span class="o_thread_name"> <span t-if="displayStatus"> <t t-call="mail.UserStatus"> - <t t-set="status" t-value="thread.getStatus()"/> + <t t-set="status" t-value="channel.getStatus()"/> </t> </span> <span t-if="displayHash" class="o_mail_hash">#</span> - <t t-esc="_.unescape(thread.getName())"/> - <i t-if="thread.isMassMailing()" class="fa fa-envelope-o" title="Sends messages by email" role="img" aria-label="Send by mail"/> + <i t-if="channel.getType() === 'multi_user_channel' and !channel.isPublic()" class="fa fa-lock" title="Private channel" role="img" aria-label="Private channel"/> + <t t-esc="_.unescape(channel.getName())"/> + <i t-if="channel.isMassMailing()" class="fa fa-envelope-o" title="Sends messages by email" role="img" aria-label="Send by mail"/> </span> + <t t-if="channel.hasTypingNotification() and channel.isSomeoneTyping()"> + <t t-set="thread" t-value="channel"/> + <t t-call="mail.ThreadTypingIcon"/> + </t> <span t-attf-class="fa fa-cog o_mail_channel_settings" - title="Channel settings" role="img" aria-label="Channel settings" t-att-data-thread-id="thread.getID()"/> + title="Channel settings" role="img" aria-label="Channel settings" t-att-data-thread-id="channel.getID()"/> <t t-call="mail.discuss.SidebarCounter"/> - <span t-if="!thread.isGroupBasedSubscription()" t-attf-class="fa fa-times o_mail_partner_unpin #{counter ? 'd-none' : ''}" - title="Leave this channel" role="img" aria-label="Leave this channel" t-att-data-thread-id="thread.getID()"/> + <span t-if="!channel.isGroupBasedSubscription()" t-attf-class="fa fa-times o_mail_partner_unpin #{counter ? 'd-none' : ''}" + title="Leave this channel" role="img" aria-label="Leave this channel" t-att-data-thread-id="channel.getID()"/> </div> </t> </t> @@ -179,7 +204,7 @@ <button type="button" class="btn btn-secondary o_mail_discuss_button_mark_all_read d-none d-md-inline-block" title="Mark all as read">Mark all read</button> <button type="button" class="btn btn-secondary o_mail_discuss_button_unstar_all" title="Unstar all messages">Unstar all</button> <button type="button" class="btn btn-secondary o_mail_discuss_button_dm_chat o_hidden d-md-none" title="New Message">New Message</button> - <button t-if="!disableAddThread" type="button" class="btn btn-secondary o_mail_discuss_button_public o_mail_discuss_button_private d-block d-md-none" title="New Channel">New Channel</button> + <button t-if="!disableAddThread" type="button" class="btn btn-secondary o_mail_discuss_button_multi_user_channel d-block d-md-none" title="New Channel">New Channel</button> <button type="button" class="btn btn-secondary o_hidden o_mail_discuss_button_select_all" title="Select all messages to moderate">Select All</button> <button type="button" class="btn btn-secondary o_hidden o_mail_discuss_button_unselect_all" title="Unselect all messages to moderate">Unselect All</button> <button type="button" data-decision="accept" class="btn btn-secondary o_mail_discuss_button_moderate_all" title="Accept selected messages">Accept</button> @@ -193,6 +218,11 @@ <input type="text" class="o_input o_mail_discuss_partner_invite_input" id="mail_search_partners"/> </div> + <!-- Rename channel dialog's content --> + <div t-name="mail.RenameConversationDialog"> + <input type="text" class="o_input o_mail_discuss_rename_channel_input"/> + </div> + <div t-name="mail.ModeratorRejectMessageDialog"> <input class="form-control" type="text" id="message_title" placeholder="Subject" value="Message Rejected"/> <textarea class="form-control mt16" id="reject_message" placeholder="Mail Body">Your message was rejected by moderator.</textarea> @@ -219,14 +249,10 @@ <span class="fa fa-user"/> <span class="o_tab_title">Chat</span> </div> - <div class="o_mail_mobile_tab" data-type="public"> + <div class="o_mail_mobile_tab" data-type="multi_user_channel"> <span class="fa fa-users"/> <span class="o_tab_title">Channels</span> </div> - <div class="o_mail_mobile_tab" data-type="private"> - <span class="fa fa-eye-slash"/> - <span class="o_tab_title">Private Channels</span> - </div> </div> </div> </t> @@ -238,8 +264,8 @@ <t t-name="mail.discuss.MobileTabPane"> <div class="o_mail_discuss_tab_pane" t-att-data-type="type"> <div t-if="!disableAddThread" class="o_mail_add_thread" t-att-data-type="type"> - <span t-if="type == 'private' || type == 'public'">#</span> - <t t-set="inputPlaceholder" t-if="type == 'private' || type == 'public'">Add a channel</t> + <span t-if="type == 'multi_user_channel'">#</span> + <t t-set="inputPlaceholder" t-if="type == 'multi_user_channel'">Add a channel</t> <t t-set="inputPlaceholder" t-if="type == 'dm_chat'">Open chat</t> <input type="text" t-attf-placeholder="#{inputPlaceholder}"/> </div> diff --git a/addons/mail/static/src/xml/thread.xml b/addons/mail/static/src/xml/thread.xml index f28e071b2f3..fcfe8ba7de2 100644 --- a/addons/mail/static/src/xml/thread.xml +++ b/addons/mail/static/src/xml/thread.xml @@ -191,7 +191,6 @@ <t t-if="options.displayBottomThreadFreeSpace"> <div class="o_thread_bottom_free_space"/> </t> - <t t-if="thread.hasTypingNotification()" t-call="mail.widget.Thread.TypingNotificationBar"/> </div> </t> @@ -217,27 +216,12 @@ <div class="o_mail_thread_content"> <t t-if="options.messagesSeparatorPosition == 'top'" t-call="mail.MessagesSeparator"/> <t t-set="messages" t-value="messages.slice().reverse()"/> - <t t-if="thread.hasTypingNotification()" t-call="mail.widget.Thread.TypingNotificationBar"/> <t t-call="mail.widget.Thread.Messages"/> <t t-if="options.displayLoadMore" t-call="mail.widget.Thread.LoadMore"/> </div> </t> <!-- - @param {mail.model.AbstractThread} thread - --> - <t t-name="mail.widget.Thread.TypingNotificationBar"> - <t t-if="options.displayOrder === ORDER.ASC"> - <div class="o_thread_typing_notification_free_space"/> - <div class="o_thread_typing_notification_bar o_thread_order_asc"/> - </t> - <t t-else=""> - <div class="o_thread_typing_notification_free_space"/> - <div class="o_thread_typing_notification_bar o_thread_order_desc"/> - </t> - </t> - - <!-- @param {mail.model.AbstractMessage[]} messages messages are ordered based on desired display order --> @@ -275,7 +259,7 @@ @param {integer} [options.selectedMessageID] --> <t t-name="mail.widget.Thread.Message"> - <div t-att-class="'o_thread_message' + (message.getID() === options.selectedMessageID ? 'o_thread_selected_message ' : ' ') + (message.isDiscussion() or message.isNotification() ? ' o_mail_discussion' : ' o_mail_not_discussion')" t-att-data-message-id="message.getID()"> + <div t-att-class="'o_thread_message ' + (message.getID() === options.selectedMessageID ? 'o_thread_selected_message ' : ' ') + (message.isDiscussion() or message.isNotification() ? ' o_mail_discussion ' : ' o_mail_not_discussion ')" t-att-data-message-id="message.getID()"> <div t-if="options.displayAvatars" class="o_thread_message_sidebar"> <t t-if="message.hasAuthor()"> <img t-if="displayAuthorMessages[message.getID()]" @@ -297,6 +281,7 @@ <i t-if="!displayAuthorMessages[message.getID()] and options.displayStars and message.getType() !== 'notification'" t-att-class="'fa o_thread_message_star o_thread_icon ' + (message.isStarred() ? 'fa-star' : 'fa-star-o')" t-att-data-message-id="message.getID()" title="Mark as Todo" role="img" aria-label="Mark as todo"/> + <t t-if="!displayAuthorMessages[message.getID()] and thread.hasSeenFeature()" t-call="mail.widget.Thread.Message.SeenIcon"/> </div> <div class="o_thread_message_core"> <p t-if="displayAuthorMessages[message.getID()]" class="o_mail_info text-muted"> @@ -335,6 +320,7 @@ <i t-att-class="'o_thread_tooltip o_thread_message_email o_thread_message_email_' + message.getCustomerEmailStatus() + ' fa fa-envelope-o'" t-att-data-message-id="message.getID()"/> </span> <span t-attf-class="o_thread_icons"> + <t t-if="thread.hasSeenFeature()" t-call="mail.widget.Thread.Message.SeenIcon"/> <i t-if="options.displayStars and !message.isSystemNotification() and !message.needsModeration()" t-att-class="'fa fa-lg o_thread_icon o_thread_message_star ' + (message.isStarred() ? 'fa-star' : 'fa-star-o')" t-att-data-message-id="message.getID()" title="Mark as Todo" role="img" aria-label="Mark as Todo"/> @@ -380,6 +366,70 @@ </t> <!-- + Display the seen icon of a message in the thread. + It shows the fetch 'check' before the seen 'check'. We change the order in the template + so that fetch 'check' is on top of 'seen' check (z-index does not work with absolute positioning) + + @param {mail.model.Thread} thread + @param {mail.model.Message} message + --> + <t t-name="mail.widget.Thread.Message.SeenIcon"> + <t t-if="message.isMyselfAuthor() and message.getID() >= thread.getLastMessageIDSeenByEveryone()"> + <span t-attf-class="o_mail_thread_message_seen_icon #{thread.hasEveryoneSeen(message) ? 'o_all_seen' : ''}" t-att-data-message-id="message.getID()"> + <t t-if="thread.hasSomeoneFetched(message)"> + <i class="fa fa-check"/> + </t> + <t t-if="thread.hasSomeoneSeen(message)"> + <i class="fa fa-check"/> + </t> + </span> + </t> + </t> + + <!-- + Display the popover content when clicking the seen icion of a message in the thread. + + List the members that have received the messages, and the members that have seen it. + + @param {mail.model.Thread} thread + @param {mail.model.Message} message + --> + <t t-name="mail.widget.Thread.Message.SeenIconPopoverContent"> + <div class="o_mail_thread_message_seen_icon_content"> + <t t-if="thread.hasEveryoneSeen(message)"> + <p>Seen by Everyone</p> + </t> + <t t-else=""> + <t t-if="thread.hasSomeoneSeen(message)"> + <t t-set="seen_members" t-value="thread.getSeenMembers(message)"/> + Seen by: + <ul> + <li t-foreach="seen_members" t-as="member"> + <t t-esc="member.name"/> (<t t-esc="member.email"/>) + </li> + </ul> + </t> + <t t-if="thread.hasSomeoneFetched(message)"> + <t t-if="thread.hasEveryoneFetched(message)"> + <p>Received by Everyone</p> + </t> + <t t-else=""> + <t t-set="fetched_members" t-value="thread.getFetchedNotSeenMembers(message)"/> + <t t-if="!_.isEmpty(fetched_members)"> + Received by: + <ul> + <li t-foreach="fetched_members" t-as="member"> + <t t-esc="member.name"/> (<t t-esc="member.email"/>) + </li> + </ul> + </t> + </t> + </t> + </t> + </div> + </t> + + <!-- @param {Object[]|undefined} list of customer email data of a given message. A customer email data is a list with the following format: [partnerID, partnerName, emailStatus] @@ -550,4 +600,16 @@ </t> </div> </t> + + <!-- + @param {mail.model.Thread} thread with typing feature + --> + <t t-name="mail.ThreadTypingIcon"> + <span class="o_mail_thread_typing_icon" t-att-title="thread.getTypingMembersToText()"> + <span class="o_mail_thread_typing_icon_dot"/> + <span class="o_mail_thread_typing_icon_dot"/> + <span class="o_mail_thread_typing_icon_dot"/> + </span> + </t> + </templates> |
