@@ -5,6 +5,7 @@ import 'package:azure_devops/src/mixins/logger_mixin.dart';
55import 'package:azure_devops/src/services/azure_api_service.dart' ;
66import 'package:azure_devops/src/widgets/empty_page.dart' ;
77import 'package:azure_devops/src/widgets/error_page.dart' ;
8+ import 'package:flutter/foundation.dart' ;
89import 'package:flutter/material.dart' ;
910import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart' ;
1011
@@ -194,122 +195,127 @@ class _AppPageStateListenable<T> extends State<AppPage<T>> with AppLogger {
194195 );
195196 }
196197
197- return Scaffold (
198- body: ValueListenableBuilder <ApiResponse <T ?>?>(
199- valueListenable: widget.notifier! ,
200- builder: (_, response, __) => Stack (
201- alignment: Alignment .center,
202- children: [
203- SafeArea (
204- bottom: widget.safeAreaBottom,
205- child: Scrollbar (
206- controller: scrollController,
207- thickness: widget.showScrollbar ? null : 0 ,
208- child: SmartRefresher (
209- controller: _refreshController,
210- onRefresh: _onRefresh,
211- onLoading: _onLoading,
212- enablePullUp: widget.onLoading != null ,
213- footer: CustomFooter (
214- builder: (context, mode) {
215- var loadText = '' ;
216- switch (mode) {
217- case LoadStatus .canLoading:
218- loadText = 'Load more' ;
219- case LoadStatus .idle:
220- loadText = 'Idle' ;
221- case LoadStatus .loading:
222- loadText = 'Loading' ;
223- case LoadStatus .noMore:
224- case LoadStatus .failed:
225- default :
226- break ;
227- }
228- return SizedBox (
229- height: 48 ,
230- child: Center (child: Text (loadText)),
231- );
232- },
233- ),
234- child: CustomScrollView (
235- controller: scrollController,
236- slivers: [
237- SliverAppBar (
238- title: Text (widget.title),
239- floating: true ,
240- snap: true ,
241- pinned: widget.fixedAppBar,
242- actions: actions,
243- surfaceTintColor: context.themeExtension.background,
244- scrolledUnderElevation: 0 ,
245- expandedHeight: 50 ,
246- automaticallyImplyLeading: widget.showBackButton,
247- bottom: widget.header == null
248- ? null
249- : _Header (
250- child: Column (
251- children: [
252- const SizedBox (
253- height: 10 ,
254- ),
255- widget.header !(),
256- const SizedBox (
257- height: 10 ,
258- ),
259- ],
198+ return RefreshConfiguration (
199+ springDescription: defaultTargetPlatform == TargetPlatform .android
200+ ? SpringDescription .withDurationAndBounce ()
201+ : const SpringDescription (mass: 1 , stiffness: 364.718677686 , damping: 35.2 ),
202+ child: Scaffold (
203+ body: ValueListenableBuilder <ApiResponse <T ?>?>(
204+ valueListenable: widget.notifier! ,
205+ builder: (_, response, __) => Stack (
206+ alignment: Alignment .center,
207+ children: [
208+ SafeArea (
209+ bottom: widget.safeAreaBottom,
210+ child: Scrollbar (
211+ controller: scrollController,
212+ thickness: widget.showScrollbar ? null : 0 ,
213+ child: SmartRefresher (
214+ controller: _refreshController,
215+ onRefresh: _onRefresh,
216+ onLoading: _onLoading,
217+ enablePullUp: widget.onLoading != null ,
218+ footer: CustomFooter (
219+ builder: (context, mode) {
220+ var loadText = '' ;
221+ switch (mode) {
222+ case LoadStatus .canLoading:
223+ loadText = 'Load more' ;
224+ case LoadStatus .idle:
225+ loadText = 'Idle' ;
226+ case LoadStatus .loading:
227+ loadText = 'Loading' ;
228+ case LoadStatus .noMore:
229+ case LoadStatus .failed:
230+ default :
231+ break ;
232+ }
233+ return SizedBox (
234+ height: 48 ,
235+ child: Center (child: Text (loadText)),
236+ );
237+ },
238+ ),
239+ child: CustomScrollView (
240+ controller: scrollController,
241+ slivers: [
242+ SliverAppBar (
243+ title: Text (widget.title),
244+ floating: true ,
245+ snap: true ,
246+ pinned: widget.fixedAppBar,
247+ actions: actions,
248+ surfaceTintColor: context.themeExtension.background,
249+ scrolledUnderElevation: 0 ,
250+ expandedHeight: 50 ,
251+ automaticallyImplyLeading: widget.showBackButton,
252+ bottom: widget.header == null
253+ ? null
254+ : _Header (
255+ child: Column (
256+ children: [
257+ const SizedBox (
258+ height: 10 ,
259+ ),
260+ widget.header !(),
261+ const SizedBox (
262+ height: 10 ,
263+ ),
264+ ],
265+ ),
260266 ),
261- ),
262- ),
263- if (widget.header == null )
264- SliverToBoxAdapter (
265- child: const SizedBox (
266- height: 20 ,
267- ),
268267 ),
269- if (response != null && response.isError)
270- SliverPadding (
271- padding: EdgeInsets .only (top: paddingTop),
272- sliver: SliverToBoxAdapter (
273- child: ErrorPage (
274- description: (response.errorResponse? .reasonPhrase? .isEmpty ?? true )
275- ? 'Something went wrong'
276- : response.errorResponse! .reasonPhrase! ,
277- onRetry: widget.init,
268+ if (widget.header == null )
269+ SliverToBoxAdapter (
270+ child: const SizedBox (
271+ height: 20 ,
272+ ),
273+ ),
274+ if (response != null && response.isError)
275+ SliverPadding (
276+ padding: EdgeInsets .only (top: paddingTop),
277+ sliver: SliverToBoxAdapter (
278+ child: ErrorPage (
279+ description: (response.errorResponse? .reasonPhrase? .isEmpty ?? true )
280+ ? 'Something went wrong'
281+ : response.errorResponse! .reasonPhrase! ,
282+ onRetry: widget.init,
283+ ),
278284 ),
285+ )
286+ else if (response != null &&
287+ widget.onEmpty != null &&
288+ (response.data is List ) &&
289+ (response.data as List ).isEmpty)
290+ SliverPadding (
291+ padding: EdgeInsets .only (top: paddingTop),
292+ sliver: SliverToBoxAdapter (
293+ child: EmptyPage (widget: widget, onRefresh: _onRefresh),
294+ ),
295+ )
296+ else if (response? .data != null )
297+ SliverPadding (
298+ padding: widget.padding ?? const EdgeInsets .symmetric (horizontal: 16 ),
299+ sliver: widget.sliverBuilder? .call (widget.notifier! .value! .data! ) ??
300+ SliverToBoxAdapter (child: widget.builder !(widget.notifier! .value! .data! )),
279301 ),
280- )
281- else if (response != null &&
282- widget.onEmpty != null &&
283- (response.data is List ) &&
284- (response.data as List ).isEmpty)
285- SliverPadding (
286- padding: EdgeInsets .only (top: paddingTop),
287- sliver: SliverToBoxAdapter (
288- child: EmptyPage (widget: widget, onRefresh: _onRefresh),
302+ SliverToBoxAdapter (
303+ child: const SizedBox (
304+ height: 40 ,
289305 ),
290- )
291- else if (response? .data != null )
292- SliverPadding (
293- padding: widget.padding ?? const EdgeInsets .symmetric (horizontal: 16 ),
294- sliver: widget.sliverBuilder? .call (widget.notifier! .value! .data! ) ??
295- SliverToBoxAdapter (child: widget.builder !(widget.notifier! .value! .data! )),
296306 ),
297- SliverToBoxAdapter (
298- child: const SizedBox (
299- height: 40 ,
300- ),
301- ),
302- ],
307+ ],
308+ ),
303309 ),
304310 ),
305311 ),
306- ),
307- if (response == null )
308- Padding (
309- padding : EdgeInsets . only (top : paddingTop ),
310- child : const CircularProgressIndicator ( ),
311- ) ,
312- ] ,
312+ if (response == null )
313+ Padding (
314+ padding : EdgeInsets . only (top : paddingTop),
315+ child : const CircularProgressIndicator ( ),
316+ ),
317+ ] ,
318+ ) ,
313319 ),
314320 ),
315321 );
0 commit comments