src/cm/media/js/client/c_sync.js
changeset 0 40c8f766c9b8
child 12 f69ff46d3240
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 gShowingAllComments = false ;
       
     2 // YUI : queue, overlay
       
     3 Sync = function() {
       
     4 	// this queue handles both animations and io requests
       
     5 	this._q = null ;
       
     6 	
       
     7 	this._iPreventClick = false ; // oh really ?
       
     8 }
       
     9 
       
    10 Sync.prototype = {
       
    11 	init : function (iComment) {
       
    12 	this._q = new CY.AsyncQueue() ;
       
    13 // pr2 this._q = new CY.Queue() ;
       
    14 	},
       
    15 	
       
    16 	setPreventClickOn : function () {
       
    17 		CY.log("setPreventClickOn !") ;
       
    18 		if (gLayout.isInFrame())
       
    19 			parent.f_interfaceFreeze()		
       
    20 		this._iPreventClick = true ;
       
    21 	},
       
    22 
       
    23 	setPreventClickOff : function () {
       
    24 		CY.log("setPreventClickOff !") ;
       
    25 		if (gLayout.isInFrame())
       
    26 			parent.f_interfaceUnfreeze()		
       
    27 		this._iPreventClick = false ;
       
    28 	},
       
    29 
       
    30 	removeCommentRet : function(args) {
       
    31 		var successfull = args['successfull'] ;
       
    32 		
       
    33 		var iComment = (successfull) ? args['failure']['iComment'] : args['success']['iComment'] ;
       
    34 		
       
    35 		if (successfull) {
       
    36 			var filterData = args['returned']['filterData'] ;
       
    37 			if (gLayout.isInFrame()) {
       
    38 				parent.f_updateFilterData(filterData) ;
       
    39 			}
       
    40 			
       
    41 			var y = gIComments.getTopPosition()[1] ;
       
    42 			
       
    43 			var comment = gDb.getComment(iComment.commentId) ;
       
    44 			this._q.add(
       
    45 		            function(){
       
    46 		            	
       
    47 		    	    	unpaintCommentScope(comment) ;
       
    48 		    	    	gIComments.close(comment.id) ;
       
    49 		    	    	gIComments.remove(comment.id) ;
       
    50 		    	    	if (comment.reply_to_id != null)
       
    51 		    	    		gIComments.refresh(comment.reply_to_id) ;
       
    52 		    	    	
       
    53 		    	    	gDb.del(comment) ;
       
    54 		    	    	
       
    55 		    	    	if (gLayout.isInFrame()) {
       
    56 		    		    	if (gDb.comments.length == 0 && gDb.allComments.length != 0) {
       
    57 		    		    		parent.f_enqueueMsg(gettext("no filtered comments left")) ;
       
    58 		    					parent.resetFilter() ;  
       
    59 		    		    	}
       
    60 		    		    	else {
       
    61 		    					// just counting here ...
       
    62 		    					var filterRes = gDb.computeFilterResults() ;
       
    63 		    					updateFilterResultsCount(filterRes['nbDiscussions'], filterRes['nbComments'], filterRes['nbReplies']) ;
       
    64 		    		    	}
       
    65 		    	    	}
       
    66 		            }
       
    67 			);
       
    68 			
       
    69 			this._animateTo(y) ;		
       
    70 		}
       
    71 		this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ;
       
    72 		this.resume() ;
       
    73 	},
       
    74 	
       
    75 	moderateCommentRet : function(args) {
       
    76 		var successfull = args['successfull'] ;
       
    77 
       
    78 		var iComment = (successfull) ? args['failure']['iComment'] : args['success']['iComment'] ;
       
    79 
       
    80 		if (successfull) {
       
    81 			var ret = args['returned'] ;
       
    82 			var comment = ret['comment'] ;
       
    83 
       
    84 			gDb.upd(comment) ;
       
    85 			
       
    86 			var shouldReset = gLayout.isInFrame() && !parent.f_isFrameFilterFieldsInit() ;
       
    87 			if (shouldReset){
       
    88 				parent.resetFilter() ;
       
    89 				this._showSingleComment(comment) ;
       
    90 			}
       
    91 			else 
       
    92 				iComment.changeModeration(comment) ;
       
    93 		}
       
    94 
       
    95 		this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ;
       
    96 		this.resume() ;
       
    97 	},
       
    98 	
       
    99 	saveCommentRet : function(args) {
       
   100 		var successfull = args['successfull'] ;
       
   101 		if (successfull) {
       
   102 			var formId = args['success']['formId'] ;
       
   103 			var ret = args['returned'] ;
       
   104 		
       
   105 			removeFormErrMsg(formId) ;
       
   106 		
       
   107 			if ('errors' in ret) { // validation error
       
   108 				var errors = ret['errors'] ;
       
   109 				for (var eltName in errors) {
       
   110 					addFormErrMsg(formId, eltName, errors[eltName]) ;
       
   111 				}
       
   112 				this._animateToTop() ;
       
   113 			}
       
   114 			else {
       
   115 				var isReply = function() {return (gNewReply != null) && (formId == gNewReply['ids']['formId']) ;} ;
       
   116 				var isNewComment = function() {return (gICommentForm != null) && (formId == gICommentForm['formId']) ;} ;
       
   117 				var isEdit = function() {return (gEdit != null) && (formId == gEdit['ids']['formId']) ;} ;
       
   118 				
       
   119 				// doing this here for the a priori moderation case
       
   120 				if (isNewComment())
       
   121 					this.hideICommentForm(cleanICommentForm()) ;
       
   122 				else if (isEdit())
       
   123 					this._hideEditForm() ;
       
   124 				else if (isReply())
       
   125 					this._hideNewReplyForm() ;
       
   126 				
       
   127 				if ("comment" in ret) { // won't be when add with a priori moderation
       
   128 					var comment = ret['comment'] ;
       
   129 	
       
   130 					gDb.upd(comment) ;
       
   131 	
       
   132 					var shouldReset = gLayout.isInFrame() && !parent.f_isFrameFilterFieldsInit() ;
       
   133 					if (shouldReset)
       
   134 						parent.resetFilter() ;
       
   135 					else { // ASSUMING filter is in init state ! (because when not // TODO $$$$$$$$$$$ this isn't true anymore .... when passing filter arguments in url !!
       
   136 							// in frame for now data can't be filtered)
       
   137 						if (comment.reply_to_id == null) { // not a reply
       
   138 							unpaintCommentScope(comment) ; // for the edit case
       
   139 							paintCommentScope(comment) ;
       
   140 						}
       
   141 					}
       
   142 	
       
   143 					// UPDATE FILTER DATA // TODO move ????
       
   144 					var filterData = ret['filterData'] ;
       
   145 					if (gLayout.isInFrame()) {
       
   146 						parent.f_updateFilterData(filterData) ;
       
   147 						updateResetFilterResultsCount() ;				
       
   148 					}
       
   149 
       
   150 					if (isReply()) { // add reply case
       
   151 						if (!shouldReset) {
       
   152 							this._insertReply(comment) ;
       
   153 						}
       
   154 					}
       
   155 					else { // edit (reply or comment) or add (comment) case
       
   156 				    	this._showSingleComment(comment) ;
       
   157 					}
       
   158 				}
       
   159 				else 
       
   160 					this._animateToTop() ;
       
   161 			}
       
   162 
       
   163 		}
       
   164 		else { // TODO ? ALL ret-FUNCTIONS ?
       
   165 			this._q.add({id:"expl", fn:function () {CY.log('in example .........') ;}}) ;
       
   166 			this._q.promote("expl") ;
       
   167 		}
       
   168 
       
   169 		this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ;
       
   170 		this.resume() ;
       
   171 	},
       
   172 	
       
   173 	example : function () {
       
   174 		CY.log('in example .........') ;
       
   175 	},
       
   176 
       
   177 	moderateComment	: function(iComment, state) {
       
   178 		var comment = gDb.getComment(iComment['commentId']) ;
       
   179         this._q.add(
       
   180 	            {fn:CY.bind(this.setPreventClickOn, this)},
       
   181 	            {autoContinue:false, fn:CY.bind(doExchange, null, "editComment", {'comment_key':comment.key, 'state':state}, null, this.moderateCommentRet, this, {'iComment':iComment}, gettext("could not save comment"))}
       
   182 	            ).run();
       
   183 	},
       
   184 	
       
   185 	_saveComment : function(serverFun, formId) {
       
   186         this._q.add(
       
   187 	            {fn:CY.bind(this.setPreventClickOn, this)},
       
   188 	            {autoContinue:false, fn:CY.bind(doExchange, null, serverFun, {}, formId, this.saveCommentRet, this, {'formId':formId}, gettext("could not save comment"))}
       
   189 	            ).run();
       
   190 	},
       
   191 	
       
   192 	editComment : function() {
       
   193 		this._saveComment("editComment", gEdit['ids']['formId']) ;
       
   194 	},
       
   195 	
       
   196 	saveComment : function(formId) {
       
   197 		this._saveComment("addComment", formId) ;
       
   198 	},
       
   199 	
       
   200 	removeComment : function(iComment) {
       
   201 		checkForOpenedDialog(iComment, function() {
       
   202 			if (gLayout.isInFrame()) {
       
   203 				parent.f_yesNoDialog(gettext("Are you sure you want to delete this comment?"), gettext("Warning"), function() { this.animateToTop() ;}, this, null, function() {
       
   204 					var comment = gDb.getComment(iComment.commentId) ;
       
   205 			        this._q.add(
       
   206 				            {fn:CY.bind(this.setPreventClickOn, this)},
       
   207 				            {autoContinue:false, fn:CY.bind(doExchange, null, "removeComment", {'comment_key':comment.key}, null, this.removeCommentRet, this, {'iComment':iComment}, gettext("could not remove comment"))}
       
   208 				            ).run();
       
   209 				}, this, null) ;
       
   210 		        
       
   211 			}
       
   212 //			else {
       
   213 //				alert("TODO : can't yet delete comments when not embed in text_view_frame because can't 'dialog' confirmation") ;
       
   214 //			}
       
   215 		
       
   216 		}, this, null) ;
       
   217 	},
       
   218 	
       
   219 	resume : function(commentDbIds, mouseXY) {
       
   220 		this._q.run() ;
       
   221 	},
       
   222 	
       
   223 	resetAutoContinue : function(callbackId) {
       
   224 		this._q.getCallback(callbackId).autoContinue = true;
       
   225 	},
       
   226 	
       
   227 	hideICommentForm : function(funObj) {
       
   228 //		this._q.add({fn:function() {persistICommentFormValues();}}) ;
       
   229 		this._q.add({autoContinue:false, fn:CY.bind(gICommentForm['animationHide'].run, gICommentForm['animationHide'])}) ;
       
   230 //		this._q.add({fn:function() {cleanICommentForm();}}) ;
       
   231 		if (funObj)
       
   232 			this._q.add(funObj) ;
       
   233 	},
       
   234 	
       
   235 	/* ANIMATION DRIVEN INTERFACE CHANGES */
       
   236 	
       
   237 	showCommentForm : function(iComment) {
       
   238 		checkForOpenedDialog(null, function() {
       
   239 	        this._q.add({fn:CY.bind(this.setPreventClickOn, this)});
       
   240 			this._q.add({fn:function() {
       
   241 								if (iComment == null) {
       
   242 									var selection = getSelectionInfo() ;
       
   243 									updateICommentFormSelection(selection) ;
       
   244 								}
       
   245 								showICommentForm(iComment);
       
   246 							}}) ;
       
   247 			this._q.add({autoContinue:false, fn:CY.bind(gICommentForm['animationShow'].run, gICommentForm['animationShow'])},
       
   248 					{fn:CY.bind(this.setPreventClickOff, this)}
       
   249 					).run();
       
   250 		}, this, null) ;
       
   251 	},
       
   252 	
       
   253 	showEditForm : function(iComment) {
       
   254 		checkForOpenedDialog(null, function() {
       
   255 	        this._q.add({fn:CY.bind(this.setPreventClickOn, this)});
       
   256 
       
   257 	        this._q.add({fn:function() {
       
   258 	        				showEditForm(iComment) ;
       
   259 	        			}});
       
   260 			this._animateToTop() ;
       
   261 			
       
   262 	        this._q.add({fn:CY.bind(this.setPreventClickOff, this)});
       
   263 	        this._q.run() ;
       
   264 		}, this, null) ;
       
   265 	},
       
   266 	
       
   267 	showReplyForm : function(iComment) {
       
   268 		checkForOpenedDialog(null, function() {
       
   269 	        this._q.add({fn:CY.bind(this.setPreventClickOn, this)});
       
   270 
       
   271 	        this._q.add({fn:function() {
       
   272 	        					instanciateNewReplyForm(iComment) ;
       
   273 	        					}});
       
   274 			this._animateToTop() ;
       
   275 			
       
   276 	        this._q.add({fn:CY.bind(this.setPreventClickOff, this)});
       
   277 	        this._q.run() ;
       
   278 		}, this, null) ;
       
   279 	},
       
   280 	
       
   281 	cancelICommentForm : function() {
       
   282         this._q.add({fn:CY.bind(this.setPreventClickOn, this)});
       
   283         
       
   284 //		this._q.add({fn:function() {cleanICommentForm();}}) ;
       
   285     	this.hideICommentForm() ;
       
   286     	
       
   287         this._q.add({fn:CY.bind(this.setPreventClickOff, this)});
       
   288         this._q.run() ;
       
   289 	},
       
   290 	cancelEdit : function() {
       
   291         this._q.add({fn:CY.bind(this.setPreventClickOn, this)});
       
   292         
       
   293     	this._q.add({fn:function() {cancelEditForm();}}) ;
       
   294     	this._animateToTop() ;
       
   295     	
       
   296         this._q.add({fn:CY.bind(this.setPreventClickOff, this)});
       
   297         this._q.run() ;
       
   298 	},
       
   299 	cancelReply : function() {
       
   300         this._q.add({fn:CY.bind(this.setPreventClickOn, this)});
       
   301         
       
   302     	this._q.add({fn:function() {cancelNewReplyForm();}}) ;
       
   303     	this._animateToTop() ;
       
   304     	
       
   305         this._q.add({fn:CY.bind(this.setPreventClickOff, this)});
       
   306         this._q.run() ;
       
   307 	},
       
   308 	changeScopeFormClick : function() {
       
   309         this._q.add({fn:CY.bind(this.setPreventClickOn, this)});
       
   310         
       
   311     	this._q.add({fn:function() {changeScopeFormClick();}}) ;
       
   312     	this._animateToTop() ;
       
   313     	
       
   314         this._q.add({fn:CY.bind(this.setPreventClickOff, this)});
       
   315         this._q.run() ;
       
   316 	},
       
   317 	// this is invoked during queue execution
       
   318 	_hideNewReplyForm : function() {
       
   319 		this._q.add({fn:function() {
       
   320 					cleanNewReplyForm() ; 
       
   321 					cancelNewReplyForm() ;}}) ;
       
   322 	},
       
   323 	// this is invoked during queue execution
       
   324 	_hideEditForm : function() {
       
   325 		this._q.add({fn:function() {
       
   326 					cancelEditForm() ;}}) ;
       
   327 	},
       
   328 	// this is invoked during queue execution
       
   329 	_insertReply : function(comment) {
       
   330 		this._q.add({fn:function() {
       
   331 					var parentComment = gDb.getComment(comment.reply_to_id) ;
       
   332 					var parentThread = gDb.getThreads([parentComment]) ;
       
   333 					var previousComment = parentThread[parentThread.length - 2] ; // - 2 because now that comment has been added comment is parentThread[parentThread.length - 1]
       
   334 
       
   335 					var iComment = gIComments.insertAfter(previousComment, comment) ;
       
   336 					// iComment CAN'T BE NULL ! (TODO check that there is a
       
   337 					// check server side that parent exists when adding a reply
       
   338 					// !)
       
   339 					
       
   340 					var parentPosition = gIComments.getPosition(comment.reply_to_id) ;
       
   341 					iComment.setPosition(parentPosition) ;
       
   342 					
       
   343 					// check if activation is necessary (will always be ?)
       
   344 					var comment_path = gDb.getPath(comment) ;
       
   345 					var topComment = comment_path[comment_path.length - 1] ;
       
   346 					if (gIComments.isTopActive(topComment.id))
       
   347 						iComment.activate() ;
       
   348 
       
   349 					iComment.show() ;}}) ;
       
   350     	this._animateToTop() ;
       
   351 	},
       
   352 	_showSingleComment : function(comment) {
       
   353 		if (comment != null) {
       
   354 			var path = gDb.getPath(comment) ;
       
   355 			var topAncestorComment = path[path.length - 1] ;
       
   356 			var topY = CY.get(".c-id-"+topAncestorComment.id).getY() ;
       
   357 			this._showComments([topAncestorComment.id], topY, false) ;
       
   358 			// optim when browsing comments with no reply			
       
   359 			if (topAncestorComment.replies.length > 0)
       
   360 				this._animateTo(topY) ;
       
   361 		}
       
   362 	},
       
   363 
       
   364 	showSingleComment : function(comment) {
       
   365 		this._q.add({fn:CY.bind(this.setPreventClickOn, this)}) ;
       
   366 		this._showSingleComment(comment) ;
       
   367 		this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ;
       
   368 		this._q.run();
       
   369 	},
       
   370 	
       
   371 	browse : function(order, whereto) { 
       
   372 		var comment = gIComments.browse(order, whereto) ;
       
   373 		if (comment != null) 
       
   374 			this.showSingleComment(comment) ;
       
   375 	},
       
   376 	
       
   377 	_showComments : function(commentDbIds, topY, showingAll) {
       
   378 		this._q.add(
       
   379 			{fn:function() {
       
   380 				gShowingAllComments = showingAll ;			
       
   381 				gIComments.hide() ; 
       
   382 				var cs = CY.Array.map(commentDbIds, function(id) { return gDb.getComment(id) ; }) ;
       
   383 				var comments = gDb.getThreads(cs) ;
       
   384 				gIComments.fetch(comments) ;
       
   385 	
       
   386 				if (commentDbIds.length > 0) {
       
   387 					if (!showingAll) {
       
   388 						gIComments.activate(commentDbIds[0]) ;
       
   389 						var scopeStart = CY.get(".c-id-"+commentDbIds[0]) ;
       
   390 						if (!scopeStart.inViewportRegion())
       
   391 							scopeStart.scrollIntoView(true) ;
       
   392 					}
       
   393 					else {
       
   394 						CY.get('document').set('scrollTop', 0) ; 
       
   395 					}
       
   396 				}
       
   397 				
       
   398 				gIComments.setPosition([gConf['iCommentLeftPadding'], topY]) ;
       
   399 	
       
   400 				gIComments.show() ;
       
   401 			}}) ;
       
   402 	},
       
   403 	
       
   404 	_animateTo : function(topY) {
       
   405 		this._q.add({fn:function() {
       
   406 						gIComments.setAnimationToPositions(topY) ;
       
   407 						}},
       
   408 					{id:"animationRun", autoContinue:false, fn:CY.bind(gIComments.runAnimations, gIComments)}
       
   409 	            ) ;
       
   410 	},
       
   411 	
       
   412 	_animateToTop : function() {
       
   413 		var topPos = gIComments.getTopPosition() ;
       
   414 		if (topPos != null)
       
   415 			this._animateTo(topPos[1]) ;
       
   416 	},
       
   417 	
       
   418 	animateToTop : function() {
       
   419 		this._q.add({fn:CY.bind(this.setPreventClickOn, this)}) ;
       
   420 		this._animateToTop() ;
       
   421 		this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ;
       
   422 		this._q.run();
       
   423 	},
       
   424 	
       
   425 	showAllComments : function() {
       
   426 		checkForOpenedDialog(null, function() {
       
   427 			gShowingAllComments = true ;
       
   428 			var allTopComments = CY.Array.map(gDb.comments, function(c){return c.id;}) ;
       
   429 			this.showComments(allTopComments, [0,0], true) ;
       
   430 		}, this, null) ;
       
   431 	},
       
   432 
       
   433 	showComments : function(commentDbIds, mouseXY, showingAll) {
       
   434 		checkForOpenedDialog(null, function() {
       
   435 			this._q.add({fn:CY.bind(this.setPreventClickOn, this)}) ;
       
   436 			this._showComments(commentDbIds, mouseXY[1], showingAll) ;
       
   437 			this._animateTo(mouseXY[1]) ;
       
   438 			this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ;
       
   439 			this._q.run();
       
   440 		}, this, null) ;
       
   441 	},
       
   442 
       
   443 	openComment : function(iComment) { 
       
   444 		this._q.add({fn:CY.bind(this.setPreventClickOn, this)}) ;
       
   445 
       
   446 		var y = gIComments.getTopPosition()[1] ;
       
   447 		this._q.add({fn:function() {
       
   448 			gIComments.open(iComment.commentId) ;
       
   449     		gIComments.refresh(iComment.commentId) ;
       
   450 		}}) ;
       
   451 		this._animateTo(y) ;
       
   452 		
       
   453 		this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ;
       
   454 		this._q.run();
       
   455 	},
       
   456 	
       
   457 	closeComment : function(iComment) { 
       
   458 		checkForOpenedDialog(iComment, function() {
       
   459 			this._q.add({fn:CY.bind(this.setPreventClickOn, this)}) ;
       
   460 	
       
   461 			var y = gIComments.getTopPosition()[1] ;
       
   462 			this._q.add({fn:function() {
       
   463 				var comment = gDb.getComment(iComment.commentId) ;
       
   464 				gIComments.close(iComment.commentId) ;
       
   465 		    	if (comment.reply_to_id != null)
       
   466 		    		gIComments.refresh(comment.reply_to_id) ;
       
   467 			}}) ;
       
   468 			this._animateTo(y) ;
       
   469 	
       
   470 			this._q.add({fn:CY.bind(this.setPreventClickOff, this)}) ;
       
   471 			this._q.run() ;
       
   472 		}, this, null) ;
       
   473 	},
       
   474 	
       
   475 	activate : function(iComment) {
       
   476 		gIComments.activate(iComment.commentId) ;
       
   477 	}
       
   478 }
       
   479 			
       
   480 readyForAction = function () {
       
   481 	return !gSync._iPreventClick ;
       
   482 };