Files
odoo_source/addons/website_livechat/views/website_livechat.xml
T
Alexandre Kühn 5f1d32f3fb [IMP] mail, im_livechat: 'is typing...' indicator on mail channels
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
2018-08-13 14:17:40 +02:00

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) &gt; 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>