roster.go
changeset 46 4a4530b8f622
parent 42 f6bb47ca12f2
child 47 22e575eff35a
--- 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
+		}
+	}
+}