Revision 80684e32

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
    }
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