diff --git a/examples/demo/bun.lock b/examples/demo/bun.lock index c4392b35..39a2d284 100644 --- a/examples/demo/bun.lock +++ b/examples/demo/bun.lock @@ -1006,7 +1006,7 @@ "react-native-dotenv": ["react-native-dotenv@3.4.11", "", { "dependencies": { "dotenv": "^16.4.5" }, "peerDependencies": { "@babel/runtime": "^7.20.6" } }, "sha512-6vnIE+WHABSeHCaYP6l3O1BOEhWxKH6nHAdV7n/wKn/sciZ64zPPp2NUdEUf1m7g4uuzlLbjgr+6uDt89q2DOg=="], - "react-native-onesignal": ["react-native-onesignal@../../react-native-onesignal.tgz", { "dependencies": { "invariant": "^2.2.4" }, "peerDependencies": { "react-native": ">=0.79.0" } }, "sha512-5pN/I1dsp6CnLpazNGt4Qjkhh+zw0sU2uHp3UyxM8gIzfJKLvi2Avzwzfdh7Ao+0tA4xB9jQ1UBLzZdpg/yRLw=="], + "react-native-onesignal": ["react-native-onesignal@../../react-native-onesignal.tgz", { "dependencies": { "invariant": "^2.2.4" }, "peerDependencies": { "react-native": ">=0.79.0" } }, "sha512-jpqguCfDcDnTWYI63H3h9s5moqBW94P3uqe2a4liNUsT8GKaatQFJcouQWdG6+OLTqi8BFPmdm8Hj2cm1akHpQ=="], "react-native-safe-area-context": ["react-native-safe-area-context@5.7.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-/9/MtQz8ODphjsLdZ+GZAIcC/RtoqW9EeShf7Uvnfgm/pzYrJ75y3PV/J1wuAV1T5Dye5ygq4EAW20RoBq0ABQ=="], diff --git a/examples/demo/ios/Podfile.lock b/examples/demo/ios/Podfile.lock index c8cd4dfd..b79b977d 100644 --- a/examples/demo/ios/Podfile.lock +++ b/examples/demo/ios/Podfile.lock @@ -1449,7 +1449,7 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon/turbomodule/core - ReactNativeDependencies - - react-native-onesignal (5.5.7): + - react-native-onesignal (5.5.8): - hermes-engine - OneSignalXCFramework (= 5.5.6) - RCTRequired @@ -2314,7 +2314,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: FBLazyVector: c12d2108050e27952983d565a232f6f7b1ad5e69 - hermes-engine: 431876dbea22ba6821b0e999131ecbf5d706c8d2 + hermes-engine: 177322198264d50dc281084c48e1ed80ea14884c OneSignalXCFramework: 9a0f33eaef7544788a2b04f067e90fe18759fdf9 RCTDeprecation: 3280799c14232a56e5a44f92981a8ee33bc69fd9 RCTRequired: 9854a51b0f65ccf43ea0b744df4d70fce339db32 @@ -2324,7 +2324,7 @@ SPEC CHECKSUMS: React: 7ef36630d07638043a134a7dd2ec17e0be10fc3c React-callinvoker: af4e8fe1d60ab63dd8d74c2a68988064c2848954 React-Core: c609976c034ba9556bef9850a571a71bd458d73f - React-Core-prebuilt: 5e3e0e5fe0a22af7fb36c5b593882da759f395c9 + React-Core-prebuilt: f4df078355bf9605a0d0278aa5c63fcd4b764a1d React-CoreModules: 0ea85f3b3f4b8cbfb3afacd2ed85458fb878517a React-cxxreact: 6752bab77c0599d6136e2b8b9b64b4a7d316d401 React-debug: 38389b86e3570558ec73dd4cbc0cd2f2eec47a51 @@ -2352,7 +2352,7 @@ SPEC CHECKSUMS: React-logger: 9e51e01455f15cb3ef87a09a1ec773cdb22d56c1 React-Mapbuffer: 92b99e450e8ff598b27d6e4db3a75e04fd45e9a9 React-microtasksnativemodule: 2fe0f2bd2840dedbd66c0ac249c64f977f39cc18 - react-native-onesignal: aa3a644f781e6dd21a1127afd33c1c66cb2fcc10 + react-native-onesignal: e2f5c75b26ba500eaad8d249ca8ae101ed615742 react-native-safe-area-context: ae7587b95fb580d1800c5b0b2a7bd48c2868e67a React-NativeModulesApple: 44a9474594566cd03659f92e38f42599c6b9dee4 React-networking: db73d91466cb134fcbdaaa579fb2de14e2c2ea01 @@ -2387,7 +2387,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: 6b7e8d8d974ed13fb66698d82c30c5e70c1f7d3a ReactCodegen: c5e5343f6691b0cd76913b9be5e89e5a83ff3315 ReactCommon: 92b53b0bd7f7d86154dc9f512c1ea5dee717cc72 - ReactNativeDependencies: f822e1f0812f671d9bfe99225d09dc144fa6f02b + ReactNativeDependencies: eaebe8c9533ec2c41b08a02844af461bfff10540 RNCAsyncStorage: 3a4f5e2777dae1688b781a487923a08569e27fe4 RNScreens: 6cb648bdad8fe9bee9259fe144df95b6d1d5b707 RNSVG: c69f7709226108f5eb89b5aa8833c17a36345468 diff --git a/examples/demo/src/components/AppHeader.tsx b/examples/demo/src/components/AppHeader.tsx index 82c9e52f..b18ba70e 100644 --- a/examples/demo/src/components/AppHeader.tsx +++ b/examples/demo/src/components/AppHeader.tsx @@ -15,7 +15,7 @@ export default function AppHeader({ options, back }: NativeStackHeaderProps) { typeof options.headerTitle === 'function' ? ( options.headerTitle({ children: options.title ?? '', tintColor: AppColors.white }) ) : ( - {options.title ?? ''} + {options.headerTitle ?? options.title ?? ''} ); return ( diff --git a/examples/demo/src/components/modals/MultiPairInputModal.tsx b/examples/demo/src/components/modals/MultiPairInputModal.tsx index d0bca09e..cca1aa7f 100644 --- a/examples/demo/src/components/modals/MultiPairInputModal.tsx +++ b/examples/demo/src/components/modals/MultiPairInputModal.tsx @@ -40,7 +40,7 @@ export default function MultiPairInputModal({ onConfirm, onClose, }: Props) { - const [rows, setRows] = useState([makeRow()]); + const [rows, setRows] = useState(() => [makeRow()]); const allFilled = rows.every((r) => r.key.trim() && r.value.trim()); @@ -49,7 +49,8 @@ export default function MultiPairInputModal({ }, []); const addRow = useCallback(() => { - setRows((prev) => [...prev, makeRow()]); + const row = makeRow(); + setRows((prev) => [...prev, row]); }, []); const removeRow = useCallback((id: number) => { @@ -60,10 +61,7 @@ export default function MultiPairInputModal({ if (!allFilled) { return; } - const pairs: Record = {}; - for (const row of rows) { - pairs[row.key.trim()] = row.value.trim(); - } + const pairs = Object.fromEntries(rows.map((row) => [row.key.trim(), row.value.trim()])); onConfirm(pairs); reset(); onClose(); diff --git a/examples/demo/src/components/modals/MultiSelectRemoveModal.tsx b/examples/demo/src/components/modals/MultiSelectRemoveModal.tsx index 5aa5d3f5..a8994d2a 100644 --- a/examples/demo/src/components/modals/MultiSelectRemoveModal.tsx +++ b/examples/demo/src/components/modals/MultiSelectRemoveModal.tsx @@ -28,7 +28,7 @@ export default function MultiSelectRemoveModal({ onConfirm, onClose, }: Props) { - const [selected, setSelected] = useState>(new Set()); + const [selected, setSelected] = useState>(() => new Set()); const toggle = (key: string) => { setSelected((prev) => { diff --git a/examples/demo/src/components/modals/OutcomeModal.tsx b/examples/demo/src/components/modals/OutcomeModal.tsx index 708c9734..f5038adb 100644 --- a/examples/demo/src/components/modals/OutcomeModal.tsx +++ b/examples/demo/src/components/modals/OutcomeModal.tsx @@ -33,8 +33,9 @@ export default function OutcomeModal({ const [name, setName] = useState(''); const [value, setValue] = useState(''); + const numericValue = Number(value); const canSubmit = - name.trim() && (outcomeType !== 'withValue' || (value.trim() && !isNaN(parseFloat(value)))); + name.trim() && (outcomeType !== 'withValue' || (value.trim() && Number.isFinite(numericValue))); const handleSend = () => { if (!canSubmit) { @@ -48,7 +49,7 @@ export default function OutcomeModal({ onSendUnique(name.trim()); break; case 'withValue': - onSendWithValue(name.trim(), parseFloat(value)); + onSendWithValue(name.trim(), numericValue); break; } handleClose(); diff --git a/examples/demo/src/components/modals/TrackEventModal.tsx b/examples/demo/src/components/modals/TrackEventModal.tsx index 09d1ad76..29c46d1e 100644 --- a/examples/demo/src/components/modals/TrackEventModal.tsx +++ b/examples/demo/src/components/modals/TrackEventModal.tsx @@ -29,7 +29,11 @@ export default function TrackEventModal({ visible, onConfirm, onClose }: Props) return true; } try { - JSON.parse(text); + const properties = JSON.parse(text); + if (properties === null || typeof properties !== 'object' || Array.isArray(properties)) { + setJsonError('Properties must be a JSON object'); + return false; + } setJsonError(''); return true; } catch { @@ -40,15 +44,10 @@ export default function TrackEventModal({ visible, onConfirm, onClose }: Props) const handlePropertiesChange = (text: string) => { setPropertiesText(text); - if (text.trim()) { - validateJson(text); - } else { - setJsonError(''); - } + validateJson(text); }; - const canSubmit = - name.trim() && !jsonError && (propertiesText.trim() === '' || !!propertiesText.trim()); + const canSubmit = !!name.trim() && !jsonError; const handleConfirm = () => { if (!name.trim()) {