From 99d0a49cc2a33f88c9226d8d842908d91656c1ba Mon Sep 17 00:00:00 2001 From: mike doornenbal Date: Wed, 23 Oct 2024 15:25:34 +0200 Subject: [PATCH] feat: add new structure --- CHANGELOG.md | 8 +- README.md | 136 ++------------- packages/example/lib/main.dart | 101 ----------- packages/example/pubspec.yaml | 53 ------ packages/firebase_start_repository/.gitignore | 29 ++++ .../firebase_start_repository/CHANGELOG.md | 1 + .../firebase_start_repository/CONTRIBUTING.md | 1 + packages/firebase_start_repository/LICENSE | 1 + packages/firebase_start_repository/README.md | 1 + .../analysis_options.yaml | 4 +- .../lib/firebase_start_repository.dart | 4 + .../src/firebase_killswitch_repository.dart | 34 ++++ .../firebase_start_repository/pubspec.yaml | 23 +++ packages/flutter_start/CONTRIBUTING.md | 1 + packages/flutter_start/analysis_options.yaml | 11 +- .../{ => flutter_start}/example/.gitignore | 0 packages/flutter_start/example/README.md | 16 ++ .../example/analysis_options.yaml | 28 +++ packages/flutter_start/example/lib/main.dart | 54 ++++++ packages/flutter_start/example/lib/theme.dart | 154 +++++++++++++++++ packages/flutter_start/example/pubspec.yaml | 24 +++ .../example/test/widget_test.dart | 30 ++++ packages/flutter_start/lib/flutter_start.dart | 20 ++- .../flutter_start_navigator_userstory.dart | 52 ++++++ .../lib/src/models/flutter_start_options.dart | 66 +++++++ .../lib/src/models/start_configuration.dart | 74 -------- .../lib/src/screens/introductions_screen.dart | 46 +++++ .../lib/src/screens/splash_screen.dart | 96 +++++++++++ .../lib/src/services/killswitch_service.dart | 46 ----- .../flutter_start_userstory_navigator.dart | 162 ------------------ .../src/widgets/default_splash_screen.dart | 6 - packages/flutter_start/pubspec.yaml | 62 ++----- .../CONTRIBUTING.md | 1 + .../analysis_options.yaml | 11 +- .../killswitch_repository_interface.dart | 6 + .../local/local_killswitch_repository.dart | 7 + .../lib/src/services/start_service.dart | 18 ++ .../lib/start_repository_interface.dart | 9 +- .../start_repository_interface/pubspec.yaml | 45 +---- .../test/start_repository_interface_test.dart | 12 -- 40 files changed, 772 insertions(+), 681 deletions(-) delete mode 100644 packages/example/lib/main.dart delete mode 100644 packages/example/pubspec.yaml create mode 100644 packages/firebase_start_repository/.gitignore create mode 120000 packages/firebase_start_repository/CHANGELOG.md create mode 120000 packages/firebase_start_repository/CONTRIBUTING.md create mode 120000 packages/firebase_start_repository/LICENSE create mode 120000 packages/firebase_start_repository/README.md rename packages/{example => firebase_start_repository}/analysis_options.yaml (57%) create mode 100644 packages/firebase_start_repository/lib/firebase_start_repository.dart create mode 100644 packages/firebase_start_repository/lib/src/firebase_killswitch_repository.dart create mode 100644 packages/firebase_start_repository/pubspec.yaml create mode 120000 packages/flutter_start/CONTRIBUTING.md rename packages/{ => flutter_start}/example/.gitignore (100%) create mode 100644 packages/flutter_start/example/README.md create mode 100644 packages/flutter_start/example/analysis_options.yaml create mode 100644 packages/flutter_start/example/lib/main.dart create mode 100644 packages/flutter_start/example/lib/theme.dart create mode 100644 packages/flutter_start/example/pubspec.yaml create mode 100644 packages/flutter_start/example/test/widget_test.dart create mode 100644 packages/flutter_start/lib/src/flutter_start_navigator_userstory.dart create mode 100644 packages/flutter_start/lib/src/models/flutter_start_options.dart delete mode 100644 packages/flutter_start/lib/src/models/start_configuration.dart create mode 100644 packages/flutter_start/lib/src/screens/introductions_screen.dart create mode 100644 packages/flutter_start/lib/src/screens/splash_screen.dart delete mode 100644 packages/flutter_start/lib/src/services/killswitch_service.dart delete mode 100644 packages/flutter_start/lib/src/user_stories/flutter_start_userstory_navigator.dart delete mode 100644 packages/flutter_start/lib/src/widgets/default_splash_screen.dart create mode 120000 packages/start_repository_interface/CONTRIBUTING.md create mode 100644 packages/start_repository_interface/lib/src/interfaces/killswitch_repository_interface.dart create mode 100644 packages/start_repository_interface/lib/src/local/local_killswitch_repository.dart create mode 100644 packages/start_repository_interface/lib/src/services/start_service.dart delete mode 100644 packages/start_repository_interface/test/start_repository_interface_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index e67a7f2..83af27e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ -## 4.2.1 +## 5.0.0 +- Updated README +- Added new userstory structure +- refactored package -* Updated flutter_introduction to 5.0.0 +## 4.2.1 +- Updated flutter_introduction to 5.0.0 ## 4.1.0 - Updated README diff --git a/README.md b/README.md index 6c7deba..9b6da63 100644 --- a/README.md +++ b/README.md @@ -4,147 +4,45 @@ Flutter_start is a package that allows you to jumpstart your application with a ## Setup -To use this package, add flutter_start as a dependency in your pubspec.yaml file: +To use flutter_start in your flutter app, import it in your pubspec.yaml: -```yaml - flutter_start: +``` yaml + flutter_chat: git: url: https://github.com/Iconica-Development/flutter_start - ref: 4.1.0 + path: packages/flutter_start + ref: 5.0.0 ``` -## go_router +After importing flutter_start you can add the `FlutterStartNavigatorUserstory` widget like so: -Add `go_router` as dependency to your project. - -Add the following configuration to your flutter_application: - -``` -List getStartStoryRoutes() => getStartStoryRoutes(); -``` - -Or with options: - -Place the following code somewhere in your project where it can be accessed globally: - -``` -var startUserStoryConfiguration = const StartUserStoryConfiguration(); -``` - -``` -List getStartStoryRoutes() => getStartStoryRoutes( - configuration: startUserStoryConfiguration, - ); -``` - -Finally add the `getStartRoutes` to your `go_router` routes like so: - -``` -final GoRouter _router = GoRouter( - routes: [ - ...getStartStoryRoutes() - ], -); -``` - -The routes that can be used to navigate are: - -For routing to the `splashScreen`: - -``` -static const String splashScreen = '/splashScreen'; -``` - -For routing to the `introduction`: - -``` -static const String introduction = '/introduction'; -``` - -For routing to the `home`: - -``` -static const String home = '/home'; -``` - -If you don't want a SplashScreen in your application set your initialRoute to `Introduction`: - -``` -final GoRouter _router = GoRouter( - routes: [ - ...getStartRoutes() - ], - initialLocation: '/introduction', -); -``` - -## Navigator - -Add the following code to the build-method of a chosen widget like so: -``` -class Example extends StatelessWidget { - const Example({super.key}); +``` dart +class FlutterStart extends StatelessWidget { + const FlutterStart({super.key}); @override Widget build(BuildContext context) { - return NavigatorStartUserStory( - onComplete: (context) {}, + return FlutterStartNavigatorUserstory( + startService: StartService(), + options: const FlutterStartOptions(), + afterIntroduction: (context) async {}, ); } } ``` -or with options: +startService: optional, Used for adding a killswitch implementation to the app. This is a function that will be called before exiting the splash screen. If the function returns false, it will continue to the introductions. otherwise it will go no further. -Place the following code somewhere in your project where it can be accessed globally: - -``` -var startUserStoryConfiguration = const StartUserStoryConfiguration(); -``` - -``` -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: -| Parameter | Explanation | -|-----------|-------------| -| `splashScreenBuilder` | The builder to override the default splashScreen | -| `introductionBuilder` | A builder to wrap the introductions in your own page | -| `introductionOptionsBuilder` | The builder to override the default `introductionOptions` | -|`introductionService` | The service to override the default `introductionService` | -| `homeScreenRoute` | The route to navigate to after the introduction or splashScreen is completed | -| `introductionFallbackScreen` | The screen that is shown when something goes wrong fetching data for the introduction | -| `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 | +options: optional, here you can tweek some settings of flutter_start to your liking. +afterIntroduction: required, after showing the introduction, this function will be called. Here you can navigate to the home screen or any other screen you want to show after the introduction. If you do not want introductions you can use the `afterSplashScreen` function in the `FlutterStartOptions` to navigate to the home screen. ## 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 \ No newline at end of file +flutter_start for Flutter is developed by [Iconica](https://iconica.nl). You can contact us at \ No newline at end of file diff --git a/packages/example/lib/main.dart b/packages/example/lib/main.dart deleted file mode 100644 index f6f643c..0000000 --- a/packages/example/lib/main.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_start/flutter_start.dart'; - -import 'package:go_router/go_router.dart'; - -void main() { - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - @override - Widget build(BuildContext context) => const MaterialApp( - home: Home(), - ); -} - -class Home extends StatelessWidget { - const Home({super.key}); - - @override - Widget build(BuildContext context) => NavigatorStartUserStory( - // configuration: config, - onComplete: (context) async { - await Navigator.of(context).pushReplacement( - MaterialPageRoute(builder: (context) => const HomeEntry()), - ); - }, - ); -} - -StartUserStoryConfiguration config = StartUserStoryConfiguration( - // showIntroduction: false, - introductionService: MyIntroductionService(), - splashScreenBuilder: (context, onFinish) => SplashScreen( - onFinish: onFinish, - ), -); - -class MyIntroductionService implements IntroductionService { - @override - Future onComplete() { - // TODO: implement onComplete - throw UnimplementedError(); - } - - @override - Future onSkip() { - // TODO: implement onSkip - throw UnimplementedError(); - } - - @override - Future shouldShow() { - // TODO: implement shouldShow - throw UnimplementedError(); - } -} - -class SplashScreen extends StatefulWidget { - const SplashScreen({ - required this.onFinish, - super.key, - }); - - final Function() onFinish; - - @override - State createState() => _SplashScreenState(); -} - -class _SplashScreenState extends State { - @override - void initState() { - Future.delayed(const Duration(seconds: 3), () { - widget.onFinish(); - }); - super.initState(); - } - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: const Text('SplashScreen'), - ), - body: const Center(child: Text('SplashScreen')), - ); -} - -class HomeEntry extends StatelessWidget { - const HomeEntry({super.key}); - - @override - Widget build(BuildContext context) => Scaffold( - appBar: AppBar( - title: const Text('HomeEntry'), - ), - body: const Center(child: Text('HomeEntry')), - ); -} diff --git a/packages/example/pubspec.yaml b/packages/example/pubspec.yaml deleted file mode 100644 index beb1f35..0000000 --- a/packages/example/pubspec.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: example -description: "Flutter_start example app" -publish_to: "none" - -environment: - sdk: ">=3.2.5 <4.0.0" - -dependencies: - flutter: - sdk: flutter - go_router: any - flutter_start: - path: ../flutter_start/ - flutter_introduction_shared_preferences: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction_shared_preferences - ref: 5.0.0 - # hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub/ - # version: ^5.0.0 - -dependency_overrides: - flutter_data_interface: - git: - url: https://github.com/Iconica-Development/flutter_data_interface.git - ref: 1.0.1 - flutter_introduction_interface: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction_interface - ref: 5.0.0 - flutter_introduction_service: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction_service - ref: 5.0.0 - flutter_introduction_widget: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction_widget - ref: 5.0.0 - -dev_dependencies: - flutter_test: - 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: - uses-material-design: true diff --git a/packages/firebase_start_repository/.gitignore b/packages/firebase_start_repository/.gitignore new file mode 100644 index 0000000..ac5aa98 --- /dev/null +++ b/packages/firebase_start_repository/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/packages/firebase_start_repository/CHANGELOG.md b/packages/firebase_start_repository/CHANGELOG.md new file mode 120000 index 0000000..699cc9e --- /dev/null +++ b/packages/firebase_start_repository/CHANGELOG.md @@ -0,0 +1 @@ +../../CHANGELOG.md \ No newline at end of file diff --git a/packages/firebase_start_repository/CONTRIBUTING.md b/packages/firebase_start_repository/CONTRIBUTING.md new file mode 120000 index 0000000..f939e75 --- /dev/null +++ b/packages/firebase_start_repository/CONTRIBUTING.md @@ -0,0 +1 @@ +../../CONTRIBUTING.md \ No newline at end of file diff --git a/packages/firebase_start_repository/LICENSE b/packages/firebase_start_repository/LICENSE new file mode 120000 index 0000000..30cff74 --- /dev/null +++ b/packages/firebase_start_repository/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/packages/firebase_start_repository/README.md b/packages/firebase_start_repository/README.md new file mode 120000 index 0000000..fe84005 --- /dev/null +++ b/packages/firebase_start_repository/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/packages/example/analysis_options.yaml b/packages/firebase_start_repository/analysis_options.yaml similarity index 57% rename from packages/example/analysis_options.yaml rename to packages/firebase_start_repository/analysis_options.yaml index 8ea00ce..0736605 100644 --- a/packages/example/analysis_options.yaml +++ b/packages/firebase_start_repository/analysis_options.yaml @@ -1,9 +1,9 @@ -include: package:flutter_iconica_analysis/analysis_options.yaml +include: package:flutter_iconica_analysis/components_options.yaml # Possible to overwrite the rules from the package analyzer: exclude: - + linter: rules: diff --git a/packages/firebase_start_repository/lib/firebase_start_repository.dart b/packages/firebase_start_repository/lib/firebase_start_repository.dart new file mode 100644 index 0000000..51643d1 --- /dev/null +++ b/packages/firebase_start_repository/lib/firebase_start_repository.dart @@ -0,0 +1,4 @@ +/// +library firebase_start_repository; + +export "src/firebase_killswitch_repository.dart"; diff --git a/packages/firebase_start_repository/lib/src/firebase_killswitch_repository.dart b/packages/firebase_start_repository/lib/src/firebase_killswitch_repository.dart new file mode 100644 index 0000000..aa4a992 --- /dev/null +++ b/packages/firebase_start_repository/lib/src/firebase_killswitch_repository.dart @@ -0,0 +1,34 @@ +import "dart:convert"; + +import "package:http/http.dart" as http; +import "package:package_info_plus/package_info_plus.dart"; +import "package:start_repository_interface/start_repository_interface.dart"; + +/// The Firebase killswitch repository. +class FirebaseKillswitchRepository implements KillswitchRepositoryInterface { + @override + Future 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; + } +} diff --git a/packages/firebase_start_repository/pubspec.yaml b/packages/firebase_start_repository/pubspec.yaml new file mode 100644 index 0000000..18eddd0 --- /dev/null +++ b/packages/firebase_start_repository/pubspec.yaml @@ -0,0 +1,23 @@ +name: firebase_start_repository +description: "A new Flutter package project." +version: 0.0.1 +homepage: none +publish_to: none + +environment: + sdk: ^3.5.3 + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + http: ^1.2.2 + package_info_plus: ^8.1.0 + start_repository_interface: + path: ../start_repository_interface + +dev_dependencies: + flutter_iconica_analysis: + git: + url: https://github.com/Iconica-Development/flutter_iconica_analysis + ref: 7.0.0 diff --git a/packages/flutter_start/CONTRIBUTING.md b/packages/flutter_start/CONTRIBUTING.md new file mode 120000 index 0000000..f939e75 --- /dev/null +++ b/packages/flutter_start/CONTRIBUTING.md @@ -0,0 +1 @@ +../../CONTRIBUTING.md \ No newline at end of file diff --git a/packages/flutter_start/analysis_options.yaml b/packages/flutter_start/analysis_options.yaml index a5744c1..bbf71fe 100644 --- a/packages/flutter_start/analysis_options.yaml +++ b/packages/flutter_start/analysis_options.yaml @@ -1,4 +1,9 @@ -include: package:flutter_lints/flutter.yaml +include: package:flutter_iconica_analysis/components_options.yaml -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options +# Possible to overwrite the rules from the package + +analyzer: + exclude: + +linter: + rules: \ No newline at end of file diff --git a/packages/example/.gitignore b/packages/flutter_start/example/.gitignore similarity index 100% rename from packages/example/.gitignore rename to packages/flutter_start/example/.gitignore diff --git a/packages/flutter_start/example/README.md b/packages/flutter_start/example/README.md new file mode 100644 index 0000000..2b3fce4 --- /dev/null +++ b/packages/flutter_start/example/README.md @@ -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. diff --git a/packages/flutter_start/example/analysis_options.yaml b/packages/flutter_start/example/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/packages/flutter_start/example/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.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: + # 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 diff --git a/packages/flutter_start/example/lib/main.dart b/packages/flutter_start/example/lib/main.dart new file mode 100644 index 0000000..47be098 --- /dev/null +++ b/packages/flutter_start/example/lib/main.dart @@ -0,0 +1,54 @@ +import 'package:example/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_start/flutter_start.dart'; + +void main(List args) { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: theme, + home: const FlutterStart(), + ); + } +} + +class FlutterStart extends StatelessWidget { + const FlutterStart({super.key}); + + @override + Widget build(BuildContext context) { + return FlutterStartNavigatorUserstory( + startService: StartService(), + options: const FlutterStartOptions(), + afterIntroduction: (context) async { + await Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (context) => const AfterIntroduction(), + ), + ); + }, + ); + } +} + +class AfterIntroduction extends StatelessWidget { + const AfterIntroduction({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("After Introduction"), + ), + body: const Center( + child: Text("After Introduction"), + ), + ); + } +} diff --git a/packages/flutter_start/example/lib/theme.dart b/packages/flutter_start/example/lib/theme.dart new file mode 100644 index 0000000..527f67e --- /dev/null +++ b/packages/flutter_start/example/lib/theme.dart @@ -0,0 +1,154 @@ +import 'package:flutter/material.dart'; + +const Color primaryColor = Color(0xFF71C6D1); + +ThemeData theme = ThemeData( + actionIconTheme: ActionIconThemeData( + drawerButtonIconBuilder: (context) { + return const Icon( + Icons.menu, + color: Colors.white, + size: 32, + ); + }, + backButtonIconBuilder: (context) { + return const Icon(Icons.arrow_back_ios_new_rounded); + }, + ), + scaffoldBackgroundColor: const Color(0xFFFAF9F6), + primaryColor: primaryColor, + checkboxTheme: CheckboxThemeData( + side: const BorderSide( + color: Color(0xFF8D8D8D), + width: 1, + ), + fillColor: WidgetStateProperty.resolveWith( + (Set states) { + if (states.contains(WidgetState.selected)) { + return primaryColor; + } + return const Color(0xFFEEEEEE); + }, + ), + ), + switchTheme: SwitchThemeData( + trackColor: + WidgetStateProperty.resolveWith((Set states) { + if (!states.contains(WidgetState.selected)) { + return const Color(0xFF8D8D8D); + } + return primaryColor; + }), + thumbColor: const WidgetStatePropertyAll( + Colors.white, + ), + ), + appBarTheme: const AppBarTheme( + centerTitle: true, + iconTheme: IconThemeData( + color: Colors.white, + size: 16, + ), + elevation: 0, + backgroundColor: Color(0xFF212121), + titleTextStyle: TextStyle( + fontWeight: FontWeight.w900, + fontSize: 24, + color: primaryColor, + fontFamily: "Merriweather", + ), + actionsIconTheme: IconThemeData()), + fontFamily: "Merriweather", + useMaterial3: false, + textTheme: const TextTheme( + headlineSmall: TextStyle( + fontWeight: FontWeight.w400, + fontSize: 16, + color: Colors.white, + ), + headlineLarge: TextStyle( + fontWeight: FontWeight.w900, + fontSize: 24, + color: primaryColor, + ), + + displayLarge: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w800, + fontSize: 20, + color: Colors.white, + ), + displayMedium: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w800, + fontSize: 18, + color: Color(0xFF71C6D1), + ), + displaySmall: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w800, + fontSize: 14, + color: Colors.black, + ), + + // TITLE + titleSmall: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w800, + fontSize: 14, + color: Colors.white, + ), + titleMedium: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w800, + fontSize: 16, + color: Colors.black, + ), + titleLarge: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w800, + fontSize: 20, + color: Colors.black, + ), + + // LABEL + labelSmall: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w400, + fontSize: 12, + color: Color(0xFF8D8D8D), + ), + + // BODY + bodySmall: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w400, + fontSize: 14, + color: Colors.black, + ), + bodyMedium: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.w400, + fontSize: 16, + color: Colors.black, + ), + ), + radioTheme: RadioThemeData( + visualDensity: const VisualDensity( + horizontal: 0, + vertical: -2, + ), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + fillColor: WidgetStateProperty.resolveWith( + (Set states) { + if (states.contains(WidgetState.selected)) { + return Colors.black; + } + return Colors.black; + }, + ), + ), + colorScheme: const ColorScheme.light( + primary: primaryColor, + ), +); diff --git a/packages/flutter_start/example/pubspec.yaml b/packages/flutter_start/example/pubspec.yaml new file mode 100644 index 0000000..8e5d5a4 --- /dev/null +++ b/packages/flutter_start/example/pubspec.yaml @@ -0,0 +1,24 @@ +name: example +description: "A new Flutter project." + +publish_to: "none" + +version: 1.0.0+1 + +environment: + sdk: ^3.5.3 + +dependencies: + flutter: + sdk: flutter + flutter_start: + path: ../ + +dev_dependencies: + flutter_test: + sdk: flutter + + flutter_lints: ^4.0.0 + +flutter: + uses-material-design: true diff --git a/packages/flutter_start/example/test/widget_test.dart b/packages/flutter_start/example/test/widget_test.dart new file mode 100644 index 0000000..092d222 --- /dev/null +++ b/packages/flutter_start/example/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:example/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/packages/flutter_start/lib/flutter_start.dart b/packages/flutter_start/lib/flutter_start.dart index 6ffc038..eebb588 100644 --- a/packages/flutter_start/lib/flutter_start.dart +++ b/packages/flutter_start/lib/flutter_start.dart @@ -1,4 +1,16 @@ -export 'package:flutter_introduction/flutter_introduction.dart'; -export 'package:flutter_introduction_shared_preferences/flutter_introduction_shared_preferences.dart'; -export 'src/models/start_configuration.dart'; -export 'src/user_stories/flutter_start_userstory_navigator.dart'; +// ignore_for_file: directives_ordering + +/// Userstory +library; + +export "package:start_repository_interface/start_repository_interface.dart"; +export "package:flutter_introduction/flutter_introduction.dart"; + +export "src/flutter_start_navigator_userstory.dart"; + +/// models +export "src/models/flutter_start_options.dart"; + +/// Screens +export "src/screens/splash_screen.dart"; +export "src/screens/introductions_screen.dart"; diff --git a/packages/flutter_start/lib/src/flutter_start_navigator_userstory.dart b/packages/flutter_start/lib/src/flutter_start_navigator_userstory.dart new file mode 100644 index 0000000..0448eb6 --- /dev/null +++ b/packages/flutter_start/lib/src/flutter_start_navigator_userstory.dart @@ -0,0 +1,52 @@ +import "package:flutter/material.dart"; +import "package:flutter_introduction_shared_preferences/flutter_introduction_shared_preferences.dart"; +import "package:flutter_start/flutter_start.dart"; + +/// A userstory that navigates to the start of the Flutter app. +class FlutterStartNavigatorUserstory extends StatelessWidget { + /// FlutterStartNavigatorUserstory constructor. + FlutterStartNavigatorUserstory({ + required this.afterIntroduction, + this.options = const FlutterStartOptions(), + StartService? startService, + super.key, + }) : startService = startService ?? StartService(); + + /// The start service to start the Flutter app. + final StartService startService; + + /// The options to configure the start of the Flutter app. + final FlutterStartOptions options; + + /// The function that is executed after the introduction screen. + final Function(BuildContext context) afterIntroduction; + + @override + Widget build(BuildContext context) => + options.useSplashScreen ? splashScreen() : introductionScreen(context); + + /// The splash screen of the Flutter app. + Widget splashScreen() => SplashScreen( + options: options, + startService: startService, + afterSplashScreen: (ctx) async { + options.afterSplashScreen?.call(ctx) ?? + await Navigator.of(ctx).pushReplacement( + MaterialPageRoute( + builder: introductionScreen, + ), + ); + }, + ); + + /// The introduction screen of the Flutter app. + Widget introductionScreen(BuildContext context) => IntroductionsScreen( + options: options, + introductionOptions: options.introductionOptions, + afterIntroduction: () async => afterIntroduction.call(context), + introductionService: options.introductionService ?? + IntroductionService(SharedPreferencesIntroductionDataProvider()), + introductionScrollPhysics: options.introductionScrollPhysics, + introDuctionFallBackScreen: options.introDuctionFallBackScreen, + ); +} diff --git a/packages/flutter_start/lib/src/models/flutter_start_options.dart b/packages/flutter_start/lib/src/models/flutter_start_options.dart new file mode 100644 index 0000000..140520e --- /dev/null +++ b/packages/flutter_start/lib/src/models/flutter_start_options.dart @@ -0,0 +1,66 @@ +import "package:flutter/material.dart"; +import "package:flutter_introduction/flutter_introduction.dart"; + +/// Options to configure the start of the Flutter app. +class FlutterStartOptions { + /// FlutterStartOptions constructor. + + const FlutterStartOptions({ + this.splashScreenBackgroundColor = const Color(0xff212121), + this.introductionOptions = const IntroductionOptions(), + this.minimumSplashScreenDuration = 3, + this.canPopFromIntroduction = true, + this.introDuctionFallBackScreen, + this.iskillswitchEnabled = true, + this.introductionScrollPhysics, + this.splashScreenCenterWidget, + this.useSplashScreen = true, + this.splashScreenBuilder, + this.introductionService, + this.splashScreenFuture, + this.afterSplashScreen, + this.afterIntroduction, + }); + + /// The background color of the splash screen. + final Color splashScreenBackgroundColor; + + /// The center widget of the splash screen. + final Widget? splashScreenCenterWidget; + + /// If the splash screen should be used. + final bool useSplashScreen; + + /// The minimum duration of the splash screen. + final double minimumSplashScreenDuration; + + /// The future that is executed when the splash screen is shown. + final Future Function(BuildContext context)? splashScreenFuture; + + /// The builder of the splash screen. + final Widget Function(BuildContext context)? splashScreenBuilder; + + /// The function that is executed after the introduction screen. + final IntroductionOptions introductionOptions; + + /// The introduction options to configure the introduction screen. + final IntroductionService? introductionService; + + /// The scroll physics of the introduction screen. + final ScrollPhysics? introductionScrollPhysics; + + /// The fallback screen of the introduction screen. + final Widget? introDuctionFallBackScreen; + + /// The function that is executed after the splash screen. + final Function(BuildContext context)? afterSplashScreen; + + /// The function that is executed after the introduction screen. + final Function(BuildContext context)? afterIntroduction; + + /// Whether or not the Introduction can be popped. + final bool canPopFromIntroduction; + + /// Whether or not the killswitch is enabled. + final bool iskillswitchEnabled; +} diff --git a/packages/flutter_start/lib/src/models/start_configuration.dart b/packages/flutter_start/lib/src/models/start_configuration.dart deleted file mode 100644 index 0adfb97..0000000 --- a/packages/flutter_start/lib/src/models/start_configuration.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_introduction/flutter_introduction.dart'; -import '../services/killswitch_service.dart'; - -/// An immutable class that represents the configuration for -/// starting a user story. -@immutable -class StartUserStoryConfiguration { - /// Creates a new instance of [StartUserStoryConfiguration]. - const StartUserStoryConfiguration({ - this.splashScreenBuilder, - this.introductionBuilder, - this.introductionOptionsBuilder, - this.introductionService, - this.homeScreenRoute, - this.introductionFallbackScreen, - this.introductionScrollPhysics, - 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( - BuildContext context, - Function() onFinish, - )? splashScreenBuilder; - - /// This is used to wrap the introduction widget in your own custom page. - final Widget Function( - BuildContext context, - Widget introductionPage, - )? introductionBuilder; - - /// The route that is used to navigate to the home screen. - final String? homeScreenRoute; - - final IntroductionOptions Function(BuildContext context)? - introductionOptionsBuilder; - final Widget? introductionFallbackScreen; - final IntroductionService? introductionService; - final KillswitchService? killswitchService; - final ScrollPhysics? introductionScrollPhysics; - - /// 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 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; -} diff --git a/packages/flutter_start/lib/src/screens/introductions_screen.dart b/packages/flutter_start/lib/src/screens/introductions_screen.dart new file mode 100644 index 0000000..b0ce005 --- /dev/null +++ b/packages/flutter_start/lib/src/screens/introductions_screen.dart @@ -0,0 +1,46 @@ +import "package:flutter/material.dart"; +import "package:flutter_start/flutter_start.dart"; + +/// The introduction screen of the Flutter app. +class IntroductionsScreen extends StatelessWidget { + /// IntrdoctionScreen constructor + const IntroductionsScreen({ + required this.introDuctionFallBackScreen, + required this.introductionScrollPhysics, + required this.introductionOptions, + required this.introductionService, + required this.afterIntroduction, + required this.options, + super.key, + }); + + /// The function that is executed after the introduction screen. + final Function() afterIntroduction; + + /// The options to configure the introduction screen. + final IntroductionOptions introductionOptions; + + /// The introduction service to configure the introduction screen. + final IntroductionService introductionService; + + /// The scroll physics of the introduction screen. + final ScrollPhysics? introductionScrollPhysics; + + /// The fallback screen of the introduction screen. + final Widget? introDuctionFallBackScreen; + + /// The options to configure the start of the Flutter app. + final FlutterStartOptions options; + + @override + Widget build(BuildContext context) => PopScope( + canPop: options.canPopFromIntroduction, + child: Introduction( + options: introductionOptions, + navigateTo: afterIntroduction, + physics: introductionScrollPhysics, + service: introductionService, + child: introDuctionFallBackScreen, + ), + ); +} diff --git a/packages/flutter_start/lib/src/screens/splash_screen.dart b/packages/flutter_start/lib/src/screens/splash_screen.dart new file mode 100644 index 0000000..ea8a3cb --- /dev/null +++ b/packages/flutter_start/lib/src/screens/splash_screen.dart @@ -0,0 +1,96 @@ +import "dart:async"; + +import "package:flutter/material.dart"; +import "package:flutter_start/flutter_start.dart"; + +/// A splash screen that is shown when the app is started. +class SplashScreen extends StatefulWidget { + /// SplashScreen constructor. + const SplashScreen({ + required this.afterSplashScreen, + required this.startService, + required this.options, + super.key, + }); + + /// The options to configure the splash screen. + final FlutterStartOptions options; + + /// The function that is executed after the splash screen. + final Function(BuildContext context) afterSplashScreen; + + /// The start service to start the Flutter app. + final StartService startService; + + @override + State createState() => _SplashScreenState(); +} + +class _SplashScreenState extends State { + bool minimumDurationPassed = false; + bool futureCompleted = false; + bool canContinue = false; + + @override + void initState() { + super.initState(); + + Future.delayed( + Duration(seconds: widget.options.minimumSplashScreenDuration.toInt()), + () { + setState(() { + minimumDurationPassed = true; + }); + checkTransitionConditions(); + }); + + if (widget.options.splashScreenFuture != null) { + unawaited( + widget.options.splashScreenFuture!(context).then((_) { + setState(() { + futureCompleted = true; + }); + checkTransitionConditions(); + }), + ); + } else { + futureCompleted = true; + } + + if (widget.options.iskillswitchEnabled) { + unawaited( + widget.startService.isKillswitchActive().then((value) { + setState(() { + canContinue = !value; + }); + checkTransitionConditions(); + }), + ); + } else { + canContinue = true; + } + } + + void checkTransitionConditions() { + if (minimumDurationPassed && + futureCompleted && + canContinue && + context.mounted) { + widget.afterSplashScreen(context); + } + } + + @override + Widget build(BuildContext context) => + widget.options.splashScreenBuilder?.call(context) ?? + Scaffold( + backgroundColor: widget.options.splashScreenBackgroundColor, + body: Center( + child: widget.options.splashScreenCenterWidget ?? + Text( + "iconinstagram", + style: Theme.of(context).textTheme.headlineLarge, + ), + ), + ); +} diff --git a/packages/flutter_start/lib/src/services/killswitch_service.dart b/packages/flutter_start/lib/src/services/killswitch_service.dart deleted file mode 100644 index 58ac99d..0000000 --- a/packages/flutter_start/lib/src/services/killswitch_service.dart +++ /dev/null @@ -1,46 +0,0 @@ -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 isKillswitchActive() => throw UnimplementedError(); -} - -class DefaultKillswitchService implements KillswitchService { - @override - Future 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; - } -} diff --git a/packages/flutter_start/lib/src/user_stories/flutter_start_userstory_navigator.dart b/packages/flutter_start/lib/src/user_stories/flutter_start_userstory_navigator.dart deleted file mode 100644 index d15f6df..0000000 --- a/packages/flutter_start/lib/src/user_stories/flutter_start_userstory_navigator.dart +++ /dev/null @@ -1,162 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import '../../flutter_start.dart'; -import '../services/killswitch_service.dart'; -import '../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) { - if (!configuration.showSplashScreen) { - return _introduction(configuration, context, onComplete); - } - - return _splashScreen(configuration, context, onComplete); - } -} - -/// 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 startNavigatorUserStory( - BuildContext context, - StartUserStoryConfiguration configuration, { - required void Function(BuildContext context) onComplete, -}) async { - var initialRoute = MaterialPageRoute( - builder: (context) => _splashScreen( - configuration, - context, - onComplete, - ), - ); - - if (!configuration.showSplashScreen && configuration.showIntroduction) { - initialRoute = MaterialPageRoute( - builder: (context) => _introduction( - configuration, - context, - onComplete, - ), - ); - } - - await Navigator.of(context).push(initialRoute); -} - -Widget _splashScreen( - StartUserStoryConfiguration configuration, - BuildContext context, - void Function(BuildContext context) onComplete, -) { - var navigator = Navigator.of(context); - - var isAllowedToPassThrough = false; - - Future splashHandler() async { - await Future.wait( - [ - 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; - - if ((!configuration.showIntroduction) && context.mounted) { - onComplete(context); - return; - } - - if (context.mounted) { - await navigator.pushReplacement( - MaterialPageRoute( - builder: (context) => _introduction( - configuration, - context, - onComplete, - ), - ), - ); - } - } - - var builder = configuration.splashScreenBuilder; - - if (builder == null) { - unawaited(splashHandler()); - return Scaffold( - backgroundColor: configuration.splashScreenBackgroundColor, - body: Center( - child: configuration.splashScreenCenterWidget?.call(context) ?? - defaultSplashScreen(context), - ), - ); - } - - return builder.call( - context, - splashHandler, - ); -} - -Widget _introduction( - StartUserStoryConfiguration configuration, - BuildContext context, - void Function(BuildContext context) onComplete, -) { - var introduction = Introduction( - service: configuration.introductionService ?? - IntroductionService(SharedPreferencesIntroductionDataProvider()), - navigateTo: () async => onComplete(context), - options: configuration.introductionOptionsBuilder?.call(context) ?? - const IntroductionOptions(), - physics: configuration.introductionScrollPhysics, - child: configuration.introductionFallbackScreen, - ); - return PopScope( - canPop: configuration.canPopFromIntroduction, - child: configuration.introductionBuilder?.call( - context, - introduction, - ) ?? - Scaffold( - body: introduction, - ), - ); -} diff --git a/packages/flutter_start/lib/src/widgets/default_splash_screen.dart b/packages/flutter_start/lib/src/widgets/default_splash_screen.dart deleted file mode 100644 index 6fa02fc..0000000 --- a/packages/flutter_start/lib/src/widgets/default_splash_screen.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -Text defaultSplashScreen(BuildContext context) => Text( - 'iconinstagram', - style: Theme.of(context).textTheme.headlineLarge, - ); diff --git a/packages/flutter_start/pubspec.yaml b/packages/flutter_start/pubspec.yaml index d6bd635..58e5624 100644 --- a/packages/flutter_start/pubspec.yaml +++ b/packages/flutter_start/pubspec.yaml @@ -1,63 +1,27 @@ name: flutter_start -description: "Flutter_start is a package that allows you to jumpstart your application with a splashScreen, introduction and a home." -version: 4.2.1 - -# publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub -publish_to: 'none' +description: "A new Flutter package project." +version: 0.0.1 +homepage: none +publish_to: none environment: - sdk: ">=3.2.5 <4.0.0" + sdk: ^3.5.3 + flutter: ">=1.17.0" dependencies: flutter: sdk: flutter - 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: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction - ref: 5.0.0 - # hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub - # version: "^5.0.0" + hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub + version: ^5.0.0 flutter_introduction_shared_preferences: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction_shared_preferences - ref: 5.0.0 - # hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub/ - # version: ^5.0.0 - -dependency_overrides: - flutter_data_interface: - git: - url: https://github.com/Iconica-Development/flutter_data_interface.git - ref: 1.0.1 - flutter_introduction_interface: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction_interface - ref: 5.0.0 - flutter_introduction_service: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction_service - ref: 5.0.0 - flutter_introduction_widget: - git: - url: https://github.com/Iconica-Development/flutter_introduction.git - path: packages/flutter_introduction_widget - ref: 5.0.0 + hosted: https://forgejo.internal.iconica.nl/api/packages/internal/pub/ + version: ^5.0.0 + start_repository_interface: + path: ../start_repository_interface dev_dependencies: - flutter_test: - sdk: flutter flutter_iconica_analysis: git: url: https://github.com/Iconica-Development/flutter_iconica_analysis - ref: 6.0.0 - -flutter: - uses-material-design: true + ref: 7.0.0 diff --git a/packages/start_repository_interface/CONTRIBUTING.md b/packages/start_repository_interface/CONTRIBUTING.md new file mode 120000 index 0000000..f939e75 --- /dev/null +++ b/packages/start_repository_interface/CONTRIBUTING.md @@ -0,0 +1 @@ +../../CONTRIBUTING.md \ No newline at end of file diff --git a/packages/start_repository_interface/analysis_options.yaml b/packages/start_repository_interface/analysis_options.yaml index a5744c1..bbf71fe 100644 --- a/packages/start_repository_interface/analysis_options.yaml +++ b/packages/start_repository_interface/analysis_options.yaml @@ -1,4 +1,9 @@ -include: package:flutter_lints/flutter.yaml +include: package:flutter_iconica_analysis/components_options.yaml -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options +# Possible to overwrite the rules from the package + +analyzer: + exclude: + +linter: + rules: \ No newline at end of file diff --git a/packages/start_repository_interface/lib/src/interfaces/killswitch_repository_interface.dart b/packages/start_repository_interface/lib/src/interfaces/killswitch_repository_interface.dart new file mode 100644 index 0000000..d1b4c2b --- /dev/null +++ b/packages/start_repository_interface/lib/src/interfaces/killswitch_repository_interface.dart @@ -0,0 +1,6 @@ +/// Killswitch repository interface +// ignore: one_member_abstracts +abstract class KillswitchRepositoryInterface { + /// Checks if the killswitch is active for the current app. + Future isKillswitchActive(); +} diff --git a/packages/start_repository_interface/lib/src/local/local_killswitch_repository.dart b/packages/start_repository_interface/lib/src/local/local_killswitch_repository.dart new file mode 100644 index 0000000..9365aa6 --- /dev/null +++ b/packages/start_repository_interface/lib/src/local/local_killswitch_repository.dart @@ -0,0 +1,7 @@ +import "package:start_repository_interface/src/interfaces/killswitch_repository_interface.dart"; + +/// The local killswitch repository. +class LocalKillswitchRepository implements KillswitchRepositoryInterface { + @override + Future isKillswitchActive() async => false; +} diff --git a/packages/start_repository_interface/lib/src/services/start_service.dart b/packages/start_repository_interface/lib/src/services/start_service.dart new file mode 100644 index 0000000..eb86652 --- /dev/null +++ b/packages/start_repository_interface/lib/src/services/start_service.dart @@ -0,0 +1,18 @@ +import "package:start_repository_interface/src/interfaces/killswitch_repository_interface.dart"; +import "package:start_repository_interface/src/local/local_killswitch_repository.dart"; + +/// Start service. +class StartService { + /// The start service constructor. + StartService({ + KillswitchRepositoryInterface? killswitchRepositoryInterface, + }) : killswitchRepositoryInterface = + killswitchRepositoryInterface ?? LocalKillswitchRepository(); + + /// The killswitch repository interface. + final KillswitchRepositoryInterface? killswitchRepositoryInterface; + + /// Check if the killswitch is active. + Future isKillswitchActive() async => + killswitchRepositoryInterface!.isKillswitchActive(); +} diff --git a/packages/start_repository_interface/lib/start_repository_interface.dart b/packages/start_repository_interface/lib/start_repository_interface.dart index 927fb58..8f08c95 100644 --- a/packages/start_repository_interface/lib/start_repository_interface.dart +++ b/packages/start_repository_interface/lib/start_repository_interface.dart @@ -1,7 +1,6 @@ +/// library start_repository_interface; -/// A Calculator. -class Calculator { - /// Returns [value] plus 1. - int addOne(int value) => value + 1; -} +export "src/interfaces/killswitch_repository_interface.dart"; +export "src/local/local_killswitch_repository.dart"; +export "src/services/start_service.dart"; diff --git a/packages/start_repository_interface/pubspec.yaml b/packages/start_repository_interface/pubspec.yaml index afda727..c9b6a96 100644 --- a/packages/start_repository_interface/pubspec.yaml +++ b/packages/start_repository_interface/pubspec.yaml @@ -1,7 +1,7 @@ name: start_repository_interface description: "A new Flutter package project." version: 0.0.1 -homepage: +homepage: none environment: sdk: ^3.5.3 @@ -12,43 +12,8 @@ dependencies: sdk: flutter dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^4.0.0 + flutter_iconica_analysis: + git: + url: https://github.com/Iconica-Development/flutter_iconica_analysis + ref: 7.0.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. -flutter: - - # To add assets to your package, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # - # For details regarding assets in packages, see - # https://flutter.dev/to/asset-from-package - # - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/to/resolution-aware-images - - # To add custom fonts to your package, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts in packages, see - # https://flutter.dev/to/font-from-package diff --git a/packages/start_repository_interface/test/start_repository_interface_test.dart b/packages/start_repository_interface/test/start_repository_interface_test.dart deleted file mode 100644 index eba62b8..0000000 --- a/packages/start_repository_interface/test/start_repository_interface_test.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; - -import 'package:start_repository_interface/start_repository_interface.dart'; - -void main() { - test('adds one to input values', () { - final calculator = Calculator(); - expect(calculator.addOne(2), 3); - expect(calculator.addOne(-7), -6); - expect(calculator.addOne(0), 1); - }); -}