PM/Chat Plugin - break it or leave it. V1.4.5 & 2.3-beta
-
Thanks for all the people who send me PM today and allowed me to get the plugin to version 1.0
The code is obscure and safe and no warranty is provided.
Features
- direct access to the last ~15 pm
- shows if new or how many unread messages in a conversation
- quick preview of the last replies inline
- participants avatars in conversation, hover to get name tooltip if needed.
Known stuff & miscellaneous
* preview messages does not show date and time - what a shame-
preview is stealth and will not mark messages as read.
-
developed on desktop was not tested or design for mobile.
* The plugin does not auto-refresh, if you want to update you have to open the envelope.
the other notification will show you if you have new message anyway.* I started the idea of adding an inline reply in the preview section to provide a chat like interface but this feature is not there yet.-
run in console and should work if add to an extension(greasemonkey)
-
security: The preview functionality almost got me with xss. I was trying to show a text version only due to visual issues,The conversion allowed html tag to be rendered. I moved back to just rendering the "cooked" version
and instead added some styling to fix the visual issues. I consider it pretty safe on that aspect, but testing is welcomed.
* there is a small bug, it may show 1 even if there are no messages need attention blah- 1/20/2014: click on @mention in the preview will go to the user page as a new page which will reset the widget
###Inline preview of the last replies
###code (Version 1.4.5)
(function(f){f.Styler||(f.Styler=new function(){var c={};this.loadStyle=function(a,h){c.hasOwnProperty(a)?0==c[a].added&&(c[a].content=h,this.appendStyle(a)):(c[a]={content:h,added:!1},this.appendStyle(a))};this.listLoadedStyles=function(){};this.removeStyle=function(a){c.hasOwnProperty(a)&&(c[a].added=!1,f("#Styler_"+a).remove())};this.appendStyle=function(a){c.hasOwnProperty(a)&&(c[a].added=!0,a=f("<style id='Styler_"+a+"'>"+c[a].content+"</style>"),f("body").append(a))}})})(jQuery); window.APIHelper=new function(){this.get_last_page=function(f,c){window.Messages_plugin.getCache();var a=window.Messages_plugin.get_topic_data(f),h=a.preview_posts.last_post_number||1,n=void 0===a.preview_posts.last_post_number,k=Math.ceil(h/20);$.getJSON("http://what.thedailywtf.com/t/"+f+".json?page="+k,function(a){var g=Math.ceil(a.posts_count/20),q=20-(20-h%20);g>k?0==q||n?$.getJSON("http://what.thedailywtf.com/t/"+f+".json?page="+g,c):c(a):c(a)})}}; window.Messages_plugin=function(){function f(a){if(null===g.json_result||null===g.last_fetch_time||1E4<Date.now()-g.last_fetch_time){var b=Discourse.User.current();b&&(b="http://what.thedailywtf.com/topics/private-messages/"+b.username+".json?_="+Date.now(),$.getJSON(b).then(function(b){g.json_result=b;a(b)}),g.last_fetch_time=Date.now())}else a(g.json_result)}function c(a,b){var p=$("<div></div>");_.forEach(a.posters,function(d){var e=_.find(b.users,{id:d.user_id});d=e.username;e=$("<img src='"+ e.avatar_template.replace("{size}","20")+"'></img>");e.attr("title",d);p.append(e)});return p}function a(a){var b=a.topic_list.topics;n.find("div.loading").hide();g.unseen=0;var p=0<n.find("li").length;_.first(b,15).forEach(function(d){if(l.hasOwnProperty(d.id))return!0;var e="<span style='float:right;margin-top:-2px;padding:3px;border-radius: 3px;'>"+Discourse.Formatter.relativeAge(new Date(d.last_posted_at),{format:"tiny",wrapInSpan:!1})+"</span>",e=$("<li><a>"+Handlebars.Utils.escapeExpression(d.title)+ "<span>"+e+"</span></a></li>");e.data("topic",d.id);e.data("preview-posts",{preview_rendered:!1});e.attr("data-topic-id",d.id);e.data("preview-posts");var b=$(e.find("a")),f="",m=d.posts_count;d.unseen&&(e.addClass("unread"),e.css("background","#D6F5FF"),b.append($("<span class='badge-notification new-posts'>new</span>")));null!==d.last_read_post_number&&(f="/"+d.last_read_post_number,m-=d.last_read_post_number);0<m&&(b.append($('<span class="badge-notification">'+m+"</span>")),g.unseen+=1);b.append(c(d, a));var m=$("<div class='last-message'><div class='messages'></div></div>"),k=m.find("div.messages");k.css({"overflow-y":"auto","max-height":"209px"});var q=$("<div class='quick_preview'><span style='background:#fff;color:#979797;border-radius: 3px;cursor:pointer' class='qr_btn badge-notification'>preview</span></div>");e.data("preview_rendered",!1);q.click(function(){l[d.id].preview_posts.preview_rendered&&$(l[d.id].last_message_preview).toggle();"none"!=$(l[d.id].last_message_preview).css("display")&& h.update_topic_preview(d.id)});e.append(q);e.data("last-message",m);e.append(m);b.attr("href","/t/"+d.slug+"/"+d.id+f);e.css({padding:"5px 5px 5px 5px","margin-bottom":"2px"});p?n.prepend(e):n.append(e);l.hasOwnProperty[d.id]||(l[d.id]={model:d,element:e,preview_rendered:!1,last_message_preview:m,last_message_preview_messages:k,preview_posts:{},active:!1})});0<g.unseen?(_pm_notification.html(g.unseen),_pm_notification.css("display","block"),$("#user-messages").css("color","#48AAEF")):(_pm_notification.html("0"), _pm_notification.css("display","none"),$("#user-messages").css("color","#999"))}var h=this,n=null,k=null,l={},g={unseen:0,last_fetch_time:null,json_result:null,last_notifications_history_unread:{},chunk_size:null};this.debug=function(){return{self:h,_list_outlet:n,_dropdown:k,_max_topics:15,_max_preview_messages:3,_list_items:l,_cache:g}};var q=function(a,b){var p=a.preview_posts,d=a.last_message_preview_messages;_.forEach(b,function(a){if(p.hasOwnProperty(a.post_number))return!0;p[a.post_number]= !0;p.last_post_number=a.post_number;var b=$("<div></div>");b.addClass("preview-stream-msg");b.attr("data-post-number",a.post_number);b.css({background:"#E6E6E6",margin:"3px","border-radius":"6px",padding:"5px"});var c=$("<div>"+a.username+"</div>");c.css({display:"inline-block","font-weight":"bold"});var f=$("<span>"+Discourse.Formatter.relativeAge(new Date(a.updated_at),{format:"tiny",wrapInSpan:!1})+"</span>");f.addClass("relative-date");f.attr({"data-time":new Date(a.updated_at),"data-format":"tiny"}); f.css({color:"#9AAFFF","margin-left":"5px"});var g=$("<img src='"+a.avatar_template.replace("{size}","20")+"'></img>");g.css({"margin-right":"5px"});c.prepend(g);a=$("<div></div>").html(a.cooked);b.append(c).append(f).append(a);d.append(b)})},r=function(a){var b=h.get_topic_data(a),c=b.preview_posts,d=b.element;if(1!=c.preview_rendered){c.preview_rendered=!0;d.addClass("active_preview");b.active=!0;var c=$("<div class='quick_reply_container'><div class='qr_input_container' ><textarea></textarea></div><span class='quick-reply-button badge-notification'><i class='fa fa-reply'></i> reply</span></div>"), e=c.find("span.quick-reply-button"),f=c.find("textarea");f.keydown(function(a){a.ctrlKey&&13==a.keyCode&&e.click()});f.focus(function(){d[0].scrollIntoView();$("#messages-dropdown").css({overflow:"hidden"})});f.blur(function(){$("#messages-dropdown").css({overflow:"auto"})});e.click(function(){var b=$(this).find("i");b.addClass("fa-spin");$.post("/posts",{raw:f.val(),category:"",topic_id:a,is_warning:"false",archetype:"regular"}).done(function(){f.val("");b.removeClass("fa-spin");h.update_topic_preview(a)})}); f.css({background:"#E2E2E2",width:"97%",height:"45px","margin-bottom":"0px","margin-top":"3px","padding-bottom":"0px"});e.css({margin:"5px 0px 5px 0px",border:"1px solid #8D8EE3",background:"#3D7FFF","border-radius":"4px",cursor:"pointer"});b.last_message_preview.append(c)}};this.get_topic_data=function(a){return l.hasOwnProperty(a)?l[a]:!1};this.update_topic_preview=function(a){var b=h.get_topic_data(a);APIHelper.get_last_page(a,function(c){b.element.css("background","#BDD8FE");var d=b.last_message_preview_messages; d.css({width:"100%",background:"#F5F5F5","max-height":"250px",margin:"-2px 0px 5px 0px",overflow:"auto"});c=_.last(c.post_stream.posts,3);var e=d[0].scrollHeight-d[0].scrollTop==d[0].clientHeight;q(b,c);e&&d.animate({scrollTop:d[0].scrollHeight},"slow");r(a)})};this.getMessages=function(){f(a);this.showDropdown()};this.showDropdown=function(){k.css("display","block");$("#messages_menu").addClass("active")};this.hideDropdown=function(){k.css("display","none");$("#messages_menu").removeClass("active")}; this.prepare=function(){f(function(c){a(c)});h.hideDropdown()};this.getCache=function(){return g};(function(){var a=$("ul[role=navigation] li.notifications"),b=$("<li id='messages_menu' class='messages'><a class='icon' href='#' id='user-messages'><i class='fa fa-envelope-o'></i><span class='sr-only'>notifications of @name mentions, replies to your posts and topics, private messages, etc</span></a></li>"),b=$(b);b.insertBefore(a);_pm_notification=$('<a id="pm-notification" href="#" style="background:#48AAEF;margin-left:-14px;" class="badge-notification"></a>'); _pm_notification.css("display","none");$("#user-messages").append(_pm_notification);$("#messages_menu").click(function(a){a.preventDefault();"block"==k.css("display")?h.hideDropdown():h.getMessages()})})();(function(){var a=$("div.panel"),b=$("<section class='d-dropdown' id='messages-dropdown'> <div id='messages_container'><ul><div class='loading'>Loading ... </div></ul></div> </section>");b.css("width","480px");k=b;n=b.find("ul");a.append(k)})()}; function hook_to_user_notifications(){window.MessageBus.subscribe("/notification/"+Discourse.User.current().id,function(f){window.last_notification_call&&300>Date.now()-window.last_notification_call?window.last_notification_call=Date.now():Discourse.ajax("/notifications/history.json").then(function(c){c=_.where(c,{read:!1,notification_type:6});_.forEach(c,function(a){window.Messages_plugin.get_topic_data(a.topic_id).active&&window.Messages_plugin.update_topic_preview(a.topic_id);window.last_notification_call= Date.now()});window.Messages_plugin.getCache().last_notifications_history_unread=c})})}$("document").ready(function(){Em.run.next(function(){hook_to_user_notifications();window.Messages_plugin=new window.Messages_plugin;window.Messages_plugin.prepare()})});$.Styler.loadStyle("custom-pm-styles","#messages-dropdown li:hover .last-message a{display:inline-block}#messages-dropdown li .last-message a{display:inline-block!important}#messages-dropdown li .last-message a.mention,#messages-dropdown li:hover .last-message a.mention{background:#cfcfcf!important}#messages-dropdown .last-message a:not(.mention){background:0 0;display:inline-block}#messages-dropdown .title{float:none;display:block;height:auto};"); $.Styler.loadStyle("custom-pm-styles2","div.last-message::-webkit-scrollbar{width:8px;height:16px}div.last-message::-webkit-scrollbar-track {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); }div.last-message::-webkit-scrollbar-thumb {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);background: rgba(162, 162, 162, 0.49); }#messages_container .last-message .preview-stream-msg {background:#fff !important;border:1px solid #cecece;}.qr_btn{margin-top:3px;}#messages_container li:hover a:not(.badge-notification) {background: rgba(138, 138, 138, 0.1)!important;}#messages_container li{ margin-top:5px;}.quick-reply-button:hover{background:#519FFF!important;}");
-
security: The preview functionality almost got me with xss. I was trying to show a text version only due to visual issues,The conversion allowed html tag to be rendered. I moved back to just rendering the "cooked" versionand instead added some styling to fix the visual issues. I consider it pretty safe on that aspect, but testing is welcomed.
Try
Handlebars.Utils.escapeExpression
, you have access to it. It's what prevents XSS throughout Discourse.
-
Try Handlebars.Utils.escapeExpression, you have access to it. It's what prevents XSS throughout Discourse.
thanks will keep that in mind.
-
After tons of great feedback since the initial release, the wait is over. the new version is here.
###Whats new
- Realtime chat
- quick reply
- Messages in preview now contain time.
UX is not the greatest, and there are some minor things that I don't like.
When a new message is added in a "chat" the scroll does not maintain position.There is no ctrl+enter for quick submit- there are no error handling when posting a reply, the best indication that something is wrong is the reply button icon will keep on spinning.
- post button does not protect for multiple clicks
- closing the widget and reopening will result in complete reload /reset of the widget.
####Good to know
When you are in preview mode, and the input for the quick reply is in focus, The widget will lock the scrolling
of the container and will only allow scrolling in the messages. to end that mode you have to click somewhere inside the widget that will remove focus for the input box.###Version 1.2
updated(1.2) 1/18/2015
Auto scroll of messages (when scroll is at the bottom).
Move input outside the messages feed so scroll of feed will keep input static if you writing a reply.
Ctrl+Enter keyboard shortcut to submit replyEDIT: Removed old version's source upon request -aliceif
-
Version 1.3
-
render widget list once on open/close of menu.
allow preserving state of chat conversations. -
background update for new pm topics and pm chat messages (quick replies feed)
-
small UI improvements
EDIT: Removed old version's source upon request -aliceif
-
-
a.addClass("fa-spin");
heh
Filed under: more constructive criticism will be provided once people actually start writing PMs to me, seems cool though
-
heh
it is for the loading animation
If you find any bugs, I am using this thread as a bug tracker. source control. and suggestions box.
-
If you find any bugs, I am using this thread as a bug tracker. source control. and suggestions box.
But not a backup solution and configuration management tool? I am disappoint.
-
But not a backup solution and configuration management tool? I am disappoint.
Thanks for sending your feedback into the project suggestion box. we will take that under advisement.
meantime we use google cache as offsite backup.
-
-
I am using this thread as a bug tracker. source control. and suggestions box.
Please don't give the DiscoDevs ideas about using Discourse for source control. :(
-
DiscSource?
-
DiScourseControl please!
Filed Under: alternative: DiscoSource... a good source for a broken time!
-
Post cannot be longer than 32000 characters
-
New Discourse coding standard: no source file to have more than 32000 characters.
Sorted!
-
Scouse Control?!
-
SpouseControl!
Filed Under: Please don't use Discourse on your significant other. Thanks!
-
-
This post is deleted!
-
The menu thingie seems to randomly open itself for me now sometimes.
I use FF35.
-
The menu thingie seems to randomly open itself for me now sometimes.I use FF35.
can you provide some ways/ideas/steps to replicate?
@riking I think after you recategorized my topic, I lost the permission to edit it (the 1st post).
can you fix it?
-
... well, not really.
It just ... opens itself after some waiting.It might be related to message bus polling, at least it seems to me that the times it opens happen once a message bus poll took place - but not after every one.Actually, abarker seems to be closer to the cause than I am
-
It seems to happen when navigating to a new page (sometimes), or when receiving a new batch of data from the server (open notifications, getting new notifications, loading a new batch of posts in a topic, etc.).
Chrome 40 on Win 7
-
That shouldn't do it. @PJH what's the edit time limit?
-
This post is deleted!
-
This post is deleted!
-
This post is deleted!
-
-
I thought the ninja limit was 60. So that's why I keep just missing the window. Why 54? That seems like a WTF-y number. (I think I probably just answered my own question.)
-
CBA to look it up again but IIRC @system changed it a while ago.
I just haven't bothered changing it.
I'd start a poll on whether either of those limits should be changed, but due to the international nature of this forum, the poll couldn't be closed... ;-)
-
This post is deleted!
-
Someone could wikify your OP, maybe?
Sounds like a kind of bad idea,potentially, though ...
-
This post is deleted!
-
This post is deleted!
-
You might want to filter out tags from topic titles when you generate the PM list.
-
Thanks,
At the time the title was escaped by default, I am pretty sure that title used to omit tags, That is a good lesson to learn from.
@aliceif, all the older version posted here are not secure, can you edit my posts above an remove code blocks?
I would have done it myself, but apparently the edit limit was not removed...Version 1.4.4
Security: Add escaping to title.
(function(f){f.Styler||(f.Styler=new function(){var c={};this.loadStyle=function(a,h){c.hasOwnProperty(a)?0==c[a].added&&(c[a].content=h,this.appendStyle(a)):(c[a]={content:h,added:!1},this.appendStyle(a))};this.listLoadedStyles=function(){};this.removeStyle=function(a){c.hasOwnProperty(a)&&(c[a].added=!1,f("#Styler_"+a).remove())};this.appendStyle=function(a){c.hasOwnProperty(a)&&(c[a].added=!0,a=f("<style id='Styler_"+a+"'>"+c[a].content+"</style>"),f("body").append(a))}})})(jQuery); window.APIHelper=new function(){this.get_last_page=function(f,c){window.Messages_plugin.getCache();var a=window.Messages_plugin.get_topic_data(f),h=a.preview_posts.last_post_number||1,n=void 0===a.preview_posts.last_post_number,k=Math.ceil(h/20);$.getJSON("http://what.thedailywtf.com/t/"+f+".json?page="+k,function(a){var g=Math.ceil(a.posts_count/20),q=20-(20-h%20);g>k?0==q||n?$.getJSON("http://what.thedailywtf.com/t/"+f+".json?page="+g,c):c(a):c(a)})}}; window.Messages_plugin=function(){function f(a){if(null===g.json_result||null===g.last_fetch_time||1E4<Date.now()-g.last_fetch_time){var b=Discourse.User.current();b&&(b="http://what.thedailywtf.com/topics/private-messages/"+b.username+".json?_="+Date.now(),$.getJSON(b).then(function(b){g.json_result=b;a(b)}),g.last_fetch_time=Date.now())}else a(g.json_result)}function c(a,b){var p=$("<div></div>");_.forEach(a.posters,function(d){var e=_.find(b.users,{id:d.user_id});d=e.username;e=$("<img src='"+ e.avatar_template.replace("{size}","20")+"'></img>");e.attr("title",d);p.append(e)});return p}function a(a){var b=a.topic_list.topics;n.find("div.loading").hide();g.unseen=0;var p=0<n.find("li").length;_.first(b,15).forEach(function(d){if(l.hasOwnProperty(d.id))return!0;var e="<span style='float:right;margin-top:-2px;padding:3px;border-radius: 3px;'>"+Discourse.Formatter.relativeAge(new Date(d.last_posted_at),{format:"tiny",wrapInSpan:!1})+"</span>",e=$("<li><a>"+Handlebars.Utils.escapeExpression(d.title)+ "<span>"+e+"</span></a></li>");e.data("topic",d.id);e.data("preview-posts",{preview_rendered:!1});e.attr("data-topic-id",d.id);e.data("preview-posts");var b=$(e.find("a")),f="",m=d.posts_count;d.unseen&&(e.addClass("unread"),e.css("background","#D6F5FF"),b.append($("<span class='badge-notification new-posts'>new</span>")));null!==d.last_read_post_number&&(f="/"+d.last_read_post_number,m-=d.last_read_post_number);0<m&&(b.append($('<span class="badge-notification">'+m+"</span>")),g.unseen+=1);b.append(c(d, a));var m=$("<div class='last-message'><div class='messages'></div></div>"),k=m.find("div.messages");k.css({"overflow-y":"auto","max-height":"209px"});var q=$("<div class='quick_preview'><span style='background:#fff;color:#979797;border-radius: 3px;cursor:pointer' class='qr_btn badge-notification'>preview</span></div>");e.data("preview_rendered",!1);q.click(function(){l[d.id].preview_posts.preview_rendered&&$(l[d.id].last_message_preview).toggle();"none"!=$(l[d.id].last_message_preview).css("display")&& h.update_topic_preview(d.id)});e.append(q);e.data("last-message",m);e.append(m);b.attr("href","/t/"+d.slug+"/"+d.id+f);e.css({padding:"5px 5px 5px 5px","margin-bottom":"2px"});p?n.prepend(e):n.append(e);l.hasOwnProperty[d.id]||(l[d.id]={model:d,element:e,preview_rendered:!1,last_message_preview:m,last_message_preview_messages:k,preview_posts:{},active:!1})});0<g.unseen?(_pm_notification.html(g.unseen),_pm_notification.css("display","block"),$("#user-messages").css("color","#48AAEF")):(_pm_notification.html("0"), _pm_notification.css("display","none"),$("#user-messages").css("color","#999"))}var h=this,n=null,k=null,l={},g={unseen:0,last_fetch_time:null,json_result:null,last_notifications_history_unread:{},chunk_size:null};this.debug=function(){return{self:h,_list_outlet:n,_dropdown:k,_max_topics:15,_max_preview_messages:3,_list_items:l,_cache:g}};var q=function(a,b){var p=a.preview_posts,d=a.last_message_preview_messages;_.forEach(b,function(a){if(p.hasOwnProperty(a.post_number))return!0;p[a.post_number]= !0;p.last_post_number=a.post_number;var b=$("<div></div>");b.addClass("preview-stream-msg");b.attr("data-post-number",a.post_number);b.css({background:"#E6E6E6",margin:"3px","border-radius":"6px",padding:"5px"});var c=$("<div>"+a.username+"</div>");c.css({display:"inline-block","font-weight":"bold"});var f=$("<span>"+Discourse.Formatter.relativeAge(new Date(a.updated_at),{format:"tiny",wrapInSpan:!1})+"</span>");f.addClass("relative-date");f.attr({"data-time":new Date(a.updated_at),"data-format":"tiny"}); f.css({color:"#9AAFFF","margin-left":"5px"});var g=$("<img src='"+a.avatar_template.replace("{size}","20")+"'></img>");g.css({"margin-right":"5px"});c.prepend(g);a=$("<div></div>").html(a.cooked);b.append(c).append(f).append(a);d.append(b)})},r=function(a){var b=h.get_topic_data(a),c=b.preview_posts,d=b.element;if(1!=c.preview_rendered){c.preview_rendered=!0;d.addClass("active_preview");b.active=!0;var c=$("<div class='quick_reply_container'><div class='qr_input_container' ><textarea></textarea></div><span class='quick-reply-button badge-notification'><i class='fa fa-reply'></i> reply</span></div>"), e=c.find("span.quick-reply-button"),f=c.find("textarea");f.keydown(function(a){a.ctrlKey&&13==a.keyCode&&e.click()});f.focus(function(){d[0].scrollIntoView();$("#messages-dropdown").css({overflow:"hidden"})});f.blur(function(){$("#messages-dropdown").css({overflow:"auto"})});e.click(function(){var b=$(this).find("i");b.addClass("fa-spin");$.post("/posts",{raw:f.val(),category:"",topic_id:a,is_warning:"false",archetype:"regular"}).done(function(){f.val("");b.removeClass("fa-spin");h.update_topic_preview(a)})}); f.css({background:"#E2E2E2",width:"97%",height:"45px","margin-bottom":"0px","margin-top":"3px","padding-bottom":"0px"});e.css({margin:"5px 0px 5px 0px",border:"1px solid #8D8EE3",background:"#3D7FFF","border-radius":"4px",cursor:"pointer"});b.last_message_preview.append(c)}};this.get_topic_data=function(a){return l.hasOwnProperty(a)?l[a]:!1};this.update_topic_preview=function(a){var b=h.get_topic_data(a);APIHelper.get_last_page(a,function(c){b.element.css("background","#BDD8FE");var d=b.last_message_preview_messages; d.css({width:"100%",background:"#F5F5F5","max-height":"250px",margin:"-2px 0px 5px 0px",overflow:"auto"});c=_.last(c.post_stream.posts,3);var e=d[0].scrollHeight-d[0].scrollTop==d[0].clientHeight;q(b,c);e&&d.animate({scrollTop:d[0].scrollHeight},"slow");r(a)})};this.getMessages=function(){f(a);this.showDropdown()};this.showDropdown=function(){k.css("display","block");$("#messages_menu").addClass("active")};this.hideDropdown=function(){k.css("display","none");$("#messages_menu").removeClass("active")}; this.prepare=function(){f(function(c){a(c)});h.hideDropdown()};this.getCache=function(){return g};(function(){var a=$("ul[role=navigation] li.notifications"),b=$("<li id='messages_menu' class='messages'><a class='icon' href='#' id='user-messages'><i class='fa fa-envelope-o'></i><span class='sr-only'>notifications of @name mentions, replies to your posts and topics, private messages, etc</span></a></li>"),b=$(b);b.insertBefore(a);_pm_notification=$('<a id="pm-notification" href="#" style="background:#48AAEF;margin-left:-14px;" class="badge-notification"></a>'); _pm_notification.css("display","none");$("#user-messages").append(_pm_notification);$("#messages_menu").click(function(a){a.preventDefault();"block"==k.css("display")?h.hideDropdown():h.getMessages()})})();(function(){var a=$("div.panel"),b=$("<section class='d-dropdown' id='messages-dropdown'> <div id='messages_container'><ul><div class='loading'>Loading ... </div></ul></div> </section>");b.css("width","480px");k=b;n=b.find("ul");a.append(k)})()}; function hook_to_user_notifications(){Discourse.MessageBus.subscribe("/notification/"+Discourse.User.current().id,function(f){window.last_notification_call&&300>Date.now()-window.last_notification_call?window.last_notification_call=Date.now():Discourse.ajax("/notifications/history.json").then(function(c){c=_.where(c,{read:!1,notification_type:6});_.forEach(c,function(a){window.Messages_plugin.get_topic_data(a.topic_id).active&&window.Messages_plugin.update_topic_preview(a.topic_id);window.last_notification_call= Date.now()});window.Messages_plugin.getCache().last_notifications_history_unread=c})})}hook_to_user_notifications();$("document").ready(function(){Em.run.next(function(){window.Messages_plugin=new window.Messages_plugin;window.Messages_plugin.prepare()})});$.Styler.loadStyle("custom-pm-styles","#messages-dropdown li:hover .last-message a{display:inline-block}#messages-dropdown li .last-message a{display:inline-block!important}#messages-dropdown li .last-message a.mention,#messages-dropdown li:hover .last-message a.mention{background:#cfcfcf!important}#messages-dropdown .last-message a:not(.mention){background:0 0;display:inline-block}#messages-dropdown .title{float:none;display:block;height:auto};"); $.Styler.loadStyle("custom-pm-styles2","div.last-message::-webkit-scrollbar{width:8px;height:16px}div.last-message::-webkit-scrollbar-track {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); }div.last-message::-webkit-scrollbar-thumb {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);background: rgba(162, 162, 162, 0.49); }#messages_container .last-message .preview-stream-msg {background:#fff !important;border:1px solid #cecece;}.qr_btn{margin-top:3px;}#messages_container li:hover a:not(.badge-notification) {background: rgba(138, 138, 138, 0.1)!important;}#messages_container li{ margin-top:5px;}.quick-reply-button:hover{background:#519FFF!important;}");
-
Done.
-
This is broken now, FYI. Breaks the site to use as of last night.
-
Thanks @Yamikuronue. you can try the new version and let me know if it fixed the problem for you.
The issue was a change to the scope of the MessageBus
Discourse.MessageBus
changed towindow.MessageBus
.**Discourse still have a reference to a broken object under Discourse,Messagebox. not sure if that was an intentional change or a regression.
@aliceif if you feel like it, you can update the code on the OP to the new version
thanks##version 1.4.5
- Fix reference MessageBus Discourse scope to window scope.
- A minor fix postpone subscribe to messagebus after document ready.
(function(f){f.Styler||(f.Styler=new function(){var c={};this.loadStyle=function(a,h){c.hasOwnProperty(a)?0==c[a].added&&(c[a].content=h,this.appendStyle(a)):(c[a]={content:h,added:!1},this.appendStyle(a))};this.listLoadedStyles=function(){};this.removeStyle=function(a){c.hasOwnProperty(a)&&(c[a].added=!1,f("#Styler_"+a).remove())};this.appendStyle=function(a){c.hasOwnProperty(a)&&(c[a].added=!0,a=f("<style id='Styler_"+a+"'>"+c[a].content+"</style>"),f("body").append(a))}})})(jQuery); window.APIHelper=new function(){this.get_last_page=function(f,c){window.Messages_plugin.getCache();var a=window.Messages_plugin.get_topic_data(f),h=a.preview_posts.last_post_number||1,n=void 0===a.preview_posts.last_post_number,k=Math.ceil(h/20);$.getJSON("http://what.thedailywtf.com/t/"+f+".json?page="+k,function(a){var g=Math.ceil(a.posts_count/20),q=20-(20-h%20);g>k?0==q||n?$.getJSON("http://what.thedailywtf.com/t/"+f+".json?page="+g,c):c(a):c(a)})}}; window.Messages_plugin=function(){function f(a){if(null===g.json_result||null===g.last_fetch_time||1E4<Date.now()-g.last_fetch_time){var b=Discourse.User.current();b&&(b="http://what.thedailywtf.com/topics/private-messages/"+b.username+".json?_="+Date.now(),$.getJSON(b).then(function(b){g.json_result=b;a(b)}),g.last_fetch_time=Date.now())}else a(g.json_result)}function c(a,b){var p=$("<div></div>");_.forEach(a.posters,function(d){var e=_.find(b.users,{id:d.user_id});d=e.username;e=$("<img src='"+ e.avatar_template.replace("{size}","20")+"'></img>");e.attr("title",d);p.append(e)});return p}function a(a){var b=a.topic_list.topics;n.find("div.loading").hide();g.unseen=0;var p=0<n.find("li").length;_.first(b,15).forEach(function(d){if(l.hasOwnProperty(d.id))return!0;var e="<span style='float:right;margin-top:-2px;padding:3px;border-radius: 3px;'>"+Discourse.Formatter.relativeAge(new Date(d.last_posted_at),{format:"tiny",wrapInSpan:!1})+"</span>",e=$("<li><a>"+Handlebars.Utils.escapeExpression(d.title)+ "<span>"+e+"</span></a></li>");e.data("topic",d.id);e.data("preview-posts",{preview_rendered:!1});e.attr("data-topic-id",d.id);e.data("preview-posts");var b=$(e.find("a")),f="",m=d.posts_count;d.unseen&&(e.addClass("unread"),e.css("background","#D6F5FF"),b.append($("<span class='badge-notification new-posts'>new</span>")));null!==d.last_read_post_number&&(f="/"+d.last_read_post_number,m-=d.last_read_post_number);0<m&&(b.append($('<span class="badge-notification">'+m+"</span>")),g.unseen+=1);b.append(c(d, a));var m=$("<div class='last-message'><div class='messages'></div></div>"),k=m.find("div.messages");k.css({"overflow-y":"auto","max-height":"209px"});var q=$("<div class='quick_preview'><span style='background:#fff;color:#979797;border-radius: 3px;cursor:pointer' class='qr_btn badge-notification'>preview</span></div>");e.data("preview_rendered",!1);q.click(function(){l[d.id].preview_posts.preview_rendered&&$(l[d.id].last_message_preview).toggle();"none"!=$(l[d.id].last_message_preview).css("display")&& h.update_topic_preview(d.id)});e.append(q);e.data("last-message",m);e.append(m);b.attr("href","/t/"+d.slug+"/"+d.id+f);e.css({padding:"5px 5px 5px 5px","margin-bottom":"2px"});p?n.prepend(e):n.append(e);l.hasOwnProperty[d.id]||(l[d.id]={model:d,element:e,preview_rendered:!1,last_message_preview:m,last_message_preview_messages:k,preview_posts:{},active:!1})});0<g.unseen?(_pm_notification.html(g.unseen),_pm_notification.css("display","block"),$("#user-messages").css("color","#48AAEF")):(_pm_notification.html("0"), _pm_notification.css("display","none"),$("#user-messages").css("color","#999"))}var h=this,n=null,k=null,l={},g={unseen:0,last_fetch_time:null,json_result:null,last_notifications_history_unread:{},chunk_size:null};this.debug=function(){return{self:h,_list_outlet:n,_dropdown:k,_max_topics:15,_max_preview_messages:3,_list_items:l,_cache:g}};var q=function(a,b){var p=a.preview_posts,d=a.last_message_preview_messages;_.forEach(b,function(a){if(p.hasOwnProperty(a.post_number))return!0;p[a.post_number]= !0;p.last_post_number=a.post_number;var b=$("<div></div>");b.addClass("preview-stream-msg");b.attr("data-post-number",a.post_number);b.css({background:"#E6E6E6",margin:"3px","border-radius":"6px",padding:"5px"});var c=$("<div>"+a.username+"</div>");c.css({display:"inline-block","font-weight":"bold"});var f=$("<span>"+Discourse.Formatter.relativeAge(new Date(a.updated_at),{format:"tiny",wrapInSpan:!1})+"</span>");f.addClass("relative-date");f.attr({"data-time":new Date(a.updated_at),"data-format":"tiny"}); f.css({color:"#9AAFFF","margin-left":"5px"});var g=$("<img src='"+a.avatar_template.replace("{size}","20")+"'></img>");g.css({"margin-right":"5px"});c.prepend(g);a=$("<div></div>").html(a.cooked);b.append(c).append(f).append(a);d.append(b)})},r=function(a){var b=h.get_topic_data(a),c=b.preview_posts,d=b.element;if(1!=c.preview_rendered){c.preview_rendered=!0;d.addClass("active_preview");b.active=!0;var c=$("<div class='quick_reply_container'><div class='qr_input_container' ><textarea></textarea></div><span class='quick-reply-button badge-notification'><i class='fa fa-reply'></i> reply</span></div>"), e=c.find("span.quick-reply-button"),f=c.find("textarea");f.keydown(function(a){a.ctrlKey&&13==a.keyCode&&e.click()});f.focus(function(){d[0].scrollIntoView();$("#messages-dropdown").css({overflow:"hidden"})});f.blur(function(){$("#messages-dropdown").css({overflow:"auto"})});e.click(function(){var b=$(this).find("i");b.addClass("fa-spin");$.post("/posts",{raw:f.val(),category:"",topic_id:a,is_warning:"false",archetype:"regular"}).done(function(){f.val("");b.removeClass("fa-spin");h.update_topic_preview(a)})}); f.css({background:"#E2E2E2",width:"97%",height:"45px","margin-bottom":"0px","margin-top":"3px","padding-bottom":"0px"});e.css({margin:"5px 0px 5px 0px",border:"1px solid #8D8EE3",background:"#3D7FFF","border-radius":"4px",cursor:"pointer"});b.last_message_preview.append(c)}};this.get_topic_data=function(a){return l.hasOwnProperty(a)?l[a]:!1};this.update_topic_preview=function(a){var b=h.get_topic_data(a);APIHelper.get_last_page(a,function(c){b.element.css("background","#BDD8FE");var d=b.last_message_preview_messages; d.css({width:"100%",background:"#F5F5F5","max-height":"250px",margin:"-2px 0px 5px 0px",overflow:"auto"});c=_.last(c.post_stream.posts,3);var e=d[0].scrollHeight-d[0].scrollTop==d[0].clientHeight;q(b,c);e&&d.animate({scrollTop:d[0].scrollHeight},"slow");r(a)})};this.getMessages=function(){f(a);this.showDropdown()};this.showDropdown=function(){k.css("display","block");$("#messages_menu").addClass("active")};this.hideDropdown=function(){k.css("display","none");$("#messages_menu").removeClass("active")}; this.prepare=function(){f(function(c){a(c)});h.hideDropdown()};this.getCache=function(){return g};(function(){var a=$("ul[role=navigation] li.notifications"),b=$("<li id='messages_menu' class='messages'><a class='icon' href='#' id='user-messages'><i class='fa fa-envelope-o'></i><span class='sr-only'>notifications of @name mentions, replies to your posts and topics, private messages, etc</span></a></li>"),b=$(b);b.insertBefore(a);_pm_notification=$('<a id="pm-notification" href="#" style="background:#48AAEF;margin-left:-14px;" class="badge-notification"></a>'); _pm_notification.css("display","none");$("#user-messages").append(_pm_notification);$("#messages_menu").click(function(a){a.preventDefault();"block"==k.css("display")?h.hideDropdown():h.getMessages()})})();(function(){var a=$("div.panel"),b=$("<section class='d-dropdown' id='messages-dropdown'> <div id='messages_container'><ul><div class='loading'>Loading ... </div></ul></div> </section>");b.css("width","480px");k=b;n=b.find("ul");a.append(k)})()}; function hook_to_user_notifications(){window.MessageBus.subscribe("/notification/"+Discourse.User.current().id,function(f){window.last_notification_call&&300>Date.now()-window.last_notification_call?window.last_notification_call=Date.now():Discourse.ajax("/notifications/history.json").then(function(c){c=_.where(c,{read:!1,notification_type:6});_.forEach(c,function(a){window.Messages_plugin.get_topic_data(a.topic_id).active&&window.Messages_plugin.update_topic_preview(a.topic_id);window.last_notification_call= Date.now()});window.Messages_plugin.getCache().last_notifications_history_unread=c})})}$("document").ready(function(){Em.run.next(function(){hook_to_user_notifications();window.Messages_plugin=new window.Messages_plugin;window.Messages_plugin.prepare()})});$.Styler.loadStyle("custom-pm-styles","#messages-dropdown li:hover .last-message a{display:inline-block}#messages-dropdown li .last-message a{display:inline-block!important}#messages-dropdown li .last-message a.mention,#messages-dropdown li:hover .last-message a.mention{background:#cfcfcf!important}#messages-dropdown .last-message a:not(.mention){background:0 0;display:inline-block}#messages-dropdown .title{float:none;display:block;height:auto};"); $.Styler.loadStyle("custom-pm-styles2","div.last-message::-webkit-scrollbar{width:8px;height:16px}div.last-message::-webkit-scrollbar-track {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); }div.last-message::-webkit-scrollbar-thumb {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);background: rgba(162, 162, 162, 0.49); }#messages_container .last-message .preview-stream-msg {background:#fff !important;border:1px solid #cecece;}.qr_btn{margin-top:3px;}#messages_container li:hover a:not(.badge-notification) {background: rgba(138, 138, 138, 0.1)!important;}#messages_container li{ margin-top:5px;}.quick-reply-button:hover{background:#519FFF!important;}");
-
Will do, give me a few moments.
-
The only time I see (fuck off discotoaster)
The only time I've seen this plugin pop up a blue symbol in response to a PM is when I'm the one sending the PM. The rest of the time it remains stale and outdated, and clicking on any of the PMs takes me way up the chain unless I do a proper refresh first to fetch newer data. So if it's supposed to be livestreaming like the notification widget, it's not, and if it's not supposed to, why does it do so when I post? Either way there seems to be a bug
-
messages_plugin.v2.1.js
Release channel : stable - adventurous
Whats new:
-
A more reliable main notification bubble.
-
A more reliable notification bubble for new messages in conversation with added
"live" synchronization mechanism.
-
Potential improvement interacting with MessageBus, reduces some overhead.
clicking on any of the PMs takes me way up the chain unless I do a proper refresh first to fetch newer data.
I am not sure I can address this concern it could be a limitation of the implementation.
1.I am not sure I completely understand this report.
2.keep in mind that the widget does not update read status, even if you read in the quick preview. the implications are that if you actually decide to watch the conversation outside the widget. the link should take you to the first unread message.
3.I may release a minor fix on the next release, now that I added some sync mechanism it should be easy to update the link to reflect the new message id based on changes in post read statuses.
Thanks for the feedback.
hope this version works better overall.
-
-
[quote="Monarch, post:42, topic:712]
1.I am not sure I completely understand this report.
[/quote]This involves some byttumptions but it seems to be that whenever the page loads, whatever was the last post in s PM thread is where clicking that thread will take me until I next do a hard refresh, b even if there's been a hundred messages in that thread since
-
I believe that what you describe relate to this.
@Monarch said:keep in mind that the widget does not update read status, even if you read in the quick preview. the implications are that if you actually decide to watch the conversation outside the widget. the link should take you to the first unread message.
And since the widget only render once per page, it will preserve the last PM you read.
next release I might fix that.did you had a chance to run the new version, does it work?
-
not yet. This week is crazy. I'll report back when I have a chance
-
Link 404'd
-
will post this later
-
Link 404'd
github think I am a bot, god bless the competition, I put it in bitbucket.
###V2.3-beta.js
####Change log
-
Update to conversation main link
-
Link will update to reflect the last read message in the conversation (on sync cycle)
-
** reading a message in the quick preview does not count as reading a message.
-
A user visiting the conversation page, outside of the widget, could affect the last read message.
-
A user reply from within the widget will set the last read message to the last message in the conversation (the behavior is based on the data returned by discourse api)
-
Updates to Conversation time
- Set time to the latest message time when synced.
- Take advantage of the builtin time format interval to maintain relative time.
-
Separate new posts and unread counter notification bubbles
-
new posts(blue bubble) reset whenever the user reply to a message, or open the conversation page in the browser(the behavior is based on the data returned by discourse api)
-
Lowered internal resource cache ttl to have a more accurate notification counter.
-
UI
-
thinner scroll bar in quick preview feed
-
Conversation line separator
-
minor css changes to better handle longer titles.
-
-
-
This broke today with the https upgrade; I fixed it by doing a search-and-replace of http with https.
-
Thanks @Yamikuronue
I removed the explicit protocol and used "//" instead it will use whatever protocol the page is loaded with.
##V2.4.js