123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- var MAXPOSTS = 10;
- var posts = [];
- var sortedBy = 'votes';
- var socket;
- var mobile = (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase()));
- // note that this array applies only to this browser session!
- // ==> could vote twice on same post during different sessions.
- // use local storage??
- var postsVoted = [];
- var userObj = { userID: null, userName: null, userAffil: null };
- var loggedIn = false;
- // the Post object is modelled on EtherPad:
- // [the schoolid and courseid are implied in the meetingid];
- function assembleNewPostObj(msgBody) {
- // the postid is assigned at the server;
- var postObj = {};
- postObj.userid = userObj.userID;
- postObj.userName = userObj.userName;
- postObj.userAffil = userObj.userAffil;
- postObj.body = msgBody;
- postObj.reports = 0;
- return postObj;
- }
- function renderPosts(fresh, post) {
- if (fresh) $('#posts .postContainer').remove();
- //$('#total_posts').text(posts.length);
- // truncate long array of Posts;
- var sortedPosts = sortedBy == 'created' ? posts.sort(createdDesc) : posts.sort(votesDesc);
- var displayPosts = sortedPosts//.slice(0, MAXPOSTS - 1);
- if (post) $("#postTemplate").tmpl(post).appendTo("#posts");
- if (fresh) $("#postTemplate").tmpl(displayPosts).appendTo("#posts");
- else $('#posts').reOrder(displayPosts, 'post-')
- posts.forEach(function(post) {
- renderComments(post._id)
- var $post = $('#post-'+post._id);
- if ($post !== []) {
- if (post.reports.length >= 2) {
- if ($('#reportedContainer').length === 0) {
- $('#posts').append('<div id="reportedContainer"><h1>Flagged Posts</h1><div class="reportedPosts hidden"></div></div>')
- $('#reportedContainer h1').click(function() {
- $('.reportedPosts').toggleClass('hidden')
- })
- }
- $post.addClass('flagged');
- $('#reportedContainer .reportedPosts').append($post)
- }
- if (post.votes.indexOf(userID) == -1) {
- if (!public) $post.find('.postVoteContainer').addClass('unvoted')
- } else {
- $post.find('.vote-tally-rect').die()
- $post.find('.vote-tally-rect').css('cursor', 'default')
- }
- if (post.reports.indexOf(userID) !== -1) {
- $post.find('.voteFlag').css('cursor', 'default')
- $post.find('.voteFlag').css('background', '#888')
- }
- if (post.userAffil === 'Instructor') {
- $post.addClass('instructor');
- }
- if (commentToggle === '4f1efbb248dc57ba43000075') {
- $('.commenttoggle').empty();
- }
- if (public) {
- $post.find('.voteFlag').css({
- 'cursor': 'default',
- 'background': '#888'
- })
- $post.find('.vote-tally-rect').css('cursor', 'default');
- if (!post.public) $post.remove();
- } else {
- if (!post.public) $post.find('.privacy').text('Private')
- }
- }
- })
- }
- function renderComments(id) {
- var comments = [];
- $.each(posts, function(i, post) {
- if (post._id == id) {
- comments = post.comments;
- if (comments.length >= 1) {
- $('#post-'+id+' .commentContainer').empty();
- $('#post-'+id+' .commentAmt').text(comments.length+' ');
- $('#commentTemplate').tmpl(comments).appendTo('#post-'+id+' .commentContainer');
- }
- }
- })
- if (loggedIn) {
- $( '.commentForm :input' ).removeAttr( 'disabled' );
- }
- }
- $.fn.reOrder = function(_array, prefix) {
- var array = $.extend([], _array, true);
- return this.each(function() {
- prefix = prefix || "";
-
- if (array) {
- var reported = $('#reportedContainer');
- for(var i=0; i < array.length; i++) {
- var sel = '#' + prefix + array[i]._id;
- if ($(sel).length === 0)
- array[i] = $("#postTemplate").tmpl(array[i])
- else
- array[i] = $(sel);
- }
- $(this).find('.postContainer').remove();
-
- for(var i=0; i < array.length; i++) {
- $(this).append(array[i]);
- }
- $(this).append(reported)
- }
- });
- }
- function assembleVoteObj(postid, upOrDown) {
- return { "parentid": postid, "direction": upOrDown };
- }
- function votesDesc(a, b) {
- if (a.reports >= 2) {
- return 1;
- } else if (b.reports >= 2) {
- return -1;
- } else {
- // for descending, reverse usual order;
- return b.votes.length - a.votes.length;
- }
- }
- function createdDesc(a, b) {
- if (a.reports >= 2) {
- return 1;
- } else if (b.reports >= 2) {
- return -1;
- } else {
- // for descending, reverse usual order;
- return new Date(b.date).valueOf() - new Date(a.date).valueOf();
- }
- }
- function refreshRO() {
- if (roID !== false || public === true) {
- $('#editor div').load(rourl, function() {
- $('#editor').find('style').remove();
- })
- }
- }
- $(document).ready(function(){
- userObj.userName = public ? null : userName;
- userObj.userAffil = public ? null : userAffil;
- userObj.userID = public ? null : userID;
- loggedIn = public ? false : true;
- if (public) {
- $('#editor').css('overflow-y', 'auto')
- refreshRO();
- setInterval(function() {
- refreshRO();
- }, 10*1000)
- } else if (RO === true) {
- $('#editor').empty().append('<div class="readonly"></div>');
- $('#editor').css('overflow-y', 'auto')
- refreshRO();
- setInterval(function() {
- refreshRO();
- }, 10*1000)
- }
- $('#userBox').removeClass('hidden');
- $( '.commentForm :input' ).removeAttr( 'disabled' );
- // add event handlers;
- $('#backchatHeader input[type="button"]').click(function() {
- $('#backchatHeaderInstructions').toggle();
- });
- $('#enterPostTextarea').keyup(function() {
- var charLimit = 250;
- var charsUsed = $(this).val().length;
- if (charsUsed > 25) {
- $('#charsLeftMsg').text("characters left: " +
- (charLimit - charsUsed).toString());
- } else {
- $('#charsLeftMsg').text(" ");
- }
- });
- $('#submitPost').click(function() {
- var form = $( this );
- var body = $('#enterPostTextarea').val();
- if (body !== '') {
- var newPost = assembleNewPostObj(body);
- var anonymous = $('#enterPostForm').find( 'input[name=anonymous]' ).is(':checked') ? true : false;
- var public = $('#enterPostForm').find( 'input[name=private]' ).is(':checked') ? false : true;
- newPost.anonymous = anonymous;
- newPost.public = public;
- socket.emit('post', {post: newPost, lecture: lectureID});
- $('#enterPostTextarea').val('');
- }
- });
- if (!public) {
- $('.vote-tally-rect').live("click", function() {
- var that = this;
- var postid = $(this).parent().attr('data-postid');
- posts.forEach(function(post) {
- if (post._id === postid) {
- if (post.votes.indexOf(userID) == -1) {
- var newVoteObj = {parentid: postid, userid: userID};
- socket.emit('vote', {vote: newVoteObj, lecture: lectureID});
- $(that).die()
- $(that).css('cursor', 'default')
- $(that).parent().removeClass('unvoted');
- }
- }
- })
- });
- }
- $('#amountPosts').change(function() {
- MAXPOSTS = $(this).val();
- renderPosts();
- });
- $('#sortPosts').change(function() {
- var sort = $(this).val();
- sortedBy = sortedBy !== sort ? sort : sortedBy;
- renderPosts();
- });
- $('.commentForm').live('submit', function(e) {
- e.preventDefault();
- var body = $(this).find('#commentText').val();
- var anonymous = $( this ).find( 'input[name=anonymous]' ).is(':checked') ? true : false;
- if (body !== '') {
- var comment = {
- userName: userObj.userName,
- userAffil: userObj.userAffil,
- body: body,
- anonymous: anonymous,
- parentid: $(this).find('[name=postid]').val()
- }
- socket.emit('comment', {comment: comment, lecture: lectureID});
- $(this).find('#commentText').val('');
- }
- })
- $('.comments').live('click', function(e) {
- e.preventDefault();
- var id = $(this).attr('id').replace('post-', '');
- $('#post-'+id+' .commentContainer').toggleClass('hidden');
- if (!public) $('#post-'+id+' .commentForm').toggleClass('hidden');
- })
- if (!public) {
- $('.voteFlag').live('click', function() {
- var that = this;
- var id = $(this).parent().parent().attr('id').replace('post-', '');
- $.each(posts, function(i, post){
- if (post._id == id) {
- if (post.reports.indexOf(userID) == -1) {
- if(confirm('By flagging a comment, you are identifying it as a violation of the FinalsClub Code of Conduct: Keep it academic.')) {
- socket.emit('report', {report: {parentid: id, userid: userID}, lecture: lectureID});
- $(that).die()
- $(that).css('cursor', 'default')
- $(that).css('background', '#888')
- }
- }
- }
- })
- })
- }
- // XXX for demonstration purposes only
- $('.readonlylink').click(function(e) {
- e.preventDefault()
- $.get('/logout', function() {
- location.reload(true)
- })
- })
- //=====================================================================
- // create socket to server; note that we only permit websocket transport
- // for this demo;
- var loc = document.location;
- var port = loc.port == '' ? (loc.protocol == 'https:' ? 443 : 80) : loc.port;
- var url = loc.protocol + '//' + loc.hostname + ':' + port;
- socket = io.connect(url + '/backchannel');
- // incoming messages are objects with one property whose value is the
- // type of message:
- // { "posts": [ <array of Post objects> ] }
- // { "recentPosts": [ <array of Post objects> ] }
- // { "vote": [ "postid": <string>, "direction": <"up"|"down"> ] }
- // Unresolved: whether to send vote messages for local change of display
- // or new arrays of posts with updated vote counts. Vote message would not
- // be adequate if it changed order of posts. For now, send two new
- // arrays with updated vote counts and refrain from sending vote message.
- var messagesArrived = 0;
- socket.on('connect', function(){
- socket.emit('subscribe', lectureID, function(_packet) {
- posts = _packet.posts;
- //posts = _posts;
- commentToggle = _packet.toggle;
- renderPosts(true);
- });
- });
- socket.on('post', function(post) {
- posts.push(post);
- renderPosts(false, post);
- })
- socket.on('vote', function(vote) {
- posts = posts.map(function(post) {
- if(post._id == vote.parentid) {
- if (!public || (public && post.public)) {
- post.votes.push(vote.userid);
- $('#post-'+vote.parentid).find('.vote-tally-rect').text(post.votes.length);
- renderPosts();
- }
- }
- return post;
- });
- })
- socket.on('report', function(report) {
- posts = posts.map(function(post) {
- if(post._id == report.parentid) {
- if (!public || (public && post.public)) {
- post.reports.push(report.userid);
- if (post.reports.length >= 2) {
- $('#post-'+post._id).addClass('flagged');
- }
- renderPosts();
- }
- }
- return post;
- });
- })
- socket.on('comment', function(comment) {
- posts = posts.map(function(post) {
- if (post._id == comment.parentid) {
- if (!public || (public && post.public)) {
- if (!post.comments) {
- post.comments = [];
- }
- post.comments.push(comment);
- post.date = new Date();
- if (sortedBy == 'created') renderPosts();
- renderComments(comment.parentid);
- }
- }
- return post;
- });
- })
- socket.on('disconnect', function(){
- // XXX something here
- });
- $('#enterPostTextarea').val("");
- });
|