mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-27 04:56:48 +00:00
Scroll fix (#633)
* Fix scrolling behaviuor * Debounce paginated search
This commit is contained in:
parent
72a78291b2
commit
1d5377ea20
@ -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
|
||||
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
)
|
||||
|
@ -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,11 +376,34 @@ abstract class PaginatedSearchState<T extends PaginatedSearchWidget> extends Sta
|
||||
|
||||
// Callback function when the search term is updated
|
||||
void updateSearchTerm() {
|
||||
searchTerm = searchController.text;
|
||||
_pagingController.refresh();
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
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(() {});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(
|
||||
|
@ -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,
|
||||
)
|
||||
],
|
||||
)
|
||||
children: getTiles(context),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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);
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user