fix: improve history page performance and state management (#47)
Some checks failed
/ build-stealth (push) Waiting to run
/ mirror (push) Waiting to run
/ build (push) Has been cancelled

smooth switch to history page

Co-authored-by: AlexisDanlos <91090088+AlexisDanlos@users.noreply.github.com>
Co-authored-by: stcb <21@stcb.cc>
Reviewed-on: #47
Co-authored-by: alexis <alexis.danlos@epitech.eu>
Co-committed-by: alexis <alexis.danlos@epitech.eu>
This commit is contained in:
alexis 2025-04-05 08:27:20 +00:00 committed by stcb
parent 37349fdc13
commit 608218175a
2 changed files with 12 additions and 6 deletions

View File

@ -37,7 +37,7 @@ class HistoryPage extends StatefulWidget {
} }
class _HistoryPageState extends State<HistoryPage> class _HistoryPageState extends State<HistoryPage>
with SingleTickerProviderStateMixin { with AutomaticKeepAliveClientMixin, SingleTickerProviderStateMixin {
List<History> histories = []; List<History> histories = [];
bool loading = true; bool loading = true;
int? _expandedIndex; int? _expandedIndex;
@ -47,10 +47,13 @@ class _HistoryPageState extends State<HistoryPage>
// Create a MethodChannel instance. // Create a MethodChannel instance.
static const MethodChannel _channel = MethodChannel('com.example.calllog'); static const MethodChannel _channel = MethodChannel('com.example.calllog');
@override
bool get wantKeepAlive => true; // Preserve state when switching pages
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
if (loading) { if (loading && histories.isEmpty) {
_buildHistories(); _buildHistories();
} }
} }
@ -149,9 +152,9 @@ class _HistoryPageState extends State<HistoryPage>
List<Contact> contacts = contactState.contacts; List<Contact> contacts = contactState.contacts;
List<History> callHistories = []; List<History> callHistories = [];
// Process each log entry. // Process each log entry with intermittent yields to avoid freezing.
for (var entry in nativeLogs) { for (int i = 0; i < nativeLogs.length; i++) {
// Each entry is a Map with keys: number, type, date, duration. final entry = nativeLogs[i];
final String number = entry['number'] ?? ''; final String number = entry['number'] ?? '';
if (number.isEmpty) continue; if (number.isEmpty) continue;
@ -197,6 +200,8 @@ class _HistoryPageState extends State<HistoryPage>
callHistories callHistories
.add(History(matchedContact, callDate, callType, callStatus, 1)); .add(History(matchedContact, callDate, callType, callStatus, 1));
// Yield every 10 iterations to avoid blocking the UI.
if (i % 10 == 0) await Future.delayed(Duration(milliseconds: 1));
} }
// Sort histories by most recent. // Sort histories by most recent.
@ -272,6 +277,7 @@ class _HistoryPageState extends State<HistoryPage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); // required due to AutomaticKeepAliveClientMixin
final contactState = ContactState.of(context); final contactState = ContactState.of(context);
if (loading || contactState.loading) { if (loading || contactState.loading) {

View File

@ -25,7 +25,7 @@ class _MyHomePageState extends State<MyHomePage>
void initState() { void initState() {
super.initState(); super.initState();
// Set the TabController length to 4 // Set the TabController length to 4
_tabController = TabController(length: 4, vsync: this, initialIndex: 1); _tabController = TabController(length: 4, vsync: this, initialIndex: 2);
_tabController.addListener(_handleTabIndex); _tabController.addListener(_handleTabIndex);
_fetchContacts(); _fetchContacts();
} }