diff --git a/CHANGELOG.md b/CHANGELOG.md index 46cec32..300fdac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.0.2 + +- fix: freeze when you type just white space into the input field when categories are visible +- fix: infinite loading when you type just white space into emoji/stickers +- fix: cursor jumping to the end of the input if you type anywhere but the end + +[All Code Changes](https://github.com/Flyclops/tenor_flutter/compare/1.0.1...1.0.2) + ## 1.0.1 - chore: Add discontinued notice diff --git a/analysis_options.yaml b/analysis_options.yaml index b825346..db98472 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -7,3 +7,6 @@ analyzer: linter: rules: require_trailing_commas: true + +formatter: + trailing_commas: preserve \ No newline at end of file diff --git a/lib/src/components/search_field.dart b/lib/src/components/search_field.dart index 1da9c00..bc8047c 100644 --- a/lib/src/components/search_field.dart +++ b/lib/src/components/search_field.dart @@ -100,7 +100,8 @@ class _TenorSearchFieldState extends State { _appBarProvider.addListener(_listenerQuery); // Set Texfield Controller - _textEditingController = widget.searchFieldController ?? + _textEditingController = + widget.searchFieldController ?? TextEditingController( text: _appBarProvider.queryText, ); @@ -202,8 +203,7 @@ class _TenorSearchFieldState extends State { left: 4, child: Icon( Icons.search, - color: - widget.style.hintStyle.color ?? const Color(0xFF8A8A86), + color: widget.style.hintStyle.color ?? const Color(0xFF8A8A86), size: 22, ), ), @@ -218,8 +218,7 @@ class _TenorSearchFieldState extends State { padding: const EdgeInsets.all(8), child: Icon( Icons.clear, - color: widget.style.hintStyle.color ?? - const Color(0xFF8A8A86), + color: widget.style.hintStyle.color ?? const Color(0xFF8A8A86), size: 20, ), ), @@ -240,8 +239,7 @@ class _TenorSearchFieldState extends State { // when they focus the input, maximize viewing space _sheetProvider.scrollController.animateTo( _sheetProvider.maxExtent, - duration: - animationStyle?.duration ?? tenorDefaultAnimationStyle.duration!, + duration: animationStyle?.duration ?? tenorDefaultAnimationStyle.duration!, curve: animationStyle?.curve ?? Curves.linear, ); } @@ -249,6 +247,9 @@ class _TenorSearchFieldState extends State { // listener query void _listenerQuery() { + // Update only when it's different. IE you tap on a category. Otherwise the cursor will jump to the end. + if (_textEditingController.text == _appBarProvider.queryText) return; + _textEditingController.text = _appBarProvider.queryText; } } diff --git a/lib/src/components/tab_view.dart b/lib/src/components/tab_view.dart index 004324f..89ed167 100644 --- a/lib/src/components/tab_view.dart +++ b/lib/src/components/tab_view.dart @@ -31,7 +31,8 @@ class TenorTabView extends StatefulWidget { String? pos, int limit, TenorCategory? category, - )? onLoad; + )? + onLoad; final Function(TenorResult? gif)? onSelected; final bool showCategories; final TenorTabViewStyle style; @@ -48,8 +49,8 @@ class TenorTabView extends StatefulWidget { this.showCategories = false, this.style = const TenorTabViewStyle(), super.key, - }) : featuredCategory = featuredCategory ?? '📈 Featured', - gifsPerRow = gifsPerRow ?? 3; + }) : featuredCategory = featuredCategory ?? '📈 Featured', + gifsPerRow = gifsPerRow ?? 3; @override State createState() => _TenorTabViewState(); @@ -151,7 +152,7 @@ class _TenorTabViewState extends State ); } - if (_appBarProvider.queryText.isEmpty && + if (_appBarProvider.queryText.trim().isEmpty && _appBarProvider.selectedCategory == null && widget.showCategories) { return Padding( @@ -188,10 +189,10 @@ class _TenorTabViewState extends State // Add safe area padding if `TenorAttributionType.poweredBy` is disabled padding: _tabProvider.attributionType == TenorAttributionType.poweredBy - ? null + ? EdgeInsets.zero : EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom, - ), + bottom: MediaQuery.of(context).padding.bottom, + ), scrollDirection: _scrollDirection, ), ), @@ -206,24 +207,24 @@ class _TenorTabViewState extends State crossAxisCount: widget.gifsPerRow, crossAxisSpacing: 8, keyboardDismissBehavior: _appBarProvider.keyboardDismissBehavior, - itemBuilder: (ctx, idx) => ClipRRect( - borderRadius: BorderRadius.circular(8), - child: TenorSelectableGif( - backgroundColor: widget.style.mediaBackgroundColor, - onTap: (selectedResult) => _selectedGif( - selectedResult, + itemBuilder: + (ctx, idx) => ClipRRect( + borderRadius: BorderRadius.circular(8), + child: TenorSelectableGif( + backgroundColor: widget.style.mediaBackgroundColor, + onTap: (selectedResult) => _selectedGif(selectedResult), + result: _list[idx], + ), ), - result: _list[idx], - ), - ), itemCount: _list.length, mainAxisSpacing: 8, // Add safe area padding if `TenorAttributionType.poweredBy` is disabled - padding: _tabProvider.attributionType == TenorAttributionType.poweredBy - ? null - : EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom, - ), + padding: + _tabProvider.attributionType == TenorAttributionType.poweredBy + ? null + : EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), scrollDirection: _scrollDirection, ), ); @@ -332,7 +333,7 @@ class _TenorTabViewState extends State if (widget.onLoad != null) { final response = await widget.onLoad?.call( - _appBarProvider.queryText, + _appBarProvider.queryText.trim(), offset, requestLimit, _appBarProvider.selectedCategory, @@ -389,7 +390,8 @@ class _TenorTabViewState extends State // if you scroll within a threshhold of the bottom of the screen, load more gifs void _scrollControllerListener() { // trending-gifs, etc - final customCategorySelected = _appBarProvider.selectedCategory != null && + final customCategorySelected = + _appBarProvider.selectedCategory != null && _appBarProvider.queryText == ''; if (customCategorySelected || @@ -404,6 +406,12 @@ class _TenorTabViewState extends State // When the text in the search input changes void _appBarProviderListener() { + // Prevent searches with only spaces + if (_appBarProvider.queryText.isNotEmpty && + _appBarProvider.queryText.trim().isEmpty) { + return; + } + setState(() { _list = []; _collection = null; diff --git a/lib/src/providers/app_bar_provider.dart b/lib/src/providers/app_bar_provider.dart index 327ad19..b3bd8fa 100644 --- a/lib/src/providers/app_bar_provider.dart +++ b/lib/src/providers/app_bar_provider.dart @@ -25,8 +25,8 @@ class TenorAppBarProvider with ChangeNotifier { Duration debounce, { required this.keyboardDismissBehavior, TenorCategory? selectedCategory, - }) : _selectedCategory = selectedCategory, - super() { + }) : _selectedCategory = selectedCategory, + super() { _queryText = queryText; _debounce = debounce; } diff --git a/pubspec.yaml b/pubspec.yaml index 46a0a32..a66bb76 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: tenor_flutter -version: 1.0.1 +version: 1.0.2 description: An opinionated yet customizable Flutter package for searching and selecting from a list of GIFs/Stickers from the Tenor GIF search API. homepage: https://github.com/flyclops repository: https://github.com/flyclops/tenor_flutter