2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-27 21:16:48 +00:00

Scroll fix (#633)

* Fix scrolling behaviuor

* Debounce paginated search
This commit is contained in:
Oliver 2025-04-15 23:42:48 +10:00 committed by GitHub
parent 72a78291b2
commit 1d5377ea20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 32 deletions

View File

@ -6,6 +6,7 @@
- Support "extra line items" for sales orders
- Display start date for purchase orders
- Display start date for sales orders
- Fix scrolling behaviour for some widgets
- Updated search functionality
- Updated translations

View File

@ -60,7 +60,9 @@ class _AttachmentWidgetState extends RefreshableState<AttachmentWidget> {
prefix: widget.imagePrefix,
);
FilePickerDialog.pickImageFromCamera().then((File? file) {
upload(context, file);
upload(context, file).then((_) {
refresh(context);
});
});
}
),
@ -68,7 +70,9 @@ class _AttachmentWidgetState extends RefreshableState<AttachmentWidget> {
icon: Icon(TablerIcons.file_upload),
onPressed: () async {
FilePickerDialog.pickFileFromDevice().then((File? file) {
upload(context, file);
upload(context, file).then((_) {
refresh(context);
});
});
}
)

View File

@ -1,3 +1,5 @@
import "dart:async";
import "package:flutter/material.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
@ -254,6 +256,9 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
// Text controller
final TextEditingController searchController = TextEditingController();
// Debounce timer
Timer? _debounceTimer;
// Pagination controller
final PagingController<int, InvenTreeModel> _pagingController = PagingController(firstPageKey: 0);
@ -307,6 +312,9 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
}
params["search"] = "${_search}";
} else {
// Remove search term if it is empty
params.remove("search");
}
// Use custom query ordering if available
@ -368,12 +376,35 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
// Callback function when the search term is updated
void updateSearchTerm() {
if (searchTerm == searchController.text) {
// No change
return;
}
// Debounce the search term
if (_debounceTimer?.isActive ?? false) {
_debounceTimer?.cancel();
}
if (searchController.text.isEmpty) {
// An empty search term evaluates immediately
searchTerm = "";
_pagingController.refresh();
if (mounted) {
setState(() {});
}
} else {
_debounceTimer = Timer(const Duration(milliseconds: 500), () {
searchTerm = searchController.text;
_pagingController.refresh();
if (mounted) {
setState(() {});
}
});
}
}
// Function to construct a single paginated item
@ -465,12 +496,12 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
icon: Icon(showSearchWidget ? Icons.zoom_out : Icons.search, size: icon_size)
));
_icons.add(IconButton(
onPressed: () async {
updateSearchTerm();
},
icon: Icon(Icons.refresh, size: icon_size),
));
// _icons.add(IconButton(
// onPressed: () async {
// updateSearchTerm();
// },
// icon: Icon(Icons.refresh, size: icon_size),
// ));
return ListTile(
title: Text(

View File

@ -39,21 +39,14 @@ mixin BaseWidgetProperties {
// Function to construct a body
Widget getBody(BuildContext context) {
// Default body calls getTiles()
return SingleChildScrollView(
// Default implementation is to return a ListView
// Override getTiles to replace the internal context
return ListView(
physics: AlwaysScrollableScrollPhysics(),
child: Column(
children: [
ListView(
children: getTiles(context),
shrinkWrap: true,
)
],
)
);
}
/*
* Construct the top AppBar for this view
*/
@ -274,14 +267,6 @@ abstract class RefreshableState<T extends StatefulWidget> extends State<T> with
Widget body = tabs.isEmpty ? getBody(context) : TabBarView(children: getTabs(context));
// predicateDepth needs to be different based on the child type
// hack, determined experimentally
int predicateDepth = 0;
if (tabs.isNotEmpty) {
predicateDepth = 1;
}
Scaffold view = Scaffold(
key: scaffoldKey,
appBar: buildAppBar(context, scaffoldKey),
@ -291,8 +276,9 @@ abstract class RefreshableState<T extends StatefulWidget> extends State<T> with
body: RefreshIndicator(
key: refreshKey,
notificationPredicate: (ScrollNotification notification) {
return notification.depth == predicateDepth;
return true;
},
onRefresh: () async {
refresh(context);
},