2014-01-24 22:26:11 -05:00
define ( [ 'composer' , 'forum/pagination' ] , function ( composer , pagination ) {
2013-11-23 17:07:31 -05:00
var Topic = { } ,
2014-01-27 19:58:03 -05:00
infiniteLoaderActive = false ;
2013-08-23 13:45:57 -04:00
2013-11-29 14:42:58 -05:00
function showBottomPostBar ( ) {
2014-01-25 19:19:25 -05:00
if ( $ ( '#post-container .post-row' ) . length > 1 || ! $ ( '#post-container li[data-index="0"]' ) . length ) {
$ ( '.bottom-post-bar' ) . removeClass ( 'hide' ) ;
2013-11-29 14:42:58 -05:00
}
}
2014-02-12 15:44:48 -05:00
$ ( window ) . on ( 'action:ajaxify.start' , function ( ev , data ) {
2014-02-14 21:41:53 -05:00
if ( data . url . indexOf ( 'topic' ) !== 0 ) {
2014-01-27 19:58:03 -05:00
$ ( '.pagination-block' ) . addClass ( 'hide' ) ;
2014-02-12 15:44:48 -05:00
$ ( '#header-topic-title' ) . html ( '' ) . hide ( ) ;
2014-01-27 19:58:03 -05:00
}
} ) ;
2013-10-03 15:04:25 -04:00
Topic . init = function ( ) {
2014-02-17 20:57:12 -05:00
2013-10-03 15:04:25 -04:00
var expose _tools = templates . get ( 'expose_tools' ) ,
tid = templates . get ( 'topic_id' ) ,
thread _state = {
locked : templates . get ( 'locked' ) ,
deleted : templates . get ( 'deleted' ) ,
pinned : templates . get ( 'pinned' )
} ,
2014-01-24 20:00:56 -05:00
topic _name = templates . get ( 'topic_name' ) ,
currentPage = parseInt ( templates . get ( 'currentPage' ) , 10 ) ,
2014-01-24 21:01:28 -05:00
pageCount = parseInt ( templates . get ( 'pageCount' ) , 10 ) ;
Topic . postCount = templates . get ( 'postcount' ) ;
2013-05-29 12:17:44 -04:00
2014-02-08 00:53:35 -05:00
$ ( window ) . trigger ( 'action:topic.loading' ) ;
2013-05-29 12:17:44 -04:00
2013-11-20 12:22:59 -05:00
function fixDeleteStateForPosts ( ) {
var postEls = document . querySelectorAll ( '#post-container li[data-deleted]' ) ;
for ( var x = 0 , numPosts = postEls . length ; x < numPosts ; x ++ ) {
if ( postEls [ x ] . getAttribute ( 'data-deleted' ) === '1' ) {
toggle _post _delete _state ( postEls [ x ] . getAttribute ( 'data-pid' ) ) ;
}
postEls [ x ] . removeAttribute ( 'data-deleted' ) ;
}
}
2013-10-03 15:04:25 -04:00
jQuery ( 'document' ) . ready ( function ( ) {
2013-08-23 13:45:57 -04:00
2013-10-03 15:04:25 -04:00
app . addCommasToNumbers ( ) ;
2013-05-29 12:17:44 -04:00
2013-11-23 17:07:31 -05:00
app . enterRoom ( 'topic_' + tid ) ;
2013-10-25 18:00:08 -04:00
2013-11-29 14:42:58 -05:00
showBottomPostBar ( ) ;
2013-10-25 18:00:08 -04:00
2013-10-03 15:04:25 -04:00
if ( thread _state . locked === '1' ) set _locked _state ( true ) ;
if ( thread _state . deleted === '1' ) set _delete _state ( true ) ;
if ( thread _state . pinned === '1' ) set _pinned _state ( true ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
if ( expose _tools === '1' ) {
var moveThreadModal = $ ( '#move_thread_modal' ) ;
2013-11-21 13:53:19 -05:00
$ ( '.thread-tools' ) . removeClass ( 'hide' ) ;
2013-10-03 15:04:25 -04:00
// Add events to the thread tools
2013-11-21 13:53:19 -05:00
$ ( '.delete_thread' ) . on ( 'click' , function ( e ) {
2013-10-03 15:04:25 -04:00
if ( thread _state . deleted !== '1' ) {
bootbox . confirm ( 'Are you sure you want to delete this thread?' , function ( confirm ) {
2013-10-16 12:56:37 -04:00
if ( confirm ) {
2014-01-16 19:58:57 -05:00
socket . emit ( 'topics.delete' , tid ) ;
2013-10-16 12:56:37 -04:00
}
2013-10-03 15:04:25 -04:00
} ) ;
} else {
bootbox . confirm ( 'Are you sure you want to restore this thread?' , function ( confirm ) {
2014-01-16 19:58:57 -05:00
if ( confirm ) {
socket . emit ( 'topics.restore' , tid ) ;
}
2013-10-03 15:04:25 -04:00
} ) ;
}
return false ;
} ) ;
2013-11-21 13:53:19 -05:00
$ ( '.lock_thread' ) . on ( 'click' , function ( e ) {
2013-10-03 15:04:25 -04:00
if ( thread _state . locked !== '1' ) {
2014-01-16 19:58:57 -05:00
socket . emit ( 'topics.lock' , tid ) ;
2013-10-03 15:04:25 -04:00
} else {
2014-01-16 19:58:57 -05:00
socket . emit ( 'topics.unlock' , tid ) ;
2013-10-03 15:04:25 -04:00
}
return false ;
} ) ;
2013-05-29 12:17:44 -04:00
2013-11-21 13:53:19 -05:00
$ ( '.pin_thread' ) . on ( 'click' , function ( e ) {
2013-10-03 15:04:25 -04:00
if ( thread _state . pinned !== '1' ) {
2014-01-16 19:58:57 -05:00
socket . emit ( 'topics.pin' , tid ) ;
2013-10-03 15:04:25 -04:00
} else {
2014-01-16 19:58:57 -05:00
socket . emit ( 'topics.unpin' , tid ) ;
2013-10-03 15:04:25 -04:00
}
return false ;
} ) ;
2013-05-29 12:17:44 -04:00
2013-11-21 13:53:19 -05:00
$ ( '.move_thread' ) . on ( 'click' , function ( e ) {
2013-10-03 15:04:25 -04:00
moveThreadModal . modal ( 'show' ) ;
return false ;
} ) ;
2013-05-29 12:17:44 -04:00
2014-01-17 17:26:07 -05:00
$ ( '.markAsUnreadForAll' ) . on ( 'click' , function ( ) {
2014-02-11 18:58:46 -05:00
var btn = $ ( this ) ;
2014-01-17 17:26:07 -05:00
socket . emit ( 'topics.markAsUnreadForAll' , tid , function ( err ) {
if ( err ) {
return app . alertError ( err . message ) ;
}
2014-02-11 18:58:46 -05:00
btn . parents ( '.thread-tools.open' ) . find ( '.dropdown-toggle' ) . trigger ( 'click' ) ;
2014-01-17 17:26:07 -05:00
} ) ;
return false ;
} )
2013-10-03 15:04:25 -04:00
moveThreadModal . on ( 'shown.bs.modal' , function ( ) {
var loadingEl = document . getElementById ( 'categories-loading' ) ;
if ( loadingEl ) {
2014-01-16 19:57:28 -05:00
socket . emit ( 'categories.get' , function ( err , data ) {
2013-10-03 15:04:25 -04:00
// Render categories
var categoriesFrag = document . createDocumentFragment ( ) ,
categoryEl = document . createElement ( 'li' ) ,
numCategories = data . categories . length ,
modalBody = moveThreadModal . find ( '.modal-body' ) ,
categoriesEl = modalBody [ 0 ] . getElementsByTagName ( 'ul' ) [ 0 ] ,
confirmDiv = document . getElementById ( 'move-confirm' ) ,
confirmCat = confirmDiv . getElementsByTagName ( 'span' ) [ 0 ] ,
commitEl = document . getElementById ( 'move_thread_commit' ) ,
cancelEl = document . getElementById ( 'move_thread_cancel' ) ,
x , info , targetCid , targetCatLabel ;
categoriesEl . className = 'category-list' ;
for ( x = 0 ; x < numCategories ; x ++ ) {
info = data . categories [ x ] ;
2013-11-26 15:14:12 -05:00
categoryEl . style . background = info . bgColor ;
categoryEl . style . color = info . color || '#fff' ;
categoryEl . className = info . disabled === '1' ? ' disabled' : '' ;
2013-11-26 14:37:27 -05:00
categoryEl . innerHTML = '<i class="fa ' + info . icon + '"></i> ' + info . name ;
2013-10-03 15:04:25 -04:00
categoryEl . setAttribute ( 'data-cid' , info . cid ) ;
categoriesFrag . appendChild ( categoryEl . cloneNode ( true ) ) ;
2013-05-29 12:17:44 -04:00
}
2013-10-03 15:04:25 -04:00
categoriesEl . appendChild ( categoriesFrag ) ;
modalBody [ 0 ] . removeChild ( loadingEl ) ;
categoriesEl . addEventListener ( 'click' , function ( e ) {
if ( e . target . nodeName === 'LI' ) {
confirmCat . innerHTML = e . target . innerHTML ;
confirmDiv . style . display = 'block' ;
targetCid = e . target . getAttribute ( 'data-cid' ) ;
targetCatLabel = e . target . innerHTML ;
commitEl . disabled = false ;
}
} , false ) ;
commitEl . addEventListener ( 'click' , function ( ) {
if ( ! commitEl . disabled && targetCid ) {
commitEl . disabled = true ;
$ ( cancelEl ) . fadeOut ( 250 ) ;
$ ( moveThreadModal ) . find ( '.modal-header button' ) . fadeOut ( 250 ) ;
2013-11-26 14:25:46 -05:00
commitEl . innerHTML = 'Moving <i class="fa-spin fa-refresh"></i>' ;
2013-10-03 15:04:25 -04:00
2014-01-16 15:10:37 -05:00
socket . emit ( 'topics.move' , {
2014-01-10 10:46:26 -05:00
tid : tid ,
cid : targetCid
2014-01-16 20:53:32 -05:00
} , function ( err ) {
2013-10-03 15:04:25 -04:00
moveThreadModal . modal ( 'hide' ) ;
2014-01-16 20:53:32 -05:00
if ( err ) {
return app . alert ( {
2013-10-03 15:04:25 -04:00
'alert_id' : 'thread_move' ,
type : 'danger' ,
title : 'Unable to Move Topic' ,
message : 'This topic could not be moved to ' + targetCatLabel + '.<br />Please try again later' ,
timeout : 5000
} ) ;
}
2014-01-16 20:53:32 -05:00
app . alert ( {
'alert_id' : 'thread_move' ,
type : 'success' ,
title : 'Topic Successfully Moved' ,
message : 'This topic has been successfully moved to ' + targetCatLabel ,
timeout : 5000
} ) ;
2013-10-03 15:04:25 -04:00
} ) ;
}
} ) ;
2013-05-29 12:17:44 -04:00
} ) ;
2013-10-03 15:04:25 -04:00
}
} ) ;
2014-01-06 17:37:42 -05:00
$ ( '.fork_thread' ) . on ( 'click' , function ( ) {
var pids = [ ] ;
var forkModal = $ ( '#fork-thread-modal' ) ,
forkCommit = forkModal . find ( '#fork_thread_commit' ) ;
forkModal . removeClass ( 'hide' ) ;
forkModal . css ( "position" , "fixed" )
. css ( "left" , Math . max ( 0 , ( ( $ ( window ) . width ( ) - $ ( forkModal ) . outerWidth ( ) ) / 2 ) + $ ( window ) . scrollLeft ( ) ) + "px" )
. css ( "top" , "0px" )
. css ( "z-index" , "2000" ) ;
showNoPostsSelected ( ) ;
forkModal . find ( '.close,#fork_thread_cancel' ) . on ( 'click' , closeForkModal ) ;
forkModal . find ( '#fork-title' ) . on ( 'change' , checkForkButtonEnable ) ;
$ ( '#post-container' ) . on ( 'click' , 'li' , togglePostSelection ) ;
forkCommit . on ( 'click' , createTopicFromPosts ) ;
function createTopicFromPosts ( ) {
2014-01-16 15:10:37 -05:00
socket . emit ( 'topics.createTopicFromPosts' , {
2014-01-06 17:37:42 -05:00
title : forkModal . find ( '#fork-title' ) . val ( ) ,
pids : pids
} , function ( err ) {
if ( err ) {
return app . alertError ( err . message ) ;
}
translator . get ( 'topic:fork_success' , function ( translated ) {
app . alertSuccess ( translated ) ;
} ) ;
for ( var i = 0 ; i < pids . length ; ++ i ) {
$ ( '#post-container li[data-pid="' + pids [ i ] + '"]' ) . fadeOut ( 500 , function ( ) {
$ ( this ) . remove ( ) ;
} ) ;
}
closeForkModal ( ) ;
} ) ;
}
function togglePostSelection ( ) {
var newPid = $ ( this ) . attr ( 'data-pid' ) ;
if ( $ ( this ) . attr ( 'data-index' ) === '0' ) {
return ;
}
if ( newPid ) {
var index = pids . indexOf ( newPid ) ;
if ( index === - 1 ) {
pids . push ( newPid ) ;
$ ( this ) . css ( 'opacity' , '0.5' ) ;
} else {
pids . splice ( index , 1 ) ;
$ ( this ) . css ( 'opacity' , '1.0' ) ;
}
if ( pids . length ) {
pids . sort ( ) ;
forkModal . find ( '#fork-pids' ) . html ( pids . toString ( ) ) ;
} else {
showNoPostsSelected ( ) ;
}
checkForkButtonEnable ( ) ;
}
}
function closeForkModal ( ) {
for ( var i = 0 ; i < pids . length ; ++ i ) {
$ ( '#post-container li[data-pid="' + pids [ i ] + '"]' ) . css ( 'opacity' , 1.0 ) ;
}
forkModal . addClass ( 'hide' ) ;
$ ( '#post-container' ) . off ( 'click' , 'li' ) ;
}
function checkForkButtonEnable ( ) {
if ( forkModal . find ( '#fork-title' ) . length && pids . length ) {
forkCommit . removeAttr ( 'disabled' ) ;
} else {
forkCommit . attr ( 'disabled' , true ) ;
}
}
function showNoPostsSelected ( ) {
translator . get ( 'topic:fork_no_pids' , function ( translated ) {
forkModal . find ( '#fork-pids' ) . html ( translated ) ;
} ) ;
}
} ) ;
2013-10-03 15:04:25 -04:00
}
2013-11-20 12:22:59 -05:00
fixDeleteStateForPosts ( ) ;
2013-10-03 15:04:25 -04:00
2014-01-16 20:53:32 -05:00
socket . emit ( 'topics.followCheck' , tid , function ( err , state ) {
2014-02-23 18:38:46 -05:00
set _follow _state ( state , false ) ;
2013-10-03 15:04:25 -04:00
} ) ;
2014-01-16 20:53:32 -05:00
2014-02-23 18:38:46 -05:00
$ ( '.posts .follow' ) . on ( 'click' , function ( ) {
2014-02-04 10:37:27 -05:00
socket . emit ( 'topics.follow' , tid , function ( err , state ) {
if ( err ) {
return app . alert ( {
type : 'danger' ,
alert _id : 'topic_follow' ,
2014-02-18 12:16:33 -05:00
title : '[[global:please_log_in]]' ,
message : '[[topic:login_to_subscribe]]' ,
2014-02-04 10:37:27 -05:00
timeout : 5000
} ) ;
}
2014-01-16 20:53:32 -05:00
2014-02-23 18:38:46 -05:00
set _follow _state ( state , true ) ;
2014-02-04 10:37:27 -05:00
} ) ;
return false ;
} ) ;
2013-06-06 20:39:45 -04:00
2013-10-03 15:04:25 -04:00
enableInfiniteLoading ( ) ;
var bookmark = localStorage . getItem ( 'topic:' + tid + ':bookmark' ) ;
2014-02-24 19:26:26 -05:00
if ( window . location . hash ) {
Topic . scrollToPost ( window . location . hash . substr ( 1 ) , true ) ;
} else if ( bookmark ) {
Topic . scrollToPost ( parseInt ( bookmark , 10 ) , true ) ;
2014-02-17 20:57:12 -05:00
} else {
updateHeader ( ) ;
2013-06-10 16:00:08 -04:00
}
2013-10-03 15:04:25 -04:00
2014-01-22 21:08:43 +01:00
$ ( '#post-container' ) . on ( 'mouseenter' , '.favourite-tooltip' , function ( e ) {
if ( ! $ ( this ) . data ( 'users-loaded' ) ) {
$ ( this ) . data ( 'users-loaded' , "true" ) ;
var pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
var el = $ ( this ) . attr ( 'title' , "Loading..." ) ;
socket . emit ( 'posts.getFavouritedUsers' , pid , function ( err , usernames ) {
el . attr ( 'title' , usernames ) . tooltip ( 'show' ) ;
} ) ;
}
} ) ;
2013-06-06 20:39:45 -04:00
} ) ;
2013-08-23 13:45:57 -04:00
2013-10-03 15:04:25 -04:00
function enableInfiniteLoading ( ) {
2014-01-24 13:27:36 -05:00
if ( ! config . usePagination ) {
2014-01-27 19:58:03 -05:00
$ ( '.pagination-block' ) . removeClass ( 'hide' ) ;
2014-02-17 20:57:12 -05:00
app . enableInfiniteLoading ( function ( direction ) {
2014-01-26 14:56:16 -05:00
if ( ! infiniteLoaderActive && $ ( '#post-container' ) . children ( ) . length ) {
2014-02-17 20:57:12 -05:00
var after = 0 ;
var el = null ;
if ( direction > 0 ) {
el = $ ( '#post-container .post-row.infiniteloaded' ) . last ( ) ;
after = parseInt ( el . attr ( 'data-index' ) , 10 ) + 1 ;
} else {
el = $ ( '#post-container .post-row.infiniteloaded' ) . first ( ) ;
after = parseInt ( el . attr ( 'data-index' ) , 10 ) ;
after -= config . postsPerPage ;
if ( after < 0 ) {
after = 0 ;
}
}
var offset = el . offset ( ) . top - $ ( '#header-menu' ) . offset ( ) . top + $ ( '#header-menu' ) . height ( ) ;
loadMorePosts ( tid , after , function ( ) {
2014-01-24 13:27:36 -05:00
fixDeleteStateForPosts ( ) ;
2014-02-17 20:57:12 -05:00
if ( direction < 0 && el ) {
2014-02-24 19:26:26 -05:00
Topic . scrollToPost ( el . attr ( 'data-pid' ) , false , 0 , offset ) ;
2014-02-17 20:57:12 -05:00
}
2014-01-24 13:27:36 -05:00
} ) ;
}
} ) ;
} else {
2014-01-24 20:00:56 -05:00
$ ( '.pagination-block' ) . addClass ( 'hide' ) ;
2014-01-24 13:27:36 -05:00
2014-01-25 19:19:25 -05:00
pagination . init ( currentPage , pageCount ) ;
2014-01-24 20:00:56 -05:00
}
}
2013-11-23 17:07:31 -05:00
$ ( '.topic' ) . on ( 'click' , '.post_reply' , function ( ) {
2013-10-03 15:04:25 -04:00
var selectionText = '' ,
selection = window . getSelection ( ) || document . getSelection ( ) ;
2013-08-08 13:04:26 -04:00
2013-10-03 15:04:25 -04:00
if ( $ ( selection . baseNode ) . parents ( '.post-content' ) . length > 0 ) {
var snippet = selection . toString ( ) ;
2013-11-29 18:00:52 -05:00
if ( snippet . length > 0 ) {
selectionText = '> ' + snippet . replace ( /\n/g , '\n> ' ) ;
}
}
var username = '' ,
2014-02-22 17:56:13 -05:00
post = $ ( this ) . parents ( 'li[data-pid]' ) ,
pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2014-01-04 21:41:22 -05:00
if ( post . length ) {
2014-01-25 20:42:29 -05:00
username = '@' + post . attr ( 'data-username' ) . replace ( /\s/g , '-' ) + ' ' ;
2013-10-03 15:04:25 -04:00
}
2013-09-23 17:41:54 -04:00
2013-10-03 15:04:25 -04:00
if ( thread _state . locked !== '1' ) {
2014-02-22 17:56:13 -05:00
composer . newReply ( tid , pid , topic _name , selectionText . length > 0 ? selectionText + '\n\n' + username : '' + username ) ;
2013-10-03 15:04:25 -04:00
}
2013-11-23 17:07:31 -05:00
} ) ;
2013-09-23 17:41:54 -04:00
2013-10-03 15:04:25 -04:00
$ ( '#post-container' ) . on ( 'click' , '.quote' , function ( ) {
if ( thread _state . locked !== '1' ) {
2014-01-04 21:41:22 -05:00
var username = '' ,
post = $ ( this ) . parents ( 'li[data-pid]' ) ,
2014-01-17 16:26:27 -05:00
pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2014-01-04 21:41:22 -05:00
if ( post . length ) {
2014-01-25 20:42:29 -05:00
username = '@' + post . attr ( 'data-username' ) . replace ( /\s/g , '-' ) ;
2014-01-04 21:41:22 -05:00
}
2013-10-03 15:04:25 -04:00
2014-01-16 22:06:23 -05:00
socket . emit ( 'posts.getRawPost' , pid , function ( err , post ) {
if ( err ) {
2014-01-25 22:19:51 -05:00
return app . alertError ( err . message ) ;
2014-01-16 22:06:23 -05:00
}
var quoted = '' ;
if ( post ) {
quoted = '> ' + post . replace ( /\n/g , '\n> ' ) + '\n\n' ;
}
2014-01-27 02:51:49 +02:00
if ( $ ( '.composer' ) . length ) {
2014-01-27 13:04:03 -05:00
composer . addQuote ( tid , pid , topic _name , username , quoted ) ;
2014-01-27 02:51:49 +02:00
} else {
2014-02-22 17:56:13 -05:00
composer . newReply ( tid , pid , topic _name , username + ' said:\n' + quoted ) ;
2014-01-27 02:51:49 +02:00
}
2013-10-03 15:04:25 -04:00
} ) ;
}
2013-08-08 13:04:26 -04:00
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
$ ( '#post-container' ) . on ( 'click' , '.favourite' , function ( ) {
2014-01-17 16:26:27 -05:00
var pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2013-09-24 14:56:51 -04:00
2014-01-30 17:41:54 -05:00
var method = $ ( this ) . attr ( 'data-favourited' ) == 'false' ? 'posts.favourite' : 'posts.unfavourite' ;
socket . emit ( method , {
pid : pid ,
room _id : app . currentRoom
} ) ;
2014-02-04 10:37:27 -05:00
return false ;
2013-09-24 14:56:51 -04:00
} ) ;
2014-02-06 12:45:06 -05:00
$ ( '#post-container' ) . on ( 'click' , '.upvote' , function ( ) {
var post = $ ( this ) . parents ( '.post-row' ) ,
pid = post . attr ( 'data-pid' ) ,
2014-02-06 14:30:59 -05:00
upvoted = post . find ( '.upvoted' ) . length ;
2014-02-08 00:53:35 -05:00
2014-02-06 14:30:59 -05:00
if ( upvoted ) {
2014-02-06 12:45:06 -05:00
socket . emit ( 'posts.unvote' , {
pid : pid ,
room _id : app . currentRoom
} ) ;
} else {
socket . emit ( 'posts.upvote' , {
pid : pid ,
room _id : app . currentRoom
} ) ;
}
2014-02-08 00:53:35 -05:00
2014-02-06 12:45:06 -05:00
return false ;
} ) ;
$ ( '#post-container' ) . on ( 'click' , '.downvote' , function ( ) {
var post = $ ( this ) . parents ( '.post-row' ) ,
pid = post . attr ( 'data-pid' ) ,
2014-02-06 14:30:59 -05:00
downvoted = post . find ( '.downvoted' ) . length ;
2014-02-06 12:45:06 -05:00
2014-02-06 14:30:59 -05:00
if ( downvoted ) {
2014-02-06 12:45:06 -05:00
socket . emit ( 'posts.unvote' , {
pid : pid ,
room _id : app . currentRoom
} ) ;
} else {
socket . emit ( 'posts.downvote' , {
pid : pid ,
room _id : app . currentRoom
} ) ;
}
2014-02-08 00:53:35 -05:00
2014-02-06 12:45:06 -05:00
return false ;
} ) ;
2014-01-30 17:41:54 -05:00
$ ( '#post-container' ) . on ( 'click' , '.flag' , function ( ) {
2014-02-24 17:19:49 -05:00
var btn = $ ( this ) ;
2014-02-04 11:50:50 -05:00
bootbox . confirm ( 'Are you sure you want to flag this post?' , function ( confirm ) {
if ( confirm ) {
2014-02-24 17:19:49 -05:00
var pid = btn . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2014-02-04 11:50:50 -05:00
socket . emit ( 'posts.flag' , pid , function ( err ) {
if ( err ) {
return app . alertError ( err . message ) ;
}
app . alertSuccess ( 'This post has been flagged for moderation.' ) ;
} ) ;
2014-01-30 17:41:54 -05:00
}
} ) ;
} ) ;
2014-01-18 19:15:07 -05:00
$ ( '#post-container' ) . on ( 'shown.bs.dropdown' , '.share-dropdown' , function ( ) {
2014-01-17 16:26:27 -05:00
var pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2014-02-24 15:10:27 -05:00
$ ( '#post_' + pid + '_link' ) . val ( window . location . protocol + '//' + window . location . host + window . location . pathname + '#' + pid ) ;
2014-01-18 19:15:07 -05:00
// without the setTimeout can't select the text in the input
2014-01-24 20:50:55 -05:00
setTimeout ( function ( ) {
2014-02-12 10:36:17 -05:00
$ ( '#post_' + pid + '_link' ) . putCursorAtEnd ( ) . select ( ) ;
2014-01-18 19:15:07 -05:00
} , 50 ) ;
} ) ;
$ ( '#post-container' ) . on ( 'click' , '.post-link' , function ( e ) {
e . preventDefault ( ) ;
return false ;
2013-10-03 15:04:25 -04:00
} ) ;
2013-07-15 17:14:57 -04:00
2013-11-28 10:58:14 -05:00
$ ( '#post-container' ) . on ( 'click' , '.twitter-share' , function ( ) {
2014-01-17 16:26:27 -05:00
var pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2013-11-28 10:58:14 -05:00
window . open ( 'https://twitter.com/intent/tweet?url=' + encodeURIComponent ( window . location . href + '#' + pid ) + '&text=' + topic _name , '_blank' , 'width=550,height=420,scrollbars=no,status=no' ) ;
return false ;
} ) ;
$ ( '#post-container' ) . on ( 'click' , '.facebook-share' , function ( ) {
2014-01-17 16:26:27 -05:00
var pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2013-11-28 10:58:14 -05:00
window . open ( 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent ( window . location . href + '#' + pid ) , '_blank' , 'width=626,height=436,scrollbars=no,status=no' ) ;
return false ;
} ) ;
$ ( '#post-container' ) . on ( 'click' , '.google-share' , function ( ) {
2014-01-17 16:26:27 -05:00
var pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2013-11-28 10:58:14 -05:00
window . open ( 'https://plus.google.com/share?url=' + encodeURIComponent ( window . location . href + '#' + pid ) , '_blank' , 'width=500,height=570,scrollbars=no,status=no' ) ;
return false ;
} ) ;
2014-01-03 21:33:41 -05:00
$ ( '#post-container' ) . on ( 'click' , '.edit' , function ( e ) {
2014-01-17 16:26:27 -05:00
var pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2013-07-15 17:14:57 -04:00
2013-12-22 15:15:59 -05:00
composer . editPost ( pid ) ;
2013-10-03 15:04:25 -04:00
} ) ;
2013-07-05 11:17:28 -04:00
2014-01-03 21:33:41 -05:00
$ ( '#post-container' ) . on ( 'click' , '.delete' , function ( e ) {
2014-01-17 16:26:27 -05:00
var pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ,
2013-10-03 15:04:25 -04:00
postEl = $ ( document . querySelector ( '#post-container li[data-pid="' + pid + '"]' ) ) ,
2014-01-16 22:06:23 -05:00
action = ! postEl . hasClass ( 'deleted' ) ? 'delete' : 'restore' ;
2013-10-03 15:04:25 -04:00
2014-01-16 22:06:23 -05:00
bootbox . confirm ( 'Are you sure you want to ' + action + ' this post?' , function ( confirm ) {
if ( confirm ) {
socket . emit ( 'posts.' + action , {
2013-11-24 13:58:06 -05:00
pid : pid ,
tid : tid
} , function ( err ) {
if ( err ) {
2014-01-16 22:06:23 -05:00
return app . alertError ( 'Can\'t ' + action + ' post!' ) ;
2013-11-24 13:58:06 -05:00
}
2013-10-03 15:04:25 -04:00
} ) ;
2013-11-24 13:58:06 -05:00
}
2014-01-16 22:06:23 -05:00
} ) ;
2013-10-03 15:04:25 -04:00
} ) ;
2013-07-05 11:17:28 -04:00
2014-01-07 15:00:05 -05:00
$ ( '#post-container' ) . on ( 'click' , '.move' , function ( e ) {
var moveModal = $ ( '#move-post-modal' ) ,
moveBtn = moveModal . find ( '#move_post_commit' ) ,
topicId = moveModal . find ( '#topicId' ) ,
2014-01-17 16:26:27 -05:00
post = $ ( this ) . parents ( '.post-row' ) ,
pid = $ ( this ) . parents ( '.post-row' ) . attr ( 'data-pid' ) ;
2014-01-07 15:00:05 -05:00
moveModal . removeClass ( 'hide' ) ;
moveModal . css ( "position" , "fixed" )
. css ( "left" , Math . max ( 0 , ( ( $ ( window ) . width ( ) - $ ( moveModal ) . outerWidth ( ) ) / 2 ) + $ ( window ) . scrollLeft ( ) ) + "px" )
. css ( "top" , "0px" )
. css ( "z-index" , "2000" ) ;
moveModal . find ( '.close,#move_post_cancel' ) . on ( 'click' , function ( ) {
moveModal . addClass ( 'hide' ) ;
} ) ;
topicId . on ( 'change' , function ( ) {
if ( topicId . val ( ) . length ) {
moveBtn . removeAttr ( 'disabled' ) ;
} else {
moveBtn . attr ( 'disabled' , true ) ;
}
} ) ;
moveBtn . on ( 'click' , function ( ) {
2014-01-16 15:10:37 -05:00
socket . emit ( 'topics.movePost' , { pid : pid , tid : topicId . val ( ) } , function ( err ) {
2014-01-07 15:00:05 -05:00
if ( err ) {
2014-01-19 17:49:16 -05:00
$ ( '#topicId' ) . val ( '' ) ;
moveModal . addClass ( 'hide' ) ;
2014-01-07 15:00:05 -05:00
return app . alertError ( err . message ) ;
}
post . fadeOut ( 500 , function ( ) {
post . remove ( ) ;
} ) ;
moveModal . addClass ( 'hide' ) ;
$ ( '#topicId' ) . val ( '' ) ;
app . alertSuccess ( 'Post moved!' ) ;
} ) ;
} ) ;
} ) ;
2013-10-03 15:04:25 -04:00
$ ( '#post-container' ) . on ( 'click' , '.chat' , function ( e ) {
2014-01-20 21:00:10 -05:00
var post = $ ( this ) . parents ( 'li.post-row' ) ,
username = post . attr ( 'data-username' ) ,
touid = post . attr ( 'data-uid' ) ;
2013-10-03 15:04:25 -04:00
app . openChat ( username , touid ) ;
2013-12-28 14:36:33 -05:00
$ ( this ) . parents ( '.btn-group' ) . find ( '.dropdown-toggle' ) . click ( ) ;
return false ;
2013-10-03 15:04:25 -04:00
} ) ;
2013-07-05 11:17:28 -04:00
2013-10-03 15:04:25 -04:00
ajaxify . register _events ( [
2014-02-06 14:48:05 -05:00
'event:rep_up' , 'event:rep_down' , 'event:favourited' , 'event:unfavourited' , 'event:new_post' , 'get_users_in_room' ,
2013-10-03 15:04:25 -04:00
'event:topic_deleted' , 'event:topic_restored' , 'event:topic:locked' ,
'event:topic_unlocked' , 'event:topic_pinned' , 'event:topic_unpinned' ,
'event:topic_moved' , 'event:post_edited' , 'event:post_deleted' , 'event:post_restored' ,
2014-02-06 12:45:06 -05:00
'posts.favourite' , 'user.isOnline' , 'posts.upvote' , 'posts.downvote'
2013-10-03 15:04:25 -04:00
] ) ;
2013-05-29 12:17:44 -04:00
2014-01-16 15:10:37 -05:00
socket . on ( 'get_users_in_room' , function ( data ) {
2014-01-19 14:27:07 -05:00
if ( data && data . room . indexOf ( 'topic' ) !== - 1 ) {
2013-10-23 15:00:06 -04:00
var activeEl = $ ( '.thread_active_users' ) ;
2013-10-03 15:04:25 -04:00
2013-10-23 14:39:46 -04:00
function createUserIcon ( uid , picture , userslug , username ) {
2014-01-04 19:20:59 -05:00
if ( ! activeEl . find ( '[href="' + RELATIVE _PATH + '/user/' + data . users [ i ] . userslug + '"]' ) . length ) {
2013-10-23 14:39:46 -04:00
var userIcon = $ ( '<img src="' + picture + '"/>' ) ;
2014-01-04 19:20:59 -05:00
var userLink = $ ( '<a href="' + RELATIVE _PATH + '/user/' + userslug + '"></a>' ) . append ( userIcon ) ;
2013-10-23 14:39:46 -04:00
userLink . attr ( 'data-uid' , uid ) ;
2013-11-21 13:53:19 -05:00
var div = $ ( '<div class="inline-block"></div>' ) ;
div . append ( userLink ) ;
2013-10-23 14:39:46 -04:00
userLink . tooltip ( {
2013-11-21 13:53:19 -05:00
placement : 'top' ,
2013-10-23 14:39:46 -04:00
title : username
} ) ;
2013-11-21 13:53:19 -05:00
return div ;
2013-10-23 14:39:46 -04:00
}
}
// remove users that are no longer here
activeEl . children ( ) . each ( function ( index , element ) {
if ( element ) {
var uid = $ ( element ) . attr ( 'data-uid' ) ;
for ( var i = 0 ; i < data . users . length ; ++ i ) {
if ( data . users [ i ] . uid == uid ) {
return ;
}
}
$ ( element ) . remove ( ) ;
}
} ) ;
var i = 0 ;
// add self
for ( i = 0 ; i < data . users . length ; ++ i ) {
if ( data . users [ i ] . uid == app . uid ) {
var icon = createUserIcon ( data . users [ i ] . uid , data . users [ i ] . picture , data . users [ i ] . userslug , data . users [ i ] . username ) ;
activeEl . prepend ( icon ) ;
data . users . splice ( i , 1 ) ;
break ;
}
}
// add other users
for ( i = 0 ; i < data . users . length ; ++ i ) {
icon = createUserIcon ( data . users [ i ] . uid , data . users [ i ] . picture , data . users [ i ] . userslug , data . users [ i ] . username )
activeEl . append ( icon ) ;
if ( activeEl . children ( ) . length > 8 ) {
break ;
}
}
var remainingUsers = data . users . length - 9 ;
remainingUsers = remainingUsers < 0 ? 0 : remainingUsers ;
var anonymousCount = parseInt ( data . anonymousCount , 10 ) ;
2013-10-23 15:00:06 -04:00
activeEl . find ( '.anonymous-box' ) . remove ( ) ;
2013-10-23 14:39:46 -04:00
if ( anonymousCount || remainingUsers ) {
2013-11-26 14:25:46 -05:00
var anonLink = $ ( '<div class="anonymous-box inline-block"><i class="fa fa-user"></i></div>' ) ;
2013-10-23 14:39:46 -04:00
activeEl . append ( anonLink ) ;
var title = '' ;
if ( remainingUsers && anonymousCount )
title = remainingUsers + ' more user(s) and ' + anonymousCount + ' guest(s)' ;
else if ( remainingUsers )
title = remainingUsers + ' more user(s)' ;
else
title = anonymousCount + ' guest(s)' ;
anonLink . tooltip ( {
2013-11-21 13:53:19 -05:00
placement : 'top' ,
2013-10-23 14:39:46 -04:00
title : title
} ) ;
}
}
2014-01-31 15:13:52 -05:00
app . populateOnlineUsers ( ) ;
} ) ;
socket . on ( 'user.isOnline' , function ( err , data ) {
2013-11-23 17:07:31 -05:00
app . populateOnlineUsers ( ) ;
2013-09-19 16:40:02 -04:00
} ) ;
2013-09-19 16:24:30 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:rep_up' , function ( data ) {
adjust _rep ( 1 , data . pid , data . uid ) ;
} ) ;
2013-07-24 00:05:58 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:rep_down' , function ( data ) {
adjust _rep ( - 1 , data . pid , data . uid ) ;
2013-06-04 16:47:07 -04:00
} ) ;
2013-05-29 12:17:44 -04:00
2014-02-06 14:48:05 -05:00
socket . on ( 'event:favourited' , function ( data ) {
adjust _favourites ( 1 , data . pid , data . uid ) ;
} ) ;
socket . on ( 'event:unfavourited' , function ( data ) {
adjust _favourites ( - 1 , data . pid , data . uid ) ;
} ) ;
2013-12-17 16:10:32 -05:00
socket . on ( 'event:new_post' , function ( data ) {
2014-01-24 20:00:56 -05:00
if ( config . usePagination ) {
onNewPostPagination ( data ) ;
return ;
}
2013-12-17 16:10:32 -05:00
var posts = data . posts ;
for ( var p in posts ) {
if ( posts . hasOwnProperty ( p ) ) {
var post = posts [ p ] ,
postcount = jQuery ( '.user_postcount_' + post . uid ) ,
ptotal = parseInt ( postcount . html ( ) , 10 ) ;
ptotal += 1 ;
postcount . html ( ptotal ) ;
}
}
2014-01-21 11:48:56 -05:00
socket . emit ( 'topics.markAsRead' , { tid : tid , uid : app . uid } ) ;
2013-12-17 16:10:32 -05:00
createNewPosts ( data ) ;
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:topic_deleted' , function ( data ) {
2014-01-16 19:58:57 -05:00
if ( data && data . tid === tid ) {
2013-10-03 15:04:25 -04:00
set _locked _state ( true ) ;
set _delete _state ( true ) ;
}
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:topic_restored' , function ( data ) {
2014-01-16 19:58:57 -05:00
if ( data && data . tid === tid ) {
2013-10-03 15:04:25 -04:00
set _locked _state ( false ) ;
set _delete _state ( false ) ;
}
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:topic_locked' , function ( data ) {
2014-01-16 19:58:57 -05:00
if ( data && data . tid === tid ) {
2013-10-03 15:04:25 -04:00
set _locked _state ( true , 1 ) ;
}
} ) ;
2013-08-26 13:18:20 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:topic_unlocked' , function ( data ) {
2014-01-16 19:58:57 -05:00
if ( data && data . tid === tid ) {
2013-10-03 15:04:25 -04:00
set _locked _state ( false , 1 ) ;
}
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:topic_pinned' , function ( data ) {
2014-01-16 19:58:57 -05:00
if ( data && data . tid === tid ) {
2013-10-03 15:04:25 -04:00
set _pinned _state ( true , 1 ) ;
}
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:topic_unpinned' , function ( data ) {
2014-01-16 19:58:57 -05:00
if ( data && data . tid === tid ) {
2013-10-03 15:04:25 -04:00
set _pinned _state ( false , 1 ) ;
}
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:topic_moved' , function ( data ) {
2014-01-16 19:58:57 -05:00
if ( data && data . tid > 0 ) {
ajaxify . go ( 'topic/' + data . tid ) ;
}
2013-10-03 15:04:25 -04:00
} ) ;
2013-07-17 12:57:57 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:post_edited' , function ( data ) {
2014-01-18 21:57:06 -05:00
var editedPostEl = $ ( '#content_' + data . pid ) ,
editedPostTitle = $ ( '#topic_title_' + data . pid ) ;
2013-05-29 12:17:44 -04:00
2014-01-18 21:57:06 -05:00
if ( editedPostTitle . length ) {
2013-10-03 15:04:25 -04:00
editedPostTitle . fadeOut ( 250 , function ( ) {
editedPostTitle . html ( data . title ) ;
editedPostTitle . fadeIn ( 250 ) ;
} ) ;
}
2013-05-29 12:17:44 -04:00
2014-01-18 21:57:06 -05:00
editedPostEl . fadeOut ( 250 , function ( ) {
editedPostEl . html ( data . content ) ;
editedPostEl . find ( 'img' ) . addClass ( 'img-responsive' ) ;
editedPostEl . fadeIn ( 250 ) ;
2013-10-03 15:04:25 -04:00
} ) ;
} ) ;
2013-05-29 12:17:44 -04:00
2014-02-06 12:45:06 -05:00
socket . on ( 'posts.upvote' , function ( data ) {
if ( data && data . pid ) {
var post = $ ( 'li[data-pid="' + data . pid + '"]' ) ,
2014-02-06 14:30:59 -05:00
upvote = post . find ( '.upvote' ) ;
2014-02-06 12:45:06 -05:00
2014-02-06 14:30:59 -05:00
upvote . addClass ( 'btn-primary upvoted' ) ;
2014-02-06 12:45:06 -05:00
}
} ) ;
socket . on ( 'posts.downvote' , function ( data ) {
if ( data && data . pid ) {
var post = $ ( 'li[data-pid="' + data . pid + '"]' ) ,
2014-02-06 14:30:59 -05:00
downvote = post . find ( '.downvote' ) ;
downvote . addClass ( 'btn-primary downvoted' ) ;
2014-02-06 12:45:06 -05:00
}
} ) ;
socket . on ( 'posts.unvote' , function ( data ) {
if ( data && data . pid ) {
var post = $ ( 'li[data-pid="' + data . pid + '"]' ) ,
upvote = post . find ( '.upvote' ) ,
2014-02-06 14:30:59 -05:00
downvote = post . find ( '.downvote' ) ;
2014-02-06 12:45:06 -05:00
2014-02-06 14:30:59 -05:00
upvote . removeClass ( 'btn-primary upvoted' ) ;
downvote . removeClass ( 'btn-primary downvoted' ) ;
2014-02-06 12:45:06 -05:00
}
} ) ;
2014-01-16 15:10:37 -05:00
socket . on ( 'posts.favourite' , function ( data ) {
2014-01-16 22:06:23 -05:00
if ( data && data . pid ) {
2013-11-28 17:45:04 -05:00
var favBtn = $ ( 'li[data-pid="' + data . pid + '"] .favourite' ) ;
if ( favBtn . length ) {
favBtn . addClass ( 'btn-warning' )
2014-01-22 12:46:37 -05:00
. attr ( 'data-favourited' , true ) ;
var icon = favBtn . find ( 'i' ) ;
var className = icon . attr ( 'class' ) ;
if ( className . indexOf ( '-o' ) !== - 1 ) {
icon . attr ( 'class' , className . replace ( '-o' , '' ) ) ;
}
2013-10-03 15:04:25 -04:00
}
}
} ) ;
2013-05-29 12:17:44 -04:00
2014-01-16 15:10:37 -05:00
socket . on ( 'posts.unfavourite' , function ( data ) {
2014-01-16 22:06:23 -05:00
if ( data && data . pid ) {
2013-11-28 17:45:04 -05:00
var favBtn = $ ( 'li[data-pid="' + data . pid + '"] .favourite' ) ;
if ( favBtn . length ) {
favBtn . removeClass ( 'btn-warning' )
2014-01-22 12:46:37 -05:00
. attr ( 'data-favourited' , false ) ;
var icon = favBtn . find ( 'i' ) ;
var className = icon . attr ( 'class' ) ;
if ( className . indexOf ( '-o' ) === - 1 ) {
icon . attr ( 'class' , className + '-o' ) ;
}
2013-10-03 15:04:25 -04:00
}
}
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:post_deleted' , function ( data ) {
2013-11-24 13:58:06 -05:00
if ( data . pid ) {
toggle _post _delete _state ( data . pid ) ;
}
2013-10-03 15:04:25 -04:00
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
socket . on ( 'event:post_restored' , function ( data ) {
2013-11-24 13:58:06 -05:00
if ( data . pid ) {
toggle _post _delete _state ( data . pid ) ;
}
2013-10-03 15:04:25 -04:00
} ) ;
2013-05-29 12:17:44 -04:00
2013-10-03 15:04:25 -04:00
function adjust _rep ( value , pid , uid ) {
2014-02-06 12:45:06 -05:00
var votes = $ ( 'li[data-pid="' + pid + '"] .votes' ) ,
reputationElements = $ ( '.reputation[data-uid="' + uid + '"]' ) ,
currentVotes = parseInt ( votes . attr ( 'data-votes' ) , 10 ) ,
reputation = parseInt ( reputationElements . attr ( 'data-reputation' ) , 10 ) ;
2013-05-29 12:17:44 -04:00
2014-02-06 12:45:06 -05:00
currentVotes += value ;
reputation += value ;
2013-08-23 13:45:57 -04:00
2014-02-06 14:30:59 -05:00
votes . html ( currentVotes ) . attr ( 'data-votes' , currentVotes ) ;
reputationElements . html ( reputation ) . attr ( 'data-reputation' , reputation ) ;
2013-05-29 12:17:44 -04:00
}
2014-02-06 14:48:05 -05:00
function adjust _favourites ( value , pid , uid ) {
var favourites = $ ( 'li[data-pid="' + pid + '"] .favouriteCount' ) ,
currentFavourites = parseInt ( favourites . attr ( 'data-favourites' ) , 10 ) ;
currentFavourites += value ;
favourites . html ( currentFavourites ) . attr ( 'data-favourites' , currentFavourites ) ;
}
2014-02-23 18:38:46 -05:00
function set _follow _state ( state , alert ) {
$ ( '.posts .follow' ) . toggleClass ( 'btn-success' , state ) . attr ( 'title' , state ? 'You are currently receiving updates to this topic' : 'Be notified of new replies in this topic' ) ;
if ( alert ) {
app . alert ( {
alert _id : 'topic_follow' ,
timeout : 2500 ,
title : state ? '[[topic:following_topic.title]]' : '[[topic:not_following_topic.title]]' ,
message : state ? '[[topic:following_topic.message]]' : '[[topic:not_following_topic.message]]' ,
type : 'success'
} ) ;
}
}
2013-10-03 15:04:25 -04:00
function set _locked _state ( locked , alert ) {
2014-02-23 18:05:50 -05:00
translator . translate ( '<i class="fa fa-fw fa-' + ( locked ? 'un' : '' ) + 'lock"></i> [[topic:thread_tools.' + ( locked ? 'un' : '' ) + 'lock]]' , function ( translated ) {
$ ( '.lock_thread' ) . html ( translated ) ;
} ) ;
2013-08-30 12:36:06 -04:00
2014-02-23 18:05:50 -05:00
$ ( '.topic-main-buttons .post_reply' ) . attr ( 'disabled' , locked ) . html ( locked ? 'Locked <i class="fa fa-lock"></i>' : 'Reply' ) ;
2013-10-03 15:04:25 -04:00
2014-02-23 18:05:50 -05:00
$ ( '#post-container .post_reply' ) . html ( locked ? 'Locked <i class="fa fa-lock"></i>' : 'Reply <i class="fa fa-reply"></i>' ) ;
$ ( '#post-container' ) . find ( '.quote, .edit, .delete' ) . toggleClass ( 'none' , locked ) ;
2013-05-29 12:17:44 -04:00
2014-02-23 18:05:50 -05:00
if ( alert ) {
app . alert ( {
'alert_id' : 'thread_lock' ,
type : 'success' ,
title : 'Thread ' + ( locked ? 'Locked' : 'Unlocked' ) ,
message : 'Thread has been successfully ' + ( locked ? 'locked' : 'unlocked' ) ,
timeout : 5000
} ) ;
2013-08-19 14:28:51 -04:00
}
2014-02-23 18:05:50 -05:00
thread _state . locked = locked ? '1' : '0' ;
2013-08-13 15:05:35 -04:00
}
2013-10-03 15:04:25 -04:00
function set _delete _state ( deleted ) {
2014-02-23 18:19:10 -05:00
var threadEl = $ ( '#post-container' ) ;
2013-10-03 15:04:25 -04:00
2014-02-23 18:19:10 -05:00
translator . translate ( '<i class="fa fa-fw ' + ( deleted ? 'fa-comment' : 'fa-trash-o' ) + '"></i> [[topic:thread_tools.' + ( deleted ? 'restore' : 'delete' ) + ']]' , function ( translated ) {
$ ( '.delete_thread span' ) . html ( translated ) ;
} ) ;
2013-10-03 15:04:25 -04:00
2014-02-23 18:19:10 -05:00
threadEl . toggleClass ( 'deleted' , deleted ) ;
thread _state . deleted = deleted ? '1' : '0' ;
2013-10-03 15:04:25 -04:00
2014-02-23 18:19:10 -05:00
if ( deleted ) {
2014-02-24 19:16:23 -05:00
$ ( '<div id="thread-deleted" class="alert alert-warning">This thread has been deleted. Only users with thread management privileges can see it.</div>' ) . insertBefore ( threadEl ) ;
2014-02-23 18:19:10 -05:00
} else {
$ ( '#thread-deleted' ) . remove ( ) ;
2013-08-23 13:45:57 -04:00
}
2013-05-29 12:17:44 -04:00
}
2013-10-03 15:04:25 -04:00
function set _pinned _state ( pinned , alert ) {
2014-02-12 14:03:02 -05:00
translator . translate ( '<i class="fa fa-fw fa-thumb-tack"></i> [[topic:thread_tools.' + ( pinned ? 'unpin' : 'pin' ) + ']]' , function ( translated ) {
2014-02-23 17:42:31 -05:00
$ ( '.pin_thread' ) . html ( translated ) ;
2013-05-29 12:17:44 -04:00
2014-02-23 17:42:31 -05:00
if ( alert ) {
app . alert ( {
'alert_id' : 'thread_pin' ,
type : 'success' ,
title : 'Thread ' + ( pinned ? 'Pinned' : 'Unpinned' ) ,
message : 'Thread has been successfully ' + ( pinned ? 'pinned' : 'unpinned' ) ,
timeout : 5000
} ) ;
2014-02-10 12:41:29 -05:00
}
2014-02-23 17:42:31 -05:00
thread _state . pinned = pinned ? '1' : '0' ;
2014-02-10 12:41:29 -05:00
} ) ;
2013-05-29 12:17:44 -04:00
}
2013-10-03 15:04:25 -04:00
function toggle _post _delete _state ( pid ) {
2014-01-25 22:19:51 -05:00
var postEl = $ ( '#post-container li[data-pid="' + pid + '"]' ) ;
2013-05-29 12:17:44 -04:00
2014-01-25 22:19:51 -05:00
if ( postEl . length ) {
postEl . toggleClass ( 'deleted' ) ;
2013-06-06 20:39:45 -04:00
2014-01-25 22:19:51 -05:00
toggle _post _tools ( pid , postEl . hasClass ( 'deleted' ) ) ;
2014-01-16 22:06:23 -05:00
2014-01-25 22:19:51 -05:00
updatePostCount ( ) ;
2013-10-03 15:04:25 -04:00
}
2013-06-06 20:39:45 -04:00
}
2013-10-03 15:04:25 -04:00
2014-01-25 22:19:51 -05:00
function toggle _post _tools ( pid , isDeleted ) {
2014-02-23 15:07:47 -05:00
var postEl = $ ( '#post-container li[data-pid="' + pid + '"]' ) ;
2014-02-23 18:19:10 -05:00
postEl . find ( '.quote, .favourite, .post_reply, .chat' ) . toggleClass ( 'none' , isDeleted ) ;
2014-02-23 15:07:47 -05:00
translator . translate ( isDeleted ? ' [[topic:restore]]' : ' [[topic:delete]]' , function ( translated ) {
postEl . find ( '.delete' ) . find ( 'span' ) . html ( translated ) ;
} ) ;
2013-05-29 12:17:44 -04:00
}
2013-10-03 15:04:25 -04:00
2014-01-27 19:58:03 -05:00
$ ( window ) . on ( 'scroll' , updateHeader ) ;
2014-02-08 00:53:35 -05:00
$ ( window ) . trigger ( 'action:topic.loaded' ) ;
2013-12-01 17:42:26 -05:00
} ;
2013-08-27 06:36:49 +08:00
2013-12-01 17:42:26 -05:00
function updateHeader ( ) {
2014-02-14 21:41:53 -05:00
$ ( '.pagination-block a' ) . off ( 'click' ) . on ( 'click' , function ( ) {
return false ;
} ) ;
$ ( '.pagination-block i:first' ) . off ( 'click' ) . on ( 'click' , function ( ) {
app . scrollToTop ( ) ;
} ) ;
$ ( '.pagination-block i:last' ) . off ( 'click' ) . on ( 'click' , function ( ) {
app . scrollToBottom ( ) ;
} ) ;
2014-02-25 14:29:19 -05:00
if ( $ ( window ) . scrollTop ( ) > 50 ) {
2014-02-25 14:17:42 -05:00
$ ( '#header-topic-title' ) . text ( templates . get ( 'topic_name' ) ) . show ( ) ;
2014-02-12 16:02:07 -05:00
} else {
2014-02-25 14:17:42 -05:00
$ ( '#header-topic-title' ) . text ( '' ) . hide ( ) ;
2014-02-12 16:02:07 -05:00
}
2014-02-17 20:57:12 -05:00
$ ( $ ( '.posts > .post-row' ) . get ( ) . reverse ( ) ) . each ( function ( ) {
var el = $ ( this ) ;
2013-08-27 04:30:00 +08:00
2014-02-17 20:57:12 -05:00
if ( elementInView ( el ) ) {
var index = parseInt ( el . attr ( 'data-index' ) , 10 ) + 1 ;
if ( index > Topic . postCount ) {
index = Topic . postCount ;
}
2014-02-25 14:29:19 -05:00
$ ( '#pagination' ) . html ( index + ' out of ' + Topic . postCount ) ;
$ ( '.progress-bar' ) . width ( ( index / Topic . postCount * 100 ) + '%' ) ;
2014-02-17 20:57:12 -05:00
return false ;
}
} ) ;
2013-10-03 15:04:25 -04:00
2014-02-17 20:57:12 -05:00
$ ( '.posts > .post-row' ) . each ( function ( ) {
var el = $ ( this ) ;
if ( elementInView ( el ) ) {
var index = parseInt ( el . attr ( 'data-index' ) , 10 ) + 1 ;
if ( index === 0 ) {
2014-02-25 14:29:19 -05:00
localStorage . removeItem ( "topic:" + templates . get ( 'topic_id' ) + ":bookmark" ) ;
2014-02-17 20:57:12 -05:00
} else {
2014-02-25 14:29:19 -05:00
localStorage . setItem ( "topic:" + templates . get ( 'topic_id' ) + ":bookmark" , el . attr ( 'data-pid' ) ) ;
2014-02-25 15:10:50 -05:00
2014-02-25 15:12:42 -05:00
if ( history . replaceState ) {
2014-02-25 15:26:10 -05:00
history . replaceState ( null , null , window . location . protocol + '//' + window . location . host + window . location . pathname + '#' + el . attr ( 'data-pid' ) ) ;
2014-02-25 15:10:50 -05:00
} else {
location . hash = '#' + el . attr ( 'data-pid' ) ;
}
2013-09-23 17:41:54 -04:00
}
2014-02-17 20:57:12 -05:00
return false ;
2013-12-01 17:42:26 -05:00
}
} ) ;
2014-02-17 20:57:12 -05:00
}
2013-08-27 04:30:00 +08:00
2014-02-17 20:57:12 -05:00
function elementInView ( el ) {
var scrollTop = $ ( window ) . scrollTop ( ) ;
var scrollBottom = scrollTop + $ ( window ) . height ( ) ;
var elTop = el . offset ( ) . top ;
2014-02-23 18:38:46 -05:00
var elBottom = elTop + Math . floor ( el . height ( ) ) ;
2014-02-18 00:42:14 -05:00
return ! ( elTop > scrollBottom || elBottom < scrollTop ) ;
2013-12-01 17:42:26 -05:00
}
2013-08-27 04:30:00 +08:00
2014-02-24 19:26:26 -05:00
Topic . scrollToPost = function ( pid , highlight , duration , offset ) {
2013-11-23 17:07:31 -05:00
if ( ! pid ) {
return ;
}
2014-02-18 01:18:37 -05:00
2014-02-17 20:57:12 -05:00
if ( ! offset ) {
offset = 0 ;
}
if ( $ ( '#post_anchor_' + pid ) . length ) {
return scrollToPid ( pid ) ;
}
2013-11-23 17:07:31 -05:00
2014-01-25 19:19:25 -05:00
if ( config . usePagination ) {
socket . emit ( 'posts.getPidPage' , pid , function ( err , page ) {
2014-01-25 19:50:50 -05:00
if ( err ) {
return ;
}
2014-01-25 19:19:25 -05:00
if ( parseInt ( page , 10 ) !== pagination . currentPage ) {
pagination . loadPage ( page ) ;
} else {
scrollToPid ( pid ) ;
}
} ) ;
} else {
2014-02-17 20:57:12 -05:00
socket . emit ( 'posts.getPidIndex' , pid , function ( err , index ) {
if ( err ) {
return ;
}
var tid = $ ( '#post-container' ) . attr ( 'data-tid' ) ;
$ ( '#post-container' ) . empty ( ) ;
var after = index - config . postsPerPage + 1 ;
if ( after < 0 ) {
after = 0 ;
}
loadMorePosts ( tid , after , function ( ) {
scrollToPid ( pid ) ;
} ) ;
} ) ;
2014-01-25 19:19:25 -05:00
}
function scrollToPid ( pid ) {
2014-02-17 20:57:12 -05:00
var scrollTo = $ ( '#post_anchor_' + pid ) ,
tid = $ ( '#post-container' ) . attr ( 'data-tid' ) ;
2013-11-23 17:07:31 -05:00
2014-01-25 19:19:25 -05:00
function animateScroll ( ) {
2014-02-24 15:23:26 -05:00
$ ( "html, body" ) . animate ( {
scrollTop : ( scrollTo . offset ( ) . top - $ ( '#header-menu' ) . height ( ) - offset ) + "px"
2014-02-17 20:57:12 -05:00
} , duration !== undefined ? duration : 400 , function ( ) {
updateHeader ( ) ;
2014-02-24 17:19:49 -05:00
2014-02-24 19:26:26 -05:00
if ( highlight ) {
scrollTo . parent ( ) . addClass ( 'highlight' ) ;
setTimeout ( function ( ) {
scrollTo . parent ( ) . removeClass ( 'highlight' ) ;
} , 5000 ) ;
}
2014-02-17 20:57:12 -05:00
} ) ;
2014-01-25 19:19:25 -05:00
}
2013-11-23 17:07:31 -05:00
2014-02-18 12:40:13 -05:00
if ( tid && scrollTo . length ) {
if ( $ ( '#post-container li.post-row[data-pid="' + pid + '"]' ) . attr ( 'data-index' ) !== '0' ) {
animateScroll ( ) ;
} else {
updateHeader ( ) ;
}
2014-01-25 19:19:25 -05:00
}
2013-11-23 17:07:31 -05:00
}
}
2014-01-25 19:19:25 -05:00
function onNewPostPagination ( data ) {
var posts = data . posts ;
2014-01-25 21:35:09 -05:00
socket . emit ( 'topics.getPageCount' , templates . get ( 'topic_id' ) , function ( err , newPageCount ) {
2014-01-25 19:19:25 -05:00
2014-01-25 21:35:09 -05:00
pagination . recreatePaginationLinks ( newPageCount ) ;
2014-01-25 19:19:25 -05:00
if ( pagination . currentPage === pagination . pageCount ) {
createNewPosts ( data ) ;
} else if ( data . posts && data . posts . length && parseInt ( data . posts [ 0 ] . uid , 10 ) === parseInt ( app . uid , 10 ) ) {
pagination . loadPage ( pagination . pageCount ) ;
}
} ) ;
}
2014-02-17 20:57:12 -05:00
function createNewPosts ( data , infiniteLoaded , callback ) {
2013-11-29 13:09:26 -05:00
if ( ! data || ( data . posts && ! data . posts . length ) ) {
2013-11-23 17:07:31 -05:00
return ;
2013-11-29 13:09:26 -05:00
}
2013-11-23 17:07:31 -05:00
function removeAlreadyAddedPosts ( ) {
data . posts = data . posts . filter ( function ( post ) {
return $ ( '#post-container li[data-pid="' + post . pid + '"]' ) . length === 0 ;
} ) ;
}
2014-02-17 20:57:12 -05:00
var after = null ,
before = null ;
2013-11-23 17:07:31 -05:00
function findInsertionPoint ( ) {
2014-02-17 20:57:12 -05:00
var firstPid = parseInt ( data . posts [ 0 ] . pid , 10 ) ;
2014-01-24 20:50:55 -05:00
2013-11-23 17:07:31 -05:00
$ ( '#post-container li[data-pid]' ) . each ( function ( ) {
2014-02-17 20:57:12 -05:00
if ( firstPid > parseInt ( $ ( this ) . attr ( 'data-pid' ) , 10 ) ) {
2013-11-24 13:58:06 -05:00
after = $ ( this ) ;
2013-11-29 14:42:58 -05:00
if ( after . next ( ) . length && after . next ( ) . hasClass ( 'post-bar' ) ) {
2013-11-24 13:58:06 -05:00
after = after . next ( ) ;
}
} else {
return false ;
}
2013-11-23 17:07:31 -05:00
} ) ;
2014-02-17 20:57:12 -05:00
if ( ! after ) {
var firstPost = $ ( '#post-container .post-row' ) . first ( ) ;
if ( firstPid < parseInt ( firstPost . attr ( 'data-pid' ) , 10 ) ) {
before = firstPost ;
}
}
2013-11-23 17:07:31 -05:00
}
removeAlreadyAddedPosts ( ) ;
if ( ! data . posts . length ) {
return ;
}
2013-11-26 14:25:46 -05:00
2014-02-17 20:57:12 -05:00
findInsertionPoint ( ) ;
2013-11-23 17:07:31 -05:00
2014-01-26 16:22:50 -05:00
parseAndTranslatePosts ( data , function ( translatedHTML ) {
2013-11-23 17:07:31 -05:00
var translated = $ ( translatedHTML ) ;
2013-11-28 18:45:36 -05:00
2013-11-23 17:07:31 -05:00
if ( ! infiniteLoaded ) {
translated . removeClass ( 'infiniteloaded' ) ;
}
2014-02-17 20:57:12 -05:00
if ( after ) {
translated . insertAfter ( after )
} else if ( before ) {
translated . insertBefore ( before ) ;
} else {
$ ( '#post-container' ) . append ( translated ) ;
}
2013-11-23 17:07:31 -05:00
2014-02-17 20:57:12 -05:00
translated . hide ( ) . fadeIn ( 'slow' ) ;
onNewPostsLoaded ( translated , data . posts ) ;
2014-02-10 11:41:25 -05:00
2014-02-17 20:57:12 -05:00
if ( typeof callback === 'function' ) {
callback ( ) ;
}
2014-01-24 20:50:55 -05:00
} ) ;
}
2013-11-23 17:07:31 -05:00
2014-01-26 16:22:50 -05:00
function parseAndTranslatePosts ( data , callback ) {
var html = templates . prepare ( templates [ 'topic' ] . blocks [ 'posts' ] ) . parse ( data ) ;
2014-01-24 20:50:55 -05:00
translator . translate ( html , callback ) ;
2013-11-23 17:07:31 -05:00
}
2014-01-24 20:50:55 -05:00
2014-02-17 20:57:12 -05:00
function onNewPostsLoaded ( html , posts ) {
2014-01-24 20:50:55 -05:00
for ( var x = 0 , numPosts = posts . length ; x < numPosts ; x ++ ) {
socket . emit ( 'posts.getPrivileges' , posts [ x ] . pid , function ( err , privileges ) {
if ( err ) {
return app . alertError ( err . message ) ;
}
toggle _mod _tools ( privileges . pid , privileges . editable ) ;
} ) ;
}
infiniteLoaderActive = false ;
app . populateOnlineUsers ( ) ;
app . createUserTooltips ( ) ;
app . addCommasToNumbers ( ) ;
2014-02-17 20:57:12 -05:00
app . makeNumbersHumanReadable ( $ ( '.human-readable-number' ) ) ;
html . find ( 'span.timeago' ) . timeago ( ) ;
html . find ( '.post-content img' ) . addClass ( 'img-responsive' ) ;
2014-01-24 20:50:55 -05:00
updatePostCount ( ) ;
showBottomPostBar ( ) ;
}
2014-02-23 18:25:24 -05:00
function toggle _mod _tools ( pid , editable ) {
$ ( '#post-container li[data-pid="' + pid + '"]' ) . find ( '.edit, .delete' ) . toggleClass ( 'none' , ! editable ) ;
2014-01-12 15:37:33 -05:00
}
2013-11-24 13:58:06 -05:00
function updatePostCount ( ) {
2014-01-16 15:10:37 -05:00
socket . emit ( 'topics.postcount' , templates . get ( 'topic_id' ) , function ( err , postcount ) {
2013-12-01 17:42:26 -05:00
if ( ! err ) {
Topic . postCount = postcount ;
$ ( '#topic-post-count' ) . html ( Topic . postCount ) ;
updateHeader ( ) ;
}
2014-01-23 21:35:25 -05:00
} ) ;
2013-11-24 13:58:06 -05:00
}
2014-02-17 20:57:12 -05:00
function loadMorePosts ( tid , after , callback ) {
2013-11-23 18:05:19 -05:00
var indicatorEl = $ ( '.loading-indicator' ) ;
2013-11-23 17:07:31 -05:00
2014-02-17 20:57:12 -05:00
if ( infiniteLoaderActive || ! $ ( '#post-container' ) . length ) {
2013-11-23 17:07:31 -05:00
return ;
}
2014-02-17 20:57:12 -05:00
if ( after === 0 && $ ( '#post-container li.post-row[data-index="0"]' ) . length ) {
return ;
}
2014-01-17 14:47:18 -05:00
2014-02-17 20:57:12 -05:00
infiniteLoaderActive = true ;
indicatorEl . fadeIn ( ) ;
socket . emit ( 'topics.loadMore' , {
tid : tid ,
after : after
} , function ( err , data ) {
infiniteLoaderActive = false ;
indicatorEl . fadeOut ( ) ;
if ( err ) {
return app . alertError ( err . message ) ;
}
2014-01-17 14:47:18 -05:00
2014-02-17 20:57:12 -05:00
if ( data && data . posts && data . posts . length ) {
createNewPosts ( data , true , callback ) ;
} else {
updateHeader ( ) ;
if ( typeof callback === 'function' ) {
2014-01-17 14:47:18 -05:00
callback ( data . posts ) ;
}
2014-02-17 20:57:12 -05:00
}
} ) ;
2013-11-23 17:07:31 -05:00
}
2013-10-03 15:04:25 -04:00
return Topic ;
} ) ;