[IMP]mail thread: load only not loaded message
bzr revid: chm@openerp.com-20120928132723-xg2y8j3ebu9a9huv
This commit is contained in:
parent
96dee3a6b0
commit
20f6a39089
|
@ -83,14 +83,14 @@ class mail_notification(osv.Model):
|
|||
return super(mail_notification, self).create(cr, uid, vals, context=context)
|
||||
return False
|
||||
|
||||
def set_message_read(self, cr, uid, msg_ids, context=None):
|
||||
def set_message_read(self, cr, uid, msg_ids, read=None, context=None):
|
||||
if msg_ids == None:
|
||||
return False
|
||||
if type(msg_ids) is not list:
|
||||
msg_ids=[msg_ids]
|
||||
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
|
||||
notif_ids = self.search(cr, uid, [('partner_id', '=', partner_id), ('message_id', 'in', msg_ids)], context=context)
|
||||
return self.write(cr, uid, notif_ids, {'read': True}, context=context)
|
||||
return self.write(cr, uid, notif_ids, {'read': read}, context=context)
|
||||
|
||||
def get_partners_to_notify(self, cr, uid, partner_ids, message, context=None):
|
||||
""" Return the list of partners to notify, based on their preferences.
|
||||
|
|
|
@ -201,7 +201,7 @@ class mail_message(osv.Model):
|
|||
partner_ids = self.pool.get('res.partner').name_get(cr, uid, [x.id for x in msg.partner_ids], context=context)
|
||||
except (orm.except_orm, osv.except_osv):
|
||||
partner_ids = []
|
||||
|
||||
|
||||
return {
|
||||
'id': msg.id,
|
||||
'type': msg.type,
|
||||
|
@ -302,6 +302,12 @@ class mail_message(osv.Model):
|
|||
further parents
|
||||
:return list: list of trees of messages
|
||||
"""
|
||||
|
||||
# don't read the message display by .js, in context message_loaded list
|
||||
if context and context.get('message_loaded'):
|
||||
domain += [['id','not in',context.get('message_loaded')]];
|
||||
|
||||
|
||||
limit = limit or self._message_read_limit
|
||||
context = context or {}
|
||||
if not ids:
|
||||
|
@ -325,13 +331,14 @@ class mail_message(osv.Model):
|
|||
record_parent['child_ids'].append(record)
|
||||
record = record_parent
|
||||
msg = msg.parent_id
|
||||
if msg.id not in tree:
|
||||
# if not in record and not in message_loded list
|
||||
if msg.id not in tree and not(context and context.get('message_loaded') and msg.id in context.get('message_loaded')) :
|
||||
result.append(record)
|
||||
tree[msg.id] = record
|
||||
|
||||
# Flatten the result
|
||||
result = self.message_read_tree_flatten(cr, uid, None, result, domain, level, context=context, limit=limit, add_expandable=add_expandable)
|
||||
return result
|
||||
result2 = self.message_read_tree_flatten(cr, uid, None, result, domain, level, context=context, limit=limit, add_expandable=add_expandable)
|
||||
return result2
|
||||
|
||||
#------------------------------------------------------
|
||||
# Email api
|
||||
|
@ -483,11 +490,18 @@ class mail_message(osv.Model):
|
|||
fol_objs = fol_obj.browse(cr, uid, fol_ids, context=context)
|
||||
extra_notified = set(fol.partner_id.id for fol in fol_objs)
|
||||
missing_notified = extra_notified - partners_to_notify
|
||||
missing_notified = missing_notified
|
||||
if missing_notified:
|
||||
self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(4, p_id) for p_id in missing_notified]}, context=context)
|
||||
partners_to_notify |= extra_notified
|
||||
# # remove uid from partners
|
||||
self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(3, uid)]}, context=context)
|
||||
|
||||
if message.model=="res.partner" and message.res_id==message.author_id.id:
|
||||
# add myself author if I wrote on my wall
|
||||
self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(4, message.author_id.id)]}, context=context)
|
||||
else:
|
||||
# unless remove myself author
|
||||
self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(3, message.author_id.id)]}, context=context)
|
||||
|
||||
self.pool.get('mail.notification').notify(cr, uid, list(partners_to_notify), newid, context=context)
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
|
|
|
@ -94,14 +94,14 @@
|
|||
<record id="action_mail_inbox_feeds" model="ir.actions.client">
|
||||
<field name="name">Inbox</field>
|
||||
<field name="tag">mail.wall</field>
|
||||
<field name="params" eval=""{'domain': ['&','|','&','&',('notification_ids.partner_id.user_ids', 'in', [uid]),('unread', '=', True),('author_id.user_ids', 'in', [uid]),('type', '=', 'comment'),('unread', '=', True)],
|
||||
<field name="params" eval=""{'domain': [('notification_ids.partner_id.user_ids', 'in', [uid]),('unread', '=', True)],
|
||||
'context': {'default_model': 'res.users', 'default_res_id': uid} }""/>
|
||||
</record>
|
||||
|
||||
<record id="action_mail_archives_feeds" model="ir.actions.client">
|
||||
<field name="name">Archives</field>
|
||||
<field name="tag">mail.wall</field>
|
||||
<field name="params" eval=""{'domain': [('author_id.user_ids', 'in', [uid]),('unread', '=', False)],
|
||||
<field name="params" eval=""{'domain': [('notification_ids.partner_id.user_ids', 'in', [uid]),('unread', '=', False)],
|
||||
'context': {'default_model': 'res.users', 'default_res_id': uid} }""/>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -615,6 +615,7 @@ class mail_thread(osv.AbstractModel):
|
|||
""" Post a new message in an existing thread, returning the new
|
||||
mail.message ID. Extra keyword arguments will be used as default
|
||||
column values for the new mail.message record.
|
||||
Auto link messages for same id and object
|
||||
:param int thread_id: thread ID to post into, or list with one ID
|
||||
:param str body: body of the message, usually raw HTML that will
|
||||
be sanitized
|
||||
|
@ -655,11 +656,12 @@ class mail_thread(osv.AbstractModel):
|
|||
else:
|
||||
subtype_id = False
|
||||
|
||||
model = context.get('thread_model', self._name) if thread_id else False
|
||||
messages = self.pool.get('mail.message')
|
||||
|
||||
|
||||
#auto link messages for same id and object
|
||||
messages = self.pool.get('mail.message')
|
||||
model = context.get('thread_model', self._name) if thread_id else False
|
||||
if model != 'res.partner':
|
||||
if model != 'res.partner' and thread_id:
|
||||
message_ids = messages.search(cr, uid, ['&',('res_id', '=', thread_id),('model','=',model)], context=context)
|
||||
if len(message_ids):
|
||||
parent_id = min(message_ids)
|
||||
|
|
|
@ -294,7 +294,6 @@ openerp.mail = function(session) {
|
|||
expandable_max: options.expandable_max || 5,
|
||||
not_expendable: options.not_expendable || false,
|
||||
}
|
||||
|
||||
// datasets and internal vars
|
||||
this.id= options.id || false;
|
||||
this.top_parent= (options.top_parent && options.top_parent.browse_thread) ? options.top_parent : (parent.browse_thread ? parent : this);
|
||||
|
@ -337,28 +336,35 @@ openerp.mail = function(session) {
|
|||
this.$('*').unbind('click');
|
||||
// event: click on 'More' at bottom of thread
|
||||
this.$el.on('click', 'a.oe_mail_fetch_more', this.do_message_fetch_more);
|
||||
// event: writing in basic textarea of composition form (quick reply)
|
||||
this.$('textarea.oe_mail_compose_textarea').keyup(function (event) {
|
||||
var charCode = (event.which) ? event.which : window.event.keyCode;
|
||||
if (event.shiftKey && charCode == 13) { this.value = this.value+"\n"; }
|
||||
else if (charCode == 13) { return self.message_post(); }
|
||||
});
|
||||
// event: click on 'Reply' in msg
|
||||
this.$el.on('click', 'a.oe_mail_msg_reply', function (event) {
|
||||
this.$el.on('click', 'a.oe_reply', function (event) {
|
||||
var act_dom = $(this).parents('li.oe_mail_thread_msg').eq(0).find('div.oe_mail_thread_action:first');
|
||||
act_dom.toggle();
|
||||
});
|
||||
// event: writing in basic textarea of composition form (quick reply)
|
||||
// event: onblur for hide 'Reply'
|
||||
this.$('textarea.oe_mail_compose_textarea:first')
|
||||
.keyup(function (event) {
|
||||
var charCode = (event.which) ? event.which : window.event.keyCode;
|
||||
if (event.shiftKey && charCode == 13) { this.value = this.value+"\n"; }
|
||||
else if (charCode == 13) { return self.message_post(); }
|
||||
})
|
||||
.blur(function (event) {
|
||||
$(this).parents('.oe_mail_thread_action:first').toggle();
|
||||
});
|
||||
// event: click on 'Attachment(s)' in msg
|
||||
this.$el.on('click', 'a.oe_mail_msg_view_attachments', function (event) {
|
||||
var act_dom = $(this).parent().parent().parent().find('.oe_mail_msg_attachments');
|
||||
act_dom.toggle();
|
||||
});
|
||||
// event: click on icone 'Read' in header
|
||||
this.$el.on('click', 'a.oe_read', this.on_message_read);
|
||||
this.$el.on('click', 'a.oe_read', this.on_message_read_unread);
|
||||
// event: click on icone 'UnRead' in header
|
||||
this.$el.on('click', 'a.oe_unread', this.on_message_read_unread);
|
||||
// event: click on 'Delete' in msg side menu
|
||||
this.$el.on('click', 'a.oe_mail_msg_delete', this.on_message_delete);
|
||||
// event: click on 'Reply by email' in msg side menu
|
||||
this.$el.on('click', 'a.oe_mail_msg_reply_by_email', function (event) {
|
||||
this.$el.on('click', 'a.oe_reply_by_email', function (event) {
|
||||
if (! self.compose_message_widget) return true;
|
||||
var msg_id = event.srcElement.dataset.msg_id;
|
||||
if (! msg_id) return false;
|
||||
|
@ -373,17 +379,7 @@ openerp.mail = function(session) {
|
|||
|
||||
on_message_delete: function (event) {
|
||||
if (! confirm(_t("Do you really want to delete this message?"))) { return false; }
|
||||
var msg_id = event.srcElement.dataset.id;
|
||||
if (! msg_id) return false;
|
||||
$(event.srcElement).parents('li.oe_mail_thread_msg').eq(0).remove();
|
||||
return this.ds_message.unlink([parseInt(msg_id)]);
|
||||
},
|
||||
|
||||
/*The selected thread and all childs (messages/thread) became read
|
||||
* @param {object} mouse envent
|
||||
*/
|
||||
on_message_read: function (event) {
|
||||
//TDE: TODO
|
||||
var source = $(event.srcElement).parents('[data-msg_id]:first');
|
||||
var msg_id = source.data("msg_id");
|
||||
var msg_model = source.data("msg_model");
|
||||
|
@ -392,12 +388,29 @@ openerp.mail = function(session) {
|
|||
var thread=this.browse_thread({'id':msg_id, 'model':msg_model});
|
||||
if(thread){
|
||||
thread.animated_destroy({fadeTime:250});
|
||||
var ids = [thread.id]
|
||||
// delete this thread and his childs
|
||||
var ids = ids.concat( thread.get_child_thread_ids() );
|
||||
this.ds_message.unlink(ids);
|
||||
}
|
||||
},
|
||||
|
||||
/*The selected thread and all childs (messages/thread) became read
|
||||
* @param {object} mouse envent
|
||||
*/
|
||||
on_message_read_unread: function (event) {
|
||||
var source = $(event.srcElement).parents('[data-msg_id]:first');
|
||||
var msg_id = source.data("msg_id");
|
||||
var msg_model = source.data("msg_model");
|
||||
if (!msg_id || !msg_model) return false;
|
||||
|
||||
var thread=this.browse_thread({'id':msg_id, 'model':msg_model});
|
||||
if(thread){
|
||||
thread.animated_destroy({fadeTime:250});
|
||||
var ids = [thread.id]
|
||||
// if this thread is read, all childs thread display is read
|
||||
var ids = ids.concat( thread.get_child_thread_ids() );
|
||||
|
||||
thread.ds_notification.call('set_message_read', [ids]);
|
||||
thread.ds_notification.call('set_message_read', [ids,$(event.srcElement).hasClass("oe_read")]);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -428,7 +441,7 @@ openerp.mail = function(session) {
|
|||
return this.top_parent.browse_thread(options);
|
||||
}
|
||||
|
||||
if(this.id && this.model){
|
||||
if(options.id && options.model){
|
||||
if(this.id==options.id && this.model==options.model)
|
||||
return this;
|
||||
|
||||
|
@ -448,7 +461,7 @@ openerp.mail = function(session) {
|
|||
|
||||
animated_destroy: function(options) {
|
||||
var self=this;
|
||||
//graphic effects
|
||||
//graphic effects
|
||||
if(options.fadeTime)
|
||||
self.$el.parents(".oe_mail_thread_msg:first").fadeOut(options.fadeTime, function(){
|
||||
self.destroy();
|
||||
|
@ -490,6 +503,7 @@ openerp.mail = function(session) {
|
|||
/** Instantiate the composition form, with every parameters in context
|
||||
or in the widget context. */
|
||||
instantiate_composition_form: function(context) {
|
||||
var self=this;
|
||||
if (this.compose_message_widget) {
|
||||
this.compose_message_widget.destroy();
|
||||
}
|
||||
|
@ -498,7 +512,12 @@ openerp.mail = function(session) {
|
|||
});
|
||||
var composition_node = this.$('div.oe_mail_thread_action');
|
||||
composition_node.empty();
|
||||
var compose_done = this.compose_message_widget.appendTo(composition_node);
|
||||
var compose_done = this.compose_message_widget.appendTo(composition_node)
|
||||
.then(function(){
|
||||
self.$("button.oe_mail_compose_message_button_send").mouseup(function(){
|
||||
self.browse_thread({'top_thread':1}).message_fetch();
|
||||
});
|
||||
});
|
||||
return compose_done;
|
||||
},
|
||||
|
||||
|
@ -524,6 +543,12 @@ openerp.mail = function(session) {
|
|||
// domain and context: options + additional
|
||||
fetch_domain = _.flatten([this.domain, additional_domain || []], true);
|
||||
fetch_context = _.extend({}, this.context, additional_context || {});
|
||||
|
||||
fetch_context.message_loaded=[];
|
||||
self.$("li[data-msg_id][data-msg_model]").each(function(){
|
||||
fetch_context.message_loaded.push($(this).data("msg_id"))
|
||||
});
|
||||
|
||||
// initial mode: try to use message_data or message_ids
|
||||
if (initial_mode && this.options.message_data) {
|
||||
return this.message_display_create_thread(this.options.message_data);
|
||||
|
@ -548,6 +573,11 @@ openerp.mail = function(session) {
|
|||
$(rendered).appendTo(self.$el.children('ul.oe_mail_thread_display:first'));
|
||||
}
|
||||
else if(inc<=self.options.expandable_max) {
|
||||
|
||||
//if thread exists, don't create new thread
|
||||
if(self.browse_thread({'model': record.model,'id': record.id,}))
|
||||
return false;
|
||||
|
||||
/*create thread*/
|
||||
var thread = new mail.Thread(self, self.domain,
|
||||
{ 'default_model': record.model,
|
||||
|
@ -558,7 +588,7 @@ openerp.mail = function(session) {
|
|||
'message_data': record.child_ids,
|
||||
'thread_level': self.options.thread_level - 1,
|
||||
'show_header_compose': false,
|
||||
'show_reply': self.options.show_reply && self.options.thread_level > 1,
|
||||
'show_reply': self.options.show_reply,
|
||||
'show_reply_by_email': self.options.show_reply_by_email,
|
||||
'show_dd_hide': self.options.show_dd_hide,
|
||||
'show_dd_delete': self.options.show_dd_delete,
|
||||
|
@ -647,6 +677,8 @@ openerp.mail = function(session) {
|
|||
else
|
||||
$rendered.prependTo(this.$('> ul.oe_mail_thread_display:first'));
|
||||
|
||||
$rendered.hide().fadeIn(750);
|
||||
|
||||
|
||||
this.$('> div.oe_mail_msg_body').expander({
|
||||
slicePoint: this.options.truncate_limit,
|
||||
|
@ -882,7 +914,7 @@ openerp.mail = function(session) {
|
|||
{ 'thread_level': this.options.thread_level,
|
||||
'use_composer': true,
|
||||
'show_reply': this.options.thread_level > 0,
|
||||
'show_dd_hide': true
|
||||
'show_dd_hide': true,
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -112,9 +112,10 @@
|
|||
|
||||
<!-- message actions (read/unread, reply, delete...) -->
|
||||
<ul class="oe_header">
|
||||
<li t-if="options.thread_level>0"><a class="oe_read oe_e">W<!-- Read/Unread --></a></li>
|
||||
<li t-if="options.show_reply"><a class="oe_mail_msg_reply oe_e">)</a></li>
|
||||
<li t-if="options.show_reply_by_email"><a class="oe_mail_msg_reply_by_email oe_e">)</a></li>
|
||||
<li t-if="options.thread_level>0 and record.unread"><a class="oe_read oe_e">W</a></li>
|
||||
<li t-if="options.thread_level>0 and !record.unread"><a class="oe_unread oe_e">h</a></li>
|
||||
<li t-if="options.thread_level>0 and options.show_reply"><a class="oe_reply oe_e">)</a></li>
|
||||
<li t-if="options.show_reply_by_email"><a class="oe_reply_by_email oe_e">)</a></li>
|
||||
<li>
|
||||
<span class="oe_dropdown_toggle">
|
||||
<a class="oe_e">é</a>
|
||||
|
@ -124,7 +125,7 @@
|
|||
<li t-if="display['show_hide']">
|
||||
<a href="#" class="oe_mail_msg_hide_type" t-attf-data-subtype='{record.subtype}'>Hide '<t t-esc="record.subtype"/>' for this document</a>
|
||||
</li> -->
|
||||
<li t-if="options.show_dd_reply_by_email"><a class="oe_mail_msg_reply_by_email">Quote and reply</a></li>
|
||||
<li t-if="options.show_dd_reply_by_email"><a class="oe_reply_by_email">Quote and reply</a></li>
|
||||
<li t-if="record.type == 'email'"><a class="oe_mail_msg_details" t-attf-href="#model=mail.message&id=#{record.id}" >Details</a></li>
|
||||
</ul>
|
||||
</span>
|
||||
|
@ -173,6 +174,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- expandable message layout -->
|
||||
<li t-name="mail.thread.message.expandable" class="oe_mail oe_mail_thread_msg" t-attf-data-msg_model="{record.model}" t-attf-data-msg_id="{record.id}" data-msg_timestamp="-1">
|
||||
<div t-attf-class="oe_mail_msg_expandable oe_semantic_html_override">
|
||||
|
|
|
@ -217,10 +217,6 @@ class mail_compose_message(osv.TransientModel):
|
|||
def send_mail(self, cr, uid, ids, context=None):
|
||||
""" Process the wizard content and proceed with sending the related
|
||||
email(s), rendering any template patterns on the fly if needed. """
|
||||
|
||||
print ""
|
||||
print "send_mail", ids, context
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
active_ids = context.get('active_ids')
|
||||
|
@ -256,7 +252,10 @@ class mail_compose_message(osv.TransientModel):
|
|||
# post process: update attachments, because id is not necessarily known when adding attachments in Chatter
|
||||
self.pool.get('ir.attachment').write(cr, uid, [attach.id for attach in wizard.attachment_ids], {'res_id': wizard.id}, context=context)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
if context.get('mail_action_wizard_close'):
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
else:
|
||||
return False
|
||||
|
||||
def render_message(self, cr, uid, wizard, res_id, context=None):
|
||||
""" Generate an email from the template for given (wizard.model, res_id)
|
||||
|
|
Loading…
Reference in New Issue