With this commit, most threads show an indicator when a member is typing
something. e.g.
"Mitchell Stephens is typing..."
Supported threads:
- DM
- (public & private) channels
- Livechat (Website & Backend)
Unsupported threads:
- mailboxes (e.g. 'Inbox')
- document thread (= 'Chatter')
- support channel (with `im_support` module)
Some technical details:
- This is a mix between 'start'/'stop' and 'regular notify' strategies.
- On typing text in composer: notify 'start typing' to all members of
thread.
- On clearing text in composer: notify 'stop typing' to all members of
thread.
- A member can only notify once every 2.5 seconds to the server when he
starts or stops typing something (throttled, buffered notify call).
- On receiving a message from someone that is typing: determine that he is
no longer typing.
- On non-empty and unchanged composer text for 5.0 seconds: automatically
notifies all members of thread that he is no longer typing anything.
(This is like a 'soft / cooperative sender' timeout).
- On non-receiving a typing notification of someone after 60 seconds:
determine that he is not longer typing something (This is like a
'hard / receiver assumption' timeout).
- When some types for more than 50 seconds straight: notify that he is
still typing something (again and again every 50 seconds).
- When two or more people are typing something (Multi-User channels), it
displays at most 2 typing users (ordering rule: longer typers first):
"Mitchell Stephens, Marc Brown and more are typing..."
- Timing summary:
- Usually 2.5 seconds uncertainty.
- Up to 5.0 seconds uncertainty on typer inactivity.
- Up to 60 seconds uncertainty on typer page reload / browser tab
closed / etc.
Future Improvements:
- Detect page reload or browser tab close with loose of longpolling
connection
Task-ID 28188
192 lines
12 KiB
XML
192 lines
12 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
<data>
|
|
|
|
<!--
|
|
Integrate Livechat in Common Frontend for Website
|
|
Template registering all the assets required to execute the Livechat from a page containing Odoo
|
|
-->
|
|
<template id="assets_frontend" name="im_livechat assets frontend" inherit_id="website.assets_frontend">
|
|
<xpath expr="." position="inside">
|
|
<!-- thread window -->
|
|
<script type="text/javascript" src="/mail/static/src/js/thread_windows/abstract_thread_window.js"></script>
|
|
<script type="text/javascript" src="/im_livechat/static/src/js/website_livechat_window.js"></script>
|
|
|
|
<script type="text/javascript" src="/bus/static/src/js/longpolling_bus.js"></script>
|
|
<script type="text/javascript" src="/bus/static/src/js/crosstab_bus.js"></script>
|
|
<script type="text/javascript" src="/bus/static/src/js/services/bus_service.js"></script>
|
|
|
|
<script type="text/javascript" src="/mail/static/src/js/document_viewer.js"></script>
|
|
<script type="text/javascript" src="/mail/static/src/js/thread_widget.js"></script>
|
|
<script type="text/javascript" src="/mail/static/src/js/utils.js"></script>
|
|
<script type="text/javascript" src="/im_livechat/static/src/js/im_livechat.js"></script>
|
|
<!-- Models -->
|
|
<!-- threads -->
|
|
<script type="text/javascript" src="/mail/static/src/js/models/threads/abstract_thread.js"></script>
|
|
<script type="text/javascript" src="/im_livechat/static/src/js/models/website_livechat.js"></script>
|
|
<!-- thread typing mixin -->
|
|
<script type="text/javascript" src="/mail/static/src/js/models/threads/thread_typing_mixin/thread_typing_mixin.js"></script>
|
|
<script type="text/javascript" src="/mail/static/src/js/models/threads/thread_typing_mixin/timer.js"></script>
|
|
<script type="text/javascript" src="/mail/static/src/js/models/threads/thread_typing_mixin/timers.js"></script>
|
|
<script type="text/javascript" src="/mail/static/src/js/models/threads/thread_typing_mixin/cc_throttle_function.js"></script>
|
|
<!-- messages -->
|
|
<script type="text/javascript" src="/mail/static/src/js/models/messages/abstract_message.js"></script>
|
|
<script type="text/javascript" src="/im_livechat/static/src/js/models/website_livechat_message.js"></script>
|
|
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/abstract_thread_window.scss"></link>
|
|
<link rel="stylesheet" type="text/scss" href="/mail/static/src/scss/thread.scss"></link>
|
|
<link rel="stylesheet" type="text/scss" href="/im_livechat/static/src/scss/im_livechat.scss"/>
|
|
</xpath>
|
|
</template>
|
|
<template id="loader" inherit_id="website.layout" name="Livechat : include loader on Website">
|
|
<xpath expr="//div[@id='wrapwrap']" position="after">
|
|
<t t-if="website and website.channel_id">
|
|
<script>
|
|
<t t-call="im_livechat.loader">
|
|
<t t-set="channel" t-value="website.channel_id.id"/>
|
|
</t>
|
|
</script>
|
|
</t>
|
|
</xpath>
|
|
</template>
|
|
|
|
<!-- Page Layout -->
|
|
<template id="channel_page" name="Livechat Channel Satisfaction Page">
|
|
<t t-call="website.layout">
|
|
<div id="wrap">
|
|
<div class="container">
|
|
<!-- published button -->
|
|
<t t-call="website.publish_management">
|
|
<t t-set="object" t-value="channel"/>
|
|
<t t-set="publish_edit" t-value="True"/>
|
|
</t>
|
|
|
|
<h1><span>Livechat Channel</span> <small t-field="channel.name" /></h1>
|
|
<div t-field="channel.website_description" class="oe_structure mt16" />
|
|
<div class="row mt32">
|
|
<div class="col-lg-8">
|
|
<t t-if="len(ratings) > 0">
|
|
<div class="row">
|
|
<h3>Statistics</h3>
|
|
<div class="row">
|
|
<div class="col-lg-3">
|
|
<div class="card bg-warning text-white">
|
|
<div class="card-body text-center">
|
|
<img src="/rating/static/src/img/rating_5.png" style="height:50px" alt="Neutral face"/>
|
|
</div>
|
|
<div class="card-body text-center">
|
|
<h2 style="margin: 0">
|
|
<b style="font-size: 50px">
|
|
<t t-esc="percentage['okay']" />
|
|
</b>
|
|
<small>%</small>
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-4">
|
|
<div class="card bg-success text-white">
|
|
<div class="card-body text-center">
|
|
<img src="/rating/static/src/img/rating_10.png" style="height:60px" alt="Happy face"/>
|
|
</div>
|
|
<div class="card-body text-center">
|
|
<h2 style="margin: 0">
|
|
<b style="font-size: 60px">
|
|
<t t-esc="percentage['great']" />
|
|
</b>
|
|
<small>%</small>
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-3">
|
|
<div class="card bg-danger text-white">
|
|
<div class="card-body text-center">
|
|
<img src="/rating/static/src/img/rating_1.png" style="height:40px" alt="Sad face"/>
|
|
</div>
|
|
<div class="card-body text-center">
|
|
<h2 style="margin: 0">
|
|
<b style="font-size: 40px">
|
|
<t t-esc="percentage['bad']" />
|
|
</b>
|
|
<small>%</small>
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-lg-12 mb32">
|
|
<h3>The <t t-esc="len(ratings)"/> last feedbacks</h3>
|
|
<div style="text-align:center">
|
|
<t t-foreach="ratings" t-as="rating">
|
|
<img t-attf-src='/rating/static/src/img/rating_#{int(rating.rating)}.png' t-att-alt="rating.res_name"/>
|
|
<t t-if="(rating_index+1) % 10 == 0">
|
|
<br/>
|
|
</t>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
<t t-if="len(ratings) == 0">
|
|
<h4 style="text-align:center">This is no rating for this channel for now.</h4>
|
|
</t>
|
|
</div>
|
|
<div class="col-lg-4 mb32">
|
|
<h3>The Team</h3>
|
|
<t t-foreach="team" t-as="user">
|
|
<div class="media mt-3">
|
|
<t t-if="user.image_small">
|
|
<img t-att-src="user.image_small and ('data:image/png;base64,' + to_text(user.image_small)) or '/web/static/src/img/placeholder.png'"
|
|
class="rounded" t-att-alt="user.name"/>
|
|
</t>
|
|
<div class="media-body">
|
|
<h5><t t-esc="user.name"/></h5>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</template>
|
|
|
|
|
|
<template id="channel_list_page" name="Livechat Channel List Page">
|
|
<t t-call="website.layout">
|
|
<div id="wrap">
|
|
<div class="oe_structure"/>
|
|
<div class="container">
|
|
<h1>Livechat Support Channels</h1>
|
|
<div class="row mt32 mb32">
|
|
<t t-if="not len(channels)">
|
|
<div class="col-lg-6 offset-lg-3">
|
|
There is no public livechat channel to show.
|
|
</div>
|
|
</t>
|
|
<t t-if="len(channels)">
|
|
<div class="col-lg-6 offset-lg-3">
|
|
<t t-foreach="channels" t-as="channel">
|
|
<div t-attf-class="media#{' mt-3' if channel_index else ''}">
|
|
<a t-attf-href="/livechat/channel/#{ slug(channel)}">
|
|
<img t-att-src="channel.image_small and ('data:image/png;base64,' + to_text(channel.image_small)) or '/web/static/src/img/placeholder.png'" t-att-alt="channel.name" />
|
|
</a>
|
|
<div class="media-body">
|
|
<h4><t t-esc="channel.name"/></h4>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
<div class="oe_structure"/>
|
|
</div>
|
|
</t>
|
|
</template>
|
|
|
|
</data>
|
|
</odoo>
|