FLEXManager.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //
  2. // FLEXManager.m
  3. // Flipboard
  4. //
  5. // Created by Ryan Olson on 4/4/14.
  6. // Copyright (c) 2020 FLEX Team. All rights reserved.
  7. //
  8. #import "FLEXManager.h"
  9. #import "FLEXUtility.h"
  10. #import "FLEXExplorerViewController.h"
  11. #import "FLEXWindow.h"
  12. #import "FLEXObjectExplorerViewController.h"
  13. #import "FLEXFileBrowserController.h"
  14. @interface FLEXManager () <FLEXWindowEventDelegate, FLEXExplorerViewControllerDelegate>
  15. @property (nonatomic, readonly, getter=isHidden) BOOL hidden;
  16. @property (nonatomic) FLEXWindow *explorerWindow;
  17. @property (nonatomic) FLEXExplorerViewController *explorerViewController;
  18. @property (nonatomic, readonly) NSMutableArray<FLEXGlobalsEntry *> *userGlobalEntries;
  19. @property (nonatomic, readonly) NSMutableDictionary<NSString *, FLEXCustomContentViewerFuture> *customContentTypeViewers;
  20. @end
  21. @implementation FLEXManager
  22. + (instancetype)sharedManager {
  23. static FLEXManager *sharedManager = nil;
  24. static dispatch_once_t onceToken;
  25. dispatch_once(&onceToken, ^{
  26. sharedManager = [self new];
  27. });
  28. return sharedManager;
  29. }
  30. - (instancetype)init {
  31. self = [super init];
  32. if (self) {
  33. _userGlobalEntries = [NSMutableArray new];
  34. _customContentTypeViewers = [NSMutableDictionary new];
  35. }
  36. return self;
  37. }
  38. - (FLEXWindow *)explorerWindow {
  39. NSAssert(NSThread.isMainThread, @"You must use %@ from the main thread only.", NSStringFromClass([self class]));
  40. if (!_explorerWindow) {
  41. _explorerWindow = [[FLEXWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
  42. _explorerWindow.eventDelegate = self;
  43. _explorerWindow.rootViewController = self.explorerViewController;
  44. }
  45. return _explorerWindow;
  46. }
  47. - (void)tripleTap:(UITapGestureRecognizer *)tapRecognizer {
  48. FXLog(@"triple tap!");
  49. [self showExplorer];
  50. }
  51. - (void)_addTVOSGestureRecognizer:(UIViewController *)explorer {
  52. UITapGestureRecognizer *tripleTaps = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tripleTap:)];
  53. tripleTaps.allowedPressTypes = @[[NSNumber numberWithInteger:UIPressTypePlayPause]];
  54. tripleTaps.numberOfTapsRequired = 3;
  55. [explorer.view addGestureRecognizer:tripleTaps];
  56. }
  57. - (FLEXExplorerViewController *)explorerViewController {
  58. if (!_explorerViewController) {
  59. _explorerViewController = [FLEXExplorerViewController new];
  60. _explorerViewController.delegate = self;
  61. #if TARGET_OS_TV
  62. [self _addTVOSGestureRecognizer:_explorerViewController];
  63. #endif
  64. }
  65. return _explorerViewController;
  66. }
  67. - (void)showExplorer {
  68. UIWindow *flex = self.explorerWindow;
  69. flex.hidden = NO;
  70. #if TARGET_OS_TV
  71. FLEXWindow *exp = [self explorerWindow];
  72. [exp makeKeyWindow];
  73. #endif
  74. #if FLEX_AT_LEAST_IOS13_SDK
  75. if (@available(iOS 13.0, *)) {
  76. // Only look for a new scene if we don't have one
  77. if (!flex.windowScene) {
  78. flex.windowScene = FLEXUtility.activeScene;
  79. }
  80. }
  81. #endif
  82. }
  83. - (void)hideExplorer {
  84. self.explorerWindow.hidden = YES;
  85. }
  86. - (void)toggleExplorer {
  87. if (self.explorerWindow.isHidden) {
  88. [self showExplorer];
  89. } else {
  90. [self hideExplorer];
  91. }
  92. }
  93. - (void)showExplorerFromScene:(UIWindowScene *)scene {
  94. #if FLEX_AT_LEAST_IOS13_SDK
  95. if (@available(iOS 13.0, *)) {
  96. self.explorerWindow.windowScene = scene;
  97. }
  98. #endif
  99. self.explorerWindow.hidden = NO;
  100. }
  101. - (BOOL)isHidden {
  102. return self.explorerWindow.isHidden;
  103. }
  104. - (FLEXExplorerToolbar *)toolbar {
  105. return self.explorerViewController.explorerToolbar;
  106. }
  107. #pragma mark - FLEXWindowEventDelegate
  108. - (BOOL)shouldHandleTouchAtPoint:(CGPoint)pointInWindow {
  109. // Ask the explorer view controller
  110. return [self.explorerViewController shouldReceiveTouchAtWindowPoint:pointInWindow];
  111. }
  112. - (BOOL)canBecomeKeyWindow {
  113. // Only when the explorer view controller wants it because
  114. // it needs to accept key input & affect the status bar.
  115. return self.explorerViewController.wantsWindowToBecomeKey;
  116. }
  117. #pragma mark - FLEXExplorerViewControllerDelegate
  118. - (void)explorerViewControllerDidFinish:(FLEXExplorerViewController *)explorerViewController {
  119. [self hideExplorer];
  120. }
  121. @end