Skip to content

Commit

Permalink
Fix recent tab behavior (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fintasys authored May 31, 2023
1 parent c5f8e7e commit ca7a6b2
Show file tree
Hide file tree
Showing 15 changed files with 204 additions and 144 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.6.0
- Breaking Change: Fix behavior of recent tab, choose behavior (None, Recent, Popular) with `recentTabBehavior`. `showRecentsTab` was removed.
- Fix typo in ReadMe (thx @nathanbacon)

## 1.5.4
- Restore compatibility of older Flutter versions

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ EmojiPicker(
skinToneDialogBgColor: Colors.white,
skinToneIndicatorColor: Colors.grey,
enableSkinTones: true,
showRecentsTab: true,
recentTabBehavior: RecentTabBehavior.RECENT,
recentsLimit: 28,
noRecents: const Text(
'No Recents',
Expand Down Expand Up @@ -84,7 +84,7 @@ See the [demo](https://github.com/Fintasys/emoji_picker_flutter/blob/master/exam
| skinToneDialogBgColor | The background color of the skin tone dialog | Colors.white |
| skinToneIndicatorColor | Color of the small triangle next to multiple skin tone emoji | Colors.grey |
| enableSkinTones | Enable feature to select a skin tone of certain emoji's | true |
| showRecentsTab | Show extra tab with recently used emoji | true |
| recentTabBehavior | Show extra tab with recently / popular used emoji | RecentTabBehavior.RECENT |
| recentsLimit | Limit of recently used emoji that will be saved | 28 |
| replaceEmojiOnLimitExceed | Replace latest emoji on recents list on limit exceed | false
| noRecents | A widget (usually [Text]) to be displayed if no recent emojis to display. Needs to be `const` Widget! | Text('No Recents', style: TextStyle(fontSize: 20, color: Colors.black26), textAlign: TextAlign.center) |
Expand Down
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand Down
2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https://services.gradle.org/distributions/gradle-7.6-all.zip
2 changes: 1 addition & 1 deletion example/lib/main-custom-font.dart
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class _MyAppState extends State<MyApp> {
skinToneDialogBgColor: Colors.white,
skinToneIndicatorColor: Colors.grey,
enableSkinTones: false,
showRecentsTab: true,
recentTabBehavior: RecentTabBehavior.RECENT,
recentsLimit: 28,
replaceEmojiOnLimitExceed: false,
noRecents: const Text(
Expand Down
10 changes: 9 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ class _MyAppState extends State<MyApp> {
super.dispose();
}

_onBackspacePressed() {
_controller
..text = _controller.text.characters.toString()
..selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length));
}

@override
Widget build(BuildContext context) {
return MaterialApp(
Expand Down Expand Up @@ -93,6 +100,7 @@ class _MyAppState extends State<MyApp> {
height: 250,
child: EmojiPicker(
textEditingController: _controller,
onBackspacePressed: _onBackspacePressed,
config: Config(
columns: 7,
// Issue: https://github.com/flutter/flutter/issues/28894
Expand All @@ -113,7 +121,7 @@ class _MyAppState extends State<MyApp> {
skinToneDialogBgColor: Colors.white,
skinToneIndicatorColor: Colors.grey,
enableSkinTones: true,
showRecentsTab: true,
recentTabBehavior: RecentTabBehavior.RECENT,
recentsLimit: 28,
replaceEmojiOnLimitExceed: false,
noRecents: const Text(
Expand Down
6 changes: 3 additions & 3 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ packages:
path: ".."
relative: true
source: path
version: "1.5.3"
version: "1.6.0"
ffi:
dependency: transitive
description:
Expand All @@ -52,10 +52,10 @@ packages:
dependency: transitive
description:
name: file
sha256: "9fd2163d866769f60f4df8ac1dc59f52498d810c356fe78022e383dd3c57c0e1"
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.dev"
source: hosted
version: "6.1.0"
version: "6.1.4"
flutter:
dependency: "direct main"
description: flutter
Expand Down
1 change: 1 addition & 0 deletions lib/emoji_picker_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export 'package:emoji_picker_flutter/src/emoji_picker_utils.dart';
export 'package:emoji_picker_flutter/src/emoji_skin_tones.dart';
export 'package:emoji_picker_flutter/src/emoji_text_editing_controller.dart';
export 'package:emoji_picker_flutter/src/emoji_view_state.dart';
export 'package:emoji_picker_flutter/src/recent_tab_behavior.dart';
11 changes: 6 additions & 5 deletions lib/src/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:math';
import 'package:emoji_picker_flutter/src/category_emoji.dart';
import 'package:emoji_picker_flutter/src/category_icons.dart';
import 'package:emoji_picker_flutter/src/emoji_picker.dart';
import 'package:emoji_picker_flutter/src/recent_tab_behavior.dart';
import 'package:flutter/material.dart';

/// Default Widget if no recent is available
Expand Down Expand Up @@ -30,7 +31,7 @@ class Config {
this.skinToneDialogBgColor = Colors.white,
this.skinToneIndicatorColor = Colors.grey,
this.enableSkinTones = true,
this.showRecentsTab = true,
this.recentTabBehavior = RecentTabBehavior.RECENT,
this.recentsLimit = 28,
this.replaceEmojiOnLimitExceed = false,
this.noRecents = DefaultNoRecentsWidget,
Expand Down Expand Up @@ -84,8 +85,8 @@ class Config {
/// Enable feature to select a skin tone of certain emoji's
final bool enableSkinTones;

/// Show extra tab with recently used emoji
final bool showRecentsTab;
/// Behavior of Recent Tab (Recent, Popular)
final RecentTabBehavior recentTabBehavior;

/// Limit of recently used emoji that will be saved
final int recentsLimit;
Expand Down Expand Up @@ -173,7 +174,7 @@ class Config {
other.skinToneDialogBgColor == skinToneDialogBgColor &&
other.skinToneIndicatorColor == skinToneIndicatorColor &&
other.enableSkinTones == enableSkinTones &&
other.showRecentsTab == showRecentsTab &&
other.recentTabBehavior == recentTabBehavior &&
other.recentsLimit == recentsLimit &&
other.noRecents == noRecents &&
other.loadingIndicator == loadingIndicator &&
Expand Down Expand Up @@ -202,7 +203,7 @@ class Config {
skinToneDialogBgColor.hashCode ^
skinToneIndicatorColor.hashCode ^
enableSkinTones.hashCode ^
showRecentsTab.hashCode ^
recentTabBehavior.hashCode ^
recentsLimit.hashCode ^
noRecents.hashCode ^
loadingIndicator.hashCode ^
Expand Down
18 changes: 15 additions & 3 deletions lib/src/emoji_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import 'package:emoji_picker_flutter/src/emoji.dart';
import 'package:emoji_picker_flutter/src/emoji_picker_internal_utils.dart';
import 'package:emoji_picker_flutter/src/emoji_view_state.dart';
import 'package:emoji_picker_flutter/src/recent_emoji.dart';
import 'package:emoji_picker_flutter/src/recent_tab_behavior.dart';
import 'package:flutter/material.dart';

/// All the possible categories that [Emoji] can be put into
///
/// All [Category] are shown in the category bar
enum Category {
/// Recent emojis
/// Recent / Popular emojis
RECENT,

/// Smiley emojis
Expand Down Expand Up @@ -222,7 +223,17 @@ class EmojiPickerState extends State<EmojiPicker> {
// Add recent emoji handling to tap listener
OnEmojiSelected _getOnEmojiListener() {
return (category, emoji) {
if (widget.config.showRecentsTab) {
if (widget.config.recentTabBehavior == RecentTabBehavior.POPULAR) {
_emojiPickerInternalUtils
.addEmojiToPopularUsed(emoji: emoji, config: widget.config)
.then((newRecentEmoji) => {
// we don't want to rebuild the widget if user is currently on
// the RECENT tab, it will make emojis jump since sorting
// is based on the use frequency
updateRecentEmoji(newRecentEmoji,
refresh: category != Category.RECENT),
});
} else if (widget.config.recentTabBehavior == RecentTabBehavior.RECENT) {
_emojiPickerInternalUtils
.addEmojiToRecentlyUsed(emoji: emoji, config: widget.config)
.then((newRecentEmoji) => {
Expand Down Expand Up @@ -265,7 +276,8 @@ class EmojiPickerState extends State<EmojiPicker> {
// Initialize emoji data
Future<void> _updateEmojis() async {
_categoryEmoji.clear();
if (widget.config.showRecentsTab) {
if ([RecentTabBehavior.RECENT, RecentTabBehavior.POPULAR]
.contains(widget.config.recentTabBehavior)) {
_recentEmoji = await _emojiPickerInternalUtils.getRecentEmojis();
final recentEmojiMap = _recentEmoji.map((e) => e.emoji).toList();
_categoryEmoji.add(CategoryEmoji(Category.RECENT, recentEmojiMap));
Expand Down
33 changes: 32 additions & 1 deletion lib/src/emoji_picker_internal_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,45 @@ class EmojiPickerInternalUtils {
return json.map<RecentEmoji>(RecentEmoji.fromJson).toList();
}

/// Add an emoji to recently used list or increase its counter
/// Add an emoji to recently used list
Future<List<RecentEmoji>> addEmojiToRecentlyUsed(
{required Emoji emoji, Config config = const Config()}) async {
// Remove emoji's skin tone in Recent-Category
if (emoji.hasSkinTone) {
emoji = removeSkinTone(emoji);
}
var recentEmoji = await getRecentEmojis();
var recentEmojiIndex =
recentEmoji.indexWhere((element) => element.emoji.emoji == emoji.emoji);
if (recentEmojiIndex != -1) {
// Already exist in recent list
// Remove it
recentEmoji.removeAt(recentEmojiIndex);
}
// Add it first position
recentEmoji.insert(0, RecentEmoji(emoji, 0));

// Limit entries to recentsLimit
if (recentEmoji.length == config.recentsLimit &&
config.replaceEmojiOnLimitExceed) {
recentEmoji =
recentEmoji.sublist(0, min(config.recentsLimit, recentEmoji.length));
}
// save locally
final prefs = await SharedPreferences.getInstance();
prefs.setString('recent', jsonEncode(recentEmoji));

return recentEmoji;
}

/// Add an emoji to popular used list or increase its counter
Future<List<RecentEmoji>> addEmojiToPopularUsed(
{required Emoji emoji, Config config = const Config()}) async {
// Remove emoji's skin tone in Recent-Category
if (emoji.hasSkinTone) {
emoji = removeSkinTone(emoji);
}
var recentEmoji = await getRecentEmojis();
var recentEmojiIndex =
recentEmoji.indexWhere((element) => element.emoji.emoji == emoji.emoji);
if (recentEmojiIndex != -1) {
Expand Down
11 changes: 11 additions & 0 deletions lib/src/recent_tab_behavior.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/// Behavior of Recent Tab
enum RecentTabBehavior {
/// Don't show Recent Tab
NONE,

/// Display the last used emoji at the top of the list
RECENT,

/// Display the most often used emoji at the top of the list
POPULAR,
}
Loading

0 comments on commit ca7a6b2

Please sign in to comment.