Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "feat: implement window manager events (#142)" #147

Merged
merged 1 commit into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ public struct RCTMainWindow: Scene {
var moduleName: String
var initialProps: RCTRootViewRepresentable.InitialPropsType
var onOpenURLCallback: ((URL) -> ())?
let windowId: String = "0"

@Environment(\.scenePhase) private var scenePhase


public init(moduleName: String, initialProps: RCTRootViewRepresentable.InitialPropsType = nil) {
self.moduleName = moduleName
Expand All @@ -35,27 +31,13 @@ public struct RCTMainWindow: Scene {
WindowGroup {
RCTRootViewRepresentable(moduleName: moduleName, initialProps: initialProps)
.modifier(WindowHandlingModifier())
.onChange(of: scenePhase, { _, newValue in
postWindowStateNotification(windowId: windowId, state: newValue)
})
.onOpenURL(perform: { url in
onOpenURLCallback?(url)
})
}
}
}

public func postWindowStateNotification(windowId: String, state: SwiftUI.ScenePhase) {
NotificationCenter.default.post(
name: NSNotification.Name(rawValue: "RCTWindowStateDidChange"),
object: nil,
userInfo: [
"windowId": windowId,
"state": "\(state)"
]
)
}

extension RCTMainWindow {
public func onOpenURL(perform action: @escaping (URL) -> ()) -> some Scene {
var scene = self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ public struct RCTWindow : Scene {
var id: String
var sceneData: RCTSceneData?
var moduleName: String
@Environment(\.scenePhase) private var scenePhase


public init(id: String, moduleName: String, sceneData: RCTSceneData?) {
self.id = id
Expand All @@ -27,9 +25,6 @@ public struct RCTWindow : Scene {
Group {
if let sceneData {
RCTRootViewRepresentable(moduleName: moduleName, initialProps: sceneData.props)
.onChange(of: scenePhase) { _, newValue in
postWindowStateNotification(windowId: id, state: newValue)
}
}
}
.onAppear {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface RCTWindowManager : RCTEventEmitter
@interface RCTWindowManager : NSObject <RCTBridgeModule>

@end
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,14 @@
static NSString *const RCTOpenWindow = @"RCTOpenWindow";
static NSString *const RCTDismissWindow = @"RCTDismissWindow";
static NSString *const RCTUpdateWindow = @"RCTUpdateWindow";
static NSString *const RCTWindowStateDidChangeEvent = @"windowStateDidChange";

static NSString *const RCTWindowStateDidChange = @"RCTWindowStateDidChange";

@interface RCTWindowManager () <NativeWindowManagerSpec> {
BOOL _hasAnyListeners;
}
@interface RCTWindowManager () <NativeWindowManagerSpec>
@end

@implementation RCTWindowManager

RCT_EXPORT_MODULE(WindowManager)

- (void)initialize {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleWindowStateChanges:)
name:RCTWindowStateDidChange
object:nil];
}

- (void)invalidate {
[super invalidate];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(void)startObserving
{
_hasAnyListeners = YES;
}

- (void)stopObserving
{
_hasAnyListeners = NO;
}

RCT_EXPORT_METHOD(openWindow
: (NSString *)windowId userInfo
: (NSDictionary *)userInfo resolve
Expand Down Expand Up @@ -95,17 +68,6 @@ - (void)stopObserving
});
}

- (void) handleWindowStateChanges:(NSNotification *)notification {

if (_hasAnyListeners) {
[self sendEventWithName:RCTWindowStateDidChangeEvent body:notification.userInfo];
}
}

- (NSArray<NSString *> *)supportedEvents {
return @[RCTWindowStateDidChangeEvent];
}

- (facebook::react::ModuleConstants<JS::NativeWindowManager::Constants::Builder>)constantsToExport {
return [self getConstants];
}
Expand All @@ -125,13 +87,4 @@ - (void) handleWindowStateChanges:(NSNotification *)notification {
return std::make_shared<facebook::react::NativeWindowManagerSpecJSI>(params);
}

+ (BOOL)requiresMainQueueSetup {
return YES;
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

@end
10 changes: 0 additions & 10 deletions packages/react-native/Libraries/WindowManager/WindowManager.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
import {NativeEventSubscription} from '../EventEmitter/RCTNativeAppEventEmitter';

type WindowManagerEvents = 'windowStateDidChange';

type WindowState = {
windowId: string;
state: 'active' | 'inactive' | 'background';
};

export interface WindowStatic {
id: String;
open (props?: Object): Promise<void>;
update (props: Object): Promise<void>;
close (): Promise<void>;
addEventListener (type: WindowManagerEvents, handler: (info: WindowState) => void): NativeEventSubscription;
}

export interface WindowManagerStatic {
Expand Down
38 changes: 7 additions & 31 deletions packages/react-native/Libraries/WindowManager/WindowManager.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,26 @@
/**
* @format
* @flow strict-local
* @flow strict
* @jsdoc
*/

import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
import Platform from '../Utilities/Platform';
import {type EventSubscription} from '../vendor/emitter/EventEmitter';
import NativeWindowManager from './NativeWindowManager';

export type WindowStateValues = 'inactive' | 'background' | 'active';

type WindowManagerEventDefinitions = {
windowStateDidChange: [{state: WindowStateValues, windowId: string}],
};

let emitter: ?NativeEventEmitter<WindowManagerEventDefinitions>;

if (NativeWindowManager != null) {
emitter = new NativeEventEmitter<WindowManagerEventDefinitions>(
Platform.OS !== 'ios' ? null : NativeWindowManager,
);
}

class WindowManager {
static getWindow = function (id: string): Window {
const WindowManager = {
getWindow: function (id: string): Window {
return new Window(id);
};

static addEventListener<K: $Keys<WindowManagerEventDefinitions>>(
type: K,
handler: (...$ElementType<WindowManagerEventDefinitions, K>) => void,
): ?EventSubscription {
return emitter?.addListener(type, handler);
}
},

// $FlowIgnore[unsafe-getters-setters]
static get supportsMultipleScenes(): boolean {
get supportsMultipleScenes(): boolean {
if (NativeWindowManager == null) {
return false;
}

const nativeConstants = NativeWindowManager.getConstants();
return nativeConstants.supportsMultipleScenes || false;
}
}
},
};

class Window {
id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9035,17 +9035,16 @@ declare export default typeof NativeWindowManager;
`;

exports[`public API should not change unintentionally Libraries/WindowManager/WindowManager.js 1`] = `
"export type WindowStateValues = \\"inactive\\" | \\"background\\" | \\"active\\";
type WindowManagerEventDefinitions = {
windowStateDidChange: [{ state: WindowStateValues, windowId: string }],
};
declare class WindowManager {
static getWindow: $FlowFixMe;
static addEventListener<K: $Keys<WindowManagerEventDefinitions>>(
type: K,
handler: (...$ElementType<WindowManagerEventDefinitions, K>) => void
): ?EventSubscription;
static get supportsMultipleScenes(): boolean;
"declare const WindowManager: {
getWindow: (id: string) => Window,
get supportsMultipleScenes(): boolean,
};
declare class Window {
id: string;
constructor(id: string): void;
open(props: ?Object): Promise<void>;
close(): Promise<void>;
update(props: ?Object): Promise<void>;
}
declare module.exports: WindowManager;
"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ export interface Spec extends TurboModule {
// $FlowIgnore[unclear-type]
+updateWindow: (windowId: string, userInfo: Object) => Promise<void>;
+closeWindow: (windowId: string) => Promise<void>;

// RCTEventEmitter
+addListener: (eventName: string) => void;
+removeListeners: (count: number) => void;
}

export default (TurboModuleRegistry.get<Spec>('WindowManager'): ?Spec);
11 changes: 0 additions & 11 deletions packages/rn-tester/js/examples/XR/XRExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@ const secondWindow = WindowManager.getWindow('SecondWindow');
const OpenXRSession = () => {
const [isOpen, setIsOpen] = React.useState(false);

React.useEffect(() => {
const listener = WindowManager.addEventListener(
'windowStateDidChange',
data => {
console.log('Window state changed to:', data);
},
);
return () => {
listener?.remove();
};
}, []);
const openXRSession = async () => {
try {
if (!WindowManager.supportsMultipleScenes) {
Expand Down