diff --git a/WebContent/cah.css b/WebContent/cah.css index 62c4510..6f51622 100644 --- a/WebContent/cah.css +++ b/WebContent/cah.css @@ -9,26 +9,56 @@ } #canvass { - /* */ + /* * / display: none; /* */ - height: 768px; + height: 750px; overflow: none; position: relative; - width: 1024px; + width: 1000px; border: 1px solid red; } -#log { - width: 50%; - height: 200px; - border: 1px solid black; +#chat_area { + width: 500px; + height: 215px; + border: 0px; position: absolute; bottom: 0px; right: 0px; + overflow: none; +} + +#log { + width: 500px; + height: 198px; + border: 1px solid black; + position: absolute; + bottom: 17px; + right: 0px; overflow: auto; } +#chat { + border: 1px solid black; + width: 451px; + height: 17px; + position: absolute; + bottom: -1px; + right: 49px; + padding: 0px; +} + +#chat_submit { + width: 50px; + height: 19px; + position: absolute; + right: 0px; + bottom: -1px; + margin: 0px; + padding: 0px; +} + span.error { color: red; } diff --git a/WebContent/index.jsp b/WebContent/index.jsp index d2995a1..a4c6322 100644 --- a/WebContent/index.jsp +++ b/WebContent/index.jsp @@ -12,6 +12,7 @@ <%-- TODO make this be dynamic with looking at the filesystem and using jquery --%> + @@ -26,10 +27,15 @@
Nickname: +
+
+ + +
diff --git a/WebContent/js/cah.ajax.handlers.js b/WebContent/js/cah.ajax.handlers.js index 1cb87e8..9db1937 100644 --- a/WebContent/js/cah.ajax.handlers.js +++ b/WebContent/js/cah.ajax.handlers.js @@ -14,7 +14,7 @@ cah.ajax.SuccessHandlers.register = function(data) { }; cah.ajax.ErrorHandlers.register = function(data) { - $("#nickbox").append("" + data.error_message + ""); + $("#nickbox_error").text(data.error_message); $("#nickname").focus(); }; @@ -31,7 +31,7 @@ cah.ajax.SuccessHandlers.firstload = function(data) { }; cah.ajax.ErrorHandlers.firstload = function(data) { - // TODO dunno what to do here + // TODO dunno what to do here, if anything }; /** @@ -42,3 +42,7 @@ cah.ajax.after_registered = function() { cah.log.debug("done registering"); cah.longpoll.longPoll(); }; + +cah.ajax.SuccessHandlers.chat = function(data) { + // pass +}; diff --git a/WebContent/js/cah.app.js b/WebContent/js/cah.app.js index 9ccc771..cb7b965 100644 --- a/WebContent/js/cah.app.js +++ b/WebContent/js/cah.app.js @@ -5,10 +5,16 @@ */ $(document).ready(function() { + // see if we already exist on the server so we can resume + cah.Ajax.request("firstload", {}); + // TODO see if we have a stored nickname somewhere $("#nicknameconfirm").click(nicknameconfirm_click); $("#nickbox").keyup(nickbox_keyup); $("#nickbox").focus(); + + $("#chat").keyup(chat_keyup); + $("#chat_submit").click(chatsubmit_click); }); function nickbox_keyup(e) { @@ -19,8 +25,26 @@ function nickbox_keyup(e) { } function nicknameconfirm_click(e) { - nickname = $.trim($("#nickname").val()); - cah.ajax.request("register", { - nickname : nickname + var nickname = $.trim($("#nickname").val()); + cah.Ajax.request("register", { + nickname : nickname, }); } + +function chat_keyup(e) { + if (e.which == 13) { + $("#chat_submit").click(); + e.preventDefault(); + } +} + +function chatsubmit_click(e) { + var text = $.trim($("#chat").val()); + // TODO when I get multiple channels working, this needs to know active and pass it + cah.Ajax.request("chat", { + message : text, + }); + cah.log.status("<" + cah.nickname + "> " + text); + $("#chat").val(""); + $("#chat").focus(); +} diff --git a/WebContent/js/cah.longpoll.handlers.js b/WebContent/js/cah.longpoll.handlers.js new file mode 100644 index 0000000..0803ad7 --- /dev/null +++ b/WebContent/js/cah.longpoll.handlers.js @@ -0,0 +1,28 @@ +/** + * Event handlers from long-poll operations. + * + * @author ajanata + */ + +cah.longpoll.ErrorCodeHandlers.not_registered = function(data) { + cah.longpoll.Resume = false; + // TODO disable interface + cah.log.error("The server seems to have restarted. Any in-progress games have been lost."); + cah.log.error("You will need to refresh the page to start a new game."); +}; + +cah.longpoll.EventHandlers.new_player = function(data) { + cah.log.status(data.nickname + " has connected."); +}; + +cah.longpoll.EventHandlers.noop = function(data) { + // pass +}; + +cah.longpoll.EventHandlers.chat = function(data) { + // TODO deal with multiple channels eventually + // don't display our own chat + if (data.from != cah.nickname) { + cah.log.status("<" + data.from + "> " + data.message); + } +}; diff --git a/WebContent/js/cah.longpoll.js b/WebContent/js/cah.longpoll.js index 13363d3..7ba8944 100644 --- a/WebContent/js/cah.longpoll.js +++ b/WebContent/js/cah.longpoll.js @@ -11,6 +11,7 @@ cah.longpoll.INITIAL_BACKOFF = 500; cah.longpoll.Backoff = cah.longpoll.INITIAL_BACKOFF; cah.longpoll.Resume = true; cah.longpoll.ErrorCodeHandlers = {}; +cah.longpoll.EventHandlers = {}; cah.longpoll.longPoll = function() { cah.log.debug("starting long poll"); @@ -42,15 +43,11 @@ cah.longpoll.done = function(data) { cah.log.error(data.error_message); } } else { - // TODO process data - // var req = pendingRequests[data.serial]; - // if (req && cah.ajax.SuccessHandlers[req.op]) { - // cah.ajax.SuccessHandlers[req.op](data); - // } else if (req) { - // addLogError("Unhandled response for op " + req.op); - // } else { - // addLogError("Unknown response for serial " + data.serial); - // } + if (cah.longpoll.EventHandlers[data.event]) { + cah.longpoll.EventHandlers[data.event](data); + } else { + cah.log.error("Unhandled event " + data.event); + } } // reset the backoff to normal when there's a successful operation @@ -66,10 +63,3 @@ cah.longpoll.error = function(jqXHR, textStatus, errorThrown) { .error("Error communicating with server. Will try again in " + (cah.longpoll.Backoff / 1000) + " second" + (cah.longpoll.Backoff != 1000 ? "s" : "") + "."); }; - -cah.longpoll.ErrorCodeHandlers.not_registered = function(data) { - cah.longpoll.Resume = false; - // TODO disable interface - cah.log.error("The server seems to have restarted. Any in-progress games have been lost."); - cah.log.error("You will need to refresh the page to start a new game."); -}; diff --git a/src/net/socialgamer/cah/data/QueuedMessage.java b/src/net/socialgamer/cah/data/QueuedMessage.java index 1732661..699b6c8 100644 --- a/src/net/socialgamer/cah/data/QueuedMessage.java +++ b/src/net/socialgamer/cah/data/QueuedMessage.java @@ -38,7 +38,7 @@ public class QueuedMessage implements Comparable { * */ public enum Type { - PING(0), NEW_PLAYER(5); + PING(0), NEW_PLAYER(5), CHAT(5); private final int weight; diff --git a/src/net/socialgamer/cah/handlers/ChatHandler.java b/src/net/socialgamer/cah/handlers/ChatHandler.java new file mode 100644 index 0000000..df447a1 --- /dev/null +++ b/src/net/socialgamer/cah/handlers/ChatHandler.java @@ -0,0 +1,54 @@ +package net.socialgamer.cah.handlers; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpSession; + +import net.socialgamer.cah.Server; +import net.socialgamer.cah.data.ConnectedUsers; +import net.socialgamer.cah.data.QueuedMessage.Type; +import net.socialgamer.cah.data.User; + +import com.google.inject.Inject; + + +public class ChatHandler extends Handler { + + public static final String OP = "chat"; + + private final ConnectedUsers users; + + @Inject + public ChatHandler(final Server server) { + this.users = server.getConnectedUsers(); + } + + @Override + public Map handle(final Map parameters, + final HttpSession session) { + final Map data = new HashMap(); + + final User user = (User) session.getAttribute("user"); + assert (user != null); + + if (!parameters.containsKey("message") || parameters.get("message").length != 1) { + return error("No message specified."); + } else { + final String message = parameters.get("message")[0].trim(); + if (message.length() > 200) { + return error("Messages cannot be longer than 200 characters."); + } else { + final HashMap broadcastData = new HashMap(); + broadcastData.put("event", "chat"); + broadcastData.put("from", user.getNickname()); + broadcastData.put("message", message); + // TODO once there are multiple chat channels, put the destination here + // TODO once there are games and they have their own chat, make it only send to participants + users.broadcastToAll(Type.CHAT, broadcastData); + } + } + + return data; + } +} diff --git a/src/net/socialgamer/cah/handlers/Handlers.java b/src/net/socialgamer/cah/handlers/Handlers.java index 4d79766..3db337e 100644 --- a/src/net/socialgamer/cah/handlers/Handlers.java +++ b/src/net/socialgamer/cah/handlers/Handlers.java @@ -10,6 +10,7 @@ public class Handlers { static { LIST = new HashMap>(); + LIST.put(ChatHandler.OP, ChatHandler.class); LIST.put(FirstLoadHandler.OP, FirstLoadHandler.class); LIST.put(RegisterHandler.OP, RegisterHandler.class); LIST.put(TestHandler.OP, TestHandler.class);