@@ -39,9 +39,16 @@ class ReadiumReaderWidget extends StatefulWidget {
3939 State <StatefulWidget > createState () => _ReadiumReaderWidgetState ();
4040}
4141
42- class _ReadiumReaderWidgetState extends State <ReadiumReaderWidget > implements ReadiumReaderWidgetInterface {
42+ class _ReadiumReaderWidgetState extends State <ReadiumReaderWidget >
43+ implements ReadiumReaderWidgetInterface {
4344 static const _wakelockTimerDuration = Duration (minutes: 30 );
44- static const _maxRetryAwaitNativeViewReady = 100 ;
45+
46+ /// Duration per retry to wait for native view to be ready.
47+ static const _awaitNativeViewReadyDuration = Duration (milliseconds: 20 );
48+
49+ /// Maximum number of retries to check, if native view is ready.
50+ static const _maxRetryAwaitNativeViewReady = 500 ;
51+
4552 Timer ? _wakelockTimer;
4653 ReadiumReaderChannel ? _channel;
4754
@@ -176,7 +183,8 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
176183 Future <void > goLeft ({final bool animated = true }) async => _channel? .goLeft ();
177184
178185 @override
179- Future <void > goRight ({final bool animated = true }) async => _channel? .goRight ();
186+ Future <void > goRight ({final bool animated = true }) async =>
187+ _channel? .goRight ();
180188
181189 @override
182190 Future <void > skipToNext ({final bool animated = true }) async {
@@ -199,7 +207,8 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
199207 final newIndex = (curIndex + 1 ).clamp (0 , toc.length - 1 );
200208 Locator ? nextChapter = widget.publication.locatorFromLink (toc[newIndex]);
201209 if (nextChapter != null ) {
202- await _channel? .go (nextChapter, isAudioBookWithText: false , animated: true );
210+ await _channel? .go (nextChapter,
211+ isAudioBookWithText: false , animated: true );
203212 }
204213 }
205214 }
@@ -214,9 +223,11 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
214223 int ? curIndex = toc.indexWhere ((l) => l.href == currentHref);
215224 if (curIndex > - 1 ) {
216225 final newIndex = (curIndex - 1 ).clamp (0 , toc.length - 1 );
217- Locator ? previousChapter = widget.publication.locatorFromLink (toc[newIndex]);
226+ Locator ? previousChapter =
227+ widget.publication.locatorFromLink (toc[newIndex]);
218228 if (previousChapter != null ) {
219- await _channel? .go (previousChapter, isAudioBookWithText: false , animated: true );
229+ await _channel? .go (previousChapter,
230+ isAudioBookWithText: false , animated: true );
220231 }
221232 }
222233 }
@@ -242,7 +253,8 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
242253 }
243254
244255 @override
245- Future <void > applyDecorations (String id, List <ReaderDecoration > decorations) async {
256+ Future <void > applyDecorations (
257+ String id, List <ReaderDecoration > decorations) async {
246258 await _channel? .applyDecorations (id, decorations);
247259 }
248260
@@ -273,7 +285,9 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
273285 final creationParams = < String , dynamic > {
274286 'pubIdentifier' : publication.identifier,
275287 'preferences' : defaultPreferences,
276- 'initialLocator' : widget.initialLocator == null ? null : json.encode (widget.initialLocator),
288+ 'initialLocator' : widget.initialLocator == null
289+ ? null
290+ : json.encode (widget.initialLocator),
277291 };
278292
279293 R2Log .d ('creationParams=$creationParams ' );
@@ -286,16 +300,17 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
286300 gestureRecognizers: const {},
287301 hitTestBehavior: PlatformViewHitTestBehavior .opaque,
288302 ),
289- onCreatePlatformView: (final params) => PlatformViewsService .initSurfaceAndroidView (
303+ onCreatePlatformView: (final params) =>
304+ PlatformViewsService .initSurfaceAndroidView (
290305 id: params.id,
291306 viewType: _viewType,
292307 layoutDirection: TextDirection .ltr,
293308 creationParams: creationParams,
294309 creationParamsCodec: const StandardMessageCodec (),
295310 )
296- ..addOnPlatformViewCreatedListener (params.onPlatformViewCreated)
297- ..addOnPlatformViewCreatedListener (_onPlatformViewCreated)
298- ..create (),
311+ ..addOnPlatformViewCreatedListener (params.onPlatformViewCreated)
312+ ..addOnPlatformViewCreatedListener (_onPlatformViewCreated)
313+ ..create (),
299314 );
300315 } else if (Platform .isIOS) {
301316 return UiKitView (
@@ -356,29 +371,32 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
356371
357372 _awaitNativeViewReady ().then ((final _) {
358373 // TODO: This is just to demo how to use and debounce the Stream, remove when appropriate.
359- final nativeLocatorStream =
360- _readium.onTextLocatorChanged.debounceTime (const Duration (milliseconds: 50 )).asBroadcastStream ().distinct ();
374+ final nativeLocatorStream = _readium.onTextLocatorChanged
375+ .debounceTime (const Duration (milliseconds: 50 ))
376+ .asBroadcastStream ()
377+ .distinct ();
361378
362379 nativeLocatorStream.listen ((locator) {
363380 R2Log .d ('LocatorChanged - $locator ' );
364381 });
365382 });
366383 }
367384
368- Future <void > _awaitNativeViewReady ([int retry = 0 ]) async {
369- R2Log .d ('attempt: $retry ' );
385+ Future <void > _awaitNativeViewReady () async {
386+ final nativeViewStartTime = DateTime .now ();
387+ for (int retry = 0 ; retry < _maxRetryAwaitNativeViewReady; retry++ ) {
388+ if (await _channel? .isReaderReady () == true ) {
389+ R2Log .d (
390+ 'Native view is ready! Time spent: ${DateTime .now ().difference (nativeViewStartTime ).inMilliseconds } ms' );
391+ return ;
392+ }
370393
371- if (retry >= _maxRetryAwaitNativeViewReady) {
372- R2Log .d ('Max retry reached!' );
373- return ;
394+ R2Log .d ('Native reader not ready - retry:$retry ' );
395+ await Future .delayed (_awaitNativeViewReadyDuration);
374396 }
375397
376- if (await _channel? .isReaderReady () != true ) {
377- R2Log .d (() => 'Native reader not ready - retry' );
378-
379- await Future .delayed (const Duration (milliseconds: 100 ));
380- return _awaitNativeViewReady (++ retry);
381- }
398+ R2Log .d (
399+ 'Max retry reached! After ${DateTime .now ().difference (nativeViewStartTime ).inMilliseconds } ms' );
382400 }
383401
384402 /// Gets a Locator's href with toc fragment appended as identifier
@@ -388,14 +406,16 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
388406 }
389407
390408 final txtLoc = locator.toTextLocator ();
391- final tocFragment = locator.locations? .fragments? .firstWhereOrNull ((f) => f.startsWith ("toc=" ));
409+ final tocFragment = locator.locations? .fragments
410+ ? .firstWhereOrNull ((f) => f.startsWith ("toc=" ));
392411 if (tocFragment == null ) {
393412 return null ;
394413 }
395414 return '${txtLoc .toTextLocator ().hrefPath .substring (1 )}#${tocFragment .substring (4 )}' ;
396415 }
397416
398- Future <void > _setLocation (final Locator locator, final bool isAudioBookWithText) async {
417+ Future <void > _setLocation (
418+ final Locator locator, final bool isAudioBookWithText) async {
399419 R2Log .d ('Set highlight' );
400420
401421 // final playbackRate = FlutterReadium.state.playbackRate;
@@ -413,7 +433,8 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
413433 }
414434
415435 // Make sure to copy fragment durations onto locators before sending over native channel.
416- final fragmentDurationInSec = (locations? .xFragmentDuration? .inSeconds ?? 0 );
436+ final fragmentDurationInSec =
437+ (locations? .xFragmentDuration? .inSeconds ?? 0 );
417438
418439 _channel? .setLocation (
419440 locator.mapLocations (
@@ -442,12 +463,14 @@ class _ReadiumReaderWidgetState extends State<ReadiumReaderWidget> implements Re
442463 // trigger scrolling to the nearest page.
443464 if (_lastOrientation != null && _currentLocator != null ) {
444465 Future .delayed (const Duration (milliseconds: 500 )).then ((final value) {
445- R2Log .d ('Orientation changed. Re-navigating to current locator to re-align page.' );
466+ R2Log .d (
467+ 'Orientation changed. Re-navigating to current locator to re-align page.' );
446468 R2Log .d ('locator = $_currentLocator ' );
447469 _channel? .go (
448470 _currentLocator! ,
449471 animated: false ,
450- isAudioBookWithText: false , // TODO: isAudioBookWithText - we don't know atm.
472+ isAudioBookWithText:
473+ false , // TODO: isAudioBookWithText - we don't know atm.
451474 );
452475 });
453476 }
0 commit comments