-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from FlutterFlow/how-to-create-use-app-state
Projects section
- Loading branch information
Showing
16 changed files
with
709 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Place your StackBlitz environment variables here, | ||
# and they will be securely synced to your account. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"label": "State Management", | ||
"position": 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
--- | ||
slug: generated-code | ||
title: Generated Code | ||
tags: [] | ||
toc_max_heading_level: 5 | ||
sidebar_position: 5 | ||
--- | ||
# State Management | ||
|
||
FlutterFlow manages state in several ways, depending on the scope. | ||
|
||
Generally, state management is handled using the Provider package, which facilitates the provisioning of data models for components, pages, and the overall app state. | ||
|
||
![state-management.avif](..%2F..%2F..%2Fstatic%2Fimg%2Fstate-management.avif) | ||
|
||
## Page & Component Models | ||
|
||
In FlutterFlow, both component widget models and page models share a uniform structure, enhancing consistency throughout the framework. They include local state fields to store data specific to the component, such as sizes or user inputs. These models are also equipped with initialization and disposal methods: `initState` for setup when the widget initializes, and `dispose` for resource cleanup when the widget is no longer needed. | ||
|
||
Additionally, they provide space for action blocks, which are a set of actions that performs a specific task and can be reused in different parts of the app, and helper methods for extra functionalities needed by the component. This consistent structure across models helps efficiently manage the state and interactions of various components within the app. | ||
|
||
## Page State | ||
|
||
Variables used exclusively within a page—such as a text field validator or the value of a checkbox—are stored in the Model of each page. These variables can be accessed by other component children on the same page. For instance, on a page with a form, tapping a button in one component may need to access the value of a text field in a different component. | ||
|
||
Variables within a page are tracked through StatefulWidgets and are encapsulated into that page’s Model. | ||
|
||
## Component State | ||
|
||
Similar to page state, component variables are accessible within the component where they are defined. Each component has a corresponding Model and Widget class. Variables may be passed in from their parent as parameters. Additionally, you can access component state values from its parent Page widget. | ||
|
||
This accessibility is possible because the Model of a component is instantiated within the parent Page model. It utilizes the Provider method `context.read()`, which returns any existing model in the tree before instantiating a new one. Thus, any updates to the state in the component model will reflect in the parent’s instance of that component model. | ||
|
||
One of the helper methods in `flutter_flow_model.dart` is `wrapWithModel()`. This method wraps the child in a Provider model to make it accessible to the child and sets a callback function, which is generally used to call `setState()` in the parent page and update any changed values. We use this wrapper around widgets that need to access the data included in the model. | ||
|
||
For example, if a page includes a component with a text field and later on the page there is a button needing access to the text field’s value, the button would be wrapped with ```wrapWithModel()```, including the text field component’s Model as a parameter. | ||
|
||
It’s important to note that components cannot directly access variables of other components on the same page. However, you can pass a variable from ComponentA as a parameter to ComponentB in their parent Page. This ensures that ComponentB receives all updates from ComponentA as expected. | ||
|
||
## Variables | ||
|
||
Variables required across multiple pages of the app, such as a username, should be added to the App State. Refer to `lib/app_state.dart`. | ||
|
||
All defined variables within the app state are components of the `FFAppState` class, which functions as a ChangeNotifier. This means listeners can subscribe and receive notifications when any changes occur. | ||
|
||
On each page that requires access to app state variables, the method ```context.watch<AppState>()``` is called to initialize a listener for that page. This ```watch()``` method, provided by the Provider package, facilitates access to inherited widgets and acts as an effective wrapper. | ||
|
||
## Persisting App State | ||
|
||
When an app state variable is created, selecting the "Persisted" option enables FlutterFlow to save it on the device using the [shared_preferences package](https://pub.dev/packages/shared_preferences). This ensures the variable remains available even after the app is restarted, making it ideal for persisting settings such as login status or a user's choice between light and dark modes. | ||
|
||
If the "Secure Persisted Fields" option is enabled in the app state settings, FlutterFlow utilizes the [flutter_secure_storage package](https://pub.dev/packages/flutter_secure_storage) to encrypt the data. This package leverages platform-specific implementations for data encryption, utilizing Keychain on iOS, KeyStore on Android, and libsecret on Linux. | ||
|
||
## Global State | ||
|
||
Global state variables are pieces of information related to the device that are accessible throughout the FlutterFlow app. | ||
|
||
These include: | ||
|
||
- Screen size | ||
- Platform (mobile, web, Android, iOS) | ||
- Keyboard visibility | ||
- Current time | ||
|
||
These variables are found in the "Global Properties" section and are automatically added by FlutterFlow, not generated by users. Users can utilize App State variables for their own global use cases. | ||
|
||
Global properties are retrieved through methods defined in `flutter_flow_utils.dart`. Typically, these methods utilize built-in Flutter libraries, such as `dart:io`, to gather the necessary information. | ||
|
||
## Constants | ||
|
||
For values that do not change throughout the app, such as API keys or environment flags, we utilize the `FFAppConstants` class, which can be found in `lib/app_constants.dart`. This is an abstract class, meaning it cannot be directly instantiated. Instead, it serves as a namespace for static constants, allowing these values to be organized and accessed consistently across the application. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
195 changes: 195 additions & 0 deletions
195
docs/resources/Projects/how-to-collaborate-on-projects.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
--- | ||
slug: how-to-collaborate-on-projects | ||
title: How to Collaborate on Projects | ||
tags: [ ] | ||
toc_max_heading_level: 5 | ||
sidebar_position: 4 | ||
|
||
--- | ||
|
||
FlutterFlow allows for multiple ways to collaborate on a project as well as the | ||
ability to manage the collaboration through permissions. | ||
|
||
## Sharing a Project with a User | ||
|
||
You can also invite users to your project who are not part of your organization. | ||
For instance, you might want to share your work with clients, stakeholders, or | ||
team members of the client. | ||
|
||
When you invite users to your project, you have the flexibility to assign them | ||
different roles depending on their level of involvement. For example, you can | ||
grant **editing** privileges to collaborators who are actively working on the | ||
project while assigning **read-only access** who need to view the progress. | ||
Alternatively, you can also make them the **owner** of the project, giving them full | ||
control. | ||
:::info | ||
|
||
- When you add a user, the default role assigned is the *Editor* role. | ||
- Users with read-only access will only be able to access that specific project | ||
and won't be able to access any shared *Teams* libraries (e.g., custom code, | ||
design system). | ||
- Read-only users added to *Teams*/*Organization* will not count against your | ||
*Teams* seat count. | ||
- You must verify your email before inviting users. | ||
::: | ||
|
||
### How to Invite Users | ||
|
||
<div class="arcade-container" style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding | ||
height: 0, | ||
width: '100%' | ||
}}> | ||
<iframe | ||
src="https://demo.arcade.software/9XkpLuC3tpiFFapWi7ao?embed&show_copy_link=true" | ||
title="Sharing a Project with a User" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light', | ||
}} | ||
frameborder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
|
||
|
||
:::info | ||
|
||
- If a user isn't already a FlutterFlow user, we will send them an invite email. | ||
Their status will be shown as **Pending** until they create an account. | ||
- FlutterFlow subscriptions are seat based. A user added to your project will | ||
only have access to the features of their account plan. | ||
::: | ||
|
||
## Branching Permissions | ||
|
||
The owner of a project can manage permissions related to branching. Owners can | ||
control two types of branching permissions: | ||
|
||
- **Editing Permissions:** Determines who is allowed to edit branching permissions. | ||
- **Merging into Main:** Specifies who is allowed to merge branches into the main | ||
branch. | ||
|
||
<div style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Correctly maintaining the aspect ratio with additional padding | ||
height: 0, | ||
width: '100%' | ||
}}> | ||
<iframe | ||
src="https://demo.arcade.software/P5MgPJuBBeaIm7dfEjqI?embed&show_copy_link=true" | ||
title="Branching Permissions" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameBorder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
|
||
## Sharing a Project with an Organization | ||
|
||
To share a project with all team members in your organization, enable the "Share | ||
with my organization" option. | ||
|
||
![share-project-with-organization.avif](..%2F..%2F..%2Fstatic%2Fimg%2Fshare-project-with-organization.avif) | ||
|
||
## Real-Time Collaboration | ||
|
||
Real-Time Collaboration is a powerful feature that allows multiple builders to | ||
work together on the same project or, rather same page and design system | ||
simultaneously. With this, all builders can see the changes being made to the | ||
page as they happen and can also make their own changes to the page without | ||
interfering with the work of others. | ||
|
||
This increases efficiency and productivity, as multiple builders can work on | ||
various aspects of the project or together on the same page at the same time. | ||
|
||
To enable real-time collaboration, navigate to **Settings & Integrations (from the | ||
left Navigation Menu) > Project Setup > Collaboration > click Enable Updated | ||
Collaboration**. | ||
|
||
![realtime-collaboration-setup.png](..%2F..%2F..%2Fstatic%2Fimg%2Frealtime-collaboration-setup.png) | ||
|
||
Now when multiple builders are on the same page, it looks like this: | ||
|
||
![real-time-collaboration.gif](..%2F..%2F..%2Fstatic%2Fimg%2Freal-time-collaboration.gif) | ||
|
||
To disable this feature anytime, click the **Disable Updated Collaboration** button. | ||
|
||
:::caution | ||
|
||
This feature is still in Beta, and unexpected issues may occur. Ensure you | ||
regularly create project versions as a backup. | ||
|
||
<!-- TODO - Add link to versioning --> | ||
::: | ||
:::info | ||
|
||
Real-Time collaboration is a feature of our Teams and Enterprise plans. | ||
::: | ||
|
||
## Transferring Project | ||
|
||
:::danger | ||
This step can not be undone. If you want to regain project ownership, the new | ||
project owner will need to transfer ownership back to you. | ||
::: | ||
|
||
<div class ="arcade-container" style={{ | ||
position: 'relative', | ||
paddingBottom: 'calc(56.67989417989418% + 41px)', // Maintain aspect ratio plus extra padding | ||
height: 0, | ||
width: '100%' | ||
}}> | ||
<iframe | ||
src="https://demo.arcade.software/hUnKMJ7eqD81SRHkxEmt?embed&show_copy_link=true" | ||
title="Transferring Project" | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
colorScheme: 'light' | ||
}} | ||
frameBorder="0" | ||
loading="lazy" | ||
webkitAllowFullScreen | ||
mozAllowFullScreen | ||
allowFullScreen | ||
allow="clipboard-write"> | ||
</iframe> | ||
</div> | ||
|
||
## Project Activity | ||
|
||
You can see a running history of changes made while building that helps you | ||
track progress and stay up to date on project changes. This feature allows team | ||
members to see all the updates made to a project in real-time, enabling them to | ||
understand how the project is evolving and collaborate more efficiently. | ||
|
||
![flutterflow-project-activity.avif](..%2F..%2F..%2Fstatic%2Fimg%2Fflutterflow-project-activity.avif) | ||
|
||
:::info | ||
Teams users can access the last 7 days of project edits, while FlutterFlow | ||
Enterprise users can access and download all previous project edits. | ||
::: |
Oops, something went wrong.