Compare commits

..

58 commits

Author SHA1 Message Date
Kiril Tijsma
87bf58e6e7
Merge pull request #40 from Iconica-Development/fix/splashscreen-future
fix: always call the splashHandler with the splashScreenFuture and killswitchService when a splashScreenBuilder is provided
2025-04-30 10:01:30 +02:00
Freek van de Ven
ada23abbc5 fix: always call the splashHandler with the splashScreenFuture and killswitchService when a splashScreenBuilder is provided 2025-04-30 09:50:45 +02:00
Jacques
2c61f8d7db fix: Check with the service if the introduction should be shown before actually showing
When removing this, the introduction is briefly shown before calling the onComplete
2025-04-29 15:16:35 +02:00
Freek van de Ven
2a66e11611 chore: add component release workflow 2025-04-22 10:34:27 +02:00
0976083a9f feat(navigator): add navigator widget to allow for app independent navigation 2025-03-17 15:46:44 +01:00
6f24e0521d chore(example): add standard flutter readme 2025-03-17 15:46:44 +01:00
328a75b5a2 chore(example): add web platform to gitignore 2025-03-17 15:46:44 +01:00
Gorter-dev
ed8b5b401a
Merge pull request #37 from Iconica-Development/bugfix/introduction
fix: introduction
2024-07-30 13:19:20 +02:00
mike doornenbal
7635b8a4cc fix: introduction 2024-07-30 13:12:39 +02:00
Gorter-dev
d0b0f88ad3
Merge pull request #35 from Iconica-Development/chore/deploy
chore: ready the package for deployment to the pub server
2024-07-22 15:11:28 +02:00
Bart Ribbers
62161aa60b chore: ready the package for deployment to the pub server 2024-07-22 15:09:14 +02:00
Bart Ribbers
bf018a3ce6 chore: add fvm configuration to gitignore 2024-07-22 15:08:05 +02:00
mike doornenbal
c521be374d
Merge pull request #36 from Iconica-Development/bugfix/default_style
fix: default style and flutter_introduction to new version
2024-07-18 13:15:23 +02:00
mike doornenbal
c558c8dbc7 fix: default style and flutter_introduction to new version 2024-07-12 16:06:01 +02:00
mike doornenbal
c51c7de53a
Merge pull request #34 from Iconica-Development/bugfix/feedback
fix: feedback on userstory
2024-06-06 13:31:23 +02:00
mike doornenbal
84e629d5b2 fix: feedback on userstory 2024-06-05 10:37:20 +02:00
Gorter-dev
e7419bc8c1
Merge pull request #27 from Iconica-Development/feature/default_styling
feat: add default styling
2024-04-19 11:21:47 +02:00
mike doornenbal
90eb8119d8 feat: add default styling 2024-04-19 10:04:03 +02:00
Gorter-dev
fc65e98f96
Merge pull request #26 from Iconica-Development/feature/default_configuration
feat: add default configuration
2024-04-18 09:33:49 +02:00
mike doornenbal
07e1ad0990 feat: add default configuration 2024-04-17 13:49:43 +02:00
mike doornenbal
e357f2fd0f
Merge pull request #25 from Iconica-Development/fix/use-correct-intro-screen-check-boolean
fix: use startWithIntroScreen instead of showIntroduction boolean for…
2024-04-15 10:11:47 +02:00
bd1d6e5bf4 fix: use startWithIntroScreen instead of showIntroduction boolean for checking on which screen to start 2024-04-05 11:44:59 +02:00
FlutterJoey
e012b8d41e
Merge pull request #24 from Iconica-Development/release-3.0.0
release: create 3.0.0 release version with changelog
2024-04-04 16:24:42 +02:00
57bddcf768 release: create 3.0.0 release version with changelog 2024-04-04 16:22:07 +02:00
Gorter-dev
06dc5b8b7a
Merge pull request #23 from Iconica-Development/16-run-the-start-user-story-without-go-router-from-the-start-of-the-app
feat!: add NavigatorStartUserStory widget
2024-04-04 16:11:33 +02:00
2cf2b1c961 feat!: add NavigatorStartUserStory widget
This also changes the startNavigatorUserStory function return type from a widget to Future<void>, as that starts the story. The widget immediately displays the initial screen. This is a breaking change.
2024-04-04 12:51:16 +02:00
Gorter-dev
da2a50c9a7
Merge pull request #21 from Iconica-Development/18-change-the-home-entry-from-a-widget-to-a-callback
feat!: change homeEntry to an onComplete callback
2024-04-04 11:42:39 +02:00
5d66928411 feat!: change homeEntry to an onComplete callback
Breaking: this changes the startNavigatorUserStory interface without any backwards compatibility
2024-04-04 11:41:24 +02:00
Gorter-dev
bf0060273b
Merge pull request #22 from Iconica-Development/17-remove-hard-dependency-on-standard-killswitch-service
feat: add parameter to configuration to supply an implementation of t…
2024-04-04 11:39:46 +02:00
Gorter-dev
40d17eaf31
Merge pull request #20 from Iconica-Development/19-rename-myfunction-in-the-splash-screen-handling-to-an-actual-proper-name
rename myfunction in the splash screen handling to an actual proper name
2024-04-04 11:38:29 +02:00
Gorter-dev
995e6cf986
Merge pull request #15 from Iconica-Development/bugfix/fix_navigator
fix: add return after routing
2024-04-04 11:37:50 +02:00
346f40435f feat: add parameter to configuration to supply an implementation of the killswitch service 2024-04-04 11:33:12 +02:00
218ff31016 fix: call splash handler when no builder is provided
The default splashscreen never proceeded to the next screen unless the splashHandler is being called
2024-04-04 10:05:01 +02:00
6ecc2f0992 fix: add mounted check to navigation after async gap for navigator version 2024-04-04 09:45:15 +02:00
51046aff1f refactor: rename myFunction in splashscreen function to splashHandler 2024-04-04 09:41:36 +02:00
mike doornenbal
b2347c5ccd fix: add return after routing 2024-04-02 11:12:06 +02:00
Freek van de Ven
c9bc617ed0
Merge pull request #14 from Iconica-Development/doc/improve-documentation
doc: improve readme and add CONTRIBUTING.md
2024-03-18 08:29:12 +01:00
Vick Top
aa2595efbf Add BSD-3-Clause license 2024-03-05 15:56:11 +01:00
Freek van de Ven
ff0df4e1b6
Merge pull request #13 from Iconica-Development/feat/can-pop-introduction
feat(introduction): add popscope for introduction screen
2024-02-28 10:57:28 +01:00
Vick Top
d9f1568f70 doc: improve readme and add CONTRIBUTING.md 2024-02-28 10:50:18 +01:00
FahadFahim71
9d4c5c014f feat(introduction): add popscope for introduction screen 2024-02-19 14:36:56 +01:00
Freek van de Ven
d7a13f731e
Merge pull request #12 from Iconica-Development/2.0.4
2.0.4
2024-02-15 15:40:10 +01:00
mike doornenbal
851a98cc1a 2.0.4 2024-02-15 15:38:43 +01:00
Freek van de Ven
e172704ac7
Merge pull request #11 from Iconica-Development/update-component-documentation-workflow-correct
Add component-documentation.yml correct
2024-02-13 16:33:31 +01:00
Freek van de Ven
ffc8e51600
Merge pull request #9 from Iconica-Development/chore/remove-secret
chore: remove old documentation workflow
2024-02-13 16:33:19 +01:00
Freek van de Ven
845fca93b4
Merge pull request #10 from Iconica-Development/feature/add_after_splash_route
feat: added after splash route
2024-02-13 16:32:50 +01:00
Vick Top
c725ab2c68 feat(documentation): Create component-documentation.yml workflow file 2024-02-13 13:33:46 +01:00
mike doornenbal
4f322cb4a3 feat: added after splash route 2024-02-13 11:59:37 +01:00
Vick Top
2f8ee9c241 chore: remove old documentation workflow 2024-02-13 09:36:11 +01:00
Freek van de Ven
cdf53e9afa feat: add documentation workflow 2024-02-11 16:13:21 +01:00
Freek van de Ven
ebe86cf934
Merge pull request #6 from Iconica-Development/feature/add_configuration_options
feat: added configuration options
2024-02-07 12:59:57 +01:00
mike doornenbal
4f5a301f19 feat: added configuration options 2024-02-07 12:55:27 +01:00
mike doornenbal
76f7ec6105 Merge branch 'feature/add_ci' 2024-02-02 16:05:18 +01:00
mike doornenbal
bfde2eb3ad feat: add CI 2024-02-02 16:05:07 +01:00
Gorter-dev
d048d91bc3
Merge pull request #4 from Iconica-Development/feat/add-scaffold
feat: add introduction screen builder
2024-02-01 09:26:08 +01:00
FahadFahim71
2990c836d5 feat: add introduction screen builder 2024-01-31 17:36:21 +01:00
Gorter-dev
68205013b5
Merge pull request #3 from Iconica-Development/feature/killswitch
feat: killswitch
2024-01-24 16:57:50 +01:00
mike doornenbal
1f2602ff76 feat: killswitch 2024-01-24 16:56:53 +01:00
26 changed files with 846 additions and 1415 deletions

14
.github/workflows/component-ci.yml vendored Normal file
View file

@ -0,0 +1,14 @@
name: Iconica Standard Component CI Workflow
# Workflow Caller version: 2.0.0
on:
pull_request:
workflow_dispatch:
jobs:
call-global-iconica-workflow:
uses: Iconica-Development/.github/.github/workflows/component-ci.yml@master
secrets: inherit
permissions: write-all
with:
subfolder: "." # add optional subfolder to run workflow in

View file

@ -0,0 +1,14 @@
name: Iconica Standard Component Documentation Workflow
# Workflow Caller version: 1.0.0
on:
release:
types: [published]
workflow_dispatch:
jobs:
call-iconica-component-documentation-workflow:
uses: Iconica-Development/.github/.github/workflows/component-documentation.yml@master
secrets: inherit
permissions: write-all

14
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,14 @@
name: Iconica Standard Component Release Workflow
# Workflow Caller version: 1.0.0
on:
release:
types: [published]
workflow_dispatch:
jobs:
call-global-iconica-workflow:
uses: Iconica-Development/.github/.github/workflows/component-release.yml@master
secrets: inherit
permissions: write-all

7
.gitignore vendored
View file

@ -19,7 +19,7 @@ migrate_working_dir/
# The .vscode folder contains launch configuration and tasks you configure in # 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 # VS Code which you may wish to be included in version control, so this line
# is commented out by default. # is commented out by default.
#.vscode/ .vscode/
# Flutter/Dart/Pub related # Flutter/Dart/Pub related
**/doc/api/ **/doc/api/
@ -43,3 +43,8 @@ app.*.map.json
/android/app/release /android/app/release
ios ios
.metadata .metadata
pubspec.lock
# FVM Version Cache
.fvm/
.fvmrc

View file

@ -1,45 +0,0 @@
# 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: "67457e669f79e9f8d13d7a68fe09775fefbb79f4"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
- platform: android
create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
- platform: ios
create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
- platform: linux
create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
- platform: macos
create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
- platform: web
create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
- platform: windows
create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

70
CHANGELOG.md Normal file
View file

@ -0,0 +1,70 @@
## 4.2.4
- Fixed the userstory to always call the splashScreenFuture and killswitchservice logic when a custom splashScreenBuilder is provided
## 4.2.3
- Added check if introduction should be shown according to the service before showing the introduction at all
## 4.2.2
- Added custom navigator in the root of the navigator user-story
## 4.2.1
- Updated flutter_introduction to 5.0.0
## 4.1.0
- Updated README
- Removed check if the introductions should be shown.
- Updated flutter_introduction to 3.1.0
## 4.0.0
- Added default introduction page.
- Added default splash screen.
- Changed the way the splash screen is enabled/disabled.
## 3.0.0
BREAKING:
- add NavigatorStartUserStory widget
- change homeEntry to an onComplete callback
Other changes:
- add parameter to configuration to supply an implementation of the killswitch service
- call splash handler when no builder is provided
- add mounted check to navigation after async gap for navigator version
- rename myFunction in splashscreen function to splashHandler
- add return after routing on navigator version
## 2.0.5
- Added canPopFromIntroduction to enable/disable popping from introduction screens
## 2.0.4
- Removed `AlwaysShowIntroduction` option, changed naming of `isKillSwitchActive` to `isAllowedToPassThrough`.
## 2.0.3
- Added after splashscreen route
## 2.0.2
- Added configuration options
- Fixed bug with killswitch
## 2.0.1
- Added Iconica Ci
## 2.0.0
- Add support for default configurable splashscreen
- Add introductionpagebuilder
- Upgrade to flutter_introduction 2.1.0
- Change the options to optionbuilders to provide BuildContext
## 1.1.0
- Add killswitch functionality
## 1.0.0
- Initial release

194
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,194 @@
# Contributing
First off, thanks for taking the time to contribute! ❤️
All types of contributions are encouraged and valued.
See the [Table of Contents](#table-of-contents) for different ways to help and details about how we handle them.
Please make sure to read the relevant section before making your contribution.
It will make it a lot easier for us maintainers and smooth out the experience for all involved.
Iconica looks forward to your contributions. 🎉
## Table of contents
- [Code of conduct](#code-of-conduct)
- [I Have a Question](#i-have-a-question)
- [I Want To Contribute](#i-want-to-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Contributing code](#contributing-code)
## Code of conduct
### Legal notice
When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
All accepted pull requests and other additions to this project will be considered intellectual property of Iconica.
All repositories should be kept clean of jokes, easter eggs and other unnecessary additions.
## I have a question
If you want to ask a question, we assume that you have read the available documentation found within the code.
Before you ask a question, it is best to search for existing issues that might help you.
In case you have found a suitable issue but still need clarification, you can ask your question
It is also advisable to search the internet for answers first.
If you then still feel the need to ask a question and need clarification, we recommend the following:
- Open an issue.
- Provide as much context as you can about what you're running into.
We will then take care of the issue as soon as possible.
## I want to contribute
### Reporting bugs
<!-- omit in toc -->
**Before submitting a bug report**
A good bug report shouldn't leave others needing to chase you up for more information.
Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report.
Please complete the following steps in advance to help us fix any potential bug as fast as possible.
- Make sure that you are using the latest version.
- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (If you are looking for support, you might want to check [this section](#i-have-a-question)).
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error.
- Also make sure to search the internet (including Stack Overflow) to see if users outside of Iconica have discussed the issue.
- Collect information about the bug:
- Stack trace (Traceback)
- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
- Time and date of occurance
- Describe the expected result and actual result
- Can you reliably reproduce the issue? And can you also reproduce it with older versions? Describe all steps that lead to the bug.
Once it's filed:
- The project team will label the issue accordingly.
- A team member will try to reproduce the issue with your provided steps.
If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for additional information.
- If the team is able to reproduce the issue, it will be moved into the backlog, as well as marked with a priority, and the issue will be left to be [implemented by someone](#contributing-code).
### Contributing code
When you start working on your contribution, make sure you are aware of the relevant documentation and the functionality of the component you are working on.
When writing code, follow the style guidelines set by Dart: [Effective Dart](https://Dart.dev/guides/language/effective-Dart). This contains most information you will need to write clean Dart code that is well documented.
**Documentation**
As Effective Dart indicates, documenting your public methods with Dart doc comments is recommended.
Aside from Effective Dart, we require specific information in the documentation of a method:
At the very least, your documentation should first name what the code does, then followed below by requirements for calling the method, the result of the method.
Any references to internal variables or other methods should be done through [var] to indicate a reference.
If the method or class is complex enough (determined by the reviewers) an example is required.
If unsure, add an example in the docs using code blocks.
For classes and methods, document the individual parameters with their implications.
> Tip: Remember that the shortest documentation can be written by having good descriptive names in the first place.
An example:
```Dart
library iconica_utilities.bidirectional_sorter;
part 'sorter.Dart';
part 'enum.Dart';
/// Generic sort method, allow sorting of list with primitives or complex types.
/// Uses [SortDirection] to determine the direction, either Ascending or Descending,
/// Gets called on [List] toSort of type [T] which cannot be shorter than 2.
/// Optionally for complex types a [Comparable] [Function] can be given to compare complex types.
/// ```
/// List<TestObject> objects = [];
/// for (int i = 0; i < 10; i++) {
/// objects.add(TestObject(name: "name", id: i));
/// }
///
/// sort<TestObject>(
/// SortDirection.descending, objects, (object) => object.id);
///
/// ```
/// In the above example a list of TestObjects is created, and then sorted in descending order.
/// If the implementation of TestObject is as following:
/// ```
/// class TestObject {
/// final String name;
/// final int id;
///
/// TestObject({required this.name, required this.id});
/// }
/// ```
/// And the list is logged to the console, the following will appear:
/// ```
/// [name9, name8, name7, name6, name5, name4, name3, name2, name1, name0]
/// ```
void sort<T>(
/// Determines the sorting direction, can be either Ascending or Descending
SortDirection sortDirection,
/// Incoming list, which gets sorted
List<T> toSort, [
/// Optional comparable, which is only necessary for complex types
SortFieldGetter<T>? sortValueCallback,
]) {
if (toSort.length < 2) return;
assert(
toSort.whereType<Comparable>().isNotEmpty || sortValueCallback != null);
BidirectionalSorter<T>(
sortInstructions: <SortInstruction<T>>[
SortInstruction(
sortValueCallback ?? (t) => t as Comparable, sortDirection),
],
).sort(toSort);
}
/// same functionality as [sort] but with the added functionality
/// of sorting multiple values
void sortMulti<T>(
/// Incoming list, which gets sorted
List<T> toSort,
/// list of comparables to sort multiple values at once,
/// priority based on index
List<SortInstruction<T>> sortValueCallbacks,
) {
if (toSort.length < 2) return;
assert(sortValueCallbacks.isNotEmpty);
BidirectionalSorter<T>(
sortInstructions: sortValueCallbacks,
).sort(toSort);
}
```
**Tests**
For each public method that was created, excluding widgets, which contains any form of logic (e.g. Calculations, predicates or major side-effects) tests are required.
A set of tests is written for each method, covering at least each path within the method. For example:
```Dart
void foo() {
try {
var bar = doSomething();
if (bar) {
doSomethingElse();
} else {
doSomethingCool();
}
} catch (_) {
displayError();
}
}
```
The method above should result in 3 tests:
1. A test for the path leading to displayError by the cause of an exception
2. A test for if bar is true, resulting in doSomethingElse()
3. A test for if bar is false, resulting in the doSomethingCool() method being called.
This means that we require 100% coverage of each method you test.

9
LICENSE Normal file
View file

@ -0,0 +1,9 @@
Copyright (c) 2024 Iconica, All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

105
README.md
View file

@ -6,57 +6,62 @@ Flutter_start is a package that allows you to jumpstart your application with a
To use this package, add flutter_start as a dependency in your pubspec.yaml file: To use this package, add flutter_start as a dependency in your pubspec.yaml file:
``` ```yaml
flutter_start: flutter_start:
git: git:
url: https://github.com/Iconica-Development/flutter_start url: https://github.com/Iconica-Development/flutter_start
ref: <Version> ref: 4.1.0
``` ```
To use the module within your Flutter-application with predefined `Go_router` routes you should add the following: ## go_router
Add `go_router` as dependency to your project.
Add go_router as dependency to your project.
Add the following configuration to your flutter_application: Add the following configuration to your flutter_application:
``` ```
StartUserStoryConfiguration startUserStoryConfiguration = const StartUserStoryConfiguration(); List<GoRoute> getStartStoryRoutes() => getStartStoryRoutes();
``` ```
and set the values as you wish. Or with options:
Next add the `StartUserStoryConfiguration` to `getStartStoryRoutes` Like so: Place the following code somewhere in your project where it can be accessed globally:
``` ```
List<GoRoute> getStartRoutes() => getStartStoryRoutes( var startUserStoryConfiguration = const StartUserStoryConfiguration();
startUserStoryConfiguration, ```
```
List<GoRoute> getStartStoryRoutes() => getStartStoryRoutes(
configuration: startUserStoryConfiguration,
); );
``` ```
Finally add the `getStartRoutes` to your `Go_router` routes like so: Finally add the `getStartRoutes` to your `go_router` routes like so:
``` ```
final GoRouter _router = GoRouter( final GoRouter _router = GoRouter(
routes: <RouteBase>[ routes: <RouteBase>[
...getStartRoutes() ...getStartStoryRoutes()
], ],
); );
``` ```
The routes that can be used to navigate are: The routes that can be used to navigate are:
For routing to the `SplashScreen`: For routing to the `splashScreen`:
``` ```
static const String splashScreen = '/splashScreen'; static const String splashScreen = '/splashScreen';
``` ```
For routing to the `Introduction`: For routing to the `introduction`:
``` ```
static const String introduction = '/introduction'; static const String introduction = '/introduction';
``` ```
For routing to the `HomeEntry`: For routing to the `home`:
``` ```
static const String home = '/home'; static const String home = '/home';
@ -73,29 +78,73 @@ final GoRouter _router = GoRouter(
); );
``` ```
To use the module within your Flutter-application without predefined `Go_router` routes but with `Navigator` routes add the following : ## Navigator
Add the following configuration to your flutter_application:
Add the following code to the build-method of a chosen widget like so:
``` ```
StartUserStoryConfiguration startUserStoryConfiguration = const StartUserStoryConfiguration(); class Example extends StatelessWidget {
const Example({super.key});
@override
Widget build(BuildContext context) {
return NavigatorStartUserStory(
onComplete: (context) {},
);
}
}
``` ```
Add the following code to the build-method of a chosen widget: or with options:
Place the following code somewhere in your project where it can be accessed globally:
``` ```
startNavigatorUserStory(startUserStoryConfiguration, context); var startUserStoryConfiguration = const StartUserStoryConfiguration();
``` ```
If the splashScreenBuilder is not used the SplashScreen will be skipped. ```
class Example extends StatelessWidget {
const Example({super.key});
@override
Widget build(BuildContext context) {
return NavigatorStartUserStory(
configuration: startUserStoryConfiguration,
onComplete: (context) {},
);
}
}
```
The `StartUserStoryConfiguration` has its own parameters, as specified below: The `StartUserStoryConfiguration` has its own parameters, as specified below:
| Parameter | Explanation | | Parameter | Explanation |
|-----------|-------------| |-----------|-------------|
| splashScreenBuilder | The builder for the splashScreen. | | `splashScreenBuilder` | The builder to override the default splashScreen |
| introductionOptions | The options for the introduction. | | `introductionBuilder` | A builder to wrap the introductions in your own page |
| introductionService | The service for the introduction. Default IntroductionService (SharedPreferencesIntroductionDataProvider()) | | `introductionOptionsBuilder` | The builder to override the default `introductionOptions` |
| homeEntry | The widget that will be shown after the introduction. | |`introductionService` | The service to override the default `introductionService` |
| introductionFallbackScreen | The widget that will be shown when the introduction is skipped. | | `homeScreenRoute` | The route to navigate to after the introduction or splashScreen is completed |
| introductionScrollPhysics | The scrollPhysics for the introduction. | | `introductionFallbackScreen` | The screen that is shown when something goes wrong fetching data for the introduction |
| showIntroduction | Whether or not the introduction should be shown. | | `introductionScrollPhysics` | The scroll physics for the introduction |
| `showIntroduction` | A boolean to show the introduction or not. Defaults to true |
| `useKillswitch` | A boolean to use the killswitch or not. Defaults to false |
| `minimumSplashScreenDuration` | The minimum duration the splashScreen should be shown. Defaults to 3 seconds |
| `splashScreenFuture` | The future to be completed before the splashScreen is completed |
| `splashScreenCenterWidget` | The widget to be shown in the center of the splashScreen |
| `splashScreenBackgroundColor` | The color of the splashScreen background. Defaults to Color(0xff212121) |
| `canPopFromIntroduction` | Allow popping from introduction, defaults to true. Defaults to true |
| `killswitchService` | The service to override the default killswitch service |
| `showSplashScreen` | A boolean to show the splashScreen or not. Defaults to true |
## Issues
Please file any issues, bugs or feature request as an issue on our [GitHub](https://github.com/Iconica-Development/flutter_start) page. Commercial support is available if you need help with integration with your app or services. You can contact us at [support@iconica.nl](mailto:support@iconica.nl).
## Want to contribute
[text](about:blank#blocked)
If you would like to contribute to the plugin (e.g. by improving the documentation, solving a bug or adding a cool new feature), please carefully review our [contribution guide](./CONTRIBUTING.md) and send us your [pull request](https://github.com/Iconica-Development/flutter_start/pulls).
## Author
This flutter_start for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at <support@iconica.nl>

View file

@ -1,28 +1,9 @@
# This file configures the analyzer, which statically analyzes Dart code to include: package:flutter_iconica_analysis/analysis_options.yaml
# 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, # Possible to overwrite the rules from the package
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml analyzer:
exclude:
linter: 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.dev/lints.
#
# 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: 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

3
example/.gitignore vendored
View file

@ -31,6 +31,9 @@ migrate_working_dir/
.pub/ .pub/
/build/ /build/
# platforms
/web
# Symbolication related # Symbolication related
app.*.symbols app.*.symbols

16
example/README.md Normal file
View file

@ -0,0 +1,16 @@
# example
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

View file

@ -1,28 +1,9 @@
# This file configures the analyzer, which statically analyzes Dart code to include: package:flutter_iconica_analysis/analysis_options.yaml
# 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, # Possible to overwrite the rules from the package
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml analyzer:
exclude:
linter: 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.dev/lints.
#
# 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: 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

View file

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_introduction_shared_preferences/flutter_introduction_shared_preferences.dart';
import 'package:flutter_start/flutter_start.dart'; import 'package:flutter_start/flutter_start.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -12,36 +11,27 @@ class MyApp extends StatelessWidget {
const MyApp({super.key}); const MyApp({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => const MaterialApp(
return const MaterialApp(
home: Home(), home: Home(),
); );
} }
}
class Home extends StatelessWidget { class Home extends StatelessWidget {
const Home({super.key}); const Home({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => NavigatorStartUserStory(
return startNavigatorUserStory(config, context); configuration: config,
} onComplete: (context) async {
} await Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const HomeEntry()),
final GoRouter _router = GoRouter(
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (BuildContext context, GoRouterState state) {
return const Home();
},
),
...getStartRoutes()
],
); );
},
);
}
List<GoRoute> getStartRoutes() => getStartStoryRoutes( List<GoRoute> getStartRoutes() => getStartStoryRoutes(
config, configuration: config,
); );
StartUserStoryConfiguration config = StartUserStoryConfiguration( StartUserStoryConfiguration config = StartUserStoryConfiguration(
@ -49,39 +39,6 @@ StartUserStoryConfiguration config = StartUserStoryConfiguration(
splashScreenBuilder: (context, onFinish) => SplashScreen( splashScreenBuilder: (context, onFinish) => SplashScreen(
onFinish: onFinish, onFinish: onFinish,
), ),
homeEntry: const HomeEntry(),
introductionOptions: IntroductionOptions(
pages: [
IntroductionPage(
title: const Text('First page'),
text: const Text('Wow a page'),
graphic: const FlutterLogo(),
),
IntroductionPage(
title: const Text('Second page'),
text: const Text('Another page'),
graphic: const FlutterLogo(),
),
IntroductionPage(
title: const Text('Third page'),
text: const Text('The final page of this app'),
graphic: const FlutterLogo(),
),
],
introductionTranslations: const IntroductionTranslations(
skipButton: 'Skip it!',
nextButton: 'Next',
previousButton: 'Previous',
finishButton: 'To the app!',
),
tapEnabled: true,
displayMode: IntroductionDisplayMode.multiPageHorizontal,
buttonMode: IntroductionScreenButtonMode.text,
indicatorMode: IndicatorMode.dash,
skippable: true,
buttonBuilder: (context, onPressed, child, type) =>
ElevatedButton(onPressed: onPressed, child: child),
),
); );
class SplashScreen extends StatefulWidget { class SplashScreen extends StatefulWidget {
@ -106,44 +63,22 @@ class _SplashScreenState extends State<SplashScreen> {
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => Scaffold(
return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("SplashScreen"), title: const Text('SplashScreen'),
), ),
body: const Center(child: Text("SplashScreen")), body: const Center(child: Text('SplashScreen')),
); );
} }
}
class HomeEntry extends StatelessWidget { class HomeEntry extends StatelessWidget {
const HomeEntry({super.key}); const HomeEntry({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => Scaffold(
return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text("HomeEntry"), title: const Text('HomeEntry'),
), ),
body: const Center(child: Text("HomeEntry")), body: const Center(child: Text('HomeEntry')),
); );
} }
}
class ExampleIntroductionDataProvider
implements SharedPreferencesIntroductionDataProvider {
@override
String key = 'example';
@override
Future<void> setCompleted({bool value = true}) async {
// ignore: void_checks
return Future.value(false);
}
@override
Future<bool> shouldShow() {
// ignore: void_checks
return Future.value(true);
}
}

View file

@ -1,551 +0,0 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
url: "https://pub.dev"
source: hosted
version: "64.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
url: "https://pub.dev"
source: hosted
version: "6.2.0"
args:
dependency: transitive
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
build:
dependency: transitive
description:
name: build
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
built_collection:
dependency: transitive
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
sha256: a3ec2e0f967bc47f69f95009bb93db936288d61d5343b9436e378b28a2f830c6
url: "https://pub.dev"
source: hosted
version: "8.9.0"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
code_builder:
dependency: transitive
description:
name: code_builder
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
url: "https://pub.dev"
source: hosted
version: "4.10.0"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.3"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
version: "1.0.6"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368"
url: "https://pub.dev"
source: hosted
version: "2.3.4"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_data_interface:
dependency: transitive
description:
path: "."
ref: "1.0.0"
resolved-ref: "500ed1d08095b33387ae3aa4ed1a2ad4d2fb2ac3"
url: "https://github.com/Iconica-Development/flutter_data_interface.git"
source: git
version: "1.0.0"
flutter_introduction:
dependency: transitive
description:
path: "packages/flutter_introduction"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_introduction_interface:
dependency: transitive
description:
path: "packages/flutter_introduction_interface"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_introduction_service:
dependency: transitive
description:
path: "packages/flutter_introduction_service"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_introduction_shared_preferences:
dependency: "direct main"
description:
path: "packages/flutter_introduction_shared_preferences"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_introduction_widget:
dependency: transitive
description:
path: "packages/flutter_introduction_widget"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.3"
flutter_start:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "1.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
glob:
dependency: transitive
description:
name: glob
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
go_router:
dependency: "direct main"
description:
name: go_router
sha256: "3b40e751eaaa855179b416974d59d29669e750d2e50fcdb2b37f1cb0ca8c803a"
url: "https://pub.dev"
source: hosted
version: "13.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
logging:
dependency: transitive
description:
name: logging
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.10.0"
mockito:
dependency: transitive
description:
name: mockito
sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917"
url: "https://pub.dev"
source: hosted
version: "5.4.4"
package_config:
dependency: transitive
description:
name: package_config
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
path:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
platform:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
shared_preferences:
dependency: transitive
description:
name: shared_preferences
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
url: "https://pub.dev"
source: hosted
version: "2.3.5"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
watcher:
dependency: transitive
description:
name: watcher
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.3.0"
win32:
dependency: transitive
description:
name: win32
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
url: "https://pub.dev"
source: hosted
version: "5.2.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev"
source: hosted
version: "1.0.4"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.2.5 <4.0.0"
flutter: ">=3.16.0"

View file

@ -1,25 +1,28 @@
name: example name: example
description: "A new Flutter project." description: "Flutter_start example app"
publish_to: "none" publish_to: "none"
environment: environment:
sdk: ">=3.2.5 <4.0.0" sdk: ">=3.2.5 <4.0.0"
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
cupertino_icons: ^1.0.2 go_router: any
go_router: ^13.0.1
flutter_start: flutter_start:
path: ../ path: ../
flutter_introduction_shared_preferences: flutter_introduction_shared_preferences:
git: hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub/
url: https://github.com/Iconica-Development/flutter_introduction version: ^5.0.0
ref: 2.0.0
path: packages/flutter_introduction_shared_preferences
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^2.0.0 flutter_lints: ^2.0.0
flutter_iconica_analysis:
git:
url: https://github.com/Iconica-Development/flutter_iconica_analysis
ref: 6.0.0
flutter: flutter:
uses-material-design: true uses-material-design: true

View file

@ -1,4 +1,6 @@
export 'package:flutter_introduction/flutter_introduction.dart';
export 'package:flutter_introduction_shared_preferences/flutter_introduction_shared_preferences.dart';
export 'package:flutter_start/src/models/start_configuration.dart'; export 'package:flutter_start/src/models/start_configuration.dart';
export 'package:flutter_start/src/routes.dart';
export 'package:flutter_start/src/user_stories/flutter_start_userstory_go_router.dart'; export 'package:flutter_start/src/user_stories/flutter_start_userstory_go_router.dart';
export 'package:flutter_start/src/user_stories/flutter_start_userstory_navigator.dart'; export 'package:flutter_start/src/user_stories/flutter_start_userstory_navigator.dart';
export 'package:flutter_introduction/flutter_introduction.dart';

View file

@ -5,6 +5,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
/// Builds a screen with a fade transition.
///
/// The [context] parameter is the [BuildContext] in which this widget is built.
/// The [state] parameter is the [GoRouterState] that contains
/// the current routing state.
/// The [child] parameter is the widget that will be displayed on the screen.
///
/// Returns a [CustomTransitionPage] with a fade transition.
CustomTransitionPage buildScreenWithFadeTransition<T>({ CustomTransitionPage buildScreenWithFadeTransition<T>({
required BuildContext context, required BuildContext context,
required GoRouterState state, required GoRouterState state,
@ -17,6 +25,14 @@ CustomTransitionPage buildScreenWithFadeTransition<T>({
FadeTransition(opacity: animation, child: child), FadeTransition(opacity: animation, child: child),
); );
/// Builds a screen without any transition.
///
/// The [context] parameter is the [BuildContext] in which this widget is built.
/// The [state] parameter is the [GoRouterState] that contains
/// the current routing state.
/// The [child] parameter is the widget that will be displayed on the screen.
///
/// Returns a [CustomTransitionPage] without any transition.
CustomTransitionPage buildScreenWithoutTransition<T>({ CustomTransitionPage buildScreenWithoutTransition<T>({
required BuildContext context, required BuildContext context,
required GoRouterState state, required GoRouterState state,

View file

@ -1,27 +1,74 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_introduction/flutter_introduction.dart'; import 'package:flutter_introduction/flutter_introduction.dart';
import 'package:flutter_start/src/services/killswitch_service.dart';
/// An immutable class that represents the configuration for
/// starting a user story.
@immutable @immutable
class StartUserStoryConfiguration { class StartUserStoryConfiguration {
/// Creates a new instance of [StartUserStoryConfiguration].
const StartUserStoryConfiguration({ const StartUserStoryConfiguration({
this.splashScreenBuilder, this.splashScreenBuilder,
this.introductionOptions = const IntroductionOptions(), this.introductionBuilder,
this.introductionOptionsBuilder,
this.introductionService, this.introductionService,
this.homeEntry, this.homeScreenRoute,
this.introductionFallbackScreen, this.introductionFallbackScreen,
this.introductionScrollPhysics, this.introductionScrollPhysics,
this.showIntroduction = true, this.showIntroduction = true,
this.useKillswitch = false,
this.minimumSplashScreenDuration = 3,
this.splashScreenFuture,
this.splashScreenCenterWidget,
this.splashScreenBackgroundColor = const Color(0xff212121),
this.canPopFromIntroduction = true,
this.killswitchService,
this.showSplashScreen = true,
}); });
/// You can use this to build your own splash screen.
final Widget Function( final Widget Function(
BuildContext context, BuildContext context,
Function() onFinish, Function() onFinish,
)? splashScreenBuilder; )? splashScreenBuilder;
final Widget? homeEntry; /// This is used to wrap the introduction widget in your own custom page.
final Widget Function(
BuildContext context,
Widget introductionPage,
)? introductionBuilder;
final IntroductionOptions introductionOptions; /// The route that is used to navigate to the home screen.
final String? homeScreenRoute;
final IntroductionOptions Function(BuildContext context)?
introductionOptionsBuilder;
final Widget? introductionFallbackScreen; final Widget? introductionFallbackScreen;
final IntroductionService? introductionService; final IntroductionService? introductionService;
final KillswitchService? killswitchService;
final ScrollPhysics? introductionScrollPhysics; final ScrollPhysics? introductionScrollPhysics;
final bool? showIntroduction;
/// If the introduction should be shown.
final bool showIntroduction;
/// If the killswitch is enabled this app can be remotely disabled.
final bool useKillswitch;
/// The widget that is shown in the center of the splash screen.
final WidgetBuilder? splashScreenCenterWidget;
/// The background color of the splash screen.
final Color? splashScreenBackgroundColor;
/// The minimum duration the splash screen in seconds.
final int minimumSplashScreenDuration;
/// The future that is awaited before the splash screen is closed.
final Future<String?> Function(BuildContext context)? splashScreenFuture;
/// Allow popping from introduction, defaults to true
final bool canPopFromIntroduction;
/// If the splash screen should be shown or not.
final bool showSplashScreen;
} }

View file

@ -0,0 +1,46 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:package_info_plus/package_info_plus.dart';
/// A service class to check if a killswitch is active for the current app.
abstract interface class KillswitchService {
/// Checks if the killswitch is active for the current app.
///
/// It makes a GET request to a specific URL with the app
/// name as a query parameter.
/// If the request fails or times out after 5 seconds,
/// it defaults to returning 'false'.
///
/// Returns a [Future] that completes with 'true' if the killswitch is active,
/// and 'false' otherwise.
Future<bool> isKillswitchActive() => throw UnimplementedError();
}
class DefaultKillswitchService implements KillswitchService {
@override
Future<bool> isKillswitchActive() async {
var packageInfo = await PackageInfo.fromPlatform();
var appName = packageInfo.appName;
http.Response response;
response = await http
.get(
Uri.parse('https://active-obelugnnza-uc.a.run.app/?appName=$appName'),
)
.timeout(
const Duration(seconds: 5),
onTimeout: () => http.Response('false', 500),
)
.onError(
(error, stackTrace) => http.Response('false', 500),
);
var decoded = jsonDecode(response.body);
if (decoded == true) {
return true;
}
return false;
}
}

View file

@ -2,36 +2,85 @@
// //
// SPDX-License-Identifier: BSD-3-Clause // SPDX-License-Identifier: BSD-3-Clause
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_introduction/flutter_introduction.dart'; import 'package:flutter_introduction/flutter_introduction.dart';
import 'package:flutter_introduction_shared_preferences/flutter_introduction_shared_preferences.dart'; import 'package:flutter_introduction_shared_preferences/flutter_introduction_shared_preferences.dart';
import 'package:flutter_start/src/go_router.dart'; import 'package:flutter_start/src/go_router.dart';
import 'package:flutter_start/src/models/start_configuration.dart'; import 'package:flutter_start/src/models/start_configuration.dart';
import 'package:flutter_start/src/routes.dart'; import 'package:flutter_start/src/routes.dart';
import 'package:flutter_start/src/services/killswitch_service.dart';
import 'package:flutter_start/src/widgets/default_splash_screen.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
List<GoRoute> getStartStoryRoutes( List<GoRoute> getStartStoryRoutes({
StartUserStoryConfiguration configuration, StartUserStoryConfiguration? configuration =
) => const StartUserStoryConfiguration(),
}) =>
<GoRoute>[ <GoRoute>[
GoRoute( GoRoute(
path: StartUserStoryRoutes.splashScreen, path: StartUserStoryRoutes.splashScreen,
pageBuilder: (context, state) { pageBuilder: (context, state) {
var go = context.go;
var isAllowedToPassThrough = false;
String? routeAfterSplash;
Future<void> splashLoadingMethod() async {
await Future.wait<void>(
[
Future.delayed(
Duration.zero,
() async {
if (configuration!.useKillswitch) {
var killswitchService = configuration.killswitchService ??
DefaultKillswitchService();
isAllowedToPassThrough =
await killswitchService.isKillswitchActive();
}
if (context.mounted)
routeAfterSplash = await configuration.splashScreenFuture
?.call(context) ??
configuration.homeScreenRoute;
},
),
Future.delayed(
Duration(
seconds: configuration!.minimumSplashScreenDuration,
),
() async {},
),
],
);
if (configuration.useKillswitch && isAllowedToPassThrough) return;
if ((!configuration.showIntroduction) && context.mounted) {
return go(
routeAfterSplash ?? StartUserStoryRoutes.home,
);
}
return go(StartUserStoryRoutes.introduction);
}
if (configuration!.splashScreenBuilder == null) {
unawaited(splashLoadingMethod());
}
return buildScreenWithoutTransition( return buildScreenWithoutTransition(
context: context, context: context,
state: state, state: state,
child: configuration.splashScreenBuilder?.call( child: configuration.splashScreenBuilder?.call(
context, context,
() { () async => splashLoadingMethod(),
if (configuration.showIntroduction == false) {
return context.go(StartUserStoryRoutes.home);
}
return context.go(StartUserStoryRoutes.introduction);
},
) ?? ) ??
const Scaffold( Scaffold(
body: SizedBox.shrink(), backgroundColor: configuration.splashScreenBackgroundColor,
body: Center(
child:
configuration.splashScreenCenterWidget?.call(context) ??
defaultSplashScreen(context),
),
), ),
); );
}, },
@ -40,34 +89,33 @@ List<GoRoute> getStartStoryRoutes(
path: StartUserStoryRoutes.introduction, path: StartUserStoryRoutes.introduction,
pageBuilder: (context, state) { pageBuilder: (context, state) {
var introduction = Introduction( var introduction = Introduction(
service: configuration.introductionService ?? service: configuration!.introductionService ??
IntroductionService( IntroductionService(
SharedPreferencesIntroductionDataProvider()), SharedPreferencesIntroductionDataProvider(),
),
navigateTo: () { navigateTo: () {
context.go(StartUserStoryRoutes.home); context.go(
configuration.homeScreenRoute ?? StartUserStoryRoutes.home,
);
}, },
options: configuration.introductionOptions, options: configuration.introductionOptionsBuilder?.call(context) ??
const IntroductionOptions(),
physics: configuration.introductionScrollPhysics, physics: configuration.introductionScrollPhysics,
child: configuration.introductionFallbackScreen, child: configuration.introductionFallbackScreen,
); );
return buildScreenWithoutTransition( return buildScreenWithoutTransition(
context: context, context: context,
state: state, state: state,
child: Scaffold( child: PopScope(
canPop: configuration.canPopFromIntroduction,
child: configuration.introductionBuilder?.call(
context,
introduction,
) ??
Scaffold(
body: introduction, body: introduction,
), ),
);
},
),
GoRoute(
path: StartUserStoryRoutes.home,
pageBuilder: (context, state) {
var home = configuration.homeEntry;
return buildScreenWithoutTransition(
context: context,
state: state,
child: Scaffold(
body: home,
), ),
); );
}, },

View file

@ -1,70 +1,172 @@
import 'package:flutter/material.dart'; import 'dart:async';
import 'package:flutter_introduction_shared_preferences/flutter_introduction_shared_preferences.dart';
import 'package:flutter_start/flutter_start.dart';
Widget startNavigatorUserStory( import 'package:flutter/material.dart';
StartUserStoryConfiguration configuration, BuildContext context) { import 'package:flutter_start/flutter_start.dart';
if (configuration.splashScreenBuilder == null) { import 'package:flutter_start/src/services/killswitch_service.dart';
return _introduction(configuration, context); import 'package:flutter_start/src/widgets/default_splash_screen.dart';
/// Initial screen of the user story.
///
/// Use this when defining an initial route.
class NavigatorStartUserStory extends StatelessWidget {
const NavigatorStartUserStory({
required this.onComplete,
this.configuration = const StartUserStoryConfiguration(),
super.key,
});
final StartUserStoryConfiguration configuration;
final void Function(BuildContext context) onComplete;
@override
Widget build(BuildContext context) => Navigator(
onGenerateInitialRoutes: (_, __) => [
_getInitialRoute(configuration, onComplete),
],
);
} }
return _splashScreen(configuration, context);
/// Enter the start user story with the Navigator 1.0 API.
///
/// Requires a Navigator widget to exist in the given [context].
///
/// Customization can be done through the [configuration] parameter.
///
/// [onComplete] triggers as soon as the userstory is finished.
///
/// The context provided here is a context has a guaranteed navigator.
Future<void> startNavigatorUserStory(
BuildContext context,
StartUserStoryConfiguration configuration, {
required void Function(BuildContext context) onComplete,
}) async {
var initialRoute = _getInitialRoute(configuration, onComplete);
await Navigator.of(context).push(initialRoute);
}
MaterialPageRoute<dynamic> _getInitialRoute(
StartUserStoryConfiguration configuration,
void Function(BuildContext context) onComplete,
) {
var initialRoute = MaterialPageRoute(
builder: (context) => _splashScreen(
configuration,
context,
onComplete,
),
);
if (!configuration.showSplashScreen && configuration.showIntroduction) {
initialRoute = MaterialPageRoute(
builder: (context) => _introduction(
configuration,
context,
onComplete,
),
);
}
return initialRoute;
} }
Widget _splashScreen( Widget _splashScreen(
StartUserStoryConfiguration configuration, StartUserStoryConfiguration configuration,
BuildContext context, BuildContext context,
void Function(BuildContext context) onComplete,
) { ) {
return configuration.splashScreenBuilder?.call( var navigator = Navigator.of(context);
context,
() { var isAllowedToPassThrough = false;
if (configuration.showIntroduction == false) {
return Navigator.of(context).pushReplacement( Future<void> splashHandler() async {
await Future.wait<void>(
[
configuration.splashScreenFuture?.call(context) ?? Future.value(),
Future.delayed(
Duration.zero,
() async {
if (configuration.useKillswitch) {
var killswitchService =
configuration.killswitchService ?? DefaultKillswitchService();
isAllowedToPassThrough =
await killswitchService.isKillswitchActive();
}
},
),
Future.delayed(
Duration(
seconds: configuration.minimumSplashScreenDuration,
),
),
],
);
if (configuration.useKillswitch && isAllowedToPassThrough) return;
var introService = configuration.introductionService ??
IntroductionService(SharedPreferencesIntroductionDataProvider());
var shouldShowIntroduction =
configuration.showIntroduction && await introService.shouldShow();
if (!context.mounted) return;
if (!shouldShowIntroduction) return onComplete(context);
await navigator.pushReplacement(
MaterialPageRoute( MaterialPageRoute(
builder: (context) => _home(configuration, context), builder: (context) => _introduction(
configuration,
context,
onComplete,
),
), ),
); );
} }
return Navigator.of(context).pushReplacement(
MaterialPageRoute( unawaited(splashHandler());
builder: (context) => _introduction(configuration, context),
var builder = configuration.splashScreenBuilder;
if (builder == null) {
return Scaffold(
backgroundColor: configuration.splashScreenBackgroundColor,
body: Center(
child: configuration.splashScreenCenterWidget?.call(context) ??
defaultSplashScreen(context),
), ),
); );
}, }
) ??
const Scaffold( return builder.call(
body: SizedBox.shrink(), context,
splashHandler,
); );
} }
Widget _introduction( Widget _introduction(
StartUserStoryConfiguration configuration, StartUserStoryConfiguration configuration,
BuildContext context, BuildContext context,
void Function(BuildContext context) onComplete,
) { ) {
var introduction = Introduction( var introduction = Introduction(
service: configuration.introductionService ?? service: configuration.introductionService ??
IntroductionService(SharedPreferencesIntroductionDataProvider()), IntroductionService(SharedPreferencesIntroductionDataProvider()),
navigateTo: () { navigateTo: () async => onComplete(context),
Navigator.of(context).pushReplacement( options: configuration.introductionOptionsBuilder?.call(context) ??
MaterialPageRoute( const IntroductionOptions(),
builder: (context) => _home(configuration, context),
),
);
},
options: configuration.introductionOptions,
physics: configuration.introductionScrollPhysics, physics: configuration.introductionScrollPhysics,
child: configuration.introductionFallbackScreen, child: configuration.introductionFallbackScreen,
); );
return Scaffold( return PopScope(
canPop: configuration.canPopFromIntroduction,
child: configuration.introductionBuilder?.call(
context,
introduction,
) ??
Scaffold(
body: introduction, body: introduction,
); ),
}
Widget _home(
StartUserStoryConfiguration configuration,
BuildContext context,
) {
var home = configuration.homeEntry;
return Scaffold(
body: home,
); );
} }

View file

@ -0,0 +1,6 @@
import 'package:flutter/material.dart';
Text defaultSplashScreen(BuildContext context) => Text(
'iconinstagram',
style: Theme.of(context).textTheme.headlineLarge,
);

View file

@ -1,544 +0,0 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
url: "https://pub.dev"
source: hosted
version: "64.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
url: "https://pub.dev"
source: hosted
version: "6.2.0"
args:
dependency: transitive
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
build:
dependency: transitive
description:
name: build
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
built_collection:
dependency: transitive
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309
url: "https://pub.dev"
source: hosted
version: "8.8.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
code_builder:
dependency: transitive
description:
name: code_builder
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
url: "https://pub.dev"
source: hosted
version: "4.10.0"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.3"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.dev"
source: hosted
version: "1.0.6"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368"
url: "https://pub.dev"
source: hosted
version: "2.3.4"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_data_interface:
dependency: transitive
description:
path: "."
ref: "1.0.0"
resolved-ref: "500ed1d08095b33387ae3aa4ed1a2ad4d2fb2ac3"
url: "https://github.com/Iconica-Development/flutter_data_interface.git"
source: git
version: "1.0.0"
flutter_introduction:
dependency: "direct main"
description:
path: "packages/flutter_introduction"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_introduction_interface:
dependency: transitive
description:
path: "packages/flutter_introduction_interface"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_introduction_service:
dependency: transitive
description:
path: "packages/flutter_introduction_service"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_introduction_shared_preferences:
dependency: "direct main"
description:
path: "packages/flutter_introduction_shared_preferences"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_introduction_widget:
dependency: transitive
description:
path: "packages/flutter_introduction_widget"
ref: "2.0.0"
resolved-ref: d4037160ce6c7d51d5d1b35b3803bc46a257c7b5
url: "https://github.com/Iconica-Development/flutter_introduction"
source: git
version: "2.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.dev"
source: hosted
version: "2.0.3"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
glob:
dependency: transitive
description:
name: glob
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
go_router:
dependency: "direct main"
description:
name: go_router
sha256: "3b40e751eaaa855179b416974d59d29669e750d2e50fcdb2b37f1cb0ca8c803a"
url: "https://pub.dev"
source: hosted
version: "13.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
logging:
dependency: transitive
description:
name: logging
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.10.0"
mockito:
dependency: transitive
description:
name: mockito
sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917"
url: "https://pub.dev"
source: hosted
version: "5.4.4"
package_config:
dependency: transitive
description:
name: package_config
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
path:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
platform:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
shared_preferences:
dependency: transitive
description:
name: shared_preferences
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
url: "https://pub.dev"
source: hosted
version: "2.3.5"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
watcher:
dependency: transitive
description:
name: watcher
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.3.0"
win32:
dependency: transitive
description:
name: win32
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
url: "https://pub.dev"
source: hosted
version: "5.2.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev"
source: hosted
version: "1.0.4"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.2.5 <4.0.0"
flutter: ">=3.16.0"

View file

@ -1,7 +1,8 @@
name: flutter_start name: flutter_start
description: "Flutter_start is a package that allows you to jumpstart your application with a splashScreen, introduction and a home." description: "Flutter_start is a package that allows you to jumpstart your application with a splashScreen, introduction and a home."
publish_to: "none" version: 4.2.4
version: 1.0.0
publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub
environment: environment:
sdk: ">=3.2.5 <4.0.0" sdk: ">=3.2.5 <4.0.0"
@ -9,23 +10,24 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
cupertino_icons: ^1.0.2 cupertino_icons: ">=1.0.2 <2.0.0"
go_router: ">=14.2.0 <15.0.0"
http: ">=1.2.1 <2.0.0"
package_info_plus: ">=8.0.0 <9.0.0"
flutter_introduction: flutter_introduction:
git: hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub
url: https://github.com/Iconica-Development/flutter_introduction version: ^5.0.0
ref: 2.0.0
path: packages/flutter_introduction
flutter_introduction_shared_preferences: flutter_introduction_shared_preferences:
git: hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub/
url: https://github.com/Iconica-Development/flutter_introduction version: ^5.0.0
ref: 2.0.0
path: packages/flutter_introduction_shared_preferences
go_router: ^13.0.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^2.0.0 flutter_iconica_analysis:
git:
url: https://github.com/Iconica-Development/flutter_iconica_analysis
ref: 6.0.0
flutter: flutter:
uses-material-design: true uses-material-design: true

14
test/_test.dart Normal file
View file

@ -0,0 +1,14 @@
// This is an example unit test.
//
// A unit test tests a single function, method, or class. To learn more about
// writing unit tests, visit
// https://flutter.dev/docs/cookbook/testing/unit/introduction
import 'package:flutter_test/flutter_test.dart';
void main() {
group('Plus Operator', () {
test('should add two numbers together', () {
expect(1 + 1, 2);
});
});
}