Skip to content
This repository was archived by the owner on Nov 11, 2024. It is now read-only.

Commit edcc0dc

Browse files
committed
feat: add "AppState.windows" and new AppState events
The new events are: "rootViewWillAppear" and "windowDidChangeScreen"
1 parent 221b429 commit edcc0dc

File tree

2 files changed

+49
-14
lines changed

2 files changed

+49
-14
lines changed

@types/index.d.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6863,22 +6863,37 @@ export interface AlertIOSStatic {
68636863
*
68646864
* @see https://facebook.github.io/react-native/docs/appstateios.html#content
68656865
*/
6866-
export type AppStateEvent = "change" | "memoryWarning";
6866+
export type AppStateEvent = "change" | "memoryWarning" | "rootViewWillAppear" | "windowDidChangeScreen";
68676867
export type AppStateStatus = "active" | "background" | "inactive";
68686868

68696869
export interface AppStateStatic {
68706870
currentState: AppStateStatus;
6871+
windows: { [rootTag: number]: WindowState };
68716872

68726873
/**
68736874
* Add a handler to AppState changes by listening to the change event
68746875
* type and providing the handler
68756876
*/
6876-
addEventListener(type: AppStateEvent, listener: (state: AppStateStatus) => void): void;
6877+
addEventListener(type: 'change', listener: (state: AppStateStatus) => void): void;
6878+
addEventListener(type: 'memoryWarning', listener: () => void): void;
6879+
addEventListener(type: 'rootViewWillAppear', listener: (state: WindowState) => void): void;
6880+
addEventListener(type: 'windowDidChangeScreen', listener: (state: WindowState) => void): void;
68776881

68786882
/**
68796883
* Remove a handler by passing the change event type and the handler
68806884
*/
6881-
removeEventListener(type: AppStateEvent, listener: (state: AppStateStatus) => void): void;
6885+
removeEventListener(type: AppStateEvent, listener: Function): void;
6886+
}
6887+
6888+
export interface WindowState {
6889+
rootTag: number;
6890+
screen: Screen;
6891+
}
6892+
6893+
export interface Screen {
6894+
id: number;
6895+
scale: number;
6896+
layout: LayoutRectangle;
68826897
}
68836898

68846899
/**

Libraries/AppState/AppState.js

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ const RCTAppState = NativeModules.AppState;
1919
const logError = require('logError');
2020
const invariant = require('fbjs/lib/invariant');
2121

22+
import type {Layout} from 'CoreEventTypes';
23+
24+
type Screen = {|
25+
+rootTag: number,
26+
+bounds: Layout,
27+
+scale: number,
28+
|};
29+
30+
const eventTypes = ['change', 'memoryWarning', 'rootViewWillAppear', 'windowDidChangeScreen'];
31+
2232
/**
2333
* `AppState` can tell you if the app is in the foreground or background,
2434
* and notify you when the state changes.
@@ -30,15 +40,16 @@ class AppState extends NativeEventEmitter {
3040
_eventHandlers: Object;
3141
currentState: ?string;
3242
isAvailable: boolean = true;
43+
windows: { [rootTag: number]: Screen };
3344

3445
constructor() {
3546
super(RCTAppState);
3647

3748
this.isAvailable = true;
38-
this._eventHandlers = {
39-
change: new Map(),
40-
memoryWarning: new Map(),
41-
};
49+
this._eventHandlers = eventTypes.reduce((out, type) => {
50+
out[type] = new Map();
51+
return out;
52+
}, {});
4253

4354
// TODO: Remove the 'active' fallback after `initialAppState` is exported by
4455
// the Android implementation.
@@ -58,6 +69,18 @@ class AppState extends NativeEventEmitter {
5869
}
5970
);
6071

72+
this.windows = RCTAppState.windows.reduce((acc, state) => {
73+
acc[state.rootTag] = state;
74+
return acc;
75+
}, {});
76+
77+
const onWindowChange = state => {
78+
this.windows[state.rootTag] = state;
79+
}
80+
81+
this.addListener('rootViewWillAppear', onWindowChange);
82+
this.addListener('windowDidChangeScreen', onWindowChange);
83+
6184
// TODO: see above - this request just populates the value of `currentState`
6285
// when the module is first initialized. Would be better to get rid of the
6386
// prop and expose `getCurrentAppState` method directly.
@@ -87,7 +110,7 @@ class AppState extends NativeEventEmitter {
87110
handler: Function
88111
) {
89112
invariant(
90-
['change', 'memoryWarning'].indexOf(type) !== -1,
113+
eventTypes.indexOf(type) !== -1,
91114
'Trying to subscribe to unknown event: "%s"', type
92115
);
93116
if (type === 'change') {
@@ -97,11 +120,8 @@ class AppState extends NativeEventEmitter {
97120
handler(appStateData.app_state);
98121
}
99122
));
100-
} else if (type === 'memoryWarning') {
101-
this._eventHandlers[type].set(handler, this.addListener(
102-
'memoryWarning',
103-
handler
104-
));
123+
} else {
124+
this._eventHandlers[type].set(handler, this.addListener(type, handler));
105125
}
106126
}
107127

@@ -115,7 +135,7 @@ class AppState extends NativeEventEmitter {
115135
handler: Function
116136
) {
117137
invariant(
118-
['change', 'memoryWarning'].indexOf(type) !== -1,
138+
eventTypes.indexOf(type) !== -1,
119139
'Trying to remove listener for unknown event: "%s"', type
120140
);
121141
if (!this._eventHandlers[type].has(handler)) {

0 commit comments

Comments
 (0)