2013-04-22 19:13:39 +00:00
var socket ,
2013-04-23 19:38:48 +00:00
config ,
2013-10-07 12:57:40 -04:00
app = {
'username' : null ,
'uid' : null
} ;
2013-04-22 19:13:39 +00:00
2013-09-24 11:02:06 -04:00
( function ( ) {
2013-08-13 12:58:07 -04:00
var showWelcomeMessage = false ;
2013-10-07 12:57:40 -04:00
2013-09-24 14:56:51 -04:00
app . loadConfig = function ( ) {
2013-08-20 12:31:08 -04:00
2013-07-11 15:50:19 -04:00
$ . ajax ( {
2013-08-13 11:25:10 -04:00
url : RELATIVE _PATH + '/api/config' ,
2013-09-24 11:02:06 -04:00
success : function ( data ) {
2013-07-11 15:50:19 -04:00
config = data ;
2013-09-24 14:56:51 -04:00
if ( socket ) {
socket . disconnect ( ) ;
2013-09-24 15:59:08 -04:00
setTimeout ( function ( ) {
socket . socket . connect ( ) ;
} , 200 ) ;
2013-09-24 14:56:51 -04:00
} else {
2013-10-03 11:34:15 -04:00
socket = io . connect ( RELATIVE _PATH ) ;
2013-09-24 14:56:51 -04:00
2013-09-28 22:05:10 -04:00
var reconnecting = false ,
reconnectEl , reconnectTimer ;
2013-09-24 14:56:51 -04:00
socket . on ( 'event:connect' , function ( data ) {
app . username = data . username ;
2013-10-07 12:57:40 -04:00
app . uid = data . uid ;
2013-09-24 14:56:51 -04:00
app . showLoginMessage ( ) ;
socket . emit ( 'api:updateHeader' , {
2013-09-24 15:59:08 -04:00
fields : [ 'username' , 'picture' , 'userslug' ]
} ) ;
2013-09-24 14:56:51 -04:00
} ) ;
2013-07-25 16:20:18 -04:00
2013-09-24 14:56:51 -04:00
socket . on ( 'event:alert' , function ( data ) {
app . alert ( data ) ;
} ) ;
2013-08-20 12:31:08 -04:00
2013-09-24 14:56:51 -04:00
socket . on ( 'connect' , function ( data ) {
if ( reconnecting ) {
2013-09-28 22:05:10 -04:00
reconnectEl . html ( '<i class="icon-ok"></i> Connected!' ) ;
2013-09-24 14:56:51 -04:00
reconnecting = false ;
2013-09-28 22:05:10 -04:00
setTimeout ( function ( ) {
reconnectEl . removeClass ( 'active' ) ;
} , 3000 ) ;
2013-09-24 14:56:51 -04:00
}
2013-09-24 15:59:08 -04:00
socket . emit ( 'api:updateHeader' , {
fields : [ 'username' , 'picture' , 'userslug' ]
} ) ;
} ) ;
socket . on ( 'event:disconnect' , function ( ) {
socket . socket . connect ( ) ;
2013-09-24 14:56:51 -04:00
} ) ;
2013-08-20 12:31:08 -04:00
2013-09-24 14:56:51 -04:00
socket . on ( 'reconnecting' , function ( data ) {
2013-09-28 22:05:10 -04:00
if ( ! reconnectEl ) reconnectEl = $ ( '#reconnect' ) ;
2013-09-24 14:56:51 -04:00
reconnecting = true ;
2013-08-20 12:31:08 -04:00
2013-09-28 22:05:10 -04:00
reconnectEl . addClass ( 'active' ) ;
reconnectEl . html ( '<i class="icon-spinner icon-spin"></i> Reconnecting...' ) ;
2013-07-11 15:50:19 -04:00
} ) ;
2013-08-20 12:31:08 -04:00
2013-09-24 14:56:51 -04:00
socket . on ( 'api:user.get_online_users' , function ( users ) {
jQuery ( 'a.username-field' ) . each ( function ( ) {
if ( this . processed === true )
return ;
2013-08-20 12:31:08 -04:00
2013-09-24 14:56:51 -04:00
var el = jQuery ( this ) ,
uid = el . parents ( 'li' ) . attr ( 'data-uid' ) ;
2013-08-20 12:31:08 -04:00
2013-09-24 14:56:51 -04:00
if ( uid && jQuery . inArray ( uid , users ) !== - 1 ) {
el . find ( 'i' ) . remove ( ) ;
el . prepend ( '<i class="icon-circle"></i>' ) ;
} else {
el . find ( 'i' ) . remove ( ) ;
el . prepend ( '<i class="icon-circle-blank"></i>' ) ;
}
2013-08-20 12:31:08 -04:00
2013-09-24 14:56:51 -04:00
el . processed = true ;
} ) ;
jQuery ( 'button .username-field' ) . each ( function ( ) {
//DRY FAIL
if ( this . processed === true )
return ;
2013-08-24 04:34:13 +08:00
2013-09-24 14:56:51 -04:00
var el = jQuery ( this ) ,
uid = el . parents ( 'li' ) . attr ( 'data-uid' ) ;
2013-08-24 04:34:13 +08:00
2013-09-24 14:56:51 -04:00
if ( uid && jQuery . inArray ( uid , users ) !== - 1 ) {
el . parent ( ) . addClass ( 'btn-success' ) ;
} else {
el . parent ( ) . addClass ( 'btn-danger' ) ;
}
2013-08-24 04:34:13 +08:00
2013-09-24 14:56:51 -04:00
el . processed = true ;
} ) ;
2013-07-11 15:50:19 -04:00
} ) ;
2013-07-15 13:49:21 -04:00
2013-09-24 14:56:51 -04:00
app . enter _room ( 'global' ) ;
}
2013-07-11 15:50:19 -04:00
} ,
async : false
} ) ;
}
2013-08-20 12:31:08 -04:00
2013-05-16 15:45:32 -04:00
// takes a string like 1000 and returns 1,000
2013-09-24 11:02:06 -04:00
app . addCommas = function ( text ) {
2013-06-20 16:48:17 -04:00
return text . replace ( /(\d)(?=(\d\d\d)+(?!\d))/g , "$1," ) ;
}
2013-05-16 15:45:32 -04:00
2013-06-20 16:48:17 -04:00
// Willingly stolen from: http://phpjs.org/functions/strip_tags/
2013-09-24 11:02:06 -04:00
app . strip _tags = function ( input , allowed ) {
2013-05-22 17:14:06 -04:00
allowed = ( ( ( allowed || "" ) + "" ) . toLowerCase ( ) . match ( /<[a-z][a-z0-9]*>/g ) || [ ] ) . join ( '' ) ; // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
2013-09-17 13:03:53 -04:00
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi ,
2013-05-22 17:14:06 -04:00
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi ;
2013-09-24 11:02:06 -04:00
return input . replace ( commentsAndPhpTags , '' ) . replace ( tags , function ( $0 , $1 ) {
2013-05-22 17:14:06 -04:00
return allowed . indexOf ( '<' + $1 . toLowerCase ( ) + '>' ) > - 1 ? $0 : '' ;
} ) ;
}
2013-08-20 12:31:08 -04:00
// use unique alert_id to have multiple alerts visible at a time, use the same alert_id to fade out the current instance
2013-04-23 19:38:48 +00:00
// type : error, success, info, warning/notify
2013-05-07 15:36:32 -04:00
// title = bolded title text
// message = alert message content
2013-04-23 19:38:48 +00:00
// timeout default = permanent
2013-05-23 10:53:09 -04:00
// location : alert_window (default) or content
2013-09-24 11:02:06 -04:00
app . alert = function ( params ) {
2013-08-20 12:31:08 -04:00
var alert _id = 'alert_button_' + ( ( params . alert _id ) ? params . alert _id : new Date ( ) . getTime ( ) ) ;
2013-04-23 19:38:48 +00:00
2013-09-17 13:03:53 -04:00
var alert = $ ( '#' + alert _id ) ;
2013-04-23 19:38:48 +00:00
2013-06-21 17:48:12 -04:00
function startTimeout ( div , timeout ) {
2013-09-24 11:02:06 -04:00
var timeoutId = setTimeout ( function ( ) {
$ ( div ) . fadeOut ( 1000 , function ( ) {
2013-06-24 15:34:44 -04:00
$ ( this ) . remove ( ) ;
2013-06-21 17:48:12 -04:00
} ) ;
} , timeout ) ;
2013-08-20 12:31:08 -04:00
2013-06-21 17:48:12 -04:00
$ ( div ) . attr ( 'timeoutId' , timeoutId ) ;
}
2013-09-17 13:03:53 -04:00
if ( alert . length > 0 ) {
2013-05-23 12:25:40 -04:00
alert . find ( 'strong' ) . html ( params . title ) ;
alert . find ( 'p' ) . html ( params . message ) ;
2013-08-27 05:16:49 +08:00
alert . attr ( 'class' , "alert toaster-alert " + "alert-" + params . type ) ;
2013-08-20 12:31:08 -04:00
2013-06-21 17:48:12 -04:00
clearTimeout ( alert . attr ( 'timeoutId' ) ) ;
startTimeout ( alert , params . timeout ) ;
2013-09-17 13:03:53 -04:00
} else {
2013-05-23 12:25:40 -04:00
var div = document . createElement ( 'div' ) ,
button = document . createElement ( 'button' ) ,
strong = document . createElement ( 'strong' ) ,
p = document . createElement ( 'p' ) ;
2013-04-23 19:38:48 +00:00
2013-05-23 12:25:40 -04:00
p . innerHTML = params . message ;
strong . innerHTML = params . title ;
2013-04-23 19:38:48 +00:00
2013-08-27 05:16:49 +08:00
div . className = "alert toaster-alert " + "alert-" + params . type ;
2013-08-20 12:31:08 -04:00
2013-05-23 12:25:40 -04:00
div . setAttribute ( 'id' , alert _id ) ;
div . appendChild ( button ) ;
div . appendChild ( strong ) ;
div . appendChild ( p ) ;
button . className = 'close' ;
button . innerHTML = '×' ;
2013-09-24 11:02:06 -04:00
button . onclick = function ( ev ) {
2013-05-23 12:25:40 -04:00
div . parentNode . removeChild ( div ) ;
}
2013-04-24 20:40:34 +00:00
2013-08-20 12:31:08 -04:00
if ( params . location == null )
2013-05-23 12:56:55 -04:00
params . location = 'alert_window' ;
2013-05-23 12:25:40 -04:00
2013-09-17 13:03:53 -04:00
jQuery ( '#' + params . location ) . prepend ( jQuery ( div ) . fadeIn ( '100' ) ) ;
2013-05-23 12:25:40 -04:00
if ( params . timeout ) {
2013-06-21 17:48:12 -04:00
startTimeout ( div , params . timeout ) ;
2013-05-23 12:25:40 -04:00
}
if ( params . clickfn ) {
2013-09-24 11:02:06 -04:00
div . onclick = function ( ) {
2013-05-23 12:25:40 -04:00
params . clickfn ( ) ;
2013-09-24 11:02:06 -04:00
jQuery ( div ) . fadeOut ( 500 , function ( ) {
2013-05-23 12:25:40 -04:00
this . remove ( ) ;
} ) ;
}
2013-04-24 20:40:34 +00:00
}
}
2013-04-23 19:38:48 +00:00
}
2013-09-24 11:02:06 -04:00
app . alertSuccess = function ( message , timeout ) {
2013-09-17 13:03:53 -04:00
if ( ! timeout )
2013-07-30 18:30:43 -04:00
timeout = 2000 ;
app . alert ( {
title : 'Success' ,
message : message ,
type : 'success' ,
timeout : timeout
} ) ;
}
2013-09-24 11:02:06 -04:00
app . alertError = function ( message , timeout ) {
2013-09-17 13:03:53 -04:00
if ( ! timeout )
2013-07-30 18:30:43 -04:00
timeout = 2000 ;
app . alert ( {
title : 'Error' ,
message : message ,
2013-08-24 03:36:44 +08:00
type : 'danger' ,
2013-07-30 18:30:43 -04:00
timeout : timeout
} ) ;
}
2013-06-21 17:48:12 -04:00
2013-08-20 12:31:08 -04:00
app . current _room = null ;
2013-09-24 11:02:06 -04:00
app . enter _room = function ( room ) {
2013-09-17 13:03:53 -04:00
if ( socket ) {
2013-08-20 12:31:08 -04:00
if ( app . current _room === room )
2013-07-14 21:58:11 -04:00
return ;
2013-08-20 12:31:08 -04:00
2013-07-14 21:58:11 -04:00
socket . emit ( 'event:enter_room' , {
'enter' : room ,
'leave' : app . current _room
} ) ;
2013-08-20 12:31:08 -04:00
2013-07-14 21:58:11 -04:00
app . current _room = room ;
}
2013-05-05 20:10:26 +00:00
} ;
2013-09-24 11:02:06 -04:00
app . populate _online _users = function ( ) {
2013-07-17 12:57:57 -04:00
var uids = [ ] ;
2013-05-21 17:02:04 -04:00
2013-09-24 11:02:06 -04:00
jQuery ( '.post-row' ) . each ( function ( ) {
2013-07-17 12:57:57 -04:00
uids . push ( this . getAttribute ( 'data-uid' ) ) ;
} ) ;
2013-08-20 12:31:08 -04:00
2013-07-17 12:57:57 -04:00
socket . emit ( 'api:user.get_online_users' , uids ) ;
}
2013-05-21 17:02:04 -04:00
2013-09-24 11:02:06 -04:00
app . process _page = function ( ) {
2013-05-21 17:02:04 -04:00
2013-06-05 17:00:58 -04:00
// here is where all modules' onNavigate should be called, I think.
2013-09-24 11:02:06 -04:00
require ( [ 'mobileMenu' ] , function ( mobileMenu ) {
2013-06-05 17:00:58 -04:00
mobileMenu . onNavigate ( ) ;
} ) ;
2013-07-17 12:57:57 -04:00
app . populate _online _users ( ) ;
2013-05-21 17:02:04 -04:00
2013-07-22 18:29:09 -04:00
var url = window . location . href ,
parts = url . split ( '/' ) ,
2013-09-17 13:03:53 -04:00
active = parts [ parts . length - 1 ] ;
2013-08-20 12:31:08 -04:00
2013-07-24 12:33:37 -04:00
jQuery ( '#main-nav li' ) . removeClass ( 'active' ) ;
2013-09-17 13:03:53 -04:00
if ( active ) {
2013-09-24 11:02:06 -04:00
jQuery ( '#main-nav li a' ) . each ( function ( ) {
2013-07-22 18:29:09 -04:00
var href = this . getAttribute ( 'href' ) ;
2013-09-23 13:43:15 -04:00
if ( active == "sort-posts" || active == "sort-reputation" || active == "search" || active == "latest" || active == "online" )
2013-07-22 18:29:09 -04:00
active = 'users' ;
2013-07-24 12:33:37 -04:00
if ( href && href . match ( active ) ) {
2013-07-22 18:29:09 -04:00
jQuery ( this . parentNode ) . addClass ( 'active' ) ;
return false ;
}
} ) ;
}
2013-09-19 15:02:35 -04:00
$ ( 'span.timeago' ) . timeago ( ) ;
2013-09-23 14:40:31 -04:00
2013-09-24 11:02:06 -04:00
setTimeout ( function ( ) {
2013-08-20 12:31:08 -04:00
window . scrollTo ( 0 , 1 ) ; // rehide address bar on mobile after page load completes.
2013-06-05 17:14:10 -04:00
} , 100 ) ;
2013-05-21 17:02:04 -04:00
}
2013-09-24 11:02:06 -04:00
app . showLoginMessage = function ( ) {
2013-07-30 18:30:43 -04:00
function showAlert ( ) {
2013-07-25 16:20:18 -04:00
app . alert ( {
type : 'success' ,
title : 'Welcome Back ' + app . username + '!' ,
message : 'You have successfully logged in!' ,
timeout : 5000
} ) ;
}
2013-08-20 12:31:08 -04:00
2013-09-17 13:03:53 -04:00
if ( showWelcomeMessage ) {
2013-08-13 12:58:07 -04:00
showWelcomeMessage = false ;
2013-09-17 13:03:53 -04:00
if ( document . readyState !== 'complete' ) {
2013-07-30 18:30:43 -04:00
$ ( document ) . ready ( showAlert ) ;
} else {
showAlert ( ) ;
}
}
2013-07-25 16:20:18 -04:00
}
2013-09-24 11:02:06 -04:00
app . addCommasToNumbers = function ( ) {
$ ( '.formatted-number' ) . each ( function ( index , element ) {
2013-08-01 16:11:00 -04:00
$ ( element ) . html ( app . addCommas ( $ ( element ) . html ( ) ) ) ;
} ) ;
}
2013-09-24 11:02:06 -04:00
app . openChat = function ( username , touid ) {
require ( [ 'chat' ] , function ( chat ) {
2013-08-30 14:25:59 -04:00
var chatModal ;
2013-09-17 13:03:53 -04:00
if ( ! chat . modalExists ( touid ) ) {
2013-08-30 14:25:59 -04:00
chatModal = chat . createModal ( username , touid ) ;
} else {
chatModal = chat . getModal ( touid ) ;
}
chat . load ( chatModal . attr ( 'UUID' ) ) ;
} ) ;
}
2013-09-24 11:02:06 -04:00
app . createNewPosts = function ( data ) {
2013-08-01 16:11:00 -04:00
data . posts [ 0 ] . display _moderator _tools = 'none' ;
2013-09-25 12:16:00 -04:00
var html = templates . prepare ( templates [ 'topic' ] . blocks [ 'posts' ] ) . parse ( data ) ;
translator . translate ( html , function ( translatedHTML ) {
var uniqueid = new Date ( ) . getTime ( ) ,
tempContainer = jQuery ( '<div id="' + uniqueid + '"></div>' )
. appendTo ( "#post-container" )
. hide ( )
. append ( translatedHTML )
. fadeIn ( 'slow' ) ;
for ( var x = 0 , numPosts = data . posts . length ; x < numPosts ; x ++ ) {
socket . emit ( 'api:post.privileges' , data . posts [ x ] . pid ) ;
}
2013-08-01 16:11:00 -04:00
2013-09-25 12:16:00 -04:00
tempContainer . replaceWith ( tempContainer . contents ( ) ) ;
infiniteLoaderActive = false ;
2013-08-01 16:11:00 -04:00
2013-09-25 12:16:00 -04:00
app . populate _online _users ( ) ;
app . addCommasToNumbers ( ) ;
$ ( 'span.timeago' ) . timeago ( ) ;
} ) ;
2013-08-01 16:11:00 -04:00
}
app . infiniteLoaderActive = false ;
2013-09-24 11:02:06 -04:00
app . loadMorePosts = function ( tid , callback ) {
2013-09-17 13:03:53 -04:00
if ( app . infiniteLoaderActive )
2013-08-01 16:11:00 -04:00
return ;
2013-08-01 17:27:37 -04:00
app . infiniteLoaderActive = true ;
2013-09-03 12:18:26 -04:00
2013-09-17 13:03:53 -04:00
if ( $ ( '#loading-indicator' ) . attr ( 'done' ) === '0' )
2013-09-03 12:18:26 -04:00
$ ( '#loading-indicator' ) . removeClass ( 'hide' ) ;
2013-08-20 12:31:08 -04:00
socket . emit ( 'api:topic.loadMore' , {
tid : tid ,
after : document . querySelectorAll ( '#post-container li[data-pid]' ) . length
2013-09-24 11:02:06 -04:00
} , function ( data ) {
2013-08-01 16:11:00 -04:00
app . infiniteLoaderActive = false ;
2013-09-17 13:03:53 -04:00
if ( data . posts . length ) {
2013-09-03 12:18:26 -04:00
$ ( '#loading-indicator' ) . attr ( 'done' , '0' ) ;
2013-08-01 16:11:00 -04:00
app . createNewPosts ( data ) ;
2013-09-03 12:18:26 -04:00
} else {
$ ( '#loading-indicator' ) . attr ( 'done' , '1' ) ;
2013-08-01 16:11:00 -04:00
}
2013-09-03 12:18:26 -04:00
$ ( '#loading-indicator' ) . addClass ( 'hide' ) ;
2013-09-17 13:03:53 -04:00
if ( callback )
2013-08-21 19:57:11 -04:00
callback ( data . posts ) ;
2013-08-01 16:11:00 -04:00
} ) ;
}
2013-09-24 11:02:06 -04:00
app . scrollToTop = function ( ) {
2013-09-04 04:50:45 +08:00
$ ( 'body,html' ) . animate ( {
scrollTop : 0
} ) ;
} ;
2013-09-24 11:02:06 -04:00
app . scrollToBottom = function ( ) {
2013-09-04 04:50:45 +08:00
$ ( 'body,html' ) . animate ( {
scrollTop : $ ( 'html' ) . height ( ) - 100
} ) ;
}
2013-09-24 11:02:06 -04:00
app . scrollToPost = function ( pid ) {
2013-08-21 19:57:11 -04:00
2013-09-17 13:03:53 -04:00
if ( ! pid )
2013-08-01 16:11:00 -04:00
return ;
2013-08-21 19:21:49 -04:00
2013-08-01 16:11:00 -04:00
var container = $ ( document . body ) ,
2013-08-20 12:31:08 -04:00
scrollTo = $ ( '#post_anchor_' + pid ) ,
tid = $ ( '#post-container' ) . attr ( 'data-tid' ) ;
2013-08-01 16:11:00 -04:00
2013-08-21 19:57:11 -04:00
function animateScroll ( ) {
2013-08-21 19:21:49 -04:00
$ ( 'body,html' ) . animate ( {
scrollTop : scrollTo . offset ( ) . top - container . offset ( ) . top + container . scrollTop ( ) - $ ( '#header-menu' ) . height ( )
2013-09-24 14:56:51 -04:00
} , 400 ) ;
//$('body,html').scrollTop(scrollTo.offset().top - container.offset().top + container.scrollTop() - $('#header-menu').height());
2013-08-21 19:21:49 -04:00
}
2013-08-21 19:57:11 -04:00
2013-09-17 13:03:53 -04:00
if ( ! scrollTo . length && tid ) {
2013-08-23 13:45:57 -04:00
2013-09-24 11:02:06 -04:00
var intervalID = setInterval ( function ( ) {
app . loadMorePosts ( tid , function ( posts ) {
2013-08-21 19:57:11 -04:00
scrollTo = $ ( '#post_anchor_' + pid ) ;
2013-08-23 13:45:57 -04:00
2013-09-17 13:03:53 -04:00
if ( tid && scrollTo . length ) {
2013-08-23 13:45:57 -04:00
animateScroll ( ) ;
2013-08-21 19:57:11 -04:00
}
2013-08-23 13:45:57 -04:00
2013-09-17 13:03:53 -04:00
if ( ! posts . length || scrollTo . length )
2013-08-21 19:57:11 -04:00
clearInterval ( intervalID ) ;
} ) ;
} , 100 ) ;
2013-08-23 13:45:57 -04:00
2013-09-17 13:03:53 -04:00
} else if ( tid ) {
2013-08-21 19:57:11 -04:00
animateScroll ( ) ;
}
2013-08-01 16:11:00 -04:00
}
2013-09-24 11:02:06 -04:00
jQuery ( 'document' ) . ready ( function ( ) {
$ ( '#search-form' ) . on ( 'submit' , function ( ) {
2013-08-03 20:54:16 -04:00
var input = $ ( this ) . find ( 'input' ) ;
2013-09-17 13:03:53 -04:00
ajaxify . go ( "search/" + input . val ( ) , null , "search" ) ;
2013-08-03 20:54:16 -04:00
input . val ( '' ) ;
return false ;
2013-09-23 14:40:31 -04:00
} ) ;
2013-05-17 12:42:20 -04:00
} ) ;
2013-06-05 17:59:20 -04:00
2013-08-13 12:58:07 -04:00
showWelcomeMessage = location . href . indexOf ( 'loggedin' ) !== - 1 ;
2013-09-24 14:56:51 -04:00
app . loadConfig ( ) ;
2013-06-05 17:59:20 -04:00
2013-09-17 13:03:53 -04:00
} ( ) ) ;