more study wip
parent
c6e56f4b78
commit
76a3d73715
|
@ -23,7 +23,7 @@ object JsonView {
|
|||
private implicit val posReader: Reads[Pos] = Reads[Pos] { v =>
|
||||
(v.asOpt[String] flatMap Pos.posAt).fold[JsResult[Pos]](JsError(Nil))(JsSuccess(_))
|
||||
}
|
||||
private implicit val pathWrites: Writes[Path] = Writes[Path] { p =>
|
||||
private[study] implicit val pathWrites: Writes[Path] = Writes[Path] { p =>
|
||||
JsString(p.toString)
|
||||
}
|
||||
private implicit val colorWriter: Writes[chess.Color] = Writes[chess.Color] { c =>
|
||||
|
@ -71,6 +71,8 @@ object JsonView {
|
|||
Json.obj(
|
||||
"id" -> s.id,
|
||||
"members" -> s.members,
|
||||
"position" -> s.position,
|
||||
"shapes" -> s.shapes,
|
||||
"ownerId" -> s.ownerId,
|
||||
"createdAt" -> s.createdAt)
|
||||
}
|
||||
|
|
|
@ -22,10 +22,10 @@ private final class Socket(
|
|||
|
||||
def receiveSpecific = {
|
||||
|
||||
case SetPosition(userId, position) => notifyIf(
|
||||
case SetPath(userId, path) => notifyIf(
|
||||
m => !m.userId.contains(userId),
|
||||
"cpos",
|
||||
position)
|
||||
"path",
|
||||
path)
|
||||
|
||||
case AddNode(pos, node) => notifyIf(
|
||||
m => !m.userId.contains(node.by),
|
||||
|
@ -46,10 +46,8 @@ private final class Socket(
|
|||
case _ =>
|
||||
}
|
||||
|
||||
case ReloadUserChapter(userId, chapter) =>
|
||||
notifyIf(
|
||||
m => m.userId contains userId,
|
||||
"chapter", chapter)
|
||||
case ReloadUser(userId) =>
|
||||
notifyIf(m => m.userId contains userId, "reload", JsNull)
|
||||
|
||||
case PingVersion(uid, v) => {
|
||||
ping(uid)
|
||||
|
@ -91,11 +89,11 @@ private object Socket {
|
|||
case class Join(uid: String, userId: Option[User.ID], owner: Boolean)
|
||||
case class Connected(enumerator: JsEnumerator, member: Member)
|
||||
|
||||
case class ReloadUserChapter(userId: User.ID, chapter: Chapter)
|
||||
case class ReloadUser(userId: User.ID)
|
||||
|
||||
case class AddNode(position: Position.Ref, node: Node)
|
||||
case class DelNode(position: Position.Ref)
|
||||
case class SetPosition(userId: User.ID, position: Position.Ref)
|
||||
case class SetPath(userId: User.ID, path: Path)
|
||||
case class ReloadMembers(members: StudyMembers)
|
||||
case class ReloadShapes(shapes: List[Shape])
|
||||
|
||||
|
|
|
@ -78,10 +78,10 @@ private[study] final class SocketHandler(
|
|||
}
|
||||
}
|
||||
}
|
||||
case ("setPos", o) => AnaRateLimit(uid) {
|
||||
case ("setPath", o) => AnaRateLimit(uid) {
|
||||
reading[AtPath](o) { d =>
|
||||
member.userId foreach { userId =>
|
||||
api.setPosition(userId, studyId, Position.Ref(d.chapterId, Path(d.path)))
|
||||
api.setPath(userId, studyId, Position.Ref(d.chapterId, Path(d.path)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,10 +39,18 @@ final class StudyApi(
|
|||
Study.WithChapter(study, chapter)
|
||||
}
|
||||
|
||||
def setPosition(userId: User.ID, studyId: Study.ID, position: Position.Ref) = sequenceStudy(studyId) { study =>
|
||||
def setPath(userId: User.ID, studyId: Study.ID, position: Position.Ref) = sequenceStudy(studyId) { study =>
|
||||
Contribute(userId, study) {
|
||||
studyRepo.setPosition(study.id, position) >>-
|
||||
sendTo(study.id, Socket.SetPosition(userId, position))
|
||||
if (study.position.chapterId == position.chapterId) {
|
||||
(study.position.path != position.path) ?? {
|
||||
studyRepo.setPosition(study.id, position) >>-
|
||||
sendTo(study.id, Socket.SetPath(userId, position.path))
|
||||
}
|
||||
}
|
||||
else {
|
||||
sendTo(study.id, Socket.ReloadUser(userId))
|
||||
funit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +58,7 @@ final class StudyApi(
|
|||
case Study.WithChapter(study, chapter) => Contribute(node.by, study) {
|
||||
chapter.addNode(position.path, node) match {
|
||||
case None =>
|
||||
sendTo(study.id, Socket.ReloadUserChapter(node.by, chapter))
|
||||
sendTo(study.id, Socket.ReloadUser(node.by))
|
||||
funit
|
||||
case Some(newChapter) =>
|
||||
chapterRepo.update(newChapter) >>
|
||||
|
|
|
@ -20,9 +20,11 @@ module.exports = {
|
|||
return myMember() || owner();
|
||||
}
|
||||
|
||||
function canContribute() {
|
||||
return myMember() && myMember().role === 'w';
|
||||
}
|
||||
|
||||
var vm = {
|
||||
position: meOrOwner().position,
|
||||
follow: null, // which user is being followed by us
|
||||
memberConfig: null // which user is being configured by us
|
||||
};
|
||||
|
||||
|
@ -34,40 +36,15 @@ module.exports = {
|
|||
});
|
||||
}
|
||||
|
||||
function addChapterId(data) {
|
||||
data.chapterId = vm.position.chapterId;
|
||||
return data;
|
||||
}
|
||||
|
||||
function updateMember(id, f) {
|
||||
data.members[id] && f(data.members[id]);
|
||||
}
|
||||
|
||||
function checkFollow() {
|
||||
if (vm.follow && (!data.members[vm.follow] || data.members[vm.follow].role !== 'w'))
|
||||
follow(null);
|
||||
function addChapterId(req) {
|
||||
req.chapterId = data.position.chapterId;
|
||||
return req;
|
||||
}
|
||||
|
||||
function updateAutoShapes() {
|
||||
if (!vm.follow) ctrl.chessground.setAutoShapes([]);
|
||||
else if (samePosition(vm.position, data.members[vm.follow].position)) {
|
||||
ctrl.chessground.setAutoShapes(data.members[vm.follow].shapes);
|
||||
}
|
||||
}
|
||||
|
||||
function follow(id) {
|
||||
if (id === vm.follow || id === ctrl.userId) vm.follow = null;
|
||||
else vm.follow = id;
|
||||
if (vm.follow) ctrl.userJump(data.members[vm.follow].position.path);
|
||||
checkFollow();
|
||||
updateAutoShapes();
|
||||
}
|
||||
if (ownage) ctrl.userJump(owner().position.path);
|
||||
else follow(data.ownerId);
|
||||
|
||||
function invite(username) {
|
||||
if (ownage) send("invite", username);
|
||||
ctrl.chessground.setAutoShapes(data.shapes);
|
||||
}
|
||||
ctrl.userJump(data.position.path);
|
||||
|
||||
function samePosition(p1, p2) {
|
||||
return p1.chapterId === p2.chapterId && p1.path === p2.path;
|
||||
|
@ -75,7 +52,9 @@ module.exports = {
|
|||
|
||||
ctrl.chessground.set({
|
||||
drawable: {
|
||||
onChange: partial(send, "shapes")
|
||||
onChange: function(shapes) {
|
||||
if (canContribute()) send("shapes", shapes)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -84,11 +63,10 @@ module.exports = {
|
|||
vm: vm,
|
||||
userId: userId,
|
||||
position: function() {
|
||||
return vm.position;
|
||||
return data.position;
|
||||
},
|
||||
setPath: function(path) {
|
||||
if (vm.follow && data.members[vm.follow].position.path !== path) follow(null);
|
||||
userId && send("setPos", addChapterId({
|
||||
if (canContribute() && path !== data.position.path) send("setPath", addChapterId({
|
||||
path: path
|
||||
}));
|
||||
},
|
||||
|
@ -103,7 +81,6 @@ module.exports = {
|
|||
}));
|
||||
},
|
||||
orderedMembers: orderedMembers,
|
||||
follow: follow,
|
||||
setRole: function(userId, role) {
|
||||
send("setRole", {
|
||||
userId: userId,
|
||||
|
@ -125,23 +102,20 @@ module.exports = {
|
|||
updateAutoShapes();
|
||||
},
|
||||
socketHandlers: {
|
||||
mpos: function(d) {
|
||||
updateMember(d.u, function(member) {
|
||||
member.position = d.p;
|
||||
if (vm.follow === d.u) {
|
||||
ctrl.userJump(member.position.path);
|
||||
m.redraw();
|
||||
}
|
||||
});
|
||||
path: function(p) {
|
||||
data.position.path = p;
|
||||
ctrl.userJump(p);
|
||||
m.redraw();
|
||||
},
|
||||
addNode: function(d) {
|
||||
if (d.p.chapterId !== vm.position.chapterId) return;
|
||||
if (d.p.chapterId !== data.position.chapterId) return;
|
||||
ctrl.tree.addNode(d.n, d.p.path);
|
||||
ctrl.jump(ctrl.vm.path);
|
||||
data.position.path = d.p.path + d.n.id;
|
||||
ctrl.jump(data.position.path);
|
||||
m.redraw();
|
||||
},
|
||||
delNode: function(d) {
|
||||
if (d.p.chapterId !== vm.position.chapterId) return;
|
||||
if (d.p.chapterId !== data.position.chapterId) return;
|
||||
ctrl.tree.deleteNodeAt(d.p.path);
|
||||
ctrl.jump(ctrl.vm.path);
|
||||
m.redraw();
|
||||
|
@ -153,7 +127,6 @@ module.exports = {
|
|||
},
|
||||
members: function(d) {
|
||||
data.members = d;
|
||||
checkFollow();
|
||||
updateAutoShapes();
|
||||
m.redraw();
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue