view public/viewer/viewer.html @ 93:d66ac07e1c36 draft

modified createMention action
author one
date Tue, 12 Mar 2013 17:44:03 +0900
parents 75d45f808217
children b0fda0545bce
line wrap: on
line source

<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>R-Consensus</title>
<link rel='stylesheet' href="form.css">
<script src='form.js'></script>
<script type="text/javascript" src="js/lib/jquery-1.8.1-min.js"></script>
<script type="text/javascript" src="js/lib/jquery-ui-1.8.23-min.js"></script>
<script type="text/javascript" src="js/lib/jquery.ui.touch-punch.min.js"></script>
<script type="text/javascript" src="js/lib/jsBezier-0.4-min.js"></script>
<script type="text/javascript" src="js/1.3.15/jsPlumb-util-1.3.15-RC1.js"></script>
<script type="text/javascript" src="js/1.3.15/jsPlumb-dom-adapter-1.3.15-RC1.js"></script>
<script type="text/javascript" src="js/1.3.15/jsPlumb-1.3.15-RC1.js"></script>
<script type="text/javascript" src="js/1.3.15/jsPlumb-defaults-1.3.15-RC1.js"></script>
<script type="text/javascript" src="js/1.3.15/jsPlumb-renderers-svg-1.3.15-RC1.js"></script>
<script type="text/javascript" src="js/1.3.15/jsPlumb-renderers-canvas-1.3.15-RC1.js"></script>
<script type="text/javascript" src="js/1.3.15/jsPlumb-renderers-vml-1.3.15-RC1.js"></script>
<script type="text/javascript" src="js/1.3.15/jquery.jsPlumb-1.3.15-RC1.js"></script>
<script type="text/javascript" src='treeArrangement.js'></script>
<script type="text/javascript">
var LOAD_INTERVAL=5;
var BASE_URL="";
if(!Array.prototype.filter){
	Array.prototype.filter=function(func){
		var arr=[];
		for(var i=0;i<this.length;i++)if(func(this[i]))arr.push(this[i]);
		return arr;
	}
}

var userName;

var treeInfo;
var userList=[];
var root_id;
function loadConsensus(id){
	function onload(json){
		document.title="R-Consensus:"+json.toulmin.title;
		$("#headertitle_main").text(json.toulmin.title)
		if(treeInfo){
			updateToNew(json);
		}else{
			console.log(JSON.parse(JSON.stringify(json)));
			treeInfo=createJSONTreeInfo(json)
			//userList=getUserListFromJSONTree(treeInfo.root);
			showUserList([]);
			updateNode(treeInfo.root);
			updateTree();
		}
	}
	$.ajax({
		url:BASE_URL+"/consensus/browse/latest/"+id,
		success:function(o){onload(o)},
		type:"GET",cache:false,
		error:function(o){console.log("ERROR",o)}
	});
}
function loadUserList(){
	$.ajax({
		url:BASE_URL+"/users/all",
		success:function(o){userList=o.sort();showUserList([]);},
		type:"GET",cache:false,
		error:function(o){console.log("ERROR",o)}
	});
}

$(function(){
	userName=localStorage.userName;
	if(userName)start();
	else $("#loginPopup").css("display","block");
})
function login(uname){
	userName=localStorage.userName=uname;
	start();
}
function start(){
	$.ajax({
		url:BASE_URL+"/users/create/"+userName,
		success:function(o){console.log(o)},
		type:"PUT",cache:false,
		error:function(o){console.log(o)}
	});
	
	popupInit();
	jsPlumb.importDefaults({
		Connector : [ "Straight", { curviness:50 } ],
		PaintStyle : { strokeStyle:"gray", lineWidth:2 },
		EndpointStyle : {},
		Anchors: ["BottomCenter","TopCenter"]
	});
	var consensus_id=(location.search.match("[0-9]+")||[])[0];
	if(consensus_id){
		root_id=consensus_id;
		loadUserList()
		loadConsensus(consensus_id);
		setInterval(function(){loadUserList();loadConsensus(consensus_id)},LOAD_INTERVAL*1000);
	}else{
		document.body.innerHTML="<div style='color:white;font-size:64px'>No ClaimID Specified.<br><a href='index.html' style='color:#88f'>back</a></div>";
	}
}

function updateToNew(json){
	var t2=createJSONTreeInfo(json)
	updateJSONTreeDiff(treeInfo.root,t2.root);
	
	updateNode(treeInfo.root);
	treeInfo.newLayout=t2.layout;
	var cnt=0,time=500;
	var time0=new Date();
	var prevCnt=0;
	function tfunc(t){return 2*t-t*t}
	function animation(){
		var cnt=(new Date()-time0)/time;
		if(cnt<1){
			if(prevCnt!=cnt){
				var pt=tfunc(prevCnt);
				var t=tfunc(cnt);
				animateTree((t-1)/(pt-t));
				prevCnt=cnt;
			
			}
			setTimeout(animation,10);
		}else{
			animateTree(0);
		}
		updateNode(treeInfo.root);
		updateTree();
	}
	animation();
}

var ViewParam={
	offsetTop:100,
	offsetBottom:100,
	offsetLeft:100,
	offsetRight:100,
	nodeWidth:120,
	nodeHeight:60,
	intervalX:140,
	intervalY:120
};

function animateTree(t){
	function animateNodePosition(node,t){
		node.position.x=(node.position.x*t+node.newPosition.x)/(1+t);
		node.position.y=(node.position.y*t+node.newPosition.y)/(1+t);
		for(var i=0;i<node.mentions.length;i++){
			animateNodePosition(node.mentions[i],t);
		}
		if(t==0){
			if(node.newPosition.remove){
				jsPlumb.removeAllEndpoints(node.view);
				$(node.view).remove();
			}
			node.mentions=node.mentions.filter(function(n){return !n.newPosition.remove});
		}
	}
	animateNodePosition(treeInfo.root,t);
	treeInfo.layout.left=(treeInfo.layout.left*t+treeInfo.newLayout.left)/(1+t);
	treeInfo.layout.right=(treeInfo.layout.right*t+treeInfo.newLayout.right)/(1+t);
	treeInfo.layout.depth=(treeInfo.layout.depth*t+treeInfo.newLayout.depth)/(1+t);
}

function updateTree(){
	with(treeInfo.layout){
		$("#treeRoot").css({
			left:ViewParam.offsetLeft+ViewParam.nodeWidth/2-ViewParam.intervalX*left,
			top:ViewParam.offsetTop+ViewParam.nodeHeight/2});
		$("#treeMain").css({
			width:ViewParam.intervalX*(right-left)+ViewParam.nodeWidth+ViewParam.offsetLeft+ViewParam.offsetRight,
			height:ViewParam.intervalY*(depth-1)+ViewParam.nodeHeight+ViewParam.offsetTop+ViewParam.offsetBottom,
			top:50});
	}
	jsPlumb.repaintEverything();
}


var relationJPMap={
	suggestion:"提案",
	refutation:"反論",
	question:"質問"
};
function updateNode(node){
	if(updateClaimElement(node)){
		var fc=$("#treeRoot")[0].firstChild;
		if(fc)$("#treeRoot")[0].insertBefore(node.view[0],fc);
		else $("#treeRoot").append(node.view);
	}
	node.view.css({
		left:node.position.x*ViewParam.intervalX-ViewParam.nodeWidth/2,
		top:node.position.y*ViewParam.intervalY-ViewParam.nodeHeight/2
	});	
	var childs=node.mentions;
	for(var i=0;i<childs.length;i++){
		var child=childs[i];
		var created=!child.view;
		updateNode(child);
		if(created){
			var c=jsPlumb.connect({source:node.view[0],target:child.view[0]});
			c.setLabel({label:"<span style='color:white'>"+(relationJPMap[child.relation]||child.relation)+"</span>",cssStyle:"color:white"});
		}
	}
}

var focusedUser=null;
function setFocusedShadowEverything(){
	function recFocusShadow(node){
		setFocusedShadow(node);
		for(var i=0;i<node.mentions.length;i++){
			recFocusShadow(node.mentions[i]);
		}
	}
	recFocusShadow(treeInfo.root);
}
function setFocusedShadow(node){
	var name=focusedUser||userName;
	var color;
	console.log(node.info.author)
	if(node.info.author==name)color="#afa";
	else{
		var users=node.info.users,status;
		for(var i=0;i<users.length;i++){
			var u=users[i];
			if(u.id==name){status=u.status;break;}
		}
		color=({agreed:"#aaf",denied:"#faa",pend:"white",unknown:"white"})[status];
	}
	node.view.css("box-shadow",color?color+" 0 0 30px":"none");
}
function updateClaimElement(node){
	var created=false;
	if(!node.view){
		created=true
		node.view=$("<div class='claimNode'/>");
		node.view.click(function(){showClaim(node);});
		node.view.hover(
			function(){div.css("box-shadow","white 0 0 50px");showUserList(node.info.users,node.info.author)},
			function(){try{setFocusedShadow(node);}catch(e){console.log(e);}showUserList([])}
		)
	}
	setFocusedShadow(node);
	var div=node.view;
	div.text(node.info.toulmin.title);
	var statusBackground={pass:"#aaf",unknown:"#fff",failed:"#faa",fail:"#faa"};
	var statusBorder={pass:"#66a",unknown:"#aaa",failed:"#a66",fail:"#a66"};
	div.css("background",statusBackground[node.info.status]||"white");
	div.css("border-color",statusBorder[node.info.status]||"white");
	return created;
}


function showUserList(users,author){
	var statusMap={};
	var userListElement=$(".userList");
	userListElement.text('')
	if(author)statusMap['#'+author]='author';
	for(var i=0;i<users.length;i++){
		statusMap['#'+users[i].id]=users[i].status;
	}
	for(var i=0;i<userList.length;i++){
		var u=userList[i];
		var ue=createUserElement(u==userName?"あなた("+u+")":u,statusMap['#'+u]);
		if(u==userName){
			ue.css({fontWeight:"bold"})
		}
		ue.appendTo(userListElement);
		with({name:u,element:ue}){
			ue.hover(
				function(){
					element.css("opacity",1);
					focusedUser=name;setFocusedShadowEverything()
				},
				function(){
					element.css("opacity",0.5);
					focusedUser=userName;setFocusedShadowEverything()
				}
			)
		}
		
	}
	$(".userList").css("opacity","1");
}
function hideUserList(){
	$(".userStatus").css("background","none");
	$(".userItem").css("opacity","1");
	$(".userList").css("opacity","0.2");
}
</script>
<style>
div.claimNode{
	z-index:20;
	position:absolute;width:92px;height:40px;font-size:12px;padding:4px;background:white;
	border:2px solid silver;
	overflow:hidden;
	border-radius:5px;
	cursor:pointer;
}
body{background-color:black;}

div.userList{
	position:fixed;
	z-index:30;
	right:0;top:0;
	width:160px;
}
div.header{
	position:absolute;
	left:0;top:0;
	z-index:5;
	height:50px;
	width:100%;
	background:#223;
	background:-moz-linear-gradient(top,#002,#223);
	background:-webkit-gradient(linear,left top,left bottom,from(#002),to(#223));
	color:silver;
	font-size:40px;
}
div.revision{
    position:absolute;
    left:0;top:50px;
    z-index:5;
    height:25px;
    width:100%;
    color:silver;
    font-size:20px;
}

</style>
<script>
function resetMentionForm(){
      var keys=['title','contents','w','d','b','q','r'];
      for(var i=0;i<keys.length;i++)$("#mentionform_"+keys[i]).val("");
      $("#mention_option")[0].className="option";
}
var formClaim;
var claimUserMap,mentionUserMap;
function showClaim(claim){
	formClaim=claim;
	var info=claim.info;
      var keys=['title','contents','w','d','b','q','r'];
      for(var i=0;i<keys.length;i++)$("#claimform_"+keys[i]).val(info.toulmin[keys[i]]);
	
	var status="";
	for(var i=0;i<info.users.length;i++)if(info.users[i].id==userName)status=info.users[i].status;
	var op=({denied:1,pend:2,agreed:3})[status];
	
	$("#claim_status").text(info.status)
	$("#claim_status").css("color",({pass:"blue",failed:"red",fail:"red",unknown:"black"})[info.status]);
	$("#agree_option")[0].className="option"+(op?" option"+op:"");
	$("#agree_option").css("display",status?"block":"none");
	
	$("#claim_button").css("display",(userName==info.author)?"block":"none");
	$("#claimvote_option").css("display",status?"block":"none");
	
	$("#claimbody")[0].className="claim_contents";
	$("#mentionbody")[0].className="mention_contents";
	
	$("#claim_author").text(info.author);
	$("#mention_author").text(userName);
	$("#claimvote_option")[0].className="option option"+(claim.agreeType=="majority"?2:1);
	$("#mentionvote_option")[0].className="option option1";
	var stateMap={};
	for(var i=0;i<info.users.length;i++)stateMap['#'+info.users[i].id]=info.users[i].status;
	claimUserMap=new HashSet(info.users.map(function(u){return u.id}));
	mentionUserMap=new HashSet();
	$("#claim_users").text("");
	$("#mention_users").text("");
	if(userName!=info.author)mentionUserMap.add(info.author);
	for(var i=0;i<userList.length;i++){
		var name=userList[i];
		if(name!=info.author){
			var status=stateMap['#'+name];
			createUserSelectItem(name,status,claimUserMap).appendTo($("#claim_users"));
		}if(name!=userName){
			createUserSelectItem(name,name==info.author?"unknown":"",mentionUserMap).appendTo($("#mention_users"));
		}
	}
      resetMentionForm();
	popupShowMain()
}


function claimSave(){
	var claim=formClaim;
	var info=claim.info;
	var id=claim.id||root_id;
	var agreeType=[null,"unanimously","majority"][($('#claimvote_option')[0].className.match("[0-9]+")||"0")[0]];
	var title=$('#claimform_title').val();
	var contents=$('#claimform_contents').val();
	var d=$('#claimform_d').val();
	var w=$('#claimform_w').val();
	var b=$('#claimform_b').val();
	var q=$('#claimform_q').val();
	var r=$('#claimform_r').val();
	var users=claimUserMap.toArray();
	var errors=[];
	if(!title)errors.push("タイトル");
	if(!agreeType)errors.push("採決方法");
	if(users.length==0)errors.push("同意を取るユーザ");
	if(errors.length){
		alert("未入力項目:"+errors.join(", "));
	}else{
		$.ajax({
			url:BASE_URL+"/claims/edit/"+id,
			success:function(o){loadConsensus(root_id)},
			type:"POST",cache:false,
			contentType:"application/json",
			data:JSON.stringify({type:agreeType,toulmin:{title:title,contents:contents,q:q,d:d,w:w,b:b,r:r},author:userName,users:users}),
			error:function(o){console.log("ERROR",o)}
		});
		popupHideAll();
	}
}
function claimAgree(status){
	var claim=formClaim;
	var info=claim.info;
	var id=claim.id||root_id;
	$.ajax({
		url:BASE_URL+"/claims/answer/"+id+"/"+userName+"/"+status,
		success:function(o){loadConsensus(root_id)},
		type:"POST",cache:false,
		error:function(o){console.log("ERROR",o)}
	});
	popupHideAll();
}
function mentionSave(){
	var claim=formClaim;
	var info=claim.info;
	var id=claim.id||root_id;
	var mentionType=[null,"refutation","question","suggestion"][($('#mention_option')[0].className.match("[0-9]+")||"0")[0]];
	var agreeType=[null,"unanimously","majority"][($('#mentionvote_option')[0].className.match("[0-9]+")||"0")[0]];
	var title=$('#mentionform_title').val();
	var contents=$('#mentionform_contents').val();
	var d=$('#mentionform_d').val();
	var w=$('#mentionform_w').val();
	var b=$('#mentionform_b').val();
	var q=$('#mentionform_q').val();
	var r=$('#mentionform_r').val();
	var users=mentionUserMap.toArray();
	var author=userName;
	var errors=[];
	if(!title)errors.push("タイトル");
	if(!agreeType)errors.push("採決方法");
	if(!mentionType)errors.push("反論質問提案");
	if(users.length==0)errors.push("同意を取るユーザ");
	if(errors.length){
		alert("未入力項目:"+errors.join(", "));
	}else{
		$.ajax({
			url:BASE_URL+"/claims/"+mentionType+"/"+id+"/create",
			success:function(o){loadConsensus(root_id)},
			type:"POST",cache:false,contentType:"application/json",
			data:JSON.stringify({type:agreeType,toulmin:{title:title,contents:contents,q:q,d:d,w:w,b:b,r:r},author:author,users:users}),
			error:function(o){console.log("ERROR",o)}
		});
		popupHideAll();
	}
}

</script>
<div class='header'>
<nobr id='header_title'><a href='index.html'>Home</a><span id='headertitle_main' style='margin-left:40px;'>loading</span></nobr>
</div>
<div class="revision">
    <span onclick='var id=location.search.match("[0-9]+");location.href="/revisionviewer.html?="+id'>revision</span>
</div>

<div style="position:relative;left:0;top:0;" id='treeMain'>
<div style="position:absolute;width:0;height:0;left:100;" id='treeRoot'>
</div>
</div>

<div class='userList'></div>


<div id='popup_base' style='display:none;z-index:100'>
<div id='popup_background'></div>
<div class='popup_center'>
<div class='claiminfo' id='claiminfo'>
	<div class='claim_title'><input placeholder="title" id='claimform_title'></div>
	<div id='claimbody' class='claim_contents'>
		<div class='claim_menu'>
			<div class='menu_item menu_contents' onclick="$('#claimbody')[0].className='claim_contents'">Contents</div>
			<div class='menu_item menu_toulmin' onclick="$('#claimbody')[0].className='claim_toulmin'">Toulmin</div>
			<div class='menu_item menu_users'  onclick="$('#claimbody')[0].className='claim_users'">Users</div>
			<div id='claim_status'></div>
		</div>
		<div class='claim_main main_contents'>
			<textarea placeholder='contents' id='claimform_contents'></textarea>
		</div>
		<div class='claim_main main_toulmin'>
			<div class='item_toulmin'><span>データ</span><input id='claimform_d'></div>
			<div class='item_toulmin'><span>論拠 </span><input id='claimform_w'></div>
			<div class='item_toulmin'><span>裏付け</span><input id='claimform_b'></div>
			<div class='item_toulmin'><span>限定詞</span><input id='claimform_q'></div>
			<div class='item_toulmin'><span>反駁 </span><input id='claimform_r'></div>
		</div>
		<div class='claim_main main_users'>
			<span class='author_label'>作者:</span>
			<span class='author_name' id='claim_author'></span>
			<div class='option option1' id='claimvote_option'>
				<span class='option option1 vote1' onclick="$('#claimvote_option')[0].className='option option1'">全会一致</span>
				<span class='option option2 vote2' onclick="$('#claimvote_option')[0].className='option option2'">多数決</span>
			</div>
			<div id='claim_users'></div>
		</div>
	</div>
	<div class='claim_footer'>
		<span onclick='popupShowSubMain()' class='button mention_button'>mention</span>
		<div class='option' id='agree_option'>
			<span class='option option1 agree1' onclick="$('#agree_option')[0].className='option option1';claimAgree('denied');">否認</span>
			<span class='option option2 agree2' onclick="$('#agree_option')[0].className='option option2';claimAgree('pend');">保留</span>
			<span class='option option3 agree3' onclick="$('#agree_option')[0].className='option option3';claimAgree('agreed');">合意</span>
		</div>
		<div id='claim_button'>
		<span class='button cancel' onclick="popupHideAll()">cancel</span>
		<span class='button save' onclick="claimSave()">save</span>
		</div>
	</div>
	<div class='cover' id='claim_cover'></div>
</div>


<div class='mentioninfo' id='mentioninfo'>
	<div class='claim_title'><input placeholder="title" id='mentionform_title'></div>
	<div id='mentionbody' class='mention_contents'>
		<div class='claim_menu'>
			<div class='menu_item menu_contents' onclick="$('#mentionbody')[0].className='mention_contents'">Contents</div>
			<div class='menu_item menu_toulmin' onclick="$('#mentionbody')[0].className='mention_toulmin'">Toulmin</div>
			<div class='menu_item menu_users'  onclick="$('#mentionbody')[0].className='mention_users'">Users</div>
		</div>
		<div class='mention_main main_contents'>
			<textarea placeholder='contents' id='mentionform_contents'></textarea>
		</div>
		<div class='mention_main main_toulmin'>
			<div class='item_toulmin'><span>データ</span><input id='mentionform_d'></div>
			<div class='item_toulmin'><span>論拠 </span><input id='mentionform_w'></div>
			<div class='item_toulmin'><span>裏付け</span><input id='mentionform_b'></div>
			<div class='item_toulmin'><span>限定詞</span><input id='mentionform_q'></div>
			<div class='item_toulmin'><span>反駁 </span><input id='mentionform_r'></div>
		</div>
		<div class='mention_main main_users'>
			<span class='author_label'>作者:</span>
			<span class='author_name' id='mention_author'></span>
			<div class='option option1' id='mentionvote_option'>
				<span class='option option1 vote1' onclick="$('#mentionvote_option')[0].className='option option1'">全会一致</span>
				<span class='option option2 vote2' onclick="$('#mentionvote_option')[0].className='option option2'">多数決</span>
			</div>
			<div id='mention_users'></div>
		</div>
	</div>	
	<div class='claim_footer'>
		<div class='option' id='mention_option'>
			<span class='option option1 mention1' onclick="$('#mention_option')[0].className='option option1'">反論</span>
			<span class='option option2 mention2' onclick="$('#mention_option')[0].className='option option2'">質問</span>
			<span class='option option3 mention3' onclick="$('#mention_option')[0].className='option option3'">提案</span>
		</div>
		<span class='button cancel' onclick="popupShowMain()">cancel</span>
		<span class='button save' onclick="mentionSave()">save</span>
	</div>
	<div class='cover' id='mention_cover'></div>
</div>
</div>
</div>




<div id="loginPopup" style='position:fixed;left:0;top:0;width:100%;height:100%;z-index:10;display:none;'>
<div style='position:absolute;left:0;top:0;width:100%;height:100%;background:black;opacity:0.5'></div>
<div style='position:absolute;left:50%;top:50%;'>
<div style='position:absolute;left:-160px;top:-80px;width:320px;height:120px;background:white'>
<form onsubmit="try{a=$('#loginUserName');if(a.val()){login(a.val());$('#loginPopup').remove();}}catch(e){console.log(e)}return false">
<div style='position:absolute;left:20px;top:15px;font-size:24px;width:280;text-align:center;'>
	R-Consensus Login
</div>
<input type=text placeholder='username' style='position:absolute;left:20px;top:70px;width:180px;font-size:16px;height:24px;' id='loginUserName'>
<span style='position:absolute;left:220px;top:70px;width:80px;font-size:16px;height:24px;line-height:24px;' class='button' value='login' onclick="try{a=$('#loginUserName');if(a.val()){login(a.val());$('#loginPopup').remove();}}catch(e){console.log(e)}return false">login</span>
</form>
</div>
</div>
</div>