1- import React , { useCallback , useEffect , useMemo , useRef , useState } from "react" ;
1+ import React , { useCallback , useMemo , useRef , useState } from "react" ;
22
33import Ionicons from "@expo/vector-icons/Ionicons" ;
44import MaskedView from "@react-native-masked-view/masked-view" ;
@@ -12,7 +12,6 @@ import {
1212 Text ,
1313 TouchableOpacity ,
1414 View ,
15- useWindowDimensions ,
1615} from "react-native" ;
1716import type { NativeScrollEvent , NativeSyntheticEvent } from "react-native" ;
1817// import { AudioContext, type AudioBuffer } from "react-native-audio-api";
@@ -23,12 +22,11 @@ import { formatTime } from "./utils/formatTime";
2322// import { getClickSound } from "./utils/getClickSound";
2423
2524export default function App ( ) {
26- const { width : screenWidth } = useWindowDimensions ( ) ;
27-
2825 const scrollViewRef = useRef < ScrollView > ( null ) ;
2926 // const audioContextRef = useRef<AudioContext | null>(null);
3027 // const audioBufferRef = useRef<AudioBuffer | null>(null);
3128
29+ const [ pageWidth , setPageWidth ] = useState ( 0 ) ;
3230 const [ currentPageIndex , setCurrentPageIndex ] = useState ( 0 ) ;
3331 const [ showPickerExample1 , setShowPickerExample1 ] = useState ( false ) ;
3432 const [ showPickerExample2 , setShowPickerExample2 ] = useState ( false ) ;
@@ -59,23 +57,26 @@ export default function App() {
5957 // };
6058 // }, []);
6159
62- useEffect ( ( ) => {
63- // when changing to landscape mode, scroll to the nearest page index
64- scrollViewRef . current ?. scrollTo ( {
65- animated : false ,
66- x : screenWidth * currentPageIndex ,
67- } ) ;
68- // eslint-disable-next-line react-hooks/exhaustive-deps
69- } , [ screenWidth ] ) ;
60+ const onRootLayout = useCallback (
61+ ( event : { nativeEvent : { layout : { width : number } } } ) => {
62+ const { width } = event . nativeEvent . layout ;
63+ setPageWidth ( width ) ;
64+ scrollViewRef . current ?. scrollTo ( {
65+ animated : false ,
66+ x : width * currentPageIndex ,
67+ } ) ;
68+ } ,
69+ [ currentPageIndex ]
70+ ) ;
7071
7172 const onMomentumScrollEnd = useCallback (
7273 ( event : NativeSyntheticEvent < NativeScrollEvent > ) => {
7374 LayoutAnimation . configureNext ( LayoutAnimation . Presets . easeInEaseOut ) ;
7475 const { contentOffset } = event . nativeEvent ;
75- const newPageIndex = Math . round ( contentOffset . x / screenWidth ) as 0 | 1 ;
76+ const newPageIndex = Math . round ( contentOffset . x / pageWidth ) as 0 | 1 ;
7677 setCurrentPageIndex ( newPageIndex ) ;
7778 } ,
78- [ screenWidth ]
79+ [ pageWidth ]
7980 ) ;
8081
8182 const pickerFeedback = useCallback ( ( ) => {
@@ -101,7 +102,7 @@ export default function App() {
101102
102103 const renderExample1 = useMemo ( ( ) => {
103104 return (
104- < View style = { [ styles . container , styles . page1Container , { width : screenWidth } ] } >
105+ < View style = { [ styles . container , styles . page1Container , { width : pageWidth } ] } >
105106 < Text style = { styles . textDark } >
106107 { alarmStringExample1 !== null ? "Alarm set for" : "No alarm set" }
107108 </ Text >
@@ -134,11 +135,11 @@ export default function App() {
134135 />
135136 </ View >
136137 ) ;
137- } , [ alarmStringExample1 , pickerFeedback , screenWidth , showPickerExample1 ] ) ;
138+ } , [ alarmStringExample1 , pickerFeedback , pageWidth , showPickerExample1 ] ) ;
138139
139140 const renderExample2 = useMemo ( ( ) => {
140141 return (
141- < View style = { [ styles . container , styles . page2Container , { width : screenWidth } ] } >
142+ < View style = { [ styles . container , styles . page2Container , { width : pageWidth } ] } >
142143 < Text style = { styles . textLight } >
143144 { alarmStringExample2 !== null ? "Alarm set for" : "No alarm set" }
144145 </ Text >
@@ -166,21 +167,21 @@ export default function App() {
166167 pickerFeedback = { pickerFeedback }
167168 setIsVisible = { setShowPickerExample2 }
168169 styles = { {
169- theme : "light" ,
170170 pickerColumnWidth : {
171171 hours : 90 ,
172172 } ,
173+ theme : "light" ,
173174 } }
174175 use12HourPicker
175176 visible = { showPickerExample2 }
176177 />
177178 </ View >
178179 ) ;
179- } , [ alarmStringExample2 , pickerFeedback , screenWidth , showPickerExample2 ] ) ;
180+ } , [ alarmStringExample2 , pickerFeedback , pageWidth , showPickerExample2 ] ) ;
180181
181182 const renderExample3 = useMemo ( ( ) => {
182183 return (
183- < View style = { [ styles . container , styles . page3Container , { width : screenWidth } ] } >
184+ < View style = { [ styles . container , styles . page3Container , { width : pageWidth } ] } >
184185 < Text style = { styles . textLight } >
185186 { alarmStringExample3 !== null ? "Alarm set for" : "No alarm set" }
186187 </ Text >
@@ -219,15 +220,15 @@ export default function App() {
219220 />
220221 </ View >
221222 ) ;
222- } , [ alarmStringExample3 , pickerFeedback , screenWidth , showPickerExample3 ] ) ;
223+ } , [ alarmStringExample3 , pickerFeedback , pageWidth , showPickerExample3 ] ) ;
223224
224225 const renderExample4 = useMemo ( ( ) => {
225226 return (
226227 < LinearGradient
227228 colors = { [ "#202020" , "#220578" ] }
228229 end = { { x : 1 , y : 1 } }
229230 start = { { x : 0 , y : 0 } }
230- style = { [ styles . container , { width : screenWidth } ] }
231+ style = { [ styles . container , { width : pageWidth } ] }
231232 >
232233 < TimerPicker
233234 hourLabel = ":"
@@ -257,11 +258,11 @@ export default function App() {
257258 />
258259 </ LinearGradient >
259260 ) ;
260- } , [ pickerFeedback , screenWidth ] ) ;
261+ } , [ pickerFeedback , pageWidth ] ) ;
261262
262263 const renderExample5 = useMemo ( ( ) => {
263264 return (
264- < View style = { [ styles . container , styles . page5Container , { width : screenWidth } ] } >
265+ < View style = { [ styles . container , styles . page5Container , { width : pageWidth } ] } >
265266 < TimerPicker
266267 hideHours
267268 LinearGradient = { LinearGradient }
@@ -285,7 +286,7 @@ export default function App() {
285286 />
286287 </ View >
287288 ) ;
288- } , [ pickerFeedback , screenWidth ] ) ;
289+ } , [ pickerFeedback , pageWidth ] ) ;
289290
290291 const renderNavigationArrows = useMemo ( ( ) => {
291292 const pageIndicesWithDarkBackground = [ 0 , 3 ] ;
@@ -303,7 +304,7 @@ export default function App() {
303304 setCurrentPageIndex ( ( currentPageIndex ) => {
304305 scrollViewRef . current ?. scrollTo ( {
305306 animated : true ,
306- x : screenWidth * ( currentPageIndex + 1 ) ,
307+ x : pageWidth * ( currentPageIndex + 1 ) ,
307308 } ) ;
308309 return currentPageIndex + 1 ;
309310 } ) ;
@@ -328,7 +329,7 @@ export default function App() {
328329 setCurrentPageIndex ( ( currentPageIndex ) => {
329330 scrollViewRef . current ?. scrollTo ( {
330331 animated : true ,
331- x : screenWidth * ( currentPageIndex - 1 ) ,
332+ x : pageWidth * ( currentPageIndex - 1 ) ,
332333 } ) ;
333334 return currentPageIndex - 1 ;
334335 } ) ;
@@ -348,10 +349,10 @@ export default function App() {
348349 ) : null }
349350 </ >
350351 ) ;
351- } , [ currentPageIndex , screenWidth ] ) ;
352+ } , [ currentPageIndex , pageWidth ] ) ;
352353
353354 return (
354- < >
355+ < View onLayout = { onRootLayout } style = { styles . root } >
355356 < ScrollView
356357 ref = { scrollViewRef }
357358 horizontal
@@ -366,7 +367,7 @@ export default function App() {
366367 { renderExample5 }
367368 </ ScrollView >
368369 { renderNavigationArrows }
369- </ >
370+ </ View >
370371 ) ;
371372}
372373
@@ -422,6 +423,9 @@ const styles = StyleSheet.create({
422423 page5Container : {
423424 backgroundColor : "#F1F1F1" ,
424425 } ,
426+ root : {
427+ flex : 1 ,
428+ } ,
425429 textDark : {
426430 color : "#F1F1F1" ,
427431 fontSize : 18 ,
0 commit comments