Added roster updating.
--- a/roster.go Sun Jan 01 19:00:21 2012 -0700
+++ b/roster.go Sun Jan 01 19:32:51 2012 -0700
@@ -62,8 +62,6 @@
return <- ch
}
-// BUG(cjyar) The roster isn't actually updated when things change.
-
// Returns the current roster of other entities which this one has a
// relationship with. Changes to the roster will be signaled by an
// appropriate Iq appearing on Client.In. See RFC 3921, Section 7.4.
@@ -74,3 +72,40 @@
}
return r
}
+
+// The roster filter updates the Client's representation of the
+// roster, but it lets the relevant stanzas through.
+func (cl *Client) startRosterFilter() {
+ out := make(chan Stanza)
+ in := cl.AddFilter(out)
+ go func(inSave <-chan Stanza, outSave chan<- Stanza) {
+ defer close(out)
+ in := inSave
+ var out chan<- Stanza
+ var st Stanza
+ var ok bool
+ for {
+ select {
+ case st, ok = <- in:
+ if !ok {
+ break
+ }
+ cl.maybeUpdateRoster(st)
+ in = nil
+ out = outSave
+ case out <- st:
+ out = nil
+ in = inSave
+ }
+ }
+ }(in, out)
+}
+
+func (cl *Client) maybeUpdateRoster(st Stanza) {
+ rq, ok := st.GetNested().(*RosterQuery)
+ if st.GetName() == "iq" && st.GetType() == "set" && ok {
+ for _, item := range(rq.Item) {
+ cl.roster[item.Jid] = &item
+ }
+ }
+}
--- a/stream.go Sun Jan 01 19:00:21 2012 -0700
+++ b/stream.go Sun Jan 01 19:32:51 2012 -0700
@@ -217,8 +217,6 @@
}
}
-// BUG(cjyar) Allow extensions to provide filters in the form of "in
-// chan<- Stanza, out <-chan Stanza".
func (cl *Client) readStream(srvIn <-chan interface{}, cliOut chan<- Stanza) {
defer tryClose(srvIn, cliOut)
--- a/xmpp.go Sun Jan 01 19:00:21 2012 -0700
+++ b/xmpp.go Sun Jan 01 19:32:51 2012 -0700
@@ -146,6 +146,7 @@
// Start the manager for the filters that can modify what the
// app sees.
clIn := cl.startFilter(stIn)
+ cl.startRosterFilter()
// Initial handshake.
hsOut := &stream{To: jid.Domain, Version: Version}
@@ -200,6 +201,8 @@
filterOut := make(chan (<-chan Stanza))
filterIn := make(chan (<-chan Stanza))
go filter(srvIn, cliOut, filterOut, filterIn)
+ cl.filterOut = filterOut
+ cl.filterIn = filterIn
return cliOut
}