diff --git a/Limelight/HostCardView.h b/Limelight/HostCardView.h index 34928aa0..5d25df99 100644 --- a/Limelight/HostCardView.h +++ b/Limelight/HostCardView.h @@ -20,9 +20,12 @@ @interface HostCardView : UIView @property (nonatomic, assign) CGFloat sizeFactor; +@property (nonatomic, readonly) CGSize size; + - (void)resizeBySizeFactor:(CGFloat)factor; - (id) initWithHost:(TemporaryHost*)host; +- (id) initWithHost:(TemporaryHost*)host andSizeFactor:(CGFloat)sizeFactor; @end diff --git a/Limelight/HostCardView.m b/Limelight/HostCardView.m index 0ddd0e93..2305bdf4 100644 --- a/Limelight/HostCardView.m +++ b/Limelight/HostCardView.m @@ -26,6 +26,8 @@ @property (nonatomic, strong) UIView *separatorLine; @property (nonatomic, assign) CGFloat cardContentpadding; @property (nonatomic, assign) UIUserInterfaceStyle userIterfaceStyle; +@property (nonatomic, assign) CGSize size; + @end @@ -50,14 +52,13 @@ static const float REFRESH_CYCLE = 2.0f; - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { - self.sizeFactor = 1.0; // decisive factor assign computerIconMonitorCenterYOffset = -3.3*_sizeFactor; iconAndButtonSpacing = 37*_sizeFactor; buttonHeight = 40*_sizeFactor; defaultBlue = [UIColor appPrimaryColor]; defaultGreen = [UIColor colorWithRed:52.0/255.0 green:199.0/255.0 blue:89.0/255.0 alpha:1.0]; self.userIterfaceStyle = self.traitCollection.userInterfaceStyle; - self.userIterfaceStyle = UIUserInterfaceStyleLight; + // self.userIterfaceStyle = UIUserInterfaceStyleLight; [self createBackgroundLayer]; [self setupUI]; } @@ -65,6 +66,17 @@ static const float REFRESH_CYCLE = 2.0f; } - (id) initWithHost:(TemporaryHost*)host { + self.sizeFactor = 1.0; + self = [self init]; + _host = host; + + // Use UIContextMenuInteraction on iOS 13.0+ and a standard UILongPressGestureRecognizer + // for tvOS devices and iOS prior to 13.0. + return self; +} + +- (id) initWithHost:(TemporaryHost*)host andSizeFactor:(CGFloat)sizeFactor { + _sizeFactor = sizeFactor; self = [self init]; _host = host; @@ -268,6 +280,9 @@ static const float REFRESH_CYCLE = 2.0f; // Fallback on earlier versions } + [_rightButton addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside]; + + [NSLayoutConstraint activateConstraints:@[ [self.rightButton.leadingAnchor constraintEqualToAnchor:self.leftButton.trailingAnchor constant:15*_sizeFactor], [self.rightButton.centerYAnchor constraintEqualToAnchor:self.leftButton.centerYAnchor constant:0], @@ -328,6 +343,8 @@ static const float REFRESH_CYCLE = 2.0f; _widthConstraint.constant = _cardContentpadding*2 + appButtonWidth + 15*_sizeFactor + launchButtonWidth; _heightConstraint.constant = _cardContentpadding*2 + _iconBackgroundView.frame.size.height + iconAndButtonSpacing + buttonHeight + 1; + _size = CGSizeMake(_widthConstraint.constant, _heightConstraint.constant); + // standard size: 261 * 184 [self updateTheme:_userIterfaceStyle]; // [self updateContentsForHost:_host]; @@ -336,8 +353,9 @@ static const float REFRESH_CYCLE = 2.0f; - (void)createBackgroundLayer{ backgroundLayer = [CAGradientLayer layer]; - UIColor *gradientColor = [UIColor colorWithRed:0.0 green:0.319 blue:0.64 alpha:1.0]; - CGColorRef gradientColorRef = _userIterfaceStyle == UIUserInterfaceStyleDark ? gradientColor.CGColor : [gradientColor colorWithAlphaComponent:0.52].CGColor; + UIColor *gradientColorDark = [UIColor colorWithRed:0.0 green:0.319 blue:0.64 alpha:1.0]; + UIColor *gradientColorLight = [gradientColorDark colorWithAlphaComponent:0.52]; + CGColorRef gradientColorRef = _userIterfaceStyle == UIUserInterfaceStyleDark ? gradientColorDark.CGColor : gradientColorLight.CGColor; backgroundLayer.colors = @[ (__bridge id)[UIColor clearColor].CGColor, (__bridge id)[UIColor clearColor].CGColor, @@ -380,15 +398,16 @@ static const float REFRESH_CYCLE = 2.0f; self.backgroundColor = [UIColor widgetBackgroundColorLight]; backgroundLayer.hidden = NO; break; - default:break; } + [self updateContentsForHost:_host]; } - (void)didMoveToSuperview { // Start our update loop when we are added to our cell if (self.superview != nil && _host != nil) { + NSLog(@"start update loop"); [self updateLoop]; } } @@ -406,32 +425,23 @@ static const float REFRESH_CYCLE = 2.0f; } +- (void) buttonTapped { + NSLog(@"button test"); +} + + - (void) updateLoop { // Stop immediately if the view has been detached if (self.superview == nil) { return; } - + [self updateContentsForHost:_host]; // Queue the next refresh cycle [self performSelector:@selector(updateLoop) withObject:self afterDelay:REFRESH_CYCLE]; } -- (void) switchButtonsForHostState:(State)hostState{ - switch (hostState) { - case StateOnline: - [self.leftButton setTitle:[LocalizationHelper localizedStringForKey:@"Applications"] forState:UIControlStateNormal]; - [self.rightButton setTitle:[LocalizationHelper localizedStringForKey:@" Launch"] forState:UIControlStateNormal]; - - break; - case StateOffline: - break; - case StateUnknown: - break; - } -} - - (void) updateContentsForHost:(TemporaryHost*)host { _hostNameLabel.text = host.name; // self.hostNameLabel.text = @"RazerBlade 16 testttttettest"; diff --git a/Limelight/UIColor+Theme.m b/Limelight/UIColor+Theme.m index c063de77..b7283174 100644 --- a/Limelight/UIColor+Theme.m +++ b/Limelight/UIColor+Theme.m @@ -28,7 +28,9 @@ } + (UIColor *)widgetBackgroundColorLight{ - return [UIColor colorWithRed:242.0/255.0 green:242.0/255.0 blue:247.0/255.0 alpha:1.0]; + // return [UIColor colorWithRed:242.0/255.0 green:242.0/255.0 blue:247.0/255.0 alpha:1.0]; + return [UIColor whiteColor]; + } + (UIColor *)separatorColorDark{ @@ -60,7 +62,9 @@ } + (UIColor *)appBackgroundColorLight { - return [UIColor whiteColor]; + //return [UIColor whiteColor]; + return [UIColor colorWithRed:242.0/255.0 green:242.0/255.0 blue:247.0/255.0 alpha:1.0]; + } diff --git a/Limelight/ViewControllers/HostCollectionViewController.h b/Limelight/ViewControllers/HostCollectionViewController.h new file mode 100644 index 00000000..9725152d --- /dev/null +++ b/Limelight/ViewControllers/HostCollectionViewController.h @@ -0,0 +1,41 @@ +// +// HostCollectionViewController.h +// Moonlight-ZWM +// +// Created by True砖家 on 2025/5/28. +// Copyright 2025 True砖家 @ Bilibili. All rights reserved. +// + +#import +// #import "HostCardView.h" + +@class HostCardView; +@class TemporaryHost; + +@interface HostCollectionViewController : UICollectionViewController + +/// 横向 cell 间距 +@property (nonatomic, assign) CGFloat interItemMinimumSpacing; + +/// 纵向行间距 +@property (nonatomic, assign) CGFloat minimumLineSpacing; + +/// 固定的 cell 尺寸 +@property (nonatomic, assign) CGSize cellSize; + +@property (nonatomic, strong, readonly) NSMutableArray *items; + +/// 添加一个 item +- (void)addHost:(TemporaryHost *)host; + +/// 移除最后一个 item(如果有) +- (void)removeLastItem; + +@end + + +@interface HostCell : UICollectionViewCell +@property (nonatomic, strong) HostCardView *cardView; + +- (void)configureWithHost:(TemporaryHost *)host; +@end diff --git a/Limelight/ViewControllers/HostCollectionViewController.m b/Limelight/ViewControllers/HostCollectionViewController.m new file mode 100644 index 00000000..32b68d31 --- /dev/null +++ b/Limelight/ViewControllers/HostCollectionViewController.m @@ -0,0 +1,167 @@ +// +// HostCollectionViewController.m +// Moonlight-ZWM +// +// Created by True砖家 on 2025/5/28. +// Copyright 2025 True砖家 @ Bilibili. All rights reserved. +// + +#import "HostCollectionViewController.h" +#import "HostCardView.h" +#import "TemporaryHost.h" +#import "UIColor+Theme.h" + + + +@implementation HostCell + +- (void)prepareForReuse { + [super prepareForReuse]; + [self.cardView removeFromSuperview]; + self.cardView = nil; +} + +- (CGFloat)getHostCardSizeFactor{ + TemporaryHost* dummyHost = [[TemporaryHost alloc] init]; + HostCardView* dummyCard = [[HostCardView alloc] initWithHost:dummyHost]; + return self.contentView.bounds.size.height/dummyCard.size.height; +} + + +- (void)configureWithHost:(TemporaryHost *)host { + if (!self.cardView) { + self.cardView = [[HostCardView alloc] initWithHost:host andSizeFactor:[self getHostCardSizeFactor]]; + // self.cardView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.contentView addSubview:self.cardView]; + NSLog(@"contentView width %f, %f", self.contentView.bounds.size.width, self.cardView.size.width); + + [NSLayoutConstraint activateConstraints:@[ + [self.cardView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor], + [self.cardView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor], + ]]; + } +} + +@end + +@interface HostCollectionViewController () +@property (nonatomic, strong, readwrite) NSMutableArray *items; +@property (nonatomic, strong) NSLayoutConstraint *collectionViewHeightConstraint; +@end + +@implementation HostCollectionViewController + +- (instancetype)init { + UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; + layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 13); // 上、左、下、右的间距 + if (self = [super initWithCollectionViewLayout:layout]) { + _interItemMinimumSpacing = 10; + _minimumLineSpacing = 10; + // _cellSize = CGSizeMake(100, 100); + _items = [NSMutableArray array]; + + _collectionViewHeightConstraint = [self.collectionView.heightAnchor constraintEqualToConstant:50]; + _collectionViewHeightConstraint.active = YES; + } + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.collectionView registerClass:[HostCell class] forCellWithReuseIdentifier:@"HostCell"]; + if (@available(iOS 13.0, *)) { + self.collectionView.backgroundColor = UIColor.systemBackgroundColor; + } else { + // Fallback on earlier versions + } + self.collectionView.alwaysBounceVertical = NO; + self.collectionView.backgroundColor = self.view.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ? [UIColor appBackgroundColorDark] : [UIColor appBackgroundColorLight]; +} + +#pragma mark - Data control + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + NSLog(@"View did appear"); +} + +- (void)didMoveToParentViewController:(UIViewController *)parent { + [super didMoveToParentViewController:parent]; + NSLog(@"moved to parentVC: %@", parent); + + // 可以在这里进行一些初始化,比如加载数据、刷新 UI 等 +} + +- (void)addHost:(TemporaryHost *)host { + if(![self.items containsObject:host]){ + [self.items addObject:host]; + [self.items addObject:host]; + [self.items addObject:host]; + [self.items addObject:host]; + + [self.collectionView reloadData]; + // [self.view layoutIfNeeded]; + } + NSLog(@"addhost log"); + +} + +- (void)removeLastItem { + if (self.items.count > 0) { + [self.items removeLastObject]; + [self.collectionView reloadData]; + } +} + +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + + CGFloat contentHeight = self.collectionView.collectionViewLayout.collectionViewContentSize.height; + bool contentExceedsView = contentHeight > self.view.superview.bounds.size.height - self.view.frame.origin.y; + if(contentExceedsView){ + [NSLayoutConstraint activateConstraints:@[ + [self.view.bottomAnchor constraintEqualToAnchor:self.view.superview.safeAreaLayoutGuide.bottomAnchor constant:0] + ]]; + } + else _collectionViewHeightConstraint.constant = contentHeight; +} + +#pragma mark - UICollectionView DataSource + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { + return self.items.count; +} + +- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { + NSLog(@"config cell log"); + + HostCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"HostCell" forIndexPath:indexPath]; + TemporaryHost *host = self.items[indexPath.item]; + [cell configureWithHost:host]; + return cell; +} + +#pragma mark - UICollectionViewDelegateFlowLayout + +- (CGSize)collectionView:(UICollectionView *)collectionView + layout:(UICollectionViewLayout *)collectionViewLayout + sizeForItemAtIndexPath:(NSIndexPath *)indexPath { + NSLog(@"return cellsize: %f, %f", self.cellSize.width, self.cellSize.height); + return self.cellSize; +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView + layout:(UICollectionViewLayout *)collectionViewLayout +minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { + NSLog(@"return iterIterm: %f", self.interItemMinimumSpacing); + + return self.interItemMinimumSpacing; +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView + layout:(UICollectionViewLayout *)collectionViewLayout +minimumLineSpacingForSectionAtIndex:(NSInteger)section { + return self.minimumLineSpacing; +} + +@end diff --git a/Limelight/ViewControllers/MainFrameViewController.h b/Limelight/ViewControllers/MainFrameViewController.h index 5eca6576..ee872f9e 100644 --- a/Limelight/ViewControllers/MainFrameViewController.h +++ b/Limelight/ViewControllers/MainFrameViewController.h @@ -17,6 +17,8 @@ #import "UIAppView.h" #import "AppAssetManager.h" #import "SWRevealViewController.h" +#import "HostCollectionViewController.h" + @interface MainFrameViewController : UICollectionViewController @@ -24,6 +26,8 @@ #if !TARGET_OS_TV @property (weak, nonatomic) IBOutlet UIBarButtonItem *upButton; @property (nonatomic, assign) bool settingsExpandedInStreamView; +@property (nonatomic, strong) HostCollectionViewController *hostCollectionVC; + -(void)simulateSettingsButtonPress; -(void)reloadStreamConfig; diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m index 95fe7287..90c7915f 100644 --- a/Limelight/ViewControllers/MainFrameViewController.m +++ b/Limelight/ViewControllers/MainFrameViewController.m @@ -1133,6 +1133,7 @@ static NSMutableSet* hostList; [super viewDidLoad]; //[OrientationHelper updateOrientationToLandscape]; + #if !TARGET_OS_TV self.settingsExpandedInStreamView = false; // init this flag self.revealViewController.isStreaming = false; //init this flag for rvlVC @@ -1223,16 +1224,14 @@ static NSMutableSet* hostList; [self.collectionView addGestureRecognizer:cellLongPress]; #endif - [self retrieveSavedHosts]; - _discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self]; [self updateTitle]; - [self.view addSubview:hostScrollView]; + // [self.view addSubview:hostScrollView]; if ([hostList count] == 1) [self hostClicked:[hostList anyObject] view:nil]; // auto click for single host - - + self.view.backgroundColor = self.view.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ? [UIColor appBackgroundColorDark] : [UIColor appBackgroundColorLight]; + //if([SettingsViewController isLandscapeNow] != _streamConfig.width > _streamConfig.height) //[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app. //[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app. @@ -1243,6 +1242,9 @@ static NSMutableSet* hostList; } -(void)viewDidLayoutSubviews{ + [super viewDidLayoutSubviews]; + + [self updateHosts]; } -(void)reloadScrollHostView{ @@ -1279,7 +1281,7 @@ static NSMutableSet* hostList; //[self retrieveSavedHosts]; //_discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self]; [self updateTitle]; - [self.view addSubview:hostScrollView]; + // [self.view addSubview:hostScrollView]; } // this will also be called back when device orientation changes @@ -1434,7 +1436,10 @@ static NSMutableSet* hostList; - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:NO]; - [self reloadScrollHostView]; + + + + // [self reloadScrollHostView]; //remove this for proper test [self attachWaterMark]; #if !TARGET_OS_TV @@ -1485,7 +1490,6 @@ static NSMutableSet* hostList; [subview removeFromSuperview]; // 暂时移除所有子视图 } - self.view.backgroundColor = [UIColor appBackgroundColorDark]; //theme test // We can get here on home press while streaming // since the stream view segues to us just before @@ -1498,6 +1502,12 @@ static NSMutableSet* hostList; // this view via an error dialog from the stream // view, so we won't get a return to active notification // for that which would normally fire beginForegroundRefresh. + [self initHostCollection]; + + [self retrieveSavedHosts]; + + _discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self]; + [self beginForegroundRefresh]; } @@ -1592,11 +1602,16 @@ static NSMutableSet* hostList; // Sort the host list in alphabetical order NSArray* sortedHostList = [[hostList allObjects] sortedArrayUsingSelector:@selector(compareName:)]; for (TemporaryHost* comp in sortedHostList) { + + [self.hostCollectionVC addHost:comp]; + compView = [[UIComputerView alloc] initWithComputer:comp andCallback:self]; // host view created here // new host card test // if([comp.name isEqualToString: @"ASRockPC"]) { - if([comp.name isEqualToString: @"PianoServer"]) { + /* + if([comp.name isEqualToString: @"ASRockPC"]) { + //if([comp.name isEqualToString: @"PianoServer"]) { //if([comp.name isEqualToString: @"TrueZj"]) { HostCardView *testCard = [[HostCardView alloc] initWithHost:comp]; @@ -1606,8 +1621,8 @@ static NSMutableSet* hostList; [testCard.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant:0], [testCard.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor constant:150], ]]; - - } + + }*/ // @@ -1817,4 +1832,39 @@ static NSMutableSet* hostList; #endif } +- (CGSize)getHostCardSize{ + CGSize cardSize; + cardSize.height = 0.25*MIN(CGRectGetHeight([[UIScreen mainScreen] bounds]),CGRectGetWidth([[UIScreen mainScreen] bounds])); + TemporaryHost* dummyHost = [[TemporaryHost alloc] init]; + HostCardView* dummyCard = [[HostCardView alloc] initWithHost:dummyHost]; + cardSize.width = cardSize.height * (dummyCard.size.width/dummyCard.size.height); + // cardSize.width = + return cardSize; +} + +- (void)initHostCollection{ + // 初始化 HostCollectionViewController + self.hostCollectionVC = [[HostCollectionViewController alloc] init]; + self.hostCollectionVC.cellSize = [self getHostCardSize]; + self.hostCollectionVC.interItemMinimumSpacing = 25; + self.hostCollectionVC.minimumLineSpacing = 25; + // 添加为子控制器 + [self addChildViewController:self.hostCollectionVC]; + [self.view addSubview:self.hostCollectionVC.view]; + + // 设置其布局(Auto Layout 示例) + CGFloat hostCollectionViewPadding = 75; + self.hostCollectionVC.view.translatesAutoresizingMaskIntoConstraints = NO; + [NSLayoutConstraint activateConstraints:@[ + [self.hostCollectionVC.view.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:50], + [self.hostCollectionVC.view.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant:hostCollectionViewPadding], + [self.hostCollectionVC.view.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant:-hostCollectionViewPadding], + // [self.hostCollectionVC.view.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:0] //? + ]]; + + // 通知子控制器已添加完成 + [self.hostCollectionVC didMoveToParentViewController:self]; + +} + @end diff --git a/Moonlight.xcodeproj/project.pbxproj b/Moonlight.xcodeproj/project.pbxproj index 62ff1b55..e36b316d 100644 --- a/Moonlight.xcodeproj/project.pbxproj +++ b/Moonlight.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 189AD29A2DE7446000E24B88 /* HostCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 189AD2992DE7446000E24B88 /* HostCollectionViewController.m */; }; 840751B32BF49C050096B657 /* CustomTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 840751B22BF49C050096B657 /* CustomTapGestureRecognizer.m */; }; 841BAC922DE35D6B00DA639E /* UIColor+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 841BAC912DE35D6B00DA639E /* UIColor+Theme.m */; }; 84203F232C5F24C00032EEED /* OnScreenWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84203F222C5F24C00032EEED /* OnScreenWidgetView.swift */; }; @@ -127,6 +128,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 189AD2962DE743B700E24B88 /* HostCollectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HostCollectionViewController.h; sourceTree = ""; }; + 189AD2992DE7446000E24B88 /* HostCollectionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HostCollectionViewController.m; sourceTree = ""; }; 566E9D2B2770B23A00EF7BFE /* Moonlight v1.7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.7.xcdatamodel"; sourceTree = ""; }; 693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 840751B12BF49B5A0096B657 /* CustomTapGestureRecognizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomTapGestureRecognizer.h; sourceTree = ""; }; @@ -635,6 +638,8 @@ FBD3495219FF36FB002D2A60 /* SWRevealViewController.m */, FB89462419F646E200339C8A /* MainFrameViewController.h */, FB89462519F646E200339C8A /* MainFrameViewController.m */, + 189AD2962DE743B700E24B88 /* HostCollectionViewController.h */, + 189AD2992DE7446000E24B88 /* HostCollectionViewController.m */, FB89462619F646E200339C8A /* StreamFrameViewController.h */, FB89462719F646E200339C8A /* StreamFrameViewController.m */, FBD3494E19FF2174002D2A60 /* SettingsViewController.h */, @@ -872,6 +877,7 @@ 84E1CDEC2C4F67D300547904 /* CommandManager.swift in Sources */, 847D2FDB2DDA015F00937A62 /* MenuSectionView.m in Sources */, FB53E1431BE5DC4400CD6ECE /* IdManager.m in Sources */, + 189AD29A2DE7446000E24B88 /* HostCollectionViewController.m in Sources */, 9897B6A1221260EF00966419 /* Controller.m in Sources */, 84351B112C29ACCB00A77989 /* OSCProfilesManager.m in Sources */, FB89462919F646E200339C8A /* mkcert.c in Sources */,