From 1f608042283eb1029689c92bd4416254d430a9a2 Mon Sep 17 00:00:00 2001 From: Abdelouahed Date: Fri, 5 Mar 2021 12:19:25 +0100 Subject: [PATCH 001/136] deprecated scaffold --- example/.flutter-plugins-dependencies | 1 - .../ios/Flutter/flutter_export_environment.sh | 2 - example/lib/items/comments.dart | 17 +- example/lib/items/item.dart | 3 +- example/lib/main.dart | 2 +- example/lib/models/comment.dart | 5 +- example/pubspec.lock | 241 ++---------------- example/pubspec.yaml | 2 - pubspec.lock | 38 +-- 9 files changed, 50 insertions(+), 261 deletions(-) delete mode 100644 example/.flutter-plugins-dependencies diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies deleted file mode 100644 index 35fadf0..0000000 --- a/example/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"C:\\\\Users\\\\Lenovo\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.18\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Lenovo\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.3.1+1\\\\","dependencies":[]}],"android":[{"name":"path_provider","path":"C:\\\\Users\\\\Lenovo\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-1.6.18\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Lenovo\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.3.1+1\\\\","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"C:\\\\Users\\\\Lenovo\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_macos-0.0.4+4\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\Lenovo\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.3.1+1\\\\","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\Lenovo\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_linux-0.0.1+2\\\\","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\Lenovo\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_windows-0.0.4+1\\\\","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2021-02-12 11:21:18.662164","version":"1.22.0-12.3.pre"} \ No newline at end of file diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index e1b7122..86c128c 100644 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -5,8 +5,6 @@ export "FLUTTER_APPLICATION_PATH=C:\Users\Lenovo\VsProjects\flutter_reaction_but export "FLUTTER_TARGET=lib\main.dart" export "FLUTTER_BUILD_DIR=build" export "SYMROOT=${SOURCE_ROOT}/../build\ios" -export "OTHER_LDFLAGS=$(inherited) -framework Flutter" -export "FLUTTER_FRAMEWORK_DIR=C:\flutter\bin\cache\artifacts\engine\ios" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" export "DART_OBFUSCATION=false" diff --git a/example/lib/items/comments.dart b/example/lib/items/comments.dart index c733457..dff603f 100644 --- a/example/lib/items/comments.dart +++ b/example/lib/items/comments.dart @@ -1,4 +1,3 @@ -import 'package:avataaar_image/avataaar_image.dart'; import 'package:flutter/material.dart'; import '../models/comment.dart'; @@ -31,7 +30,6 @@ class _CommentsState extends State { if (_textEditingController.text.isEmpty) return; setState(() { final comment = Comment( - avatar: Avataaar.random(), name: 'Person ${widget.comments.length}', content: _textEditingController.text, ); @@ -68,7 +66,7 @@ class _CommentsState extends State { ], ); - Widget buildComment(comment) => SizedBox( + Widget buildComment(Comment comment) => SizedBox( height: 75, child: Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -78,16 +76,9 @@ class _CommentsState extends State { width: 40, child: CircleAvatar( radius: 100, - child: AvataaarImage( - avatar: comment.avatar, - errorImage: CircleAvatar( - backgroundColor: Colors.grey[200], - radius: 100, - ), - placeholder: CircleAvatar( - backgroundColor: Colors.grey[200], - radius: 100, - ), + child: CircleAvatar( + child: + Text(comment.name?.substring(0, 1)?.toUpperCase() ?? ' '), ), ), ), diff --git a/example/lib/items/item.dart b/example/lib/items/item.dart index b54f011..400bb4a 100644 --- a/example/lib/items/item.dart +++ b/example/lib/items/item.dart @@ -89,7 +89,8 @@ class _ItemState extends State with AutomaticKeepAliveClientMixin { ), ), InkWell( - onTap: () => Scaffold.of(context).showSnackBar(SnackBar( + onTap: () => + ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 2), content: Text( 'Share image ${widget.title}', diff --git a/example/lib/main.dart b/example/lib/main.dart index 650590c..b0e0827 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -24,7 +24,7 @@ class _MyAppState extends State { Builder( builder: (ctx) => FlutterReactionButton( onReactionChanged: (reaction, index) { - Scaffold.of(ctx).showSnackBar( + ScaffoldMessenger.of(ctx).showSnackBar( SnackBar( content: Text('reaction selected index: $index'), ), diff --git a/example/lib/models/comment.dart b/example/lib/models/comment.dart index 6135a5f..3b7936c 100644 --- a/example/lib/models/comment.dart +++ b/example/lib/models/comment.dart @@ -1,9 +1,8 @@ -import 'package:avataaar_image/avataaar_image.dart'; +import 'package:meta/meta.dart'; class Comment { - final Avataaar avatar; final String name; final String content; - const Comment({this.avatar, this.name, this.content}); + const Comment({@required this.name, @required this.content}); } diff --git a/example/pubspec.lock b/example/pubspec.lock index 9f1c34e..cae86e2 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,70 +7,42 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.1" - avataaar_image: - dependency: "direct main" - description: - name: avataaar_image - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.8" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" - cached_network_image: - dependency: transitive - description: - name: cached_network_image - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.2+1" + version: "2.1.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.3" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.5" + version: "1.15.0" cupertino_icons: dependency: "direct main" description: @@ -84,171 +56,45 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.1" + version: "1.2.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.2" flutter_reaction_button: dependency: "direct main" description: - path: ".." - relative: true - source: path + name: flutter_reaction_button + url: "https://pub.dartlang.org" + source: hosted version: "1.0.7+3" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.4" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.1" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" - octo_image: - dependency: transitive - description: - name: octo_image - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.0" + version: "1.3.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.1" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.18" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+2" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+4" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+1" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.2" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.13" - rxdart: - dependency: transitive - description: - name: rxdart - url: "https://pub.dartlang.org" - source: hosted - version: "0.24.1" + version: "1.8.0" sky_engine: dependency: transitive description: flutter @@ -260,98 +106,55 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.2" - sqflite: - dependency: transitive - description: - name: sqflite - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1+1" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2+1" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0+2" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.2" + version: "0.2.19" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.3" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2" + version: "2.1.0" sdks: - dart: ">=2.10.0-110 <2.11.0" - flutter: ">=1.20.0 <2.0.0" + dart: ">=2.12.0-0.0 <3.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index a00aa6f..cc07800 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -23,9 +23,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 - avataaar_image: ^1.0.6 flutter_reaction_button: - path: ../ dev_dependencies: flutter_test: diff --git a/pubspec.lock b/pubspec.lock index b308ac3..19b13d0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,49 +7,49 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.1" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.3" + version: "1.15.0" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -66,21 +66,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.1" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.1" + version: "1.8.0" sky_engine: dependency: transitive description: flutter @@ -92,55 +92,55 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.2" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.2" + version: "0.2.19" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0" sdks: - dart: ">=2.10.0-110 <2.11.0" + dart: ">=2.12.0-0.0 <3.0.0" From 76630e26aece41ef5fd78ee96f40ea4eaa4222fc Mon Sep 17 00:00:00 2001 From: Abdelouahed Date: Tue, 16 Mar 2021 20:07:30 +0100 Subject: [PATCH 002/136] support null safety --- .gitignore | 3 ++ .vscode/settings.json | 3 ++ CHANGELOG.md | 6 ++- example/.gitignore | 3 ++ example/android/.gitignore | 11 ++++++ .../example/MainActivity.kt | 6 +++ example/ios/.gitignore | 32 +++++++++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 ++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 ++++ example/lib/data/example_data.dart | 2 +- example/lib/items/comments.dart | 13 ++---- example/lib/main.dart | 2 +- example/lib/models/comment.dart | 4 +- example/pubspec.lock | 10 ++--- example/pubspec.yaml | 4 +- example/web/favicon.png | Bin 0 -> 917 bytes example/web/icons/Icon-192.png | Bin 0 -> 5292 bytes example/web/icons/Icon-512.png | Bin 0 -> 8252 bytes example/web/index.html | 33 ++++++++++++++++ example/web/manifest.json | 23 +++++++++++ lib/src/extensions.dart | 4 +- lib/src/flutter_reaction_button.dart | 19 +++++---- lib/src/flutter_reaction_button_check.dart | 37 +++++++++--------- lib/src/reaction.dart | 15 ++++--- lib/src/reactions_box.dart | 26 ++++++------ lib/src/reactions_box_item.dart | 30 +++++++------- pubspec.lock | 2 +- pubspec.yaml | 4 +- 30 files changed, 231 insertions(+), 93 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 example/android/.gitignore create mode 100644 example/android/app/src/main/kotlin/abdelouahedmedjoudja/example/MainActivity.kt create mode 100644 example/ios/.gitignore create mode 100644 example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 example/web/favicon.png create mode 100644 example/web/icons/Icon-192.png create mode 100644 example/web/icons/Icon-512.png create mode 100644 example/web/index.html create mode 100644 example/web/manifest.json diff --git a/.gitignore b/.gitignore index 8921a0c..75b9a03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +#Flutter versions manager +.fvm/ + ./idea ./vscode diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a66e62 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "dart.flutterSdkPath": "C:\\Users\\Lenovo\\fvm\\versions\\stable" +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e7f25df..d56486e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,4 +71,8 @@ ## 1.0.7+3 -* Deprecated Reaction id \ No newline at end of file +* Deprecated Reaction id + +## 1.0.8 + +* Added support null safety \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore index ac4a906..32d0148 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -1,3 +1,6 @@ +#Flutter versions manager +.fvm/ + # Miscellaneous *.class *.log diff --git a/example/android/.gitignore b/example/android/.gitignore new file mode 100644 index 0000000..0a741cb --- /dev/null +++ b/example/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/example/android/app/src/main/kotlin/abdelouahedmedjoudja/example/MainActivity.kt b/example/android/app/src/main/kotlin/abdelouahedmedjoudja/example/MainActivity.kt new file mode 100644 index 0000000..950a7d2 --- /dev/null +++ b/example/android/app/src/main/kotlin/abdelouahedmedjoudja/example/MainActivity.kt @@ -0,0 +1,6 @@ +package abdelouahedmedjoudja.example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/example/ios/.gitignore b/example/ios/.gitignore new file mode 100644 index 0000000..e96ef60 --- /dev/null +++ b/example/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/lib/data/example_data.dart b/example/lib/data/example_data.dart index 1cfe1cf..b2e845e 100644 --- a/example/lib/data/example_data.dart +++ b/example/lib/data/example_data.dart @@ -1,7 +1,7 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_reaction_button/flutter_reaction_button.dart'; + List flagsReactions = [ Reaction( previewIcon: _builFlagsdPreviewIcon( diff --git a/example/lib/items/comments.dart b/example/lib/items/comments.dart index dff603f..010fcab 100644 --- a/example/lib/items/comments.dart +++ b/example/lib/items/comments.dart @@ -12,13 +12,7 @@ class Comments extends StatefulWidget { } class _CommentsState extends State { - TextEditingController _textEditingController; - - @override - void initState() { - super.initState(); - _textEditingController = TextEditingController(); - } + TextEditingController _textEditingController = TextEditingController(); @override void dispose() { @@ -77,8 +71,7 @@ class _CommentsState extends State { child: CircleAvatar( radius: 100, child: CircleAvatar( - child: - Text(comment.name?.substring(0, 1)?.toUpperCase() ?? ' '), + child: Text(comment.name.substring(0, 1).toUpperCase()), ), ), ), @@ -129,7 +122,7 @@ class _CommentsState extends State { Widget buildCommentField() => Container( margin: const EdgeInsets.all(10), decoration: BoxDecoration( - color: Colors.grey[300].withOpacity(.5), + color: Colors.grey[300]?.withOpacity(.5), borderRadius: BorderRadius.circular(30), ), child: TextFormField( diff --git a/example/lib/main.dart b/example/lib/main.dart index b0e0827..a4ed672 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_reaction_button/flutter_reaction_button.dart'; -import 'data/example_data.dart' as Example; +import 'data/example_data.dart' as Example; import 'items/item.dart'; void main() => runApp(MyApp()); diff --git a/example/lib/models/comment.dart b/example/lib/models/comment.dart index 3b7936c..1b418df 100644 --- a/example/lib/models/comment.dart +++ b/example/lib/models/comment.dart @@ -1,8 +1,6 @@ -import 'package:meta/meta.dart'; - class Comment { final String name; final String content; - const Comment({@required this.name, @required this.content}); + const Comment({required this.name, required this.content}); } diff --git a/example/pubspec.lock b/example/pubspec.lock index cae86e2..2f676ae 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -65,10 +65,10 @@ packages: flutter_reaction_button: dependency: "direct main" description: - name: flutter_reaction_button - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.7+3" + path: ".." + relative: true + source: path + version: "1.0.7+4" flutter_test: dependency: "direct dev" description: flutter @@ -157,4 +157,4 @@ packages: source: hosted version: "2.1.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index cc07800..057fac6 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,5 +1,6 @@ name: flutter_reaction_button_test description: A new Flutter application. +publish_to: none # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -14,7 +15,7 @@ description: A new Flutter application. version: 1.0.0+1 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: @@ -24,6 +25,7 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 flutter_reaction_button: + path: ../ dev_dependencies: flutter_test: diff --git a/example/web/favicon.png b/example/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/example/web/icons/Icon-192.png b/example/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/example/web/icons/Icon-512.png b/example/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/example/web/index.html b/example/web/index.html new file mode 100644 index 0000000..a0c1460 --- /dev/null +++ b/example/web/index.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + example + + + + + + + + diff --git a/example/web/manifest.json b/example/web/manifest.json new file mode 100644 index 0000000..8c01291 --- /dev/null +++ b/example/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/lib/src/extensions.dart b/lib/src/extensions.dart index c583810..4d005fd 100644 --- a/lib/src/extensions.dart +++ b/lib/src/extensions.dart @@ -2,12 +2,12 @@ import 'package:flutter/widgets.dart'; extension KeyExtensions on GlobalKey { Offset get buttonOffset { - final RenderBox containerRenderBox = this.currentContext.findRenderObject(); + final RenderBox containerRenderBox = this.currentContext!.findRenderObject() as RenderBox; return containerRenderBox.localToGlobal(Offset.zero); } Size get buttonSize { - final RenderBox containerRenderBox = this.currentContext.findRenderObject(); + final RenderBox containerRenderBox = this.currentContext!.findRenderObject() as RenderBox; return containerRenderBox.size; } } diff --git a/lib/src/flutter_reaction_button.dart b/lib/src/flutter_reaction_button.dart index adcea75..523dae6 100644 --- a/lib/src/flutter_reaction_button.dart +++ b/lib/src/flutter_reaction_button.dart @@ -12,13 +12,13 @@ class FlutterReactionButton extends StatefulWidget { final OnFlutterReactionButtonChanged onReactionChanged; /// Default reaction button widget - final Reaction initialReaction; + final Reaction? initialReaction; final List reactions; - final Color highlightColor; + final Color? highlightColor; - final Color splashColor; + final Color? splashColor; /// Position reactions box for the button [default = TOP] final Position boxPosition; @@ -46,9 +46,9 @@ class FlutterReactionButton extends StatefulWidget { final double boxItemsSpacing; FlutterReactionButton({ - Key key, - @required this.onReactionChanged, - @required this.reactions, + Key? key, + required this.onReactionChanged, + required this.reactions, this.initialReaction, this.highlightColor, this.splashColor, @@ -61,8 +61,7 @@ class FlutterReactionButton extends StatefulWidget { this.shouldChangeReaction = true, this.boxPadding = const EdgeInsets.all(0), this.boxItemsSpacing = 0, - }) : assert(reactions != null), - super(key: key); + }) : super(key: key); @override _FlutterReactionButtonState createState() => _FlutterReactionButtonState(); @@ -71,7 +70,7 @@ class FlutterReactionButton extends StatefulWidget { class _FlutterReactionButtonState extends State { final GlobalKey _buttonKey = GlobalKey(); - Reaction _selectedReaction; + Reaction? _selectedReaction; void _init() { _selectedReaction = widget.initialReaction; @@ -127,7 +126,7 @@ class _FlutterReactionButtonState extends State { } void _updateReaction(Reaction reaction) { - widget.onReactionChanged?.call( + widget.onReactionChanged.call( reaction, widget.reactions.indexOf(reaction), ); diff --git a/lib/src/flutter_reaction_button_check.dart b/lib/src/flutter_reaction_button_check.dart index 214ff1f..53882a1 100644 --- a/lib/src/flutter_reaction_button_check.dart +++ b/lib/src/flutter_reaction_button_check.dart @@ -7,23 +7,23 @@ import 'reactions_box.dart'; import 'reaction.dart'; import 'extensions.dart'; -typedef FlutterReactionButtonCheckChanged = void Function(Reaction, int, bool); +typedef FlutterReactionButtonCheckChanged = void Function(Reaction?, int, bool); class FlutterReactionButtonCheck extends StatefulWidget { /// This triggers when reaction button value changed. final FlutterReactionButtonCheckChanged onReactionChanged; /// Default reaction button widget if [isChecked == false] - final Reaction initialReaction; + final Reaction? initialReaction; /// Default reaction button widget if [isChecked == true] - final Reaction selectedReaction; + final Reaction? selectedReaction; - final List reactions; + final List reactions; - final Color highlightColor; + final Color? highlightColor; - final Color splashColor; + final Color? splashColor; /// Position reactions box for the button [default = TOP] final Position boxPosition; @@ -52,9 +52,9 @@ class FlutterReactionButtonCheck extends StatefulWidget { final double boxItemsSpacing; FlutterReactionButtonCheck({ - Key key, - @required this.onReactionChanged, - @required this.reactions, + Key? key, + required this.onReactionChanged, + required this.reactions, this.initialReaction, this.selectedReaction, this.highlightColor, @@ -68,8 +68,7 @@ class FlutterReactionButtonCheck extends StatefulWidget { this.isChecked = false, this.boxPadding = const EdgeInsets.all(0), this.boxItemsSpacing = 0, - }) : assert(reactions != null), - super(key: key); + }) : super(key: key); @override _FlutterReactionButtonCheckState createState() => @@ -82,9 +81,9 @@ class _FlutterReactionButtonCheckState final int _maxTick = 2; - Timer _timer; + Timer? _timer; - Reaction _selectedReaction; + Reaction? _selectedReaction; bool _isChecked = false; @@ -117,16 +116,15 @@ class _FlutterReactionButtonCheckState onLongPress: () { _onTapReactionButton(context); }, - child: (_selectedReaction ?? widget.reactions[0]).icon, + child: (_selectedReaction ?? widget.reactions[0])!.icon, ); void _onTapReactionButton(BuildContext context) { _timer = Timer.periodic(Duration(milliseconds: 100), (timer) { - if (_timer.tick >= _maxTick) { + if (_timer!.tick >= _maxTick) { _showReactionButtons(context); - _timer.cancel(); + _timer!.cancel(); } - return _timer; }); } @@ -167,10 +165,11 @@ class _FlutterReactionButtonCheckState if (reactionButton != null) _updateReaction(reactionButton, true); } - void _updateReaction(Reaction reaction, [bool isSelectedFromDialog = false]) { + void _updateReaction(Reaction? reaction, + [bool isSelectedFromDialog = false]) { _isChecked = isSelectedFromDialog ? true : reaction != widget.initialReaction; - widget.onReactionChanged?.call( + widget.onReactionChanged.call( reaction, widget.reactions.indexOf(reaction), _isChecked, diff --git a/lib/src/reaction.dart b/lib/src/reaction.dart index 7bad7ec..b437d7b 100644 --- a/lib/src/reaction.dart +++ b/lib/src/reaction.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; class Reaction { @deprecated - final int id; + final int? id; /// Widget showing as button after selecting preview Icon from box appear. final Widget icon; @@ -15,27 +15,26 @@ class Reaction { /// Widget that describes the action that will occur when the button is pressed. /// ///This widget is displayed when the user hover on the button. - final Widget title; + final Widget? title; final bool enabled; Reaction({ this.id, - @required this.icon, - Widget previewIcon, + required this.icon, + Widget? previewIcon, this.title, this.enabled = true, - }) : this.previewIcon = previewIcon ?? icon, - assert(icon != null); + }) : this.previewIcon = previewIcon ?? icon; @override - bool operator ==(Object object) => + bool operator ==(Object? object) => object != null && object is Reaction && icon == object.icon && icon.key == object.icon.key && previewIcon == object.previewIcon && - previewIcon?.key == object.previewIcon?.key && + previewIcon.key == object.previewIcon.key && title == object.title && title?.key == object.title?.key; diff --git a/lib/src/reactions_box.dart b/lib/src/reactions_box.dart index 0a85006..e02a6a4 100644 --- a/lib/src/reactions_box.dart +++ b/lib/src/reactions_box.dart @@ -10,7 +10,7 @@ class ReactionsBox extends StatefulWidget { final Size buttonSize; - final List reactions; + final List reactions; final Position position; @@ -22,9 +22,9 @@ class ReactionsBox extends StatefulWidget { final Duration duration; - final Color highlightColor; + final Color? highlightColor; - final Color splashColor; + final Color? splashColor; final AlignmentGeometry alignment; @@ -33,10 +33,11 @@ class ReactionsBox extends StatefulWidget { final double boxItemsSpacing; const ReactionsBox({ - @required this.buttonOffset, - @required this.buttonSize, - @required this.reactions, - @required this.position, + Key? key, + required this.buttonOffset, + required this.buttonSize, + required this.reactions, + required this.position, this.color = Colors.white, this.elevation = 5, this.radius = 50, @@ -46,10 +47,7 @@ class ReactionsBox extends StatefulWidget { this.alignment = Alignment.center, this.boxPadding = const EdgeInsets.all(0), this.boxItemsSpacing = 0, - }) : assert(buttonOffset != null), - assert(buttonSize != null), - assert(reactions != null), - assert(position != null); + }) : super(key: key); @override _ReactionsBoxState createState() => _ReactionsBoxState(); @@ -57,13 +55,13 @@ class ReactionsBox extends StatefulWidget { class _ReactionsBoxState extends State with TickerProviderStateMixin { - AnimationController _scaleController; + late AnimationController _scaleController; - Animation _scaleAnimation; + late Animation _scaleAnimation; double _scale = 0; - Reaction _selectedReaction; + Reaction? _selectedReaction; @override void initState() { diff --git a/lib/src/reactions_box_item.dart b/lib/src/reactions_box_item.dart index 220c2cb..a110dae 100644 --- a/lib/src/reactions_box_item.dart +++ b/lib/src/reactions_box_item.dart @@ -3,18 +3,18 @@ import 'package:flutter/material.dart'; import 'reaction.dart'; class ReactionsBoxItem extends StatefulWidget { - final Function(Reaction) onReactionClick; + final Function(Reaction?) onReactionClick; - final Reaction reaction; + final Reaction? reaction; - final Color highlightColor; + final Color? highlightColor; - final Color splashColor; + final Color? splashColor; const ReactionsBoxItem({ - Key key, - @required this.reaction, - @required this.onReactionClick, + Key? key, + required this.reaction, + required this.onReactionClick, this.highlightColor, this.splashColor, }) : super(key: key); @@ -25,16 +25,16 @@ class ReactionsBoxItem extends StatefulWidget { class _ReactionsBoxItemState extends State with TickerProviderStateMixin { - AnimationController _scaleController; + late AnimationController _scaleController; - Animation _scaleAnimation; + late Animation _scaleAnimation; double _scale = 1; - OverlayEntry _overlayEntry; + OverlayEntry? _overlayEntry; OverlayEntry _createTitle() { - RenderBox renderBox = context.findRenderObject(); + RenderBox renderBox = context.findRenderObject() as RenderBox; final size = renderBox.size; final offset = renderBox.localToGlobal(Offset.zero); @@ -45,7 +45,7 @@ class _ReactionsBoxItemState extends State child: Material( elevation: 0, color: Colors.transparent, - child: widget.reaction.title ?? const SizedBox(), + child: widget.reaction!.title ?? const SizedBox(), ), ), ); @@ -53,7 +53,7 @@ class _ReactionsBoxItemState extends State void _showTitle() { _overlayEntry = _createTitle(); - Overlay.of(context).insert(_overlayEntry); + Overlay.of(context)!.insert(_overlayEntry!); } void _hideTitle() { @@ -92,7 +92,7 @@ class _ReactionsBoxItemState extends State @override Widget build(BuildContext context) => IgnorePointer( - ignoring: !widget.reaction.enabled, + ignoring: !widget.reaction!.enabled, child: Transform.scale( scale: _scale, child: InkWell( @@ -108,7 +108,7 @@ class _ReactionsBoxItemState extends State }, splashColor: widget.splashColor, highlightColor: widget.highlightColor, - child: widget.reaction.previewIcon, + child: widget.reaction!.previewIcon, ), ), ); diff --git a/pubspec.lock b/pubspec.lock index 19b13d0..49a0ce6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -143,4 +143,4 @@ packages: source: hosted version: "2.1.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 498229e..87f0e20 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,11 +1,11 @@ name: flutter_reaction_button description: Flutter button reaction it is fully customizable widget such as Facebook reaction button -version: 1.0.7+3 +version: 1.0.7+4 homepage: https://github.com/GeekAbdelouahed/flutter-reaction-button repository: https://github.com/GeekAbdelouahed/flutter-reaction-button.git environment: - sdk: ">=2.6.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: From a8b317340c671a4380f2088dabbc98c2f19d0986 Mon Sep 17 00:00:00 2001 From: Abdelouahed Date: Tue, 16 Mar 2021 20:09:08 +0100 Subject: [PATCH 003/136] version update --- example/pubspec.lock | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index 2f676ae..678304e 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -68,7 +68,7 @@ packages: path: ".." relative: true source: path - version: "1.0.7+4" + version: "1.0.8" flutter_test: dependency: "direct dev" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 87f0e20..2830180 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_reaction_button description: Flutter button reaction it is fully customizable widget such as Facebook reaction button -version: 1.0.7+4 +version: 1.0.8 homepage: https://github.com/GeekAbdelouahed/flutter-reaction-button repository: https://github.com/GeekAbdelouahed/flutter-reaction-button.git From 0e0b6bb7316c539c1caf1d836c2d2c685740e683 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Fri, 22 Oct 2021 09:51:25 +0100 Subject: [PATCH 004/136] abc --- .../ios/Flutter/flutter_export_environment.sh | 2 +- lib/src/extensions.dart | 10 +++-- lib/src/flutter_reaction_button.dart | 4 +- lib/src/flutter_reaction_button_check.dart | 4 +- lib/src/reactions_box.dart | 45 ++++++++++++------- lib/src/reactions_box_item.dart | 41 +++++++++++++++-- 6 files changed, 78 insertions(+), 28 deletions(-) diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index 86c128c..0a13457 100644 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -1,7 +1,7 @@ #!/bin/sh # This is a generated file; do not edit or check into version control. export "FLUTTER_ROOT=C:\flutter" -export "FLUTTER_APPLICATION_PATH=C:\Users\Lenovo\VsProjects\flutter_reaction_button\example" +export "FLUTTER_APPLICATION_PATH=E:\Projects\flutter_reaction_button\example" export "FLUTTER_TARGET=lib\main.dart" export "FLUTTER_BUILD_DIR=build" export "SYMROOT=${SOURCE_ROOT}/../build\ios" diff --git a/lib/src/extensions.dart b/lib/src/extensions.dart index 4d005fd..c334d73 100644 --- a/lib/src/extensions.dart +++ b/lib/src/extensions.dart @@ -1,13 +1,15 @@ import 'package:flutter/widgets.dart'; extension KeyExtensions on GlobalKey { - Offset get buttonOffset { - final RenderBox containerRenderBox = this.currentContext!.findRenderObject() as RenderBox; + Offset get widgetOffset { + final RenderBox containerRenderBox = + this.currentContext!.findRenderObject() as RenderBox; return containerRenderBox.localToGlobal(Offset.zero); } - Size get buttonSize { - final RenderBox containerRenderBox = this.currentContext!.findRenderObject() as RenderBox; + Size get widgetSize { + final RenderBox containerRenderBox = + this.currentContext!.findRenderObject() as RenderBox; return containerRenderBox.size; } } diff --git a/lib/src/flutter_reaction_button.dart b/lib/src/flutter_reaction_button.dart index 523dae6..5c07074 100644 --- a/lib/src/flutter_reaction_button.dart +++ b/lib/src/flutter_reaction_button.dart @@ -98,8 +98,8 @@ class _FlutterReactionButtonState extends State { ); void _showReactionButtons(BuildContext context) async { - final buttonOffset = _buttonKey.buttonOffset; - final buttonSize = _buttonKey.buttonSize; + final buttonOffset = _buttonKey.widgetOffset; + final buttonSize = _buttonKey.widgetSize; final reactionButton = await Navigator.of(context).push( PageRouteBuilder( opaque: false, diff --git a/lib/src/flutter_reaction_button_check.dart b/lib/src/flutter_reaction_button_check.dart index 53882a1..68307e0 100644 --- a/lib/src/flutter_reaction_button_check.dart +++ b/lib/src/flutter_reaction_button_check.dart @@ -138,8 +138,8 @@ class _FlutterReactionButtonCheckState } void _showReactionButtons(BuildContext context) async { - final buttonOffset = _buttonKey.buttonOffset; - final buttonSize = _buttonKey.buttonSize; + final buttonOffset = _buttonKey.widgetOffset; + final buttonSize = _buttonKey.widgetSize; final reactionButton = await Navigator.of(context).push( PageRouteBuilder( opaque: false, diff --git a/lib/src/reactions_box.dart b/lib/src/reactions_box.dart index e02a6a4..cf06e1b 100644 --- a/lib/src/reactions_box.dart +++ b/lib/src/reactions_box.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'reactions_box_item.dart'; @@ -55,6 +57,9 @@ class ReactionsBox extends StatefulWidget { class _ReactionsBoxState extends State with TickerProviderStateMixin { + StreamController _offsetStreamController = StreamController(); + late Stream _offsetStream; + late AnimationController _scaleController; late Animation _scaleAnimation; @@ -83,11 +88,14 @@ class _ReactionsBoxState extends State }); _scaleController.forward(); + + _offsetStream = _offsetStreamController.stream.asBroadcastStream(); } @override void dispose() { _scaleController.dispose(); + _offsetStreamController.close(); super.dispose(); } @@ -115,21 +123,28 @@ class _ReactionsBoxState extends State ), child: Padding( padding: widget.boxPadding, - child: Wrap( - spacing: widget.boxItemsSpacing, - children: widget.reactions - .map( - (reaction) => ReactionsBoxItem( - onReactionClick: (reaction) { - _selectedReaction = reaction; - _scaleController.reverse(); - }, - splashColor: widget.splashColor, - highlightColor: widget.highlightColor, - reaction: reaction, - ), - ) - .toList(), + child: GestureDetector( + onHorizontalDragUpdate: (details) { + _offsetStreamController.add(details.globalPosition); + }, + child: Wrap( + spacing: widget.boxItemsSpacing, + children: widget.reactions + .map( + (reaction) => ReactionsBoxItem( + index: widget.reactions.indexOf(reaction), + onReactionClick: (reaction) { + _selectedReaction = reaction; + _scaleController.reverse(); + }, + splashColor: widget.splashColor, + highlightColor: widget.highlightColor, + reaction: reaction, + offsetStream: _offsetStream, + ), + ) + .toList(), + ), ), ), ), diff --git a/lib/src/reactions_box_item.dart b/lib/src/reactions_box_item.dart index a110dae..b654043 100644 --- a/lib/src/reactions_box_item.dart +++ b/lib/src/reactions_box_item.dart @@ -1,8 +1,14 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; +import 'extensions.dart'; import 'reaction.dart'; class ReactionsBoxItem extends StatefulWidget { + // TODO remove it later + final int index; + final Function(Reaction?) onReactionClick; final Reaction? reaction; @@ -11,12 +17,16 @@ class ReactionsBoxItem extends StatefulWidget { final Color? splashColor; + final Stream offsetStream; + const ReactionsBoxItem({ Key? key, + required this.index, required this.reaction, required this.onReactionClick, this.highlightColor, this.splashColor, + required this.offsetStream, }) : super(key: key); @override @@ -25,10 +35,14 @@ class ReactionsBoxItem extends StatefulWidget { class _ReactionsBoxItemState extends State with TickerProviderStateMixin { + final GlobalKey _key = GlobalKey(); + late AnimationController _scaleController; late Animation _scaleAnimation; + late StreamSubscription _streamSubscription; + double _scale = 1; OverlayEntry? _overlayEntry; @@ -69,29 +83,48 @@ class _ReactionsBoxItemState extends State _scaleController = AnimationController(vsync: this, duration: Duration(milliseconds: 100)); - final Tween startTween = Tween(begin: 1, end: 1.3); + final Tween startTween = Tween(begin: 1, end: 1.5); _scaleAnimation = startTween.animate(_scaleController) ..addListener(() { setState(() { _scale = _scaleAnimation.value; }); - if (_scale == 1.3 && _overlayEntry == null) { + if (_scale == 1.5 && _overlayEntry == null) { _showTitle(); } else if (_scale == 1) { _hideTitle(); } }); + + _streamSubscription = widget.offsetStream.listen((offset) { + final Size widgetSize = _key.widgetSize; + final Offset deltaOffset = offset - _key.widgetOffset; + + if (widgetSize.width > deltaOffset.distance) { + _showTitle(); + setState(() { + _scale = 1.5; + }); + } else { + _hideTitle(); + setState(() { + _scale = 1; + }); + } + }); } @override void dispose() { _scaleController.dispose(); + _streamSubscription.cancel(); super.dispose(); } @override Widget build(BuildContext context) => IgnorePointer( + key: _key, ignoring: !widget.reaction!.enabled, child: Transform.scale( scale: _scale, @@ -100,12 +133,12 @@ class _ReactionsBoxItemState extends State _scaleController.reverse(); widget.onReactionClick(widget.reaction); }, - onTapDown: (_) { + /*onTapDown: (_) { _scaleController.forward(); }, onTapCancel: () { _scaleController.reverse(); - }, + },*/ splashColor: widget.splashColor, highlightColor: widget.highlightColor, child: widget.reaction!.previewIcon, From 95f720d23dbdf79d72b08fa1140f3c250d3300dd Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Fri, 22 Oct 2021 10:40:09 +0100 Subject: [PATCH 005/136] drag with scal --- lib/src/drag.dart | 22 +++++++++ lib/src/reactions_box.dart | 21 ++++++--- lib/src/reactions_box_item.dart | 83 ++++++++++++++++----------------- 3 files changed, 77 insertions(+), 49 deletions(-) create mode 100644 lib/src/drag.dart diff --git a/lib/src/drag.dart b/lib/src/drag.dart new file mode 100644 index 0000000..7e139b1 --- /dev/null +++ b/lib/src/drag.dart @@ -0,0 +1,22 @@ +import 'package:flutter/cupertino.dart'; + +class DragData { + final Offset offset; + final bool isEnd; + + DragData({ + required this.offset, + this.isEnd = false, + }); + + DragData copyWith({ + Offset? offset, + bool? isEnd, + }) { + if (isEnd == null) isEnd = this.isEnd; + return DragData( + offset: offset ?? this.offset, + isEnd: isEnd, + ); + } +} diff --git a/lib/src/reactions_box.dart b/lib/src/reactions_box.dart index cf06e1b..ac24ad0 100644 --- a/lib/src/reactions_box.dart +++ b/lib/src/reactions_box.dart @@ -6,6 +6,7 @@ import 'reactions_box_item.dart'; import 'reactions_position.dart'; import 'reaction.dart'; import 'extensions.dart'; +import 'drag.dart'; class ReactionsBox extends StatefulWidget { final Offset buttonOffset; @@ -57,8 +58,9 @@ class ReactionsBox extends StatefulWidget { class _ReactionsBoxState extends State with TickerProviderStateMixin { - StreamController _offsetStreamController = StreamController(); - late Stream _offsetStream; + StreamController _dragStreamController = + StreamController(); + late Stream _dragStream; late AnimationController _scaleController; @@ -68,6 +70,8 @@ class _ReactionsBoxState extends State Reaction? _selectedReaction; + late DragData _dragData; + @override void initState() { super.initState(); @@ -89,13 +93,13 @@ class _ReactionsBoxState extends State _scaleController.forward(); - _offsetStream = _offsetStreamController.stream.asBroadcastStream(); + _dragStream = _dragStreamController.stream.asBroadcastStream(); } @override void dispose() { _scaleController.dispose(); - _offsetStreamController.close(); + _dragStreamController.close(); super.dispose(); } @@ -125,7 +129,12 @@ class _ReactionsBoxState extends State padding: widget.boxPadding, child: GestureDetector( onHorizontalDragUpdate: (details) { - _offsetStreamController.add(details.globalPosition); + _dragData = DragData(offset: details.globalPosition); + _dragStreamController.add(_dragData); + }, + onHorizontalDragEnd: (details) { + _dragData = _dragData.copyWith(isEnd: true); + _dragStreamController.add(_dragData); }, child: Wrap( spacing: widget.boxItemsSpacing, @@ -140,7 +149,7 @@ class _ReactionsBoxState extends State splashColor: widget.splashColor, highlightColor: widget.highlightColor, reaction: reaction, - offsetStream: _offsetStream, + dragStream: _dragStream, ), ) .toList(), diff --git a/lib/src/reactions_box_item.dart b/lib/src/reactions_box_item.dart index b654043..fa7f8e1 100644 --- a/lib/src/reactions_box_item.dart +++ b/lib/src/reactions_box_item.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'extensions.dart'; import 'reaction.dart'; +import 'drag.dart'; class ReactionsBoxItem extends StatefulWidget { // TODO remove it later @@ -17,7 +18,7 @@ class ReactionsBoxItem extends StatefulWidget { final Color? splashColor; - final Stream offsetStream; + final Stream dragStream; const ReactionsBoxItem({ Key? key, @@ -26,7 +27,7 @@ class ReactionsBoxItem extends StatefulWidget { required this.onReactionClick, this.highlightColor, this.splashColor, - required this.offsetStream, + required this.dragStream, }) : super(key: key); @override @@ -41,12 +42,16 @@ class _ReactionsBoxItemState extends State late Animation _scaleAnimation; - late StreamSubscription _streamSubscription; - double _scale = 1; OverlayEntry? _overlayEntry; + void _onSelected() { + _hideTitle(); + _scaleController.reverse(); + widget.onReactionClick(widget.reaction); + } + OverlayEntry _createTitle() { RenderBox renderBox = context.findRenderObject() as RenderBox; final size = renderBox.size; @@ -96,53 +101,45 @@ class _ReactionsBoxItemState extends State _hideTitle(); } }); - - _streamSubscription = widget.offsetStream.listen((offset) { - final Size widgetSize = _key.widgetSize; - final Offset deltaOffset = offset - _key.widgetOffset; - - if (widgetSize.width > deltaOffset.distance) { - _showTitle(); - setState(() { - _scale = 1.5; - }); - } else { - _hideTitle(); - setState(() { - _scale = 1; - }); - } - }); } @override void dispose() { _scaleController.dispose(); - _streamSubscription.cancel(); super.dispose(); } @override - Widget build(BuildContext context) => IgnorePointer( - key: _key, - ignoring: !widget.reaction!.enabled, - child: Transform.scale( - scale: _scale, - child: InkWell( - onTap: () { - _scaleController.reverse(); - widget.onReactionClick(widget.reaction); - }, - /*onTapDown: (_) { - _scaleController.forward(); - }, - onTapCancel: () { + Widget build(BuildContext context) { + return IgnorePointer( + key: _key, + ignoring: !widget.reaction!.enabled, + child: StreamBuilder( + stream: widget.dragStream, + builder: (context, snapshot) { + if (snapshot.hasData) { + final widgetSize = _key.widgetSize; + final deltaOffset = + (snapshot.data?.offset ?? Offset.zero) - _key.widgetOffset; + if (widgetSize.width > deltaOffset.distance) { + if (snapshot.data?.isEnd ?? false) { + _onSelected(); + } else + _scaleController.forward(); + } else + _scaleController.reverse(); + } else _scaleController.reverse(); - },*/ - splashColor: widget.splashColor, - highlightColor: widget.highlightColor, - child: widget.reaction!.previewIcon, - ), - ), - ); + return Transform.scale( + scale: _scale, + child: InkWell( + onTap: _onSelected, + splashColor: widget.splashColor, + highlightColor: widget.highlightColor, + child: widget.reaction!.previewIcon, + ), + ); + }), + ); + } } From 32990b06e4fcf1035bf9e1f8f4b50529b6a88125 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Fri, 22 Oct 2021 11:55:31 +0100 Subject: [PATCH 006/136] drag data --- example/lib/data/example_data.dart | 2 - lib/src/drag.dart | 8 +-- lib/src/reactions_box.dart | 89 +++++++++++++++++++----------- lib/src/reactions_box_item.dart | 55 +++++++++++------- 4 files changed, 95 insertions(+), 59 deletions(-) diff --git a/example/lib/data/example_data.dart b/example/lib/data/example_data.dart index b2e845e..ee59f8c 100644 --- a/example/lib/data/example_data.dart +++ b/example/lib/data/example_data.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_reaction_button/flutter_reaction_button.dart'; - List flagsReactions = [ Reaction( previewIcon: _builFlagsdPreviewIcon( @@ -14,7 +13,6 @@ List flagsReactions = [ icon: _buildIcon('assets/images/algeria.png'), ), Reaction( - enabled: false, previewIcon: _builFlagsdPreviewIcon('assets/images/germany-round.png', 'German'), icon: _buildIcon('assets/images/germany.png'), diff --git a/lib/src/drag.dart b/lib/src/drag.dart index 7e139b1..9e05ebf 100644 --- a/lib/src/drag.dart +++ b/lib/src/drag.dart @@ -2,21 +2,21 @@ import 'package:flutter/cupertino.dart'; class DragData { final Offset offset; - final bool isEnd; + final bool isDragEnd; DragData({ required this.offset, - this.isEnd = false, + this.isDragEnd = false, }); DragData copyWith({ Offset? offset, bool? isEnd, }) { - if (isEnd == null) isEnd = this.isEnd; + if (isEnd == null) isEnd = this.isDragEnd; return DragData( offset: offset ?? this.offset, - isEnd: isEnd, + isDragEnd: isEnd, ); } } diff --git a/lib/src/reactions_box.dart b/lib/src/reactions_box.dart index ac24ad0..58bac68 100644 --- a/lib/src/reactions_box.dart +++ b/lib/src/reactions_box.dart @@ -104,7 +104,12 @@ class _ReactionsBoxState extends State } @override - Widget build(BuildContext context) => Stack( + Widget build(BuildContext context) { + double top = _getPosition(context); + return Material( + elevation: 0, + color: Colors.transparent, + child: Stack( alignment: widget.alignment, children: [ Positioned.fill( @@ -115,52 +120,70 @@ class _ReactionsBoxState extends State ), ), Positioned( - top: _getPosition(context), + top: top, child: Transform.scale( scale: _scale, - child: Card( + child: Material( color: widget.color, elevation: widget.elevation, clipBehavior: Clip.antiAlias, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(widget.radius), ), - child: Padding( - padding: widget.boxPadding, - child: GestureDetector( - onHorizontalDragUpdate: (details) { - _dragData = DragData(offset: details.globalPosition); - _dragStreamController.add(_dragData); - }, - onHorizontalDragEnd: (details) { - _dragData = _dragData.copyWith(isEnd: true); - _dragStreamController.add(_dragData); - }, - child: Wrap( - spacing: widget.boxItemsSpacing, - children: widget.reactions - .map( - (reaction) => ReactionsBoxItem( - index: widget.reactions.indexOf(reaction), - onReactionClick: (reaction) { - _selectedReaction = reaction; - _scaleController.reverse(); - }, - splashColor: widget.splashColor, - highlightColor: widget.highlightColor, - reaction: reaction, - dragStream: _dragStream, - ), - ) - .toList(), - ), + child: IgnorePointer( + ignoring: true, + child: Opacity( + opacity: 0, + child: _buildItems(), ), ), ), ), ), + Positioned( + top: top, + child: Transform.scale( + scale: _scale, + child: _buildItems(), + ), + ), ], - ); + ), + ); + } + + Padding _buildItems() { + return Padding( + padding: widget.boxPadding, + child: GestureDetector( + onHorizontalDragUpdate: (details) { + _dragData = DragData(offset: details.globalPosition); + _dragStreamController.add(_dragData); + }, + onHorizontalDragEnd: (details) { + _dragData = _dragData.copyWith(isEnd: true); + _dragStreamController.add(_dragData); + }, + child: Wrap( + spacing: widget.boxItemsSpacing, + children: widget.reactions + .map( + (reaction) => ReactionsBoxItem( + onReactionClick: (reaction) { + _selectedReaction = reaction; + _scaleController.reverse(); + }, + splashColor: widget.splashColor, + highlightColor: widget.highlightColor, + reaction: reaction, + dragStream: _dragStream, + ), + ) + .toList(), + ), + ), + ); + } double _getPosition(BuildContext context) => (_getTopPosition() - widget.buttonSize.height * 2 < 0) diff --git a/lib/src/reactions_box_item.dart b/lib/src/reactions_box_item.dart index fa7f8e1..f572ab6 100644 --- a/lib/src/reactions_box_item.dart +++ b/lib/src/reactions_box_item.dart @@ -7,9 +7,6 @@ import 'reaction.dart'; import 'drag.dart'; class ReactionsBoxItem extends StatefulWidget { - // TODO remove it later - final int index; - final Function(Reaction?) onReactionClick; final Reaction? reaction; @@ -22,7 +19,6 @@ class ReactionsBoxItem extends StatefulWidget { const ReactionsBoxItem({ Key? key, - required this.index, required this.reaction, required this.onReactionClick, this.highlightColor, @@ -36,10 +32,12 @@ class ReactionsBoxItem extends StatefulWidget { class _ReactionsBoxItemState extends State with TickerProviderStateMixin { - final GlobalKey _key = GlobalKey(); + final GlobalKey _widgetKey = GlobalKey(); late AnimationController _scaleController; + late Tween _startTween; + late Animation _scaleAnimation; double _scale = 1; @@ -86,10 +84,10 @@ class _ReactionsBoxItemState extends State // Start animation _scaleController = - AnimationController(vsync: this, duration: Duration(milliseconds: 100)); + AnimationController(vsync: this, duration: Duration(milliseconds: 250)); - final Tween startTween = Tween(begin: 1, end: 1.5); - _scaleAnimation = startTween.animate(_scaleController) + _startTween = Tween(begin: 1, end: 1.5); + _scaleAnimation = _startTween.animate(_scaleController) ..addListener(() { setState(() { _scale = _scaleAnimation.value; @@ -97,7 +95,7 @@ class _ReactionsBoxItemState extends State if (_scale == 1.5 && _overlayEntry == null) { _showTitle(); - } else if (_scale == 1) { + } else if (_scale <= 1) { _hideTitle(); } }); @@ -112,24 +110,41 @@ class _ReactionsBoxItemState extends State @override Widget build(BuildContext context) { return IgnorePointer( - key: _key, + key: _widgetKey, ignoring: !widget.reaction!.enabled, child: StreamBuilder( stream: widget.dragStream, - builder: (context, snapshot) { + builder: (_, snapshot) { if (snapshot.hasData) { - final widgetSize = _key.widgetSize; - final deltaOffset = - (snapshot.data?.offset ?? Offset.zero) - _key.widgetOffset; - if (widgetSize.width > deltaOffset.distance) { - if (snapshot.data?.isEnd ?? false) { + final dragData = snapshot.data; + final Offset currentOffset = dragData?.offset ?? Offset.zero; + final widgetSize = _widgetKey.widgetSize; + final deltaOffset = currentOffset - _widgetKey.widgetOffset; + final isHovered = widgetSize.width > deltaOffset.distance && + widget.reaction!.enabled; + if (isHovered) { + bool isSelected = snapshot.data?.isDragEnd ?? false; + if (isSelected) { _onSelected(); - } else + } else { _scaleController.forward(); - } else - _scaleController.reverse(); - } else + } + } else { + bool isDraggingEnded = dragData?.isDragEnd ?? false; + if (isDraggingEnded) { + _startTween.begin = 1; + WidgetsBinding.instance!.addPostFrameCallback((_) { + _scaleController.reset(); + }); + } else { + _startTween.begin = .75; + _scaleController.reverse(); + } + } + } else { + _startTween.begin = 1; _scaleController.reverse(); + } return Transform.scale( scale: _scale, child: InkWell( From 8bfd893ea4ec2bb2140937e30414a0942ce3f1ac Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Fri, 22 Oct 2021 19:59:07 +0100 Subject: [PATCH 007/136] scale on drag --- example/lib/items/item.dart | 2 +- lib/src/drag.dart | 6 ++-- lib/src/flutter_reaction_button_check.dart | 11 +----- lib/src/reactions_box.dart | 28 +++++++++++++-- lib/src/reactions_box_item.dart | 41 +++++++++++++++------- 5 files changed, 58 insertions(+), 30 deletions(-) diff --git a/example/lib/items/item.dart b/example/lib/items/item.dart index 400bb4a..2995bc5 100644 --- a/example/lib/items/item.dart +++ b/example/lib/items/item.dart @@ -21,7 +21,7 @@ class _ItemState extends State with AutomaticKeepAliveClientMixin { List _comments = []; - _showBottomSheetCommets() { + void _showBottomSheetCommets() { showBottomSheet( context: context, builder: (context) => Comments(_comments), diff --git a/lib/src/drag.dart b/lib/src/drag.dart index 9e05ebf..3e14b3c 100644 --- a/lib/src/drag.dart +++ b/lib/src/drag.dart @@ -11,12 +11,12 @@ class DragData { DragData copyWith({ Offset? offset, - bool? isEnd, + bool? isDragEnd, }) { - if (isEnd == null) isEnd = this.isDragEnd; + if (isDragEnd == null) isDragEnd = this.isDragEnd; return DragData( offset: offset ?? this.offset, - isDragEnd: isEnd, + isDragEnd: isDragEnd, ); } } diff --git a/lib/src/flutter_reaction_button_check.dart b/lib/src/flutter_reaction_button_check.dart index 68307e0..6492942 100644 --- a/lib/src/flutter_reaction_button_check.dart +++ b/lib/src/flutter_reaction_button_check.dart @@ -114,20 +114,11 @@ class _FlutterReactionButtonCheckState _onClickReactionButton(); }, onLongPress: () { - _onTapReactionButton(context); + _showReactionButtons(context); }, child: (_selectedReaction ?? widget.reactions[0])!.icon, ); - void _onTapReactionButton(BuildContext context) { - _timer = Timer.periodic(Duration(milliseconds: 100), (timer) { - if (_timer!.tick >= _maxTick) { - _showReactionButtons(context); - _timer!.cancel(); - } - }); - } - void _onClickReactionButton() { _isChecked = !_isChecked; _updateReaction( diff --git a/lib/src/reactions_box.dart b/lib/src/reactions_box.dart index 58bac68..b1bb600 100644 --- a/lib/src/reactions_box.dart +++ b/lib/src/reactions_box.dart @@ -134,7 +134,7 @@ class _ReactionsBoxState extends State ignoring: true, child: Opacity( opacity: 0, - child: _buildItems(), + child: _buildDumpItems(), ), ), ), @@ -152,7 +152,7 @@ class _ReactionsBoxState extends State ); } - Padding _buildItems() { + Padding _buildDumpItems() { return Padding( padding: widget.boxPadding, child: GestureDetector( @@ -161,11 +161,33 @@ class _ReactionsBoxState extends State _dragStreamController.add(_dragData); }, onHorizontalDragEnd: (details) { - _dragData = _dragData.copyWith(isEnd: true); + _dragData = _dragData.copyWith(isDragEnd: true); _dragStreamController.add(_dragData); }, child: Wrap( spacing: widget.boxItemsSpacing, + children: widget.reactions.map((reaction) { + return reaction!.previewIcon; + }).toList(), + ), + ), + ); + } + + Padding _buildItems() { + return Padding( + padding: widget.boxPadding, + child: GestureDetector( + onHorizontalDragUpdate: (details) { + _dragData = DragData(offset: details.globalPosition); + _dragStreamController.add(_dragData); + }, + onHorizontalDragEnd: (details) { + _dragData = _dragData.copyWith(isDragEnd: true); + _dragStreamController.add(_dragData); + }, + child: Row( + //spacing: widget.boxItemsSpacing, children: widget.reactions .map( (reaction) => ReactionsBoxItem( diff --git a/lib/src/reactions_box_item.dart b/lib/src/reactions_box_item.dart index f572ab6..bc12976 100644 --- a/lib/src/reactions_box_item.dart +++ b/lib/src/reactions_box_item.dart @@ -32,6 +32,7 @@ class ReactionsBoxItem extends StatefulWidget { class _ReactionsBoxItemState extends State with TickerProviderStateMixin { + static const double _MIN_SCALE = .8, _NORMAL_SCALE = 1, _MAX_SCALE = 1.2; final GlobalKey _widgetKey = GlobalKey(); late AnimationController _scaleController; @@ -42,6 +43,9 @@ class _ReactionsBoxItemState extends State double _scale = 1; + double? _height; + double? _width; + OverlayEntry? _overlayEntry; void _onSelected() { @@ -86,16 +90,16 @@ class _ReactionsBoxItemState extends State _scaleController = AnimationController(vsync: this, duration: Duration(milliseconds: 250)); - _startTween = Tween(begin: 1, end: 1.5); + _startTween = Tween(begin: _NORMAL_SCALE, end: _MAX_SCALE); _scaleAnimation = _startTween.animate(_scaleController) ..addListener(() { setState(() { _scale = _scaleAnimation.value; }); - if (_scale == 1.5 && _overlayEntry == null) { + if (_scale == _MAX_SCALE && _overlayEntry == null) { _showTitle(); - } else if (_scale <= 1) { + } else if (_scale <= _NORMAL_SCALE) { _hideTitle(); } }); @@ -119,9 +123,13 @@ class _ReactionsBoxItemState extends State final dragData = snapshot.data; final Offset currentOffset = dragData?.offset ?? Offset.zero; final widgetSize = _widgetKey.widgetSize; + if (_height == null && _width == null) { + _height = widgetSize.height; + _width = widgetSize.width; + } final deltaOffset = currentOffset - _widgetKey.widgetOffset; - final isHovered = widgetSize.width > deltaOffset.distance && - widget.reaction!.enabled; + final isHovered = + _width! > deltaOffset.distance && widget.reaction!.enabled; if (isHovered) { bool isSelected = snapshot.data?.isDragEnd ?? false; if (isSelected) { @@ -132,26 +140,33 @@ class _ReactionsBoxItemState extends State } else { bool isDraggingEnded = dragData?.isDragEnd ?? false; if (isDraggingEnded) { - _startTween.begin = 1; + _startTween.begin = _NORMAL_SCALE; WidgetsBinding.instance!.addPostFrameCallback((_) { _scaleController.reset(); }); } else { - _startTween.begin = .75; + _startTween.begin = _MIN_SCALE; _scaleController.reverse(); } } } else { - _startTween.begin = 1; + _startTween.begin = _NORMAL_SCALE; _scaleController.reverse(); } return Transform.scale( scale: _scale, - child: InkWell( - onTap: _onSelected, - splashColor: widget.splashColor, - highlightColor: widget.highlightColor, - child: widget.reaction!.previewIcon, + child: AnimatedContainer( + height: _height != null ? _height! * _scale : null, + width: _width != null ? _width! * _scale : null, + duration: const Duration(milliseconds: 250), + child: FittedBox( + child: InkWell( + onTap: _onSelected, + splashColor: widget.splashColor, + highlightColor: widget.highlightColor, + child: widget.reaction!.previewIcon, + ), + ), ), ); }), From 5fe580522aa5ffc603a4b25720450431490784f0 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Fri, 22 Oct 2021 20:00:35 +0100 Subject: [PATCH 008/136] scale on drag --- lib/src/reactions_box.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/reactions_box.dart b/lib/src/reactions_box.dart index b1bb600..d7f72d1 100644 --- a/lib/src/reactions_box.dart +++ b/lib/src/reactions_box.dart @@ -186,8 +186,8 @@ class _ReactionsBoxState extends State _dragData = _dragData.copyWith(isDragEnd: true); _dragStreamController.add(_dragData); }, - child: Row( - //spacing: widget.boxItemsSpacing, + child: Wrap( + spacing: widget.boxItemsSpacing, children: widget.reactions .map( (reaction) => ReactionsBoxItem( From f732d1d19170f6ad7f5e2cbd2a88d89f4c3f21f2 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Fri, 22 Oct 2021 20:09:12 +0100 Subject: [PATCH 009/136] code format --- example/lib/items/item.dart | 7 ++++--- lib/flutter_reaction_button.dart | 8 ++++---- lib/src/{ => models}/drag.dart | 0 lib/src/{ => models}/reaction.dart | 0 lib/src/{ => ui}/flutter_reaction_button.dart | 6 +++--- lib/src/{ => ui}/flutter_reaction_button_check.dart | 6 +++--- lib/src/{ => ui}/reactions_box.dart | 8 ++++---- lib/src/{ => ui}/reactions_box_item.dart | 6 +++--- lib/src/{ => utils}/extensions.dart | 0 lib/src/{ => utils}/reactions_position.dart | 0 10 files changed, 21 insertions(+), 20 deletions(-) rename lib/src/{ => models}/drag.dart (100%) rename lib/src/{ => models}/reaction.dart (100%) rename lib/src/{ => ui}/flutter_reaction_button.dart (97%) rename lib/src/{ => ui}/flutter_reaction_button_check.dart (97%) rename lib/src/{ => ui}/reactions_box.dart (97%) rename lib/src/{ => ui}/reactions_box_item.dart (97%) rename lib/src/{ => utils}/extensions.dart (100%) rename lib/src/{ => utils}/reactions_position.dart (100%) diff --git a/example/lib/items/item.dart b/example/lib/items/item.dart index 2995bc5..53d2fb3 100644 --- a/example/lib/items/item.dart +++ b/example/lib/items/item.dart @@ -1,8 +1,9 @@ -import 'package:flutter_reaction_button/flutter_reaction_button.dart'; import 'package:flutter/material.dart'; -import 'comments.dart'; -import '../models/comment.dart'; +import 'package:flutter_reaction_button/flutter_reaction_button.dart'; + import '../data/example_data.dart' as Example; +import '../models/comment.dart'; +import 'comments.dart'; class Item extends StatefulWidget { final String title; diff --git a/lib/flutter_reaction_button.dart b/lib/flutter_reaction_button.dart index 7fd56e7..c478240 100644 --- a/lib/flutter_reaction_button.dart +++ b/lib/flutter_reaction_button.dart @@ -1,6 +1,6 @@ library flutter_reaction_button; -export 'src/flutter_reaction_button_check.dart'; -export 'src/flutter_reaction_button.dart'; -export 'src/reactions_position.dart'; -export 'src/reaction.dart'; +export 'src/models/reaction.dart'; +export 'src/ui/flutter_reaction_button.dart'; +export 'src/ui/flutter_reaction_button_check.dart'; +export 'src/utils/reactions_position.dart'; diff --git a/lib/src/drag.dart b/lib/src/models/drag.dart similarity index 100% rename from lib/src/drag.dart rename to lib/src/models/drag.dart diff --git a/lib/src/reaction.dart b/lib/src/models/reaction.dart similarity index 100% rename from lib/src/reaction.dart rename to lib/src/models/reaction.dart diff --git a/lib/src/flutter_reaction_button.dart b/lib/src/ui/flutter_reaction_button.dart similarity index 97% rename from lib/src/flutter_reaction_button.dart rename to lib/src/ui/flutter_reaction_button.dart index 5c07074..b2da252 100644 --- a/lib/src/flutter_reaction_button.dart +++ b/lib/src/ui/flutter_reaction_button.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'reactions_position.dart'; +import '../models/reaction.dart'; +import '../utils/extensions.dart'; +import '../utils/reactions_position.dart'; import 'reactions_box.dart'; -import 'reaction.dart'; -import 'extensions.dart'; typedef OnFlutterReactionButtonChanged = void Function(Reaction, int); diff --git a/lib/src/flutter_reaction_button_check.dart b/lib/src/ui/flutter_reaction_button_check.dart similarity index 97% rename from lib/src/flutter_reaction_button_check.dart rename to lib/src/ui/flutter_reaction_button_check.dart index 6492942..808aa8c 100644 --- a/lib/src/flutter_reaction_button_check.dart +++ b/lib/src/ui/flutter_reaction_button_check.dart @@ -2,10 +2,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'reactions_position.dart'; +import '../models/reaction.dart'; +import '../utils/extensions.dart'; +import '../utils/reactions_position.dart'; import 'reactions_box.dart'; -import 'reaction.dart'; -import 'extensions.dart'; typedef FlutterReactionButtonCheckChanged = void Function(Reaction?, int, bool); diff --git a/lib/src/reactions_box.dart b/lib/src/ui/reactions_box.dart similarity index 97% rename from lib/src/reactions_box.dart rename to lib/src/ui/reactions_box.dart index d7f72d1..ff41bdc 100644 --- a/lib/src/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -2,11 +2,11 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import '../models/drag.dart'; +import '../models/reaction.dart'; +import '../utils/extensions.dart'; +import '../utils/reactions_position.dart'; import 'reactions_box_item.dart'; -import 'reactions_position.dart'; -import 'reaction.dart'; -import 'extensions.dart'; -import 'drag.dart'; class ReactionsBox extends StatefulWidget { final Offset buttonOffset; diff --git a/lib/src/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart similarity index 97% rename from lib/src/reactions_box_item.dart rename to lib/src/ui/reactions_box_item.dart index bc12976..1842797 100644 --- a/lib/src/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -2,9 +2,9 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'extensions.dart'; -import 'reaction.dart'; -import 'drag.dart'; +import '../models/drag.dart'; +import '../models/reaction.dart'; +import '../utils/extensions.dart'; class ReactionsBoxItem extends StatefulWidget { final Function(Reaction?) onReactionClick; diff --git a/lib/src/extensions.dart b/lib/src/utils/extensions.dart similarity index 100% rename from lib/src/extensions.dart rename to lib/src/utils/extensions.dart diff --git a/lib/src/reactions_position.dart b/lib/src/utils/reactions_position.dart similarity index 100% rename from lib/src/reactions_position.dart rename to lib/src/utils/reactions_position.dart From 6d7950240e51b9e248ac829375141f05f497fc25 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Sat, 23 Oct 2021 22:51:08 +0100 Subject: [PATCH 010/136] use Listener + code improvements --- lib/src/ui/reactions_box.dart | 45 ++++++-------- lib/src/ui/reactions_box_item.dart | 95 +++++++++++++++++++----------- 2 files changed, 78 insertions(+), 62 deletions(-) diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index ff41bdc..076e176 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -113,10 +113,11 @@ class _ReactionsBoxState extends State alignment: widget.alignment, children: [ Positioned.fill( - child: GestureDetector( - onTapDown: (_) => _scaleController.reverse(), - onVerticalDragUpdate: (_) => _scaleController.reverse(), - onHorizontalDragUpdate: (_) => _scaleController.reverse(), + child: Listener( + onPointerDown: (_) => _scaleController.reverse(), + child: Container( + color: Colors.transparent, + ), ), ), Positioned( @@ -152,37 +153,27 @@ class _ReactionsBoxState extends State ); } - Padding _buildDumpItems() { + Widget _buildDumpItems() { return Padding( padding: widget.boxPadding, - child: GestureDetector( - onHorizontalDragUpdate: (details) { - _dragData = DragData(offset: details.globalPosition); - _dragStreamController.add(_dragData); - }, - onHorizontalDragEnd: (details) { - _dragData = _dragData.copyWith(isDragEnd: true); - _dragStreamController.add(_dragData); - }, - child: Wrap( - spacing: widget.boxItemsSpacing, - children: widget.reactions.map((reaction) { - return reaction!.previewIcon; - }).toList(), - ), + child: Wrap( + spacing: widget.boxItemsSpacing, + children: widget.reactions.map((reaction) { + return reaction!.previewIcon; + }).toList(), ), ); } - Padding _buildItems() { + Widget _buildItems() { return Padding( padding: widget.boxPadding, - child: GestureDetector( - onHorizontalDragUpdate: (details) { - _dragData = DragData(offset: details.globalPosition); + child: Listener( + onPointerMove: (point) { + _dragData = DragData(offset: point.position); _dragStreamController.add(_dragData); }, - onHorizontalDragEnd: (details) { + onPointerUp: (point) { _dragData = _dragData.copyWith(isDragEnd: true); _dragStreamController.add(_dragData); }, @@ -191,13 +182,15 @@ class _ReactionsBoxState extends State children: widget.reactions .map( (reaction) => ReactionsBoxItem( + index: widget.reactions.indexOf(reaction), onReactionClick: (reaction) { _selectedReaction = reaction; _scaleController.reverse(); }, splashColor: widget.splashColor, highlightColor: widget.highlightColor, - reaction: reaction, + itemsCount: widget.reactions.length, + reaction: reaction!, dragStream: _dragStream, ), ) diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 1842797..0473625 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -7,23 +7,30 @@ import '../models/reaction.dart'; import '../utils/extensions.dart'; class ReactionsBoxItem extends StatefulWidget { + // TODO for test + final int index; + final Function(Reaction?) onReactionClick; - final Reaction? reaction; + final Reaction reaction; + + final int itemsCount; + + final Stream dragStream; final Color? highlightColor; final Color? splashColor; - final Stream dragStream; - const ReactionsBoxItem({ Key? key, + required this.index, required this.reaction, required this.onReactionClick, + required this.itemsCount, + required this.dragStream, this.highlightColor, this.splashColor, - required this.dragStream, }) : super(key: key); @override @@ -32,18 +39,23 @@ class ReactionsBoxItem extends StatefulWidget { class _ReactionsBoxItemState extends State with TickerProviderStateMixin { - static const double _MIN_SCALE = .8, _NORMAL_SCALE = 1, _MAX_SCALE = 1.2; final GlobalKey _widgetKey = GlobalKey(); + final StreamController _scaleControllerStream = + StreamController()..add(1); + + late Stream _scaleStream; + late AnimationController _scaleController; late Tween _startTween; late Animation _scaleAnimation; + double _minScale = 1, _normalScale = 1, _maxScale = 1.2; + double _scale = 1; - double? _height; double? _width; OverlayEntry? _overlayEntry; @@ -51,7 +63,7 @@ class _ReactionsBoxItemState extends State void _onSelected() { _hideTitle(); _scaleController.reverse(); - widget.onReactionClick(widget.reaction); + widget.onReactionClick.call(widget.reaction); } OverlayEntry _createTitle() { @@ -66,7 +78,7 @@ class _ReactionsBoxItemState extends State child: Material( elevation: 0, color: Colors.transparent, - child: widget.reaction!.title ?? const SizedBox(), + child: widget.reaction.title ?? const SizedBox(), ), ), ); @@ -86,20 +98,28 @@ class _ReactionsBoxItemState extends State void initState() { super.initState(); + // Calculating how much we should scale down unselected items + _minScale = 1 - (.2 / widget.itemsCount); + + _scaleStream = _scaleControllerStream.stream; + // Start animation _scaleController = AnimationController(vsync: this, duration: Duration(milliseconds: 250)); - _startTween = Tween(begin: _NORMAL_SCALE, end: _MAX_SCALE); + _startTween = Tween(begin: _normalScale, end: _maxScale); + _scaleAnimation = _startTween.animate(_scaleController) ..addListener(() { - setState(() { + /*setState(() { _scale = _scaleAnimation.value; - }); + });*/ + _scale = _scaleAnimation.value; + _scaleControllerStream.add(_scale); - if (_scale == _MAX_SCALE && _overlayEntry == null) { + if (_scale == _maxScale && _overlayEntry == null) { _showTitle(); - } else if (_scale <= _NORMAL_SCALE) { + } else if (_scale <= _normalScale) { _hideTitle(); } }); @@ -108,6 +128,7 @@ class _ReactionsBoxItemState extends State @override void dispose() { _scaleController.dispose(); + _scaleControllerStream.close(); super.dispose(); } @@ -115,7 +136,7 @@ class _ReactionsBoxItemState extends State Widget build(BuildContext context) { return IgnorePointer( key: _widgetKey, - ignoring: !widget.reaction!.enabled, + ignoring: !widget.reaction.enabled, child: StreamBuilder( stream: widget.dragStream, builder: (_, snapshot) { @@ -123,13 +144,12 @@ class _ReactionsBoxItemState extends State final dragData = snapshot.data; final Offset currentOffset = dragData?.offset ?? Offset.zero; final widgetSize = _widgetKey.widgetSize; - if (_height == null && _width == null) { - _height = widgetSize.height; + if (_width == null) { _width = widgetSize.width; } final deltaOffset = currentOffset - _widgetKey.widgetOffset; final isHovered = - _width! > deltaOffset.distance && widget.reaction!.enabled; + _width! > deltaOffset.distance && widget.reaction.enabled; if (isHovered) { bool isSelected = snapshot.data?.isDragEnd ?? false; if (isSelected) { @@ -140,35 +160,38 @@ class _ReactionsBoxItemState extends State } else { bool isDraggingEnded = dragData?.isDragEnd ?? false; if (isDraggingEnded) { - _startTween.begin = _NORMAL_SCALE; + _startTween.begin = _normalScale; WidgetsBinding.instance!.addPostFrameCallback((_) { _scaleController.reset(); }); } else { - _startTween.begin = _MIN_SCALE; + _startTween.begin = _minScale; _scaleController.reverse(); } } } else { - _startTween.begin = _NORMAL_SCALE; + _startTween.begin = _normalScale; _scaleController.reverse(); } - return Transform.scale( - scale: _scale, - child: AnimatedContainer( - height: _height != null ? _height! * _scale : null, - width: _width != null ? _width! * _scale : null, - duration: const Duration(milliseconds: 250), - child: FittedBox( - child: InkWell( - onTap: _onSelected, - splashColor: widget.splashColor, - highlightColor: widget.highlightColor, - child: widget.reaction!.previewIcon, - ), - ), - ), - ); + return StreamBuilder( + stream: _scaleStream, + builder: (context, snapshot) { + return Transform.scale( + scale: snapshot.data!, + child: AnimatedContainer( + width: _width != null ? _width! * _scale : null, + duration: const Duration(milliseconds: 250), + child: FittedBox( + child: InkWell( + onTap: _onSelected, + splashColor: widget.splashColor, + highlightColor: widget.highlightColor, + child: widget.reaction.previewIcon, + ), + ), + ), + ); + }); }), ); } From 2e5dfc5e64b0873b7b7d4ed8f95c5070c966a4c8 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Sat, 23 Oct 2021 22:51:52 +0100 Subject: [PATCH 011/136] clean resources --- lib/src/ui/flutter_reaction_button_check.dart | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/src/ui/flutter_reaction_button_check.dart b/lib/src/ui/flutter_reaction_button_check.dart index 808aa8c..decb476 100644 --- a/lib/src/ui/flutter_reaction_button_check.dart +++ b/lib/src/ui/flutter_reaction_button_check.dart @@ -1,5 +1,3 @@ -import 'dart:async'; - import 'package:flutter/material.dart'; import '../models/reaction.dart'; @@ -79,10 +77,6 @@ class _FlutterReactionButtonCheckState extends State { final GlobalKey _buttonKey = GlobalKey(); - final int _maxTick = 2; - - Timer? _timer; - Reaction? _selectedReaction; bool _isChecked = false; From c56def69b50045616bc0cb401c3fdc70bade4ac9 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Sun, 24 Oct 2021 12:31:23 +0100 Subject: [PATCH 012/136] use AnimatedBuilder for item --- lib/src/ui/reactions_box_item.dart | 49 +++++++++--------------------- lib/src/ui/title.dart | 27 ++++++++++++++++ 2 files changed, 42 insertions(+), 34 deletions(-) create mode 100644 lib/src/ui/title.dart diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 0473625..747e7c1 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import '../models/drag.dart'; import '../models/reaction.dart'; import '../utils/extensions.dart'; +import 'title.dart'; class ReactionsBoxItem extends StatefulWidget { // TODO for test @@ -41,11 +42,6 @@ class _ReactionsBoxItemState extends State with TickerProviderStateMixin { final GlobalKey _widgetKey = GlobalKey(); - final StreamController _scaleControllerStream = - StreamController()..add(1); - - late Stream _scaleStream; - late AnimationController _scaleController; late Tween _startTween; @@ -66,27 +62,19 @@ class _ReactionsBoxItemState extends State widget.onReactionClick.call(widget.reaction); } - OverlayEntry _createTitle() { - RenderBox renderBox = context.findRenderObject() as RenderBox; - final size = renderBox.size; - final offset = renderBox.localToGlobal(Offset.zero); - - return OverlayEntry( - builder: (_) => Positioned( - left: offset.dx, - top: offset.dy - size.height * .5, - child: Material( - elevation: 0, - color: Colors.transparent, - child: widget.reaction.title ?? const SizedBox(), - ), + void _showTitle() { + final size = _widgetKey.widgetSize; + final offset = _widgetKey.widgetOffset; + + _overlayEntry = OverlayEntry( + builder: (_) => TitleWidget( + title: widget.reaction.title, + parentSize: size, + parentOffset: offset, ), ); - } - void _showTitle() { - _overlayEntry = _createTitle(); - Overlay.of(context)!.insert(_overlayEntry!); + Overlay.of(context)?.insert(_overlayEntry!); } void _hideTitle() { @@ -101,8 +89,6 @@ class _ReactionsBoxItemState extends State // Calculating how much we should scale down unselected items _minScale = 1 - (.2 / widget.itemsCount); - _scaleStream = _scaleControllerStream.stream; - // Start animation _scaleController = AnimationController(vsync: this, duration: Duration(milliseconds: 250)); @@ -111,11 +97,7 @@ class _ReactionsBoxItemState extends State _scaleAnimation = _startTween.animate(_scaleController) ..addListener(() { - /*setState(() { - _scale = _scaleAnimation.value; - });*/ _scale = _scaleAnimation.value; - _scaleControllerStream.add(_scale); if (_scale == _maxScale && _overlayEntry == null) { _showTitle(); @@ -128,7 +110,6 @@ class _ReactionsBoxItemState extends State @override void dispose() { _scaleController.dispose(); - _scaleControllerStream.close(); super.dispose(); } @@ -173,11 +154,11 @@ class _ReactionsBoxItemState extends State _startTween.begin = _normalScale; _scaleController.reverse(); } - return StreamBuilder( - stream: _scaleStream, - builder: (context, snapshot) { + return AnimatedBuilder( + animation: _scaleAnimation, + builder: (_, snapshot) { return Transform.scale( - scale: snapshot.data!, + scale: _scaleAnimation.value, child: AnimatedContainer( width: _width != null ? _width! * _scale : null, duration: const Duration(milliseconds: 250), diff --git a/lib/src/ui/title.dart b/lib/src/ui/title.dart new file mode 100644 index 0000000..6756b21 --- /dev/null +++ b/lib/src/ui/title.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +class TitleWidget extends StatelessWidget { + final Widget? title; + final Size parentSize; + final Offset parentOffset; + + const TitleWidget({ + Key? key, + required this.title, + required this.parentSize, + required this.parentOffset, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Positioned( + left: parentOffset.dx, + top: parentOffset.dy - parentSize.height * .5, + child: Material( + elevation: 0, + color: Colors.transparent, + child: title ?? const SizedBox(), + ), + ); + } +} From c16bf82bba307450af710419d762625d7c798dd4 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Sun, 24 Oct 2021 13:27:53 +0100 Subject: [PATCH 013/136] remove unused resources --- lib/src/ui/flutter_reaction_button.dart | 10 ---------- lib/src/ui/flutter_reaction_button_check.dart | 10 ---------- lib/src/ui/reactions_box.dart | 8 -------- lib/src/ui/reactions_box_item.dart | 11 ++--------- 4 files changed, 2 insertions(+), 37 deletions(-) diff --git a/lib/src/ui/flutter_reaction_button.dart b/lib/src/ui/flutter_reaction_button.dart index b2da252..65e196c 100644 --- a/lib/src/ui/flutter_reaction_button.dart +++ b/lib/src/ui/flutter_reaction_button.dart @@ -16,10 +16,6 @@ class FlutterReactionButton extends StatefulWidget { final List reactions; - final Color? highlightColor; - - final Color? splashColor; - /// Position reactions box for the button [default = TOP] final Position boxPosition; @@ -50,8 +46,6 @@ class FlutterReactionButton extends StatefulWidget { required this.onReactionChanged, required this.reactions, this.initialReaction, - this.highlightColor, - this.splashColor, this.boxPosition = Position.TOP, this.boxColor = Colors.white, this.boxElevation = 5, @@ -91,8 +85,6 @@ class _FlutterReactionButtonState extends State { @override Widget build(BuildContext context) => InkWell( key: _buttonKey, - highlightColor: widget.highlightColor, - splashColor: widget.splashColor, onTap: () => _showReactionButtons(context), child: (_selectedReaction ?? widget.reactions[0]).icon, ); @@ -113,8 +105,6 @@ class _FlutterReactionButtonState extends State { elevation: widget.boxElevation, radius: widget.boxRadius, duration: widget.boxDuration, - highlightColor: widget.highlightColor, - splashColor: widget.splashColor, alignment: widget.boxAlignment, boxPadding: widget.boxPadding, boxItemsSpacing: widget.boxItemsSpacing, diff --git a/lib/src/ui/flutter_reaction_button_check.dart b/lib/src/ui/flutter_reaction_button_check.dart index decb476..07906f6 100644 --- a/lib/src/ui/flutter_reaction_button_check.dart +++ b/lib/src/ui/flutter_reaction_button_check.dart @@ -19,10 +19,6 @@ class FlutterReactionButtonCheck extends StatefulWidget { final List reactions; - final Color? highlightColor; - - final Color? splashColor; - /// Position reactions box for the button [default = TOP] final Position boxPosition; @@ -55,8 +51,6 @@ class FlutterReactionButtonCheck extends StatefulWidget { required this.reactions, this.initialReaction, this.selectedReaction, - this.highlightColor, - this.splashColor, this.boxPosition = Position.TOP, this.boxColor = Colors.white, this.boxElevation = 5, @@ -102,8 +96,6 @@ class _FlutterReactionButtonCheckState @override Widget build(BuildContext context) => InkWell( key: _buttonKey, - highlightColor: widget.highlightColor, - splashColor: widget.splashColor, onTap: () { _onClickReactionButton(); }, @@ -138,8 +130,6 @@ class _FlutterReactionButtonCheckState elevation: widget.boxElevation, radius: widget.boxRadius, duration: widget.boxDuration, - highlightColor: widget.highlightColor, - splashColor: widget.splashColor, alignment: widget.boxAlignment, boxPadding: widget.boxPadding, boxItemsSpacing: widget.boxItemsSpacing, diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index 076e176..8e5041e 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -25,10 +25,6 @@ class ReactionsBox extends StatefulWidget { final Duration duration; - final Color? highlightColor; - - final Color? splashColor; - final AlignmentGeometry alignment; final EdgeInsets boxPadding; @@ -45,8 +41,6 @@ class ReactionsBox extends StatefulWidget { this.elevation = 5, this.radius = 50, this.duration = const Duration(milliseconds: 200), - this.highlightColor, - this.splashColor, this.alignment = Alignment.center, this.boxPadding = const EdgeInsets.all(0), this.boxItemsSpacing = 0, @@ -187,8 +181,6 @@ class _ReactionsBoxState extends State _selectedReaction = reaction; _scaleController.reverse(); }, - splashColor: widget.splashColor, - highlightColor: widget.highlightColor, itemsCount: widget.reactions.length, reaction: reaction!, dragStream: _dragStream, diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 747e7c1..98e4a5f 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -19,10 +19,6 @@ class ReactionsBoxItem extends StatefulWidget { final Stream dragStream; - final Color? highlightColor; - - final Color? splashColor; - const ReactionsBoxItem({ Key? key, required this.index, @@ -30,8 +26,6 @@ class ReactionsBoxItem extends StatefulWidget { required this.onReactionClick, required this.itemsCount, required this.dragStream, - this.highlightColor, - this.splashColor, }) : super(key: key); @override @@ -154,6 +148,7 @@ class _ReactionsBoxItemState extends State _startTween.begin = _normalScale; _scaleController.reverse(); } + return AnimatedBuilder( animation: _scaleAnimation, builder: (_, snapshot) { @@ -163,10 +158,8 @@ class _ReactionsBoxItemState extends State width: _width != null ? _width! * _scale : null, duration: const Duration(milliseconds: 250), child: FittedBox( - child: InkWell( + child: GestureDetector( onTap: _onSelected, - splashColor: widget.splashColor, - highlightColor: widget.highlightColor, child: widget.reaction.previewIcon, ), ), From 11bfcd95962ac27fb111e09a11632faa80bfbb1b Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Mon, 25 Oct 2021 21:27:52 +0100 Subject: [PATCH 014/136] fix reverse scale --- example/lib/main.dart | 1 + lib/src/ui/reactions_box_item.dart | 145 ++++++++++++++++------------- 2 files changed, 82 insertions(+), 64 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index a4ed672..c5aecb0 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -14,6 +14,7 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { @override Widget build(BuildContext context) => MaterialApp( + debugShowMaterialGrid: true, debugShowCheckedModeBanner: false, title: 'Flutter Reaction Button', home: Scaffold( diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 98e4a5f..2f8faac 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -38,11 +38,17 @@ class _ReactionsBoxItemState extends State late AnimationController _scaleController; - late Tween _startTween; + late Tween _scaleTween; late Animation _scaleAnimation; - double _minScale = 1, _normalScale = 1, _maxScale = 1.2; + static const double _DELTA_SCALE = .2; + + double _minScale = 1; + + double _normalScale = 1; + + double _maxScale = 1 + _DELTA_SCALE; double _scale = 1; @@ -76,29 +82,37 @@ class _ReactionsBoxItemState extends State _overlayEntry = null; } + late void Function() _listener; + + void _updateAnimation({double? begin, double? end}) { + _scaleTween = Tween(begin: begin ?? _normalScale, end: end ?? _maxScale); + _scaleAnimation = _scaleTween.animate(_scaleController); + _scaleAnimation + ..removeListener(_listener) + ..addListener(_listener); + } + @override void initState() { super.initState(); // Calculating how much we should scale down unselected items - _minScale = 1 - (.2 / widget.itemsCount); + _minScale = 1 - (_DELTA_SCALE / widget.itemsCount); - // Start animation _scaleController = AnimationController(vsync: this, duration: Duration(milliseconds: 250)); - _startTween = Tween(begin: _normalScale, end: _maxScale); + _listener = () { + _scale = _scaleAnimation.value; - _scaleAnimation = _startTween.animate(_scaleController) - ..addListener(() { - _scale = _scaleAnimation.value; + if (_scale == _maxScale && _overlayEntry == null) { + _showTitle(); + } else if (_scale <= _normalScale) { + _hideTitle(); + } + }; - if (_scale == _maxScale && _overlayEntry == null) { - _showTitle(); - } else if (_scale <= _normalScale) { - _hideTitle(); - } - }); + _updateAnimation(begin: _normalScale, end: _maxScale); } @override @@ -113,60 +127,63 @@ class _ReactionsBoxItemState extends State key: _widgetKey, ignoring: !widget.reaction.enabled, child: StreamBuilder( - stream: widget.dragStream, - builder: (_, snapshot) { - if (snapshot.hasData) { - final dragData = snapshot.data; - final Offset currentOffset = dragData?.offset ?? Offset.zero; - final widgetSize = _widgetKey.widgetSize; - if (_width == null) { - _width = widgetSize.width; - } - final deltaOffset = currentOffset - _widgetKey.widgetOffset; - final isHovered = - _width! > deltaOffset.distance && widget.reaction.enabled; - if (isHovered) { - bool isSelected = snapshot.data?.isDragEnd ?? false; - if (isSelected) { - _onSelected(); - } else { - _scaleController.forward(); - } + stream: widget.dragStream, + builder: (_, snapshot) { + if (snapshot.hasData) { + final dragData = snapshot.data; + final Offset currentOffset = dragData?.offset ?? Offset.zero; + final widgetSize = _widgetKey.widgetSize; + if (_width == null) { + _width = widgetSize.width; + } + final deltaOffset = currentOffset - _widgetKey.widgetOffset; + final isHovered = + _width! > deltaOffset.distance && widget.reaction.enabled; + if (isHovered) { + bool isSelected = snapshot.data?.isDragEnd ?? false; + if (isSelected) { + _onSelected(); } else { - bool isDraggingEnded = dragData?.isDragEnd ?? false; - if (isDraggingEnded) { - _startTween.begin = _normalScale; - WidgetsBinding.instance!.addPostFrameCallback((_) { - _scaleController.reset(); - }); - } else { - _startTween.begin = _minScale; - _scaleController.reverse(); - } + _scaleController.forward(); } } else { - _startTween.begin = _normalScale; - _scaleController.reverse(); - } - - return AnimatedBuilder( - animation: _scaleAnimation, - builder: (_, snapshot) { - return Transform.scale( - scale: _scaleAnimation.value, - child: AnimatedContainer( - width: _width != null ? _width! * _scale : null, - duration: const Duration(milliseconds: 250), - child: FittedBox( - child: GestureDetector( - onTap: _onSelected, - child: widget.reaction.previewIcon, - ), - ), - ), - ); + bool isDraggingEnded = dragData?.isDragEnd ?? false; + if (isDraggingEnded) { + _updateAnimation(begin: _normalScale, end: _normalScale); + _scaleController.forward(); + } else { + _updateAnimation(begin: _minScale); + WidgetsBinding.instance?.addPostFrameCallback((_) { + _scaleController.reset(); }); - }), + } + } + } else { + _updateAnimation(begin: _normalScale); + _scaleController.reverse(); + } + + return AnimatedBuilder( + animation: _scaleAnimation, + child: FittedBox( + child: GestureDetector( + onTap: _onSelected, + child: widget.reaction.previewIcon, + ), + ), + builder: (_, child) { + return Transform.scale( + scale: _scaleAnimation.value, + child: AnimatedContainer( + width: _width != null ? _width! * _scale : null, + duration: const Duration(milliseconds: 250), + child: child, + ), + ); + }, + ); + }, + ), ); } } From 4e66e3e40c153ab84f00b1baae5e3643e5a58617 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Mon, 25 Oct 2021 21:49:25 +0100 Subject: [PATCH 015/136] rearrange code --- example/lib/data/example_data.dart | 108 +++++----- example/lib/items/comments.dart | 199 +++++++++--------- example/lib/items/item.dart | 39 ++-- example/lib/main.dart | 47 +++-- lib/src/models/reaction.dart | 23 +- lib/src/ui/flutter_reaction_button.dart | 42 ++-- lib/src/ui/flutter_reaction_button_check.dart | 56 ++--- lib/src/ui/reactions_box.dart | 78 +++---- lib/src/ui/reactions_box_item.dart | 26 +-- lib/src/utils/extensions.dart | 4 +- 10 files changed, 339 insertions(+), 283 deletions(-) diff --git a/example/lib/data/example_data.dart b/example/lib/data/example_data.dart index ee59f8c..74e697b 100644 --- a/example/lib/data/example_data.dart +++ b/example/lib/data/example_data.dart @@ -114,58 +114,68 @@ final reactions = [ ), ]; -Widget _builFlagsdPreviewIcon(String path, String text) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), - child: Column( - children: [ - Text( - text, - style: TextStyle( - fontSize: 10, - fontWeight: FontWeight.w300, - color: Colors.white, - ), +Padding _builFlagsdPreviewIcon(String path, String text) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + child: Column( + children: [ + Text( + text, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w300, + color: Colors.white, ), - const SizedBox(height: 7.5), - Image.asset(path, height: 30), - ], - ), - ); - -Widget _buildTitle(String title) => Container( - padding: const EdgeInsets.symmetric(horizontal: 7.5, vertical: 2.5), - decoration: BoxDecoration( - color: Colors.red, - borderRadius: BorderRadius.circular(15), - ), - child: Text( - title, - style: TextStyle( - color: Colors.white, - fontSize: 10, - fontWeight: FontWeight.bold, ), + const SizedBox(height: 7.5), + Image.asset(path, height: 30), + ], + ), + ); +} + +Container _buildTitle(String title) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 7.5, vertical: 2.5), + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(15), + ), + child: Text( + title, + style: TextStyle( + color: Colors.white, + fontSize: 10, + fontWeight: FontWeight.bold, ), - ); + ), + ); +} -Widget _buildReactionsPreviewIcon(String path) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 3.5, vertical: 5), - child: Image.asset(path, height: 40), - ); +Padding _buildReactionsPreviewIcon(String path) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 3.5, vertical: 5), + child: Image.asset(path, height: 40), + ); +} -Widget _buildIcon(String path) => Image.asset( - path, - height: 30, - width: 30, - ); +Image _buildIcon(String path) { + return Image.asset( + path, + height: 30, + width: 30, + ); +} -Widget _buildReactionsIcon(String path, Text text) => Container( - color: Colors.transparent, - child: Row( - children: [ - Image.asset(path, height: 20), - const SizedBox(width: 5), - text, - ], - ), - ); +Container _buildReactionsIcon(String path, Text text) { + return Container( + color: Colors.transparent, + child: Row( + children: [ + Image.asset(path, height: 20), + const SizedBox(width: 5), + text, + ], + ), + ); +} diff --git a/example/lib/items/comments.dart b/example/lib/items/comments.dart index 010fcab..984b7dd 100644 --- a/example/lib/items/comments.dart +++ b/example/lib/items/comments.dart @@ -20,7 +20,7 @@ class _CommentsState extends State { super.dispose(); } - _onSubmiteComment() { + void _onSubmiteComment() { if (_textEditingController.text.isEmpty) return; setState(() { final comment = Comment( @@ -33,115 +33,124 @@ class _CommentsState extends State { } @override - Widget build(BuildContext context) => Column( - children: [ - const SizedBox(height: 20), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: widget.comments.isEmpty - ? Center( - child: const Text( - 'No comment yet', - style: TextStyle( - fontSize: 18, - ), + Widget build(BuildContext context) { + return Column( + children: [ + const SizedBox(height: 20), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: widget.comments.isEmpty + ? Center( + child: const Text( + 'No comment yet', + style: TextStyle( + fontSize: 18, ), - ) - : ListView.builder( - physics: BouncingScrollPhysics(), - itemCount: widget.comments.length, - itemBuilder: (context, index) => - buildComment(widget.comments[index]), ), - ), + ) + : ListView.builder( + physics: BouncingScrollPhysics(), + itemCount: widget.comments.length, + itemBuilder: (context, index) { + return buildComment(widget.comments[index]); + }, + ), ), - buildCommentField(), - ], - ); + ), + buildCommentField(), + ], + ); + } - Widget buildComment(Comment comment) => SizedBox( - height: 75, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 40, - width: 40, + SizedBox buildComment(Comment comment) { + return SizedBox( + height: 75, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 40, + width: 40, + child: CircleAvatar( + radius: 100, child: CircleAvatar( - radius: 100, - child: CircleAvatar( - child: Text(comment.name.substring(0, 1).toUpperCase()), + child: Text( + comment.name.substring(0, 1).toUpperCase(), ), ), ), - const SizedBox(width: 10), - Expanded( - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 5, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: Colors.grey[200], - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - comment.name, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 15, - fontWeight: FontWeight.w700, - color: Colors.black.withOpacity(.9), - ), + ), + const SizedBox(width: 10), + Expanded( + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 5, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.grey[200], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + comment.name, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w700, + color: Colors.black.withOpacity(.9), ), - Text( - comment.content, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 17, - fontWeight: FontWeight.w400, - color: Colors.black.withOpacity(.75), - ), + ), + Text( + comment.content, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w400, + color: Colors.black.withOpacity(.75), ), - ], - ), + ), + ], ), ), - ], - ), - ); + ), + ], + ), + ); + } - Widget buildCommentField() => Container( - margin: const EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.grey[300]?.withOpacity(.5), - borderRadius: BorderRadius.circular(30), + Container buildCommentField() { + return Container( + margin: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.grey[300]?.withOpacity(.5), + borderRadius: BorderRadius.circular(30), + ), + child: TextFormField( + controller: _textEditingController, + style: TextStyle( + fontSize: 18, ), - child: TextFormField( - controller: _textEditingController, - style: TextStyle( - fontSize: 18, + decoration: InputDecoration( + hintText: 'Write a comment...', + border: InputBorder.none, + icon: SizedBox( + width: 10, ), - decoration: InputDecoration( - hintText: 'Write a comment...', - border: InputBorder.none, - icon: SizedBox( - width: 10, - ), - suffixIcon: IconButton( - icon: Icon(Icons.send), - onPressed: () => _onSubmiteComment(), - ), + suffixIcon: IconButton( + icon: Icon(Icons.send), + onPressed: _onSubmiteComment, ), - onFieldSubmitted: (_) => _onSubmiteComment(), ), - ); + onFieldSubmitted: (_) => _onSubmiteComment(), + ), + ); + } } diff --git a/example/lib/items/item.dart b/example/lib/items/item.dart index 53d2fb3..3d31da1 100644 --- a/example/lib/items/item.dart +++ b/example/lib/items/item.dart @@ -25,7 +25,9 @@ class _ItemState extends State with AutomaticKeepAliveClientMixin { void _showBottomSheetCommets() { showBottomSheet( context: context, - builder: (context) => Comments(_comments), + builder: (context) { + return Comments(_comments); + }, ); } @@ -36,7 +38,9 @@ class _ItemState extends State with AutomaticKeepAliveClientMixin { margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), elevation: 2, child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5)), + borderRadius: BorderRadius.all( + Radius.circular(5), + ), child: Column( children: [ AspectRatio( @@ -83,21 +87,26 @@ class _ItemState extends State with AutomaticKeepAliveClientMixin { const SizedBox(width: 5), Text( 'Comment', - style: - TextStyle(fontSize: 17, color: Colors.grey[600]), + style: TextStyle( + fontSize: 17, + color: Colors.grey[600], + ), ), ], ), ), InkWell( - onTap: () => - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - duration: Duration(seconds: 2), - content: Text( - 'Share image ${widget.title}', - style: TextStyle(color: Colors.white), - ), - )), + onTap: () { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: Duration(seconds: 2), + content: Text( + 'Share image ${widget.title}', + style: TextStyle(color: Colors.white), + ), + ), + ); + }, child: Row( children: [ Icon( @@ -108,8 +117,10 @@ class _ItemState extends State with AutomaticKeepAliveClientMixin { const SizedBox(width: 5), Text( 'Share', - style: - TextStyle(fontSize: 17, color: Colors.grey[600]), + style: TextStyle( + fontSize: 17, + color: Colors.grey[600], + ), ), ], ), diff --git a/example/lib/main.dart b/example/lib/main.dart index c5aecb0..9cd1ce6 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -13,17 +13,18 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { @override - Widget build(BuildContext context) => MaterialApp( - debugShowMaterialGrid: true, - debugShowCheckedModeBanner: false, - title: 'Flutter Reaction Button', - home: Scaffold( - backgroundColor: Colors.grey[200], - appBar: AppBar( - title: const Text('Flutter Reaction Button'), - actions: [ - Builder( - builder: (ctx) => FlutterReactionButton( + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + title: 'Flutter Reaction Button', + home: Scaffold( + backgroundColor: Colors.grey[200], + appBar: AppBar( + title: const Text('Flutter Reaction Button'), + actions: [ + Builder( + builder: (ctx) { + return FlutterReactionButton( onReactionChanged: (reaction, index) { ScaffoldMessenger.of(ctx).showSnackBar( SnackBar( @@ -37,13 +38,15 @@ class _MyAppState extends State { boxRadius: 10, boxDuration: Duration(milliseconds: 500), boxAlignment: AlignmentDirectional.bottomEnd, - ), - ), - SizedBox(width: 10), - ], - ), - body: Builder( - builder: (context) => ListView( + ); + }, + ), + SizedBox(width: 10), + ], + ), + body: Builder( + builder: (_) { + return ListView( padding: const EdgeInsets.symmetric(vertical: 5), children: [ Item( @@ -72,8 +75,10 @@ class _MyAppState extends State { Example.reactions, ), ], - ), - ), + ); + }, ), - ); + ), + ); + } } diff --git a/lib/src/models/reaction.dart b/lib/src/models/reaction.dart index b437d7b..d382963 100644 --- a/lib/src/models/reaction.dart +++ b/lib/src/models/reaction.dart @@ -28,16 +28,19 @@ class Reaction { }) : this.previewIcon = previewIcon ?? icon; @override - bool operator ==(Object? object) => - object != null && - object is Reaction && - icon == object.icon && - icon.key == object.icon.key && - previewIcon == object.previewIcon && - previewIcon.key == object.previewIcon.key && - title == object.title && - title?.key == object.title?.key; + bool operator ==(Object? object) { + return object != null && + object is Reaction && + icon == object.icon && + icon.key == object.icon.key && + previewIcon == object.previewIcon && + previewIcon.key == object.previewIcon.key && + title == object.title && + title?.key == object.title?.key; + } @override - int get hashCode => hashValues(icon, previewIcon, title); + int get hashCode { + return hashValues(icon, previewIcon, title); + } } diff --git a/lib/src/ui/flutter_reaction_button.dart b/lib/src/ui/flutter_reaction_button.dart index 65e196c..065fee6 100644 --- a/lib/src/ui/flutter_reaction_button.dart +++ b/lib/src/ui/flutter_reaction_button.dart @@ -83,11 +83,15 @@ class _FlutterReactionButtonState extends State { } @override - Widget build(BuildContext context) => InkWell( - key: _buttonKey, - onTap: () => _showReactionButtons(context), - child: (_selectedReaction ?? widget.reactions[0]).icon, - ); + Widget build(BuildContext context) { + return InkWell( + key: _buttonKey, + onTap: () { + _showReactionButtons(context); + }, + child: (_selectedReaction ?? widget.reactions[0]).icon, + ); + } void _showReactionButtons(BuildContext context) async { final buttonOffset = _buttonKey.widgetOffset; @@ -96,19 +100,21 @@ class _FlutterReactionButtonState extends State { PageRouteBuilder( opaque: false, transitionDuration: const Duration(milliseconds: 200), - pageBuilder: (_, __, ___) => ReactionsBox( - buttonOffset: buttonOffset, - buttonSize: buttonSize, - reactions: widget.reactions, - position: widget.boxPosition, - color: widget.boxColor, - elevation: widget.boxElevation, - radius: widget.boxRadius, - duration: widget.boxDuration, - alignment: widget.boxAlignment, - boxPadding: widget.boxPadding, - boxItemsSpacing: widget.boxItemsSpacing, - ), + pageBuilder: (_, __, ___) { + return ReactionsBox( + buttonOffset: buttonOffset, + buttonSize: buttonSize, + reactions: widget.reactions, + position: widget.boxPosition, + color: widget.boxColor, + elevation: widget.boxElevation, + radius: widget.boxRadius, + duration: widget.boxDuration, + alignment: widget.boxAlignment, + boxPadding: widget.boxPadding, + boxItemsSpacing: widget.boxItemsSpacing, + ); + }, ), ); diff --git a/lib/src/ui/flutter_reaction_button_check.dart b/lib/src/ui/flutter_reaction_button_check.dart index 07906f6..e04c5bd 100644 --- a/lib/src/ui/flutter_reaction_button_check.dart +++ b/lib/src/ui/flutter_reaction_button_check.dart @@ -94,16 +94,18 @@ class _FlutterReactionButtonCheckState } @override - Widget build(BuildContext context) => InkWell( - key: _buttonKey, - onTap: () { - _onClickReactionButton(); - }, - onLongPress: () { - _showReactionButtons(context); - }, - child: (_selectedReaction ?? widget.reactions[0])!.icon, - ); + Widget build(BuildContext context) { + return InkWell( + key: _buttonKey, + onTap: () { + _onClickReactionButton(); + }, + onLongPress: () { + _showReactionButtons(context); + }, + child: (_selectedReaction ?? widget.reactions[0])!.icon, + ); + } void _onClickReactionButton() { _isChecked = !_isChecked; @@ -121,27 +123,31 @@ class _FlutterReactionButtonCheckState PageRouteBuilder( opaque: false, transitionDuration: const Duration(milliseconds: 200), - pageBuilder: (_, __, ___) => ReactionsBox( - buttonOffset: buttonOffset, - buttonSize: buttonSize, - reactions: widget.reactions, - position: widget.boxPosition, - color: widget.boxColor, - elevation: widget.boxElevation, - radius: widget.boxRadius, - duration: widget.boxDuration, - alignment: widget.boxAlignment, - boxPadding: widget.boxPadding, - boxItemsSpacing: widget.boxItemsSpacing, - ), + pageBuilder: (_, __, ___) { + return ReactionsBox( + buttonOffset: buttonOffset, + buttonSize: buttonSize, + reactions: widget.reactions, + position: widget.boxPosition, + color: widget.boxColor, + elevation: widget.boxElevation, + radius: widget.boxRadius, + duration: widget.boxDuration, + alignment: widget.boxAlignment, + boxPadding: widget.boxPadding, + boxItemsSpacing: widget.boxItemsSpacing, + ); + }, ), ); if (reactionButton != null) _updateReaction(reactionButton, true); } - void _updateReaction(Reaction? reaction, - [bool isSelectedFromDialog = false]) { + void _updateReaction( + Reaction? reaction, [ + bool isSelectedFromDialog = false, + ]) { _isChecked = isSelectedFromDialog ? true : reaction != widget.initialReaction; widget.onReactionChanged.call( diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index 8e5041e..55364cd 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -52,9 +52,9 @@ class ReactionsBox extends StatefulWidget { class _ReactionsBoxState extends State with TickerProviderStateMixin { - StreamController _dragStreamController = - StreamController(); - late Stream _dragStream; + StreamController _dragStreamController = + StreamController(); + late Stream _dragStream; late AnimationController _scaleController; @@ -64,7 +64,7 @@ class _ReactionsBoxState extends State Reaction? _selectedReaction; - late DragData _dragData; + DragData? _dragData; @override void initState() { @@ -108,7 +108,9 @@ class _ReactionsBoxState extends State children: [ Positioned.fill( child: Listener( - onPointerDown: (_) => _scaleController.reverse(), + onPointerDown: (_) { + _scaleController.reverse(); + }, child: Container( color: Colors.transparent, ), @@ -147,7 +149,7 @@ class _ReactionsBoxState extends State ); } - Widget _buildDumpItems() { + Padding _buildDumpItems() { return Padding( padding: widget.boxPadding, child: Wrap( @@ -159,7 +161,7 @@ class _ReactionsBoxState extends State ); } - Widget _buildItems() { + Padding _buildItems() { return Padding( padding: widget.boxPadding, child: Listener( @@ -168,43 +170,45 @@ class _ReactionsBoxState extends State _dragStreamController.add(_dragData); }, onPointerUp: (point) { - _dragData = _dragData.copyWith(isDragEnd: true); + _dragData = _dragData?.copyWith(isDragEnd: true); _dragStreamController.add(_dragData); }, child: Wrap( spacing: widget.boxItemsSpacing, - children: widget.reactions - .map( - (reaction) => ReactionsBoxItem( - index: widget.reactions.indexOf(reaction), - onReactionClick: (reaction) { - _selectedReaction = reaction; - _scaleController.reverse(); - }, - itemsCount: widget.reactions.length, - reaction: reaction!, - dragStream: _dragStream, - ), - ) - .toList(), + children: widget.reactions.map( + (reaction) { + return ReactionsBoxItem( + onReactionClick: (reaction) { + _selectedReaction = reaction; + _scaleController.reverse(); + }, + itemsCount: widget.reactions.length, + reaction: reaction!, + dragStream: _dragStream, + ); + }, + ).toList(), ), ), ); } - double _getPosition(BuildContext context) => - (_getTopPosition() - widget.buttonSize.height * 2 < 0) - ? _getBottomPosition() - : (_getBottomPosition() + widget.buttonSize.height * 2 > - context.screenSize.height) - ? _getTopPosition() - : widget.position == Position.TOP - ? _getTopPosition() - : _getBottomPosition(); - - double _getTopPosition() => - widget.buttonOffset.dy - widget.buttonSize.height * 3.3; - - double _getBottomPosition() => - widget.buttonOffset.dy + widget.buttonSize.height; + double _getPosition(BuildContext context) { + return (_getTopPosition() - widget.buttonSize.height * 2 < 0) + ? _getBottomPosition() + : (_getBottomPosition() + widget.buttonSize.height * 2 > + context.screenSize.height) + ? _getTopPosition() + : widget.position == Position.TOP + ? _getTopPosition() + : _getBottomPosition(); + } + + double _getTopPosition() { + return widget.buttonOffset.dy - widget.buttonSize.height * 3.3; + } + + double _getBottomPosition() { + return widget.buttonOffset.dy + widget.buttonSize.height; + } } diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 2f8faac..6249298 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -8,20 +8,16 @@ import '../utils/extensions.dart'; import 'title.dart'; class ReactionsBoxItem extends StatefulWidget { - // TODO for test - final int index; - final Function(Reaction?) onReactionClick; final Reaction reaction; final int itemsCount; - final Stream dragStream; + final Stream dragStream; const ReactionsBoxItem({ Key? key, - required this.index, required this.reaction, required this.onReactionClick, required this.itemsCount, @@ -67,11 +63,13 @@ class _ReactionsBoxItemState extends State final offset = _widgetKey.widgetOffset; _overlayEntry = OverlayEntry( - builder: (_) => TitleWidget( - title: widget.reaction.title, - parentSize: size, - parentOffset: offset, - ), + builder: (_) { + return TitleWidget( + title: widget.reaction.title, + parentSize: size, + parentOffset: offset, + ); + }, ); Overlay.of(context)?.insert(_overlayEntry!); @@ -99,8 +97,10 @@ class _ReactionsBoxItemState extends State // Calculating how much we should scale down unselected items _minScale = 1 - (_DELTA_SCALE / widget.itemsCount); - _scaleController = - AnimationController(vsync: this, duration: Duration(milliseconds: 250)); + _scaleController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 250), + ); _listener = () { _scale = _scaleAnimation.value; @@ -126,7 +126,7 @@ class _ReactionsBoxItemState extends State return IgnorePointer( key: _widgetKey, ignoring: !widget.reaction.enabled, - child: StreamBuilder( + child: StreamBuilder( stream: widget.dragStream, builder: (_, snapshot) { if (snapshot.hasData) { diff --git a/lib/src/utils/extensions.dart b/lib/src/utils/extensions.dart index c334d73..98921aa 100644 --- a/lib/src/utils/extensions.dart +++ b/lib/src/utils/extensions.dart @@ -15,5 +15,7 @@ extension KeyExtensions on GlobalKey { } extension ContextExtensions on BuildContext { - Size get screenSize => MediaQuery.of(this).size; + Size get screenSize { + return MediaQuery.of(this).size; + } } From 974a113c7f35cae8ba4ce866d120f89a488b40a4 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Mon, 25 Oct 2021 22:13:14 +0100 Subject: [PATCH 016/136] handle click from box --- lib/src/ui/reactions_box.dart | 4 ++++ lib/src/ui/reactions_box_item.dart | 9 +++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index 55364cd..fe519ab 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -165,6 +165,10 @@ class _ReactionsBoxState extends State return Padding( padding: widget.boxPadding, child: Listener( + onPointerDown: (point) { + _dragData = DragData(offset: point.position); + _dragStreamController.add(_dragData); + }, onPointerMove: (point) { _dragData = DragData(offset: point.position); _dragStreamController.add(_dragData); diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 6249298..43a9cd7 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -138,7 +138,7 @@ class _ReactionsBoxItemState extends State } final deltaOffset = currentOffset - _widgetKey.widgetOffset; final isHovered = - _width! > deltaOffset.distance && widget.reaction.enabled; + _width! * .9 > deltaOffset.distance && widget.reaction.enabled; if (isHovered) { bool isSelected = snapshot.data?.isDragEnd ?? false; if (isSelected) { @@ -159,17 +159,14 @@ class _ReactionsBoxItemState extends State } } } else { - _updateAnimation(begin: _normalScale); + _updateAnimation(begin: _minScale); _scaleController.reverse(); } return AnimatedBuilder( animation: _scaleAnimation, child: FittedBox( - child: GestureDetector( - onTap: _onSelected, - child: widget.reaction.previewIcon, - ), + child: widget.reaction.previewIcon, ), builder: (_, child) { return Transform.scale( From 30b8b3e4593425929999a870d8b5f1b750e6c336 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Tue, 26 Oct 2021 20:44:12 +0100 Subject: [PATCH 017/136] reset box items state --- lib/src/ui/reactions_box_item.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 43a9cd7..d4f83ee 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -149,8 +149,10 @@ class _ReactionsBoxItemState extends State } else { bool isDraggingEnded = dragData?.isDragEnd ?? false; if (isDraggingEnded) { - _updateAnimation(begin: _normalScale, end: _normalScale); - _scaleController.forward(); + _updateAnimation(begin: _normalScale, end: _maxScale); + WidgetsBinding.instance?.addPostFrameCallback((_) { + _scaleController.reset(); + }); } else { _updateAnimation(begin: _minScale); WidgetsBinding.instance?.addPostFrameCallback((_) { From 00fa8ae85ccf696809ede236e32f2580df9f0887 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Tue, 26 Oct 2021 20:45:06 +0100 Subject: [PATCH 018/136] reset box items state --- lib/src/ui/reactions_box_item.dart | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index d4f83ee..b76b5d1 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -148,17 +148,14 @@ class _ReactionsBoxItemState extends State } } else { bool isDraggingEnded = dragData?.isDragEnd ?? false; - if (isDraggingEnded) { + if (isDraggingEnded) _updateAnimation(begin: _normalScale, end: _maxScale); - WidgetsBinding.instance?.addPostFrameCallback((_) { - _scaleController.reset(); - }); - } else { + else _updateAnimation(begin: _minScale); - WidgetsBinding.instance?.addPostFrameCallback((_) { - _scaleController.reset(); - }); - } + + WidgetsBinding.instance?.addPostFrameCallback((_) { + _scaleController.reset(); + }); } } else { _updateAnimation(begin: _minScale); From d36f199090f3bb32b6aedc2bf301af9f0a125110 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Tue, 26 Oct 2021 22:35:48 +0100 Subject: [PATCH 019/136] title in widget item --- example/lib/main.dart | 1 + lib/src/ui/reactions_box.dart | 164 +++++++++++++--------- lib/src/ui/reactions_box_item.dart | 51 +++---- lib/src/ui/title.dart | 27 ---- lib/src/ui/widget_size_render_object.dart | 42 ++++++ 5 files changed, 155 insertions(+), 130 deletions(-) delete mode 100644 lib/src/ui/title.dart create mode 100644 lib/src/ui/widget_size_render_object.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index 9cd1ce6..ba3b534 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -15,6 +15,7 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { return MaterialApp( + debugShowMaterialGrid: true, debugShowCheckedModeBanner: false, title: 'Flutter Reaction Button', home: Scaffold( diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index fe519ab..1627d93 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -7,6 +7,7 @@ import '../models/reaction.dart'; import '../utils/extensions.dart'; import '../utils/reactions_position.dart'; import 'reactions_box_item.dart'; +import 'widget_size_render_object.dart'; class ReactionsBox extends StatefulWidget { final Offset buttonOffset; @@ -56,25 +57,49 @@ class _ReactionsBoxState extends State StreamController(); late Stream _dragStream; + late AnimationController _boxSizeController; + + late Animation _boxSizeAnimation; + + late Tween _boxSizeTween; + late AnimationController _scaleController; late Animation _scaleAnimation; - double _scale = 0; - Reaction? _selectedReaction; DragData? _dragData; + double _scale = 0; + + double? _getBoxHeight() { + if (_boxSizeAnimation.value == null) return null; + + bool anyItemHasTitle = widget.reactions.any( + (item) => item?.title != null, + ); + + if (anyItemHasTitle) return _boxSizeAnimation.value!.height * .75; + + return _boxSizeAnimation.value!.height; + } + @override void initState() { super.initState(); + _boxSizeController = + AnimationController(vsync: this, duration: widget.duration); + + _boxSizeTween = Tween(); + _boxSizeAnimation = _boxSizeTween.animate(_boxSizeController); + _scaleController = AnimationController(vsync: this, duration: widget.duration); - final Tween startTween = Tween(begin: 0, end: 1); - _scaleAnimation = startTween.animate(_scaleController) + final Tween scaleTween = Tween(begin: 0, end: 1); + _scaleAnimation = scaleTween.animate(_scaleController) ..addListener(() { setState(() { _scale = _scaleAnimation.value; @@ -92,6 +117,7 @@ class _ReactionsBoxState extends State @override void dispose() { + _boxSizeController.dispose(); _scaleController.dispose(); _dragStreamController.close(); super.dispose(); @@ -100,6 +126,7 @@ class _ReactionsBoxState extends State @override Widget build(BuildContext context) { double top = _getPosition(context); + return Material( elevation: 0, color: Colors.transparent, @@ -120,78 +147,79 @@ class _ReactionsBoxState extends State top: top, child: Transform.scale( scale: _scale, - child: Material( - color: widget.color, - elevation: widget.elevation, - clipBehavior: Clip.antiAlias, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(widget.radius), - ), - child: IgnorePointer( - ignoring: true, - child: Opacity( - opacity: 0, - child: _buildDumpItems(), - ), - ), + child: AnimatedBuilder( + animation: _boxSizeAnimation, + child: _buildItems(), + builder: (_, child) { + return SizedBox( + height: _boxSizeAnimation.value?.height, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + Material( + color: widget.color, + elevation: widget.elevation, + clipBehavior: Clip.antiAlias, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(widget.radius), + ), + child: SizedBox( + height: _getBoxHeight(), + width: _boxSizeAnimation.value?.width, + ), + ), + child!, + ], + ), + ); + }, ), ), ), - Positioned( - top: top, - child: Transform.scale( - scale: _scale, - child: _buildItems(), - ), - ), ], ), ); } - Padding _buildDumpItems() { - return Padding( - padding: widget.boxPadding, - child: Wrap( - spacing: widget.boxItemsSpacing, - children: widget.reactions.map((reaction) { - return reaction!.previewIcon; - }).toList(), - ), - ); - } - - Padding _buildItems() { - return Padding( - padding: widget.boxPadding, - child: Listener( - onPointerDown: (point) { - _dragData = DragData(offset: point.position); - _dragStreamController.add(_dragData); - }, - onPointerMove: (point) { - _dragData = DragData(offset: point.position); - _dragStreamController.add(_dragData); - }, - onPointerUp: (point) { - _dragData = _dragData?.copyWith(isDragEnd: true); - _dragStreamController.add(_dragData); - }, - child: Wrap( - spacing: widget.boxItemsSpacing, - children: widget.reactions.map( - (reaction) { - return ReactionsBoxItem( - onReactionClick: (reaction) { - _selectedReaction = reaction; - _scaleController.reverse(); - }, - itemsCount: widget.reactions.length, - reaction: reaction!, - dragStream: _dragStream, - ); - }, - ).toList(), + Widget _buildItems() { + return WidgetSizeOffsetWrapper( + onSizeChange: (Size size) { + _boxSizeTween + ..begin = size + ..end = size; + _boxSizeController.forward(); + }, + child: Padding( + padding: widget.boxPadding, + child: Listener( + onPointerDown: (point) { + _dragData = DragData(offset: point.position); + _dragStreamController.add(_dragData); + }, + onPointerMove: (point) { + _dragData = DragData(offset: point.position); + _dragStreamController.add(_dragData); + }, + onPointerUp: (point) { + _dragData = _dragData?.copyWith(isDragEnd: true); + _dragStreamController.add(_dragData); + }, + child: Wrap( + spacing: widget.boxItemsSpacing, + children: widget.reactions.map( + (reaction) { + return ReactionsBoxItem( + onReactionClick: (reaction) { + _selectedReaction = reaction; + _scaleController.reverse(); + }, + itemsCount: widget.reactions.length, + reaction: reaction!, + dragStream: _dragStream, + ); + }, + ).toList(), + ), ), ), ); diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index b76b5d1..26b8ccc 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -5,10 +5,11 @@ import 'package:flutter/material.dart'; import '../models/drag.dart'; import '../models/reaction.dart'; import '../utils/extensions.dart'; -import 'title.dart'; + +typedef OnReactionClick = void Function(Reaction?); class ReactionsBoxItem extends StatefulWidget { - final Function(Reaction?) onReactionClick; + final OnReactionClick onReactionClick; final Reaction reaction; @@ -50,37 +51,12 @@ class _ReactionsBoxItemState extends State double? _width; - OverlayEntry? _overlayEntry; - void _onSelected() { - _hideTitle(); _scaleController.reverse(); widget.onReactionClick.call(widget.reaction); } - void _showTitle() { - final size = _widgetKey.widgetSize; - final offset = _widgetKey.widgetOffset; - - _overlayEntry = OverlayEntry( - builder: (_) { - return TitleWidget( - title: widget.reaction.title, - parentSize: size, - parentOffset: offset, - ); - }, - ); - - Overlay.of(context)?.insert(_overlayEntry!); - } - - void _hideTitle() { - _overlayEntry?.remove(); - _overlayEntry = null; - } - - late void Function() _listener; + late VoidCallback _listener; void _updateAnimation({double? begin, double? end}) { _scaleTween = Tween(begin: begin ?? _normalScale, end: end ?? _maxScale); @@ -104,12 +80,6 @@ class _ReactionsBoxItemState extends State _listener = () { _scale = _scaleAnimation.value; - - if (_scale == _maxScale && _overlayEntry == null) { - _showTitle(); - } else if (_scale <= _normalScale) { - _hideTitle(); - } }; _updateAnimation(begin: _normalScale, end: _maxScale); @@ -173,7 +143,18 @@ class _ReactionsBoxItemState extends State child: AnimatedContainer( width: _width != null ? _width! * _scale : null, duration: const Duration(milliseconds: 250), - child: child, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Opacity( + opacity: _scale == _maxScale ? 1 : 0, + child: FittedBox( + child: widget.reaction.title, + ), + ), + child!, + ], + ), ), ); }, diff --git a/lib/src/ui/title.dart b/lib/src/ui/title.dart deleted file mode 100644 index 6756b21..0000000 --- a/lib/src/ui/title.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -class TitleWidget extends StatelessWidget { - final Widget? title; - final Size parentSize; - final Offset parentOffset; - - const TitleWidget({ - Key? key, - required this.title, - required this.parentSize, - required this.parentOffset, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Positioned( - left: parentOffset.dx, - top: parentOffset.dy - parentSize.height * .5, - child: Material( - elevation: 0, - color: Colors.transparent, - child: title ?? const SizedBox(), - ), - ); - } -} diff --git a/lib/src/ui/widget_size_render_object.dart b/lib/src/ui/widget_size_render_object.dart new file mode 100644 index 0000000..cad1fe3 --- /dev/null +++ b/lib/src/ui/widget_size_render_object.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; + +class WidgetSizeRenderObject extends RenderProxyBox { + final Function(Size) onSizeChange; + Size? currentSize; + + WidgetSizeRenderObject(this.onSizeChange); + + @override + void performLayout() { + super.performLayout(); + + try { + Size? newSize = child?.size; + + if (newSize != null && currentSize != newSize) { + currentSize = newSize; + WidgetsBinding.instance?.addPostFrameCallback((_) { + onSizeChange(newSize); + }); + } + } catch (e) { + print(e); + } + } +} + +class WidgetSizeOffsetWrapper extends SingleChildRenderObjectWidget { + final Function(Size) onSizeChange; + + const WidgetSizeOffsetWrapper({ + Key? key, + required this.onSizeChange, + required Widget child, + }) : super(key: key, child: child); + + @override + RenderObject createRenderObject(BuildContext context) { + return WidgetSizeRenderObject(onSizeChange); + } +} From 0463489cd67f14038614814763d17f81b11457e7 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Wed, 27 Oct 2021 02:28:00 +0100 Subject: [PATCH 020/136] fittedbox for box item --- example/lib/main.dart | 1 - lib/src/ui/flutter_reaction_button.dart | 4 -- lib/src/ui/flutter_reaction_button_check.dart | 4 -- lib/src/ui/reactions_box.dart | 7 +-- lib/src/ui/reactions_box_item.dart | 57 ++++++++++--------- 5 files changed, 32 insertions(+), 41 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index ba3b534..9cd1ce6 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -15,7 +15,6 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { return MaterialApp( - debugShowMaterialGrid: true, debugShowCheckedModeBanner: false, title: 'Flutter Reaction Button', home: Scaffold( diff --git a/lib/src/ui/flutter_reaction_button.dart b/lib/src/ui/flutter_reaction_button.dart index 065fee6..153f207 100644 --- a/lib/src/ui/flutter_reaction_button.dart +++ b/lib/src/ui/flutter_reaction_button.dart @@ -39,8 +39,6 @@ class FlutterReactionButton extends StatefulWidget { final EdgeInsets boxPadding; - final double boxItemsSpacing; - FlutterReactionButton({ Key? key, required this.onReactionChanged, @@ -54,7 +52,6 @@ class FlutterReactionButton extends StatefulWidget { this.boxAlignment = Alignment.center, this.shouldChangeReaction = true, this.boxPadding = const EdgeInsets.all(0), - this.boxItemsSpacing = 0, }) : super(key: key); @override @@ -112,7 +109,6 @@ class _FlutterReactionButtonState extends State { duration: widget.boxDuration, alignment: widget.boxAlignment, boxPadding: widget.boxPadding, - boxItemsSpacing: widget.boxItemsSpacing, ); }, ), diff --git a/lib/src/ui/flutter_reaction_button_check.dart b/lib/src/ui/flutter_reaction_button_check.dart index e04c5bd..1e517b2 100644 --- a/lib/src/ui/flutter_reaction_button_check.dart +++ b/lib/src/ui/flutter_reaction_button_check.dart @@ -43,8 +43,6 @@ class FlutterReactionButtonCheck extends StatefulWidget { final EdgeInsets boxPadding; - final double boxItemsSpacing; - FlutterReactionButtonCheck({ Key? key, required this.onReactionChanged, @@ -59,7 +57,6 @@ class FlutterReactionButtonCheck extends StatefulWidget { this.boxAlignment = Alignment.center, this.isChecked = false, this.boxPadding = const EdgeInsets.all(0), - this.boxItemsSpacing = 0, }) : super(key: key); @override @@ -135,7 +132,6 @@ class _FlutterReactionButtonCheckState duration: widget.boxDuration, alignment: widget.boxAlignment, boxPadding: widget.boxPadding, - boxItemsSpacing: widget.boxItemsSpacing, ); }, ), diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index 1627d93..2b73670 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -30,8 +30,6 @@ class ReactionsBox extends StatefulWidget { final EdgeInsets boxPadding; - final double boxItemsSpacing; - const ReactionsBox({ Key? key, required this.buttonOffset, @@ -44,7 +42,6 @@ class ReactionsBox extends StatefulWidget { this.duration = const Duration(milliseconds: 200), this.alignment = Alignment.center, this.boxPadding = const EdgeInsets.all(0), - this.boxItemsSpacing = 0, }) : super(key: key); @override @@ -204,8 +201,8 @@ class _ReactionsBoxState extends State _dragData = _dragData?.copyWith(isDragEnd: true); _dragStreamController.add(_dragData); }, - child: Wrap( - spacing: widget.boxItemsSpacing, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, children: widget.reactions.map( (reaction) { return ReactionsBoxItem( diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 26b8ccc..79cf13b 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -94,7 +94,6 @@ class _ReactionsBoxItemState extends State @override Widget build(BuildContext context) { return IgnorePointer( - key: _widgetKey, ignoring: !widget.reaction.enabled, child: StreamBuilder( stream: widget.dragStream, @@ -107,8 +106,9 @@ class _ReactionsBoxItemState extends State _width = widgetSize.width; } final deltaOffset = currentOffset - _widgetKey.widgetOffset; - final isHovered = - _width! * .9 > deltaOffset.distance && widget.reaction.enabled; + final isHovered = widgetSize.width * widgetSize.height >= + deltaOffset.distanceSquared && + widget.reaction.enabled; if (isHovered) { bool isSelected = snapshot.data?.isDragEnd ?? false; if (isSelected) { @@ -132,32 +132,35 @@ class _ReactionsBoxItemState extends State _scaleController.reverse(); } - return AnimatedBuilder( - animation: _scaleAnimation, - child: FittedBox( - child: widget.reaction.previewIcon, - ), - builder: (_, child) { - return Transform.scale( - scale: _scaleAnimation.value, - child: AnimatedContainer( - width: _width != null ? _width! * _scale : null, - duration: const Duration(milliseconds: 250), - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Opacity( - opacity: _scale == _maxScale ? 1 : 0, - child: FittedBox( - child: widget.reaction.title, + return FittedBox( + child: AnimatedBuilder( + animation: _scaleAnimation, + child: FittedBox( + key: _widgetKey, + child: widget.reaction.previewIcon, + ), + builder: (_, child) { + return Transform.scale( + scale: _scaleAnimation.value, + child: AnimatedContainer( + width: _width != null ? _width! * _scale : null, + duration: const Duration(milliseconds: 250), + child: Column( + children: [ + Opacity( + opacity: _scale == _maxScale ? 1 : 0, + child: FittedBox( + fit: BoxFit.none, + child: widget.reaction.title, + ), ), - ), - child!, - ], + child!, + ], + ), ), - ), - ); - }, + ); + }, + ), ); }, ), From b7cc845c4fb3d4a57600868d1f856c8a2477f159 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Wed, 27 Oct 2021 03:03:12 +0100 Subject: [PATCH 021/136] drag offset --- lib/src/ui/reactions_box_item.dart | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 79cf13b..31e37c7 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -66,6 +66,25 @@ class _ReactionsBoxItemState extends State ..addListener(_listener); } + bool _isWidgetHovered(DragData? dragData) { + final Offset currentOffset = dragData?.offset ?? Offset.zero; + final widgetOffset = _widgetKey.widgetOffset; + final widgetSize = _widgetKey.widgetSize; + + if (_width == null) { + _width = widgetSize.width; + } + + final double deltaX = + (widgetOffset.dx + widgetSize.width / 1.9) - currentOffset.dx; + final double deltaY = + widgetOffset.dy + widgetSize.height * 1.5 - currentOffset.dy; + + return deltaX.abs() <= widgetSize.width / 2 && + deltaY.abs() <= widgetSize.height && + widget.reaction.enabled; + } + @override void initState() { super.initState(); @@ -100,15 +119,7 @@ class _ReactionsBoxItemState extends State builder: (_, snapshot) { if (snapshot.hasData) { final dragData = snapshot.data; - final Offset currentOffset = dragData?.offset ?? Offset.zero; - final widgetSize = _widgetKey.widgetSize; - if (_width == null) { - _width = widgetSize.width; - } - final deltaOffset = currentOffset - _widgetKey.widgetOffset; - final isHovered = widgetSize.width * widgetSize.height >= - deltaOffset.distanceSquared && - widget.reaction.enabled; + bool isHovered = _isWidgetHovered(dragData); if (isHovered) { bool isSelected = snapshot.data?.isDragEnd ?? false; if (isSelected) { From 717b3f15b0f71b78843155588e4453169f63540a Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Wed, 27 Oct 2021 03:56:20 +0100 Subject: [PATCH 022/136] generic value reaction --- example/lib/data/example_data.dart | 38 ++++++++++++------- example/lib/items/item.dart | 9 +++-- example/lib/main.dart | 13 +++++-- lib/src/models/reaction.dart | 5 ++- lib/src/ui/flutter_reaction_button.dart | 23 +++++------ lib/src/ui/flutter_reaction_button_check.dart | 27 ++++++------- 6 files changed, 64 insertions(+), 51 deletions(-) diff --git a/example/lib/data/example_data.dart b/example/lib/data/example_data.dart index 74e697b..8e96988 100644 --- a/example/lib/data/example_data.dart +++ b/example/lib/data/example_data.dart @@ -1,40 +1,47 @@ import 'package:flutter/material.dart'; import 'package:flutter_reaction_button/flutter_reaction_button.dart'; -List flagsReactions = [ - Reaction( +List> flagsReactions = [ + Reaction( + value: 'en', previewIcon: _builFlagsdPreviewIcon( 'assets/images/united-kingdom-round.png', 'English'), icon: _buildIcon('assets/images/united-kingdom.png'), ), - Reaction( + Reaction( + value: 'ar', previewIcon: _builFlagsdPreviewIcon('assets/images/algeria-round.png', 'Arabic'), icon: _buildIcon('assets/images/algeria.png'), ), - Reaction( + Reaction( + value: 'gr', previewIcon: _builFlagsdPreviewIcon('assets/images/germany-round.png', 'German'), icon: _buildIcon('assets/images/germany.png'), ), - Reaction( + Reaction( + value: 'sp', previewIcon: _builFlagsdPreviewIcon('assets/images/spain-round.png', 'Spanish'), icon: _buildIcon('assets/images/spain.png'), ), - Reaction( + Reaction( + value: 'ch', previewIcon: _builFlagsdPreviewIcon('assets/images/china-round.png', 'Chinese'), icon: _buildIcon('assets/images/china.png'), ), ]; -final defaultInitialReaction = Reaction( +final defaultInitialReaction = Reaction( + value: null, icon: Text('No raction'), ); final reactions = [ - Reaction( + Reaction( + value: 'Happy', title: _buildTitle('Happy'), previewIcon: _buildReactionsPreviewIcon('assets/images/happy.png'), icon: _buildReactionsIcon( @@ -47,7 +54,8 @@ final reactions = [ ), ), ), - Reaction( + Reaction( + value: 'Angry', title: _buildTitle('Angry'), previewIcon: _buildReactionsPreviewIcon('assets/images/angry.png'), icon: _buildReactionsIcon( @@ -60,7 +68,8 @@ final reactions = [ ), ), ), - Reaction( + Reaction( + value: 'In love', title: _buildTitle('In love'), previewIcon: _buildReactionsPreviewIcon('assets/images/in-love.png'), icon: _buildReactionsIcon( @@ -73,7 +82,8 @@ final reactions = [ ), ), ), - Reaction( + Reaction( + value: 'Sad', title: _buildTitle('Sad'), previewIcon: _buildReactionsPreviewIcon('assets/images/sad.png'), icon: _buildReactionsIcon( @@ -86,7 +96,8 @@ final reactions = [ ), ), ), - Reaction( + Reaction( + value: 'Surprised', title: _buildTitle('Surprised'), previewIcon: _buildReactionsPreviewIcon('assets/images/surprised.png'), icon: _buildReactionsIcon( @@ -99,7 +110,8 @@ final reactions = [ ), ), ), - Reaction( + Reaction( + value: 'Mad', title: _buildTitle('Mad'), previewIcon: _buildReactionsPreviewIcon('assets/images/mad.png'), icon: _buildReactionsIcon( diff --git a/example/lib/items/item.dart b/example/lib/items/item.dart index 3d31da1..ce8dd19 100644 --- a/example/lib/items/item.dart +++ b/example/lib/items/item.dart @@ -8,7 +8,7 @@ import 'comments.dart'; class Item extends StatefulWidget { final String title; final String imgPath; - final List reactions; + final List> reactions; const Item(this.title, this.imgPath, this.reactions); @@ -65,9 +65,10 @@ class _ItemState extends State with AutomaticKeepAliveClientMixin { SizedBox( width: MediaQuery.of(context).size.width * .2, child: FittedBox( - child: FlutterReactionButtonCheck( - onReactionChanged: (reaction, index, isChecked) { - print('reaction selected index: $index'); + fit: BoxFit.scaleDown, + child: FlutterReactionButtonCheck( + onReactionChanged: (String? value, bool isChcked) { + print('Selected value: $value, isChecked: $isChcked'); }, reactions: widget.reactions, initialReaction: Example.defaultInitialReaction, diff --git a/example/lib/main.dart b/example/lib/main.dart index 9cd1ce6..d7d81c9 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -24,16 +24,21 @@ class _MyAppState extends State { actions: [ Builder( builder: (ctx) { - return FlutterReactionButton( - onReactionChanged: (reaction, index) { + return FlutterReactionButton( + onReactionChanged: (String? value) { ScaffoldMessenger.of(ctx).showSnackBar( SnackBar( - content: Text('reaction selected index: $index'), + content: Text('Selected value: $value'), ), ); }, reactions: Example.flagsReactions, - initialReaction: Reaction(icon: Icon(Icons.language)), + initialReaction: Reaction( + value: null, + icon: Icon( + Icons.language, + ), + ), boxColor: Colors.black.withOpacity(0.5), boxRadius: 10, boxDuration: Duration(milliseconds: 500), diff --git a/lib/src/models/reaction.dart b/lib/src/models/reaction.dart index d382963..796eb92 100644 --- a/lib/src/models/reaction.dart +++ b/lib/src/models/reaction.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -class Reaction { +class Reaction { @deprecated final int? id; @@ -19,9 +19,12 @@ class Reaction { final bool enabled; + final T? value; + Reaction({ this.id, required this.icon, + required this.value, Widget? previewIcon, this.title, this.enabled = true, diff --git a/lib/src/ui/flutter_reaction_button.dart b/lib/src/ui/flutter_reaction_button.dart index 153f207..bc0f77c 100644 --- a/lib/src/ui/flutter_reaction_button.dart +++ b/lib/src/ui/flutter_reaction_button.dart @@ -5,16 +5,14 @@ import '../utils/extensions.dart'; import '../utils/reactions_position.dart'; import 'reactions_box.dart'; -typedef OnFlutterReactionButtonChanged = void Function(Reaction, int); - -class FlutterReactionButton extends StatefulWidget { +class FlutterReactionButton extends StatefulWidget { /// This triggers when reaction button value changed. - final OnFlutterReactionButtonChanged onReactionChanged; + final void Function(T?) onReactionChanged; /// Default reaction button widget - final Reaction? initialReaction; + final Reaction? initialReaction; - final List reactions; + final List> reactions; /// Position reactions box for the button [default = TOP] final Position boxPosition; @@ -55,10 +53,10 @@ class FlutterReactionButton extends StatefulWidget { }) : super(key: key); @override - _FlutterReactionButtonState createState() => _FlutterReactionButtonState(); + _FlutterReactionButtonState createState() => _FlutterReactionButtonState(); } -class _FlutterReactionButtonState extends State { +class _FlutterReactionButtonState extends State> { final GlobalKey _buttonKey = GlobalKey(); Reaction? _selectedReaction; @@ -68,7 +66,7 @@ class _FlutterReactionButtonState extends State { } @override - void didUpdateWidget(FlutterReactionButton oldWidget) { + void didUpdateWidget(FlutterReactionButton oldWidget) { super.didUpdateWidget(oldWidget); _init(); } @@ -117,11 +115,8 @@ class _FlutterReactionButtonState extends State { if (reactionButton != null) _updateReaction(reactionButton); } - void _updateReaction(Reaction reaction) { - widget.onReactionChanged.call( - reaction, - widget.reactions.indexOf(reaction), - ); + void _updateReaction(Reaction reaction) { + widget.onReactionChanged.call(reaction.value); if (widget.shouldChangeReaction) setState(() { _selectedReaction = reaction; diff --git a/lib/src/ui/flutter_reaction_button_check.dart b/lib/src/ui/flutter_reaction_button_check.dart index 1e517b2..d4f8ee5 100644 --- a/lib/src/ui/flutter_reaction_button_check.dart +++ b/lib/src/ui/flutter_reaction_button_check.dart @@ -5,19 +5,17 @@ import '../utils/extensions.dart'; import '../utils/reactions_position.dart'; import 'reactions_box.dart'; -typedef FlutterReactionButtonCheckChanged = void Function(Reaction?, int, bool); - -class FlutterReactionButtonCheck extends StatefulWidget { +class FlutterReactionButtonCheck extends StatefulWidget { /// This triggers when reaction button value changed. - final FlutterReactionButtonCheckChanged onReactionChanged; + final void Function(T?, bool) onReactionChanged; /// Default reaction button widget if [isChecked == false] - final Reaction? initialReaction; + final Reaction? initialReaction; /// Default reaction button widget if [isChecked == true] - final Reaction? selectedReaction; + final Reaction? selectedReaction; - final List reactions; + final List?> reactions; /// Position reactions box for the button [default = TOP] final Position boxPosition; @@ -61,14 +59,14 @@ class FlutterReactionButtonCheck extends StatefulWidget { @override _FlutterReactionButtonCheckState createState() => - _FlutterReactionButtonCheckState(); + _FlutterReactionButtonCheckState(); } -class _FlutterReactionButtonCheckState - extends State { +class _FlutterReactionButtonCheckState + extends State> { final GlobalKey _buttonKey = GlobalKey(); - Reaction? _selectedReaction; + Reaction? _selectedReaction; bool _isChecked = false; @@ -79,7 +77,7 @@ class _FlutterReactionButtonCheckState } @override - void didUpdateWidget(FlutterReactionButtonCheck oldWidget) { + void didUpdateWidget(FlutterReactionButtonCheck oldWidget) { super.didUpdateWidget(oldWidget); _init(); } @@ -141,14 +139,13 @@ class _FlutterReactionButtonCheckState } void _updateReaction( - Reaction? reaction, [ + Reaction? reaction, [ bool isSelectedFromDialog = false, ]) { _isChecked = isSelectedFromDialog ? true : reaction != widget.initialReaction; widget.onReactionChanged.call( - reaction, - widget.reactions.indexOf(reaction), + reaction?.value, _isChecked, ); setState(() { From bfe6e2ea2a1651b330e5933503486cdb2523c5ec Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Wed, 27 Oct 2021 21:08:37 +0100 Subject: [PATCH 023/136] improving dragging behavior --- example/lib/main.dart | 1 + lib/src/ui/reactions_box.dart | 8 +++ lib/src/ui/reactions_box_item.dart | 94 +++++++++++++----------------- 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index d7d81c9..ae16123 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -15,6 +15,7 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { return MaterialApp( + debugShowMaterialGrid: true, debugShowCheckedModeBanner: false, title: 'Flutter Reaction Button', home: Scaffold( diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index 2b73670..59009b6 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -201,6 +201,14 @@ class _ReactionsBoxState extends State _dragData = _dragData?.copyWith(isDragEnd: true); _dragStreamController.add(_dragData); }, + onPointerHover: (point) { + _dragData = DragData(offset: point.position); + _dragStreamController.add(_dragData); + }, + onPointerCancel: (point) { + _dragData = _dragData?.copyWith(isDragEnd: true); + _dragStreamController.add(_dragData); + }, child: Row( crossAxisAlignment: CrossAxisAlignment.end, children: widget.reactions.map( diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 31e37c7..414ddcb 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -41,29 +41,24 @@ class _ReactionsBoxItemState extends State static const double _DELTA_SCALE = .2; - double _minScale = 1; - - double _normalScale = 1; + final double _maxScale = 1 + _DELTA_SCALE; - double _maxScale = 1 + _DELTA_SCALE; + final double _normalScale = 1; - double _scale = 1; + double _minScale = 1; double? _width; + bool _isHovered = false; + void _onSelected() { _scaleController.reverse(); widget.onReactionClick.call(widget.reaction); } - late VoidCallback _listener; - void _updateAnimation({double? begin, double? end}) { _scaleTween = Tween(begin: begin ?? _normalScale, end: end ?? _maxScale); _scaleAnimation = _scaleTween.animate(_scaleController); - _scaleAnimation - ..removeListener(_listener) - ..addListener(_listener); } bool _isWidgetHovered(DragData? dragData) { @@ -77,11 +72,10 @@ class _ReactionsBoxItemState extends State final double deltaX = (widgetOffset.dx + widgetSize.width / 1.9) - currentOffset.dx; - final double deltaY = - widgetOffset.dy + widgetSize.height * 1.5 - currentOffset.dy; + final double deltaY = widgetOffset.dy - currentOffset.dy; return deltaX.abs() <= widgetSize.width / 2 && - deltaY.abs() <= widgetSize.height && + deltaY.abs() <= widgetSize.height * 2 && widget.reaction.enabled; } @@ -97,10 +91,6 @@ class _ReactionsBoxItemState extends State duration: const Duration(milliseconds: 250), ); - _listener = () { - _scale = _scaleAnimation.value; - }; - _updateAnimation(begin: _normalScale, end: _maxScale); } @@ -119,8 +109,8 @@ class _ReactionsBoxItemState extends State builder: (_, snapshot) { if (snapshot.hasData) { final dragData = snapshot.data; - bool isHovered = _isWidgetHovered(dragData); - if (isHovered) { + _isHovered = _isWidgetHovered(dragData); + if (_isHovered) { bool isSelected = snapshot.data?.isDragEnd ?? false; if (isSelected) { _onSelected(); @@ -129,49 +119,47 @@ class _ReactionsBoxItemState extends State } } else { bool isDraggingEnded = dragData?.isDragEnd ?? false; - if (isDraggingEnded) - _updateAnimation(begin: _normalScale, end: _maxScale); - else + if (isDraggingEnded) { + _updateAnimation(); + } else { _updateAnimation(begin: _minScale); - + } WidgetsBinding.instance?.addPostFrameCallback((_) { _scaleController.reset(); }); } - } else { - _updateAnimation(begin: _minScale); - _scaleController.reverse(); } - return FittedBox( - child: AnimatedBuilder( - animation: _scaleAnimation, - child: FittedBox( - key: _widgetKey, - child: widget.reaction.previewIcon, - ), - builder: (_, child) { - return Transform.scale( - scale: _scaleAnimation.value, - child: AnimatedContainer( - width: _width != null ? _width! * _scale : null, - duration: const Duration(milliseconds: 250), - child: Column( - children: [ - Opacity( - opacity: _scale == _maxScale ? 1 : 0, - child: FittedBox( - fit: BoxFit.none, - child: widget.reaction.title, - ), + return AnimatedBuilder( + animation: _scaleAnimation, + child: FittedBox( + key: _widgetKey, + fit: BoxFit.scaleDown, + child: widget.reaction.previewIcon, + ), + builder: (_, child) { + return Transform.scale( + scale: _scaleAnimation.value, + child: AnimatedContainer( + width: + _width != null ? _width! * _scaleAnimation.value : null, + duration: const Duration(milliseconds: 250), + child: Column( + children: [ + AnimatedOpacity( + duration: const Duration(milliseconds: 50), + opacity: _isHovered ? 1 : 0, + child: FittedBox( + fit: BoxFit.scaleDown, + child: widget.reaction.title, ), - child!, - ], - ), + ), + child!, + ], ), - ); - }, - ), + ), + ); + }, ); }, ), From b0d1baedd5ea28bc4f3d8c7dd05117040584487a Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Thu, 28 Oct 2021 23:20:51 +0100 Subject: [PATCH 024/136] fix box item animation --- example/lib/main.dart | 1 - lib/src/ui/reactions_box.dart | 31 ++++--- lib/src/ui/reactions_box_item.dart | 126 +++++++++++++---------------- 3 files changed, 78 insertions(+), 80 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index ae16123..d7d81c9 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -15,7 +15,6 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { return MaterialApp( - debugShowMaterialGrid: true, debugShowCheckedModeBanner: false, title: 'Flutter Reaction Button', home: Scaffold( diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index 59009b6..e8fdc0f 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -30,6 +30,8 @@ class ReactionsBox extends StatefulWidget { final EdgeInsets boxPadding; + final double itemScale; + const ReactionsBox({ Key? key, required this.buttonOffset, @@ -42,7 +44,9 @@ class ReactionsBox extends StatefulWidget { this.duration = const Duration(milliseconds: 200), this.alignment = Alignment.center, this.boxPadding = const EdgeInsets.all(0), - }) : super(key: key); + this.itemScale = .3, + }) : assert(itemScale > 0.0 && itemScale < 1), + super(key: key); @override _ReactionsBoxState createState() => _ReactionsBoxState(); @@ -50,8 +54,9 @@ class ReactionsBox extends StatefulWidget { class _ReactionsBoxState extends State with TickerProviderStateMixin { - StreamController _dragStreamController = + final StreamController _dragStreamController = StreamController(); + late Stream _dragStream; late AnimationController _boxSizeController; @@ -64,6 +69,10 @@ class _ReactionsBoxState extends State late Animation _scaleAnimation; + late double _maxScale; + + late double _normaScale; + Reaction? _selectedReaction; DragData? _dragData; @@ -86,6 +95,10 @@ class _ReactionsBoxState extends State void initState() { super.initState(); + _normaScale = 1; + // Calculating how much we should scale up when item hovered + _maxScale = _normaScale + widget.itemScale; + _boxSizeController = AnimationController(vsync: this, duration: widget.duration); @@ -184,7 +197,10 @@ class _ReactionsBoxState extends State _boxSizeTween ..begin = size ..end = size; - _boxSizeController.forward(); + if (_boxSizeController.isCompleted) + _boxSizeController.reverse(); + else + _boxSizeController.forward(); }, child: Padding( padding: widget.boxPadding, @@ -201,10 +217,6 @@ class _ReactionsBoxState extends State _dragData = _dragData?.copyWith(isDragEnd: true); _dragStreamController.add(_dragData); }, - onPointerHover: (point) { - _dragData = DragData(offset: point.position); - _dragStreamController.add(_dragData); - }, onPointerCancel: (point) { _dragData = _dragData?.copyWith(isDragEnd: true); _dragStreamController.add(_dragData); @@ -214,11 +226,12 @@ class _ReactionsBoxState extends State children: widget.reactions.map( (reaction) { return ReactionsBoxItem( - onReactionClick: (reaction) { + onReactionSelected: (reaction) { _selectedReaction = reaction; _scaleController.reverse(); }, - itemsCount: widget.reactions.length, + maxScale: _maxScale, + normaScale: _normaScale, reaction: reaction!, dragStream: _dragStream, ); diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 414ddcb..7d30dd3 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -9,19 +9,22 @@ import '../utils/extensions.dart'; typedef OnReactionClick = void Function(Reaction?); class ReactionsBoxItem extends StatefulWidget { - final OnReactionClick onReactionClick; + final OnReactionClick onReactionSelected; final Reaction reaction; - final int itemsCount; + final double maxScale; + + final double normaScale; final Stream dragStream; const ReactionsBoxItem({ Key? key, required this.reaction, - required this.onReactionClick, - required this.itemsCount, + required this.onReactionSelected, + required this.maxScale, + required this.normaScale, required this.dragStream, }) : super(key: key); @@ -39,43 +42,27 @@ class _ReactionsBoxItemState extends State late Animation _scaleAnimation; - static const double _DELTA_SCALE = .2; - - final double _maxScale = 1 + _DELTA_SCALE; - - final double _normalScale = 1; - - double _minScale = 1; - - double? _width; - - bool _isHovered = false; + Size? _widgetSize; void _onSelected() { _scaleController.reverse(); - widget.onReactionClick.call(widget.reaction); - } - - void _updateAnimation({double? begin, double? end}) { - _scaleTween = Tween(begin: begin ?? _normalScale, end: end ?? _maxScale); - _scaleAnimation = _scaleTween.animate(_scaleController); + widget.onReactionSelected.call(widget.reaction); } bool _isWidgetHovered(DragData? dragData) { final Offset currentOffset = dragData?.offset ?? Offset.zero; final widgetOffset = _widgetKey.widgetOffset; - final widgetSize = _widgetKey.widgetSize; - if (_width == null) { - _width = widgetSize.width; + if (_widgetSize == null) { + _widgetSize = _widgetKey.widgetSize; } final double deltaX = - (widgetOffset.dx + widgetSize.width / 1.9) - currentOffset.dx; + (widgetOffset.dx + _widgetSize!.width / 1.9) - currentOffset.dx; final double deltaY = widgetOffset.dy - currentOffset.dy; - return deltaX.abs() <= widgetSize.width / 2 && - deltaY.abs() <= widgetSize.height * 2 && + return deltaX.abs() <= _widgetSize!.width / 2 && + deltaY.abs() <= _widgetSize!.height * 2 && widget.reaction.enabled; } @@ -83,15 +70,17 @@ class _ReactionsBoxItemState extends State void initState() { super.initState(); - // Calculating how much we should scale down unselected items - _minScale = 1 - (_DELTA_SCALE / widget.itemsCount); - _scaleController = AnimationController( vsync: this, duration: const Duration(milliseconds: 250), ); - _updateAnimation(begin: _normalScale, end: _maxScale); + _scaleTween = Tween( + begin: widget.normaScale, + end: widget.maxScale, + ); + + _scaleAnimation = _scaleTween.animate(_scaleController); } @override @@ -107,10 +96,11 @@ class _ReactionsBoxItemState extends State child: StreamBuilder( stream: widget.dragStream, builder: (_, snapshot) { + bool isHovered = false; if (snapshot.hasData) { final dragData = snapshot.data; - _isHovered = _isWidgetHovered(dragData); - if (_isHovered) { + isHovered = _isWidgetHovered(dragData); + if (isHovered) { bool isSelected = snapshot.data?.isDragEnd ?? false; if (isSelected) { _onSelected(); @@ -118,48 +108,44 @@ class _ReactionsBoxItemState extends State _scaleController.forward(); } } else { - bool isDraggingEnded = dragData?.isDragEnd ?? false; - if (isDraggingEnded) { - _updateAnimation(); - } else { - _updateAnimation(begin: _minScale); - } - WidgetsBinding.instance?.addPostFrameCallback((_) { - _scaleController.reset(); - }); + _scaleController.reverse(); } } - return AnimatedBuilder( - animation: _scaleAnimation, - child: FittedBox( - key: _widgetKey, - fit: BoxFit.scaleDown, - child: widget.reaction.previewIcon, - ), - builder: (_, child) { - return Transform.scale( - scale: _scaleAnimation.value, - child: AnimatedContainer( - width: - _width != null ? _width! * _scaleAnimation.value : null, - duration: const Duration(milliseconds: 250), - child: Column( - children: [ - AnimatedOpacity( - duration: const Duration(milliseconds: 50), - opacity: _isHovered ? 1 : 0, - child: FittedBox( - fit: BoxFit.scaleDown, - child: widget.reaction.title, + return FittedBox( + fit: BoxFit.scaleDown, + child: AnimatedBuilder( + animation: _scaleAnimation, + child: FittedBox( + key: _widgetKey, + fit: BoxFit.scaleDown, + child: widget.reaction.previewIcon, + ), + builder: (_, child) { + return Transform.scale( + scale: _scaleAnimation.value, + child: AnimatedContainer( + width: _widgetSize != null + ? _widgetSize!.width * _scaleAnimation.value + : null, + duration: const Duration(milliseconds: 250), + child: Column( + children: [ + AnimatedOpacity( + duration: const Duration(milliseconds: 50), + opacity: isHovered ? 1 : 0, + child: FittedBox( + fit: BoxFit.scaleDown, + child: widget.reaction.title, + ), ), - ), - child!, - ], + child!, + ], + ), ), - ), - ); - }, + ); + }, + ), ); }, ), From ad60d860364b169cc0fb0332d87bc37da29c82d8 Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Thu, 28 Oct 2021 23:24:20 +0100 Subject: [PATCH 025/136] fix box item animation --- lib/src/ui/reactions_box.dart | 10 +++------- lib/src/ui/reactions_box_item.dart | 11 ++++------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index e8fdc0f..34ac030 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -69,9 +69,7 @@ class _ReactionsBoxState extends State late Animation _scaleAnimation; - late double _maxScale; - - late double _normaScale; + late double _itemScale; Reaction? _selectedReaction; @@ -95,9 +93,8 @@ class _ReactionsBoxState extends State void initState() { super.initState(); - _normaScale = 1; // Calculating how much we should scale up when item hovered - _maxScale = _normaScale + widget.itemScale; + _itemScale = 1 + widget.itemScale; _boxSizeController = AnimationController(vsync: this, duration: widget.duration); @@ -230,8 +227,7 @@ class _ReactionsBoxState extends State _selectedReaction = reaction; _scaleController.reverse(); }, - maxScale: _maxScale, - normaScale: _normaScale, + scale: _itemScale, reaction: reaction!, dragStream: _dragStream, ); diff --git a/lib/src/ui/reactions_box_item.dart b/lib/src/ui/reactions_box_item.dart index 7d30dd3..e75429e 100644 --- a/lib/src/ui/reactions_box_item.dart +++ b/lib/src/ui/reactions_box_item.dart @@ -13,9 +13,7 @@ class ReactionsBoxItem extends StatefulWidget { final Reaction reaction; - final double maxScale; - - final double normaScale; + final double scale; final Stream dragStream; @@ -23,8 +21,7 @@ class ReactionsBoxItem extends StatefulWidget { Key? key, required this.reaction, required this.onReactionSelected, - required this.maxScale, - required this.normaScale, + required this.scale, required this.dragStream, }) : super(key: key); @@ -76,8 +73,8 @@ class _ReactionsBoxItemState extends State ); _scaleTween = Tween( - begin: widget.normaScale, - end: widget.maxScale, + begin: 1, + end: widget.scale, ); _scaleAnimation = _scaleTween.animate(_scaleController); From cbd34e53fb26e2db9aa5e14981c101ef7003d32d Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Thu, 28 Oct 2021 23:30:18 +0100 Subject: [PATCH 026/136] clean some code --- lib/src/ui/reactions_box.dart | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/src/ui/reactions_box.dart b/lib/src/ui/reactions_box.dart index 34ac030..a38e4d1 100644 --- a/lib/src/ui/reactions_box.dart +++ b/lib/src/ui/reactions_box.dart @@ -240,18 +240,21 @@ class _ReactionsBoxState extends State } double _getPosition(BuildContext context) { - return (_getTopPosition() - widget.buttonSize.height * 2 < 0) - ? _getBottomPosition() - : (_getBottomPosition() + widget.buttonSize.height * 2 > - context.screenSize.height) - ? _getTopPosition() - : widget.position == Position.TOP - ? _getTopPosition() - : _getBottomPosition(); + // check if TOP space not enough for the box + if (_getTopPosition() - widget.buttonSize.height * 2 < 0) + return _getBottomPosition(); + + // check if BOTTOM space not enough for the box + if (_getBottomPosition() + widget.buttonSize.height * 2 > + context.screenSize.height) return _getTopPosition(); + + if (widget.position == Position.TOP) return _getTopPosition(); + + return _getBottomPosition(); } double _getTopPosition() { - return widget.buttonOffset.dy - widget.buttonSize.height * 3.3; + return widget.buttonOffset.dy - widget.buttonSize.height * 5; } double _getBottomPosition() { From 87e15bf165cd08ba96b6ccabde7420975843dc0b Mon Sep 17 00:00:00 2001 From: GeekAbdelouahed Date: Fri, 29 Oct 2021 00:43:05 +0100 Subject: [PATCH 027/136] Auto alignment --- .vscode/settings.json | 2 +- .../android/app/src/debug/AndroidManifest.xml | 2 +- .../android/app/src/main/AndroidManifest.xml | 12 +- .../example/MainActivity.kt | 2 +- .../MainActivity.kt | 10 +- .../main/res/drawable/launch_background.xml | 3 +- .../app/src/main/res/values/styles.xml | 1 + .../app/src/profile/AndroidManifest.xml | 2 +- .../AppIcon.appiconset/Contents.json | 160 +++++++++--------- .../LaunchImage.imageset/Contents.json | 26 +-- example/lib/items/item.dart | 9 +- example/web/index.html | 37 ++-- example/web/manifest.json | 42 ++--- lib/src/ui/flutter_reaction_button.dart | 1 - lib/src/ui/flutter_reaction_button_check.dart | 1 - lib/src/ui/reactions_box.dart | 43 ++--- pubspec.yaml | 58 +++---- 17 files changed, 207 insertions(+), 204 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7a66e62..5b97188 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "dart.flutterSdkPath": "C:\\Users\\Lenovo\\fvm\\versions\\stable" + "dart.flutterSdkPath": "C:\\Users\\Lenovo\\fvm\\versions\\stable" } \ No newline at end of file diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index 719e6f6..aefab97 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -3,5 +3,5 @@ - + diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 83c4e34..17b6fbb 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -8,14 +8,14 @@ FlutterApplication and put your custom class here. --> + android:icon="@mipmap/ic_launcher" + android:label="flutter_reaction_button_test"> + diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml index 00fa441..26e896f 100644 --- a/example/android/app/src/main/res/values/styles.xml +++ b/example/android/app/src/main/res/values/styles.xml @@ -1,5 +1,6 @@ +