|
@@ -10,6 +10,7 @@
|
|
|
#import "TXClassroomVideoListCell.h"
|
|
|
#import "ClassroomService.h"
|
|
|
#import "ClassMemberEmptyView.h"
|
|
|
+#import "KSIndexPathValidator.h"
|
|
|
|
|
|
|
|
|
|
|
@@ -51,10 +52,15 @@
|
|
|
}
|
|
|
|
|
|
- (void)getDataSource {
|
|
|
+ __weak typeof(self) weakSelf = self;
|
|
|
dispatch_async(self.videoListQueue, ^{
|
|
|
- MJ_LOCK(self.signalSemaphore);
|
|
|
+ __strong typeof(weakSelf) strongSelf = weakSelf;
|
|
|
+ if (!strongSelf) return;
|
|
|
+
|
|
|
+ MJ_LOCK(self.signalSemaphore)
|
|
|
NSArray *tempArray = [ClassroomService sharedService].currentRoom.memberList;
|
|
|
if (tempArray.count <= 0) {
|
|
|
+ MJ_UNLOCK(strongSelf.signalSemaphore)
|
|
|
return;
|
|
|
}
|
|
|
NSSortDescriptor * des = [[NSSortDescriptor alloc] initWithKey:@"joinTime" ascending:YES];
|
|
@@ -96,20 +102,29 @@
|
|
|
|
|
|
// 移除掉主屏显示成员
|
|
|
NSString *display = [ClassroomService sharedService].currentRoom.currentDisplayURI;
|
|
|
- for (RoomMember *member in lastArray) {
|
|
|
+ NSMutableIndexSet *removeIndexes = [[NSMutableIndexSet alloc] init];
|
|
|
+ [lastArray enumerateObjectsUsingBlock:^(RoomMember *member, NSUInteger idx, BOOL *stop) {
|
|
|
if ([member.userId isEqualToString:display] && [ClassroomService sharedService].currentRoom.currentDisplayType != DisplayWhiteboard) {
|
|
|
- [lastArray removeObject:member];
|
|
|
- break;
|
|
|
+ [removeIndexes addIndex:idx];
|
|
|
+ *stop = YES;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
+ }];
|
|
|
+ [lastArray removeObjectsAtIndexes:removeIndexes];
|
|
|
+
|
|
|
+ NSArray *safeData = [lastArray copy]; // 创建不可变副本
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
- self.videoDataSource = [lastArray mutableCopy];
|
|
|
- NSLog(@"---------- list count %zd", lastArray.count);
|
|
|
- [self.videoListTableView reloadData];
|
|
|
- [self changeEmptyDisplay];
|
|
|
+ __strong typeof(weakSelf) strongSelf = weakSelf;
|
|
|
+ if (!strongSelf || !strongSelf.videoListTableView) {
|
|
|
+ MJ_UNLOCK(strongSelf.signalSemaphore)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ strongSelf.videoDataSource = [safeData mutableCopy];
|
|
|
+ [strongSelf.videoListTableView reloadData];
|
|
|
+ [strongSelf changeEmptyDisplay];
|
|
|
+ MJ_UNLOCK(strongSelf.signalSemaphore)
|
|
|
});
|
|
|
- MJ_UNLOCK(self.signalSemaphore)
|
|
|
+
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -121,61 +136,115 @@
|
|
|
}
|
|
|
|
|
|
- (void)updateUserVideo:(NSString *)userId {
|
|
|
+ __weak typeof(self) weakSelf = self;
|
|
|
dispatch_async(self.videoListQueue, ^{
|
|
|
- MJ_LOCK(self.signalSemaphore)
|
|
|
- for(int i=0;i < self.videoDataSource.count; i++) {
|
|
|
- RoomMember *member = self.videoDataSource[i];
|
|
|
- if([member.userId isEqualToString:userId]) {
|
|
|
- NSIndexPath *index = [NSIndexPath indexPathForRow:i inSection:0];
|
|
|
- dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
- TXClassroomVideoListCell * cell = [self.videoListTableView cellForRowAtIndexPath:index];
|
|
|
- if (cell) {
|
|
|
- [self.videoListTableView reloadRowsAtIndexPaths:@[index] withRowAnimation:UITableViewRowAnimationNone];
|
|
|
- }
|
|
|
- });
|
|
|
+ __strong typeof(weakSelf) strongSelf = weakSelf;
|
|
|
+ if (!strongSelf) return;
|
|
|
+
|
|
|
+ MJ_LOCK(strongSelf.signalSemaphore)
|
|
|
+ NSArray *safeDataSource = [strongSelf.videoDataSource copy];
|
|
|
+ NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
|
|
|
+
|
|
|
+ [safeDataSource enumerateObjectsUsingBlock:^(RoomMember *member, NSUInteger idx, BOOL *stop) {
|
|
|
+ if ([member.userId isEqualToString:userId]) {
|
|
|
+ [indexPaths addObject:[NSIndexPath indexPathForRow:idx inSection:0]];
|
|
|
}
|
|
|
+ }];
|
|
|
+
|
|
|
+ if (indexPaths.count == 0) {
|
|
|
+ MJ_UNLOCK(strongSelf.signalSemaphore)
|
|
|
+ return;
|
|
|
}
|
|
|
- MJ_UNLOCK(self.signalSemaphore)
|
|
|
+
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
+ __strong typeof(weakSelf) strongSelf = weakSelf;
|
|
|
+ if (!strongSelf) {
|
|
|
+ MJ_UNLOCK(strongSelf.signalSemaphore)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ NSArray *validIPs = [[KSIndexPathValidator validatorWithType:KSScrollViewTypeTableView] validateForTableView:self.videoListTableView indexPaths:indexPaths];
|
|
|
+ if (validIPs.count) {
|
|
|
+ [strongSelf.videoListTableView performBatchUpdates:^{
|
|
|
+ [strongSelf.videoListTableView reloadRowsAtIndexPaths:validIPs
|
|
|
+ withRowAnimation:UITableViewRowAnimationNone];
|
|
|
+ } completion:^(BOOL finished) {
|
|
|
+ MJ_UNLOCK(strongSelf.signalSemaphore)
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ MJ_UNLOCK(strongSelf.signalSemaphore)
|
|
|
+ }
|
|
|
+ });
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- (void)updateUserQuality:(NSString *)userId netWorkingStatus:(TXNetWorkingStatus)quality {
|
|
|
+ __weak typeof(self) weakSelf = self;
|
|
|
dispatch_async(self.videoListQueue, ^{
|
|
|
- MJ_LOCK(self.signalQualitySemaphore)
|
|
|
- for(int i = 0;i < self.videoDataSource.count; i++) {
|
|
|
- RoomMember *member = self.videoDataSource[i];
|
|
|
- if([member.userId isEqualToString:userId]) {
|
|
|
- NSIndexPath *index = [NSIndexPath indexPathForRow:i inSection:0];
|
|
|
+ __strong typeof(weakSelf) strongSelf = weakSelf;
|
|
|
+ if (!strongSelf) return;
|
|
|
+
|
|
|
+ MJ_LOCK(strongSelf.signalQualitySemaphore)
|
|
|
+ NSArray *safeDataSource = [strongSelf.videoDataSource copy];
|
|
|
+
|
|
|
+ [safeDataSource enumerateObjectsUsingBlock:^(RoomMember *member, NSUInteger idx, BOOL *stop) {
|
|
|
+ if ([member.userId isEqualToString:userId]) {
|
|
|
+ RoomMember *currentMember = [[ClassroomService sharedService].currentRoom getMember:userId];
|
|
|
+ NSIndexPath *index = [NSIndexPath indexPathForRow:idx inSection:0];
|
|
|
+
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
- TXClassroomVideoListCell * cell = [self.videoListTableView cellForRowAtIndexPath:index];
|
|
|
+ __strong typeof(weakSelf) strongSelf = weakSelf;
|
|
|
+ if (!strongSelf) {
|
|
|
+ MJ_UNLOCK(strongSelf.signalQualitySemaphore)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ TXClassroomVideoListCell * cell = [strongSelf.videoListTableView cellForRowAtIndexPath:index];
|
|
|
if (cell) {
|
|
|
[cell updateQuality:quality];
|
|
|
}
|
|
|
+ MJ_UNLOCK(strongSelf.signalQualitySemaphore)
|
|
|
});
|
|
|
+ return;
|
|
|
}
|
|
|
- }
|
|
|
- MJ_UNLOCK(self.signalQualitySemaphore)
|
|
|
+ }];
|
|
|
+
|
|
|
+ MJ_UNLOCK(strongSelf.signalQualitySemaphore)
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- (void)updateMicStatus:(NSString *)userId volume:(NSInteger)volume {
|
|
|
+ __weak typeof(self) weakSelf = self;
|
|
|
dispatch_async(self.videoListQueue, ^{
|
|
|
- MJ_LOCK(self.signalVolumeSemaphore)
|
|
|
- for(int i = 0;i < self.videoDataSource.count; i++) {
|
|
|
- RoomMember *member = self.videoDataSource[i];
|
|
|
- if([member.userId isEqualToString:userId]) {
|
|
|
- RoomMember *roomMember = [[ClassroomService sharedService].currentRoom getMember:userId];
|
|
|
-
|
|
|
- NSIndexPath *index = [NSIndexPath indexPathForRow:i inSection:0];
|
|
|
+ __strong typeof(weakSelf) strongSelf = weakSelf;
|
|
|
+ if (!strongSelf) return;
|
|
|
+
|
|
|
+ MJ_LOCK(strongSelf.signalVolumeSemaphore)
|
|
|
+ NSArray *safeDataSource = [strongSelf.videoDataSource copy];
|
|
|
+
|
|
|
+ [safeDataSource enumerateObjectsUsingBlock:^(RoomMember *member, NSUInteger idx, BOOL *stop) {
|
|
|
+ if ([member.userId isEqualToString:userId]) {
|
|
|
+ RoomMember *currentMember = [[ClassroomService sharedService].currentRoom getMember:userId];
|
|
|
+ NSIndexPath *index = [NSIndexPath indexPathForRow:idx inSection:0];
|
|
|
+
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
- TXClassroomVideoListCell * cell = [self.videoListTableView cellForRowAtIndexPath:index];
|
|
|
+ __strong typeof(weakSelf) strongSelf = weakSelf;
|
|
|
+ if (!strongSelf) {
|
|
|
+ MJ_UNLOCK(strongSelf.signalVolumeSemaphore)
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ TXClassroomVideoListCell *cell = [strongSelf.videoListTableView cellForRowAtIndexPath:index];
|
|
|
if (cell) {
|
|
|
- [cell updateUserVolume:volume isCloseMic:!roomMember.microphoneEnable];
|
|
|
+ [cell updateUserVolume:volume isCloseMic:!currentMember.microphoneEnable];
|
|
|
}
|
|
|
+ MJ_UNLOCK(strongSelf.signalVolumeSemaphore)
|
|
|
});
|
|
|
+ return;
|
|
|
}
|
|
|
- }
|
|
|
- MJ_UNLOCK(self.signalVolumeSemaphore)
|
|
|
+ }];
|
|
|
+
|
|
|
+ MJ_UNLOCK(strongSelf.signalVolumeSemaphore)
|
|
|
});
|
|
|
}
|
|
|
|