Repository: GeekAbdelouahed/flutter-reaction-button
Branch: master
Commit: dbab28e9f441
Files: 68
Total size: 96.1 KB
Directory structure:
gitextract_8tbpjqev/
├── .github/
│ └── workflows/
│ ├── publish.yml
│ └── test.yml
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example/
│ ├── .gitignore
│ ├── .metadata
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── android/
│ │ ├── .gitignore
│ │ ├── .project
│ │ ├── .settings/
│ │ │ └── org.eclipse.buildship.core.prefs
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── debug/
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── kotlin/
│ │ │ │ │ └── abdelouahedmedjoudja/
│ │ │ │ │ ├── example/
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ │ └── flutter_reaction_button_test/
│ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── res/
│ │ │ │ ├── drawable/
│ │ │ │ │ └── launch_background.xml
│ │ │ │ └── values/
│ │ │ │ └── styles.xml
│ │ │ └── profile/
│ │ │ └── AndroidManifest.xml
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ └── settings.gradle
│ ├── ios/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── AppFrameworkInfo.plist
│ │ │ ├── Debug.xcconfig
│ │ │ └── Release.xcconfig
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ └── LaunchImage.imageset/
│ │ │ │ ├── Contents.json
│ │ │ │ └── README.md
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ └── Runner-Bridging-Header.h
│ │ ├── Runner.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Runner.xcscheme
│ │ └── Runner.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ ├── lib/
│ │ ├── data.dart
│ │ ├── image.dart
│ │ ├── main.dart
│ │ └── post.dart
│ ├── pubspec.yaml
│ └── web/
│ ├── index.html
│ └── manifest.json
├── flutter_reaction_button.iml
├── lib/
│ ├── flutter_reaction_button.dart
│ └── src/
│ ├── common/
│ │ ├── position.dart
│ │ └── position_notifier.dart
│ ├── enums/
│ │ ├── box.dart
│ │ └── reaction.dart
│ ├── extensions/
│ │ └── key.dart
│ ├── models/
│ │ └── reaction.dart
│ └── widgets/
│ ├── reaction_button.dart
│ ├── reactions_box.dart
│ └── reactions_box_item.dart
├── pubspec.yaml
└── test/
├── main.dart
└── reaction_button_test.dart
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Flutter
uses: subosito/flutter-action@v2.10.0
- name: Install dependencies
run: flutter pub get
- name: Analyze
run: flutter analyze
- name: Run tests
run: flutter test
- name: Format code
run: dart format --fix .
- name: Check Publish Warnings
run: dart pub publish --dry-run
- name: Publish
uses: k-paxian/dart-package-publisher@v1.5.1
with:
credentialJson: ${{ secrets.CREDENTIAL_JSON }}
flutter: true
skipTests: true
================================================
FILE: .github/workflows/test.yml
================================================
name: Test
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
- run: flutter pub get
- name: Analyze project source
run: dart analyze
- name: Format code
run: dart format --fix .
- name: Run tests
run: flutter test
================================================
FILE: .gitignore
================================================
#Flutter versions manager
.fvm/
.idea/
.vscode/
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
!flutter_reaction_button.iml
================================================
FILE: .metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: b712a172f9694745f50505c93340883493b505e5
channel: stable
project_type: package
================================================
FILE: CHANGELOG.md
================================================
## 3.0.0+3
* Fix reactions box overflow
## 3.0.0+2
* Minor updates
## 3.0.0+1
* Update README
## 3.0.0
- **BREAKING CHANGE**:
- `FlutterReactionButton` and `FlutterReactionButtonToggle` removed
- `itemSize` is required in `ReactionButton`
- `onReactionChanged` callback updated
- `VerticalPosition` and `HorizontalPosition` removed
- Adds `child` to `ReactionButton`
- Animated `ReactionsBox`
## 2.0.2
* Pipeline setup
## 2.0.1+1
* Minor bugs fixed. Thanks to [Kyle Venn](https://github.com/kvenn)
## 2.0.1
* Adds ReactionContainer
* Bugs fix and code improvements, Thanks to [Felix Gabler](https://github.com/felixgabler)
## 2.0.0+3
* Upgrade flutter version
## 2.0.0+2
* Fix Offscreen Issue. Thanks to [rlee1990](https://github.com/rlee1990)
## 2.0.0+1
* Dragging improvement
## 2.0.0
* Change `FlutterReactionButton` to `ReactionButton`
* Change `FlutterReactionButtonCheck` to `ReactionButtonToggle`
* Change `Function(Reaction, int, bool) onReactionChanged` to `Function(T?, bool) onReactionChanged`
* Change `Function(Reaction, int) onReactionChanged` to `Function(T?) onReactionChanged`
* Dynamic scale depending on the hover position
* Dynamic horizontal alignment
* Scrollable position
* Minor bugs fixed
## 1.0.8
* Added support null safety
## 1.0.7+3
* Deprecated Reaction id
## 1.0.7+2
* Improvement box flow
## 1.0.7
* Remove reaction id
* Clean code
## 1.0.6+2
* Minor bugs fixed
## 1.0.6+1
* Minor bugs fixed
## 1.0.6
* Reaction title
## 1.0.5
* Items spacing
* Box padding
## 1.0.4
* Reactions box alignment
## 1.0.3
* Change state externally
## 1.0.2
* Code improvements
## 1.0.1
* Define reaction by id.
* Alternative to popup menu.
* Enable/disable reaction click.
## 1.0.0
* Adds ripple effect.
## 0.1.3
* Selected rection index.
## 0.1.2+1
* Adds Example.
## 0.1.2
* From plugin to packages.
## 0.1.1
* Reactions List @required.
## 0.1.0
* Update Description pubspec.yaml.
## 0.0.1
* Describe initial release.
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019 Abdelouahed Medjoudja
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
[](https://pub.dartlang.org/packages/flutter_reaction_button)
# Flutter reaction button
Flutter Reaction Button is a customizable Flutter package that allows you to easily create interactive buttons with reaction emojis, similar to Facebook's iconic reaction buttons.
## Screenshot

## Installation
```yaml
# pubspec.yaml
dependencies:
flutter:
sdk: flutter
flutter_reaction_button: <last-version>
```
## Usage
```dart
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
ReactionButton<String>(
onReactionChanged: (Reaction<String>? reaction) {
debugPrint('Selected value: ${reaction?.value}');
},
reactions: <Reaction<String>>[
Reaction<String>(
value: 'like',
icon: widget,
),
Reaction<String>(
value: 'love',
icon: widget,
),
...
],
initialReaction: Reaction<String>(
value: 'like',
icon: widget,
),
selectedReaction: Reaction<String>(
value: 'like_fill',
icon: widget,
),
)
```
## License
```legal
MIT License
Copyright (c) 2023 Abdelouahed Medjoudja
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
================================================
FILE: analysis_options.yaml
================================================
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
================================================
FILE: example/.gitignore
================================================
#Flutter versions manager
.fvm/
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
/build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
================================================
FILE: example/.metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: b712a172f9694745f50505c93340883493b505e5
channel: stable
project_type: app
================================================
FILE: example/README.md
================================================
# flutter_reaction_button_example
ReactionButton:
```dart
ReactionButton<String>(
onReactionChanged: (Reaction<String>? reaction) {
debugPrint('Selected value: ${reaction?.value}');
},
reactions: <Reaction<String>>[
Reaction<String>(
value: 'like',
icon: widget,
),
Reaction<String>(
value: 'love',
icon: widget,
),
...
],
initialReaction: Reaction<String>(
value: 'like',
icon: widget,
),
selectedReaction: Reaction<String>(
value: 'like_fill',
icon: widget,
),
)
```
ReactionButton:
```dart
ReactionButton<String>(
toggle: false,
onReactionChanged: (Reaction<String>? reaction) {
debugPrint('Selected language: ${reaction?.value}');
},
reactions: <Reaction<String>>[
Reaction<String>(
value: 'en',
icon: widget,
),
Reaction<String>(
value: 'ar',
icon: widget,
),
...
],
initialReaction: Reaction<String>(
value: null,
icon: Icon(Icons.language),
),
)
```
================================================
FILE: example/analysis_options.yaml
================================================
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
================================================
FILE: example/android/.gitignore
================================================
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
================================================
FILE: example/android/.project
================================================
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>android</name>
<comment>Project android created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>
================================================
FILE: example/android/.settings/org.eclipse.buildship.core.prefs
================================================
connection.project.dir=
eclipse.preferences.version=1
================================================
FILE: example/android/app/build.gradle
================================================
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 31
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "abdelouahedmedjoudja.flutter_reaction_button_test"
minSdkVersion 21
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
================================================
FILE: example/android/app/src/debug/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="abdelouahedmedjoudja.flutter_reaction_button_test">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
================================================
FILE: example/android/app/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="abdelouahedmedjoudja.flutter_reaction_button_test">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:label="flutter_reaction_button_test">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize"
android:exported="true">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
================================================
FILE: example/android/app/src/main/kotlin/abdelouahedmedjoudja/example/MainActivity.kt
================================================
package abdelouahedmedjoudja.example
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() {
}
================================================
FILE: example/android/app/src/main/kotlin/abdelouahedmedjoudja/flutter_reaction_button_test/MainActivity.kt
================================================
package abdelouahedmedjoudja.flutter_reaction_button_test
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() {
}
================================================
FILE: example/android/app/src/main/res/drawable/launch_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?><!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
================================================
FILE: example/android/app/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>
================================================
FILE: example/android/app/src/profile/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="abdelouahedmedjoudja.flutter_reaction_button_test">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
================================================
FILE: example/android/build.gradle
================================================
buildscript {
ext.kotlin_version = '1.6.21'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: example/android/gradle/wrapper/gradle-wrapper.properties
================================================
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
================================================
FILE: example/android/gradle.properties
================================================
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
================================================
FILE: example/android/settings.gradle
================================================
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
================================================
FILE: example/ios/.gitignore
================================================
*.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/
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
================================================
FILE: example/ios/Flutter/AppFrameworkInfo.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
================================================
FILE: example/ios/Flutter/Debug.xcconfig
================================================
#include "Generated.xcconfig"
================================================
FILE: example/ios/Flutter/Release.xcconfig
================================================
#include "Generated.xcconfig"
================================================
FILE: example/ios/Runner/AppDelegate.swift
================================================
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images": [
{
"size": "20x20",
"idiom": "iphone",
"filename": "Icon-App-20x20@2x.png",
"scale": "2x"
},
{
"size": "20x20",
"idiom": "iphone",
"filename": "Icon-App-20x20@3x.png",
"scale": "3x"
},
{
"size": "29x29",
"idiom": "iphone",
"filename": "Icon-App-29x29@1x.png",
"scale": "1x"
},
{
"size": "29x29",
"idiom": "iphone",
"filename": "Icon-App-29x29@2x.png",
"scale": "2x"
},
{
"size": "29x29",
"idiom": "iphone",
"filename": "Icon-App-29x29@3x.png",
"scale": "3x"
},
{
"size": "40x40",
"idiom": "iphone",
"filename": "Icon-App-40x40@2x.png",
"scale": "2x"
},
{
"size": "40x40",
"idiom": "iphone",
"filename": "Icon-App-40x40@3x.png",
"scale": "3x"
},
{
"size": "60x60",
"idiom": "iphone",
"filename": "Icon-App-60x60@2x.png",
"scale": "2x"
},
{
"size": "60x60",
"idiom": "iphone",
"filename": "Icon-App-60x60@3x.png",
"scale": "3x"
},
{
"size": "20x20",
"idiom": "ipad",
"filename": "Icon-App-20x20@1x.png",
"scale": "1x"
},
{
"size": "20x20",
"idiom": "ipad",
"filename": "Icon-App-20x20@2x.png",
"scale": "2x"
},
{
"size": "29x29",
"idiom": "ipad",
"filename": "Icon-App-29x29@1x.png",
"scale": "1x"
},
{
"size": "29x29",
"idiom": "ipad",
"filename": "Icon-App-29x29@2x.png",
"scale": "2x"
},
{
"size": "40x40",
"idiom": "ipad",
"filename": "Icon-App-40x40@1x.png",
"scale": "1x"
},
{
"size": "40x40",
"idiom": "ipad",
"filename": "Icon-App-40x40@2x.png",
"scale": "2x"
},
{
"size": "76x76",
"idiom": "ipad",
"filename": "Icon-App-76x76@1x.png",
"scale": "1x"
},
{
"size": "76x76",
"idiom": "ipad",
"filename": "Icon-App-76x76@2x.png",
"scale": "2x"
},
{
"size": "83.5x83.5",
"idiom": "ipad",
"filename": "Icon-App-83.5x83.5@2x.png",
"scale": "2x"
},
{
"size": "1024x1024",
"idiom": "ios-marketing",
"filename": "Icon-App-1024x1024@1x.png",
"scale": "1x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
================================================
{
"images": [
{
"idiom": "universal",
"filename": "LaunchImage.png",
"scale": "1x"
},
{
"idiom": "universal",
"filename": "LaunchImage@2x.png",
"scale": "2x"
},
{
"idiom": "universal",
"filename": "LaunchImage@3x.png",
"scale": "3x"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
================================================
FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
================================================
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
================================================
FILE: example/ios/Runner/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
================================================
FILE: example/ios/Runner/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
================================================
FILE: example/ios/Runner/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>flutter_reaction_button_test</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
================================================
FILE: example/ios/Runner/Runner-Bridging-Header.h
================================================
#import "GeneratedPluginRegistrant.h"
================================================
FILE: example/ios/Runner.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0910;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6YQ9LWSA59;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = abdelouahedmedjoudja.flutterReactionButtonTest;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6YQ9LWSA59;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = abdelouahedmedjoudja.flutterReactionButtonTest;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6YQ9LWSA59;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = abdelouahedmedjoudja.flutterReactionButtonTest;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
================================================
FILE: example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
================================================
FILE: example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: example/ios/Runner.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
================================================
FILE: example/lib/data.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
final List<Reaction<String>> flagsReactions = [
Reaction<String>(
value: 'en',
previewIcon: _buildFlagPreviewIcon(
'assets/images/united-kingdom-round.png',
'English',
),
icon: _buildFlagIcon(
'assets/images/united-kingdom.png',
),
),
Reaction<String>(
value: 'ar',
previewIcon: _buildFlagPreviewIcon(
'assets/images/algeria-round.png',
'Arabic',
),
icon: _buildFlagIcon(
'assets/images/algeria.png',
),
),
Reaction<String>(
value: 'gr',
previewIcon: _buildFlagPreviewIcon(
'assets/images/germany-round.png',
'German',
),
icon: _buildFlagIcon(
'assets/images/germany.png',
),
),
Reaction<String>(
value: 'sp',
previewIcon: _buildFlagPreviewIcon(
'assets/images/spain-round.png',
'Spanish',
),
icon: _buildFlagIcon(
'assets/images/spain.png',
),
),
Reaction<String>(
value: 'ch',
previewIcon: _buildFlagPreviewIcon(
'assets/images/china-round.png',
'Chinese',
),
icon: _buildFlagIcon(
'assets/images/china.png',
),
),
];
const defaultInitialReaction = Reaction<String>(
value: null,
icon: Text(
'No reaction',
),
);
final List<Reaction<String>> reactions = [
Reaction<String>(
value: 'Happy',
title: _buildEmojiTitle(
'Happy',
),
previewIcon: _buildEmojiPreviewIcon(
'assets/images/happy.png',
),
icon: _buildReactionsIcon(
'assets/images/happy.png',
const Text(
'Happy',
style: TextStyle(
color: Color(0XFF3b5998),
),
),
),
),
Reaction<String>(
value: 'Angry',
title: _buildEmojiTitle(
'Angry',
),
previewIcon: _buildEmojiPreviewIcon(
'assets/images/angry.png',
),
icon: _buildReactionsIcon(
'assets/images/angry.png',
const Text(
'Angry',
style: TextStyle(
color: Color(0XFFed5168),
),
),
),
),
Reaction<String>(
value: 'In love',
title: _buildEmojiTitle(
'In love',
),
previewIcon: _buildEmojiPreviewIcon(
'assets/images/in-love.png',
),
icon: _buildReactionsIcon(
'assets/images/in-love.png',
const Text(
'In love',
style: TextStyle(
color: Color(0XFFffda6b),
),
),
),
),
Reaction<String>(
value: 'Sad',
title: _buildEmojiTitle(
'Sad',
),
previewIcon: _buildEmojiPreviewIcon(
'assets/images/sad.png',
),
icon: _buildReactionsIcon(
'assets/images/sad.png',
const Text(
'Sad',
style: TextStyle(
color: Color(0XFFffda6b),
),
),
),
),
Reaction<String>(
value: 'Surprised',
title: _buildEmojiTitle(
'Surprised',
),
previewIcon: _buildEmojiPreviewIcon(
'assets/images/surprised.png',
),
icon: _buildReactionsIcon(
'assets/images/surprised.png',
const Text(
'Surprised',
style: TextStyle(
color: Color(0XFFffda6b),
),
),
),
),
Reaction<String>(
value: 'Mad',
title: _buildEmojiTitle(
'Mad',
),
previewIcon: _buildEmojiPreviewIcon(
'assets/images/mad.png',
),
icon: _buildReactionsIcon(
'assets/images/mad.png',
const Text(
'Mad',
style: TextStyle(
color: Color(0XFFf05766),
),
),
),
),
];
Widget _buildFlagPreviewIcon(String path, String text) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
text,
style: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.w300,
color: Colors.white,
),
),
const SizedBox(height: 7.5),
Image.asset(path, height: 30),
],
);
}
Widget _buildEmojiTitle(String title) {
return Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: Colors.black.withOpacity(.75),
borderRadius: BorderRadius.circular(15),
),
child: Text(
title,
style: const TextStyle(
color: Colors.white,
fontSize: 8,
fontWeight: FontWeight.bold,
),
),
);
}
Widget _buildEmojiPreviewIcon(String path) {
return Image.asset(path);
}
Widget _buildFlagIcon(String path) {
return Image.asset(path);
}
Widget _buildReactionsIcon(String path, Text text) {
return Container(
color: Colors.transparent,
child: Row(
children: <Widget>[
Image.asset(path, height: 20),
const SizedBox(width: 5),
text,
],
),
);
}
================================================
FILE: example/lib/image.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
class ImageWidget extends StatefulWidget {
const ImageWidget({
Key? key,
required this.imgPath,
required this.reactions,
}) : super(key: key);
final String imgPath;
final List<Reaction<String>> reactions;
@override
State<ImageWidget> createState() => _ImageWidgetState();
}
class _ImageWidgetState extends State<ImageWidget> {
Reaction<String>? _selectedReaction;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
child: AspectRatio(
aspectRatio: 2,
child: Stack(
children: [
Card(
margin: EdgeInsets.zero,
elevation: 2,
clipBehavior: Clip.antiAlias,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
child: ReactionButton<String>(
onReactionChanged: (Reaction<String>? reaction) {
setState(() {
_selectedReaction = reaction;
});
debugPrint('Selected value: ${reaction?.value}');
},
itemSize: const Size.square(40),
reactions: widget.reactions,
child: Image.asset(
widget.imgPath,
width: double.infinity,
fit: BoxFit.cover,
),
),
),
PositionedDirectional(
end: 5,
bottom: 5,
child: Container(
height: 30,
width: 30,
decoration: BoxDecoration(
color: Colors.black.withOpacity(.35),
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(.3),
offset: const Offset(0, 3),
blurRadius: 3,
)
],
),
child: _selectedReaction?.previewIcon,
),
),
],
),
),
);
}
}
================================================
FILE: example/lib/main.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
import 'package:flutter_reaction_button_test/data.dart' as data;
import 'package:flutter_reaction_button_test/image.dart';
import 'package:flutter_reaction_button_test/post.dart';
void main() {
runApp(
const MyApp(),
);
}
class MyApp extends StatelessWidget {
const MyApp({
super.key,
});
@override
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: (context) {
return SizedBox.square(
dimension: 30,
child: ReactionButton<String>(
toggle: false,
direction: ReactionsBoxAlignment.rtl,
onReactionChanged: (Reaction<String>? reaction) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text('Selected language: ${reaction?.value}'),
),
);
},
reactions: data.flagsReactions,
placeholder: const Reaction<String>(
value: null,
icon: Icon(
Icons.language,
),
),
boxColor: Colors.black.withOpacity(0.5),
boxRadius: 10,
itemsSpacing: 20,
itemSize: const Size(40, 60),
),
);
},
),
const SizedBox(width: 10),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: 5),
child: Column(
children: [
PostWidget(
title: 'image 1',
imgPath: 'assets/images/img1.jpg',
reactions: data.reactions,
),
ImageWidget(
imgPath: 'assets/images/img1.jpg',
reactions: data.reactions,
),
PostWidget(
title: 'image 2',
imgPath: 'assets/images/img2.jpg',
reactions: data.reactions,
),
ImageWidget(
imgPath: 'assets/images/img2.jpg',
reactions: data.reactions,
),
PostWidget(
title: 'image 3',
imgPath: 'assets/images/img3.jpg',
reactions: data.reactions,
),
ImageWidget(
imgPath: 'assets/images/img3.jpg',
reactions: data.reactions,
),
PostWidget(
title: 'image 4',
imgPath: 'assets/images/img4.jpg',
reactions: data.reactions,
),
ImageWidget(
imgPath: 'assets/images/img4.jpg',
reactions: data.reactions,
),
PostWidget(
title: 'image 5',
imgPath: 'assets/images/img5.jpg',
reactions: data.reactions,
),
ImageWidget(
imgPath: 'assets/images/img5.jpg',
reactions: data.reactions,
),
const SafeArea(
child: SizedBox(),
),
],
),
),
),
);
}
}
================================================
FILE: example/lib/post.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
import 'package:flutter_reaction_button_test/data.dart' as data;
class PostWidget extends StatelessWidget {
const PostWidget({
Key? key,
required this.title,
required this.imgPath,
required this.reactions,
}) : super(key: key);
final String title;
final String imgPath;
final List<Reaction<String>> reactions;
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
elevation: 2,
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(5),
),
child: Column(
children: [
AspectRatio(
aspectRatio: 2,
child: Image.asset(
imgPath,
width: double.infinity,
fit: BoxFit.cover,
),
),
Container(
height: 55,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ReactionButton<String>(
itemSize: const Size.square(40),
onReactionChanged: (Reaction<String>? reaction) {
debugPrint('Selected value: ${reaction?.value}');
},
reactions: reactions,
placeholder: data.defaultInitialReaction,
selectedReaction: reactions.first,
),
Row(
children: [
Icon(
Icons.message,
size: 16,
color: Colors.grey[400],
),
const SizedBox(width: 5),
Text(
'Comment',
style: TextStyle(
fontSize: 12,
color: Colors.grey[600],
fontWeight: FontWeight.w600,
),
),
],
),
Row(
children: <Widget>[
Icon(
Icons.share,
size: 16,
color: Colors.grey[400],
),
const SizedBox(width: 5),
Text(
'Share',
style: TextStyle(
fontSize: 14,
color: Colors.grey[600],
fontWeight: FontWeight.w600,
),
),
],
)
],
),
),
],
),
),
);
}
}
================================================
FILE: example/pubspec.yaml
================================================
name: flutter_reaction_button_test
description: A new Flutter application.
publish_to: none
version: 1.0.0+1
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.5
flutter_reaction_button:
path: ../
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.1
flutter:
uses-material-design: true
assets:
- assets/images/
================================================
FILE: example/web/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta content="A new Flutter project." name="description">
<!-- iOS meta tags & icons -->
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="example" name="apple-mobile-web-app-title">
<link href="icons/Icon-192.png" rel="apple-touch-icon">
<!-- Favicon -->
<link href="favicon.png" rel="icon" type="image/png"/>
<title>example</title>
<link href="manifest.json" rel="manifest">
</head>
<body>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('flutter_service_worker.js');
});
}
</script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
================================================
FILE: example/web/manifest.json
================================================
{
"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"
}
]
}
================================================
FILE: flutter_reaction_button.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart Packages" level="project" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
</component>
</module>
================================================
FILE: lib/flutter_reaction_button.dart
================================================
library flutter_reaction_button;
export 'src/enums/box.dart';
export 'src/models/reaction.dart';
export 'src/widgets/reaction_button.dart';
================================================
FILE: lib/src/common/position.dart
================================================
import 'package:flutter/cupertino.dart';
class PositionData {
const PositionData({
required this.offset,
this.isBoxHovered = false,
});
final Offset offset;
final bool isBoxHovered;
const PositionData.init()
: offset = Offset.zero,
isBoxHovered = false;
PositionData copyWith({
Offset? offset,
bool? isBoxHovered,
}) {
return PositionData(
offset: offset ?? this.offset,
isBoxHovered: isBoxHovered ?? this.isBoxHovered,
);
}
}
================================================
FILE: lib/src/common/position_notifier.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/src/common/position.dart';
class PositionNotifier extends ValueNotifier<PositionData> {
PositionNotifier() : super(const PositionData.init());
}
================================================
FILE: lib/src/enums/box.dart
================================================
enum ReactionsBoxAlignment {
ltr,
rtl,
}
================================================
FILE: lib/src/enums/reaction.dart
================================================
enum ReactionType {
button,
container,
}
================================================
FILE: lib/src/extensions/key.dart
================================================
import 'package:flutter/widgets.dart';
extension GlobalKeyExtensions on GlobalKey {
Offset get offset {
final RenderBox renderBox = currentContext!.findRenderObject() as RenderBox;
return renderBox.localToGlobal(Offset.zero);
}
}
================================================
FILE: lib/src/models/reaction.dart
================================================
import 'package:flutter/material.dart';
class Reaction<T> {
const Reaction({
required this.value,
required this.icon,
Widget? previewIcon,
this.title,
}) : previewIcon = previewIcon ?? icon;
/// Widget showing as button after selecting preview Icon from box appear.
final Widget icon;
/// Widget showing when reactions box appear.
///
/// If it's null will replace by [icon].
final Widget previewIcon;
/// 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 T? value;
@override
bool operator ==(Object? other) {
return other is Reaction &&
icon == other.icon &&
icon.key == other.icon.key &&
previewIcon == other.previewIcon &&
previewIcon.key == other.previewIcon.key &&
title == other.title &&
title?.key == other.title?.key;
}
@override
int get hashCode {
return Object.hash(icon, previewIcon, title);
}
}
================================================
FILE: lib/src/widgets/reaction_button.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
import 'package:flutter_reaction_button/src/enums/reaction.dart';
import 'package:flutter_reaction_button/src/extensions/key.dart';
import 'package:flutter_reaction_button/src/widgets/reactions_box.dart';
class ReactionButton<T> extends StatefulWidget {
const ReactionButton({
super.key,
required this.onReactionChanged,
required this.reactions,
this.placeholder,
this.selectedReaction,
this.boxColor = Colors.white,
this.boxElevation = 5,
this.boxRadius = 50,
this.isChecked = false,
this.itemsSpacing = 8,
this.itemScale = .3,
required this.itemSize,
this.animateBox = true,
this.toggle = true,
this.boxPadding = const EdgeInsets.all(4),
this.boxAnimationDuration = const Duration(milliseconds: 200),
this.itemAnimationDuration = const Duration(milliseconds: 100),
this.hoverDuration = const Duration(milliseconds: 400),
this.child,
this.direction = ReactionsBoxAlignment.ltr,
}) : _type = child != null ? ReactionType.container : ReactionType.button;
/// This triggers when reaction button value changed.
final ValueChanged<Reaction<T>?> onReactionChanged;
/// Default widget if no reaction selected
final Reaction<T>? placeholder;
/// Selected reaction button when tap on widget
final Reaction<T>? selectedReaction;
final List<Reaction<T>?> reactions;
/// Reactions box color [default = white]
final Color boxColor;
/// Reactions box elevation [default = 5]
final double boxElevation;
/// Reactions box radius [default = 50]
final double boxRadius;
/// Reactions box visibility duration [default = 200 milliseconds]
final Duration boxAnimationDuration;
/// Flag for pre-set reactions if true @link selectedReaction will be
/// displayed else @link initialReaction will be displayed [default = false]
final bool isChecked;
/// Reactions box padding [default = const EdgeInsets.all(0)]
final EdgeInsetsGeometry boxPadding;
/// Spacing between the reaction items
final double itemsSpacing;
/// Scale ratio when item hovered [default = 0.3]
final double itemScale;
/// Animation duration while moving [default = const Duration(milliseconds: 100)]
final Duration itemAnimationDuration;
final Size itemSize;
final bool animateBox;
final bool toggle;
final Widget? child;
final Duration hoverDuration;
final ReactionsBoxAlignment direction;
final ReactionType _type;
@override
State<ReactionButton<T>> createState() => _ReactionButtonState<T>();
}
class _ReactionButtonState<T> extends State<ReactionButton<T>> {
final GlobalKey _globalKey = GlobalKey();
late Reaction<T>? _selectedReaction =
_isChecked ? widget.selectedReaction : widget.placeholder;
late bool _isChecked = widget.isChecked;
bool get _isContainer => widget._type == ReactionType.container;
OverlayEntry? _overlayEntry;
void _updateReaction(Reaction<T>? reaction) {
_isChecked = reaction != widget.placeholder;
widget.onReactionChanged.call(reaction);
setState(() {
_selectedReaction = reaction;
});
}
void _onCheck() {
_isChecked = !_isChecked;
_updateReaction(
_isChecked
? widget.selectedReaction ?? widget.reactions.first
: widget.placeholder,
);
}
void _onShowReactionsBox([Offset? offset]) {
_overlayEntry = OverlayEntry(
builder: (context) {
return ReactionsBox<T>(
offset: offset ?? _globalKey.offset,
itemSize: widget.itemSize,
reactions: widget.reactions,
color: widget.boxColor,
elevation: widget.boxElevation,
radius: widget.boxRadius,
boxDuration: widget.boxAnimationDuration,
boxPadding: widget.boxPadding,
itemSpace: widget.itemsSpacing,
itemScale: widget.itemScale,
itemScaleDuration: widget.itemAnimationDuration,
animateBox: widget.animateBox,
direction: widget.direction,
onReactionSelected: (reaction) {
_updateReaction(reaction);
_disposeOverlayEntry();
},
onClose: () {
_disposeOverlayEntry();
},
);
},
);
Overlay.of(context).insert(_overlayEntry!);
}
void _disposeOverlayEntry() {
_overlayEntry
?..remove()
..dispose();
_overlayEntry = null;
}
@override
void dispose() {
_disposeOverlayEntry();
super.dispose();
}
@override
Widget build(BuildContext context) {
final Widget? child = _isContainer
? widget.child
: (_selectedReaction ?? widget.reactions.first)!.icon;
return GestureDetector(
key: _globalKey,
onTap: () {
if (widget.toggle) {
_onCheck();
} else {
_onShowReactionsBox();
}
},
onLongPressStart: (details) {
if (widget.toggle) {
_onShowReactionsBox(_isContainer ? details.globalPosition : null);
}
},
child: child,
);
}
}
================================================
FILE: lib/src/widgets/reactions_box.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
import 'package:flutter_reaction_button/src/common/position.dart';
import 'package:flutter_reaction_button/src/common/position_notifier.dart';
import 'package:flutter_reaction_button/src/widgets/reactions_box_item.dart';
class ReactionsBox<T> extends StatefulWidget {
const ReactionsBox({
super.key,
required this.offset,
required this.itemSize,
required this.reactions,
required this.color,
required this.elevation,
required this.radius,
required this.boxDuration,
required this.boxPadding,
required this.itemSpace,
required this.itemScale,
required this.itemScaleDuration,
required this.onReactionSelected,
required this.onClose,
required this.animateBox,
this.direction = ReactionsBoxAlignment.ltr,
}) : assert(itemScale > 0.0 && itemScale < 1);
final Offset offset;
final Size itemSize;
final List<Reaction<T>?> reactions;
final Color color;
final double elevation;
final double radius;
final Duration boxDuration;
final EdgeInsetsGeometry boxPadding;
final double itemSpace;
final double itemScale;
final Duration itemScaleDuration;
final ValueChanged<Reaction<T>?> onReactionSelected;
final VoidCallback onClose;
final bool animateBox;
final ReactionsBoxAlignment direction;
@override
State<ReactionsBox<T>> createState() => _ReactionsBoxState<T>();
}
class _ReactionsBoxState<T> extends State<ReactionsBox<T>>
with SingleTickerProviderStateMixin {
final PositionNotifier _positionNotifier = PositionNotifier();
late final AnimationController _boxAnimationController = AnimationController(
vsync: this,
duration: widget.animateBox ? widget.boxDuration : Duration.zero,
);
late final Animation _animation;
double get _boxHeight => widget.itemSize.height + widget.boxPadding.vertical;
double get _boxWidth =>
(widget.itemSize.width * widget.reactions.length) +
(widget.itemSpace * (widget.reactions.length - 1)) +
widget.boxPadding.horizontal;
bool get _isWidthOverflow => widget.direction == ReactionsBoxAlignment.ltr
? widget.offset.dx + _boxWidth > MediaQuery.sizeOf(context).width
: widget.offset.dx - _boxWidth < 0;
bool get _shouldStartFromBottom =>
widget.offset.dy - _boxHeight - widget.boxPadding.vertical < 0;
void _checkIsOffsetOutsideBox(Offset offset) {
final Rect boxRect = Rect.fromLTWH(0, 0, _boxWidth, _boxHeight);
if (!boxRect.contains(offset)) {
widget.onClose();
}
}
@override
void initState() {
super.initState();
final Tween tween = IntTween(begin: 0, end: widget.reactions.length);
_animation = tween.animate(_boxAnimationController);
_boxAnimationController.forward();
}
@override
void dispose() {
_positionNotifier.dispose();
_boxAnimationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<PositionData?>(
valueListenable: _positionNotifier,
builder: (context, fingerPosition, child) {
final bool isBoxHovered = fingerPosition?.isBoxHovered ?? false;
final double boxScale =
1 - (widget.itemScale / widget.reactions.length);
final double widthOverflow;
if (_isWidthOverflow) {
widthOverflow = widget.direction == ReactionsBoxAlignment.ltr
? widget.offset.dx + _boxWidth - MediaQuery.sizeOf(context).width
: _boxWidth;
} else {
widthOverflow = 0;
}
final double start = widget.direction == ReactionsBoxAlignment.ltr
? widget.offset.dx - widthOverflow
: widget.offset.dx - _boxWidth + widthOverflow;
final double top = widget.offset.dy -
widget.boxPadding.vertical +
(_shouldStartFromBottom ? 1 : -1) * widget.itemSize.height;
return Stack(
children: [
Positioned.fill(
child: Listener(
onPointerDown: (_) {
widget.onClose();
},
child: Container(
key: const ValueKey('outside'),
color: Colors.transparent,
),
),
),
PositionedDirectional(
start: start,
top: top,
child: Listener(
onPointerDown: (point) {
_positionNotifier.value = PositionData(
offset: point.localPosition,
isBoxHovered: true,
);
},
onPointerMove: (point) {
_positionNotifier.value = _positionNotifier.value.copyWith(
offset: point.localPosition,
isBoxHovered: true,
);
},
onPointerUp: (point) {
_positionNotifier.value = _positionNotifier.value.copyWith(
isBoxHovered: false,
);
_checkIsOffsetOutsideBox(point.localPosition);
},
onPointerCancel: (point) {
_positionNotifier.value = _positionNotifier.value.copyWith(
isBoxHovered: false,
);
_checkIsOffsetOutsideBox(point.localPosition);
},
child: Transform.scale(
scale: isBoxHovered ? boxScale : 1,
child: child!,
),
),
),
],
);
},
child: Material(
color: widget.color,
elevation: widget.elevation,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
widget.radius,
),
),
child: Container(
width: _boxWidth,
height: _boxHeight,
padding: widget.boxPadding,
child: Row(
children: [
for (int index = 0; index < widget.reactions.length; index++) ...[
if (index > 0) ...{
SizedBox(
width: widget.itemSpace,
),
},
AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return AnimatedScale(
duration: widget.boxDuration,
scale: _animation.value > index ? 1 : 0,
child: child,
);
},
child: ReactionsBoxItem<T>(
index: index,
fingerPositionNotifier: _positionNotifier,
reaction: widget.reactions[index]!,
size: widget.itemSize,
scale: widget.itemScale,
space: widget.itemSpace,
animationDuration: widget.itemScaleDuration,
onReactionSelected: (reaction) {
widget.onReactionSelected(reaction);
},
),
),
],
],
),
),
),
);
}
}
================================================
FILE: lib/src/widgets/reactions_box_item.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
import 'package:flutter_reaction_button/src/common/position_notifier.dart';
class ReactionsBoxItem<T> extends StatefulWidget {
const ReactionsBoxItem({
super.key,
required this.reaction,
required this.onReactionSelected,
required this.scale,
required this.index,
required this.size,
required this.space,
required this.animationDuration,
required this.fingerPositionNotifier,
});
final Reaction<T> reaction;
final ValueChanged<Reaction<T>?> onReactionSelected;
final Duration animationDuration;
final PositionNotifier fingerPositionNotifier;
final double scale;
final int index;
final Size size;
final double space;
@override
State<ReactionsBoxItem<T>> createState() => _ReactionsBoxItemState<T>();
}
class _ReactionsBoxItemState<T> extends State<ReactionsBoxItem<T>>
with SingleTickerProviderStateMixin {
late final AnimationController _animationController = AnimationController(
vsync: this,
upperBound: widget.scale,
duration: widget.animationDuration,
reverseDuration: widget.animationDuration,
);
void _listener() {
final Offset fingerOffset = widget.fingerPositionNotifier.value.offset;
final Offset topLeft =
Offset((widget.size.width + widget.space) * widget.index, 0);
final Offset bottomRight = Offset(
(widget.size.width + widget.space) * (widget.index + 1),
widget.size.height,
);
final Rect rect = Rect.fromPoints(topLeft, bottomRight);
final bool selected = rect.contains(fingerOffset);
if (selected) {
final bool isBoxHovered =
widget.fingerPositionNotifier.value.isBoxHovered;
if (!isBoxHovered) {
widget.onReactionSelected(widget.reaction);
}
_animationController.forward();
} else {
_animationController.reverse();
}
}
@override
void initState() {
super.initState();
widget.fingerPositionNotifier.addListener(_listener);
}
@override
void dispose() {
widget.fingerPositionNotifier.removeListener(_listener);
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animationController,
builder: (context, child) {
final bool showTitle =
_animationController.value == _animationController.upperBound &&
widget.reaction.title != null;
return Stack(
clipBehavior: Clip.none,
alignment: Alignment.center,
children: [
Transform.scale(
scale: 1 + _animationController.value,
child: SizedBox.fromSize(
size: widget.size,
child: widget.reaction.previewIcon,
),
),
if (widget.reaction.title != null) ...{
Positioned(
bottom:
widget.size.height * (1 + (_animationController.value / 2)),
child: AnimatedOpacity(
opacity: showTitle ? 1 : 0,
duration: widget.animationDuration,
child: widget.reaction.title!,
),
)
},
],
);
},
);
}
}
================================================
FILE: pubspec.yaml
================================================
name: flutter_reaction_button
description: Flutter Reaction Button is a customizable Flutter package that allows you to easily create interactive buttons with reaction emojis, similar to Facebook's iconic reaction buttons.
homepage: https://github.com/GeekAbdelouahed/flutter-reaction-button
repository: https://github.com/GeekAbdelouahed/flutter-reaction-button.git
version: 3.0.0+3
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.1
flutter:
================================================
FILE: test/main.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
const Reaction _placeHolder = Reaction(
value: 0,
icon: Icon(Icons.sunny_snowing),
);
const List<Reaction> _reactions = [
Reaction(
value: 1,
icon: Icon(Icons.ac_unit),
),
Reaction(
value: 2,
icon: Icon(Icons.sunny),
),
Reaction(
value: 3,
icon: Icon(Icons.wind_power),
),
];
class MyApp extends StatelessWidget {
const MyApp({
super.key,
this.toggle = true,
});
final bool toggle;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: 5),
child: Column(
children: List.generate(
10,
(index) {
return ReactionButton(
toggle: toggle,
onReactionChanged: (reaction) {},
reactions: _reactions,
placeholder: _placeHolder,
itemSize: const Size.square(24),
);
},
),
),
),
),
);
}
}
================================================
FILE: test/reaction_button_test.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_reaction_button/flutter_reaction_button.dart';
import 'package:flutter_reaction_button/src/widgets/reactions_box.dart';
import 'package:flutter_reaction_button/src/widgets/reactions_box_item.dart';
import 'package:flutter_test/flutter_test.dart';
import 'main.dart';
void main() {
group(
'Reaction button with toggle = true',
() {
testWidgets(
'Expect to select initial reaction '
'when tap on reaction button',
(tester) async {
await tester.pumpWidget(const MyApp());
final Finder reaction = find.byType(ReactionButton).first;
await tester.tap(reaction);
await tester.pump();
final Finder initialReaction = find.byIcon(Icons.ac_unit);
expect(initialReaction, findsOneWidget);
},
);
testWidgets(
'Expect to show reactions box '
'when long press on reaction button',
(tester) async {
await tester.pumpWidget(const MyApp());
final Finder reaction = find.byType(ReactionButton).first;
await tester.longPress(reaction);
await tester.pumpAndSettle();
final Finder reactionsBox = find.byType(ReactionsBox);
expect(reactionsBox, findsOneWidget);
},
);
testWidgets(
'Expect reactions box to closed successfully '
'when tap outside',
(tester) async {
await tester.pumpWidget(const MyApp());
final Finder reaction = find.byType(ReactionButton).first;
await tester.longPress(reaction);
await tester.pumpAndSettle();
final Finder outsideWidget = find.byKey(const ValueKey('outside'));
await tester.tap(outsideWidget);
await tester.pumpAndSettle();
final Finder lastReactionIcon = find.byType(ReactionsBox);
expect(lastReactionIcon, findsNothing);
},
);
testWidgets(
'Expect to select last reaction from reactions box '
'when long press on reaction button and reactions box is visible',
(tester) async {
await tester.pumpWidget(const MyApp());
final Finder reaction = find.byType(ReactionButton).first;
await tester.longPress(reaction);
await tester.pumpAndSettle();
final Finder lastReaction = find.byType(ReactionsBoxItem).last;
await tester.tap(lastReaction);
await tester.pumpAndSettle();
final Finder lastReactionIcon = find.byIcon(Icons.wind_power);
expect(lastReactionIcon, findsOneWidget);
},
);
},
);
group(
'Reaction button with toggle = false',
() {
testWidgets(
'Expect to show reactions box '
'when tap on reaction button',
(tester) async {
await tester.pumpWidget(const MyApp(toggle: false));
final Finder reaction = find.byType(ReactionButton).first;
await tester.tap(reaction);
await tester.pumpAndSettle();
final Finder reactionsBox = find.byType(ReactionsBox);
expect(reactionsBox, findsOneWidget);
},
);
testWidgets(
'Expect reactions box to closed successfully '
'when tap outside',
(tester) async {
await tester.pumpWidget(const MyApp(toggle: false));
final Finder reaction = find.byType(ReactionButton).first;
await tester.tap(reaction);
await tester.pumpAndSettle();
final Finder outsideWidget = find.byKey(const ValueKey('outside'));
await tester.tap(outsideWidget);
await tester.pumpAndSettle();
final Finder lastReactionIcon = find.byType(ReactionsBox);
expect(lastReactionIcon, findsNothing);
},
);
testWidgets(
'Expect to select last reaction from reactions box '
'when long press on reaction button and reactions box is visible',
(tester) async {
await tester.pumpWidget(const MyApp(toggle: false));
final Finder reaction = find.byType(ReactionButton).first;
await tester.tap(reaction);
await tester.pumpAndSettle();
final Finder lastReaction = find.byType(ReactionsBoxItem).last;
await tester.tap(lastReaction);
await tester.pumpAndSettle();
final Finder lastReactionIcon = find.byIcon(Icons.wind_power);
expect(lastReactionIcon, findsOneWidget);
},
);
},
);
}
gitextract_8tbpjqev/
├── .github/
│ └── workflows/
│ ├── publish.yml
│ └── test.yml
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example/
│ ├── .gitignore
│ ├── .metadata
│ ├── README.md
│ ├── analysis_options.yaml
│ ├── android/
│ │ ├── .gitignore
│ │ ├── .project
│ │ ├── .settings/
│ │ │ └── org.eclipse.buildship.core.prefs
│ │ ├── app/
│ │ │ ├── build.gradle
│ │ │ └── src/
│ │ │ ├── debug/
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── kotlin/
│ │ │ │ │ └── abdelouahedmedjoudja/
│ │ │ │ │ ├── example/
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ │ └── flutter_reaction_button_test/
│ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── res/
│ │ │ │ ├── drawable/
│ │ │ │ │ └── launch_background.xml
│ │ │ │ └── values/
│ │ │ │ └── styles.xml
│ │ │ └── profile/
│ │ │ └── AndroidManifest.xml
│ │ ├── build.gradle
│ │ ├── gradle/
│ │ │ └── wrapper/
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradle.properties
│ │ └── settings.gradle
│ ├── ios/
│ │ ├── .gitignore
│ │ ├── Flutter/
│ │ │ ├── AppFrameworkInfo.plist
│ │ │ ├── Debug.xcconfig
│ │ │ └── Release.xcconfig
│ │ ├── Runner/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ └── LaunchImage.imageset/
│ │ │ │ ├── Contents.json
│ │ │ │ └── README.md
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ └── Runner-Bridging-Header.h
│ │ ├── Runner.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── Runner.xcscheme
│ │ └── Runner.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ ├── lib/
│ │ ├── data.dart
│ │ ├── image.dart
│ │ ├── main.dart
│ │ └── post.dart
│ ├── pubspec.yaml
│ └── web/
│ ├── index.html
│ └── manifest.json
├── flutter_reaction_button.iml
├── lib/
│ ├── flutter_reaction_button.dart
│ └── src/
│ ├── common/
│ │ ├── position.dart
│ │ └── position_notifier.dart
│ ├── enums/
│ │ ├── box.dart
│ │ └── reaction.dart
│ ├── extensions/
│ │ └── key.dart
│ ├── models/
│ │ └── reaction.dart
│ └── widgets/
│ ├── reaction_button.dart
│ ├── reactions_box.dart
│ └── reactions_box_item.dart
├── pubspec.yaml
└── test/
├── main.dart
└── reaction_button_test.dart
SYMBOL INDEX (46 symbols across 14 files)
FILE: example/lib/data.dart
function _buildFlagPreviewIcon (line 175) | Widget _buildFlagPreviewIcon(String path, String text)
function _buildEmojiTitle (line 193) | Widget _buildEmojiTitle(String title)
function _buildEmojiPreviewIcon (line 212) | Widget _buildEmojiPreviewIcon(String path)
function _buildFlagIcon (line 216) | Widget _buildFlagIcon(String path)
function _buildReactionsIcon (line 220) | Widget _buildReactionsIcon(String path, Text text)
FILE: example/lib/image.dart
class ImageWidget (line 4) | class ImageWidget extends StatefulWidget {
method createState (line 15) | State<ImageWidget> createState()
class _ImageWidgetState (line 18) | class _ImageWidgetState extends State<ImageWidget> {
method build (line 22) | Widget build(BuildContext context)
FILE: example/lib/main.dart
function main (line 7) | void main()
class MyApp (line 13) | class MyApp extends StatelessWidget {
method build (line 19) | Widget build(BuildContext context)
FILE: example/lib/post.dart
class PostWidget (line 5) | class PostWidget extends StatelessWidget {
method build (line 18) | Widget build(BuildContext context)
FILE: lib/src/common/position.dart
class PositionData (line 3) | class PositionData {
method copyWith (line 16) | PositionData copyWith({
FILE: lib/src/common/position_notifier.dart
class PositionNotifier (line 4) | class PositionNotifier extends ValueNotifier<PositionData> {
FILE: lib/src/enums/box.dart
type ReactionsBoxAlignment (line 1) | enum ReactionsBoxAlignment {
FILE: lib/src/enums/reaction.dart
type ReactionType (line 1) | enum ReactionType {
FILE: lib/src/models/reaction.dart
class Reaction (line 3) | class Reaction<T> {
FILE: lib/src/widgets/reaction_button.dart
class ReactionButton (line 7) | class ReactionButton<T> extends StatefulWidget {
method createState (line 85) | State<ReactionButton<T>> createState()
class _ReactionButtonState (line 88) | class _ReactionButtonState<T> extends State<ReactionButton<T>> {
method _updateReaction (line 100) | void _updateReaction(Reaction<T>? reaction)
method _onCheck (line 108) | void _onCheck()
method _onShowReactionsBox (line 117) | void _onShowReactionsBox([Offset? offset])
method _disposeOverlayEntry (line 148) | void _disposeOverlayEntry()
method dispose (line 156) | void dispose()
method build (line 162) | Widget build(BuildContext context)
FILE: lib/src/widgets/reactions_box.dart
class ReactionsBox (line 7) | class ReactionsBox<T> extends StatefulWidget {
method createState (line 58) | State<ReactionsBox<T>> createState()
class _ReactionsBoxState (line 61) | class _ReactionsBoxState<T> extends State<ReactionsBox<T>>
method _checkIsOffsetOutsideBox (line 86) | void _checkIsOffsetOutsideBox(Offset offset)
method initState (line 94) | void initState()
method dispose (line 102) | void dispose()
method build (line 109) | Widget build(BuildContext context)
FILE: lib/src/widgets/reactions_box_item.dart
class ReactionsBoxItem (line 5) | class ReactionsBoxItem<T> extends StatefulWidget {
method createState (line 35) | State<ReactionsBoxItem<T>> createState()
class _ReactionsBoxItemState (line 38) | class _ReactionsBoxItemState<T> extends State<ReactionsBoxItem<T>>
method _listener (line 47) | void _listener()
method initState (line 71) | void initState()
method dispose (line 77) | void dispose()
method build (line 84) | Widget build(BuildContext context)
FILE: test/main.dart
class MyApp (line 24) | class MyApp extends StatelessWidget {
method build (line 33) | Widget build(BuildContext context)
FILE: test/reaction_button_test.dart
function main (line 9) | void main()
Condensed preview — 68 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (109K chars).
[
{
"path": ".github/workflows/publish.yml",
"chars": 734,
"preview": "name: Publish\n\non:\n push:\n tags:\n - 'v[0-9]+.[0-9]+.[0-9]+*'\n\njobs:\n build:\n runs-on: ubuntu-latest\n steps"
},
{
"path": ".github/workflows/test.yml",
"chars": 364,
"preview": "name: Test\n\non: [push]\n\njobs:\n build:\n runs-on: ubuntu-latest\n\n steps:\n - uses: actions/checkout@v3\n - "
},
{
"path": ".gitignore",
"chars": 1568,
"preview": "#Flutter versions manager\n.fvm/\n\n.idea/\n.vscode/\n\n# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n"
},
{
"path": ".metadata",
"chars": 309,
"preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
},
{
"path": "CHANGELOG.md",
"chars": 2003,
"preview": "## 3.0.0+3\n* Fix reactions box overflow\n\n## 3.0.0+2\n* Minor updates\n\n## 3.0.0+1\n* Update README\n\n## 3.0.0\n\n- **BREAKING "
},
{
"path": "LICENSE",
"chars": 1078,
"preview": "MIT License\n\nCopyright (c) 2019 Abdelouahed Medjoudja\n\nPermission is hereby granted, free of charge, to any person obtai"
},
{
"path": "README.md",
"chars": 2398,
"preview": "[](https://pub.dartlang.org/packages/flutter_rea"
},
{
"path": "analysis_options.yaml",
"chars": 1452,
"preview": "# This file configures the analyzer, which statically analyzes Dart code to\n# check for errors, warnings, and lints.\n#\n#"
},
{
"path": "example/.gitignore",
"chars": 1478,
"preview": "#Flutter versions manager\n.fvm/\n\n# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n#"
},
{
"path": "example/.metadata",
"chars": 305,
"preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
},
{
"path": "example/README.md",
"chars": 1161,
"preview": "# flutter_reaction_button_example\n\nReactionButton:\n\n```dart\nReactionButton<String>(\n onReactionChanged: (Reaction<Str"
},
{
"path": "example/analysis_options.yaml",
"chars": 1452,
"preview": "# This file configures the analyzer, which statically analyzes Dart code to\n# check for errors, warnings, and lints.\n#\n#"
},
{
"path": "example/android/.gitignore",
"chars": 262,
"preview": "gradle-wrapper.jar\n/.gradle\n/captures/\n/gradlew\n/gradlew.bat\n/local.properties\nGeneratedPluginRegistrant.java\n\n# Remembe"
},
{
"path": "example/android/.project",
"chars": 433,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>android</name>\n\t<comment>Project android created by B"
},
{
"path": "example/android/.settings/org.eclipse.buildship.core.prefs",
"chars": 54,
"preview": "connection.project.dir=\neclipse.preferences.version=1\n"
},
{
"path": "example/android/app/build.gradle",
"chars": 2077,
"preview": "def localProperties = new Properties()\ndef localPropertiesFile = rootProject.file('local.properties')\nif (localPropertie"
},
{
"path": "example/android/app/src/debug/AndroidManifest.xml",
"chars": 358,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"abdelouahedmedjoudja.flutter_reaction_"
},
{
"path": "example/android/app/src/main/AndroidManifest.xml",
"chars": 1874,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"abdelouahedmedjoudja.flutter_reaction_"
},
{
"path": "example/android/app/src/main/kotlin/abdelouahedmedjoudja/example/MainActivity.kt",
"chars": 134,
"preview": "package abdelouahedmedjoudja.example\n\nimport io.flutter.embedding.android.FlutterActivity\n\nclass MainActivity : FlutterA"
},
{
"path": "example/android/app/src/main/kotlin/abdelouahedmedjoudja/flutter_reaction_button_test/MainActivity.kt",
"chars": 155,
"preview": "package abdelouahedmedjoudja.flutter_reaction_button_test\n\nimport io.flutter.embedding.android.FlutterActivity\n\nclass Ma"
},
{
"path": "example/android/app/src/main/res/drawable/launch_background.xml",
"chars": 433,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!-- Modify this file to customize your launch splash screen -->\n<layer-list xmlns"
},
{
"path": "example/android/app/src/main/res/values/styles.xml",
"chars": 362,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <style name=\"LaunchTheme\" parent=\"@android:style/Theme.Black.NoT"
},
{
"path": "example/android/app/src/profile/AndroidManifest.xml",
"chars": 358,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"abdelouahedmedjoudja.flutter_reaction_"
},
{
"path": "example/android/build.gradle",
"chars": 582,
"preview": "buildscript {\n ext.kotlin_version = '1.6.21'\n repositories {\n google()\n jcenter()\n }\n\n depende"
},
{
"path": "example/android/gradle/wrapper/gradle-wrapper.properties",
"chars": 233,
"preview": "#Fri Jun 23 08:50:38 CEST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER"
},
{
"path": "example/android/gradle.properties",
"chars": 104,
"preview": "android.enableJetifier=true\nandroid.useAndroidX=true\norg.gradle.jvmargs=-Xmx1536M\nandroid.enableR8=true\n"
},
{
"path": "example/android/settings.gradle",
"chars": 484,
"preview": "include ':app'\n\ndef flutterProjectRoot = rootProject.projectDir.parentFile.toPath()\n\ndef plugins = new Properties()\ndef "
},
{
"path": "example/ios/.gitignore",
"chars": 504,
"preview": "*.mode1v3\n*.mode2v3\n*.moved-aside\n*.pbxuser\n*.perspectivev3\n**/*sync/\n.sconsign.dblite\n.tags*\n**/.vagrant/\n**/DerivedDat"
},
{
"path": "example/ios/Flutter/AppFrameworkInfo.plist",
"chars": 795,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Flutter/Debug.xcconfig",
"chars": 30,
"preview": "#include \"Generated.xcconfig\"\n"
},
{
"path": "example/ios/Flutter/Release.xcconfig",
"chars": 30,
"preview": "#include \"Generated.xcconfig\"\n"
},
{
"path": "example/ios/Runner/AppDelegate.swift",
"chars": 403,
"preview": "import UIKit\nimport Flutter\n\n@UIApplicationMain\n@objc class AppDelegate: FlutterAppDelegate {\n override func applicatio"
},
{
"path": "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 2439,
"preview": "{\n \"images\": [\n {\n \"size\": \"20x20\",\n \"idiom\": \"iphone\",\n \"filename\": \"Icon-App-20x20@2x.png\",\n \""
},
{
"path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
"chars": 378,
"preview": "{\n \"images\": [\n {\n \"idiom\": \"universal\",\n \"filename\": \"LaunchImage.png\",\n \"scale\": \"1x\"\n },\n {\n"
},
{
"path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
"chars": 336,
"preview": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in"
},
{
"path": "example/ios/Runner/Base.lproj/LaunchScreen.storyboard",
"chars": 2377,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "example/ios/Runner/Base.lproj/Main.storyboard",
"chars": 1605,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "example/ios/Runner/Info.plist",
"chars": 1667,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Runner/Runner-Bridging-Header.h",
"chars": 37,
"preview": "#import \"GeneratedPluginRegistrant.h\""
},
{
"path": "example/ios/Runner.xcodeproj/project.pbxproj",
"chars": 19721,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
"chars": 3291,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1430\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "example/ios/Runner.xcworkspace/contents.xcworkspacedata",
"chars": 152,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:Runner.xcodepr"
},
{
"path": "example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "example/lib/data.dart",
"chars": 4856,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\n\nfinal Li"
},
{
"path": "example/lib/image.dart",
"chars": 2379,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\n\nclass Im"
},
{
"path": "example/lib/main.dart",
"chars": 3788,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\nimport 'p"
},
{
"path": "example/lib/post.dart",
"chars": 3027,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\nimport 'p"
},
{
"path": "example/pubspec.yaml",
"chars": 404,
"preview": "name: flutter_reaction_button_test\ndescription: A new Flutter application.\npublish_to: none\nversion: 1.0.0+1\n\nenvironmen"
},
{
"path": "example/web/index.html",
"chars": 1124,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta content=\"IE=Edge\" http-equiv=\"X-UA-Compatible\">\n <"
},
{
"path": "example/web/manifest.json",
"chars": 496,
"preview": "{\n \"name\": \"example\",\n \"short_name\": \"example\",\n \"start_url\": \".\",\n \"display\": \"standalone\",\n \"background_color\": \""
},
{
"path": "flutter_reaction_button.iml",
"chars": 982,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\">\n <component name=\"NewModuleRootManager\" "
},
{
"path": "lib/flutter_reaction_button.dart",
"chars": 141,
"preview": "library flutter_reaction_button;\n\nexport 'src/enums/box.dart';\nexport 'src/models/reaction.dart';\nexport 'src/widgets/re"
},
{
"path": "lib/src/common/position.dart",
"chars": 497,
"preview": "import 'package:flutter/cupertino.dart';\n\nclass PositionData {\n const PositionData({\n required this.offset,\n this"
},
{
"path": "lib/src/common/position_notifier.dart",
"chars": 228,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/src/common/position.dart';\n\nclass Positi"
},
{
"path": "lib/src/enums/box.dart",
"chars": 45,
"preview": "enum ReactionsBoxAlignment {\n ltr,\n rtl,\n}\n"
},
{
"path": "lib/src/enums/reaction.dart",
"chars": 45,
"preview": "enum ReactionType {\n button,\n container,\n}\n"
},
{
"path": "lib/src/extensions/key.dart",
"chars": 243,
"preview": "import 'package:flutter/widgets.dart';\n\nextension GlobalKeyExtensions on GlobalKey {\n Offset get offset {\n final Ren"
},
{
"path": "lib/src/models/reaction.dart",
"chars": 1045,
"preview": "import 'package:flutter/material.dart';\n\nclass Reaction<T> {\n const Reaction({\n required this.value,\n required th"
},
{
"path": "lib/src/widgets/reaction_button.dart",
"chars": 5132,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\nimport 'p"
},
{
"path": "lib/src/widgets/reactions_box.dart",
"chars": 7326,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\nimport 'p"
},
{
"path": "lib/src/widgets/reactions_box_item.dart",
"chars": 3361,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\nimport 'p"
},
{
"path": "pubspec.yaml",
"chars": 551,
"preview": "name: flutter_reaction_button\ndescription: Flutter Reaction Button is a customizable Flutter package that allows you to "
},
{
"path": "test/main.dart",
"chars": 1209,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\n\nconst Re"
},
{
"path": "test/reaction_button_test.dart",
"chars": 4530,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_reaction_button/flutter_reaction_button.dart';\nimport 'p"
}
]
About this extraction
This page contains the full source code of the GeekAbdelouahed/flutter-reaction-button GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 68 files (96.1 KB), approximately 27.2k tokens, and a symbol index with 46 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.