user_identity_feature 0.0.33 copy "user_identity_feature: ^0.0.33" to clipboard
user_identity_feature: ^0.0.33 copied to clipboard

MyCS user authentication, registration and profile management feature module

example/lib/main.dart

import 'dart:io';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:window_manager/window_manager.dart';
import 'package:logging/logging.dart';
import 'package:get_it/get_it.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';

import 'package:utilities_ab/utilities.dart';
import 'package:platform_utilities_component/platform_utilities.dart';
import 'package:ui_widgets_component/ui_widgets.dart';
import 'package:nav_layouts_component/nav_layouts.dart';
import 'package:app_framework_component/app_framework.dart';
import 'package:user_identity_feature/user_identity.dart';
import 'package:identity_service/identity_service.dart' as identity;

import 'aws_amplify_config.dart';

import 'features/billing_feature.dart';
import 'features/organization_feature.dart';

import 'config/app_config.dart';
import 'screens/home_page.dart';
import 'screens/app_nav_layout.dart';
import 'screens/login_view_flow.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  initLogging(
    Level.ALL,
    logToConsole: true,
  );

  // On Desktop platforms the minimum size
  // of the window is fixed at 240x400
  if (!AppPlatform.isWeb && !AppPlatform.isMobile) {
    await windowManager.ensureInitialized();

    WindowManager.instance.setMinimumSize(AppConfig.minWindowSize);
    WindowManager.instance.setTitle(AppConfig.title);
  }

  // Initialize AppPlatform
  await AppPlatform.init();

  // Initialize Amplify
  await _configureAmplify();

  // Initialize HydratedBloc storage
  HydratedBloc.storage = await HydratedStorage.build(
    storageDirectory: kIsWeb
        ? HydratedStorage.webStorageDirectory
        : Directory('${AppPlatform.appDataPath}/state'),
  );
  // HydratedBloc.storage = await SecureHydratedStorage.build();

  // Create and initialize the
  // feature registry singleton
  FeatureRegistry.intialize(featureConfigLoader);

  runApp(
    StatefulWrapper(
      onInit: (_) async {
        GetIt.instance.registerLazySingleton<identity.IdentityProvider>(
          () {
            return identity.AWSCognitoService();
          },
        );

        // register the user identity feature
        await UserIdentityFeature.register();
        // register the billing feature
        await BillingFeature.register();
        // register the organization feature
        await OrganizationFeature.register();
      },
      onDispose: () async {
        GetIt.instance.unregister<identity.IdentityProvider>(
          disposingFunction: (service) async => await service.dispose(),
        );

        FeatureRegistry.instance().dispose();
      },
      child: MainApp(),
    ),
  );
}

class MainApp extends StatelessWidget {
  late final AuthRouter _authRouter;

  MainApp({super.key}) {
    _authRouter = AuthRouter(
      navigatorKey: GlobalNavigator.key,
      initialLocation: '/',
      authRoute: LoginViewFlow(),
      publicRoutes: [
        const HomePage().route(),
      ],
      privateRoutes: [
        AppNavLayout().route(),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    AppPlatform.initOnBuild(context);

    if (AppPlatform.isDesktop && Platform.isMacOS) {
      // On macOS a system menu is a required part of every application
      final List<PlatformMenuItem> menus = <PlatformMenuItem>[
        PlatformMenu(
          label: '', // In macOS the application name is shown in the menu bar
          menus: <PlatformMenuItem>[
            PlatformMenuItemGroup(
              members: <PlatformMenuItem>[
                PlatformMenuItem(
                  label: 'About',
                  onSelected: () {
                    showAboutDialog(
                      context: context,
                      applicationName: AppConfig.title,
                      applicationVersion: AppConfig.version,
                    );
                  },
                ),
              ],
            ),
            if (PlatformProvidedMenuItem.hasMenu(
                PlatformProvidedMenuItemType.quit))
              const PlatformProvidedMenuItem(
                  type: PlatformProvidedMenuItemType.quit),
          ],
        ),
      ];
      WidgetsBinding.instance.platformMenuDelegate.setMenus(menus);
    }

    final featureRegistry = FeatureRegistry.instance();
    final localizationDelegates = [
      GlobalMaterialLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate,
      GlobalCupertinoLocalizations.delegate,
      UIWidgetLocalizations.delegate,
      ...featureRegistry.getLocalizationsDelegates(),
    ];

    return featureRegistry.scope(
      context,
      child: MaterialApp.router(
        debugShowCheckedModeBanner: false,
        title: AppConfig.title,
        localizationsDelegates: localizationDelegates,
        supportedLocales: const [
          Locale('en'), // English
        ],
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(
            seedColor: Colors.indigo,
          ),
          useMaterial3: false,
        ),
        darkTheme: ThemeData(
          colorScheme: ColorScheme.fromSeed(
            brightness: Brightness.dark,
            seedColor: Colors.indigo,
          ),
          useMaterial3: false,
        ),
        routerConfig: _authRouter.config,
      ),
    );
  }
}

Future<void> _configureAmplify() async {
  // Add any Amplify plugins you want to use
  final authPlugin = AmplifyAuthCognito();
  await Amplify.addPlugin(authPlugin);

  // You can use addPlugins if you are going to be adding multiple plugins
  // await Amplify.addPlugins([authPlugin, analyticsPlugin]);

  // Once Plugins are added, configure Amplify
  // Note: Amplify can only be configured once.
  try {
    await Amplify.configure(amplifyconfig);
  } on AmplifyAlreadyConfiguredException {
    safePrint(
        "Tried to reconfigure Amplify; this can occur when your app restarts on Android.");
  }
}

Future<Map<String, dynamic>> featureConfigLoader(
  String featureName,
) async {
  /// Load the feature configuration json from the assets
  return jsonDecode(
    await rootBundle.loadString('assets/${featureName}_feature.json'),
  );
}