Fixed long-polling and made some improvements in messages

This commit is contained in:
Norbi Peti 2016-08-15 12:37:51 +02:00
parent e12c0fee36
commit 01a1ce097c
12 changed files with 133 additions and 51 deletions

View file

@ -8,17 +8,7 @@ $(document).ready(function () {
var nodes = cmsgs.children;
for (var x = 0; x < nodes.length; x++) {
var item = nodes[x];
console.log(item);
var spans = item.getElementsByTagName("span");
var ctime = null;
for (var i = 0; i < spans.length; i++)
if (spans[i].className.split(' ').indexOf("converttime") > -1)
ctime = spans[i];
if (ctime != null)
console.log(ctime.innerText);
if (ctime != null)
ctime.innerText = moment(ctime.innerText, "YYYY-MM-DDTHH:mm:ssZ").fromNow(); //.format("lll");
handlereceivedmessage(item);
}
cmsgs.lastElementChild.scrollIntoView(false);
}
});

View file

@ -1,7 +1,30 @@
(function poll() {
setTimeout(function() {
$.ajax({ url: "/receivemessage", success: function(data) {
}, dataType: "json", complete: poll });
}, 100);
})();
var handlereceivedmessage = function handlereceivedmessage(msgnode) {
var spans = msgnode.getElementsByTagName("span");
var ctime = null;
for (var i = 0; i < spans.length; i++)
if (spans[i].className.split(' ').indexOf("converttime") > -1)
ctime = spans[i];
if (ctime != null)
ctime.innerText = moment(ctime.innerText, "YYYY-MM-DDTHH:mm:ssZ").fromNow();
msgnode.scrollIntoView(false);
}
(function poll() {
setTimeout(function () {
$.ajax({
url: "/receivemessage", success: function (data) {
console.log(data);
var msgelement = document.getElementById("channelmessages").appendChild(document.createElement("div"));
var header = msgelement.appendChild(document.createElement("p");
header.innerText = data.sender.name + " - ";
var isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
header.appendElement("span").addClass("converttime")
.value = isoFormat.format(data.time) + "+00:00";
var body = msgelement.appendChild(document.createElement("p"));
body.innerText = data.message;
handlereceivedmessage(msgnode);
}, dataType: "json", complete: poll
});
}, 100);
})();

View file

@ -7,8 +7,8 @@ var sendmsg = function sendmsg(msginputta) {
};
var respfunc = function respfunc(result) {
var msginput = document.getElementById("msginput");
if (result != "Success") { //on success result is string
var msginput = document.getElementById("msginput");
if (result.responseText.indexOf("JSONERROR") != -1) {
console.log("Got JSON error. Retrying...");
console.log(result.responseText);
@ -19,8 +19,10 @@ var respfunc = function respfunc(result) {
msginput.disabled = false;
}
}
else
location.reload(true); //TODO: Don't referesh on message send
else {
msginput.value = "";
msginput.disabled = false;
}
};
var sendmsgonenter = function sendmsgonenter(e) {

View file

@ -14,7 +14,7 @@ function getFormData($form) {
function showError(message) {
var errormsg = document.getElementById("errormsg");
errormsg.innerHTML = result.responseText;
errormsg.innerHTML = message;
errormsg.style = "display: block";
setTimeout(function(){errormsg.style.display="none";}, 2000);
setTimeout(function () { errormsg.style.display = "none"; }, 2000);
}

View file

@ -30,7 +30,8 @@ public class Main {
// https://docs.oracle.com/javase/8/docs/api/
LogManager.getLogger().log(Level.INFO, "Loading files...");
DataManager.init();
final GsonBuilder gsonBuilder = new GsonBuilder();
final GsonBuilder saveGsonBuilder = new GsonBuilder();
final GsonBuilder exchangeGsonBuilder = new GsonBuilder();
Reflections rf = new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forClassLoader(ManagedData.class.getClassLoader()))
.addClassLoader(ManagedData.class.getClassLoader()).addScanners(new SubTypesScanner())
@ -39,11 +40,11 @@ public class Main {
for (Class<? extends ManagedData> data : datas) {
if (Modifier.isAbstract(data.getModifiers()))
continue;
gsonBuilder.registerTypeAdapter(new DataType(LoaderCollection.class, data),
saveGsonBuilder.registerTypeAdapter(new DataType(LoaderCollection.class, data),
new LoaderCollectionSerializer());
gsonBuilder.registerTypeAdapter(new DataType(LoaderRef.class, data), new LoaderRefSerializer());
saveGsonBuilder.registerTypeAdapter(new DataType(LoaderRef.class, data), new LoaderRefSerializer());
}
gson = gsonBuilder.create();
gson = saveGsonBuilder.create();
/*
* User user = new User(); user.setName("asd"); user.setEmail("test@test.com"); User user2 = new User(); user2.setName("Teszt"); user2.setEmail("test2@test.com"); // user =
* provider.save(user); // user2 = provider.save(user2); user.getContacts().add(user2); user2.getContacts().add(user); LogManager.getLogger().log(Level.DEBUG, "1st's contact: " +

View file

@ -18,7 +18,6 @@ import io.github.norbipeti.chat.server.db.domain.SavedData;
* </p>
*
* @author Norbi
*
* @param <T>
*/
public class LoaderCollection<T extends SavedData> extends Loader implements List<T> {
@ -41,7 +40,7 @@ public class LoaderCollection<T extends SavedData> extends Loader implements Lis
public LoaderCollection(LoaderCollection<T> parentofsub, int fromIndex, int toIndex) {
this.cl = parentofsub.cl;
idlist = parentofsub.idlist.subList(fromIndex, toIndex);
idlist = parentofsub.idlist.subList(fromIndex, toIndex); // TODO: Test
}
public LoaderCollection(Class<T> cl, int capacity) {
@ -132,8 +131,7 @@ public class LoaderCollection<T extends SavedData> extends Loader implements Lis
/**
* Remove an object from this collection
*
* @param o
* Either the object of type T or the ID
* @param o Either the object of type T or the ID
*/
@Override
public boolean remove(Object o) {
@ -228,4 +226,19 @@ public class LoaderCollection<T extends SavedData> extends Loader implements Lis
sb.append("]");
return sb.toString();
}
@SuppressWarnings("unchecked")
public Object clone() {
Object cloned = null;
if (idlist instanceof ArrayList<?>)
cloned = ((ArrayList<Long>) idlist).clone();
if (cloned == null)
return cloned;
else {
LoaderCollection<T> lc = new LoaderCollection<T>(cl, this.size());
if (cloned instanceof List<?>)
lc.idlist = (List<Long>) cloned;
return lc;
}
}
}

View file

@ -1,6 +1,7 @@
package io.github.norbipeti.chat.server.data;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import com.google.gson.Gson;
@ -14,9 +15,7 @@ import io.github.norbipeti.chat.server.db.domain.ManagedData;
// @SuppressWarnings("rawtypes")
public class LoaderCollectionSerializer extends TypeAdapter<LoaderCollection<?>> {
// private static final Type returnType = getReturnType();
// http://stackoverflow.com/a/17300227
@Override
public void write(JsonWriter out, LoaderCollection<?> value) throws IOException {
if (value == null) {
@ -40,9 +39,13 @@ public class LoaderCollectionSerializer extends TypeAdapter<LoaderCollection<?>>
}
in.beginObject();
in.nextName();
List<Long> list = new Gson().fromJson(in, new TypeToken<List<Long>>() {
List<Long> list;
LoaderCollection<? extends ManagedData> itemcol;
list = new Gson().fromJson(in, new TypeToken<List<Long>>() {
}.getType());
if (!in.nextName().equals("class")) {
if (!in.nextName().equals("class"))
{
new Exception("Error: Next isn't \"class\"").printStackTrace();
return null;
}

View file

@ -1,9 +1,17 @@
package io.github.norbipeti.chat.server.db.domain;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import javax.persistence.*;
import org.jsoup.nodes.Element;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import io.github.norbipeti.chat.server.Main;
import io.github.norbipeti.chat.server.data.LoaderRef;
@Entity
@ -92,4 +100,28 @@ public class Message extends ManagedData {
@Override
protected void init() {
}
public Element getAsHTML(Element channelmessages) {
Element msgelement = channelmessages.appendElement("div");
Element header = msgelement.appendElement("p");
header.text(getSender().get().getName() + " - ");
header.appendElement("span").addClass("converttime").text(formatDate());
Element body = msgelement.appendElement("p");
body.text(getMessage());
return msgelement;
}
public JsonObject getAsJson() {
JsonObject msgobj = new JsonObject();
msgobj.add("sender", Main.gson.toJsonTree(getSender().get()));
msgobj.add("message", new JsonPrimitive(getMessage()));
msgobj.add("time", new JsonPrimitive(formatDate()));
return msgobj;
}
private String formatDate() {
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return isoFormat.format(getTime()) + "+00:00";
}
}

View file

@ -95,10 +95,6 @@ public class User extends SavedData {
private User() {
}
public static LoaderCollection<User> getUsers() {
return DataManager.getAll(User.class);
}
@Override
public long getId() {
return id;

View file

@ -2,6 +2,7 @@ package io.github.norbipeti.chat.server.page;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.TimeZone;
import org.apache.logging.log4j.Level;
@ -49,6 +50,7 @@ public class IndexPage extends Page {
convs.add(c); // TODO: Handle no conversation open
}
user.getConversations().add(convs.get(0));
convs.get(0).getUsers().add(user);
}
Conversation conv = user.getConversations().get(0);
Element cide = channelmessages.appendElement("p");
@ -56,17 +58,13 @@ public class IndexPage extends Page {
cide.attr("id", "convidp");
cide.text(Long.toString(conv.getId()));
LogManager.getLogger().log(Level.DEBUG, "Messages: " + conv.getMesssageChunks().size());
for (MessageChunk chunk : conv.getMesssageChunks()) { // TODO: Reverse
@SuppressWarnings("unchecked")
LoaderCollection<MessageChunk> chunks = (LoaderCollection<MessageChunk>) conv.getMesssageChunks()
.clone();
Collections.reverse(chunks);
for (MessageChunk chunk : chunks) {
for (Message message : chunk.getMessages()) {
Element msgelement = channelmessages.appendElement("div");
Element header = msgelement.appendElement("p");
header.text(message.getSender().get().getName() + " - ");
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
header.appendElement("span").addClass("converttime")
.text(isoFormat.format(message.getTime()) + "+00:00");
Element body = msgelement.appendElement("p");
body.text(message.getMessage());
message.getAsHTML(channelmessages);
}
}
return doc;

View file

@ -1,9 +1,18 @@
package io.github.norbipeti.chat.server.page;
import java.io.IOException;
import java.util.HashMap;
import org.apache.logging.log4j.LogManager;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.Main;
import io.github.norbipeti.chat.server.data.LoaderRef;
import io.github.norbipeti.chat.server.db.domain.Conversation;
import io.github.norbipeti.chat.server.db.domain.Message;
import io.github.norbipeti.chat.server.db.domain.User;
import io.github.norbipeti.chat.server.io.IOHelper;
@ -15,6 +24,8 @@ public class ReceiveMessageAjaxPage extends Page {
return "receivemessage";
}
public static HashMap<User, HttpExchange> exmap = new HashMap<>();
@Override
public void handlePage(HttpExchange exchange) throws IOException {
User user = IOHelper.GetLoggedInUser(exchange);
@ -22,7 +33,7 @@ public class ReceiveMessageAjaxPage extends Page {
IOHelper.SendResponse(403, "<p>Please log in to receive messages</p>", exchange);
return;
}
JsonObject obj = new JsonObject(); // TODO
exmap.put(user, exchange);
/*
* String message = obj.get("message").getAsString().trim(); int conversation = obj.get("conversation").getAsInt(); if (message.trim().length() == 0) { IOHelper.SendResponse(400,
* "<h1>400 Bad request</h1><p>The message cannot be empty.</p>", exchange); return; } LoaderCollection<Conversation> convos = user.getConversations(); Conversation conv = null;
@ -33,7 +44,18 @@ public class ReceiveMessageAjaxPage extends Page {
* "Added conversation's message count: " + conv.getMesssageChunks().size());
*/
IOHelper.SendResponse(200, "Success", exchange);
}
public static void sendMessageBack(Message msg, Conversation conv) throws IOException {
for (User user : conv.getUsers()) {
LogManager.getLogger().debug("User: " + user);
if (exmap.containsKey(user)) {
LogManager.getLogger().debug("Exmap contains user");
JsonObject msgobj = msg.getAsJson();
IOHelper.SendResponse(200, msgobj.toString(), exmap.get(user));
exmap.remove(user);
} else
LogManager.getLogger().warn("User is not listening: " + user);
}
}
}

View file

@ -71,6 +71,8 @@ public class SendMessageAjaxPage extends Page {
LogManager.getLogger().log(Level.DEBUG,
"Added conversation's message count: " + conv.getMesssageChunks().size());
ReceiveMessageAjaxPage.sendMessageBack(msg, conv);
IOHelper.SendResponse(200, "Success", exchange);
}