├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── build.yaml
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── example
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable-v21
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── values-night
│ │ │ │ └── styles.xml
│ │ │ │ └── values
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── build.excerpt.yaml
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── 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
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── lib
│ ├── main.dart
│ ├── pages
│ │ ├── post_detail
│ │ │ ├── post_detail_page.dart
│ │ │ ├── post_detail_page_scenes.dart
│ │ │ └── post_detail_page_scenes.stager_app.g.dart
│ │ ├── posts_list
│ │ │ ├── posts_list_page.dart
│ │ │ ├── posts_list_page_scenes.dart
│ │ │ ├── posts_list_page_scenes.mocks.dart
│ │ │ └── posts_list_page_scenes.stager_app.g.dart
│ │ └── user_detail
│ │ │ ├── user_detail_page.dart
│ │ │ ├── user_detail_page_scenes.dart
│ │ │ └── user_detail_page_scenes.stager_app.g.dart
│ └── shared
│ │ ├── api.dart
│ │ ├── post.dart
│ │ ├── post_card
│ │ ├── post_card.dart
│ │ ├── post_card_scenes.dart
│ │ └── post_card_scenes.stager_app.g.dart
│ │ ├── posts_list
│ │ └── posts_list.dart
│ │ └── user.dart
├── linux
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ ├── main.cc
│ ├── my_application.cc
│ └── my_application.h
├── macos
│ ├── .gitignore
│ ├── Flutter
│ │ ├── Flutter-Debug.xcconfig
│ │ ├── Flutter-Release.xcconfig
│ │ └── GeneratedPluginRegistrant.swift
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── app_icon_1024.png
│ │ │ ├── app_icon_128.png
│ │ │ ├── app_icon_16.png
│ │ │ ├── app_icon_256.png
│ │ │ ├── app_icon_32.png
│ │ │ ├── app_icon_512.png
│ │ │ └── app_icon_64.png
│ │ ├── Base.lproj
│ │ └── MainMenu.xib
│ │ ├── Configs
│ │ ├── AppInfo.xcconfig
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── Warnings.xcconfig
│ │ ├── DebugProfile.entitlements
│ │ ├── Info.plist
│ │ ├── MainFlutterWindow.swift
│ │ └── Release.entitlements
├── pubspec.lock
├── pubspec.yaml
├── test
│ ├── pages
│ │ ├── post_detail_page_test.dart
│ │ ├── posts_list_page_test.dart
│ │ └── user_detail_page_test.dart
│ └── scene_test_extensions.dart
├── web
│ ├── favicon.png
│ ├── icons
│ │ ├── Icon-192.png
│ │ ├── Icon-512.png
│ │ ├── Icon-maskable-192.png
│ │ └── Icon-maskable-512.png
│ ├── index.html
│ └── manifest.json
└── windows
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
│ └── runner
│ ├── CMakeLists.txt
│ ├── Runner.rc
│ ├── flutter_window.cpp
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── resource.h
│ ├── resources
│ └── app_icon.ico
│ ├── runner.exe.manifest
│ ├── utils.cpp
│ ├── utils.h
│ ├── win32_window.cpp
│ └── win32_window.h
├── lib
├── builder.dart
├── src
│ ├── environment
│ │ ├── controls
│ │ │ ├── boolean_control.dart
│ │ │ ├── dropdown_control.dart
│ │ │ ├── environment_control.dart
│ │ │ ├── stepper_control.dart
│ │ │ └── text_input_control.dart
│ │ ├── environment_control_panel.dart
│ │ └── state
│ │ │ ├── environment_state.dart
│ │ │ └── screen_size_preset.dart
│ ├── environment_aware_app.dart
│ ├── extensions
│ │ └── string_extensions.dart
│ ├── scene.dart
│ ├── scene_container.dart
│ ├── scene_list.dart
│ ├── stager_app.dart
│ └── stager_app_generator.dart
└── stager.dart
├── pubspec.lock
├── pubspec.yaml
└── test
├── environment_control_panel_test.dart
├── scene_container_test.dart
└── stager_app_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | # Files and directories created by pub.
2 | .dart_tool/
3 | .packages
4 |
5 | # Conventional directory for build output.
6 | build/
7 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.0.0
2 |
3 | - Better support for the environment control panel on larger screens.
4 | - Overhaul of environment control system, including custom controls.
5 | - Updated license from MIT to Apache 2.0, changed copyright to Google.
6 |
7 | ## 0.2.2
8 |
9 | This version includes a complete overhaul of the environment control panel.
10 |
11 | - Adds new functionality to environment control panel (device sizes, bold text).
12 | - Scenes can now add their own widgets to the environment control panel.
13 |
14 | ## 0.1.0
15 |
16 | - Initial version.
17 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Unfortunately, we are not accepting contributions at this time.
2 |
--------------------------------------------------------------------------------
/build.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | targets:
16 | $default:
17 | builders:
18 | stager|stagerAppBuilder:
19 | generate_for:
20 | - example/**.dart
21 |
22 | builders:
23 | stagerAppBuilder:
24 | import: "package:stager/builder.dart"
25 | builder_factories: ["buildStagerApp"]
26 | build_extensions: {".dart": [".stager_app.dart"]}
27 | build_to: source
28 | auto_apply: dependents
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled.
5 |
6 | version:
7 | revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
8 | channel: master
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
17 | base_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
18 | - platform: android
19 | create_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
20 | base_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
21 | - platform: ios
22 | create_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
23 | base_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
24 | - platform: linux
25 | create_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
26 | base_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
27 | - platform: macos
28 | create_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
29 | base_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
30 | - platform: web
31 | create_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
32 | base_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
33 | - platform: windows
34 | create_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
35 | base_revision: 80a36fcb0c4845085c150a83d1b63adc8c9a88ec
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Stager Example
2 |
3 | A barebones sample app demonstrating how and why you might want to use Scenes.
4 |
5 | ## Overview
6 |
7 | This app shows a Twitter-like UI. It launches to a list of posts, from which you can
8 | navigate to a post detail page. From the post detail page, you can navigate to a user detail page,
9 | which shows the user's name and their posts.
10 |
11 | To demonstrate how this works with DI and testing, this also uses [package:provider](https://pub.dev/packages/provider)
12 | and [package:mockito](https://pub.dev/packages/mockito). These only serve to illustrate one way you might
13 | use Stager and are not a requirement.
14 |
15 | The app has three pages, each of which have their own scenes. These scenes exercise several different states
16 | for each page, some of which might be a bit diffcult or cumbersome to develop otherwise. For example, developing
17 | a loading screen without Stager might require:
18 |
19 | 1. A one-off edit to the page code to permanently show a loading state. This would almost certainly never be
20 | committed to source control, and any future developers who want to test this would need to duplicate the work.
21 | 2. Using Network Link Conditioner or a similar tool to simulate a bad network connection. This is better than
22 | option 1, but will not be useful when attempting to simulate other states (e.g., empty).
23 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | def localProperties = new Properties()
18 | def localPropertiesFile = rootProject.file('local.properties')
19 | if (localPropertiesFile.exists()) {
20 | localPropertiesFile.withReader('UTF-8') { reader ->
21 | localProperties.load(reader)
22 | }
23 | }
24 |
25 | def flutterRoot = localProperties.getProperty('flutter.sdk')
26 | if (flutterRoot == null) {
27 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
28 | }
29 |
30 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
31 | if (flutterVersionCode == null) {
32 | flutterVersionCode = '1'
33 | }
34 |
35 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
36 | if (flutterVersionName == null) {
37 | flutterVersionName = '1.0'
38 | }
39 |
40 | apply plugin: 'com.android.application'
41 | apply plugin: 'kotlin-android'
42 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
43 |
44 | android {
45 | compileSdkVersion flutter.compileSdkVersion
46 | ndkVersion flutter.ndkVersion
47 |
48 | compileOptions {
49 | sourceCompatibility JavaVersion.VERSION_1_8
50 | targetCompatibility JavaVersion.VERSION_1_8
51 | }
52 |
53 | kotlinOptions {
54 | jvmTarget = '1.8'
55 | }
56 |
57 | sourceSets {
58 | main.java.srcDirs += 'src/main/kotlin'
59 | }
60 |
61 | defaultConfig {
62 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
63 | applicationId "com.example.example"
64 | // You can update the following values to match your application needs.
65 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
66 | minSdkVersion flutter.minSdkVersion
67 | targetSdkVersion flutter.targetSdkVersion
68 | versionCode flutterVersionCode.toInteger()
69 | versionName flutterVersionName
70 | }
71 |
72 | buildTypes {
73 | release {
74 | // TODO: Add your own signing config for the release build.
75 | // Signing with the debug keys for now, so `flutter run --release` works.
76 | signingConfig signingConfigs.debug
77 | }
78 | }
79 | }
80 |
81 | flutter {
82 | source '../..'
83 | }
84 |
85 | dependencies {
86 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
87 | }
88 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
19 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
19 |
23 |
31 |
35 |
39 |
40 |
41 |
42 |
43 |
44 |
46 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package com.example.example
18 |
19 | import io.flutter.embedding.android.FlutterActivity
20 |
21 | class MainActivity: FlutterActivity() {
22 | }
23 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
25 |
31 |
34 |
35 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
25 |
31 |
34 |
35 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
19 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | buildscript {
18 | ext.kotlin_version = '1.6.10'
19 | repositories {
20 | google()
21 | mavenCentral()
22 | }
23 |
24 | dependencies {
25 | classpath 'com.android.tools.build:gradle:7.1.2'
26 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
27 | }
28 | }
29 |
30 | allprojects {
31 | repositories {
32 | google()
33 | mavenCentral()
34 | }
35 | }
36 |
37 | rootProject.buildDir = '../build'
38 | subprojects {
39 | project.buildDir = "${rootProject.buildDir}/${project.name}"
40 | }
41 | subprojects {
42 | project.evaluationDependsOn(':app')
43 | }
44 |
45 | task clean(type: Delete) {
46 | delete rootProject.buildDir
47 | }
48 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
6 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | include ':app'
18 |
19 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
20 | def properties = new Properties()
21 |
22 | assert localPropertiesFile.exists()
23 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
24 |
25 | def flutterSdkPath = properties.getProperty("flutter.sdk")
26 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
27 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
28 |
--------------------------------------------------------------------------------
/example/build.excerpt.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | targets:
16 | $default:
17 | sources:
18 | include:
19 | - lib/**
20 | - test/**
21 | # Some default includes that aren't really used here but will prevent
22 | # false-negative warnings:
23 | - $package$
24 | - lib/$lib$
25 | exclude:
26 | - '**/.*/**'
27 | - '**/build/**'
28 | builders:
29 | code_excerpter|code_excerpter:
30 | enabled: true
31 |
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import UIKit
18 | import Flutter
19 |
20 | @UIApplicationMain
21 | @objc class AppDelegate: FlutterAppDelegate {
22 | override func application(
23 | _ application: UIApplication,
24 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
25 | ) -> Bool {
26 | GeneratedPluginRegistrant.register(with: self)
27 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/flutter-stager/2e9c5de4e14d0b0d2e0980101d7429e3440fc6cc/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | 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.
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Example
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | example
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 | CADisableMinimumFrameDurationOnPhone
47 |
48 | UIApplicationSupportsIndirectInputEvents
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | #import "GeneratedPluginRegistrant.h"
18 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import 'package:flutter/material.dart';
18 | import 'package:provider/provider.dart';
19 |
20 | import 'pages/posts_list/posts_list_page.dart';
21 | import 'shared/api.dart';
22 |
23 | void main() {
24 | runApp(const MyApp());
25 | }
26 |
27 | /// The main app.
28 | class MyApp extends StatelessWidget {
29 | /// Creates a [MyApp].
30 | const MyApp({super.key});
31 |
32 | @override
33 | Widget build(BuildContext context) {
34 | return Provider.value(
35 | value: Api(),
36 | child: MaterialApp(
37 | title: 'Flutter Demo',
38 | theme: ThemeData(
39 | primarySwatch: Colors.blue,
40 | ),
41 | home: const PostsListPage(),
42 | ),
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/example/lib/pages/post_detail/post_detail_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import 'package:flutter/material.dart';
18 |
19 | import '../../shared/post.dart';
20 | import '../user_detail/user_detail_page.dart';
21 |
22 | /// A page for a single [Post].
23 | class PostDetailPage extends StatelessWidget {
24 | /// Creates a [PostDetailPage].
25 | const PostDetailPage({super.key, required this.post});
26 |
27 | /// The [Post] being displayed.
28 | final Post post;
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return Scaffold(
33 | appBar: AppBar(
34 | title: const Text('Post'),
35 | actions: >[
36 | PopupMenuButton(
37 | onSelected: (_) {
38 | final NavigatorState navigatorstate = Navigator.of(context);
39 | navigatorstate.push(
40 | MaterialPageRoute(
41 | builder: (BuildContext context) =>
42 | UserDetailPage(user: post.author),
43 | ),
44 | );
45 | },
46 | itemBuilder: (BuildContext context) => >[
47 | const PopupMenuItem(
48 | value: 0,
49 | child: Text('View User'),
50 | ),
51 | ],
52 | )
53 | ],
54 | ),
55 | body: Padding(
56 | padding: const EdgeInsets.all(10),
57 | child: Column(
58 | crossAxisAlignment: CrossAxisAlignment.start,
59 | children: [
60 | Row(
61 | children: [
62 | CircleAvatar(
63 | child: Text(
64 | post.author.name
65 | .split(' ')
66 | .map((String e) => e[0].toUpperCase())
67 | .join(),
68 | ),
69 | ),
70 | const SizedBox(width: 10),
71 | Text(post.time.toString()),
72 | ],
73 | ),
74 | const SizedBox(height: 10),
75 | Text(
76 | post.text,
77 | style: Theme.of(context).textTheme.headlineSmall,
78 | ),
79 | ],
80 | ),
81 | ),
82 | );
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/example/lib/pages/post_detail/post_detail_page_scenes.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import 'package:flutter/material.dart';
18 | import 'package:stager/stager.dart';
19 |
20 | import '../../shared/post.dart';
21 | import 'post_detail_page.dart';
22 |
23 | /// A scene demonstrating a [PostDetailPage] with content.
24 | class PostDetailPageScene extends Scene {
25 | /// The [EnvironmentState] key that maps to the currentPost value.
26 | static const String _currentPostKey = 'PostDetailPageScene.CurrentPost';
27 |
28 | /// Creates an [EnvironmentControl] that allows the user to choose which
29 | /// [Post] is displayed in this Scene.
30 | final DropdownControl postSelectorControl = DropdownControl(
31 | title: 'Post',
32 | stateKey: _currentPostKey,
33 | defaultValue: Post.fakePosts().first,
34 | items: Post.fakePosts(),
35 | );
36 |
37 | @override
38 | String get title => 'Post Detail';
39 |
40 | /// This [Scene] overrides the otional [environmentControls] getter to add a
41 | /// custom control to the Stager environment control panel.
42 | @override
43 | late final List> environmentControls =
44 | >[
45 | postSelectorControl,
46 | ];
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return EnvironmentAwareApp(
51 | home: PostDetailPage(
52 | post: postSelectorControl.currentValue,
53 | ),
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/example/lib/pages/post_detail/post_detail_page_scenes.stager_app.g.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | // GENERATED CODE - DO NOT MODIFY BY HAND
18 |
19 | // **************************************************************************
20 | // StagerAppGenerator
21 | // **************************************************************************
22 |
23 | import 'package:stager/stager.dart';
24 |
25 | import 'post_detail_page_scenes.dart';
26 |
27 | void main() {
28 | final List scenes = [
29 | PostDetailPageScene(),
30 | ];
31 |
32 | if (const String.fromEnvironment('Scene').isNotEmpty) {
33 | const String sceneName = String.fromEnvironment('Scene');
34 | final Scene scene =
35 | scenes.firstWhere((Scene scene) => scene.title == sceneName);
36 | runStagerApp(scenes: [scene]);
37 | } else {
38 | runStagerApp(scenes: scenes);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/example/lib/pages/posts_list/posts_list_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import 'package:flutter/material.dart';
18 | import 'package:provider/provider.dart';
19 |
20 | import '../../shared/api.dart';
21 | import '../../shared/post.dart';
22 | import '../../shared/posts_list/posts_list.dart';
23 |
24 | /// Shows a timeline view of all [Post]s.
25 | class PostsListPage extends StatefulWidget {
26 | /// Creates a [PostsListPage].
27 | const PostsListPage({super.key});
28 |
29 | @override
30 | State createState() => _PostsListPageState();
31 | }
32 |
33 | class _PostsListPageState extends State {
34 | late Future> _fetchPostsFuture;
35 |
36 | @override
37 | void initState() {
38 | super.initState();
39 | _fetchPostsFuture = Provider.of(context, listen: false).fetchPosts();
40 | }
41 |
42 | @override
43 | Widget build(BuildContext context) {
44 | return Scaffold(
45 | appBar: AppBar(
46 | title: const Text('Posts'),
47 | ),
48 | body: PostsList.fromFuture(_fetchPostsFuture),
49 | );
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/example/lib/pages/posts_list/posts_list_page_scenes.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import 'dart:async';
18 | import 'dart:math';
19 |
20 | import 'package:flutter/material.dart';
21 | import 'package:mockito/annotations.dart';
22 | import 'package:mockito/mockito.dart';
23 | import 'package:provider/provider.dart';
24 | import 'package:stager/stager.dart';
25 |
26 | import '../../shared/api.dart';
27 | import '../../shared/post.dart';
28 | import 'posts_list_page.dart';
29 |
30 | // #docregion PostsListPageScene
31 | @GenerateMocks([Api])
32 | import 'posts_list_page_scenes.mocks.dart';
33 |
34 | /// Defines a shared build method used by subclasses and a [MockApi] subclasses
35 | /// can use to control the behavior of the [PostsListPage].
36 | abstract class BasePostsListScene extends Scene {
37 | /// A mock dependency of [PostsListPage]. Mock the value of [Api.fetchPosts]
38 | /// to put the staged [PostsListPage] into different states.
39 | late MockApi mockApi;
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | return EnvironmentAwareApp(
44 | home: Provider.value(
45 | value: mockApi,
46 | child: const PostsListPage(),
47 | ),
48 | );
49 | }
50 |
51 | @override
52 | Future setUp() async {
53 | mockApi = MockApi();
54 | }
55 | }
56 |
57 | /// A Scene showing the [PostsListPage] with no [Post]s.
58 | class EmptyListScene extends BasePostsListScene {
59 | @override
60 | String get title => 'Empty List';
61 |
62 | @override
63 | Future setUp() async {
64 | await super.setUp();
65 | when(mockApi.fetchPosts()).thenAnswer((_) async => []);
66 | }
67 | }
68 | // #enddocregion PostsListPageScene
69 |
70 | /// A Scene showing the [PostsListPage] with [Post]s.
71 | class WithPostsScene extends BasePostsListScene {
72 | /// Allows the number of posts shown in this Scene to be set in the control
73 | /// panel.
74 | ///
75 | /// Because [PostListsPage] issues a request to fetch posts in [initState],
76 | /// we need to call [setNeedsReconstruct] in the onValueUpdated callback to
77 | /// tell Stager to fully recreate this Scene.
78 | late final StepperControl postCountStepperControl = StepperControl(
79 | title: 'Post Count',
80 | stateKey: 'WithPostsScene.PostCount',
81 | defaultValue: Post.fakePosts().length,
82 | onDecrementPressed: (int currentValue) => max(0, currentValue - 1),
83 | onIncrementPressed: (int currentValue) =>
84 | min(currentValue + 1, Post.fakePosts().length),
85 | onValueUpdated: (_) => setNeedsReconstruct(),
86 | );
87 |
88 | @override
89 | String get title => 'With Posts';
90 |
91 | @override
92 | late final List> environmentControls =
93 | >[
94 | postCountStepperControl,
95 | ];
96 |
97 | @override
98 | Future setUp() async {
99 | await super.setUp();
100 | when(mockApi.fetchPosts()).thenAnswer((_) async {
101 | return Post.fakePosts()
102 | .take(postCountStepperControl.currentValue)
103 | .toList();
104 | });
105 | }
106 | }
107 |
108 | /// A Scene showing the [PostsListPage] in a loading state.
109 | class LoadingScene extends BasePostsListScene {
110 | @override
111 | String get title => 'Loading';
112 |
113 | @override
114 | Future setUp() async {
115 | await super.setUp();
116 | final Completer> completer = Completer>();
117 | when(mockApi.fetchPosts()).thenAnswer((_) async => completer.future);
118 | }
119 | }
120 |
121 | /// A Scene showing the [PostsListPage] in a error state.
122 | class ErrorScene extends BasePostsListScene {
123 | @override
124 | String get title => 'Error';
125 |
126 | @override
127 | Future setUp() async {
128 | await super.setUp();
129 | when(mockApi.fetchPosts()).thenAnswer(
130 | (_) => Future>.error(Exception()),
131 | );
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/example/lib/pages/posts_list/posts_list_page_scenes.mocks.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | // Mocks generated by Mockito 5.3.2 from annotations
18 | // in stager_example/pages/posts_list/posts_list_page_scenes.dart.
19 | // Do not manually edit this file.
20 |
21 | // ignore_for_file: no_leading_underscores_for_library_prefixes
22 | import 'dart:async' as _i3;
23 |
24 | import 'package:mockito/mockito.dart' as _i1;
25 | import 'package:stager_example/shared/api.dart' as _i2;
26 | import 'package:stager_example/shared/post.dart' as _i4;
27 | import 'package:stager_example/shared/user.dart' as _i5;
28 |
29 | // ignore_for_file: type=lint
30 | // ignore_for_file: avoid_redundant_argument_values
31 | // ignore_for_file: avoid_setters_without_getters
32 | // ignore_for_file: comment_references
33 | // ignore_for_file: implementation_imports
34 | // ignore_for_file: invalid_use_of_visible_for_testing_member
35 | // ignore_for_file: prefer_const_constructors
36 | // ignore_for_file: unnecessary_parenthesis
37 | // ignore_for_file: camel_case_types
38 | // ignore_for_file: subtype_of_sealed_class
39 |
40 | /// A class which mocks [Api].
41 | ///
42 | /// See the documentation for Mockito's code generation for more information.
43 | class MockApi extends _i1.Mock implements _i2.Api {
44 | MockApi() {
45 | _i1.throwOnMissingStub(this);
46 | }
47 |
48 | @override
49 | _i3.Future> fetchPosts({_i5.User? user}) =>
50 | (super.noSuchMethod(
51 | Invocation.method(
52 | #fetchPosts,
53 | [],
54 | {#user: user},
55 | ),
56 | returnValue: _i3.Future>.value(<_i4.Post>[]),
57 | ) as _i3.Future>);
58 | }
59 |
--------------------------------------------------------------------------------
/example/lib/pages/posts_list/posts_list_page_scenes.stager_app.g.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | // GENERATED CODE - DO NOT MODIFY BY HAND
18 |
19 | // **************************************************************************
20 | // StagerAppGenerator
21 | // **************************************************************************
22 |
23 | import 'package:stager/stager.dart';
24 |
25 | import 'posts_list_page_scenes.dart';
26 |
27 | void main() {
28 | final List scenes = [
29 | EmptyListScene(),
30 | WithPostsScene(),
31 | LoadingScene(),
32 | ErrorScene(),
33 | ];
34 |
35 | if (const String.fromEnvironment('Scene').isNotEmpty) {
36 | const String sceneName = String.fromEnvironment('Scene');
37 | final Scene scene =
38 | scenes.firstWhere((Scene scene) => scene.title == sceneName);
39 | runStagerApp(scenes: [scene]);
40 | } else {
41 | runStagerApp(scenes: scenes);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/example/lib/pages/user_detail/user_detail_page.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import 'package:flutter/material.dart';
18 | import 'package:provider/provider.dart';
19 |
20 | import '../../shared/api.dart';
21 | import '../../shared/post.dart';
22 | import '../../shared/posts_list/posts_list.dart';
23 | import '../../shared/user.dart';
24 |
25 | /// A page for a single [User].
26 | class UserDetailPage extends StatefulWidget {
27 | /// Creates a [UserDetailPage] which displays information about [user].
28 | const UserDetailPage({super.key, required this.user});
29 |
30 | /// The [User] whose info is being displayed.
31 | final User user;
32 |
33 | @override
34 | State createState() => _UserDetailPageState();
35 | }
36 |
37 | class _UserDetailPageState extends State {
38 | late Future> _userPostsFuture;
39 |
40 | @override
41 | void initState() {
42 | super.initState();
43 |
44 | _userPostsFuture = Provider.of(context, listen: false).fetchPosts(
45 | user: widget.user,
46 | );
47 | }
48 |
49 | @override
50 | Widget build(BuildContext context) {
51 | return Scaffold(
52 | appBar: AppBar(
53 | title: Text(
54 | widget.user.name,
55 | ),
56 | ),
57 | body: Column(
58 | children: [
59 | Padding(
60 | padding: const EdgeInsets.all(10),
61 | child: Text(
62 | '${widget.user.name} (${widget.user.handle})',
63 | style: Theme.of(context).textTheme.displaySmall,
64 | ),
65 | ),
66 | Expanded(
67 | child: PostsList.fromFuture(_userPostsFuture),
68 | ),
69 | ],
70 | ),
71 | );
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/example/lib/pages/user_detail/user_detail_page_scenes.stager_app.g.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | // GENERATED CODE - DO NOT MODIFY BY HAND
18 |
19 | // **************************************************************************
20 | // StagerAppGenerator
21 | // **************************************************************************
22 |
23 | import 'package:stager/stager.dart';
24 |
25 | import 'user_detail_page_scenes.dart';
26 |
27 | void main() {
28 | final List scenes = [
29 | LoadingUserDetailPageScene(),
30 | ErrorUserDetailPageScene(),
31 | EmptyUserDetailPageScene(),
32 | WithPostsUserDetailPageScene(),
33 | ComplexUserDetailPageScene(),
34 | ];
35 |
36 | if (const String.fromEnvironment('Scene').isNotEmpty) {
37 | const String sceneName = String.fromEnvironment('Scene');
38 | final Scene scene =
39 | scenes.firstWhere((Scene scene) => scene.title == sceneName);
40 | runStagerApp(scenes: [scene]);
41 | } else {
42 | runStagerApp(scenes: scenes);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/example/lib/shared/api.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import 'post.dart';
18 | import 'user.dart';
19 |
20 | /// A fake class meant to represent an API client.
21 | class Api {
22 | /// Waits 2 seconds and returns [Post.fakePosts].
23 | Future> fetchPosts({User? user}) async {
24 | await Future.delayed(const Duration(seconds: 2));
25 | return Post.fakePosts(user: user);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/example/lib/shared/post.dart:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2023 Google LLC
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | https://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | import 'package:equatable/equatable.dart';
18 |
19 | import 'user.dart';
20 |
21 | /// A single tweet-like entry.
22 | class Post extends Equatable {
23 | /// Creates a [Post].
24 | const Post({
25 | required this.id,
26 | required this.text,
27 | required this.author,
28 | required this.time,
29 | });
30 |
31 | /// The id of this post.
32 | final int id;
33 |
34 | /// The content of this post.
35 | final String text;
36 |
37 | /// The author of this post.
38 | final User author;
39 |
40 | /// When this post was created.
41 | final DateTime time;
42 |
43 | @override
44 | List