[IMP]mail chatter: uploader

bzr revid: chm@openerp.com-20121008142654-pll3vfvjufo1gsr9
This commit is contained in:
Christophe Matthieu 2012-10-08 16:26:54 +02:00
parent af7e536f24
commit 4557bf1d50
5 changed files with 144 additions and 117 deletions

View File

@ -623,7 +623,7 @@ class mail_thread(osv.AbstractModel):
:param str subject: optional subject
:param str type: mail_message.type
:param int parent_id: optional ID of parent message in this thread
:param tuple(str,str) attachments: list of attachment tuples in the form
:param tuple(str,str) attachments or list id: list of attachment tuples in the form
``(name,content)``, where content is NOT base64 encoded
:return: ID of newly created mail.message
"""
@ -634,7 +634,7 @@ class mail_thread(osv.AbstractModel):
if isinstance(thread_id, (list, tuple)):
thread_id = thread_id and thread_id[0]
attachment_ids = []
attachment_ids=[]
for name, content in attachments:
if isinstance(content, unicode):
content = content.encode('utf-8')
@ -701,8 +701,21 @@ class mail_thread(osv.AbstractModel):
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
thread_id = user.partner_id.id
if attachments and attachments[0]==None:
attachments=[]
added_message_id = self.message_post(cr, uid, thread_id=thread_id, body=body, subject=subject, type=type,
subtype=subtype, parent_id=parent_id, attachments=attachments, context=context)
subtype=subtype, parent_id=parent_id, attachments=[], context=context)
attachment_ids=[]
if attachments:
ir_attachment = self.pool.get('ir.attachment')
attachment_ids = ir_attachment.search(cr, 1, [('res_model', '=', ""), ('res_id', '=', ""), ('user_id', '=', uid), ('id', 'in', attachments)], context=context)
if attachment_ids:
self.pool.get('ir.attachment').write(cr, 1, attachment_ids, { 'res_model': self._name, 'res_id': thread_id }, context=context)
self.pool.get('mail.message').write(cr, 1, [added_message_id], {'attachment_ids': attachment_ids} )
added_message = self.pool.get('mail.message').message_read(cr, uid, [added_message_id])
return added_message

View File

@ -195,6 +195,10 @@
margin-left: 66px;
}
.openerp li.oe_mail_thread_msg {
width: 560px;
}
.openerp div.oe_thread_placeholder li.oe_mail_thread_msg:last-child {
margin-bottom: 8px;
}
@ -212,13 +216,18 @@
.openerp li.oe_mail_thread_msg.oe_mail_read,
.openerp li.oe_mail_thread_msg.oe_mail_read div {
background-color: #F0F0F0;
border-left: #F0F0F0;
}
.openerp li.oe_mail_thread_msg.oe_mail_read li.oe_mail_thread_msg.oe_mail_unread,
.openerp li.oe_mail_thread_msg.oe_mail_read li.oe_mail_thread_msg.oe_mail_unread div {
background-color: #F6F6F6;
}
.openerp li.oe_mail_thread_msg.oe_mail_unread>div>ul>li.oe_unread,
.openerp li.oe_mail_thread_msg.oe_mail_read>div>ul>li.oe_read {
display: none;
}
.openerp li.oe_mail_thread_msg > div:after {
content: "";
display: block;
@ -236,7 +245,6 @@
.openerp .oe_mail_msg_email {
padding: 8px;
background: white;
border-top: 1px solid #ebebeb;
}
.openerp .oe_mail_msg_notification:after,
@ -248,7 +256,7 @@
}
.openerp div.oe_mail_msg_content {
float: right;
float: left;
position: relative;
width: 486px;
}
@ -333,33 +341,26 @@
/* Dropdown menu */
.openerp .oe_mail .oe_semantic_html_override {
.openerp .oe_mail ul.oe_mail_thread_display ul.oe_mail_thread_display {
position: relative;
border-left: 1px #DDD dashed;
}
.openerp .oe_mail ul.oe_header {
position: absolute;
right: 3px;
top: -6px;
display: none;
z-index: 10;
height: 18px;
}
.openerp .oe_mail ul.oe_header a {
text-decoration: none;
}
.openerp .oe_mail .oe_semantic_html_override:hover > ul.oe_header {
display: block;
}
.openerp .oe_mail ul.oe_header>li {
display: inline-block;
}
.openerp .oe_mail_msg_content .oe_dropdown_arrow:after {
border-top: 4px solid #404040;
height: 20px;
text-align: right;
}
/* Message footer */

View File

@ -29,6 +29,8 @@
.openerp .oe_mail .oe_mail_compose_textarea button.oe_full {
float: right;
position: relative;
right: -10px;
}
/* ------------------------------------------------------------ */

View File

@ -18,12 +18,8 @@ openerp.mail = function(session) {
session.web.FormView = session.web.FormView.extend({
do_action: function(action, on_close) {
if (action.res_model == 'mail.compose.message' &&
action.context && action.context.redirect == true &&
this.fields && this.fields.message_ids && this.fields.message_ids.view.get("actual_mode") != 'create') {
var thread = this.fields.message_ids.thread;
thread.refresh(action.context);
if (action.res_model == 'mail.compose.message') {
$(".openerp_webclient_container .oe_view_manager_current .oe_mail .oe_mail_wall_button_fletch").click();
return false;
}
else {
@ -105,27 +101,31 @@ openerp.mail = function(session) {
this.id = options.parameters.id;
this.model = options.parameters.model;
this.res_id = options.parameters.res_id;
this.is_private = options.parameters.is_private;
this.partner_ids = options.parameters.partner_ids;
this.attachment_ids = [];
this.show_attachment_delete = true;
this.show_attachment_link = false;
this.show_attachment_link = true;
this.parent_thread= parent.messages!= undefined ? parent : false;
this.fileupload_id = _.uniqueId('oe_fileupload_temp');
$(window).on(self.fileupload_id, self.on_attachment_loaded);
},
start: function(){
var self = this;
this.display_attachments();
this.bind_events();
self.bind_events();
//load avatar img
var user_avatar = mail.ChatterUtils.get_image(this.session, 'res.users', 'image_small', this.session.uid);
this.$('img.oe_mail_icon').attr('src', user_avatar);
},
/* upload the file on the server, add in the attachments list and reload display
*/
display_attachments: function(){
var self = this;
var render = $(session.web.qweb.render('mail.thread.message.attachments', {'widget': self}));
@ -139,47 +139,70 @@ openerp.mail = function(session) {
// event: delete an attachment
this.$el.on('click', '.oe_mail_attachment_delete', self.on_attachment_delete);
},
on_attachment_change: function (event) {
event.stopPropagation();
var self = this;
var $target = $(event.target);
if ($target.val() !== '') {
for(var i in this.attachment_ids){
if(this.attachment_ids[i].url == $target.val()){
var ds_attachment = new session.web.DataSetSearch(this, 'ir.attachment');
ds_attachment.unlink(this.attachment_ids.id);
}
}
// submit file
session.web.blockUI();
var form = self.$('form.oe_form_binary_form');
form.submit();
}
},
on_attachment_loaded: function (event, result) {
session.web.unblockUI();
this.attachment_ids.push({
'id': result.id,
'name': '',
'filename': result.filename,
'url': mail.ChatterUtils.get_attachment_url(this.session, result)
});
this.$('input.oe_form_binary_file').empty();
this.display_attachments();
},
/* unlink the file on the server and reload display
*/
on_attachment_delete: function (event) {
event.stopPropagation();
var attachment_id=$(event.target).data("id");
if (attachment_id) {
var attachments=[];
for(var i in this.attachment_ids){
if(attachment_id!=this.attachment_ids[i].id)
attachments.push(this.attachment_ids[i]);
}
this.attachment_ids = attachments;
this.display_attachments();
var ds_attachment = new session.web.DataSetSearch(this, 'ir.attachment');
ds_attachment.unlink(attachment_id);
}
},
bind_events: function() {
var self = this;
// event: add a new attachment
$(window).on(this.fileupload_id, function() {
var args = [].slice.call(arguments).slice(1);
var attachment = args[0];
attachment['url'] = mail.ChatterUtils.get_attachment_url(self.session, attachment);
self.attachment_ids.push(attachment);
self.display_attachments();
session.web.unblockUI();
});
// set the function called when attachments are added
this.$el.on('change', 'input.oe_insert_file', self.on_attachment_change );
this.$el.on('change', 'input.oe_form_binary_file', self.on_attachment_change );
this.$el.on('click', 'a.oe_cancel', self.on_cancel );
this.$el.on('click', 'button.oe_post', function(){self.on_message_post()} );
this.$el.on('click', 'button.oe_full', function(){self.on_compose_fullmail()} );
},
on_attachment_change: function (event) {
event.stopPropagation();
var $target = $(event.target);
if ($target.val() !== '') {
//session.web.blockUI();
var id = _.uniqueId('oe_fileupload');
this.attachment_ids.push({
'url': $target.val(),
'filename' : $target.val().replace(/.*[\/\\]/,''),
'id': id
});
$newfield = $target.clone();
$newfield.insertAfter($target);
$target.hide();
$target.attr("data-id",id);
this.display_attachments();
}
},
on_compose_fullmail: function(){
var attachments=[];
for(var i in this.attachment_ids){
attachments.push(this.attachment_ids[i].id);
}
var action = {
type: 'ir.actions.act_window',
res_model: 'mail.compose.message',
@ -194,7 +217,7 @@ openerp.mail = function(session) {
'default_is_private': true,
'default_parent_id': this.id,
'default_body': (this.$('textarea').val() || '').replace(/[\n\r]/g,'<br>'),
'default_attachment_ids': this.attachment_ids
'default_attachment_ids': attachments
},
};
this.do_action(action);
@ -209,40 +232,23 @@ openerp.mail = function(session) {
this.$el.hide();
},
on_attachment_delete: function (event) {
event.stopPropagation();
var id=$(event.target).data("id");
if (id) {
var attachments=[];
for(var i in this.attachment_ids){
if(id!=this.attachment_ids[i].id)
attachments.push(this.attachment_ids[i]);
}
this.attachment_ids = attachments;
this.$("input[data-id='"+id+"'").remove();
/*
var attachment_id = parseInt(event.target.dataset.id);
var idx = _.pluck(this.attachment_ids, 'id').indexOf(attachment_id);
if (idx == -1) return false;
new session.web.DataSetSearch(this, 'ir.attachment').unlink(attachment_id);
this.attachment_ids.splice(idx, 1);
*/
this.display_attachments();
}
},
/*post a message and fletch the message*/
on_message_post: function (body) {
var self = this;
if (! body) {
var comment_node = this.$('textarea');
var body = comment_node.val();
comment_node.val('');
}
if(body.match(/\S+/)) {
var attachments=[];
for(var i in this.attachment_ids){
attachments.push(this.attachment_ids[i].id);
}
this.parent_thread.ds_thread.call('message_post_api', [
[this.context.default_res_id], body, false, 'comment', false, this.context.default_parent_id, undefined])
[this.context.default_res_id], body, false, 'comment', false, this.context.default_parent_id, attachments])
.then(this.parent_thread.proxy('switch_new_message'));
this.on_cancel();
}
@ -537,7 +543,14 @@ openerp.mail = function(session) {
if($(event.srcElement).hasClass("oe_read")) this.animated_destroy({fadeTime:250});
// if this message is read, all childs message display is read
var ids = [this.id].concat( this.get_child_ids() );
this.ds_notification.call('set_message_read', [ids,$(event.srcElement).hasClass("oe_read")]);
if($(event.srcElement).hasClass("oe_read")) {
this.ds_notification.call('set_message_read', [ids,true]);
this.$el.removeClass("oe_mail_unread").addClass("oe_mail_read");
} else {
this.ds_notification.call('set_message_read', [ids,false]);
this.$el.removeClass("oe_mail_read").addClass("oe_mail_unread");
}
return false;
},
@ -727,24 +740,24 @@ openerp.mail = function(session) {
this.ComposeMessage.appendTo(this.$(".oe_mail_thread_action:first"));
},
/**
* Override-hack of do_action: automatically load message on the chatter.
* Normally it should be called only when clicking on 'Post/Send'
* in the composition form. */
do_action: function(action, on_close) {
this.message_fletch(false, false, false, [action.id]);
return this._super(action, on_close);
},
/* this method is runing for first parent thread
*/
on_first_thread: function(){
var self=this;
// fetch and display message, using message_ids if set
display_done = this.message_fletch(true);
this.message_fletch(true);
$(document).scroll( self.on_scroll );
window.setTimeout( self.on_scroll, 500 );
$(session.web.qweb.render('mail.wall_no_message', {})).appendTo(this.$('ul.oe_mail_thread_display'));
var button_flesh = $('<button style="display:none;" class="oe_mail_wall_button_fletch"/>').click(function(event){
if(event)event.stopPropagation();
self.message_fletch(true);
});
this.$el.prepend(button_flesh);
},
/* When the expandable object is visible on screen (with scrolling)
@ -841,12 +854,6 @@ openerp.mail = function(session) {
return false;
},
refresh: function (action_context) {
var self=this;
_(this.messages).each(function(){ self.destroy(); });
self.message_fletch();
},
/** Fetch messages
* @param {Bool} initial_mode: initial mode: try to use message_data or
* message_ids, if nothing available perform a message_read; otherwise
@ -892,6 +899,8 @@ openerp.mail = function(session) {
insert_message: function (message) {
var self=this;
this.$("li.oe_wall_no_message").remove();
if(message.type=='expandable'){
var message = new mail.ThreadExpandable(self, {
'domain': message.domain,
@ -1129,12 +1138,7 @@ openerp.mail = function(session) {
'parameters': {},
}
);
this.$('ul.oe_mail_wall_threads').empty();
var render_res = session.web.qweb.render('mail.wall_thread_container', {});
$(render_res).appendTo(this.$('ul.oe_mail_wall_threads'));
return this.thread.appendTo( this.$('li.oe_mail_wall_thread:last') );
return this.thread.appendTo( this.$('.oe_mail_wall_threads:first') );
},

View File

@ -37,8 +37,15 @@
<t t-name="mail.compose_message.add_attachment">
<div class="oe_attachment_file">
<div class="oe_add">
<input type="file" class="oe_insert_file"/>
<!-- uploader of file -->
<button><span class="oe_e">p</span></button>
<t t-call="HiddenInputFile">
<t t-set="fileupload_id" t-value="widget.fileupload_id"/>
<t t-set="fileupload_action">/web/binary/upload_attachment</t>
<input type="hidden" name="model" value=""/>
<input type="hidden" name="id" value="0"/>
<input type="hidden" name="session_id" t-att-value="widget.session.session_id"/>
</t>
</div>
</div>
</t>
@ -92,7 +99,8 @@
wall main template
Template used to display the communication history in the wall.
-->
<div t-name="mail.wall" class="oe_view_manager oe_mail_wall oe_view_manager_current">
<div t-name="mail.wall" class="oe_view_manager oe_mail_wall oe_view_manag
er_current">
<table class="oe_view_manager_header">
<colgroup>
<col width="33%"/>
@ -124,19 +132,18 @@
</tr>
</tbody>
</table>
<ul class="oe_mail_wall_threads">
<!-- contains threads -->
</ul>
<!-- placeholder for the wall threads -->
<div class="oe_mail_wall_threads"/>
<div class="oe_mail_wall_aside">
<!-- contains currently nothing -->
</div>
</div>
<!--
wall_thread_container template for the wall
Each discussion thread is contained inside this template
display message on the wall when there are no message
-->
<li t-name="mail.wall_thread_container" class="oe_mail_wall_thread">
<li t-name="mail.wall_no_message" class="oe_wall_no_message">
You have no messages
</li>
<!--
@ -172,8 +179,8 @@
<!-- message actions (read/unread, reply, delete...) -->
<ul class="oe_header">
<li class="placeholder-mail-vote"><t t-call="mail.thread.message.vote"/></li>
<li t-if="!widget.options.thread.display_on_flat and widget.unread" title="Read"><a class="oe_read oe_e">W</a></li>
<li t-if="!widget.options.thread.display_on_flat and !widget.unread" title="Set back to unread"><a class="oe_unread oe_e">h</a></li>
<li t-if="!widget.options.thread.display_on_flat" title="Read" class="oe_read"><a class="oe_read oe_e">W</a></li>
<li t-if="!widget.options.thread.display_on_flat" title="Set back to unread" class="oe_unread"><a class="oe_unread oe_e">h</a></li>
<li title="Quick reply"><a class="oe_reply oe_e">)</a></li>
<t t-if="(widget.options.message.show_reply || widget.options.message.show_reply_by_email || (widget.is_author and widget.options.message.show_dd_delete) || widget.type == 'email')">
<li>