From 8e34d0d4798e97986afda2ad22c5dc029bab1b05 Mon Sep 17 00:00:00 2001 From: Rosa saepul nugraha Date: Wed, 29 Apr 2026 13:13:07 +0700 Subject: [PATCH] refactor: replace ClassicHeader with custom refresh header in multiple pages Co-authored-by: Copilot --- lib/app/core/widgets/layout/app_screen.dart | 99 ++++++++++++++++++- .../presentation/screen/berkas_page.dart | 1 - .../home/presentation/screen/home_page.dart | 1 - .../presentation/screen/profile_page.dart | 1 - 4 files changed, 98 insertions(+), 4 deletions(-) diff --git a/lib/app/core/widgets/layout/app_screen.dart b/lib/app/core/widgets/layout/app_screen.dart index c4b0283..8884e16 100644 --- a/lib/app/core/widgets/layout/app_screen.dart +++ b/lib/app/core/widgets/layout/app_screen.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -145,7 +147,7 @@ class AppScreen extends StatelessWidget { enablePullUp: enablePullUp, onRefresh: onRefresh, onLoading: onLoadMore, - header: refreshHeader, + header: refreshHeader ?? _buildDefaultRefreshHeader(), footer: refreshFooter, physics: physics, child: content, @@ -168,6 +170,101 @@ class AppScreen extends StatelessWidget { ); } + Widget _buildDefaultRefreshHeader() { + return CustomHeader( + builder: (context, mode) { + Widget child; + var icon = Icons.arrow_downward; + var text = 'Tarik untuk memuat'; + var color = Colors.black; + + if (mode == RefreshStatus.canRefresh) { + unawaited(HapticFeedback.lightImpact()); + } + + switch (mode) { + case null: + return const SizedBox(); + case RefreshStatus.idle: + icon = Icons.arrow_downward; + text = 'Tarik untuk memuat ulang'; + + case RefreshStatus.canRefresh: + icon = Icons.arrow_upward; + text = 'Lepas untuk memuat ulang'; + + case RefreshStatus.refreshing: + return SizedBox( + height: 60, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox( + width: 13, + height: 13, + child: CircularProgressIndicator( + strokeWidth: 1.5, + color: Colors.black, + ), + ), + const SizedBox(width: 10), + Text( + 'Sedang memuat halaman, mohon tunggu', + style: AppTextStyles.body, + ), + ], + ), + ); + + case RefreshStatus.completed: + icon = Icons.check_rounded; + text = 'Berhasil memperbaharui data'; + color = Colors.black; + + case RefreshStatus.failed: + icon = Icons.close_rounded; + text = 'Gagal memperbaharui data'; + color = Colors.black; + + case RefreshStatus.twoLevelOpening: + case RefreshStatus.twoLeveling: + case RefreshStatus.twoLevelClosing: + case RefreshStatus.canTwoLevel: + return const SizedBox(); + } + + child = Row( + key: ValueKey(text), + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(icon, size: 18, color: color), + const SizedBox(width: 8), + Text( + text, + style: AppTextStyles.body.copyWith(color: color), + ), + ], + ); + + return SizedBox( + height: 60, + child: Center( + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + transitionBuilder: (child, anim) { + return FadeTransition( + opacity: anim, + child: ScaleTransition(scale: anim, child: child), + ); + }, + child: child, + ), + ), + ); + }, + ); + } + Widget _buildBody(BuildContext context) { final content = backgroundWidgets == null ? _buildBodyContent(context) diff --git a/lib/modules/berkas/presentation/screen/berkas_page.dart b/lib/modules/berkas/presentation/screen/berkas_page.dart index fcbdaee..49ffe06 100644 --- a/lib/modules/berkas/presentation/screen/berkas_page.dart +++ b/lib/modules/berkas/presentation/screen/berkas_page.dart @@ -39,7 +39,6 @@ class _BerkasPageState extends State { refreshController: _refreshController, enablePullDown: true, onRefresh: _onRefresh, - refreshHeader: const ClassicHeader(), body: const SizedBox.shrink(), slivers: [ if (todayBerkas.isNotEmpty) diff --git a/lib/modules/home/presentation/screen/home_page.dart b/lib/modules/home/presentation/screen/home_page.dart index 4bc13ee..bec12a6 100644 --- a/lib/modules/home/presentation/screen/home_page.dart +++ b/lib/modules/home/presentation/screen/home_page.dart @@ -57,7 +57,6 @@ class _HomeUIState extends State { refreshController: _refreshController, enablePullDown: true, onRefresh: _onRefresh, - refreshHeader: const ClassicHeader(), body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/lib/modules/profile/presentation/screen/profile_page.dart b/lib/modules/profile/presentation/screen/profile_page.dart index f08c83f..7fe3722 100644 --- a/lib/modules/profile/presentation/screen/profile_page.dart +++ b/lib/modules/profile/presentation/screen/profile_page.dart @@ -70,7 +70,6 @@ class _ProfileUIState extends State { refreshController: _refreshController, enablePullDown: true, onRefresh: _onRefresh, - refreshHeader: const ClassicHeader(), body: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 900),