Revision 74191bbf

View differences:

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
    }
83 88
    
84 89
    if (!room) {
85 90
        OTRXMPPRoomYapStorage *storage = [[OTRXMPPRoomYapStorage alloc] initWithDatabaseConnection:self.databaseConnection];
......
356 361

  
357 362
- (void) xmppRoom:(XMPPRoom *)room didFetchMembersList:(NSArray<NSXMLElement*> *)items {
358 363
    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 {
359 373
    NSString *accountId = room.xmppStream.tag;
360 374
    [self.databaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) {
361 375
        [items enumerateObjectsUsingBlock:^(NSXMLElement *item, NSUInteger idx, BOOL * _Nonnull stop) {
362 376
            NSString *jidString = [item attributeStringValueForName:@"jid"];
363 377
            XMPPJID *jid = [XMPPJID jidWithString:jidString];
364
            if (!jid) { return; }
378
            NSString *affiliation = [item attributeStringValueForName:@"affiliation"];
379
            
380
            // jid and affiliation MUST be included
381
            if (!jid || !affiliation) { return; }
382
            
365 383
            // Make sure occupant object exists/is created
366 384
            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
            
367 393
            [occupant saveWithTransaction:transaction];
368 394
        }];
369 395
    }];
370 396
}
371 397

  
372
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
373
{
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.
374 423
    [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];
424
            [sender fetchMembersList];
425
            [sender fetchModeratorsList];
397 426
    }];
398 427
}
399 428

  
429
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
430
{
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
    }
442
}
443

  
400 444
- (void)xmppRoomDidLeave:(XMPPRoom *)sender {
401 445
    NSString *databaseRoomKey = [OTRXMPPRoom createUniqueId:self.xmppStream.tag jid:[sender.roomJID bare]];
402 446
    [self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) {
ChatSecure/Classes/Controllers/XMPP/OTRXMPPRoomYapStorage.m
195 195
        occupant.roomName = [presenceJID resource];
196 196
        
197 197
        // Role
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
        }
198
        occupant.role = [RoomOccupantRoleHelper roleWithString:buddyRole];
207 199

  
208 200
        // Affiliation
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
        }
201
        occupant.affiliation = [RoomOccupantAffiliationHelper affiliationWithString:buddyAffiliation];
220 202
        [occupant saveWithTransaction:transaction];
221 203
    }];
222 204
}
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

  
35 51
@objc public enum RoomOccupantAffiliation:Int {
36 52
    case none = 0
37 53
    case outcast = 1
......
47 63
    }
48 64
}
49 65

  
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

  
50 84
open class OTRXMPPRoomOccupant: OTRYapDatabaseObject, YapDatabaseRelationshipNode {
51 85
    
52 86
    @objc open static let roomEdgeName = "OTRRoomOccupantEdgeName"

Also available in: Unified diff