summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--data/ephraim.glade1
-rw-r--r--src/core/ephraim.erl18
-rw-r--r--src/core/ephraim_conn.erl4
-rw-r--r--src/core/ephraim_conv.erl11
-rw-r--r--src/gui/Conversation.vala31
-rw-r--r--src/gui/CoreConnector.vala52
-rw-r--r--src/gui/Ephraim.vala40
-rw-r--r--src/gui/Roster.vala2
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 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
+ <property name="cursor_visible">False</property>
</object>
</child>
</object>
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<string, Conversation> conversations = new Gee.TreeMap<string, Conversation>();
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<string, Contact.Resource> 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];
}