From fe332740f7c0be59d4ede7097e5bd1eabbf40e39 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 25 Jun 2010 06:14:12 +0200 Subject: Chatting works now --- data/ephraim.glade | 1 + src/core/ephraim.erl | 18 ++++++++++++++++ src/core/ephraim_conn.erl | 4 ++++ src/core/ephraim_conv.erl | 11 ++++++++++ src/gui/Conversation.vala | 31 +++++++++++++++++++++++++-- src/gui/CoreConnector.vala | 52 ++++++++++++++++++++++++++++++++++++++++++++++ src/gui/Ephraim.vala | 40 +++++++++++++++++++++++++++++++++-- src/gui/Roster.vala | 2 -- 8 files changed, 153 insertions(+), 6 deletions(-) diff --git a/data/ephraim.glade b/data/ephraim.glade index 1b53b1b..cde04f3 100644 --- a/data/ephraim.glade +++ b/data/ephraim.glade @@ -153,6 +153,7 @@ True True False + False diff --git a/src/core/ephraim.erl b/src/core/ephraim.erl index 61c3c68..c0ab7ae 100644 --- a/src/core/ephraim.erl +++ b/src/core/ephraim.erl @@ -97,6 +97,24 @@ loop(State) -> end, loop(State2); + {send_message, To, Type, Message} -> + {State2, Conv} = get_conv(State, To), + case Conv of + undefined -> + io:format("ephraim: send_message: ~p~n", [Message]); + _ -> + Conv ! {send_message, Type, Message} + end, + loop(State2); + + {start_conversation, To} -> + {State2, _Conv} = get_conv(State, To), + loop(State2); + + {send_packet, Packet} -> + State#state.conn ! {send_packet, Packet}, + loop(State); + {receive_event, From, Packet} -> State#state.event ! {receive_event, From, Packet}, loop(State); diff --git a/src/core/ephraim_conn.erl b/src/core/ephraim_conn.erl index bce4d07..7a6ddae 100644 --- a/src/core/ephraim_conn.erl +++ b/src/core/ephraim_conn.erl @@ -53,6 +53,10 @@ loop(State) -> ephraim ! {receive_iq, IQ}, loop(State); + {send_packet, Packet} -> + exmpp_session:send_packet(State#conn_state.session, Packet), + loop(State); + Msg -> io:format("ephraim_conn: ~p~n", [Msg]), loop(State) diff --git a/src/core/ephraim_conv.erl b/src/core/ephraim_conv.erl index 3010036..ac4c26d 100644 --- a/src/core/ephraim_conv.erl +++ b/src/core/ephraim_conv.erl @@ -19,7 +19,18 @@ loop(State) -> ok; {receive_message, Packet} -> + Type = exmpp_message:get_type(Packet), + Body = exmpp_message:get_body(Packet), io:format("Received message from ~p:~n~p~n", [State#conv_state.jid, Packet]), + ephraim ! {ui_update, {receive_message, State#conv_state.jid, Type, Body}}, + loop(State); + + {send_message, Type, Message} -> + Packet = exmpp_message:normal(Message), + Packet2 = exmpp_message:set_type(Packet, Type), + Packet3 = exmpp_xml:set_attribute(Packet2, to, State#conv_state.jid), + ephraim ! {send_packet, Packet3}, + ephraim ! {ui_update, {sent_message, State#conv_state.jid, Type, Message}}, loop(State); Msg -> diff --git a/src/gui/Conversation.vala b/src/gui/Conversation.vala index 321fba9..629461e 100644 --- a/src/gui/Conversation.vala +++ b/src/gui/Conversation.vala @@ -1,9 +1,14 @@ public class Conversation { private Gtk.Notebook conversations; private Gtk.Widget widget; + private Gtk.TextView content; + private Gtk.Entry entry; + private string me; private string jid; private string display_name; + + public signal void send_message(string type, string message); private class TabLabel : Gtk.HBox { public TabLabel(string label) { @@ -21,8 +26,9 @@ public class Conversation { } } - public Conversation(Gtk.Notebook conversations0, string jid0, string? display_name0) { + public Conversation(Gtk.Notebook conversations0, string me0, string jid0, string? display_name0) { conversations = conversations0; + me = me0; jid = jid0; if(display_name0 != null) @@ -38,8 +44,15 @@ public class Conversation { } widget = builder.get_object("Conversation") as Gtk.Widget; - unowned Gtk.Label title = builder.get_object("ConversationTitle") as Gtk.Label; + content = builder.get_object("ConversationContent") as Gtk.TextView; + entry = builder.get_object("ConversationEntry") as Gtk.Entry; + + entry.activate.connect((widget) => { + send_message("chat", entry.text); + entry.text = ""; + }); + unowned Gtk.Label title = builder.get_object("ConversationTitle") as Gtk.Label; title.set_text("Conversation with " + display_name); conversations.append_page(widget, new TabLabel(display_name)); @@ -48,4 +61,18 @@ public class Conversation { ~Conversation() { conversations.remove(widget); } + + public void sent_message(string type, string message) { + if(type != "chat") + return; + + content.buffer.text += me + ": " + message + "\n"; + } + + public void receive_message(string type, string message) { + if(type != "chat") + return; + + content.buffer.text += display_name + ": " + message + "\n"; + } } diff --git a/src/gui/CoreConnector.vala b/src/gui/CoreConnector.vala index 18cef2d..a152e58 100644 --- a/src/gui/CoreConnector.vala +++ b/src/gui/CoreConnector.vala @@ -8,6 +8,8 @@ public class CoreConnector { public signal void update_contact(Contact contact); public signal void new_conversation(string jid); + public signal void receive_message(string jid, string type, string message); + public signal void sent_message(string jid, string type, string message); private class TermStore { public Erl.Term term; @@ -177,9 +179,59 @@ public class CoreConnector { new_conversation(jid); } + else if((match_term = match("{receive_message,JID,Type,Body}", term)) != null) { + Erl.Term jid_term = match_term.var_content("JID"); + if(!jid_term.is_binary()) + // TODO Debug output + return; + string jid = ((string)jid_term.bin_ptr()).ndup(jid_term.bin_size()); + + Erl.Term type_term = match_term.var_content("Type"); + if(!type_term.is_atom()) + // TODO Debug output + return; + string type = ((string)type_term.atom_ptr()).ndup(type_term.atom_size()); + + Erl.Term body_term = match_term.var_content("Body"); + if(!body_term.is_binary()) + // TODO Debug output + return; + string body = ((string)body_term.bin_ptr()).ndup(body_term.bin_size()); + + receive_message(jid, type, body); + } + else if((match_term = match("{sent_message,JID,Type,Body}", term)) != null) { + Erl.Term jid_term = match_term.var_content("JID"); + if(!jid_term.is_binary()) + // TODO Debug output + return; + string jid = ((string)jid_term.bin_ptr()).ndup(jid_term.bin_size()); + + Erl.Term type_term = match_term.var_content("Type"); + if(!type_term.is_atom()) + // TODO Debug output + return; + string type = ((string)type_term.atom_ptr()).ndup(type_term.atom_size()); + + Erl.Term body_term = match_term.var_content("Body"); + if(!body_term.is_list()) + // TODO Debug output + return; + string body = body_term.iolist_to_string(); + + sent_message(jid, type, body); + } else { Erl.print_term(stdout, term); stdout.printf("\n"); } } + + public void start_conversation(string jid) { + con.reg_send("ephraim", Erl.format("{start_conversation,~w}", Erl.mk_binary(jid.to_utf8()))); + } + + public void send_message(string jid, string type, string message) { + con.reg_send("ephraim", Erl.format("{send_message,~s,~a,~s}", jid, type, message)); + } } diff --git a/src/gui/Ephraim.vala b/src/gui/Ephraim.vala index 9d3083c..fe9f431 100644 --- a/src/gui/Ephraim.vala +++ b/src/gui/Ephraim.vala @@ -26,15 +26,33 @@ public class Ephraim { Gee.TreeMap conversations = new Gee.TreeMap(); unowned Gtk.Notebook conversationNotebook = builder.get_object("Conversations") as Gtk.Notebook; + // FIXME + string me = "/me"; + coreconn.new_conversation.connect((jid) => { Contact contact = roster.get_contact(jid); if(contact != null) { - conversations[jid] = new Conversation(conversationNotebook, jid, contact.display_string); + conversations[jid] = new Conversation(conversationNotebook, me, jid, contact.display_string); } else { - conversations[jid] = new Conversation(conversationNotebook, jid, null); + conversations[jid] = new Conversation(conversationNotebook, me, jid, null); } + + conversations[jid].send_message.connect((type, message) => coreconn.send_message(jid, type, message)); + }); + + coreconn.receive_message.connect((jid, type, message) => { + if(!(jid in conversations)) + return; + + conversations[jid].receive_message(type, message); + }); + coreconn.sent_message.connect((jid, type, message) => { + if(!(jid in conversations)) + return; + + conversations[jid].sent_message(type, message); }); if(!coreconn.start()) @@ -65,6 +83,24 @@ public class Ephraim { }); rosterView.has_tooltip = true; + rosterView.row_activated.connect((view, path, column) => { + Gtk.TreeIter iter; + roster.get_iter(out iter, path); + + Value value; + roster.get_value(iter, 0, out value); + + Contact contact = value.get_object() as Contact; + if(contact == null) + return; + + Gee.Map.Entry res = contact.get_resource_with_highest_priority(); + if(res == null) + return; //FIXME + + coreconn.start_conversation(contact.jid + "/" + res.key); + }); + Gtk.TreeViewColumn presenceColumn = new Gtk.TreeViewColumn.with_attributes(null, new CellRendererPresence(), "contact", 0, null); presenceColumn.min_width = 32; rosterView.append_column(presenceColumn); diff --git a/src/gui/Roster.vala b/src/gui/Roster.vala index 72134e6..be0a5ed 100644 --- a/src/gui/Roster.vala +++ b/src/gui/Roster.vala @@ -29,8 +29,6 @@ public class Roster : Object, Gtk.TreeModel { public Contact get_contact(string jid) { string bareJID = jid.split("/", 2)[0]; - stdout.printf("Getting Contact for %s\n", bareJID); - return entries[bareJID]; } -- cgit v1.2.3