aboutsummaryrefslogtreecommitdiff
path: root/web/scripts.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/scripts.js')
-rw-r--r--web/scripts.js684
1 files changed, 684 insertions, 0 deletions
diff --git a/web/scripts.js b/web/scripts.js
new file mode 100644
index 00000000..c420dcdb
--- /dev/null
+++ b/web/scripts.js
@@ -0,0 +1,684 @@
+var ws=null;
+var pageTitle;
+
+function initWS() {
+ if(typeof(pageMID)!="undefined" && pageMID>0) {
+ var url;
+ if(typeof(juickDebug)!="undefined") {
+ url="wss://ws.juick.com/_replies";
+ } else {
+ url="wss://ws.juick.com/"+pageMID;
+ }
+ if(typeof(hash)!="undefined" && hash) {
+ url+="?hash="+hash;
+ }
+
+ ws = new WebSocket(url);
+ ws.onopen = function() {
+ console.log('online');
+ if($('#wsthread').length==0) {
+ var d=$('<div id="wsthread"/>');
+ d.on('click',onclickNextReply);
+ d.appendTo("body");
+ pageTitle=document.title;
+ }
+ };
+ ws.onclose = function() {
+ console.log('offline');
+ ws=null;
+ setTimeout(function() {
+ initWS();
+ },2000);
+ };
+ ws.onmessage = function(msg) {
+ if(msg.data==' ') {
+ ws.send(' ');
+ } else {
+ try {
+ var jsonMsg=$.parseJSON(msg.data);
+ console.log('data: '+msg.data);
+ wsIncomingReply(jsonMsg);
+ } catch(err) {
+ console.log(err);
+ }
+ }
+ };
+ setInterval(wsSendKeepAlive, 90000);
+ }
+}
+
+function wsSendKeepAlive() {
+ if(ws) {
+ ws.send(' ');
+ }
+}
+
+function wsShutdown() {
+ if(ws) {
+ ws.onclose=function(){};
+ ws.close();
+ }
+}
+
+function wsIncomingReply(msg) {
+ var p;
+ if(msg.replyto>0) {
+ p=$('#'+msg.replyto);
+ if(p.length==0) {
+ p=null;
+ }
+ }
+
+ var li=$('<li class="msg reply-new" id="'+msg.rid+'" onclick="onclickNewReply(this)" onmouseover="onclickNewReply(this)">');
+ li.html('<div class="msg-avatar"><a href="/'+msg.user.uname+'/"><img src="//i.juick.com/a/'+msg.user.uid+'.png"/></a></div>'+
+ '<div class="msg-cont">'+
+ '<div class="msg-menu"><a href="#" onclick="showMessageLinksDialog('+msg.mid+','+msg.rid+'); return false"></a></div>'+
+ '<div class="msg-header"><a href="/'+msg.user.uname+'/">@'+msg.user.uname+'</a>:</div>'+
+ '<div class="msg-ts"><a href="/'+msg.mid+'#'+msg.rid+'" title="'+msg.timestamp+' GMT">'+msg.timestamp+'</a></div>'+
+ '<div class="msg-txt">'+msg.body+'</div>'+
+ '<div class="msg-links"><a href="#" onclick="return showCommentForm('+msg.mid+','+msg.rid+')">Ответить</a></div>'+
+ '<div class="msg-comment" style="display: none"></div>'+
+ '</div>');
+
+ if(p) {
+ li.css('margin-left',parseInt(p.css('margin-left'))+20+'px');
+ p.after(li);
+ } else {
+ $('#replies').append(li);
+ }
+
+ updateRepliesCounter();
+}
+
+function onclickNewReply(e) {
+ var li=$(e);
+ li.removeClass('reply-new');
+ li.off('click');
+ li.off('mouseover');
+ updateRepliesCounter();
+}
+
+function onclickNextReply() {
+ var li=$('#replies>li.reply-new:first');
+ if(li.length) {
+ li.removeClass('reply-new');
+ li.off('click');
+ li.get(0).scrollIntoView();
+ updateRepliesCounter();
+ }
+}
+
+function updateRepliesCounter() {
+ var replies=$('#replies>li.reply-new').length;
+ if(replies>0) {
+ $('#wsthread').text(replies).css('display','block');
+ document.title='['+replies+'] '+pageTitle;
+ } else {
+ $('#wsthread').css('display','none');
+ document.title=pageTitle;
+ }
+}
+
+/******************************************************************************/
+/******************************************************************************/
+/******************************************************************************/
+
+function postformListener(formEl,ev) {
+ if(ev.ctrlKey && (ev.keyCode==10 || ev.keyCode==13)) {
+ if(!formEl.onsubmit || formEl.onsubmit()) {
+ formEl.submit();
+ }
+ }
+}
+
+function unfoldPostForm() {
+ if(window.location.pathname==="/" && window.location.hash==="#post") {
+ $('#newmessage>div').css('display','block');
+ $('#newmessage textarea').css('min-height','70px');
+ $('#newmessage textarea')[0].focus();
+ }
+}
+
+function onsubmitNewMessage() {
+ if($('#newmessage .tags').val().length==0) {
+ openDialog('<p class="dialogtxt">Пожалуйста, введите теги сообщения</p>');
+ return false;
+ } else if($('#newmessage textarea').val().length==0) {
+ openDialog('<p class="dialogtxt">Пожалуйста, введите текст сообщения</p>');
+ return false;
+ }
+ return true;
+}
+
+function showMoreReplies(id) {
+ $('#'+id+' .msg-comments').hide();
+
+ var replies=$('#replies>li');
+ var flagshow=0;
+ for(var i=0; i<replies.length; i++) {
+ if(flagshow==1) {
+ if(replies[i].style.display=="none") {
+ replies[i].style.display="block";
+ } else {
+ break;
+ }
+ }
+ if(replies[i].id==id) {
+ flagshow=1;
+ }
+ }
+ return false;
+}
+
+function showCommentForm(mid,rid) {
+ if($('#replies #'+rid+' textarea').length==0) {
+ var c=$('#replies #'+rid+' .msg-comment');
+ c.wrap('<form action="/comment" method="POST" enctype="multipart/form-data"/>');
+ c.before('<input type="hidden" name="mid" value="'+mid+'"/><input type="hidden" name="rid" value="'+rid+'"/>');
+ c.append('<div class="ta-wrapper"><textarea name="body" rows="1" class="reply narrow" placeholder="Add a comment..." onkeypress="postformListener(this.form,event)"></textarea><div class="attach-photo" onclick="attachCommentPhoto(this)"/></div><input type="submit" value="OK"/>');
+ }
+ // $('#replies #'+rid+' .msg-links').hide();
+ $('#replies #'+rid+' .msg-comment').show();
+ $('#replies #'+rid+' textarea')[0].focus();
+ $('#replies #'+rid+' textarea').autoResize({
+ extraSpace: 0,
+ minHeight: 1
+ });
+ return false;
+}
+
+function showCommentFooter(e) {
+ var a=$(e).closest("article");
+ if(a.find("footer.comm").length==0) {
+ a.append('<form action="/comment" method="POST" enctype="multipart/form-data"><input type="hidden" name="mid" value="'+a.data('mid')+'"/><footer class="comm"><div class="ta-wrapper"><textarea name="body" rows="1" class="reply narrow" placeholder="Написать комментарий..." onkeypress="postformListener(this.form,event)"></textarea><div class="attach-photo" onclick="attachCommentPhoto(this)"/></div><input type="submit" value="OK"/></footer></form>');
+ a.find('textarea').autoResize({
+ extraSpace: 0,
+ minHeight: 1
+ });
+ }
+ a.find('textarea')[0].focus();
+ return false;
+}
+
+function attachCommentPhoto(div) {
+ if($(div).children().length===0) {
+ var inp=$('<input type="file" name="attach" accept="image/jpeg,image/png" style="visibility: hidden"/>');
+ inp.on('change',function() {
+ $(this).parent().attr('class','attach-photo-active');
+ });
+ inp.trigger('click');
+ $(div).append(inp);
+ } else {
+ $(div).empty();
+ $(div).attr('class','attach-photo');
+ }
+}
+
+function attachMessagePhoto(div) {
+ var f=$(div).closest('form');
+ if(f.find('input:file').length===0) {
+ var inp=$('<input type="file" name="attach" accept="image/jpeg,image/png" style="float: left; width: 0; height: 0; visibility: hidden"/>');
+ inp.on('change',function() {
+ $(div).text("загрузить (✓)");
+ });
+ f.append(inp);
+ inp.trigger('click');
+ } else {
+ f.find('input:file').remove();
+ $(div).text("загрузить");
+ }
+}
+
+function unfoldReply() {
+ if((0+window.location.hash.substring(1))>0) {
+ var el=$(window.location.hash);
+ while(el.is(":hidden")) {
+ el=el.prev();
+ }
+ showMoreReplies(el.attr('id'));
+ window.location.replace(window.location.hash);
+ }
+}
+
+function showMessageLinksDialog(mid,rid) {
+ var hlink="http://juick.com/"+mid;
+ var mlink="#"+mid;
+ if(rid>0) {
+ hlink+="#"+rid;
+ mlink+="/"+rid;
+ }
+ var hlinkenc=encodeURIComponent(hlink);
+
+ var html="<div class=\"dialogshare\">Ссылка на сообщение:";
+ html+="<div onclick=\"$(this).selectText()\" class=\"dialogl\">"+hlink+"</div>";
+ html+="Номер сообщения:";
+ html+="<div onclick=\"$(this).selectText()\" class=\"dialogl\">"+mlink+"</div>";
+ html+="Поделиться:<ul>";
+ html+="<li><a href=\"https://www.facebook.com/sharer/sharer.php?u="+hlinkenc+"\" onclick=\"return openSocialWindow(this)\"></a></li>";
+ html+="<li><a href=\"https://twitter.com/intent/tweet?url="+hlinkenc+"\" onclick=\"return openSocialWindow(this)\" style=\"background-position: -32px 0;\"></a></li>";
+ html+="<li><a href=\"https://vk.com/share.php?url="+hlinkenc+"\" onclick=\"return openSocialWindow(this)\" style=\"background-position: -64px 0;\"></a></li>";
+ html+="<li><a href=\"https://plus.google.com/share?url="+hlinkenc+"\" onclick=\"return openSocialWindow(this)\" style=\"background-position: -96px 0;\"></a></li>";
+ html+="</ul></div>";
+
+ openDialog(html);
+}
+
+function showPhotoDialog(fname) {
+ var width=$(window).width();
+ var height=$(window).height()*0.9;
+ if(width<640) {
+ return true;
+ } else if(width<1280) {
+ openDialog("<a href=\"//i.juick.com/photos-1024/"+fname+"\"><img src=\"//i.juick.com/photos-512/"+fname+"\"/></a>");
+ $('#dialogw img').css('max-height',height+'px');
+ return false;
+ } else {
+ openDialog("<a href=\"//i.juick.com/p/"+fname+"\"><img src=\"//i.juick.com/photos-1024/"+fname+"\"/></a>");
+ $('#dialogw img').css('max-height',height+'px');
+ return false;
+ }
+}
+
+function openDialog(html) {
+ var dhtml="<table id=\"dialogt\"><tr><td><div id=\"dialogb\" onclick=\"closeDialog()\"></div><div id=\"dialogw\"><div id=\"dialogc\" onclick=\"closeDialog()\"></div>";
+ dhtml+=html;
+ dhtml+="</div></td></tr></table>";
+ $('body').append(dhtml);
+}
+
+function closeDialog() {
+ $('#dialogb').remove();
+ $('#dialogt').remove();
+}
+
+function openSocialWindow(a) {
+ var w=window.open(a.href,'juickshare','width=640,height=400');
+ if(window.focus) w.focus();
+ return false;
+}
+
+function checkUsername() {
+ var uname=$('#username').val();
+ $.ajax('http://api.juick.com/users?uname='+uname).done(function() {
+ $('#username').css('background','#FFCCCC');
+ }).fail(function() {
+ $('#username').css('background','#CCFFCC');
+ });
+}
+
+/******************************************************************************/
+
+function openDialogLogin() {
+ var html='<div class="dialoglogin"><p>Пожалуйста, представьтесь:'
+ +'<a href="/_fblogin" id="signfb">Facebook</a> '
+ +'<a href="/_vklogin" id="signvk">ВКонтакте</a></p>'
+ +'<p>Уже зарегистрированы?</p>'
+ +'<form action="/login" method="POST">'
+ +'<input class="signinput" type="text" name="username" placeholder="Имя пользователя"/><br/>'
+ +'<input class="signinput" type="password" name="password" placeholder="Пароль"/><br/>'
+ +'<input class="signsubmit" type="submit" value="OK"/>'
+ +'</form></div>';
+ openDialog(html);
+ return false;
+}
+
+/******************************************************************************/
+
+function likeMessage(e,mid) {
+ $.ajax({
+ url: 'http://juick.com/like?mid='+mid,
+ type: 'POST'
+ }).done(function() {
+ $(e).closest("article").append("<p>OK!</p>");
+ }).fail(function() {
+ $(e).closest("article").append("<p>Ошибка</p>");
+ });
+ return false;
+}
+
+/******************************************************************************/
+
+function setPopular(e,mid,popular) {
+ $.ajax('http://api.juick.com/messages/set_popular?mid='+mid+'&popular='+popular+'&hash='+hash).done(function() {
+ var a=$(e).closest("article");
+ a.append("<p>OK!</p>");
+ });
+ return false;
+}
+
+function setPrivacy(e,mid) {
+ $.ajax('http://api.juick.com/messages/set_privacy?mid='+mid+'&hash='+hash).done(function() {
+ var a=$(e).closest("article");
+ a.append("<p>OK!</p>");
+ });
+ return false;
+}
+
+/******************************************************************************/
+
+function readerLinkReplace(e) {
+ var a=$(e);
+ a.attr('href','/_out?lid='+a.data('lid'));
+}
+
+/******************************************************************************/
+
+jQuery.fn.selectText = function(){
+ var d = document;
+ if (d.body.createTextRange) {
+ var range = d.body.createTextRange();
+ range.moveToElementText(this[0]);
+ range.select();
+ } else if (window.getSelection) {
+ var selection = window.getSelection();
+ var range = d.createRange();
+ range.selectNodeContents(this[0]);
+ selection.removeAllRanges();
+ selection.addRange(range);
+ }
+};
+
+/*
+ * jQuery.fn.autoResize 1.14
+ */
+
+(function($){
+
+ var uid = 'ar' + +new Date,
+
+ defaults = autoResize.defaults = {
+ onResize: function(){},
+ onBeforeResize: function(){
+ return 123
+ },
+ onAfterResize: function(){
+ return 555
+ },
+ animate: {
+ duration: 200,
+ complete: function(){}
+ },
+ extraSpace: 50,
+ minHeight: 'original',
+ maxHeight: 500,
+ minWidth: 'original',
+ maxWidth: 500
+ };
+
+ autoResize.cloneCSSProperties = [
+ 'lineHeight', 'textDecoration', 'letterSpacing',
+ 'fontSize', 'fontFamily', 'fontStyle', 'fontWeight',
+ 'textTransform', 'textAlign', 'direction', 'wordSpacing', 'fontSizeAdjust',
+ 'paddingTop', 'paddingLeft', 'paddingBottom', 'paddingRight', 'width'
+ ];
+
+ autoResize.cloneCSSValues = {
+ position: 'absolute',
+ top: -9999,
+ left: -9999,
+ opacity: 0,
+ overflow: 'hidden'
+ };
+
+ autoResize.resizableFilterSelector = [
+ 'textarea:not(textarea.' + uid + ')',
+ 'input:not(input[type])',
+ 'input[type=text]',
+ 'input[type=password]',
+ 'input[type=email]',
+ 'input[type=url]'
+ ].join(',');
+
+ autoResize.AutoResizer = AutoResizer;
+
+ $.fn.autoResize = autoResize;
+
+ function autoResize(config) {
+ this.filter(autoResize.resizableFilterSelector).each(function(){
+ new AutoResizer( $(this), config );
+ });
+ return this;
+ }
+
+ function AutoResizer(el, config) {
+
+ if (el.data('AutoResizer')) {
+ el.data('AutoResizer').destroy();
+ }
+
+ config = this.config = $.extend({}, autoResize.defaults, config);
+ this.el = el;
+
+ this.nodeName = el[0].nodeName.toLowerCase();
+
+ this.originalHeight = el.height();
+ this.previousScrollTop = null;
+
+ this.value = el.val();
+
+ if (config.maxWidth === 'original') config.maxWidth = el.width();
+ if (config.minWidth === 'original') config.minWidth = el.width();
+ if (config.maxHeight === 'original') config.maxHeight = el.height();
+ if (config.minHeight === 'original') config.minHeight = el.height();
+
+ if (this.nodeName === 'textarea') {
+ el.css({
+ resize: 'none',
+ overflowY: 'hidden'
+ });
+ }
+
+ el.data('AutoResizer', this);
+
+ // Make sure onAfterResize is called upon animation completion
+ config.animate.complete = (function(f){
+ return function() {
+ config.onAfterResize.call(el);
+ return f.apply(this, arguments);
+ };
+ }(config.animate.complete));
+
+ this.bind();
+
+ }
+
+ AutoResizer.prototype = {
+
+ bind: function() {
+
+ var check = $.proxy(function(){
+ this.check();
+ return true;
+ }, this);
+
+ this.unbind();
+
+ this.el
+ .bind('keyup.autoResize', check)
+ //.bind('keydown.autoResize', check)
+ .bind('change.autoResize', check)
+ .bind('paste.autoResize', function() {
+ setTimeout(function() {
+ check();
+ }, 0);
+ });
+
+ if (!this.el.is(':hidden')) {
+ this.check(null, true);
+ }
+
+ },
+
+ unbind: function() {
+ this.el.unbind('.autoResize');
+ },
+
+ createClone: function() {
+
+ var el = this.el,
+ clone = this.nodeName === 'textarea' ? el.clone() : $('<span/>');
+
+ this.clone = clone;
+
+ $.each(autoResize.cloneCSSProperties, function(i, p){
+ clone[0].style[p] = el.css(p);
+ });
+
+ clone
+ .removeAttr('name')
+ .removeAttr('id')
+ .addClass(uid)
+ .attr('tabIndex', -1)
+ .css(autoResize.cloneCSSValues);
+
+ if (this.nodeName === 'textarea') {
+ clone.height('auto');
+ } else {
+ clone.width('auto').css({
+ whiteSpace: 'nowrap'
+ });
+ }
+
+ },
+
+ check: function(e, immediate) {
+
+ if (!this.clone) {
+ this.createClone();
+ this.injectClone();
+ }
+
+ var config = this.config,
+ clone = this.clone,
+ el = this.el,
+ value = el.val();
+
+ // Do nothing if value hasn't changed
+ if (value === this.prevValue) {
+ return true;
+ }
+ this.prevValue = value;
+
+ if (this.nodeName === 'input') {
+
+ clone.text(value);
+
+ // Calculate new width + whether to change
+ var cloneWidth = clone.width(),
+ newWidth = (cloneWidth + config.extraSpace) >= config.minWidth ?
+ cloneWidth + config.extraSpace : config.minWidth,
+ currentWidth = el.width();
+
+ newWidth = Math.min(newWidth, config.maxWidth);
+
+ if (
+ (newWidth < currentWidth && newWidth >= config.minWidth) ||
+ (newWidth >= config.minWidth && newWidth <= config.maxWidth)
+ ) {
+
+ config.onBeforeResize.call(el);
+ config.onResize.call(el);
+
+ el.scrollLeft(0);
+
+ if (config.animate && !immediate) {
+ el.stop(1,1).animate({
+ width: newWidth
+ }, config.animate);
+ } else {
+ el.width(newWidth);
+ config.onAfterResize.call(el);
+ }
+
+ }
+
+ return;
+
+ }
+
+ // TEXTAREA
+
+ clone.width(el.width()).height(0).val(value).scrollTop(10000);
+
+ var scrollTop = clone[0].scrollTop;
+
+ // Don't do anything if scrollTop hasen't changed:
+ if (this.previousScrollTop === scrollTop) {
+ return;
+ }
+
+ this.previousScrollTop = scrollTop;
+
+ if (scrollTop + config.extraSpace >= config.maxHeight) {
+ el.css('overflowY', '');
+ scrollTop = config.maxHeight;
+ immediate = true;
+ } else if (scrollTop <= config.minHeight) {
+ scrollTop = config.minHeight;
+ } else {
+ el.css('overflowY', 'hidden');
+ scrollTop += config.extraSpace;
+ }
+
+ config.onBeforeResize.call(el);
+ config.onResize.call(el);
+
+ // Either animate or directly apply height:
+ if (config.animate && !immediate) {
+ el.stop(1,1).animate({
+ height: scrollTop
+ }, config.animate);
+ } else {
+ el.height(scrollTop);
+ config.onAfterResize.call(el);
+ }
+
+ },
+
+ destroy: function() {
+ this.unbind();
+ this.el.removeData('AutoResizer');
+ this.clone.remove();
+ delete this.el;
+ delete this.clone;
+ },
+
+ injectClone: function() {
+ (
+ autoResize.cloneContainer ||
+ (autoResize.cloneContainer = $('<arclones/>').appendTo('body'))
+ ).append(this.clone);
+ }
+
+ };
+
+})(jQuery);
+
+/******************************************************************************/
+
+$(document).ready(function() {
+ $('textarea').autoResize({
+ extraSpace: 0,
+ minHeight: 1
+ });
+
+ $('textarea.reply').click(function () {
+ $(this).addClass("narrow");
+ $(this).after('<div class="attach-photo" onclick="attachCommentPhoto(this)"/>');
+ $(this).parent().after('<input type="submit" value="OK"/>');
+ $(this).off('click');
+ });
+
+ $('textarea.replypm').click(function () {
+ $(this).addClass("narrowpm");
+ $(this).parent().after('<input type="submit" value="OK"/>');
+ $(this).off('click');
+ });
+
+ unfoldPostForm();
+ unfoldReply();
+ $(window).bind('hashchange',unfoldPostForm);
+ $(window).bind('hashchange',unfoldReply);
+
+ $(window).on('beforeunload',wsShutdown);
+});