mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 13:17:49 +00:00
342 lines
12 KiB
Objective-C
342 lines
12 KiB
Objective-C
//
|
|
// RBFullFriendListScreenController.m
|
|
// RobloxMobile
|
|
//
|
|
// Created by Ariel Lichtin on 9/23/14.
|
|
// Copyright (c) 2014 ROBLOX. All rights reserved.
|
|
//
|
|
|
|
#import "RBFullFriendListScreenController.h"
|
|
#import "RobloxTheme.h"
|
|
#import "RobloxData.h"
|
|
#import "RBPlayerThumbnailCell.h"
|
|
#import "RBProfileViewController.h"
|
|
|
|
#define FRIENDCELL_ID @"FriendCell"
|
|
|
|
#define FRIEND_AVATAR_SIZE CGSizeMake(110, 110)
|
|
#define ITEM_SIZE CGSizeMake(90, 108)
|
|
|
|
#define FRIENDS_PER_REQUEST 60
|
|
#define START_REQUEST_THRESHOLD 10 // The next request will start when there are 10 elements left
|
|
|
|
#define FOLLOWERS_PER_PAGE 50
|
|
|
|
@interface RBFullFriendListScreenController () <UICollectionViewDataSource, UICollectionViewDelegate>
|
|
|
|
@end
|
|
|
|
@implementation RBFullFriendListScreenController
|
|
{
|
|
NSMutableArray* _friends;
|
|
|
|
UICollectionView* _collectionView;
|
|
|
|
BOOL _requestInProgress;
|
|
BOOL _friendsListComplete;
|
|
NSUInteger _numItemsInCollectionView;
|
|
}
|
|
|
|
-(id)init
|
|
{
|
|
_listTypeValue = RBListTypeFriends; //unless overwritten, this should be the default
|
|
return self;
|
|
}
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
|
|
self.view.backgroundColor = [RobloxTheme lightBackground];
|
|
|
|
self.edgesForExtendedLayout = UIRectEdgeNone;
|
|
|
|
self.title = [self useRelevantTitle];
|
|
|
|
// Initialize the collection view
|
|
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
|
|
[flowLayout setItemSize:ITEM_SIZE];
|
|
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
|
|
[flowLayout setMinimumLineSpacing:42.0f];
|
|
[flowLayout setMinimumInteritemSpacing:6.0f];
|
|
[flowLayout setSectionInset:UIEdgeInsetsMake(24, 35, 24, 35)];
|
|
|
|
_collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
|
|
_collectionView.dataSource = self;
|
|
_collectionView.delegate = self;
|
|
_collectionView.backgroundColor = [UIColor clearColor];
|
|
_collectionView.backgroundView = nil;
|
|
[_collectionView registerNib:[UINib nibWithNibName:@"RBPlayerThumbnailCell" bundle:nil] forCellWithReuseIdentifier:FRIENDCELL_ID];
|
|
|
|
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:nil];
|
|
[self.navigationItem setBackBarButtonItem:backButton];
|
|
|
|
[self.view addSubview:_collectionView];
|
|
|
|
[self clearCollectionView];
|
|
|
|
[self fetchFriends];
|
|
}
|
|
|
|
- (void)viewDidLayoutSubviews
|
|
{
|
|
[super viewDidLayoutSubviews];
|
|
|
|
[_collectionView setFrame:self.view.bounds];
|
|
}
|
|
|
|
- (void) clearCollectionView
|
|
{
|
|
_requestInProgress = NO;
|
|
_friendsListComplete = NO;
|
|
_numItemsInCollectionView = 0;
|
|
_friends = [NSMutableArray array];
|
|
[_collectionView reloadData];
|
|
}
|
|
|
|
- (NSString*) useRelevantTitle
|
|
{
|
|
NSString* aTitle = @"";
|
|
|
|
switch (_listTypeValue)
|
|
{
|
|
case RBListTypeFollowing: { aTitle = [NSString stringWithFormat:NSLocalizedString(@"FollowingTitleFormat", nil)]; }
|
|
break;
|
|
|
|
case RBListTypeFollowers: { aTitle = [NSString stringWithFormat:NSLocalizedString(@"FollowersTitleFormat", nil), self.playerName]; }
|
|
break;
|
|
|
|
default: { aTitle = [NSString stringWithFormat:NSLocalizedString(@"FriendsTitleFormat", nil), self.playerName]; }
|
|
break;
|
|
}
|
|
return aTitle;
|
|
}
|
|
|
|
//THIS IS A MISNOMER- THIS IS A CONTEXT SPECIFIC SEARCH
|
|
//IT MIGHT FETCH FRIENDS BUT IT CAN ALSO FETCH OTHER THINGS LIKE FOLLOWERS AND FOLLOWING TOO
|
|
- (void) fetchFriends
|
|
{
|
|
_friends = [NSMutableArray array];
|
|
[_collectionView reloadData];
|
|
|
|
switch (_listTypeValue)
|
|
{
|
|
case RBListTypeFriends:
|
|
{
|
|
[RobloxData fetchUserFriends:self.playerID
|
|
friendType:RBXFriendTypeAllFriends
|
|
startIndex:0
|
|
numItems:FRIENDS_PER_REQUEST
|
|
avatarSize:FRIEND_AVATAR_SIZE
|
|
completion:^(NSUInteger totalFriends, NSArray *friends)
|
|
{
|
|
if(friends)
|
|
{
|
|
[self initializeElementsWithArray:friends];
|
|
}
|
|
}];
|
|
}
|
|
break;
|
|
case RBListTypeFollowing:
|
|
{
|
|
[RobloxData fetchMyFollowingAtPage:1
|
|
avatarSize:FRIEND_AVATAR_SIZE
|
|
withCompletion:^(bool success, NSArray *following) {
|
|
if (following)
|
|
[self initializeElementsWithArray:following];
|
|
}];
|
|
}
|
|
break;
|
|
case RBListTypeFollowers:
|
|
{
|
|
[RobloxData fetchFollowersForUser:_playerID
|
|
atPage:1
|
|
avatarSize:FRIEND_AVATAR_SIZE
|
|
withCompletion:^(bool success, NSArray *followers) {
|
|
if (followers)
|
|
[self initializeElementsWithArray:followers];
|
|
}];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
- (void) fetchMoreFriends
|
|
{
|
|
if(!_friendsListComplete && !_requestInProgress && _numItemsInCollectionView > _friends.count)
|
|
{
|
|
_requestInProgress = YES;
|
|
|
|
switch (_listTypeValue)
|
|
{
|
|
case RBListTypeFriends:
|
|
{
|
|
NSUInteger itemsToRequest = _numItemsInCollectionView - _friends.count;
|
|
[RobloxData fetchUserFriends:self.playerID
|
|
friendType:RBXFriendTypeAllFriends
|
|
startIndex:_friends.count
|
|
numItems:itemsToRequest
|
|
avatarSize:FRIEND_AVATAR_SIZE
|
|
completion:^(NSUInteger totalFriends, NSArray *friends) {
|
|
[self updateVisualElementsWithArray:friends];
|
|
}];
|
|
}
|
|
break;
|
|
case RBListTypeFollowing:
|
|
{
|
|
int page = _friends.count / FOLLOWERS_PER_PAGE;
|
|
[RobloxData fetchMyFollowingAtPage:page
|
|
avatarSize:FRIEND_AVATAR_SIZE
|
|
withCompletion:^(bool success, NSArray *following) {
|
|
[self updateVisualElementsWithArray:following];
|
|
}];
|
|
}
|
|
break;
|
|
case RBListTypeFollowers:
|
|
{
|
|
int page = _friends.count / FOLLOWERS_PER_PAGE;
|
|
[RobloxData fetchFollowersForUser:_playerID
|
|
atPage:page
|
|
avatarSize:FRIEND_AVATAR_SIZE
|
|
withCompletion:^(bool success, NSArray *followers) {
|
|
[self updateVisualElementsWithArray:followers];
|
|
}];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
-(void) initializeElementsWithArray:(NSArray*)friends
|
|
{
|
|
dispatch_async(dispatch_get_main_queue(), ^
|
|
{
|
|
_numItemsInCollectionView = friends.count;
|
|
[_friends addObjectsFromArray:friends];
|
|
[_collectionView reloadData];
|
|
});
|
|
}
|
|
-(void) updateVisualElementsWithArray:(NSArray*)friends
|
|
{
|
|
dispatch_async(dispatch_get_main_queue(), ^
|
|
{
|
|
NSInteger rangeFrom = _friends.count;
|
|
NSInteger rangeTo = rangeFrom + friends.count;
|
|
|
|
[_friends addObjectsFromArray:friends];
|
|
|
|
// Update visible elements
|
|
NSArray* visibleCells = [_collectionView indexPathsForVisibleItems];
|
|
NSMutableArray* cellsToUpdate = [NSMutableArray array];
|
|
for(NSIndexPath* indexPath in visibleCells)
|
|
{
|
|
BOOL inRange = indexPath.row >= rangeFrom && indexPath.row < rangeTo;
|
|
if(inRange)
|
|
[cellsToUpdate addObject:indexPath];
|
|
}
|
|
[_collectionView reloadItemsAtIndexPaths:cellsToUpdate];
|
|
|
|
NSUInteger itemsToRequest = _numItemsInCollectionView - _friends.count;
|
|
_friendsListComplete = friends.count < itemsToRequest;
|
|
if(_friendsListComplete)
|
|
{
|
|
// If the list is already completed,
|
|
// remove the remaining placeholder empty cells
|
|
NSUInteger totalElements = _numItemsInCollectionView;
|
|
|
|
_numItemsInCollectionView = _friends.count;
|
|
|
|
[_collectionView performBatchUpdates:^
|
|
{
|
|
NSMutableArray* indexes = [NSMutableArray array];
|
|
for(NSUInteger i = _friends.count; i < totalElements; ++i)
|
|
{
|
|
[indexes addObject:[NSIndexPath indexPathForRow:i inSection:0]];
|
|
}
|
|
[_collectionView deleteItemsAtIndexPaths:indexes];
|
|
}
|
|
completion:nil];
|
|
}
|
|
|
|
_requestInProgress = NO;
|
|
|
|
[self fetchMoreFriends];
|
|
});
|
|
}
|
|
|
|
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
|
{
|
|
return _numItemsInCollectionView;
|
|
}
|
|
|
|
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
RBPlayerThumbnailCell *cell = [_collectionView dequeueReusableCellWithReuseIdentifier:FRIENDCELL_ID forIndexPath:indexPath];
|
|
if(indexPath.row < _friends.count)
|
|
{
|
|
RBXFriendInfo* friendData = _friends[indexPath.row];
|
|
if([friendData isKindOfClass:[NSNull class]])
|
|
[cell setFriendInfo:nil];
|
|
else
|
|
[cell setFriendInfo:friendData];
|
|
}
|
|
else
|
|
{
|
|
[cell setFriendInfo:nil];
|
|
}
|
|
|
|
return cell;
|
|
}
|
|
|
|
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
|
{
|
|
NSArray* indexes = [_collectionView indexPathsForVisibleItems];
|
|
NSIndexPath* maxIndex = nil;
|
|
for(NSIndexPath* index in indexes)
|
|
{
|
|
if(maxIndex == nil || maxIndex.row < index.row)
|
|
{
|
|
maxIndex = index;
|
|
}
|
|
}
|
|
|
|
if(_friendsListComplete == NO && maxIndex.row + START_REQUEST_THRESHOLD > _numItemsInCollectionView)
|
|
{
|
|
int totalAdded = (_listTypeValue == RBListTypeFriends) ? FRIENDS_PER_REQUEST : FOLLOWERS_PER_PAGE;
|
|
_numItemsInCollectionView += totalAdded;
|
|
|
|
[_collectionView performBatchUpdates:^
|
|
{
|
|
NSMutableArray* indexes = [NSMutableArray array];
|
|
for(NSUInteger i = _numItemsInCollectionView - totalAdded; i < _numItemsInCollectionView; ++i)
|
|
{
|
|
[indexes addObject:[NSIndexPath indexPathForRow:i inSection:0]];
|
|
}
|
|
[_collectionView insertItemsAtIndexPaths:indexes];
|
|
}
|
|
completion:nil];
|
|
|
|
[self fetchMoreFriends];
|
|
}
|
|
}
|
|
|
|
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
if(indexPath.row < _friends.count)
|
|
{
|
|
RBProfileViewController *viewController = (RBProfileViewController*) [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"RBOthersProfileViewController"];
|
|
|
|
RBXFriendInfo* friendInfo = _friends[indexPath.row];
|
|
viewController.userId = friendInfo.userID;
|
|
|
|
[self.navigationController pushViewController:viewController animated:YES];
|
|
}
|
|
}
|
|
|
|
@end
|