Revision 80684e32
ChatSecure/Classes/Controllers/XMPP/OTRXMPPRoomManager.m | ||
---|---|---|
80 | 80 |
NSString* accountId = self.xmppStream.tag; |
81 | 81 |
NSString *databaseRoomKey = [OTRXMPPRoom createUniqueId:accountId jid:jid.bare]; |
82 | 82 |
__block NSString *nickname = name; |
83 |
|
|
84 |
// Already joined? Can happen if we have auto-join bookmarks. |
|
85 |
if (room && room.isJoined) { |
|
86 |
return databaseRoomKey; |
|
87 |
} |
|
88 | 83 |
|
89 | 84 |
if (!room) { |
90 | 85 |
OTRXMPPRoomYapStorage *storage = [[OTRXMPPRoomYapStorage alloc] initWithDatabaseConnection:self.databaseConnection]; |
... | ... | |
361 | 356 |
|
362 | 357 |
- (void) xmppRoom:(XMPPRoom *)room didFetchMembersList:(NSArray<NSXMLElement*> *)items { |
363 | 358 |
DDLogInfo(@"Fetched members list: %@", items); |
364 |
[self xmppRoom:room addOccupantItems:items]; |
|
365 |
} |
|
366 |
|
|
367 |
- (void)xmppRoom:(XMPPRoom *)room didFetchModeratorsList:(NSArray *)items { |
|
368 |
DDLogInfo(@"Fetched moderators list: %@", items); |
|
369 |
[self xmppRoom:room addOccupantItems:items]; |
|
370 |
} |
|
371 |
|
|
372 |
- (void) xmppRoom:(XMPPRoom *)room addOccupantItems:(NSArray<NSXMLElement*> *)items { |
|
373 | 359 |
NSString *accountId = room.xmppStream.tag; |
374 | 360 |
[self.databaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) { |
375 | 361 |
[items enumerateObjectsUsingBlock:^(NSXMLElement *item, NSUInteger idx, BOOL * _Nonnull stop) { |
376 | 362 |
NSString *jidString = [item attributeStringValueForName:@"jid"]; |
377 | 363 |
XMPPJID *jid = [XMPPJID jidWithString:jidString]; |
378 |
NSString *affiliation = [item attributeStringValueForName:@"affiliation"]; |
|
379 |
|
|
380 |
// jid and affiliation MUST be included |
|
381 |
if (!jid || !affiliation) { return; } |
|
382 |
|
|
364 |
if (!jid) { return; } |
|
383 | 365 |
// Make sure occupant object exists/is created |
384 | 366 |
OTRXMPPRoomOccupant *occupant = [OTRXMPPRoomOccupant occupantWithJid:jid realJID:jid roomJID:room.roomJID accountId:accountId createIfNeeded:YES transaction:transaction]; |
385 |
occupant.affiliation = [RoomOccupantAffiliationHelper affiliationWithString:affiliation]; |
|
386 |
|
|
387 |
// Role MAY be included, so get that if it's there |
|
388 |
NSString *role = [item attributeStringValueForName:@"role"]; |
|
389 |
if (role) { |
|
390 |
occupant.role = [RoomOccupantRoleHelper roleWithString:role]; |
|
391 |
} |
|
392 |
|
|
393 | 367 |
[occupant saveWithTransaction:transaction]; |
394 | 368 |
}]; |
395 | 369 |
}]; |
396 | 370 |
} |
397 | 371 |
|
398 |
- (void)xmppRoomDidCreate:(XMPPRoom *)sender { |
|
399 |
[self.roomsToConfigure removeObject:sender.roomJID.bare]; |
|
400 |
[sender fetchConfigurationForm]; |
|
401 |
} |
|
402 |
|
|
403 |
- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(DDXMLElement *)configForm { |
|
404 |
[sender configureRoomUsingOptions:[[self class] defaultRoomConfiguration]]; |
|
405 |
} |
|
406 |
|
|
407 |
- (void)xmppRoom:(XMPPRoom *)sender didConfigure:(XMPPIQ *)iqResult { |
|
408 |
//Set Room Subject |
|
409 |
NSString *subject = [self.tempRoomSubject objectForKey:sender.roomJID.bare]; |
|
410 |
if (subject) { |
|
411 |
[self.tempRoomSubject removeObjectForKey:sender.roomJID.bare]; |
|
412 |
[sender changeRoomSubject:subject]; |
|
413 |
} |
|
414 |
|
|
415 |
//Invite buddies |
|
416 |
NSArray<NSString*> *buddyUniqueIds = [self.inviteDictionary objectForKey:sender.roomJID.bare]; |
|
417 |
if (buddyUniqueIds) { |
|
418 |
[self.inviteDictionary removeObjectForKey:sender.roomJID.bare]; |
|
419 |
[self inviteBuddies:buddyUniqueIds toRoom:sender]; |
|
420 |
} |
|
421 |
|
|
422 |
// Fetch member list. Ideally this would be done after the invites above have been sent to the network, but the messages pass all kinds of async delegates before they are actually sent, so unfortunately we can't wait for that. |
|
423 |
[self performBlockAsync:^{ |
|
424 |
[sender fetchMembersList]; |
|
425 |
[sender fetchModeratorsList]; |
|
426 |
}]; |
|
427 |
} |
|
428 |
|
|
429 | 372 |
- (void)xmppRoomDidJoin:(XMPPRoom *)sender |
430 | 373 |
{ |
431 |
// Older prosody servers have a bug where they consider all room as already |
|
432 |
// existing, so the status 201 is never sent. |
|
433 |
if ([self.roomsToConfigure containsObject:sender.roomJID.bare]) { |
|
434 |
[self xmppRoomDidCreate:sender]; |
|
435 |
} else { |
|
436 |
// Fetch member list |
|
437 |
[self performBlockAsync:^{ |
|
438 |
[sender fetchMembersList]; |
|
439 |
[sender fetchModeratorsList]; |
|
440 |
}]; |
|
441 |
} |
|
374 |
[self performBlockAsync:^{ |
|
375 |
//Configure room if we are the creator |
|
376 |
if ([self.roomsToConfigure containsObject:sender.roomJID.bare]) { |
|
377 |
[self.roomsToConfigure removeObject:sender.roomJID.bare]; |
|
378 |
[sender configureRoomUsingOptions:[[self class] defaultRoomConfiguration]]; |
|
379 |
|
|
380 |
//Set Room Subject |
|
381 |
NSString *subject = [self.tempRoomSubject objectForKey:sender.roomJID.bare]; |
|
382 |
if (subject) { |
|
383 |
[self.tempRoomSubject removeObjectForKey:sender.roomJID.bare]; |
|
384 |
[sender changeRoomSubject:subject]; |
|
385 |
} |
|
386 |
} |
|
387 |
|
|
388 |
//Invite buddies |
|
389 |
NSArray<NSString*> *buddyUniqueIds = [self.inviteDictionary objectForKey:sender.roomJID.bare]; |
|
390 |
if (buddyUniqueIds) { |
|
391 |
[self.inviteDictionary removeObjectForKey:sender.roomJID.bare]; |
|
392 |
[self inviteBuddies:buddyUniqueIds toRoom:sender]; |
|
393 |
} |
|
394 |
|
|
395 |
//Fetch member list |
|
396 |
[sender fetchMembersList]; |
|
397 |
}]; |
|
442 | 398 |
} |
443 | 399 |
|
444 | 400 |
- (void)xmppRoomDidLeave:(XMPPRoom *)sender { |
ChatSecure/Classes/Controllers/XMPP/OTRXMPPRoomYapStorage.m | ||
---|---|---|
195 | 195 |
occupant.roomName = [presenceJID resource]; |
196 | 196 |
|
197 | 197 |
// Role |
198 |
occupant.role = [RoomOccupantRoleHelper roleWithString:buddyRole]; |
|
198 |
if ([buddyRole isEqualToString:@"moderator"]) { |
|
199 |
occupant.role = RoomOccupantRoleModerator; |
|
200 |
} else if ([buddyRole isEqualToString:@"participant"]) { |
|
201 |
occupant.role = RoomOccupantRoleParticipant; |
|
202 |
} else if ([buddyRole isEqualToString:@"visitor"]) { |
|
203 |
occupant.role = RoomOccupantRoleVisitor; |
|
204 |
} else { |
|
205 |
occupant.role = RoomOccupantRoleNone; |
|
206 |
} |
|
199 | 207 |
|
200 | 208 |
// Affiliation |
201 |
occupant.affiliation = [RoomOccupantAffiliationHelper affiliationWithString:buddyAffiliation]; |
|
209 |
if ([buddyAffiliation isEqualToString:@"owner"]) { |
|
210 |
occupant.affiliation = RoomOccupantAffiliationOwner; |
|
211 |
} else if ([buddyAffiliation isEqualToString:@"admin"]) { |
|
212 |
occupant.affiliation = RoomOccupantAffiliationAdmin; |
|
213 |
} else if ([buddyAffiliation isEqualToString:@"member"]) { |
|
214 |
occupant.affiliation = RoomOccupantAffiliationMember; |
|
215 |
} else if ([buddyAffiliation isEqualToString:@"outcast"]) { |
|
216 |
occupant.affiliation = RoomOccupantAffiliationOutcast; |
|
217 |
} else { |
|
218 |
occupant.affiliation = RoomOccupantAffiliationNone; |
|
219 |
} |
|
202 | 220 |
[occupant saveWithTransaction:transaction]; |
203 | 221 |
}]; |
204 | 222 |
} |
ChatSecure/Classes/Model/Yap Storage/OTRXMPPRoomOccupant.swift | ||
---|---|---|
32 | 32 |
} |
33 | 33 |
} |
34 | 34 |
|
35 |
// Helper class to create from string, callable from obj-c |
|
36 |
@objc public class RoomOccupantRoleHelper: NSObject { |
|
37 |
@objc public static func role(withString role:String) -> RoomOccupantRole { |
|
38 |
switch role { |
|
39 |
case "moderator": |
|
40 |
return RoomOccupantRole.moderator |
|
41 |
case "participant": |
|
42 |
return RoomOccupantRole.participant |
|
43 |
case "visitor": |
|
44 |
return RoomOccupantRole.visitor |
|
45 |
default: |
|
46 |
return RoomOccupantRole.none |
|
47 |
} |
|
48 |
} |
|
49 |
} |
|
50 |
|
|
51 | 35 |
@objc public enum RoomOccupantAffiliation:Int { |
52 | 36 |
case none = 0 |
53 | 37 |
case outcast = 1 |
... | ... | |
63 | 47 |
} |
64 | 48 |
} |
65 | 49 |
|
66 |
// Helper class to create from string, callable from obj-c |
|
67 |
@objc public class RoomOccupantAffiliationHelper: NSObject { |
|
68 |
@objc public static func affiliation(withString affiliation:String) -> RoomOccupantAffiliation { |
|
69 |
switch affiliation { |
|
70 |
case "owner": |
|
71 |
return RoomOccupantAffiliation.owner |
|
72 |
case "admin": |
|
73 |
return RoomOccupantAffiliation.admin |
|
74 |
case "member": |
|
75 |
return RoomOccupantAffiliation.member |
|
76 |
case "outcast": |
|
77 |
return RoomOccupantAffiliation.outcast |
|
78 |
default: |
|
79 |
return RoomOccupantAffiliation.none |
|
80 |
} |
|
81 |
} |
|
82 |
} |
|
83 |
|
|
84 | 50 |
open class OTRXMPPRoomOccupant: OTRYapDatabaseObject, YapDatabaseRelationshipNode { |
85 | 51 |
|
86 | 52 |
@objc open static let roomEdgeName = "OTRRoomOccupantEdgeName" |
ChatSecure/Classes/View Controllers/OTRRoomOccupantsViewController.swift | ||
---|---|---|
330 | 330 |
fileprivate func fetchMembersList() { |
331 | 331 |
guard let xmppRoom = xmppRoom() else { return } |
332 | 332 |
xmppRoom.fetchMembersList() |
333 |
xmppRoom.fetchModeratorsList() |
|
334 | 333 |
} |
335 | 334 |
} |
336 | 335 |
|
... | ... | |
360 | 359 |
let cell:OTRBuddyInfoCheckableCell = tableView.dequeueReusableCell(withIdentifier: OTRRoomOccupantsViewController.CellIdentifier, for: indexPath) as! OTRBuddyInfoCheckableCell |
361 | 360 |
cell.setCheckImage(image: self.crownImage) |
362 | 361 |
var buddy:OTRXMPPBuddy? = nil |
363 |
var accountObject:OTRXMPPAccount? = nil |
|
364 | 362 |
if let roomOccupant = self.viewHandler?.object(indexPath) as? OTRXMPPRoomOccupant, let room = self.room, let jidString = roomOccupant.realJID ?? roomOccupant.jid, let jid = XMPPJID(string: jidString), let account = room.accountUniqueId { |
365 | 363 |
OTRDatabaseManager.shared.readOnlyDatabaseConnection?.read({ (transaction) in |
366 | 364 |
buddy = OTRXMPPBuddy.fetchBuddy(jid: jid, accountUniqueId: account, transaction: transaction) |
367 |
accountObject = OTRXMPPAccount.fetchObject(withUniqueID: account, transaction: transaction) |
|
368 | 365 |
}) |
369 | 366 |
if let buddy = buddy { |
370 | 367 |
cell.setThread(buddy, account: nil) |
371 | 368 |
if let occupantJid = roomOccupant.jid, let ownJid = ownOccupant?.jid, occupantJid.compare(ownJid) == .orderedSame { |
372 |
if let accountObject = accountObject { |
|
373 |
cell.avatarImageView.image = accountObject.avatarImage() |
|
374 |
} |
|
375 | 369 |
cell.nameLabel.text?.append(" (" + GROUP_INFO_YOU() + ")") |
376 | 370 |
} |
377 | 371 |
} else if let roomJid = room.jid { |
Also available in: Unified diff