fetch the list of current room members when joining

pull/34/head
Zlatin Balevsky 2019-11-12 10:55:21 +00:00
parent d57d2ccb71
commit 3d36351a6b
9 changed files with 103 additions and 41 deletions

View File

@ -1,17 +1,20 @@
package com.muwire.core.chat;
enum ChatAction {
JOIN(true, false),
LEAVE(false, false),
SAY(false, false),
LIST(true, true),
HELP(true, true),
INFO(true, true);
JOIN(true, false, true),
LEAVE(false, false, true),
SAY(false, false, true),
LIST(true, true, true),
HELP(true, true, true),
INFO(true, true, true),
JOINED(true, true, false);
final boolean console;
final boolean stateless;
ChatAction(boolean console, boolean stateless) {
final boolean user;
ChatAction(boolean console, boolean stateless, boolean user) {
this.console = console;
this.stateless = stateless;
this.user = user;
}
}

View File

@ -83,6 +83,11 @@ class ChatConnection implements ChatLink {
running.get()
}
@Override
public Persona getPersona() {
persona
}
@Override
public void close() {
if (!running.compareAndSet(true, false)) {
@ -199,7 +204,8 @@ class ChatConnection implements ChatLink {
def event = new ChatMessageEvent( uuid : uuid, payload : payload, sender : sender,
host : host, room : room, chatTime : chatTime, sig : sig)
eventBus.publish(event)
incomingEvents.put(event)
if (!incoming)
incomingEvents.put(event)
}
private void handleLeave(def json) {

View File

@ -5,6 +5,7 @@ import java.io.Closeable;
import com.muwire.core.Persona;
public interface ChatLink extends Closeable {
public Persona getPersona();
public boolean isUp();
public void sendChat(ChatMessageEvent e);
public void sendLeave(Persona p);

View File

@ -107,7 +107,6 @@ class ChatServer {
joinRoom(client, CONSOLE)
connection.start()
processHelp(connection.endpoint.destination)
eventBus.publish(new ChatConnectionEvent(connection : connection, status : ChatConnectionAttemptStatus.SUCCESSFUL, persona : client))
}
void onChatDisconnectionEvent(ChatDisconnectionEvent e) {
@ -185,7 +184,8 @@ class ChatServer {
}
if ((command.action.console && e.room != CONSOLE) ||
(!command.action.console && e.room == CONSOLE))
(!command.action.console && e.room == CONSOLE) ||
!command.action.user)
return
switch(command.action) {
@ -205,10 +205,29 @@ class ChatServer {
return
connections[it.destination].sendChat(e)
}
String payload = rooms[room].stream().filter({it != e.sender}).map({it.toBase64()})
.collect(Collectors.joining(","))
if (payload.length() == 0) {
return
}
payload = "/JOINED $payload"
long now = System.currentTimeMillis()
UUID uuid = UUID.randomUUID()
byte [] sig = ChatConnection.sign(uuid, now, room, payload, me, me, spk)
ChatMessageEvent echo = new ChatMessageEvent(
uuid : uuid,
payload : payload,
sender : me,
host : me,
room : room,
chatTime : now,
sig : sig
)
connections[e.sender.destination].sendChat(echo)
}
private void processLeave(ChatMessageEvent e) {
leaveRoom(e.room)
leaveRoom(e.sender, e.room)
rooms.getOrDefault(e.room, []).each {
if (it == e.sender)
return

View File

@ -42,4 +42,8 @@ class LocalChatLink implements ChatLink {
public boolean isUp() {
true
}
public Persona getPersona() {
null
}
}

View File

@ -6,6 +6,7 @@ import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
import groovy.util.logging.Log
import net.i2p.crypto.DSAEngine
import net.i2p.data.Base64
import net.i2p.data.DataHelper
import net.i2p.data.Signature
@ -13,6 +14,7 @@ import java.nio.charset.StandardCharsets
import java.util.logging.Level
import javax.annotation.Nonnull
import javax.swing.JOptionPane
import com.muwire.core.Persona
import com.muwire.core.chat.ChatCommand
@ -43,6 +45,36 @@ class ChatRoomController {
command = new ChatCommand("/SAY $words")
}
if (!command.action.user) {
JOptionPane.showMessageDialog(null, "$words is not a user command","Invalid Command", JOptionPane.ERROR_MESSAGE)
return
}
if (command.action == ChatAction.SAY && command.payload.length() > 0) {
String toShow = DataHelper.formatTime(now) + " <" + model.core.me.getHumanReadableName() + "> "+command.payload
view.roomTextArea.append(toShow)
view.roomTextArea.append('\n')
}
if (command.action == ChatAction.JOIN) {
String newRoom = command.payload
if (!mvcGroup.parentGroup.childrenGroups.containsKey(newRoom)) {
def params = [:]
params['core'] = model.core
params['tabName'] = model.host.getHumanReadableName() + "-chat-rooms"
params['room'] = newRoom
params['console'] = false
params['host'] = model.host
mvcGroup.parentGroup.createMVCGroup("chat-room", newRoom, params)
}
}
if (command.action == ChatAction.LEAVE && !model.console) {
leftRoom = true
view.closeTab.call()
}
long now = System.currentTimeMillis()
UUID uuid = UUID.randomUUID()
String room = model.console ? ChatServer.CONSOLE : model.room
@ -58,30 +90,6 @@ class ChatRoomController {
sig : sig)
model.core.eventBus.publish(event)
if (command.action == ChatAction.SAY && command.payload.length() > 0) {
String toShow = DataHelper.formatTime(now) + " <" + model.core.me.getHumanReadableName() + "> "+command.payload
view.roomTextArea.append(toShow)
view.roomTextArea.append('\n')
}
if (command.action == ChatAction.JOIN) {
String newRoom = command.payload
if (mvcGroup.parentGroup.childrenGroups.containsKey(newRoom))
return
def params = [:]
params['core'] = model.core
params['tabName'] = model.host.getHumanReadableName() + "-chat-rooms"
params['room'] = newRoom
params['console'] = false
params['host'] = model.host
mvcGroup.parentGroup.createMVCGroup("chat-room", newRoom, params)
}
if (command.action == ChatAction.LEAVE && !model.console) {
leftRoom = true
view.closeTab.call()
}
}
void leaveRoom() {
@ -109,16 +117,16 @@ class ChatRoomController {
log.log(Level.WARNING,"bad chat command",bad)
return
}
log.info("$model.room processing $command.action")
switch(command.action) {
case ChatAction.SAY : processSay(e, command.payload);break
case ChatAction.JOIN : processJoin(e.timestamp, e.sender); break
case ChatAction.JOINED : processJoined(command.payload); break
case ChatAction.LEAVE : processLeave(e.timestamp, e.sender); break
}
}
private void processSay(ChatMessageEvent e, String text) {
log.info "processing say $text"
String toDisplay = DataHelper.formatTime(e.timestamp) + " <"+e.sender.getHumanReadableName()+"> " + text + "\n"
runInsideUIAsync {
view.roomTextArea.append(toDisplay)
@ -128,14 +136,28 @@ class ChatRoomController {
private void processJoin(long timestamp, Persona p) {
String toDisplay = DataHelper.formatTime(timestamp) + " " + p.getHumanReadableName() + " joined the room\n"
runInsideUIAsync {
model.members.add(p)
view.roomTextArea.append(toDisplay)
view.membersTable?.model?.fireTableDataChanged()
}
}
private void processJoined(String list) {
runInsideUIAsync {
list.split(",").each {
Persona p = new Persona(new ByteArrayInputStream(Base64.decode(it)))
model.members.add(p)
}
view.membersTable?.model?.fireTableDataChanged()
}
}
private void processLeave(long timestamp, Persona p) {
String toDisplay = DataHelper.formatTime(timestamp) + " " + p.getHumanReadableName() + " left the room\n"
runInsideUIAsync {
model.members.remove(p)
view.roomTextArea.append(toDisplay)
view.membersTable?.model?.fireTableDataChanged()
}
}

View File

@ -16,4 +16,5 @@ class ChatRoomModel {
boolean console
def members = []
}

View File

@ -50,11 +50,17 @@ class ChatServerModel {
}
void onChatConnectionEvent(ChatConnectionEvent e) {
if (e.connection != null)
link = e.connection
runInsideUIAsync {
status = e.status
}
ChatLink link = e.connection
if (link == null)
return
if (link.getPersona() == host)
this.link = link
else if (link.getPersona() == null && host == core.me)
this.link = link
}
private void eventLoop() {
@ -87,7 +93,6 @@ class ChatServerModel {
if (chatCommand.action == ChatAction.JOIN) {
room = chatCommand.payload
}
log.info("dispatching to room ${room}")
mvcGroup.childrenGroups[room]?.controller?.handleChatMessage(e)
}

View File

@ -24,6 +24,7 @@ class ChatRoomView {
def parent
def sayField
def roomTextArea
def membersTable
void initUI() {
int rowHeight = application.context.get("row-height")
@ -51,7 +52,7 @@ class ChatRoomView {
panel {
gridLayout(rows : 1, cols : 1)
scrollPane {
table(autoCreateRowSorter : true, rowHeight : rowHeight) {
membersTable = table(autoCreateRowSorter : true, rowHeight : rowHeight) {
tableModel(list : model.members) {
closureColumn(header : "Name", preferredWidth: 100, type: String, read : {it.getHumanReadableName()})
closureColumn(header : "Trust Status", preferredWidth: 30, type : String, read : {String.valueOf(model.core.trustService.getLevel(it.destination))})