diff --git a/frappe/core/doctype/comment/comment.py b/frappe/core/doctype/comment/comment.py index a2105c1511..d2e365d1e0 100644 --- a/frappe/core/doctype/comment/comment.py +++ b/frappe/core/doctype/comment/comment.py @@ -18,10 +18,7 @@ from frappe.exceptions import ImplicitCommitError class Comment(Document): def after_insert(self): self.notify_mentions() - - frappe.publish_realtime('new_communication', self.as_dict(), - doctype=self.reference_doctype, docname=self.reference_name, - after_commit=True) + self.notify_change('add') def validate(self): if not self.comment_email: @@ -33,9 +30,14 @@ class Comment(Document): def on_trash(self): self.remove_comment_from_cache() - frappe.publish_realtime('delete_communication', self.as_dict(), - doctype= self.reference_doctype, docname = self.reference_name, - after_commit=True) + self.notify_change('delete') + + def notify_change(self, action): + frappe.publish_realtime('update_docinfo_for_{}_{}'.format(self.reference_doctype, self.reference_name), { + 'doc': self.as_dict(), + 'key': 'comments', + 'action': action + }, after_commit=True) def remove_comment_from_cache(self): _comments = get_comments_from_parent(self) diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py index 232d485f36..b2aaf2535c 100644 --- a/frappe/core/doctype/communication/communication.py +++ b/frappe/core/doctype/communication/communication.py @@ -99,10 +99,7 @@ class Communication(Document): frappe.db.set_value("Communication", self.reference_name, "status", "Replied") if self.communication_type == "Communication": - # send new comment to listening clients - frappe.publish_realtime('new_communication', self.as_dict(), - doctype=self.reference_doctype, docname=self.reference_name, - after_commit=True) + self.notify_change('add') elif self.communication_type in ("Chat", "Notification", "Bot"): if self.reference_name == frappe.session.user: @@ -125,10 +122,14 @@ class Communication(Document): def on_trash(self): if self.communication_type == "Communication": - # send delete comment to listening clients - frappe.publish_realtime('delete_communication', self.as_dict(), - doctype= self.reference_doctype, docname = self.reference_name, - after_commit=True) + self.notify_change('delete') + + def notify_change(self, action): + frappe.publish_realtime('update_docinfo_for_{}_{}'.format(self.reference_doctype, self.reference_name), { + 'doc': self.as_dict(), + 'key': 'communications', + 'action': action + }, after_commit=True) def set_status(self): if not self.is_new(): @@ -244,9 +245,7 @@ class Communication(Document): if delivery_status: self.db_set('delivery_status', delivery_status) - - frappe.publish_realtime('update_communication', self.as_dict(), - doctype=self.reference_doctype, docname=self.reference_name, after_commit=True) + self.notify_change('update') # for list views and forms self.notify_update() diff --git a/frappe/public/js/frappe/form/footer/new_timeline.js b/frappe/public/js/frappe/form/footer/new_timeline.js index 412c206f4c..b7eb5426f1 100644 --- a/frappe/public/js/frappe/form/footer/new_timeline.js +++ b/frappe/public/js/frappe/form/footer/new_timeline.js @@ -5,7 +5,6 @@ import { get_version_timeline_content } from "./version_timeline_content_builder frappe.ui.form.NewTimeline = class { constructor(opts) { Object.assign(this, opts); - this.doc_info = this.frm && this.frm.get_docinfo() || {}; this.make(); } @@ -57,6 +56,7 @@ frappe.ui.form.NewTimeline = class { render_timeline_items() { this.timeline_items_wrapper.empty(); this.timeline_items = []; + this.doc_info = this.frm && this.frm.get_docinfo() || {}; this.prepare_timeline_contents(); this.timeline_items.sort((item1, item2) => new Date(item1.creation) - new Date(item2.creation)); @@ -363,7 +363,6 @@ frappe.ui.form.NewTimeline = class { name: comment_name }).then(() => { frappe.utils.play_sound("delete"); - this.refresh(); }); }); } diff --git a/frappe/public/js/frappe/form/footer/timeline.js b/frappe/public/js/frappe/form/footer/timeline.js index 109a52cb0f..4ee73f15fb 100644 --- a/frappe/public/js/frappe/form/footer/timeline.js +++ b/frappe/public/js/frappe/form/footer/timeline.js @@ -851,75 +851,4 @@ frappe.ui.form.Timeline = class Timeline { frappe.ui.setup_like_popover(this.wrapper, ".comment-likes"); } -}; - -$.extend(frappe.timeline, { - new_communication: function(communication) { - if (!communication.communication_type) { - communication.communication_type = 'Comment'; - } - var docinfo = frappe.model.get_docinfo(communication.reference_doctype, communication.reference_name); - if (docinfo && docinfo.communications) { - var communications = docinfo.communications; - var communication_exists = false; - for (var i=0, l=communications.length; i driver.reset()); driver.start(); } + + setup_docinfo_change_listener() { + frappe.realtime.on(`update_docinfo_for_${this.doctype}_${this.docname}`, ({doc, key, action='update'}) => { + let doc_list = (frappe.model.docinfo[this.doctype][this.docname][key] || []); + if (action === 'add') { + frappe.model.docinfo[this.doctype][this.docname][key].push(doc); + } + + let docindex = doc_list.findIndex(old_doc => { + return old_doc.name === doc.name; + }); + + if (docindex > -1) { + if (action === 'update') { + frappe.model.docinfo[this.doctype][this.docname][key].splice(docindex, 1, doc); + } + if (action === 'delete') { + frappe.model.docinfo[this.doctype][this.docname][key].splice(docindex, 1); + } + } + this.timeline && this.timeline.refresh(); + }); + } }; frappe.validated = 0; diff --git a/frappe/public/js/frappe/views/formview.js b/frappe/public/js/frappe/views/formview.js index 7440ab198d..35769abfcd 100644 --- a/frappe/public/js/frappe/views/formview.js +++ b/frappe/public/js/frappe/views/formview.js @@ -24,18 +24,6 @@ frappe.views.FormFactory = class FormFactory extends frappe.views.Factory { frappe.ui.form.close_grid_form(); }); - frappe.realtime.on("new_communication", function(data) { - frappe.timeline.new_communication(data); - }); - - frappe.realtime.on("delete_communication", function(data) { - frappe.timeline.delete_communication(data); - }); - - frappe.realtime.on('update_communication', function(data) { - frappe.timeline.update_communication(data); - }); - frappe.realtime.on("doc_viewers", function(data) { // set users that currently viewing the form frappe.ui.form.set_users(data, 'viewers');