mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-30 13:13:25 +00:00
Backport the Unistyles 3.5.3 Activity configuration fix while keeping 3.2.4 and its existing fixes. Application resources could leave the responsive shell on the previous fold size after resume. Cover the real device-state sequence with a native UI regression.
708 lines
32 KiB
Diff
708 lines
32 KiB
Diff
diff --git a/node_modules/react-native-unistyles/lib/commonjs/web/registry.js b/node_modules/react-native-unistyles/lib/commonjs/web/registry.js
|
|
index 120ff60..d1ff102 100644
|
|
--- a/node_modules/react-native-unistyles/lib/commonjs/web/registry.js
|
|
+++ b/node_modules/react-native-unistyles/lib/commonjs/web/registry.js
|
|
@@ -10,6 +10,17 @@ class UnistylesRegistry {
|
|
stylesheets = new Map();
|
|
stylesCache = new Set();
|
|
stylesCounter = new Map();
|
|
+ cleanupGeneration = 0;
|
|
+ finalizerTokens = new WeakMap();
|
|
+ finalizationRegistry = typeof FinalizationRegistry === 'undefined' ? undefined : new FinalizationRegistry(({
|
|
+ hash,
|
|
+ generation
|
|
+ }) => {
|
|
+ if (generation !== this.cleanupGeneration) {
|
|
+ return;
|
|
+ }
|
|
+ this.decrementAndMaybeCleanup(hash);
|
|
+ });
|
|
disposeListenersMap = new Map();
|
|
dependenciesMap = new Map();
|
|
constructor(services) {
|
|
@@ -50,26 +61,48 @@ class UnistylesRegistry {
|
|
this.disposeListenersMap.set(stylesheet, dispose);
|
|
};
|
|
connect = (ref, hash) => {
|
|
- const stylesCounter = this.stylesCounter.get(hash) ?? new Set();
|
|
- stylesCounter.add(ref);
|
|
- this.stylesCounter.set(hash, stylesCounter);
|
|
+ this.stylesCounter.set(hash, (this.stylesCounter.get(hash) ?? 0) + 1);
|
|
+ if (!this.finalizationRegistry) {
|
|
+ return;
|
|
+ }
|
|
+ const token = {};
|
|
+ const tokensByHash = this.finalizerTokens.get(ref) ?? new Map();
|
|
+ const tokens = tokensByHash.get(hash) ?? [];
|
|
+ tokens.push(token);
|
|
+ tokensByHash.set(hash, tokens);
|
|
+ this.finalizerTokens.set(ref, tokensByHash);
|
|
+ this.finalizationRegistry.register(ref, {
|
|
+ hash,
|
|
+ generation: this.cleanupGeneration
|
|
+ }, token);
|
|
};
|
|
remove = (ref, hash) => {
|
|
- const stylesCounter = this.stylesCounter.get(hash) ?? new Set();
|
|
- stylesCounter.delete(ref);
|
|
- if (stylesCounter.size === 0) {
|
|
- // Move this to the end of the event loop so the element is removed from the DOM
|
|
- return Promise.resolve().then(() => {
|
|
- // Check if element is still in the DOM
|
|
- if (document.querySelector(`.${hash}`)) {
|
|
- return false;
|
|
- }
|
|
- this.css.remove(hash);
|
|
- this.stylesCache.delete(hash);
|
|
- return true;
|
|
- });
|
|
+ const token = this.finalizerTokens.get(ref)?.get(hash)?.pop();
|
|
+ if (token) {
|
|
+ this.finalizationRegistry?.unregister(token);
|
|
+ }
|
|
+ return this.decrementAndMaybeCleanup(hash);
|
|
+ };
|
|
+ decrementAndMaybeCleanup = hash => {
|
|
+ const next = (this.stylesCounter.get(hash) ?? 0) - 1;
|
|
+ if (next > 0) {
|
|
+ this.stylesCounter.set(hash, next);
|
|
+ return Promise.resolve(false);
|
|
}
|
|
- return Promise.resolve(false);
|
|
+ this.stylesCounter.delete(hash);
|
|
+ // Move this to the end of the event loop so the element is removed from the DOM
|
|
+ return Promise.resolve().then(() => {
|
|
+ // Check if element is still in the DOM
|
|
+ if ((this.stylesCounter.get(hash) ?? 0) > 0) {
|
|
+ return false;
|
|
+ }
|
|
+ if (document.querySelector(`.${hash}`)) {
|
|
+ return false;
|
|
+ }
|
|
+ this.css.remove(hash);
|
|
+ this.stylesCache.delete(hash);
|
|
+ return true;
|
|
+ });
|
|
};
|
|
add = (value, forChild) => {
|
|
const generatedHash = (0, _utils.generateHash)(value);
|
|
@@ -91,7 +124,10 @@ class UnistylesRegistry {
|
|
this.css.add(hash, value);
|
|
};
|
|
reset = () => {
|
|
+ this.cleanupGeneration += 1;
|
|
+ this.disposeListenersMap.forEach(dispose => dispose());
|
|
this.css.reset();
|
|
+ this.stylesheets.clear();
|
|
this.stylesCache.clear();
|
|
this.dependenciesMap.clear();
|
|
this.disposeListenersMap.clear();
|
|
diff --git a/node_modules/react-native-unistyles/lib/module/web/registry.js b/node_modules/react-native-unistyles/lib/module/web/registry.js
|
|
index 6362f43..8e769f8 100644
|
|
--- a/node_modules/react-native-unistyles/lib/module/web/registry.js
|
|
+++ b/node_modules/react-native-unistyles/lib/module/web/registry.js
|
|
@@ -6,6 +6,17 @@ export class UnistylesRegistry {
|
|
stylesheets = new Map();
|
|
stylesCache = new Set();
|
|
stylesCounter = new Map();
|
|
+ cleanupGeneration = 0;
|
|
+ finalizerTokens = new WeakMap();
|
|
+ finalizationRegistry = typeof FinalizationRegistry === 'undefined' ? undefined : new FinalizationRegistry(({
|
|
+ hash,
|
|
+ generation
|
|
+ }) => {
|
|
+ if (generation !== this.cleanupGeneration) {
|
|
+ return;
|
|
+ }
|
|
+ this.decrementAndMaybeCleanup(hash);
|
|
+ });
|
|
disposeListenersMap = new Map();
|
|
dependenciesMap = new Map();
|
|
constructor(services) {
|
|
@@ -46,26 +57,48 @@ export class UnistylesRegistry {
|
|
this.disposeListenersMap.set(stylesheet, dispose);
|
|
};
|
|
connect = (ref, hash) => {
|
|
- const stylesCounter = this.stylesCounter.get(hash) ?? new Set();
|
|
- stylesCounter.add(ref);
|
|
- this.stylesCounter.set(hash, stylesCounter);
|
|
+ this.stylesCounter.set(hash, (this.stylesCounter.get(hash) ?? 0) + 1);
|
|
+ if (!this.finalizationRegistry) {
|
|
+ return;
|
|
+ }
|
|
+ const token = {};
|
|
+ const tokensByHash = this.finalizerTokens.get(ref) ?? new Map();
|
|
+ const tokens = tokensByHash.get(hash) ?? [];
|
|
+ tokens.push(token);
|
|
+ tokensByHash.set(hash, tokens);
|
|
+ this.finalizerTokens.set(ref, tokensByHash);
|
|
+ this.finalizationRegistry.register(ref, {
|
|
+ hash,
|
|
+ generation: this.cleanupGeneration
|
|
+ }, token);
|
|
};
|
|
remove = (ref, hash) => {
|
|
- const stylesCounter = this.stylesCounter.get(hash) ?? new Set();
|
|
- stylesCounter.delete(ref);
|
|
- if (stylesCounter.size === 0) {
|
|
- // Move this to the end of the event loop so the element is removed from the DOM
|
|
- return Promise.resolve().then(() => {
|
|
- // Check if element is still in the DOM
|
|
- if (document.querySelector(`.${hash}`)) {
|
|
- return false;
|
|
- }
|
|
- this.css.remove(hash);
|
|
- this.stylesCache.delete(hash);
|
|
- return true;
|
|
- });
|
|
+ const token = this.finalizerTokens.get(ref)?.get(hash)?.pop();
|
|
+ if (token) {
|
|
+ this.finalizationRegistry?.unregister(token);
|
|
+ }
|
|
+ return this.decrementAndMaybeCleanup(hash);
|
|
+ };
|
|
+ decrementAndMaybeCleanup = hash => {
|
|
+ const next = (this.stylesCounter.get(hash) ?? 0) - 1;
|
|
+ if (next > 0) {
|
|
+ this.stylesCounter.set(hash, next);
|
|
+ return Promise.resolve(false);
|
|
}
|
|
- return Promise.resolve(false);
|
|
+ this.stylesCounter.delete(hash);
|
|
+ // Move this to the end of the event loop so the element is removed from the DOM
|
|
+ return Promise.resolve().then(() => {
|
|
+ // Check if element is still in the DOM
|
|
+ if ((this.stylesCounter.get(hash) ?? 0) > 0) {
|
|
+ return false;
|
|
+ }
|
|
+ if (document.querySelector(`.${hash}`)) {
|
|
+ return false;
|
|
+ }
|
|
+ this.css.remove(hash);
|
|
+ this.stylesCache.delete(hash);
|
|
+ return true;
|
|
+ });
|
|
};
|
|
add = (value, forChild) => {
|
|
const generatedHash = generateHash(value);
|
|
@@ -87,7 +120,10 @@ export class UnistylesRegistry {
|
|
this.css.add(hash, value);
|
|
};
|
|
reset = () => {
|
|
+ this.cleanupGeneration += 1;
|
|
+ this.disposeListenersMap.forEach(dispose => dispose());
|
|
this.css.reset();
|
|
+ this.stylesheets.clear();
|
|
this.stylesCache.clear();
|
|
this.dependenciesMap.clear();
|
|
this.disposeListenersMap.clear();
|
|
diff --git a/node_modules/react-native-unistyles/src/web/registry.ts b/node_modules/react-native-unistyles/src/web/registry.ts
|
|
index 39e0d9d..a21ba95 100644
|
|
--- a/node_modules/react-native-unistyles/src/web/registry.ts
|
|
+++ b/node_modules/react-native-unistyles/src/web/registry.ts
|
|
@@ -9,7 +9,24 @@ import { error, extractUnistyleDependencies, generateHash } from './utils'
|
|
export class UnistylesRegistry {
|
|
private readonly stylesheets = new Map<StyleSheetWithSuperPowers<StyleSheet>, StyleSheet>()
|
|
private readonly stylesCache = new Set<string>()
|
|
- private readonly stylesCounter = new Map<string, Set<HTMLElement>>()
|
|
+ // Use counter instead of Set<HTMLElement> to avoid retaining detached DOM nodes
|
|
+ // FR is a fallback when remove() is missed
|
|
+ private readonly stylesCounter = new Map<string, number>()
|
|
+ // Bumped on reset() so stale FR callbacks are ignored
|
|
+ private cleanupGeneration = 0
|
|
+ // Per-registration unregister token, so remove() cancels only its own registration
|
|
+ private readonly finalizerTokens = new WeakMap<HTMLElement, Map<string, Array<object>>>()
|
|
+ // FR isn't available on every runtime - fall back to counter-only cleanup
|
|
+ private readonly finalizationRegistry =
|
|
+ typeof FinalizationRegistry === 'undefined'
|
|
+ ? undefined
|
|
+ : new FinalizationRegistry<{ hash: string; generation: number }>(({ hash, generation }) => {
|
|
+ if (generation !== this.cleanupGeneration) {
|
|
+ return
|
|
+ }
|
|
+
|
|
+ this.decrementAndMaybeCleanup(hash)
|
|
+ })
|
|
private readonly disposeListenersMap = new Map<object, VoidFunction>()
|
|
private readonly dependenciesMap = new Map<StyleSheetWithSuperPowers<StyleSheet>, Set<UnistyleDependency>>()
|
|
readonly css: CSSState
|
|
@@ -78,33 +95,61 @@ export class UnistylesRegistry {
|
|
}
|
|
|
|
connect = (ref: HTMLElement, hash: string) => {
|
|
- const stylesCounter = this.stylesCounter.get(hash) ?? new Set()
|
|
+ this.stylesCounter.set(hash, (this.stylesCounter.get(hash) ?? 0) + 1)
|
|
|
|
- stylesCounter.add(ref)
|
|
- this.stylesCounter.set(hash, stylesCounter)
|
|
+ if (!this.finalizationRegistry) {
|
|
+ return
|
|
+ }
|
|
+
|
|
+ const token = {}
|
|
+ const tokensByHash = this.finalizerTokens.get(ref) ?? new Map<string, Array<object>>()
|
|
+ const tokens = tokensByHash.get(hash) ?? []
|
|
+
|
|
+ tokens.push(token)
|
|
+ tokensByHash.set(hash, tokens)
|
|
+ this.finalizerTokens.set(ref, tokensByHash)
|
|
+ this.finalizationRegistry.register(ref, { hash, generation: this.cleanupGeneration }, token)
|
|
}
|
|
|
|
remove = (ref: HTMLElement, hash: string) => {
|
|
- const stylesCounter = this.stylesCounter.get(hash) ?? new Set()
|
|
+ const token = this.finalizerTokens.get(ref)?.get(hash)?.pop()
|
|
|
|
- stylesCounter.delete(ref)
|
|
+ if (token) {
|
|
+ this.finalizationRegistry?.unregister(token)
|
|
+ }
|
|
|
|
- if (stylesCounter.size === 0) {
|
|
- // Move this to the end of the event loop so the element is removed from the DOM
|
|
- return Promise.resolve().then(() => {
|
|
- // Check if element is still in the DOM
|
|
- if (document.querySelector(`.${hash}`)) {
|
|
- return false
|
|
- }
|
|
+ return this.decrementAndMaybeCleanup(hash)
|
|
+ }
|
|
+
|
|
+ private decrementAndMaybeCleanup = (hash: string): Promise<boolean> => {
|
|
+ const next = (this.stylesCounter.get(hash) ?? 0) - 1
|
|
|
|
- this.css.remove(hash)
|
|
- this.stylesCache.delete(hash)
|
|
+ if (next > 0) {
|
|
+ this.stylesCounter.set(hash, next)
|
|
|
|
- return true
|
|
- })
|
|
+ return Promise.resolve(false)
|
|
}
|
|
|
|
- return Promise.resolve(false)
|
|
+ // Drop the empty bucket from the Map
|
|
+ this.stylesCounter.delete(hash)
|
|
+
|
|
+ // Move this to the end of the event loop so the element is removed from the DOM
|
|
+ return Promise.resolve().then(() => {
|
|
+ // New connect raced in during the microtask
|
|
+ if ((this.stylesCounter.get(hash) ?? 0) > 0) {
|
|
+ return false
|
|
+ }
|
|
+
|
|
+ // Check if element is still in the DOM
|
|
+ if (document.querySelector(`.${hash}`)) {
|
|
+ return false
|
|
+ }
|
|
+
|
|
+ this.css.remove(hash)
|
|
+ this.stylesCache.delete(hash)
|
|
+
|
|
+ return true
|
|
+ })
|
|
}
|
|
|
|
add = (value: UnistylesValues, forChild?: boolean) => {
|
|
@@ -126,7 +171,11 @@ export class UnistylesRegistry {
|
|
}
|
|
|
|
reset = () => {
|
|
+ // Invalidate pending FR callbacks from this generation
|
|
+ this.cleanupGeneration += 1
|
|
+ this.disposeListenersMap.forEach((dispose) => dispose())
|
|
this.css.reset()
|
|
+ this.stylesheets.clear()
|
|
this.stylesCache.clear()
|
|
this.dependenciesMap.clear()
|
|
this.disposeListenersMap.clear()
|
|
diff --git a/node_modules/react-native-unistyles/android/build.gradle b/node_modules/react-native-unistyles/android/build.gradle
|
|
index 195954b..c4ac28c 100644
|
|
--- a/node_modules/react-native-unistyles/android/build.gradle
|
|
+++ b/node_modules/react-native-unistyles/android/build.gradle
|
|
@@ -38,6 +38,7 @@ if (isNewArchitectureEnabled()) {
|
|
|
|
android {
|
|
compileSdkVersion safeExtGet('compileSdkVersion', 35)
|
|
+ ndkVersion safeExtGet('ndkVersion', '27.1.12297006')
|
|
namespace "com.unistyles"
|
|
|
|
defaultConfig {
|
|
diff --git a/node_modules/react-native-unistyles/src/core/withUnistyles/withUnistyles.tsx b/node_modules/react-native-unistyles/src/core/withUnistyles/withUnistyles.tsx
|
|
--- a/node_modules/react-native-unistyles/src/core/withUnistyles/withUnistyles.tsx
|
|
+++ b/node_modules/react-native-unistyles/src/core/withUnistyles/withUnistyles.tsx
|
|
@@ -28,13 +28,14 @@
|
|
|
|
return forwardRef<GenericComponentRef<TComponent>, PropsWithUnistyles>((props, ref) => {
|
|
const narrowedProps = props as PropsWithUnistyles & UnistyleStyles
|
|
+ const { uniProps, ...componentProps } = narrowedProps
|
|
const styleClassNames = getClassName(narrowedProps.style, true)
|
|
const contentContainerStyleClassNames = getClassName(narrowedProps.contentContainerStyle)
|
|
const { proxifiedRuntime, proxifiedTheme } = useProxifiedUnistyles()
|
|
|
|
const { key: mappingsKey, ...mappingsProps } = mappings ? mappings(proxifiedTheme, proxifiedRuntime) : {}
|
|
- const { key: uniPropsKey, ...unistyleProps } = narrowedProps.uniProps
|
|
- ? narrowedProps.uniProps(proxifiedTheme, proxifiedRuntime)
|
|
+ const { key: uniPropsKey, ...unistyleProps } = uniProps
|
|
+ ? uniProps(proxifiedTheme, proxifiedRuntime)
|
|
: {}
|
|
|
|
const emptyStyles = narrowedProps.style
|
|
@@ -46,7 +47,7 @@
|
|
: undefined
|
|
|
|
const combinedProps = {
|
|
- ...deepMergeObjects(mappingsProps, unistyleProps, props),
|
|
+ ...deepMergeObjects(mappingsProps, unistyleProps, componentProps),
|
|
...(narrowedProps.style
|
|
? {
|
|
// Override default component styles with undefined values to reset them
|
|
diff --git a/node_modules/react-native-unistyles/src/core/withUnistyles/withUnistyles.native.tsx b/node_modules/react-native-unistyles/src/core/withUnistyles/withUnistyles.native.tsx
|
|
--- a/node_modules/react-native-unistyles/src/core/withUnistyles/withUnistyles.native.tsx
|
|
+++ b/node_modules/react-native-unistyles/src/core/withUnistyles/withUnistyles.native.tsx
|
|
@@ -63,6 +63,7 @@
|
|
|
|
return forwardRef<GenericComponentRef<TComponent>, PropsWithUnistyles>((props, ref) => {
|
|
const narrowedProps = props as PropsWithUnistyles & UnistyleStyles
|
|
+ const { uniProps, ...componentProps } = narrowedProps
|
|
const NativeComponent = Component as ComponentType
|
|
|
|
// @ts-ignore we don't know the type of the component
|
|
@@ -89,15 +90,15 @@
|
|
}, [narrowedProps.style, narrowedProps.contentContainerStyle])
|
|
|
|
const { key: mappingsKey, ...mappingsProps } = mappings ? mappings(proxifiedTheme, proxifiedRuntime) : {}
|
|
- const { key: uniPropsKey, ...unistyleProps } = narrowedProps.uniProps
|
|
- ? narrowedProps.uniProps(proxifiedTheme, proxifiedRuntime)
|
|
+ const { key: uniPropsKey, ...unistyleProps } = uniProps
|
|
+ ? uniProps(proxifiedTheme, proxifiedRuntime)
|
|
: {}
|
|
|
|
const styleSecrets = getSecrets(narrowedProps.style)
|
|
const contentContainerStyleSecrets = getSecrets(narrowedProps.contentContainerStyle)
|
|
|
|
const finalProps = {
|
|
- ...deepMergeObjects(mappingsProps, unistyleProps, props),
|
|
+ ...deepMergeObjects(mappingsProps, unistyleProps, componentProps),
|
|
...(narrowedProps.style
|
|
? {
|
|
style: styleSecrets.styles,
|
|
diff --git a/node_modules/react-native-unistyles/lib/module/core/withUnistyles/withUnistyles.js b/node_modules/react-native-unistyles/lib/module/core/withUnistyles/withUnistyles.js
|
|
--- a/node_modules/react-native-unistyles/lib/module/core/withUnistyles/withUnistyles.js
|
|
+++ b/node_modules/react-native-unistyles/lib/module/core/withUnistyles/withUnistyles.js
|
|
@@ -13,6 +13,7 @@
|
|
export const withUnistyles = (Component, mappings) => {
|
|
return /*#__PURE__*/forwardRef((props, ref) => {
|
|
const narrowedProps = props;
|
|
+ const { uniProps, ...componentProps } = narrowedProps;
|
|
const styleClassNames = getClassName(narrowedProps.style, true);
|
|
const contentContainerStyleClassNames = getClassName(narrowedProps.contentContainerStyle);
|
|
const {
|
|
@@ -26,10 +27,10 @@
|
|
const {
|
|
key: uniPropsKey,
|
|
...unistyleProps
|
|
- } = narrowedProps.uniProps ? narrowedProps.uniProps(proxifiedTheme, proxifiedRuntime) : {};
|
|
+ } = uniProps ? uniProps(proxifiedTheme, proxifiedRuntime) : {};
|
|
const emptyStyles = narrowedProps.style ? Object.fromEntries(Object.entries(Object.getOwnPropertyDescriptors(narrowedProps.style)).filter(([key]) => !key.startsWith('unistyles') && !key.startsWith('_')).map(([key]) => [key, undefined])) : undefined;
|
|
const combinedProps = {
|
|
- ...deepMergeObjects(mappingsProps, unistyleProps, props),
|
|
+ ...deepMergeObjects(mappingsProps, unistyleProps, componentProps),
|
|
...(narrowedProps.style ? {
|
|
// Override default component styles with undefined values to reset them
|
|
style: emptyStyles
|
|
diff --git a/node_modules/react-native-unistyles/lib/module/core/withUnistyles/withUnistyles.native.js b/node_modules/react-native-unistyles/lib/module/core/withUnistyles/withUnistyles.native.js
|
|
--- a/node_modules/react-native-unistyles/lib/module/core/withUnistyles/withUnistyles.native.js
|
|
+++ b/node_modules/react-native-unistyles/lib/module/core/withUnistyles/withUnistyles.native.js
|
|
@@ -27,6 +27,7 @@
|
|
};
|
|
return /*#__PURE__*/forwardRef((props, ref) => {
|
|
const narrowedProps = props;
|
|
+ const { uniProps, ...componentProps } = narrowedProps;
|
|
const NativeComponent = Component;
|
|
|
|
// @ts-ignore we don't know the type of the component
|
|
@@ -57,11 +58,11 @@
|
|
const {
|
|
key: uniPropsKey,
|
|
...unistyleProps
|
|
- } = narrowedProps.uniProps ? narrowedProps.uniProps(proxifiedTheme, proxifiedRuntime) : {};
|
|
+ } = uniProps ? uniProps(proxifiedTheme, proxifiedRuntime) : {};
|
|
const styleSecrets = getSecrets(narrowedProps.style);
|
|
const contentContainerStyleSecrets = getSecrets(narrowedProps.contentContainerStyle);
|
|
const finalProps = {
|
|
- ...deepMergeObjects(mappingsProps, unistyleProps, props),
|
|
+ ...deepMergeObjects(mappingsProps, unistyleProps, componentProps),
|
|
...(narrowedProps.style ? {
|
|
style: styleSecrets.styles
|
|
} : {}),
|
|
diff --git a/node_modules/react-native-unistyles/lib/commonjs/core/withUnistyles/withUnistyles.js b/node_modules/react-native-unistyles/lib/commonjs/core/withUnistyles/withUnistyles.js
|
|
--- a/node_modules/react-native-unistyles/lib/commonjs/core/withUnistyles/withUnistyles.js
|
|
+++ b/node_modules/react-native-unistyles/lib/commonjs/core/withUnistyles/withUnistyles.js
|
|
@@ -18,6 +18,7 @@
|
|
const withUnistyles = (Component, mappings) => {
|
|
return /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
|
const narrowedProps = props;
|
|
+ const { uniProps, ...componentProps } = narrowedProps;
|
|
const styleClassNames = (0, _getClassname.getClassName)(narrowedProps.style, true);
|
|
const contentContainerStyleClassNames = (0, _getClassname.getClassName)(narrowedProps.contentContainerStyle);
|
|
const {
|
|
@@ -31,10 +32,10 @@
|
|
const {
|
|
key: uniPropsKey,
|
|
...unistyleProps
|
|
- } = narrowedProps.uniProps ? narrowedProps.uniProps(proxifiedTheme, proxifiedRuntime) : {};
|
|
+ } = uniProps ? uniProps(proxifiedTheme, proxifiedRuntime) : {};
|
|
const emptyStyles = narrowedProps.style ? Object.fromEntries(Object.entries(Object.getOwnPropertyDescriptors(narrowedProps.style)).filter(([key]) => !key.startsWith('unistyles') && !key.startsWith('_')).map(([key]) => [key, undefined])) : undefined;
|
|
const combinedProps = {
|
|
- ...(0, _utils.deepMergeObjects)(mappingsProps, unistyleProps, props),
|
|
+ ...(0, _utils.deepMergeObjects)(mappingsProps, unistyleProps, componentProps),
|
|
...(narrowedProps.style ? {
|
|
// Override default component styles with undefined values to reset them
|
|
style: emptyStyles
|
|
diff --git a/node_modules/react-native-unistyles/lib/commonjs/core/withUnistyles/withUnistyles.native.js b/node_modules/react-native-unistyles/lib/commonjs/core/withUnistyles/withUnistyles.native.js
|
|
--- a/node_modules/react-native-unistyles/lib/commonjs/core/withUnistyles/withUnistyles.native.js
|
|
+++ b/node_modules/react-native-unistyles/lib/commonjs/core/withUnistyles/withUnistyles.native.js
|
|
@@ -32,6 +32,7 @@
|
|
};
|
|
return /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
|
const narrowedProps = props;
|
|
+ const { uniProps, ...componentProps } = narrowedProps;
|
|
const NativeComponent = Component;
|
|
|
|
// @ts-ignore we don't know the type of the component
|
|
@@ -62,11 +63,11 @@
|
|
const {
|
|
key: uniPropsKey,
|
|
...unistyleProps
|
|
- } = narrowedProps.uniProps ? narrowedProps.uniProps(proxifiedTheme, proxifiedRuntime) : {};
|
|
+ } = uniProps ? uniProps(proxifiedTheme, proxifiedRuntime) : {};
|
|
const styleSecrets = getSecrets(narrowedProps.style);
|
|
const contentContainerStyleSecrets = getSecrets(narrowedProps.contentContainerStyle);
|
|
const finalProps = {
|
|
- ...(0, _utils.deepMergeObjects)(mappingsProps, unistyleProps, props),
|
|
+ ...(0, _utils.deepMergeObjects)(mappingsProps, unistyleProps, componentProps),
|
|
...(narrowedProps.style ? {
|
|
style: styleSecrets.styles
|
|
} : {}),
|
|
diff --git a/node_modules/react-native-unistyles/lib/commonjs/web/runtime.js b/node_modules/react-native-unistyles/lib/commonjs/web/runtime.js
|
|
index 305fa49..5957aa5 100644
|
|
--- a/node_modules/react-native-unistyles/lib/commonjs/web/runtime.js
|
|
+++ b/node_modules/react-native-unistyles/lib/commonjs/web/runtime.js
|
|
@@ -35,10 +35,17 @@ class UnistylesRuntime {
|
|
return this.darkMedia;
|
|
}
|
|
get colorScheme() {
|
|
+ // Read the scheme through fresh lists, never through lightMedia/darkMedia. Chromium defers
|
|
+ // MediaQueryList change events while the document is hidden and drops the pending event
|
|
+ // of any list whose `matches` was read before the document became visible again, which
|
|
+ // would silence the adaptive-theme listeners registered on those two lists.
|
|
+ if ((0, _utils.isServer)()) {
|
|
+ return _types.ColorScheme.Unspecified;
|
|
+ }
|
|
switch (true) {
|
|
- case this.getLightMedia()?.matches:
|
|
+ case window.matchMedia('(prefers-color-scheme: light)').matches:
|
|
return _types.ColorScheme.Light;
|
|
- case this.getDarkMedia()?.matches:
|
|
+ case window.matchMedia('(prefers-color-scheme: dark)').matches:
|
|
return _types.ColorScheme.Dark;
|
|
default:
|
|
return _types.ColorScheme.Unspecified;
|
|
diff --git a/node_modules/react-native-unistyles/lib/module/web/runtime.js b/node_modules/react-native-unistyles/lib/module/web/runtime.js
|
|
index 7f13a06..c487bee 100644
|
|
--- a/node_modules/react-native-unistyles/lib/module/web/runtime.js
|
|
+++ b/node_modules/react-native-unistyles/lib/module/web/runtime.js
|
|
@@ -31,10 +31,17 @@ export class UnistylesRuntime {
|
|
return this.darkMedia;
|
|
}
|
|
get colorScheme() {
|
|
+ // Read the scheme through fresh lists, never through lightMedia/darkMedia. Chromium defers
|
|
+ // MediaQueryList change events while the document is hidden and drops the pending event
|
|
+ // of any list whose `matches` was read before the document became visible again, which
|
|
+ // would silence the adaptive-theme listeners registered on those two lists.
|
|
+ if (isServer()) {
|
|
+ return ColorScheme.Unspecified;
|
|
+ }
|
|
switch (true) {
|
|
- case this.getLightMedia()?.matches:
|
|
+ case window.matchMedia('(prefers-color-scheme: light)').matches:
|
|
return ColorScheme.Light;
|
|
- case this.getDarkMedia()?.matches:
|
|
+ case window.matchMedia('(prefers-color-scheme: dark)').matches:
|
|
return ColorScheme.Dark;
|
|
default:
|
|
return ColorScheme.Unspecified;
|
|
diff --git a/node_modules/react-native-unistyles/src/web/runtime.ts b/node_modules/react-native-unistyles/src/web/runtime.ts
|
|
index a16dac0..6519858 100644
|
|
--- a/node_modules/react-native-unistyles/src/web/runtime.ts
|
|
+++ b/node_modules/react-native-unistyles/src/web/runtime.ts
|
|
@@ -41,8 +41,16 @@ export class UnistylesRuntime {
|
|
get colorScheme() {
|
|
+ // Read the scheme through fresh lists, never through lightMedia/darkMedia. Chromium defers
|
|
+ // MediaQueryList change events while the document is hidden and drops the pending event
|
|
+ // of any list whose `matches` was read before the document became visible again, which
|
|
+ // would silence the adaptive-theme listeners registered on those two lists.
|
|
+ if (isServer()) {
|
|
+ return ColorScheme.Unspecified
|
|
+ }
|
|
+
|
|
switch (true) {
|
|
- case this.getLightMedia()?.matches:
|
|
+ case window.matchMedia('(prefers-color-scheme: light)').matches:
|
|
return ColorScheme.Light
|
|
- case this.getDarkMedia()?.matches:
|
|
+ case window.matchMedia('(prefers-color-scheme: dark)').matches:
|
|
return ColorScheme.Dark
|
|
default:
|
|
return ColorScheme.Unspecified
|
|
diff --git a/node_modules/react-native-unistyles/android/src/main/java/com/unistyles/NativePlatform+android.kt b/node_modules/react-native-unistyles/android/src/main/java/com/unistyles/NativePlatform+android.kt
|
|
index 0f8d1f0..154a12a 100644
|
|
--- a/node_modules/react-native-unistyles/android/src/main/java/com/unistyles/NativePlatform+android.kt
|
|
+++ b/node_modules/react-native-unistyles/android/src/main/java/com/unistyles/NativePlatform+android.kt
|
|
@@ -3,11 +3,16 @@ package com.unistyles
|
|
import android.os.Build
|
|
import android.content.Context
|
|
import android.content.res.Configuration
|
|
+import android.content.res.Resources
|
|
+import android.os.Handler
|
|
+import android.os.Looper
|
|
import android.util.DisplayMetrics
|
|
import android.view.View
|
|
import android.view.WindowManager
|
|
import androidx.annotation.Keep
|
|
+import androidx.core.content.OnConfigurationChangedProvider
|
|
import androidx.core.text.TextUtilsCompat
|
|
+import androidx.core.util.Consumer
|
|
import androidx.core.view.ViewCompat
|
|
import androidx.core.view.WindowCompat
|
|
import androidx.core.view.WindowInsetsCompat
|
|
@@ -22,6 +27,7 @@ import com.margelo.nitro.unistyles.Insets
|
|
import com.margelo.nitro.unistyles.Orientation
|
|
import com.margelo.nitro.unistyles.UnistyleDependency
|
|
import com.margelo.nitro.unistyles.UnistylesNativeMiniRuntime
|
|
+import java.lang.ref.WeakReference
|
|
import java.util.Locale
|
|
|
|
@Keep
|
|
@@ -30,6 +36,14 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
private val _insets = NativePlatformInsets(reactContext, this::getMiniRuntime) { this.onConfigChange() }
|
|
private var _miniRuntime: UnistylesNativeMiniRuntime = buildMiniRuntime()
|
|
private val _listener = NativePlatformListener(reactContext, this::getMiniRuntime) { this.diffMiniRuntime() }
|
|
+ private var _configurationProvider: WeakReference<OnConfigurationChangedProvider>? = null
|
|
+ private val _activityConfigurationListener = Consumer<Configuration> {
|
|
+ Handler(Looper.getMainLooper()).post { this.onConfigChange() }
|
|
+ }
|
|
+
|
|
+ // Application resources can lag behind configuration changes
|
|
+ private val configurationResources: Resources
|
|
+ get() = reactContext.currentActivity?.resources ?: reactContext.resources
|
|
|
|
init {
|
|
checkEdgeToEdge()
|
|
@@ -37,12 +51,16 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
}
|
|
|
|
fun onDestroy() {
|
|
+ stopObservingActivityConfiguration()
|
|
_listener.onDestroy()
|
|
_insets.onDestroy()
|
|
reactContext.removeLifecycleEventListener(this)
|
|
}
|
|
|
|
override fun onHostResume() {
|
|
+ observeActivityConfiguration()
|
|
+ // catch configuration changes missed while no Activity was attached
|
|
+ onConfigChange()
|
|
_insets.getInitialInsets(false)
|
|
_insets.startInsetsListener()
|
|
}
|
|
@@ -51,7 +69,26 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
_insets.stopInsetsListener()
|
|
}
|
|
|
|
- override fun onHostDestroy() {}
|
|
+ override fun onHostDestroy() {
|
|
+ stopObservingActivityConfiguration()
|
|
+ }
|
|
+
|
|
+ private fun observeActivityConfiguration() {
|
|
+ val provider = reactContext.currentActivity as? OnConfigurationChangedProvider
|
|
+
|
|
+ if (_configurationProvider?.get() === provider) {
|
|
+ return
|
|
+ }
|
|
+
|
|
+ stopObservingActivityConfiguration()
|
|
+ provider?.addOnConfigurationChangedListener(_activityConfigurationListener)
|
|
+ _configurationProvider = provider?.let { WeakReference(it) }
|
|
+ }
|
|
+
|
|
+ private fun stopObservingActivityConfiguration() {
|
|
+ _configurationProvider?.get()?.removeOnConfigurationChangedListener(_activityConfigurationListener)
|
|
+ _configurationProvider = null
|
|
+ }
|
|
|
|
override val memorySize: Long
|
|
get() = 0
|
|
@@ -61,7 +98,7 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
}
|
|
|
|
override fun getColorScheme(): ColorScheme {
|
|
- val uiMode = reactContext.resources.configuration.uiMode
|
|
+ val uiMode = configurationResources.configuration.uiMode
|
|
|
|
val colorScheme = when (uiMode.and(Configuration.UI_MODE_NIGHT_MASK)) {
|
|
Configuration.UI_MODE_NIGHT_YES -> ColorScheme.DARK
|
|
@@ -73,15 +110,15 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
}
|
|
|
|
override fun getFontScale(): Double {
|
|
- return reactContext.resources.configuration.fontScale.toDouble()
|
|
+ return configurationResources.configuration.fontScale.toDouble()
|
|
}
|
|
|
|
override fun getPixelRatio(): Double {
|
|
- return reactContext.resources.displayMetrics.density.toDouble()
|
|
+ return configurationResources.displayMetrics.density.toDouble()
|
|
}
|
|
|
|
override fun getOrientation(): Orientation {
|
|
- val orientation = when (reactContext.resources.configuration.orientation) {
|
|
+ val orientation = when (configurationResources.configuration.orientation) {
|
|
Configuration.ORIENTATION_PORTRAIT -> Orientation.PORTRAIT
|
|
Configuration.ORIENTATION_LANDSCAPE -> Orientation.LANDSCAPE
|
|
else -> Orientation.PORTRAIT
|
|
@@ -122,7 +159,7 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
return Dimensions(screenWidth, screenHeight)
|
|
}
|
|
else -> {
|
|
- val displayMetrics = reactContext.resources.displayMetrics
|
|
+ val displayMetrics = configurationResources.displayMetrics
|
|
|
|
reactContext.currentActivity?.windowManager?.currentWindowMetrics?.bounds?.let {
|
|
val boundsWidth = (it.width() / displayMetrics.density).toDouble()
|
|
@@ -157,7 +194,7 @@ class NativePlatformAndroid(private val reactContext: ReactApplicationContext):
|
|
"com.facebook.react.modules.i18nmanager.I18nUtil",
|
|
Context.MODE_PRIVATE
|
|
)
|
|
- val resourcesLocale = reactContext.resources.configuration.locales[0]
|
|
+ val resourcesLocale = configurationResources.configuration.locales[0]
|
|
val hasForcedRtl = sharedPrefs.getBoolean("RCTI18nUtil_forceRTL", false)
|
|
// user preferences
|
|
val isRtl = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_RTL
|
|
diff --git a/node_modules/react-native-unistyles/android/src/main/java/com/unistyles/NativePlatform+insets.kt b/node_modules/react-native-unistyles/android/src/main/java/com/unistyles/NativePlatform+insets.kt
|
|
index a9c1804..f5a3c20 100644
|
|
--- a/node_modules/react-native-unistyles/android/src/main/java/com/unistyles/NativePlatform+insets.kt
|
|
+++ b/node_modules/react-native-unistyles/android/src/main/java/com/unistyles/NativePlatform+insets.kt
|
|
@@ -38,7 +38,7 @@ class NativePlatformInsets(
|
|
}
|
|
|
|
fun getInsets(): Insets {
|
|
- val density = reactContext.resources.displayMetrics.density
|
|
+ val density = (reactContext.currentActivity?.resources ?: reactContext.resources).displayMetrics.density
|
|
|
|
return Insets(
|
|
this._insets.top / density,
|