Unverified Commit 65550d0f authored by Tonic Artos's avatar Tonic Artos Committed by GitHub

New license page. (#57588)

This is a PR addressing #57226 - Proposal: New UI for Licenses Page.

This PR replaces the previous single panel license page with one that uses a master/detail flow (MDFlow) to display packages and their respective licenses.

The License Page API remains unchanged. The logic for processing the license data is kept largely the same. This PR changes how the licenses are displayed, by introducing a responsive UI using the master/detail UI pattern. For now I am calling it Master Detail Flow, or MDFlow.

MDFlow manifests as two layouts depending on the screen size. On small and medium displays, as determined by the breakpoints given by the Material Design Spec, MDFlow utilises a nested layout. On large displays, MDFlow uses a two panel (lateral) layout. MDFlow is implemented in this PR using a Navigator for the nested layout, and a Stack for the lateral layout. The master and detail views are built using builders. For the interactive component, detail pages are requested from the master view using a proxy obtained by a widget lookup on the build context; MasterDetailFlow.of(context).
parent 15a28159
......@@ -13,15 +13,25 @@ import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart' hide Flow;
import 'app_bar.dart';
import 'back_button.dart';
import 'button_bar.dart';
import 'card.dart';
import 'constants.dart';
import 'debug.dart';
import 'dialog.dart';
import 'flat_button.dart';
import 'floating_action_button.dart';
import 'floating_action_button_location.dart';
import 'ink_decoration.dart';
import 'list_tile.dart';
import 'material.dart';
import 'material_localizations.dart';
import 'page.dart';
import 'page_transitions_theme.dart';
import 'progress_indicator.dart';
import 'scaffold.dart';
import 'scrollbar.dart';
import 'text_theme.dart';
import 'theme.dart';
/// A [ListTile] that shows an about box.
......@@ -294,6 +304,9 @@ void showLicensePage({
));
}
/// The amount of vertical space to separate chunks of text.
const double _textVerticalSeparation = 18.0;
/// An about box. This is a dialog box with the application's icon, name,
/// version number, and copyright, plus a button to show licenses for software
/// used by the application.
......@@ -379,7 +392,7 @@ class AboutDialog extends StatelessWidget {
children: <Widget>[
Text(name, style: Theme.of(context).textTheme.headline5),
Text(version, style: Theme.of(context).textTheme.bodyText2),
Container(height: 18.0),
const SizedBox(height: _textVerticalSeparation),
Text(applicationLegalese ?? '', style: Theme.of(context).textTheme.caption),
],
),
......@@ -474,6 +487,336 @@ class LicensePage extends StatefulWidget {
}
class _LicensePageState extends State<LicensePage> {
final ValueNotifier<int> selectedId = ValueNotifier<int>(null);
@override
Widget build(BuildContext context) {
return _MasterDetailFlow(
detailPageFABlessGutterWidth: _getGutterSize(context),
title: Text(MaterialLocalizations.of(context).licensesPageTitle),
detailPageBuilder: _packageLicensePage,
masterViewBuilder: _packagesView,
);
}
Widget _packageLicensePage(BuildContext _, Object args, ScrollController scrollController) {
assert(args is _DetailArguments);
final _DetailArguments detailArguments = args as _DetailArguments;
return _PackageLicensePage(
packageName: detailArguments.packageName,
licenseEntries: detailArguments.licenseEntries,
scrollController: scrollController,
);
}
Widget _packagesView(final BuildContext _, final bool isLateral) {
final Widget about = _AboutProgram(
name: widget.applicationName ?? _defaultApplicationName(context),
icon: widget.applicationIcon ?? _defaultApplicationIcon(context),
version: widget.applicationVersion ?? _defaultApplicationVersion(context),
legalese: widget.applicationLegalese,
);
return _PackagesView(
about: about,
isLateral: isLateral,
selectedId: selectedId,
);
}
}
class _AboutProgram extends StatelessWidget {
const _AboutProgram({
Key key,
@required this.name,
@required this.version,
this.icon,
this.legalese,
}) : assert(name != null),
assert(version != null),
super(key: key);
final String name;
final String version;
final Widget icon;
final String legalese;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(
horizontal: _getGutterSize(context),
vertical: 24.0,
),
child: Column(
children: <Widget>[
Text(
name,
style: Theme.of(context).textTheme.headline5,
textAlign: TextAlign.center,
),
if (icon != null)
IconTheme(data: Theme.of(context).iconTheme, child: icon),
Text(
version,
style: Theme.of(context).textTheme.bodyText2,
textAlign: TextAlign.center,
),
const SizedBox(height: _textVerticalSeparation),
Text(
legalese ?? '',
style: Theme.of(context).textTheme.caption,
textAlign: TextAlign.center,
),
const SizedBox(height: _textVerticalSeparation),
Text(
'Powered by Flutter',
style: Theme.of(context).textTheme.bodyText2,
textAlign: TextAlign.center,
),
],
),
);
}
}
class _PackagesView extends StatefulWidget {
const _PackagesView({
Key key,
@required this.about,
@required this.isLateral,
@required this.selectedId,
}) : assert(about != null),
assert(isLateral != null),
super(key: key);
final Widget about;
final bool isLateral;
final ValueNotifier<int> selectedId;
@override
_PackagesViewState createState() => _PackagesViewState();
}
class _PackagesViewState extends State<_PackagesView> {
final Future<_LicenseData> licenses = LicenseRegistry.licenses
.fold<_LicenseData>(
_LicenseData(),
(_LicenseData prev, LicenseEntry license) => prev..addLicense(license),
)
.then((_LicenseData licenseData) => licenseData..sortPackages());
@override
Widget build(BuildContext context) {
return FutureBuilder<_LicenseData>(
future: licenses,
builder: (BuildContext context, AsyncSnapshot<_LicenseData> snapshot) {
return AnimatedSwitcher(
transitionBuilder: (Widget child, Animation<double> animation) => FadeTransition(opacity: animation, child: child),
duration: kThemeAnimationDuration,
child: LayoutBuilder(
key: ValueKey<ConnectionState>(snapshot.connectionState),
builder: (BuildContext context, BoxConstraints constraints) {
switch (snapshot.connectionState) {
case ConnectionState.done:
_initDefaultDetailPage(snapshot.data, context);
return ValueListenableBuilder<int>(
valueListenable: widget.selectedId,
builder: (BuildContext context, int selectedId, Widget _) {
return Center(
child: Material(
color: Theme.of(context).cardColor,
elevation: 4.0,
child: Container(
constraints: BoxConstraints.loose(const Size.fromWidth(600.0)),
child: _packagesList(context, selectedId, snapshot.data, widget.isLateral),
),
),
);
},
);
default:
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
widget.about,
const Center(child: CircularProgressIndicator()),
],
);
}
},
),
);
},
);
}
void _initDefaultDetailPage(_LicenseData data, BuildContext context) {
final String packageName = data.packages[widget.selectedId.value ?? 0];
final List<int> bindings = data.packageLicenseBindings[packageName];
_MasterDetailFlow.of(context).setInitialDetailPage(
_DetailArguments(
packageName,
bindings.map((int i) => data.licenses[i]).toList(growable: false),
),
);
}
Widget _packagesList(
final BuildContext context,
final int selectedId,
final _LicenseData data,
final bool drawSelection,
) {
return ListView(
children: <Widget>[
widget.about,
...data.packages
.asMap()
.entries
.map<Widget>((MapEntry<int, String> entry) {
final String packageName = entry.value;
final int index = entry.key;
final List<int> bindings = data.packageLicenseBindings[packageName];
return _PackageListTile(
packageName: packageName,
index: index,
isSelected: drawSelection && entry.key == (selectedId ?? 0),
numberLicenses: bindings.length,
onTap: () {
widget.selectedId.value = index;
_MasterDetailFlow.of(context).openDetailPage(_DetailArguments(
packageName,
bindings.map((int i) => data.licenses[i]).toList(growable: false),
));
},
);
}),
],
);
}
}
class _PackageListTile extends StatelessWidget {
const _PackageListTile({
Key key,
this.packageName,
this.index,
this.isSelected,
this.numberLicenses,
this.onTap,
}) : super(key:key);
final String packageName;
final int index;
final bool isSelected;
final int numberLicenses;
final GestureTapCallback onTap;
@override
Widget build(BuildContext context) {
return Ink(
color: isSelected ? Theme.of(context).highlightColor : Theme.of(context).cardColor,
child: ListTile(
title: Text(packageName),
subtitle: Text(MaterialLocalizations.of(context).licensesPackageDetailText(numberLicenses)),
selected: isSelected,
onTap: onTap,
),
);
}
}
/// This is a collection of licenses and the packages to which they apply.
/// [packageLicenseBindings] records the m+:n+ relationship between the license
/// and packages as a map of package names to license indexes.
class _LicenseData {
final List<LicenseEntry> licenses = <LicenseEntry>[];
final Map<String, List<int>> packageLicenseBindings = <String, List<int>>{};
final List<String> packages = <String>[];
// Special treatment for the first package since it should be the package
// for delivered application.
String firstPackage;
void addLicense(LicenseEntry entry) {
// Before the license can be added, we must first record the packages to
// which it belongs.
for (final String package in entry.packages) {
_addPackage(package);
// Bind this license to the package using the next index value. This
// creates a contract that this license must be inserted at this same
// index value.
packageLicenseBindings[package].add(licenses.length);
}
licenses.add(entry); // Completion of the contract above.
}
/// Add a package and initialise package license binding. This is a no-op if
/// the package has been seen before.
void _addPackage(String package) {
if (!packageLicenseBindings.containsKey(package)) {
packageLicenseBindings[package] = <int>[];
firstPackage ??= package;
packages.add(package);
}
}
/// Sort the packages using some comparison method, or by the default manner,
/// which is to put the application package first, followed by every other
/// package in case-insensitive alphabetical order.
void sortPackages([int compare(String a, String b)]) {
packages.sort(compare ?? (String a, String b) {
// Based on how LicenseRegistry currently behaves, the first package
// returned is the end user application license. This should be
// presented first in the list. So here we make sure that first package
// remains at the front regardless of alphabetical sorting.
if (a == firstPackage) {
return -1;
}
if (b == firstPackage) {
return 1;
}
return a.toLowerCase().compareTo(b.toLowerCase());
});
}
}
@immutable
class _DetailArguments {
const _DetailArguments(this.packageName, this.licenseEntries);
final String packageName;
final List<LicenseEntry> licenseEntries;
@override
bool operator ==(final dynamic other) {
if (other is _DetailArguments) {
return other.packageName == packageName;
}
return other == this;
}
@override
int get hashCode => packageName.hashCode; // Good enough.
}
class _PackageLicensePage extends StatefulWidget {
const _PackageLicensePage({
Key key,
this.packageName,
this.licenseEntries,
this.scrollController,
}) : super(key: key);
final String packageName;
final List<LicenseEntry> licenseEntries;
final ScrollController scrollController;
@override
_PackageLicensePageState createState() => _PackageLicensePageState();
}
class _PackageLicensePageState extends State<_PackageLicensePage> {
@override
void initState() {
super.initState();
......@@ -491,7 +834,7 @@ class _LicensePageState extends State<LicensePage> {
debugFlowId = flow.id;
return true;
}());
await for (final LicenseEntry license in LicenseRegistry.licenses) {
for (final LicenseEntry license in widget.licenseEntries) {
if (!mounted) {
return;
}
......@@ -516,16 +859,6 @@ class _LicensePageState extends State<LicensePage> {
textAlign: TextAlign.center,
),
));
_licenses.add(Container(
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(width: 0.0))
),
child: Text(
license.packages.join(', '),
style: const TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
));
for (final LicenseParagraph paragraph in paragraphs) {
if (paragraph.indent == LicenseParagraph.centeredIndent) {
_licenses.add(Padding(
......@@ -558,35 +891,13 @@ class _LicensePageState extends State<LicensePage> {
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
final String name = widget.applicationName ?? _defaultApplicationName(context);
final String version = widget.applicationVersion ?? _defaultApplicationVersion(context);
final Widget icon = widget.applicationIcon ?? _defaultApplicationIcon(context);
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
return Scaffold(
appBar: AppBar(
title: Text(localizations.licensesPageTitle),
),
// All of the licenses page text is English. We don't want localized text
// or text direction.
body: Localizations.override(
locale: const Locale('en', 'US'),
context: context,
child: DefaultTextStyle(
style: Theme.of(context).textTheme.caption,
child: SafeArea(
bottom: false,
child: Scrollbar(
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 12.0),
children: <Widget>[
Text(name, style: Theme.of(context).textTheme.headline5, textAlign: TextAlign.center),
if (icon != null) IconTheme(data: Theme.of(context).iconTheme, child: icon),
Text(version, style: Theme.of(context).textTheme.bodyText2, textAlign: TextAlign.center),
Container(height: 18.0),
Text(widget.applicationLegalese ?? '', style: Theme.of(context).textTheme.caption, textAlign: TextAlign.center),
Container(height: 18.0),
Text('Powered by Flutter', style: Theme.of(context).textTheme.bodyText2, textAlign: TextAlign.center),
Container(height: 24.0),
final ThemeData theme = Theme.of(context);
final String title = widget.packageName;
final String subtitle = localizations.licensesPackageDetailText(widget.licenseEntries.length);
final double pad = _getGutterSize(context);
final EdgeInsets padding = EdgeInsets.only(left: pad, right: pad, bottom: pad);
final List<Widget> listWidgets = <Widget>[
..._licenses,
if (!_loaded)
const Padding(
......@@ -595,13 +906,86 @@ class _LicensePageState extends State<LicensePage> {
child: CircularProgressIndicator(),
),
),
],
];
Widget page;
if (widget.scrollController == null) {
page = Scaffold(
appBar: AppBar(
title: _PackageLicensePageTitle(title, subtitle, theme.primaryTextTheme),
),
body: Center(
child: Material(
color: theme.cardColor,
elevation: 4.0,
child: Container(
constraints: BoxConstraints.loose(const Size.fromWidth(600.0)),
child: Localizations.override(
locale: const Locale('en', 'US'),
context: context,
child: Scrollbar(
child: ListView(padding: padding, children: listWidgets),
),
),
),
),
),
);
} else {
page = CustomScrollView(
controller: widget.scrollController,
slivers: <Widget>[
SliverAppBar(
automaticallyImplyLeading: false,
pinned: true,
backgroundColor: theme.cardColor,
title: _PackageLicensePageTitle(title, subtitle, theme.textTheme),
),
SliverPadding(
padding: padding,
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) => Localizations.override(
locale: const Locale('en', 'US'),
context: context,
child: listWidgets[index],
),
childCount: listWidgets.length,
),
),
),
],
);
}
return DefaultTextStyle(
style: theme.textTheme.caption,
child: page,
);
}
}
class _PackageLicensePageTitle extends StatelessWidget {
const _PackageLicensePageTitle(
this.title,
this.subtitle,
this.theme, {
Key key,
}) : super(key: key);
final String title;
final String subtitle;
final TextTheme theme;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(title, style: theme.headline6),
Text(subtitle, style: theme.subtitle2),
],
);
}
}
......@@ -625,3 +1009,658 @@ Widget _defaultApplicationIcon(BuildContext context) {
// TODO(ianh): Get this from the embedder somehow.
return null;
}
const int _materialGutterThreshold = 720;
const double _wideGutterSize = 24.0;
const double _narrowGutterSize = 12.0;
double _getGutterSize(BuildContext context) =>
MediaQuery.of(context).size.width >= _materialGutterThreshold ? _wideGutterSize : _narrowGutterSize;
/// Signature for the builder callback used by [_MasterDetailFlow].
typedef _MasterViewBuilder = Widget Function(BuildContext context, bool isLateralUI);
/// Signature for the builder callback used by [_MasterDetailFlow.detailPageBuilder].
///
/// scrollController is provided when the page destination is the draggable
/// sheet in the lateral UI. Otherwise, it is null.
typedef _DetailPageBuilder = Widget Function(BuildContext context, Object arguments, ScrollController scrollController);
/// Signature for the builder callback used by [_MasterDetailFlow.actionBuilder].
///
/// Builds the actions that go in the app bars constructed for the master and
/// lateral UI pages. actionLevel indicates the intended destination of the
/// return actions.
typedef _ActionBuilder = List<Widget> Function(BuildContext context, _ActionLevel actionLevel);
/// Describes which type of app bar the actions are intended for.
enum _ActionLevel {
/// Indicates the top app bar in the lateral UI.
top,
/// Indicates the master view app bar in the lateral UI.
view,
/// Indicates the master page app bar in the nested UI.
composite,
}
/// Describes which layout will be used by [_MasterDetailFlow].
enum _LayoutMode {
/// Use a nested or lateral layout depending on available screen width.
auto,
/// Always use a lateral layout.
lateral,
/// Always use a nested layout.
nested,
}
const String _navMaster = 'master';
const String _navDetail = 'detail';
enum _Focus { master, detail }
/// A Master Detail Flow widget. Depending on screen width it builds either a
/// lateral or nested navigation flow between a master view and a detail page.
/// bloc pattern.
///
/// If focus is on detail view, then switching to nested navigation will
/// populate the navigation history with the master page and the detail page on
/// top. Otherwise the focus is on the master view and just the master page
/// is shown.
class _MasterDetailFlow extends StatefulWidget {
/// Creates a master detail navigation flow which is either nested or
/// lateral depending on screen width.
const _MasterDetailFlow({
Key key,
@required this.detailPageBuilder,
@required this.masterViewBuilder,
this.actionBuilder,
this.automaticallyImplyLeading = true,
this.breakpoint,
this.centerTitle,
this.detailPageFABGutterWidth,
this.detailPageFABlessGutterWidth,
this.displayMode = _LayoutMode.auto,
this.flexibleSpace,
this.floatingActionButton,
this.floatingActionButtonLocation,
this.floatingActionButtonMasterPageLocation,
this.leading,
this.masterPageBuilder,
this.masterViewWidth,
this.title,
}) : assert(masterViewBuilder != null),
assert(automaticallyImplyLeading != null),
assert(detailPageBuilder != null),
assert(displayMode != null),
super(key: key);
/// Builder for the master view for lateral navigation.
///
/// If [masterPageBuilder] is not supplied the master page required for nested navigation, also
/// builds the master view inside a [Scaffold] with an [AppBar].
final _MasterViewBuilder masterViewBuilder;
/// Builder for the master page for nested navigation.
///
/// This builder is usually a wrapper around the [masterViewBuilder] builder to provide the
/// extra UI required to make a page. However, this builder is optional, and the master page
/// can be built using the master view builder and the configuration for the lateral UI's app bar.
final _MasterViewBuilder masterPageBuilder;
/// Builder for the detail page.
///
/// If scrollController == null, the page is intended for nested navigation. The lateral detail
/// page is inside a [DraggableScrollableSheet] and should have a scrollable element that uses
/// the [ScrollController] provided. In fact, it is strongly recommended the entire lateral
/// page is scrollable.
final _DetailPageBuilder detailPageBuilder;
/// Override the width of the master view in the lateral UI.
final double masterViewWidth;
/// Override the width of the floating action button gutter in the lateral UI.
final double detailPageFABGutterWidth;
/// Override the width of the gutter when there is no floating action button.
final double detailPageFABlessGutterWidth;
/// Add a floating action button to the lateral UI. If no [masterPageBuilder] is supplied, this
/// floating action button is also used on the nested master page.
///
/// See [Scaffold.floatingActionButton].
final FloatingActionButton floatingActionButton;
/// The title for the lateral UI [AppBar].
///
/// See [AppBar.title].
final Widget title;
/// A widget to display before the title for the lateral UI [AppBar].
///
/// See [AppBar.leading].
final Widget leading;
/// Override the framework from determining whether to show a leading widget or not.
///
/// See [AppBar.automaticallyImplyLeading].
final bool automaticallyImplyLeading;
/// Override the framework from determining whether to display the title in the centre of the
/// app bar or not.
///
/// See [AppBar.centerTitle].
final bool centerTitle;
/// See [AppBar.flexibleSpace].
final Widget flexibleSpace;
/// Build actions for the lateral UI, and potentially the master page in the nested UI.
///
/// If level is [_ActionLevel.top] then the actions are for
/// the entire lateral UI page. If level is [_ActionLevel.view] the actions
/// are for the master
/// view toolbar. Finally, if the [AppBar] for the master page for the nested UI is being built
/// by [_MasterDetailFlow], then [_ActionLevel.composite] indicates the
/// actions are for the
/// nested master page.
final _ActionBuilder actionBuilder;
/// Determine where the floating action button will go.
///
/// If null, [FloatingActionButtonLocation.endTop] is used.
///
/// Also see [Scaffold.floatingActionButtonLocation].
final FloatingActionButtonLocation floatingActionButtonLocation;
/// Determine where the floating action button will go on the master page.
///
/// See [Scaffold.floatingActionButtonLocation].
final FloatingActionButtonLocation floatingActionButtonMasterPageLocation;
/// Forces display mode and style.
final _LayoutMode displayMode;
/// Width at which layout changes from nested to lateral.
final double breakpoint;
@override
_MasterDetailFlowState createState() => _MasterDetailFlowState();
/// The master detail flow proxy from the closest instance of this class that encloses the given
/// context.
///
/// Typical usage is as follows:
///
/// ```dart
/// _MasterDetailFlow.of(context).openDetailPage(arguments);
/// ```
static _MasterDetailFlowProxy of(
BuildContext context, {
bool nullOk = false,
}) {
_PageOpener pageOpener = context.findAncestorStateOfType<_MasterDetailScaffoldState>();
pageOpener ??= context.findAncestorStateOfType<_MasterDetailFlowState>();
assert(() {
if (pageOpener == null && !nullOk) {
throw FlutterError(
'Master Detail operation requested with a context that does not include a Master Detail'
' Flow.\nThe context used to open a detail page from the Master Detail Flow must be'
' that of a widget that is a descendant of a Master Detail Flow widget.');
}
return true;
}());
return pageOpener != null ? _MasterDetailFlowProxy._(pageOpener) : null;
}
}
/// Interface for interacting with the [_MasterDetailFlow].
class _MasterDetailFlowProxy implements _PageOpener {
_MasterDetailFlowProxy._(this._pageOpener);
final _PageOpener _pageOpener;
/// Open detail page with arguments.
@override
void openDetailPage(Object arguments) =>
_pageOpener.openDetailPage(arguments);
/// Set the initial page to be open for the lateral layout. This can be set at any time, but
/// will have no effect after any calls to openDetailPage.
@override
void setInitialDetailPage(Object arguments) =>
_pageOpener.setInitialDetailPage(arguments);
}
abstract class _PageOpener {
void openDetailPage(Object arguments);
void setInitialDetailPage(Object arguments);
}
const int _materialWideDisplayThreshold = 840;
class _MasterDetailFlowState extends State<_MasterDetailFlow> implements _PageOpener {
/// Tracks whether focus is on the detail or master views. Determines behaviour when switching
/// from lateral to nested navigation.
_Focus focus = _Focus.master;
/// Cache of arguments passed when opening a detail page. Used when rebuilding.
Object _cachedDetailArguments;
/// Record of the layout that was built.
_LayoutMode _builtLayout;
/// Key to access navigator in the nested layout.
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
@override
void openDetailPage(Object arguments) {
_cachedDetailArguments = arguments;
if (_builtLayout == _LayoutMode.nested) {
_navigatorKey.currentState.pushNamed(_navDetail, arguments: arguments);
} else {
focus = _Focus.detail;
}
}
@override
void setInitialDetailPage(Object arguments) {
_cachedDetailArguments = arguments;
}
@override
Widget build(BuildContext context) {
switch (widget.displayMode) {
case _LayoutMode.nested:
return _nestedUI(context);
case _LayoutMode.lateral:
return _lateralUI(context);
case _LayoutMode.auto:
default:
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final double availableWidth = constraints.maxWidth;
if (availableWidth >= (widget.breakpoint ?? _materialWideDisplayThreshold)) {
return _lateralUI(context);
} else {
return _nestedUI(context);
}
});
}
}
Widget _nestedUI(BuildContext context) {
_builtLayout = _LayoutMode.nested;
final MaterialPageRoute<void> masterPageRoute = _masterPageRoute(context);
return WillPopScope(
// Push pop check into nested navigator.
onWillPop: () async => !(await _navigatorKey.currentState.maybePop()),
child: Navigator(
key: _navigatorKey,
initialRoute: 'initial',
onGenerateInitialRoutes: (NavigatorState navigator, String initialRoute) {
switch (focus) {
case _Focus.master:
return <Route<void>>[masterPageRoute];
case _Focus.detail:
default:
return <Route<void>>[
masterPageRoute,
_detailPageRoute(_cachedDetailArguments)
];
}
},
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case _navMaster:
// Matching state to navigation event.
focus = _Focus.master;
return masterPageRoute;
case _navDetail:
// Matching state to navigation event.
focus = _Focus.detail;
// Cache detail page settings.
_cachedDetailArguments = settings.arguments;
return _detailPageRoute(_cachedDetailArguments);
default:
throw Exception('Unknown route ${settings.name}');
}
},
),
);
}
MaterialPageRoute<void> _masterPageRoute(BuildContext context) {
return MaterialPageRoute<dynamic>(
builder: (BuildContext c) => BlockSemantics(
child: widget.masterPageBuilder != null
? widget.masterPageBuilder(c, false)
: _MasterPage(
leading: widget.leading ??
(widget.automaticallyImplyLeading && Navigator.of(context).canPop()
? BackButton(onPressed: () => Navigator.of(context).pop())
: null),
title: widget.title,
centerTitle: widget.centerTitle,
flexibleSpace: widget.flexibleSpace,
automaticallyImplyLeading: widget.automaticallyImplyLeading,
floatingActionButton: widget.floatingActionButton,
floatingActionButtonLocation: widget.floatingActionButtonMasterPageLocation,
masterViewBuilder: widget.masterViewBuilder,
actionBuilder: widget.actionBuilder,
),
),
);
}
MaterialPageRoute<void> _detailPageRoute(Object arguments) {
return MaterialPageRoute<dynamic>(builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
// No need for setState() as rebuild happens on navigation pop.
focus = _Focus.master;
Navigator.of(context).pop();
return false;
},
child: BlockSemantics(child: widget.detailPageBuilder(context, arguments, null)),
);
});
}
Widget _lateralUI(BuildContext context) {
_builtLayout = _LayoutMode.lateral;
return _MasterDetailScaffold(
actionBuilder: widget.actionBuilder ?? (_, __) => const<Widget>[],
automaticallyImplyLeading: widget.automaticallyImplyLeading,
centerTitle: widget.centerTitle,
detailPageBuilder: (BuildContext context, Object args, ScrollController scrollController) =>
widget.detailPageBuilder(context, args ?? _cachedDetailArguments, scrollController),
floatingActionButton: widget.floatingActionButton,
detailPageFABlessGutterWidth: widget.detailPageFABlessGutterWidth,
detailPageFABGutterWidth: widget.detailPageFABGutterWidth,
floatingActionButtonLocation: widget.floatingActionButtonLocation,
initialArguments: _cachedDetailArguments,
leading: widget.leading,
masterViewBuilder: (BuildContext context, bool isLateral) => widget.masterViewBuilder(context, isLateral),
masterViewWidth: widget.masterViewWidth,
title: widget.title,
);
}
}
class _MasterPage extends StatelessWidget {
const _MasterPage({
Key key,
this.leading,
this.title,
this.actionBuilder,
this.centerTitle,
this.flexibleSpace,
this.floatingActionButton,
this.floatingActionButtonLocation,
this.masterViewBuilder,
this.automaticallyImplyLeading,
}) : super(key: key);
final _MasterViewBuilder masterViewBuilder;
final Widget title;
final Widget leading;
final bool automaticallyImplyLeading;
final bool centerTitle;
final Widget flexibleSpace;
final _ActionBuilder actionBuilder;
final FloatingActionButton floatingActionButton;
final FloatingActionButtonLocation floatingActionButtonLocation;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: title,
leading: leading,
actions: actionBuilder == null
? const <Widget>[]
: actionBuilder(context, _ActionLevel.composite),
centerTitle: centerTitle,
flexibleSpace: flexibleSpace,
automaticallyImplyLeading: automaticallyImplyLeading,
),
body: masterViewBuilder(context, false),
floatingActionButton: floatingActionButton,
floatingActionButtonLocation: floatingActionButtonLocation,
);
}
}
const double _kCardElevation = 4.0;
const double _kMasterViewWidth = 320.0;
const double _kDetailPageFABlessGutterWidth = 40.0;
const double _kDetailPageFABGutterWidth = 84.0;
class _MasterDetailScaffold extends StatefulWidget {
const _MasterDetailScaffold({
Key key,
@required this.detailPageBuilder,
@required this.masterViewBuilder,
this.actionBuilder,
this.floatingActionButton,
this.floatingActionButtonLocation,
this.initialArguments,
this.leading,
this.title,
this.automaticallyImplyLeading,
this.centerTitle,
this.detailPageFABlessGutterWidth,
this.detailPageFABGutterWidth,
this.masterViewWidth,
}) : assert(detailPageBuilder != null),
assert(masterViewBuilder != null),
super(key: key);
final _MasterViewBuilder masterViewBuilder;
/// Builder for the detail page.
///
/// The detail page is inside a [DraggableScrollableSheet] and should have a scrollable element
/// that uses the [ScrollController] provided. In fact, it is strongly recommended the entire
/// lateral page is scrollable.
final _DetailPageBuilder detailPageBuilder;
final _ActionBuilder actionBuilder;
final FloatingActionButton floatingActionButton;
final FloatingActionButtonLocation floatingActionButtonLocation;
final Object initialArguments;
final Widget leading;
final Widget title;
final bool automaticallyImplyLeading;
final bool centerTitle;
final double detailPageFABlessGutterWidth;
final double detailPageFABGutterWidth;
final double masterViewWidth;
@override
_MasterDetailScaffoldState createState() => _MasterDetailScaffoldState();
}
class _MasterDetailScaffoldState extends State<_MasterDetailScaffold>
implements _PageOpener {
FloatingActionButtonLocation floatingActionButtonLocation;
double detailPageFABGutterWidth;
double detailPageFABlessGutterWidth;
double masterViewWidth;
final ValueNotifier<Object> _detailArguments = ValueNotifier<Object>(null);
@override
void initState() {
super.initState();
detailPageFABlessGutterWidth = widget.detailPageFABlessGutterWidth ?? _kDetailPageFABlessGutterWidth;
detailPageFABGutterWidth = widget.detailPageFABGutterWidth ?? _kDetailPageFABGutterWidth;
masterViewWidth = widget.masterViewWidth ?? _kMasterViewWidth;
floatingActionButtonLocation = widget.floatingActionButtonLocation ?? FloatingActionButtonLocation.endTop;
}
@override
void openDetailPage(Object arguments) {
SchedulerBinding.instance
.addPostFrameCallback((_) => _detailArguments.value = arguments);
_MasterDetailFlow.of(context).openDetailPage(arguments);
}
@override
void setInitialDetailPage(Object arguments) {
SchedulerBinding.instance
.addPostFrameCallback((_) => _detailArguments.value = arguments);
_MasterDetailFlow.of(context).setInitialDetailPage(arguments);
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Scaffold(
floatingActionButtonLocation: floatingActionButtonLocation,
appBar: AppBar(
title: widget.title,
actions: widget.actionBuilder(context, _ActionLevel.top),
leading: widget.leading,
automaticallyImplyLeading: widget.automaticallyImplyLeading,
centerTitle: widget.centerTitle,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(kToolbarHeight),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
ConstrainedBox(
constraints:
BoxConstraints.tightFor(width: masterViewWidth),
child: IconTheme(
data: Theme.of(context).primaryIconTheme,
child: ButtonBar(
children:
widget.actionBuilder(context, _ActionLevel.view),
),
),
)
],
),
),
),
body: _masterPanel(context),
floatingActionButton: widget.floatingActionButton,
),
// Detail view stacked above main scaffold and master view.
SafeArea(
child: Padding(
padding: EdgeInsetsDirectional.only(
start: masterViewWidth - _kCardElevation,
end: widget.floatingActionButton == null
? detailPageFABlessGutterWidth
: detailPageFABGutterWidth,
),
child: ValueListenableBuilder<Object>(
valueListenable: _detailArguments,
builder: (BuildContext context, Object value, Widget child) {
return AnimatedSwitcher(
transitionBuilder:
(Widget child, Animation<double> animation) =>
const FadeUpwardsPageTransitionsBuilder()
.buildTransitions<void>(
null, null, animation, null, child),
duration: const Duration(milliseconds: 500),
child: Container(
key: ValueKey<Object>(value ?? widget.initialArguments),
constraints: const BoxConstraints.expand(),
child: _DetailView(
builder: widget.detailPageBuilder,
arguments: value ?? widget.initialArguments,
),
),
);
},
),
),
),
],
);
}
ConstrainedBox _masterPanel(BuildContext context, {bool needsScaffold = false}) {
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: masterViewWidth),
child: needsScaffold
? Scaffold(
appBar: AppBar(
title: widget.title,
actions: widget.actionBuilder(context, _ActionLevel.top),
leading: widget.leading,
automaticallyImplyLeading: widget.automaticallyImplyLeading,
centerTitle: widget.centerTitle,
),
body: widget.masterViewBuilder(context, true),
)
: widget.masterViewBuilder(context, true),
);
}
}
class _DetailView extends StatelessWidget {
const _DetailView({
Key key,
@required _DetailPageBuilder builder,
Object arguments,
}) : assert(builder != null),
_builder = builder,
_arguments = arguments,
super(key: key);
final _DetailPageBuilder _builder;
final Object _arguments;
@override
Widget build(BuildContext context) {
if (_arguments == null) {
return Container();
}
final double screenHeight = MediaQuery.of(context).size.height;
final double minHeight = (screenHeight - kToolbarHeight) / screenHeight;
return GestureDetector(
onTap: () {
print('draggable');
},
behavior: HitTestBehavior.deferToChild,
child: DraggableScrollableSheet(
initialChildSize: minHeight,
minChildSize: minHeight,
maxChildSize: 1,
expand: false,
builder: (BuildContext context, ScrollController controller) {
return MouseRegion(
// TODO(TonicArtos): Remove MouseRegion workaround for pointer hover events passing through DraggableScrollableSheet once https://github.com/flutter/flutter/issues/59741 is resolved.
child: Card(
color: Theme.of(context).cardColor,
elevation: _kCardElevation,
clipBehavior: Clip.antiAlias,
margin: const EdgeInsets.fromLTRB(
_kCardElevation, 0.0, _kCardElevation, 0.0),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(3.0), bottom: Radius.zero),
),
child: _builder(
context,
_arguments,
controller,
),
),
);
},
),
);
}
}
......@@ -122,6 +122,9 @@ abstract class MaterialLocalizations {
/// Title for the [LicensePage] widget.
String get licensesPageTitle;
/// Subtitle for a package in the [LicensePage] widget.
String licensesPackageDetailText(int licenseCount);
/// Title for the [PaginatedDataTable]'s row info footer.
String pageRowsInfoTitle(int firstRow, int lastRow, int rowCount, bool rowCountIsApproximate);
......@@ -860,6 +863,17 @@ class DefaultMaterialLocalizations implements MaterialLocalizations {
@override
String get licensesPageTitle => 'Licenses';
@override
String licensesPackageDetailText(int licenseCount) {
assert (licenseCount >= 1);
switch (licenseCount) {
case 1:
return '1 license';
default:
return '$licenseCount licenses';
}
}
@override
String pageRowsInfoTitle(int firstRow, int lastRow, int rowCount, bool rowCountIsApproximate) {
return rowCountIsApproximate
......
......@@ -92,6 +92,8 @@ void main() {
find.text('I am the very model of a modern major general.'),
findsOneWidget,
);
await tester.tap(find.text('Pirate package '));
await tester.pumpAndSettle(const Duration(milliseconds: 100));
expect(find.text('Pirate license'), findsOneWidget);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/54385
......@@ -136,9 +138,23 @@ void main() {
await tester.pumpAndSettle();
// Check for packages.
expect(find.text('AAA'), findsOneWidget);
expect(find.text('BBB'), findsOneWidget);
expect(find.text('Another package'), findsOneWidget);
// Check license is displayed after entering into license page for 'AAA'.
await tester.tap(find.text('AAA'));
await tester.pumpAndSettle(const Duration(milliseconds: 100));
expect(find.text('BBB'), findsOneWidget);
/// Go back to list of packages.
await tester.pageBack();
await tester.pumpAndSettle();
/// Check license is displayed after entering into license page for
/// 'Another package'.
await tester.tap(find.text('Another package'));
await tester.pumpAndSettle(const Duration(milliseconds: 100));
expect(find.text('Another license'), findsOneWidget);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/54385
......@@ -197,9 +213,24 @@ void main() {
find.text('I am the very model of a modern major general.'),
findsOneWidget,
);
// Check for packages.
expect(find.text('AAA'), findsOneWidget);
expect(find.text('BBB'), findsOneWidget);
expect(find.text('Another package'), findsOneWidget);
// Check license is displayed after entering into license page for 'AAA'.
await tester.tap(find.text('AAA'));
await tester.pumpAndSettle(const Duration(milliseconds: 100));
expect(find.text('BBB'), findsOneWidget);
/// Go back to list of packages.
await tester.pageBack();
await tester.pumpAndSettle();
/// Check license is displayed after entering into license page for
/// 'Another package'.
await tester.tap(find.text('Another package'));
await tester.pumpAndSettle(const Duration(milliseconds: 100));
expect(find.text('Another license'), findsOneWidget);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/54385
......@@ -225,7 +256,12 @@ void main() {
await tester.pumpAndSettle();
expect(tester.getTopLeft(find.text('DEF')), const Offset(8.0 + safeareaPadding, 287.0));
// The position of the top left of app bar title should indicate whether
// the safe area is sufficiently respected.
expect(
tester.getTopLeft(find.text('Licenses')),
const Offset(16.0 + safeareaPadding, 18.0 + safeareaPadding),
);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/54385
testWidgets('LicensePage returns early if unmounted', (WidgetTester tester) async {
......@@ -250,7 +286,7 @@ void main() {
await tester.pumpAndSettle();
final FakeLicenseEntry licenseEntry = FakeLicenseEntry();
licenseCompleter.complete(licenseEntry);
expect(licenseEntry.paragraphsCalled, false);
expect(licenseEntry.packagesCalled, false);
});
testWidgets('LicensePage returns late if unmounted', (WidgetTester tester) async {
......@@ -275,7 +311,7 @@ void main() {
);
await tester.pumpAndSettle();
expect(licenseEntry.paragraphsCalled, true);
expect(licenseEntry.packagesCalled, true);
});
testWidgets('LicensePage logic defaults to executable name for app name', (WidgetTester tester) async {
......@@ -524,16 +560,16 @@ void main() {
class FakeLicenseEntry extends LicenseEntry {
FakeLicenseEntry();
bool get paragraphsCalled => _paragraphsCalled;
bool _paragraphsCalled = false;
bool get packagesCalled => _packagesCalled;
bool _packagesCalled = false;
@override
Iterable<String> packages = <String>[];
Iterable<LicenseParagraph> paragraphs = <LicenseParagraph>[];
@override
Iterable<LicenseParagraph> get paragraphs {
_paragraphsCalled = true;
return <LicenseParagraph>[];
Iterable<String> get packages {
_packagesCalled = true;
return <String>[];
}
}
......
......@@ -88,5 +88,13 @@ void main() {
expect(localizations.pageRowsInfoTitle(1, 10, 100, false).contains(r'$firstRow'), isFalse);
expect(localizations.pageRowsInfoTitle(1, 10, 100, false).contains(r'$lastRow'), isFalse);
expect(localizations.pageRowsInfoTitle(1, 10, 100, false).contains(r'$rowCount'), isFalse);
expect(() => localizations.licensesPackageDetailText(0), throwsAssertionError);
expect(localizations.licensesPackageDetailText(1), isNotNull);
expect(localizations.licensesPackageDetailText(2), isNotNull);
expect(localizations.licensesPackageDetailText(100), isNotNull);
expect(localizations.licensesPackageDetailText(1).contains(r'$licensesCount'), isFalse);
expect(localizations.licensesPackageDetailText(2).contains(r'$licensesCount'), isFalse);
expect(localizations.licensesPackageDetailText(100).contains(r'$licensesCount'), isFalse);
});
}
......@@ -140,6 +140,12 @@ class MaterialLocalizationAf extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lisensies';
......@@ -407,6 +413,12 @@ class MaterialLocalizationAm extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'ፈቃዶች';
......@@ -674,6 +686,12 @@ class MaterialLocalizationAr extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'التراخيص';
......@@ -941,6 +959,12 @@ class MaterialLocalizationAs extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'অনুজ্ঞাপত্ৰসমূহ';
......@@ -1208,6 +1232,12 @@ class MaterialLocalizationAz extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lisenziyalar';
......@@ -1475,6 +1505,12 @@ class MaterialLocalizationBe extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Ліцэнзіі';
......@@ -1742,6 +1778,12 @@ class MaterialLocalizationBg extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Лицензи';
......@@ -2009,6 +2051,12 @@ class MaterialLocalizationBn extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'লাইসেন্স';
......@@ -2276,6 +2324,12 @@ class MaterialLocalizationBs extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licence';
......@@ -2543,6 +2597,12 @@ class MaterialLocalizationCa extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Llicències';
......@@ -2810,6 +2870,12 @@ class MaterialLocalizationCs extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licence';
......@@ -3077,6 +3143,12 @@ class MaterialLocalizationDa extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licenser';
......@@ -3344,6 +3416,12 @@ class MaterialLocalizationDe extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lizenzen';
......@@ -3647,6 +3725,12 @@ class MaterialLocalizationEl extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Άδειες';
......@@ -3914,6 +3998,12 @@ class MaterialLocalizationEn extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licenses';
......@@ -4094,6 +4184,12 @@ class MaterialLocalizationEnAu extends MaterialLocalizationEn {
@override
String get licensesPageTitle => 'Licences';
@override
String get licensesPackageDetailTextOne => '1 licence';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licences';
@override
String get copyButtonLabel => 'COPY';
......@@ -4154,6 +4250,12 @@ class MaterialLocalizationEnCa extends MaterialLocalizationEn {
@override
String get licensesPageTitle => 'Licences';
@override
String get licensesPackageDetailTextOne => '1 licence';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licences';
@override
String get copyButtonLabel => 'COPY';
......@@ -4226,6 +4328,12 @@ class MaterialLocalizationEnGb extends MaterialLocalizationEn {
@override
String get licensesPageTitle => 'Licences';
@override
String get licensesPackageDetailTextOne => '1 licence';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licences';
@override
String get pasteButtonLabel => 'PASTE';
......@@ -4289,6 +4397,12 @@ class MaterialLocalizationEnIe extends MaterialLocalizationEn {
@override
String get licensesPageTitle => 'Licences';
@override
String get licensesPackageDetailTextOne => '1 licence';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licences';
@override
String get pasteButtonLabel => 'PASTE';
......@@ -4340,6 +4454,12 @@ class MaterialLocalizationEnIn extends MaterialLocalizationEn {
@override
String get licensesPageTitle => 'Licences';
@override
String get licensesPackageDetailTextOne => '1 licence';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licences';
@override
String get copyButtonLabel => 'COPY';
......@@ -4400,6 +4520,12 @@ class MaterialLocalizationEnNz extends MaterialLocalizationEn {
@override
String get licensesPageTitle => 'Licences';
@override
String get licensesPackageDetailTextOne => '1 licence';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licences';
@override
String get copyButtonLabel => 'COPY';
......@@ -4460,6 +4586,12 @@ class MaterialLocalizationEnSg extends MaterialLocalizationEn {
@override
String get licensesPageTitle => 'Licences';
@override
String get licensesPackageDetailTextOne => '1 licence';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licences';
@override
String get copyButtonLabel => 'COPY';
......@@ -4532,6 +4664,12 @@ class MaterialLocalizationEnZa extends MaterialLocalizationEn {
@override
String get licensesPageTitle => 'Licences';
@override
String get licensesPackageDetailTextOne => '1 licence';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licences';
@override
String get pasteButtonLabel => 'PASTE';
......@@ -4670,6 +4808,12 @@ class MaterialLocalizationEs extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licencias';
......@@ -6620,6 +6764,12 @@ class MaterialLocalizationEt extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Litsentsid';
......@@ -6887,6 +7037,12 @@ class MaterialLocalizationEu extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lizentziak';
......@@ -7154,6 +7310,12 @@ class MaterialLocalizationFa extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'مجوزها';
......@@ -7421,6 +7583,12 @@ class MaterialLocalizationFi extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lisenssit';
......@@ -7688,6 +7856,12 @@ class MaterialLocalizationFil extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Mga Lisensya';
......@@ -7955,6 +8129,12 @@ class MaterialLocalizationFr extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licences';
......@@ -8282,6 +8462,12 @@ class MaterialLocalizationGl extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licenzas';
......@@ -8549,6 +8735,12 @@ class MaterialLocalizationGsw extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lizenzen';
......@@ -8816,6 +9008,12 @@ class MaterialLocalizationGu extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'લાઇસન્સ';
......@@ -9083,6 +9281,12 @@ class MaterialLocalizationHe extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'רישיונות';
......@@ -9350,6 +9554,12 @@ class MaterialLocalizationHi extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'लाइसेंस';
......@@ -9617,6 +9827,12 @@ class MaterialLocalizationHr extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licence';
......@@ -9884,6 +10100,12 @@ class MaterialLocalizationHu extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licencek';
......@@ -10151,6 +10373,12 @@ class MaterialLocalizationHy extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Արտոնագրեր';
......@@ -10418,6 +10646,12 @@ class MaterialLocalizationId extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lisensi';
......@@ -10685,6 +10919,12 @@ class MaterialLocalizationIs extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Leyfi';
......@@ -10952,6 +11192,12 @@ class MaterialLocalizationIt extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licenze';
......@@ -11219,6 +11465,12 @@ class MaterialLocalizationJa extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'ライセンス';
......@@ -11486,6 +11738,12 @@ class MaterialLocalizationKa extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'ლიცენზიები';
......@@ -11753,6 +12011,12 @@ class MaterialLocalizationKk extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Лицензиялар';
......@@ -12020,6 +12284,12 @@ class MaterialLocalizationKm extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'អាជ្ញាបណ្ណ';
......@@ -12287,6 +12557,12 @@ class MaterialLocalizationKn extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => '\u{caa}\u{cb0}\u{cb5}\u{cbe}\u{ca8}\u{c97}\u{cbf}\u{c97}\u{cb3}\u{cc1}';
......@@ -12554,6 +12830,12 @@ class MaterialLocalizationKo extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => '라이선스';
......@@ -12821,6 +13103,12 @@ class MaterialLocalizationKy extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Уруксаттамалар';
......@@ -13088,6 +13376,12 @@ class MaterialLocalizationLo extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'ໃບອະນຸຍາດ';
......@@ -13355,6 +13649,12 @@ class MaterialLocalizationLt extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licencijos';
......@@ -13622,6 +13922,12 @@ class MaterialLocalizationLv extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licences';
......@@ -13889,6 +14195,12 @@ class MaterialLocalizationMk extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Лиценци';
......@@ -14156,6 +14468,12 @@ class MaterialLocalizationMl extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'ലൈസൻസുകൾ';
......@@ -14423,6 +14741,12 @@ class MaterialLocalizationMn extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Лиценз';
......@@ -14690,6 +15014,12 @@ class MaterialLocalizationMr extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'परवाने';
......@@ -14957,6 +15287,12 @@ class MaterialLocalizationMs extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lesen';
......@@ -15224,6 +15560,12 @@ class MaterialLocalizationMy extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'လိုင်စင်များ';
......@@ -15521,6 +15863,12 @@ class MaterialLocalizationNe extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'इजाजतपत्रहरू';
......@@ -15788,6 +16136,12 @@ class MaterialLocalizationNl extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licenties';
......@@ -16055,6 +16409,12 @@ class MaterialLocalizationNo extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lisenser';
......@@ -16322,6 +16682,12 @@ class MaterialLocalizationOr extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'ଲାଇସେନ୍ସଗୁଡ଼କ';
......@@ -16589,6 +16955,12 @@ class MaterialLocalizationPa extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'ਲਾਇਸੰਸ';
......@@ -16856,6 +17228,12 @@ class MaterialLocalizationPl extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licencje';
......@@ -17123,6 +17501,12 @@ class MaterialLocalizationPs extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'جوازونه';
......@@ -17390,6 +17774,12 @@ class MaterialLocalizationPt extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licenças';
......@@ -17741,6 +18131,12 @@ class MaterialLocalizationRo extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licențe';
......@@ -18008,6 +18404,12 @@ class MaterialLocalizationRu extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Лицензии';
......@@ -18275,6 +18677,12 @@ class MaterialLocalizationSi extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'බලපත්‍ර';
......@@ -18542,6 +18950,12 @@ class MaterialLocalizationSk extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licencie';
......@@ -18809,6 +19223,12 @@ class MaterialLocalizationSl extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licence';
......@@ -19076,6 +19496,12 @@ class MaterialLocalizationSq extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licencat';
......@@ -19343,6 +19769,12 @@ class MaterialLocalizationSr extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Лиценце';
......@@ -19829,6 +20261,12 @@ class MaterialLocalizationSv extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Licenser';
......@@ -20096,6 +20534,12 @@ class MaterialLocalizationSw extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Leseni';
......@@ -20363,6 +20807,12 @@ class MaterialLocalizationTa extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'உரிமங்கள்';
......@@ -20630,6 +21080,12 @@ class MaterialLocalizationTe extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'లైసెన్స్‌లు';
......@@ -20897,6 +21353,12 @@ class MaterialLocalizationTh extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'ใบอนุญาต';
......@@ -21164,6 +21626,12 @@ class MaterialLocalizationTl extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Mga Lisensya';
......@@ -21431,6 +21899,12 @@ class MaterialLocalizationTr extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Lisanslar';
......@@ -21698,6 +22172,12 @@ class MaterialLocalizationUk extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Ліцензії';
......@@ -21965,6 +22445,12 @@ class MaterialLocalizationUr extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'لائسنسز';
......@@ -22232,6 +22718,12 @@ class MaterialLocalizationUz extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Litsenziyalar';
......@@ -22499,6 +22991,12 @@ class MaterialLocalizationVi extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Giấy phép';
......@@ -22766,6 +23264,12 @@ class MaterialLocalizationZh extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => '许可';
......@@ -23330,6 +23834,12 @@ class MaterialLocalizationZu extends GlobalMaterialLocalizations {
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get licensesPackageDetailTextOne => '1 license';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get licensesPageTitle => 'Amalayisense';
......
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -77,5 +77,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -73,5 +73,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -72,5 +72,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -74,5 +74,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -72,6 +72,13 @@
"description": "The title for the Flutter licenses page."
},
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses",
"@licensesPackageDetailText": {
"description": "The subtitle and detail text for a package displayed on the Flutter licenses page. The value of $licenseCount is an integer which indicates the number of licenses the package has. A zero value is not allowed.",
"plural": "licenseCount"
},
"pageRowsInfoTitle": "$firstRow–$lastRow of $rowCount",
"@pageRowsInfoTitle": {
"description": "The text shown in the footer of a paginated data table when the exact overall row count is known. This message describes an integer range where $firstRow is the index of the start of the range, $lastRow is the index of the end of the range, and $rowCount is the limit of the range. All values are greater than or equal to zero.",
......
......@@ -19,6 +19,8 @@
"showMenuTooltip": "Show menu",
"aboutListTileTitle": "About $applicationName",
"licensesPageTitle": "Licences",
"licensesPackageDetailTextOne": "1 licence",
"licensesPackageDetailTextOther": "$licenseCount licences",
"pageRowsInfoTitle": "$firstRow–$lastRow of $rowCount",
"pageRowsInfoTitleApproximate": "$firstRow–$lastRow of about $rowCount",
"rowsPerPageTitle": "Rows per page:",
......
......@@ -19,6 +19,8 @@
"showMenuTooltip": "Show menu",
"aboutListTileTitle": "About $applicationName",
"licensesPageTitle": "Licences",
"licensesPackageDetailTextOne": "1 licence",
"licensesPackageDetailTextOther": "$licenseCount licences",
"pageRowsInfoTitle": "$firstRow–$lastRow of $rowCount",
"pageRowsInfoTitleApproximate": "$firstRow–$lastRow of about $rowCount",
"rowsPerPageTitle": "Rows per page:",
......
......@@ -19,6 +19,8 @@
"aboutListTileTitle": "About $applicationName",
"backButtonTooltip": "Back",
"licensesPageTitle": "Licences",
"licensesPackageDetailTextOne": "1 licence",
"licensesPackageDetailTextOther": "$licenseCount licences",
"okButtonLabel": "OK",
"pasteButtonLabel": "PASTE",
"previousMonthTooltip": "Previous month",
......
......@@ -19,6 +19,8 @@
"aboutListTileTitle": "About $applicationName",
"backButtonTooltip": "Back",
"licensesPageTitle": "Licences",
"licensesPackageDetailTextOne": "1 licence",
"licensesPackageDetailTextOther": "$licenseCount licences",
"okButtonLabel": "OK",
"pasteButtonLabel": "PASTE",
"previousMonthTooltip": "Previous month",
......
......@@ -19,6 +19,8 @@
"showMenuTooltip": "Show menu",
"aboutListTileTitle": "About $applicationName",
"licensesPageTitle": "Licences",
"licensesPackageDetailTextOne": "1 licence",
"licensesPackageDetailTextOther": "$licenseCount licences",
"pageRowsInfoTitle": "$firstRow–$lastRow of $rowCount",
"pageRowsInfoTitleApproximate": "$firstRow–$lastRow of about $rowCount",
"rowsPerPageTitle": "Rows per page:",
......
......@@ -13,6 +13,8 @@
"showMenuTooltip": "Show menu",
"aboutListTileTitle": "About $applicationName",
"licensesPageTitle": "Licences",
"licensesPackageDetailTextOne": "1 licence",
"licensesPackageDetailTextOther": "$licenseCount licences",
"pageRowsInfoTitle": "$firstRow–$lastRow of $rowCount",
"pageRowsInfoTitleApproximate": "$firstRow–$lastRow of about $rowCount",
"rowsPerPageTitle": "Rows per page:",
......
......@@ -19,6 +19,8 @@
"showMenuTooltip": "Show menu",
"aboutListTileTitle": "About $applicationName",
"licensesPageTitle": "Licences",
"licensesPackageDetailTextOne": "1 licence",
"licensesPackageDetailTextOther": "$licenseCount licences",
"pageRowsInfoTitle": "$firstRow–$lastRow of $rowCount",
"pageRowsInfoTitleApproximate": "$firstRow–$lastRow of about $rowCount",
"rowsPerPageTitle": "Rows per page:",
......
......@@ -19,6 +19,8 @@
"aboutListTileTitle": "About $applicationName",
"backButtonTooltip": "Back",
"licensesPageTitle": "Licences",
"licensesPackageDetailTextOne": "1 licence",
"licensesPackageDetailTextOther": "$licenseCount licences",
"okButtonLabel": "OK",
"pasteButtonLabel": "PASTE",
"previousMonthTooltip": "Previous month",
......
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -74,5 +74,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -72,5 +72,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -75,5 +75,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0044\u0041\u0054\u0045",
"dateRangePickerHelpText": "\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0052\u0041\u004e\u0047\u0045",
"calendarModeButtonLabel": "\u0053\u0077\u0069\u0074\u0063\u0068\u0020\u0074\u006f\u0020\u0063\u0061\u006c\u0065\u006e\u0064\u0061\u0072",
"inputDateModeButtonLabel": "\u0053\u0077\u0069\u0074\u0063\u0068\u0020\u0074\u006f\u0020\u0069\u006e\u0070\u0075\u0074"
"inputDateModeButtonLabel": "\u0053\u0077\u0069\u0074\u0063\u0068\u0020\u0074\u006f\u0020\u0069\u006e\u0070\u0075\u0074",
"licensesPackageDetailTextOne": "\u0031\u0020\u006c\u0069\u0063\u0065\u006e\u0073\u0065",
"licensesPackageDetailTextOther": "\u0024\u006c\u0069\u0063\u0065\u006e\u0073\u0065\u0043\u006f\u0075\u006e\u0074\u0020\u006c\u0069\u0063\u0065\u006e\u0073\u0065\u0073"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -74,5 +74,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -74,5 +74,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -72,5 +72,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -73,5 +73,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -75,5 +75,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -74,5 +74,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -74,5 +74,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -72,5 +72,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -71,5 +71,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -74,5 +74,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -70,5 +70,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -69,5 +69,7 @@
"datePickerHelpText": "SELECT DATE",
"dateRangePickerHelpText": "SELECT RANGE",
"calendarModeButtonLabel": "Switch to calendar",
"inputDateModeButtonLabel": "Switch to input"
"inputDateModeButtonLabel": "Switch to input",
"licensesPackageDetailTextOne": "1 license",
"licensesPackageDetailTextOther": "$licenseCount licenses"
}
......@@ -446,6 +446,115 @@ abstract class GlobalMaterialLocalizations implements MaterialLocalizations {
return timeOfDayFormatRaw;
}
/// The "zero" form of [licensesPackageDetailText].
///
/// This form is optional.
///
/// See also:
///
/// * [Intl.plural], to which this form is passed.
/// * [licensesPackageDetailTextZero], the "zero" form
/// * [licensesPackageDetailTextOne], the "one" form
/// * [licensesPackageDetailTextTwo], the "two" form
/// * [licensesPackageDetailTextFew], the "few" form
/// * [licensesPackageDetailTextMany], the "many" form
/// * [licensesPackageDetailTextOther], the "other" form
@protected
String get licensesPackageDetailTextZero => null;
/// The "one" form of [licensesPackageDetailText].
///
/// This form is optional.
///
/// See also:
///
/// * [licensesPackageDetailTextZero], the "zero" form
/// * [licensesPackageDetailTextOne], the "one" form
/// * [licensesPackageDetailTextTwo], the "two" form
/// * [licensesPackageDetailTextFew], the "few" form
/// * [licensesPackageDetailTextMany], the "many" form
/// * [licensesPackageDetailTextOther], the "other" form
@protected
String get licensesPackageDetailTextOne => null;
/// The "two" form of [licensesPackageDetailText].
///
/// This form is optional.
///
/// See also:
///
/// * [Intl.plural], to which this form is passed.
/// * [licensesPackageDetailTextZero], the "zero" form
/// * [licensesPackageDetailTextOne], the "one" form
/// * [licensesPackageDetailTextTwo], the "two" form
/// * [licensesPackageDetailTextFew], the "few" form
/// * [licensesPackageDetailTextMany], the "many" form
/// * [licensesPackageDetailTextOther], the "other" form
@protected
String get licensesPackageDetailTextTwo => null;
/// The "many" form of [licensesPackageDetailText].
///
/// This form is optional.
///
/// See also:
///
/// * [Intl.plural], to which this form is passed.
/// * [licensesPackageDetailTextZero], the "zero" form
/// * [licensesPackageDetailTextOne], the "one" form
/// * [licensesPackageDetailTextTwo], the "two" form
/// * [licensesPackageDetailTextFew], the "few" form
/// * [licensesPackageDetailTextMany], the "many" form
/// * [licensesPackageDetailTextOther], the "other" form
@protected
String get licensesPackageDetailTextMany => null;
/// The "few" form of [licensesPackageDetailText].
///
/// This form is optional.
///
/// See also:
///
/// * [Intl.plural], to which this form is passed.
/// * [licensesPackageDetailTextZero], the "zero" form
/// * [licensesPackageDetailTextOne], the "one" form
/// * [licensesPackageDetailTextTwo], the "two" form
/// * [licensesPackageDetailTextFew], the "few" form
/// * [licensesPackageDetailTextMany], the "many" form
/// * [licensesPackageDetailTextOther], the "other" form
@protected
String get licensesPackageDetailTextFew => null;
/// The "other" form of [licensesPackageDetailText].
///
/// This form is required.
///
/// See also:
///
/// * [Intl.plural], to which this form is passed.
/// * [licensesPackageDetailTextZero], the "zero" form
/// * [licensesPackageDetailTextOne], the "one" form
/// * [licensesPackageDetailTextTwo], the "two" form
/// * [licensesPackageDetailTextFew], the "few" form
/// * [licensesPackageDetailTextMany], the "many" form
/// * [licensesPackageDetailTextOther], the "other" form
@protected
String get licensesPackageDetailTextOther;
@override
String licensesPackageDetailText(int licenseCount) {
return intl.Intl.pluralLogic(
licenseCount,
zero: licensesPackageDetailTextZero,
one: licensesPackageDetailTextOne,
two: licensesPackageDetailTextTwo,
many: licensesPackageDetailTextMany,
few: licensesPackageDetailTextFew,
other: licensesPackageDetailTextOther,
locale: _localeName,
).replaceFirst(r'$licenseCount', formatDecimal(licenseCount));
}
/// The "zero" form of [remainingTextFieldCharacterCount].
///
/// This form is required.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment