Kohler Providers

Documentation Localizely

A toolkit of shared providers and widgets for Kohler applications

This package contains shared widgets based on our high fidelity designs that provide consistency for Kohler applications.

This also contains an opinionated set of providers that automatically build Kohler-related such as the Clean Energy API classes and Kohler-specific authentication.

Features

  • Shared Kohler app-specific widgets such as remote exercise dialog, notification page, Kohler logos, etc.
  • Environment variable support with versioning
  • Providers for the Kohler Energy Management Web APIs (using the clean_energy_api package)
  • API / Network interceptor code that's specific to Kohler's backend
  • Providers for OAuth related code (using the flutter_oauth package)
  • Shared flutter widgets for common interaction patterns.
  • Other shared code for themes, routing, display range, etc.

Getting started

Create your .env file

To get started, you must create your own .env file in the root project folder

This is because these providers use environment variables under the hood to configure the Clean Energy API and OAuth instances.

See .env.example for a sample .env file structure. Your .env file must contain all values in .env.example, but may contain additional values for your app-specific configurations.

It must also have a SHARED_ENV_VERSION=6 entry, or else reading the providers will throw. This serves as a way to ensure that the environment files of developers and pipeline agents are up-to-date. If there are any breaking changes to the environment file within this package, the required version will increment.

Add the .env file to your assets

Add the .env file to your assets bundle in pubspec.yaml. Ensure that the path corresponds to the location of the .env file.

Update .gitignore

Remember to add the .env file as an entry to your .gitignore if it isn't already.

You should not include the .env file in source control, as a general rule.

Usage

This package contains shared themes and widgets that are common across multiple Kohler apps.

Some notable shared code includes the shared theme, colors, icons, and so forth which can be used like so:

// Themes
MaterialApp.router(
  theme: KohlerTheme.theme,
  darkTheme: KohlerTheme.darkTheme,
  // ...
)

// Icons
Icon(KohlerIcons.logo)

// Colors
context.appColors.orange

This package also contains many shared Kohler application widgets, such as a remote exercise dialog (showRemoteExerciseDialog), a shared notification page (AppNotificationPage), a shared events log page (AppEventsPage), etc. See app_features/ and app_widgets/ for details.

The shared backend API calls under the hood are also available via providers. Notably, generatorDetailsFamily(id) can be used to retrieve the generator details for any device with the given id. See app_providers/ for details.

This package contains other shared Flutter widgets and utility methods that provide common useful functionality. See widgets/ and utils/ for details.

Another main purpose of this package is to easily access APIs such as the Clean Energy Web API or the Authentication Manager. This can be done like so:

/// Access APIs using [cleanEnergyRdc2ServiceProvider],
/// [energyManagementApiProvider], and [energyManagementV3ApiProvider].
final devicesProvider = FutureProvider.autoDispose(
  (ref) => ref.watch(energyManagementV3ApiProvider.future)
    .then((api) => api.kemApiV3DealerDevicesGet())
    .then(responseToValue);
);

/// Access authentication related info and controllers
class AuthScreen extends ConsumerWidget {
  const AuthScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    /// Access the authentication manager
    final manager = ref.watch(authManagerProvider).value;

    /// Access the current user
    final currentUser = ref.watch(currentUserProvider).value;

    /// Access whether the user is logged in or not
    final isLoggedIn = ref.watch(isLoggedInProvider);

    return ...
  }
}

This package also provides a consistent shared way to access environment variables, like so:

/// First, set-up an environment provider family
final envFamily = createEnvFamily(
  filename: '.env', // Defaults to .env already, but can be customized
  requiredVersions: {
    'VERSION': 1 // Optional version number that must be included in the file
  },
);

/// Then, use the family provider to access environment variables
final clientId = envFamily('CLIENT_ID');

The .env file that was set-up earlier can contain additional values beyond the standard set of values required for this package.

Finally, this package also provides Flutter widgets to customize the handling of authentication errors within the App. Whenever these widgets are on the widget tree, they will attach handlers to the authentication handler to manage and potentially recover from authentication errors.

/// Set-up a callback to be run when an authentication error occurs
return AuthErrorScope(
  onAuthError: (request, response, originalRequest) => request.copyWith(
    headers: ...
  ),
  child: MyChild(),
);

/// Set-up a shared, opinionated handler that displays a dialog with an option 
/// to log-in again when an aunthentication error occurs.
return DialogOnAuthErrorScope(
  child: MyChild(),
);

Localization

This package uses Flutter's recommended tooling for internationalization known as gen_l10n, and also uses Localizely for translation hosting and contributing services.

Only the english translations are saved in source control, under lib/src/localization/inputs/intl_en.arb. The english translations are included in source control are considered correct & reviewed.

To use translations, import the corresponding lib/src/localization/localization.dart file and call SharedLocalizations.of(context) or the extension method context.sharedL10n.

To add a new localization string, add an entry to the english localization file, following the .arb file structure.

You must then call the following command to add the new localizations to SharedLocalizations:

# cd packages/kohler_providers/
flutter gen-l10n

Unlike the localizations in the apps, the flutter gen-l10n command must always be called because localizations for packages are not generated on hot reload.

All other translations are stored in Localizely. They are downloaded during the setup step of the app within Azure pipelines. For testing / review purposes, you can manually download translations by running the following:

flutter pub global activate intl_utils

# cd packages/kohler_providers/
flutter pub global run intl_utils:localizely_download --api-token <LOCALIZELY_READ_TOKEN>

Any non-english translations should not be added to source control, since they are managed by Localizely.

When your pull request is merged into main, any additional translations are automatically uploaded to Localizely for translation by language contributors. They can also be manually uploaded by running the following:

# Assuming intl_utils package is already activated using prior command
flutter pub global run intl_utils:localizely_upload_main --api-token <LOCALIZELY_READ_WRITE_TOKEN>

Libraries

kohler_providers
A toolkit of shared providers and widgets for Kohler applications