Added roster updating.
authorChris Jones <chris@cjones.org>
Sun, 01 Jan 2012 19:32:51 -0700
changeset 46 4a4530b8f622
parent 45 abf958bcc201
child 47 22e575eff35a
Added roster updating.
roster.go
stream.go
xmpp.go
--- 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
 }