]> cgit.babelmonkeys.de Git - jubjub.git/blob - src/core/JubChatClient.m
Add basic Service Discovery support
[jubjub.git] / src / core / JubChatClient.m
1 #import "JubChatClient.h"
2 #import "ObjXMPP/namespaces.h"
3
4 #define JUB_CLIENT_URI @"http://babelmonkeys.de/jubjub"
5
6 @implementation JubChatClient
7 @synthesize connection = _connection;
8 @synthesize roster = _roster;
9 @synthesize contactManager = _contactManager;
10 @synthesize discoEntity = _discoEntity;
11 @synthesize presence = _presence;
12 @synthesize ui = _ui;
13
14 - initWithConfig: (JubConfig*)config
15 {
16         self = [super init];
17
18         @try {
19                 _chatMap = [[OFMutableDictionary alloc] init];
20
21                 _connection = [XMPPConnection new];
22                 _connection.username = config.username;
23                 _connection.domain = config.domain;
24                 _connection.server = config.server;
25                 _connection.password = config.password;
26                 [_connection addDelegate: self];
27
28                 _roster = [[XMPPRoster alloc] initWithConnection: _connection];
29                 [_roster addDelegate: self];
30
31                 _contactManager = [[XMPPContactManager alloc]
32                     initWithConnection: _connection
33                                 roster: _roster];
34                 [_contactManager addDelegate: self];
35
36                 _streamManagement = [[XMPPStreamManagement alloc]
37                     initWithConnection: _connection];
38         } @catch (id e) {
39                 [self release];
40                 @throw e;
41         }
42
43         return self;
44 }
45
46 - (void)dealloc
47 {
48         [_roster removeDelegate: self];
49         [_contactManager removeDelegate: self];
50         [_connection removeDelegate: self];
51
52         [_roster release];
53         [_contactManager release];
54         [_discoEntity release];
55         [_streamManagement release];
56         [_connection release];
57         [_presence release];
58         [_chatMap release];
59
60         [super dealloc];
61 }
62
63 - (id<JubChatUI>)chatForContact: (XMPPContact*)contact
64 {
65         OFAutoreleasePool *pool = [OFAutoreleasePool new];
66         OFString *bareJID = [contact.rosterItem.JID bareJID];
67
68         id<JubChatUI> chat = [_chatMap objectForKey: bareJID];
69         if (chat == nil) {
70                 OFString * title =
71                     [@"Chat with " stringByAppendingString: bareJID];
72
73                 chat = [[[[_ui chatUIClass] alloc]
74                     initWithTitle: title
75                        closeBlock: ^{
76                                 [_chatMap removeObjectForKey: bareJID];
77                         }
78                         sendBlock: ^(OFString *text) {
79                                 XMPPMessage *msg =
80                                     [XMPPMessage messageWithType: @"chat"];
81                                 msg.body = text;
82                                 [contact sendMessage: msg
83                                           connection: _connection];
84                         }
85                 ] autorelease];
86
87                 [_chatMap setObject: chat
88                              forKey: bareJID];
89         }
90
91         [pool release];
92
93         return chat;
94 }
95
96 - (void)sendPresenceWithStatus: (OFString*)status
97 {
98         [self sendPresenceWithStatus: status
99                                 text: nil];
100 }
101
102 - (void)sendPresenceWithStatus: (OFString*)status
103                           text: (OFString*)text
104 {
105         XMPPPresence *presence;
106
107         if ([status isEqual: @"unavailable"])
108                 presence = [XMPPPresence presenceWithType: @"unavailable"];
109         else
110                 presence = [XMPPPresence presence];
111
112         if (!([status isEqual: @"available"] ||
113               [status isEqual: @"unavailable"]))
114                 presence.show = status;
115
116         if (text != nil)
117                 presence.status = text;
118
119         OFXMLElement *caps = [OFXMLElement elementWithName: @"c"
120                                                  namespace: XMPP_NS_CAPS];
121         [caps addAttributeWithName: @"hash"
122                        stringValue: @"sha-1"];
123         [caps addAttributeWithName: @"ver"
124                        stringValue: [_discoEntity capsHash]];
125         [caps addAttributeWithName: @"node"
126                        stringValue: JUB_CLIENT_URI];
127
128         [presence addChild: caps];
129
130         [_connection sendStanza: presence];
131 }
132
133 - (void)connection: (XMPPConnection*)connection
134      wasBoundToJID: (XMPPJID*)jid
135 {
136         of_log(@"Bound to JID: %@", [jid fullJID]);
137
138         _discoEntity =
139             [[XMPPDiscoEntity alloc] initWithConnection: connection
140                                                capsNode: JUB_CLIENT_URI];
141
142         XMPPDiscoIdentity *identity =
143             [XMPPDiscoIdentity identityWithCategory: @"client"
144                                                type: @"pc"
145                                                name: @"JubJub"];
146         [_discoEntity addIdentity: identity];
147         [_discoEntity addFeature: XMPP_NS_CAPS];
148
149         [_roster requestRoster];
150 }
151
152 -   (void)connection: (XMPPConnection*)connection
153   didReceivePresence: (XMPPPresence*)presence
154 {
155         if ([presence.from isEqual: connection.JID]) {
156                 [_ui         client: self
157                   didChangePresence: presence];
158                 OF_SETTER(_presence, presence, YES, 0);
159         }
160 }
161
162 -  (void)contact: (XMPPContact*)contact
163   didSendMessage: (XMPPMessage*)message
164 {
165         if (message.body == nil || ![message.type isEqual: @"chat"])
166                 return;
167
168         id<JubChatUI> chat = [self chatForContact: contact];
169         [chat addMessage: message.body
170                   sender: [message.from bareJID]];
171 }
172
173 - (void)rosterWasReceived: (XMPPRoster*)roster
174 {
175         [self sendPresenceWithStatus: @"available"
176                                 text: @"Hello from JubJub"];
177 }
178 @end