From 1311ffbbecf2c68e007c2f71d2856e6dcbdd2775 Mon Sep 17 00:00:00 2001 From: CodeDoctorDE Date: Thu, 20 Jan 2022 17:09:11 +0100 Subject: [PATCH] Convert project to recommended lints --- app/analysis_options.yaml | 32 +- app/lib/add.dart | 10 +- app/lib/app_module.dart | 20 +- app/lib/app_widget.dart | 38 +- app/lib/articles/bloc.dart | 9 +- app/lib/articles/details.dart | 53 ++- app/lib/articles/home.dart | 53 +-- app/lib/articles/module.dart | 3 +- app/lib/backends/entry.dart | 64 +-- app/lib/backends/home.dart | 25 +- app/lib/backends/module.dart | 12 +- app/lib/backends/user.dart | 20 +- app/lib/courses/bloc.dart | 11 +- app/lib/courses/details.dart | 75 ++-- app/lib/courses/drawer.dart | 18 +- app/lib/courses/home.dart | 55 +-- app/lib/courses/module.dart | 3 +- app/lib/courses/part/bloc.dart | 11 +- app/lib/courses/part/details.dart | 15 +- app/lib/courses/part/item.dart | 46 ++- app/lib/courses/part/layout.dart | 19 +- app/lib/courses/part/quiz.dart | 88 ++-- app/lib/courses/part/text.dart | 7 +- app/lib/courses/part/video.dart | 25 +- app/lib/courses/part/video_mobile.dart | 15 +- app/lib/courses/part/video_web.dart | 13 +- app/lib/courses/statistics.dart | 280 +++++++------ app/lib/editor/author.dart | 15 +- app/lib/editor/code.dart | 4 +- app/lib/editor/create.dart | 20 +- app/lib/editor/home.dart | 12 +- app/lib/editor/item.dart | 9 +- app/lib/editor/markdown.dart | 12 +- app/lib/editor/module.dart | 36 +- app/lib/home.dart | 33 +- app/lib/loader.dart | 5 +- app/lib/main.dart | 15 +- app/lib/models/collection.dart | 9 +- app/lib/models/course.dart | 15 +- app/lib/models/editor/server.dart | 4 +- app/lib/models/item.dart | 4 +- app/lib/models/items/quiz.dart | 15 +- app/lib/models/items/text.dart | 6 +- app/lib/models/items/video.dart | 8 +- app/lib/models/part.dart | 2 +- app/lib/models/server.dart | 26 +- app/lib/settings/appearance.dart | 17 +- app/lib/settings/collections.dart | 20 +- app/lib/settings/general.dart | 5 +- app/lib/settings/home.dart | 52 +-- app/lib/settings/module.dart | 8 +- app/lib/settings/servers.dart | 20 +- app/lib/themes/artistic.dart | 4 +- app/lib/themes/autumn.dart | 4 +- app/lib/themes/classic.dart | 4 +- app/lib/themes/modern.dart | 4 +- app/lib/themes/spring.dart | 4 +- app/lib/themes/summer.dart | 4 +- app/lib/themes/winter.dart | 4 +- app/lib/widgets/appbar.dart | 36 +- app/lib/widgets/author.dart | 2 +- app/lib/widgets/error.dart | 5 +- app/lib/widgets/image_type.dart | 3 +- app/lib/widgets/system_padding.dart | 4 +- app/lib/widgets/text_divider.dart | 4 +- app/pubspec.lock | 82 ++-- app/pubspec.yaml | 15 +- docs/package.json | 20 +- docs/yarn.lock | 533 +++++++++++++------------ 69 files changed, 1171 insertions(+), 953 deletions(-) diff --git a/app/analysis_options.yaml b/app/analysis_options.yaml index cb1ea33c..839cc647 100644 --- a/app/analysis_options.yaml +++ b/app/analysis_options.yaml @@ -1,3 +1,29 @@ -analyzer: - errors: - undefined_prefixed_name: ignore \ No newline at end of file +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options \ No newline at end of file diff --git a/app/lib/add.dart b/app/lib/add.dart index 9b0cdabe..ee22ec11 100644 --- a/app/lib/add.dart +++ b/app/lib/add.dart @@ -32,15 +32,15 @@ class _AddServerPageState extends State { builder: (context) => AlertDialog( actions: [ TextButton( - child: Text("disagree").tr(), + child: const Text("disagree").tr(), onPressed: () => Navigator.of(context).pop(false)), TextButton( - child: Text("agree").tr(), + child: const Text("agree").tr(), onPressed: () => Navigator.of(context).pop(true)) ], - title: Text("settings.servers.add.title").tr( + title: const Text("settings.servers.add.title").tr( namedArgs: {"name": server.name, "url": server.url}), - content: Text("settings.servers.add.body").tr( + content: const Text("settings.servers.add.body").tr( namedArgs: {"name": server.name, "url": server.url})))); if (shouldAdd!) { await _serversBox.add(url); @@ -57,6 +57,6 @@ class _AddServerPageState extends State { @override Widget build(BuildContext context) { - return ServersSettingsPage(); + return const ServersSettingsPage(); } } diff --git a/app/lib/app_module.dart b/app/lib/app_module.dart index e5cd49bd..b222ca57 100644 --- a/app/lib/app_module.dart +++ b/app/lib/app_module.dart @@ -24,18 +24,18 @@ class AppModule extends Module { // Provide all the routes for your module @override final List routes = [ - ChildRoute('/', child: (_, args) => MyHomePage(), children: [ + ChildRoute('/', child: (_, args) => const MyHomePage(), children: [ ...HomeRoutes.values.map((e) => ChildRoute(e.route, child: (_, __) => e.widget, transition: TransitionType.fadeIn)), - WildcardRoute(child: (_, __) => ErrorDisplay()) + WildcardRoute(child: (_, __) => const ErrorDisplay()) ]), - WildcardRoute(child: (_, __) => ErrorDisplay()), + WildcardRoute(child: (_, __) => const ErrorDisplay()), ModuleRoute('/editor', module: EditorModule()), ModuleRoute('/backends', module: BackendsModule()), ModuleRoute('/articles', module: ArticlesModule()), ModuleRoute('/settings', module: SettingsModule()), ModuleRoute('/courses', module: CourseModule()), - ChildRoute('/error', child: (_, args) => ErrorDisplay()), + ChildRoute('/error', child: (_, args) => const ErrorDisplay()), ChildRoute('/add', child: (_, args) => AddServerPage(url: args.queryParams['url']!)), ]; @@ -64,17 +64,17 @@ extension HomeRoutesExtension on HomeRoutes { Widget get widget { switch (this) { case HomeRoutes.home: - return HomePage(); + return const HomePage(); case HomeRoutes.backends: - return BackendsPage(); + return const BackendsPage(); case HomeRoutes.articles: - return ArticlesPage(); + return const ArticlesPage(); case HomeRoutes.courses: - return CoursesPage(); + return const CoursesPage(); case HomeRoutes.editor: - return EditorPage(); + return const EditorPage(); case HomeRoutes.settings: - return SettingsPage(); + return const SettingsPage(); } } diff --git a/app/lib/app_widget.dart b/app/lib/app_widget.dart index f01f4626..4a329be3 100644 --- a/app/lib/app_widget.dart +++ b/app/lib/app_widget.dart @@ -9,15 +9,17 @@ import 'package:phosphor_flutter/phosphor_flutter.dart'; import 'themes/theme.dart'; class AppWidget extends StatelessWidget { + const AppWidget({Key? key}) : super(key: key); + // This widget is the root of your application. @override Widget build(BuildContext context) { // var locale = Hive.box('appearance').get('locale', defaultValue: 'default'); //if (locale != 'default') context.locale = Locale.fromSubtags(scriptCode: locale); return EasyLocalization( - supportedLocales: [Locale('en'), Locale('de'), Locale('fr')], + supportedLocales: const [Locale('en'), Locale('de'), Locale('fr')], path: 'translations', - fallbackLocale: Locale('en'), + fallbackLocale: const Locale('en'), useOnlyLangCode: true, child: ValueListenableBuilder( valueListenable: Hive.box('appearance').listenable(), @@ -28,7 +30,7 @@ class AppWidget extends StatelessWidget { title: 'Dev-Doctor', localizationsDelegates: [ ...context.localizationDelegates, - LocaleNamesLocalizationsDelegate() + const LocaleNamesLocalizationsDelegate() ], supportedLocales: context.supportedLocales, locale: context.locale, @@ -36,10 +38,10 @@ class AppWidget extends StatelessWidget { debugShowCheckedModeBanner: false, builder: (context, widget) { ErrorWidget.builder = (FlutterErrorDetails errorDetails) { - return ErrorDisplay(); + return const ErrorDisplay(); }; - return widget ?? ErrorDisplay(); + return widget ?? const ErrorDisplay(); }, theme: ThemeData( // This is the theme of your application. @@ -79,7 +81,7 @@ class AppWidget extends StatelessWidget { // the app on. For desktop platforms, the controls will be smaller and // closer together (more dense) than on mobile platforms. visualDensity: VisualDensity.adaptivePlatformDensity), - home: MyHomePage(), + home: const MyHomePage(), ).modular(); })); } @@ -116,33 +118,33 @@ class _MyHomePageState extends State { items: [ BottomNavigationBarItem( backgroundColor: Theme.of(context).primaryColor, - activeIcon: Icon(PhosphorIcons.houseFill), - icon: Icon(PhosphorIcons.houseLight), + activeIcon: const Icon(PhosphorIcons.houseFill), + icon: const Icon(PhosphorIcons.houseLight), label: 'home'.tr()), BottomNavigationBarItem( backgroundColor: Theme.of(context).primaryColor, - activeIcon: Icon(PhosphorIcons.storefrontFill), - icon: Icon(PhosphorIcons.storefrontLight), + activeIcon: const Icon(PhosphorIcons.storefrontFill), + icon: const Icon(PhosphorIcons.storefrontLight), label: 'backends.title'.tr()), BottomNavigationBarItem( backgroundColor: Theme.of(context).primaryColor, - activeIcon: Icon(PhosphorIcons.articleFill), - icon: Icon(PhosphorIcons.articleLight), + activeIcon: const Icon(PhosphorIcons.articleFill), + icon: const Icon(PhosphorIcons.articleLight), label: 'articles.title'.tr()), BottomNavigationBarItem( backgroundColor: Theme.of(context).primaryColor, - activeIcon: Icon(PhosphorIcons.graduationCapFill), - icon: Icon(PhosphorIcons.graduationCapLight), + activeIcon: const Icon(PhosphorIcons.graduationCapFill), + icon: const Icon(PhosphorIcons.graduationCapLight), label: 'courses.title'.tr()), BottomNavigationBarItem( backgroundColor: Theme.of(context).primaryColor, - activeIcon: Icon(PhosphorIcons.pencilFill), - icon: Icon(PhosphorIcons.pencilLight), + activeIcon: const Icon(PhosphorIcons.pencilFill), + icon: const Icon(PhosphorIcons.pencilLight), label: 'editor.title'.tr()), BottomNavigationBarItem( backgroundColor: Theme.of(context).primaryColor, - activeIcon: Icon(PhosphorIcons.gearFill), - icon: Icon(PhosphorIcons.gearLight), + activeIcon: const Icon(PhosphorIcons.gearFill), + icon: const Icon(PhosphorIcons.gearLight), label: 'settings.title'.tr()) ], unselectedItemColor: Theme.of(context).unselectedWidgetColor, diff --git a/app/lib/articles/bloc.dart b/app/lib/articles/bloc.dart index df5c9ab4..d080f081 100644 --- a/app/lib/articles/bloc.dart +++ b/app/lib/articles/bloc.dart @@ -12,7 +12,7 @@ class ArticleBloc extends Disposable { bool error = false; bool get hasError => error; - CoursePartBloc() {} + ArticleBloc(); Future fetch( {ServerEditorBloc? editorBloc, String? server, @@ -27,11 +27,12 @@ class ArticleBloc extends Disposable { : await CoursesServer.fetch(index: serverId, url: server); if (editorBloc == null && !(currentServer?.added ?? false) && - server != null) + server != null) { Modular.to.pushNamed(Uri( pathSegments: ["", "add"], queryParameters: {"url": server, "redirect": Modular.to.path}) .toString()); + } if (articleId != null) article = currentServer?.articles[articleId]; this.article = article; var current = article == null @@ -42,7 +43,9 @@ class ArticleBloc extends Disposable { articleSubject.add(current ?? Article(slug: '')); if (current == null) error = true; } catch (e) { - print("Error $e"); + if (kDebugMode) { + print("Error $e"); + } error = true; } } diff --git a/app/lib/articles/details.dart b/app/lib/articles/details.dart index bb9ea11a..b63239a8 100644 --- a/app/lib/articles/details.dart +++ b/app/lib/articles/details.dart @@ -31,8 +31,8 @@ class ArticlePage extends StatefulWidget { class _ArticlePageState extends State { ServerEditorBloc? _editorBloc; late ArticleBloc bloc; - TextEditingController _titleController = TextEditingController(); - TextEditingController _slugController = TextEditingController(); + final TextEditingController _titleController = TextEditingController(); + final TextEditingController _slugController = TextEditingController(); final GlobalKey _formKey = GlobalKey(); @override @@ -57,10 +57,11 @@ class _ArticlePageState extends State { return StreamBuilder
( stream: bloc.articleSubject, builder: (context, snapshot) { - if (snapshot.hasError || bloc.hasError) return ErrorDisplay(); + if (snapshot.hasError || bloc.hasError) return const ErrorDisplay(); if (snapshot.connectionState == ConnectionState.waiting || - !snapshot.hasData) - return Center(child: CircularProgressIndicator()); + !snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } var article = snapshot.data!; return _buildView(article); }); @@ -72,7 +73,7 @@ class _ArticlePageState extends State { appBar: AppBar(title: Text(article.title), actions: [ if (_editorBloc == null) ...[ IconButton( - icon: Icon(PhosphorIcons.shareNetworkLight), + icon: const Icon(PhosphorIcons.shareNetworkLight), tooltip: "share".tr(), onPressed: () { Clipboard.setData(ClipboardData( @@ -92,12 +93,12 @@ class _ArticlePageState extends State { }) ] else IconButton( - icon: Icon(PhosphorIcons.codeLight), + icon: const Icon(PhosphorIcons.codeLight), tooltip: "code".tr(), onPressed: () async { //var packageInfo = await PackageInfo.fromPlatform(); //var buildNumber = int.tryParse(packageInfo.buildNumber); - var encoder = JsonEncoder.withIndent(" "); + var encoder = const JsonEncoder.withIndent(" "); var data = await Modular.to.push(MaterialPageRoute( builder: (context) => EditorCodeDialogPage( initialValue: encoder.convert(article.toJson())))); @@ -109,22 +110,26 @@ class _ArticlePageState extends State { initEditor(); } }), - if (!kIsWeb && isWindow()) ...[VerticalDivider(), WindowButtons()] + if (!kIsWeb && isWindow()) ...[ + const VerticalDivider(), + const WindowButtons() + ] ]), body: ListView(children: [ Padding( - padding: EdgeInsets.all(4), + padding: const EdgeInsets.all(4), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16)), child: Padding( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Column(children: [ if (_editorBloc != null) Form( key: _formKey, child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: + const BoxConstraints(maxWidth: 1000), child: Column(children: [ TextFormField( decoration: InputDecoration( @@ -133,8 +138,9 @@ class _ArticlePageState extends State { hintText: "article.title.hint".tr()), validator: (value) { - if (value!.isEmpty) + if (value!.isEmpty) { return "article.title.empty".tr(); + } return null; }, controller: _titleController), @@ -144,11 +150,13 @@ class _ArticlePageState extends State { "article.slug.label".tr(), hintText: "article.slug.hint".tr()), validator: (value) { - if (value!.isEmpty) + if (value!.isEmpty) { return "article.slug.empty".tr(); + } if (_slugs!.contains(value) && - value != article.slug) + value != article.slug) { return "article.slug.exist".tr(); + } return null; }, controller: _slugController), @@ -167,12 +175,12 @@ class _ArticlePageState extends State { bloc.articleSubject.add(article); setState(() {}); }, - icon: Icon( + icon: const Icon( PhosphorIcons.floppyDiskLight), label: Text("save".tr().toUpperCase())), ), - Divider() + const Divider() ]))), Row( mainAxisAlignment: MainAxisAlignment.center, @@ -184,7 +192,7 @@ class _ArticlePageState extends State { if (_editorBloc != null) ...[ IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: const Icon(PhosphorIcons.pencilLight), onPressed: () => Modular.to.pushNamed(Uri( pathSegments: [ '', @@ -200,12 +208,13 @@ class _ArticlePageState extends State { if (article.author.name.isNotEmpty) IconButton( tooltip: "delete".tr(), - icon: Icon(PhosphorIcons.trashLight), + icon: + const Icon(PhosphorIcons.trashLight), onPressed: () async { var articleBloc = _editorBloc! .getArticle(bloc.article!); article = articleBloc.copyWith( - author: Author()); + author: const Author()); _editorBloc?.updateArticle(article); bloc.articleSubject.add(article); await _editorBloc?.save(); @@ -215,7 +224,7 @@ class _ArticlePageState extends State { ]), Row(children: [ Expanded( - child: (!article.body.isEmpty) + child: (article.body.isNotEmpty) ? MarkdownBody( onTapLink: (_, url, __) => launch(url!), extensionSet: md.ExtensionSet( @@ -234,7 +243,7 @@ class _ArticlePageState extends State { if (_editorBloc != null) IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: const Icon(PhosphorIcons.pencilLight), onPressed: () => Modular.to.pushNamed( Uri(pathSegments: [ "", diff --git a/app/lib/articles/home.dart b/app/lib/articles/home.dart index 2a8f9fa5..867f8a7a 100644 --- a/app/lib/articles/home.dart +++ b/app/lib/articles/home.dart @@ -11,6 +11,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; class ArticlesPage extends StatefulWidget { + const ArticlesPage({Key? key}) : super(key: key); + @override _ArticlesPageState createState() => _ArticlesPageState(); } @@ -46,8 +48,9 @@ class _ItemFetcher { var index = _currentPage * _itemsPerPage + i; var entry = entries[index]; if (entry.body.toUpperCase().contains(query.toUpperCase()) || - entry.title.toUpperCase().contains(query.toUpperCase())) + entry.title.toUpperCase().contains(query.toUpperCase())) { list.add(entry); + } } _currentPage++; return list; @@ -55,7 +58,7 @@ class _ItemFetcher { } class CustomSearchDelegate extends SearchDelegate { - var _itemFetcher; + final _ItemFetcher _itemFetcher; final List? servers; final bool gridView; @@ -65,7 +68,7 @@ class CustomSearchDelegate extends SearchDelegate { return [ IconButton( tooltip: "clear".tr(), - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), onPressed: () { query = ''; }, @@ -77,7 +80,7 @@ class CustomSearchDelegate extends SearchDelegate { Widget buildLeading(BuildContext context) { return IconButton( tooltip: "back".tr(), - icon: Icon(PhosphorIcons.arrowArcLeftLight), + icon: const Icon(PhosphorIcons.arrowArcLeftLight), onPressed: () { close(context, null); }, @@ -114,8 +117,8 @@ class CustomSearchDelegate extends SearchDelegate { } class _ArticlesPageState extends State { - var _itemFetcher; - var _box = Hive.box('servers'); + late _ItemFetcher _itemFetcher; + final _box = Hive.box('servers'); bool gridView = false; final List _filteredServers = []; @@ -131,7 +134,7 @@ class _ArticlesPageState extends State { return Scaffold( appBar: MyAppBar(title: "articles.title".tr(), actions: [ IconButton( - icon: Icon(PhosphorIcons.magnifyingGlassLight), + icon: const Icon(PhosphorIcons.magnifyingGlassLight), tooltip: "search".tr(), onPressed: () { showSearch( @@ -140,16 +143,16 @@ class _ArticlesPageState extends State { ); }), IconButton( - icon: Icon(PhosphorIcons.funnelLight), + icon: const Icon(PhosphorIcons.funnelLight), tooltip: "articles.filter".tr(), onPressed: () async { await showDialog( context: context, builder: (context) => AlertDialog( - title: Text("articles.filter").tr(), + title: const Text("articles.filter").tr(), actions: [ TextButton.icon( - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), label: Text("close".tr().toUpperCase()), onPressed: () => Navigator.of(context).pop()) ], @@ -215,7 +218,7 @@ class _ArticlesListState extends State { bool _isLoading = true; bool _hasMore = true; - Box _favoriteBox = Hive.box('favorite'); + final Box _favoriteBox = Hive.box('favorite'); @override void initState() { super.initState(); @@ -288,12 +291,12 @@ class _ArticlesListState extends State { tag: "Article-icon-${article.server?.index}-${article.slug}", child: UniversalImage(type: article.icon, url: article.url + "/icon")); - if (widget.gridView) + if (widget.gridView) { return Card( child: InkWell( onTap: onTap, child: Container( - constraints: BoxConstraints(maxWidth: 250), + constraints: const BoxConstraints(maxWidth: 250), padding: const EdgeInsets.all(8.0), child: SizedBox( height: 250, @@ -312,6 +315,7 @@ class _ArticlesListState extends State { ]) ]), )))); + } return ListTile( title: Text(article.title), subtitle: Text(article.body), @@ -330,7 +334,7 @@ class _ArticlesListState extends State { if (!_isLoading) { _loadMore(); } - return Center( + return const Center( child: SizedBox( child: CircularProgressIndicator(), height: 24, @@ -345,16 +349,15 @@ class _ArticlesListState extends State { @override Widget build(BuildContext context) { - return Container( - child: Scrollbar( - child: SingleChildScrollView( - child: widget.gridView - ? Container( - width: double.infinity, - alignment: Alignment.center, - child: Wrap(children: _buildList(context))) - : Column( - // Need to display a loading tile if more items are coming - children: _buildList(context))))); + return Scrollbar( + child: SingleChildScrollView( + child: widget.gridView + ? Container( + width: double.infinity, + alignment: Alignment.center, + child: Wrap(children: _buildList(context))) + : Column( + // Need to display a loading tile if more items are coming + children: _buildList(context)))); } } diff --git a/app/lib/articles/module.dart b/app/lib/articles/module.dart index 9a8612f0..8d8cdd25 100644 --- a/app/lib/articles/module.dart +++ b/app/lib/articles/module.dart @@ -7,9 +7,10 @@ import 'home.dart'; class ArticlesModule extends Module { @override List get routes => [ - ChildRoute('/', child: (_, args) => ArticlesPage()), + ChildRoute('/', child: (_, args) => const ArticlesPage()), ChildRoute('/details', child: (_, args) => ArticlePage(model: args.data)) ]; + @override List> get binds => [Bind.singleton((i) => ArticleBloc())]; } diff --git a/app/lib/backends/entry.dart b/app/lib/backends/entry.dart index 9995c53c..b1ac82c8 100644 --- a/app/lib/backends/entry.dart +++ b/app/lib/backends/entry.dart @@ -44,8 +44,8 @@ class _BackendPageState extends State late TabController _tabController; late TextEditingController _nameController; late TextEditingController _noteController; - GlobalKey _formKey = GlobalKey(); - Box _box = Hive.box('editor'); + final GlobalKey _formKey = GlobalKey(); + final Box _box = Hive.box('editor'); ServerEditorBloc? _editorBloc; void _handleTabChange() { @@ -93,12 +93,13 @@ class _BackendPageState extends State builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.waiting: - return Center(child: CircularProgressIndicator()); + return const Center(child: CircularProgressIndicator()); default: - if (snapshot.hasError) + if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); + } var server = snapshot.data; - if (server == null) return ErrorDisplay(); + if (server == null) return const ErrorDisplay(); return _buildView(server); } }); @@ -119,10 +120,11 @@ class _BackendPageState extends State AddBackendButton(server: server) else IconButton( - icon: Icon(PhosphorIcons.codeLight), + icon: const Icon(PhosphorIcons.codeLight), tooltip: "code".tr(), onPressed: () async { - var encoder = JsonEncoder.withIndent(" "); + var encoder = + const JsonEncoder.withIndent(" "); var data = await Modular.to.push( MaterialPageRoute( builder: (context) => @@ -139,8 +141,8 @@ class _BackendPageState extends State } }), if (!kIsWeb && isWindow()) ...[ - VerticalDivider(), - WindowButtons() + const VerticalDivider(), + const WindowButtons() ] ], bottom: _editorBloc != null @@ -160,7 +162,8 @@ class _BackendPageState extends State ? null : FlexibleSpaceBar( background: Container( - margin: EdgeInsets.fromLTRB(10, 20, 10, 84), + margin: const EdgeInsets.fromLTRB( + 10, 20, 10, 84), child: Hero( tag: _editorBloc != null ? "editor-backend-${_editorBloc!.server.name}" @@ -246,7 +249,7 @@ class _BackendPageState extends State onPressed: _tabController.index == 1 ? _showCreateCourseDialog : _showCreateArticleDialog, - child: Icon(PhosphorIcons.plusLight), + child: const Icon(PhosphorIcons.plusLight), ); } @@ -256,7 +259,7 @@ class _BackendPageState extends State child: ListView( children: [ Padding( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16)), @@ -276,13 +279,14 @@ class _BackendPageState extends State "user": server.entry!.user, "server": server }), - icon: Icon(PhosphorIcons.userLight), + icon: const Icon(PhosphorIcons.userLight), label: Text(widget.user!))), ] else Form( key: _formKey, child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: + const BoxConstraints(maxWidth: 1000), child: Column(children: [ TextFormField( decoration: InputDecoration( @@ -293,14 +297,16 @@ class _BackendPageState extends State "editor.create.name.hint" .tr()), validator: (value) { - if (value!.isEmpty) + if (value!.isEmpty) { return "editor.create.name.empty" .tr(); + } if (_names.contains(value) && value != - _editorBloc!.server.name) + _editorBloc!.server.name) { return "editor.create.name.exist" .tr(); + } return null; }, controller: _nameController), @@ -328,12 +334,12 @@ class _BackendPageState extends State await _editorBloc?.save(); setState(() {}); }, - icon: Icon( + icon: const Icon( PhosphorIcons.floppyDiskLight), label: Text( "save".tr().toUpperCase())), ), - Divider() + const Divider() ]))), Row(children: [ Expanded( @@ -358,7 +364,7 @@ class _BackendPageState extends State : Container()), IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: const Icon(PhosphorIcons.pencilLight), onPressed: () => Modular.to.pushNamed( '/editor/edit?serverId=${_editorBloc!.key.toString()}')) ]) @@ -438,19 +444,19 @@ class _BackendPageState extends State } Future _createCourse(String name) async { - if (_editorBloc!.courses.map((e) => e.course.slug).contains(name)) + if (_editorBloc!.courses.map((e) => e.course.slug).contains(name)) { showDialog( context: context, builder: (context) => AlertDialog( - title: Text("course.add.exist.title").tr(), - content: Text("course.add.exist.content").tr(), + title: const Text("course.add.exist.title").tr(), + content: const Text("course.add.exist.content").tr(), actions: [ TextButton.icon( - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), onPressed: () => Navigator.of(context).pop(), label: Text("close".tr().toUpperCase())) ])); - else { + } else { _editorBloc!.createCourse(name); _editorBloc?.save(); setState(() {}); @@ -458,19 +464,19 @@ class _BackendPageState extends State } Future _createArticle(String name) async { - if (_editorBloc!.getCourseSlugs().contains(name)) + if (_editorBloc!.getCourseSlugs().contains(name)) { showDialog( context: context, builder: (context) => AlertDialog( - title: Text("article.add.exist.title").tr(), - content: Text("article.add.exist.content").tr(), + title: const Text("article.add.exist.title").tr(), + content: const Text("article.add.exist.content").tr(), actions: [ TextButton.icon( - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), onPressed: () => Navigator.of(context).pop(), label: Text("close".tr().toUpperCase())) ])); - else { + } else { _editorBloc!.createArticle(name); _editorBloc?.save(); setState(() {}); diff --git a/app/lib/backends/home.dart b/app/lib/backends/home.dart index c3086fc0..1a1d0790 100644 --- a/app/lib/backends/home.dart +++ b/app/lib/backends/home.dart @@ -17,12 +17,13 @@ class _ItemFetcher { // This async function simulates fetching results from Internet, etc. Future> fetch(String query) async { - if (entries.isEmpty) + if (entries.isEmpty) { await Future.wait(Hive.box('collections').values.map((e) async { var collection = await BackendCollection.fetch(url: e); var users = await collection?.fetchUsers(); entries.addAll(users?.expand((e) => e.buildEntries()) ?? []); })); + } final list = []; var n = min(_itemsPerPage, entries.length - _currentPage * _itemsPerPage); for (int i = 0; i < n; i++) { @@ -31,8 +32,9 @@ class _ItemFetcher { var server = await entry.fetchServer(); if ((server!.body.isNotEmpty && server.body.toUpperCase().contains(query.toUpperCase())) || - server.name.toUpperCase().contains(query.toUpperCase())) + server.name.toUpperCase().contains(query.toUpperCase())) { list.add(server); + } } _currentPage++; return list; @@ -40,7 +42,7 @@ class _ItemFetcher { } class CustomSearchDelegate extends SearchDelegate { - var _itemFetcher; + _ItemFetcher _itemFetcher; final bool gridView; CustomSearchDelegate(this._itemFetcher, this.gridView); @@ -49,7 +51,7 @@ class CustomSearchDelegate extends SearchDelegate { return [ IconButton( tooltip: "clear".tr(), - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), onPressed: () { query = ''; }, @@ -61,7 +63,7 @@ class CustomSearchDelegate extends SearchDelegate { Widget buildLeading(BuildContext context) { return IconButton( tooltip: "back".tr(), - icon: Icon(PhosphorIcons.arrowArcLeftLight), + icon: const Icon(PhosphorIcons.arrowArcLeftLight), onPressed: () { close(context, null); }, @@ -162,7 +164,7 @@ class _BackendsListState extends State { if (!_isLoading) { _loadMore(); } - return Center( + return const Center( child: SizedBox( child: CircularProgressIndicator(), height: 24, @@ -192,12 +194,12 @@ class _BackendsListState extends State { child: UniversalImage(type: server.icon, url: server.url + "/icon")); - if (widget.gridView) + if (widget.gridView) { return Card( child: InkWell( onTap: onTap, child: Container( - constraints: BoxConstraints(maxWidth: 250), + constraints: const BoxConstraints(maxWidth: 250), padding: const EdgeInsets.all(8.0), child: Column(children: [ Container(padding: const EdgeInsets.all(8.0), child: hero), @@ -212,6 +214,7 @@ class _BackendsListState extends State { ]) ]), ))); + } return ListTile( title: Text(server.name), @@ -223,6 +226,8 @@ class _BackendsListState extends State { } class BackendsPage extends StatefulWidget { + const BackendsPage({Key? key}) : super(key: key); + @override _BackendsPageState createState() => _BackendsPageState(); } @@ -237,7 +242,7 @@ class _BackendsPageState extends State appBar: MyAppBar(title: "backends.title".tr(), actions: [ IconButton( tooltip: "search".tr(), - icon: Icon(PhosphorIcons.magnifyingGlassLight), + icon: const Icon(PhosphorIcons.magnifyingGlassLight), onPressed: () { showSearch( context: context, @@ -281,7 +286,7 @@ class _AddBackendButtonState extends State _server = widget.server; _controller = AnimationController( vsync: this, - duration: Duration(milliseconds: 100), + duration: const Duration(milliseconds: 100), value: _server.added ? 1 : 0); _animation = Tween(begin: -0.25, end: 0).animate(_controller); } diff --git a/app/lib/backends/module.dart b/app/lib/backends/module.dart index 38c9bd6c..1d00aec5 100644 --- a/app/lib/backends/module.dart +++ b/app/lib/backends/module.dart @@ -8,26 +8,28 @@ import 'home.dart'; class BackendsModule extends Module { @override final List routes = [ - ChildRoute('/', child: (_, args) => BackendsPage()), + ChildRoute('/', child: (_, args) => const BackendsPage()), ChildRoute("/user", child: (_, args) { if (args.queryParams.containsKey('collectionId') && - args.queryParams.containsKey('user')) + args.queryParams.containsKey('user')) { return BackendUserPage( model: args.data, collectionId: int.parse(args.queryParams['collectionId']!), user: args.queryParams['user']); - return ErrorDisplay(); + } + return const ErrorDisplay(); }), ChildRoute('/entry', child: (_, args) { if (args.queryParams.containsKey('collectionId') && args.queryParams.containsKey('user') && - args.queryParams.containsKey('entry')) + args.queryParams.containsKey('entry')) { return BackendPage( model: args.data, collectionId: int.parse(args.queryParams['collectionId']!), user: args.queryParams['user']!, entry: args.queryParams['entry']!); - return ErrorDisplay(); + } + return const ErrorDisplay(); }) ]; } diff --git a/app/lib/backends/user.dart b/app/lib/backends/user.dart index a37e3469..f7e81884 100644 --- a/app/lib/backends/user.dart +++ b/app/lib/backends/user.dart @@ -26,7 +26,7 @@ class _BackendUserPageState extends State { if (widget.model != null) return widget.model!['user']; var collection = await BackendCollection.fetch(index: widget.collectionId); var current = await collection!.fetchUser(widget.user); - return await current; + return current; } @override @@ -38,10 +38,12 @@ class _BackendUserPageState extends State { future: _buildFuture(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting || - !snapshot.hasData) - return Center(child: CircularProgressIndicator()); - if (snapshot.hasError) + !snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } + if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); + } var backendUser = snapshot.data!; return _buildView(backendUser); })); @@ -77,10 +79,12 @@ class _BackendUserPageState extends State { future: entries[index].fetchServer(), builder: (context, snapshot) { if (!snapshot.hasData || - snapshot.connectionState == ConnectionState.waiting) - return Center(child: CircularProgressIndicator()); - if (snapshot.hasError) + snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } + if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); + } var server = snapshot.data!; return _buildTile(server, entries, index); })); @@ -99,7 +103,7 @@ class _BackendUserPageState extends State { child: InkWell( onTap: tileTap, child: Container( - constraints: BoxConstraints(maxWidth: 250), + constraints: const BoxConstraints(maxWidth: 250), padding: const EdgeInsets.all(8.0), child: Column(children: [ hero, diff --git a/app/lib/courses/bloc.dart b/app/lib/courses/bloc.dart index dd254d5d..1c66d484 100644 --- a/app/lib/courses/bloc.dart +++ b/app/lib/courses/bloc.dart @@ -12,7 +12,7 @@ class CourseBloc extends Disposable { bool error = false; bool get hasError => error; - CoursePartBloc() {} + CourseBloc(); Future fetch( {ServerEditorBloc? editorBloc, String? server, @@ -27,11 +27,12 @@ class CourseBloc extends Disposable { : await CoursesServer.fetch(index: serverId, url: server); if (editorBloc == null && !(currentServer?.added ?? false) && - server != null) + server != null) { Modular.to.pushNamed(Uri( pathSegments: ["", "add"], queryParameters: {"url": server, "redirect": Modular.to.path}) .toString()); + } if (courseId != null) course = currentServer?.courses[courseId]; this.course = course; var current = course == null @@ -39,10 +40,12 @@ class CourseBloc extends Disposable { : editorBloc != null ? editorBloc.getCourse(course).course : await currentServer?.fetchCourse(course); - courseSubject.add(current ?? Course(parts: [], slug: '')); + courseSubject.add(current ?? const Course(parts: [], slug: '')); if (current == null) error = true; } catch (e) { - print("Error $e"); + if (kDebugMode) { + print("Error $e"); + } error = true; } } diff --git a/app/lib/courses/details.dart b/app/lib/courses/details.dart index 47ac711e..47fa4524 100644 --- a/app/lib/courses/details.dart +++ b/app/lib/courses/details.dart @@ -84,9 +84,12 @@ class _CoursePageState extends State with TickerProviderStateMixin { stream: bloc.courseSubject, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting || - !snapshot.hasData) - return Center(child: CircularProgressIndicator()); - if (snapshot.hasError || bloc.hasError) return ErrorDisplay(); + !snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } + if (snapshot.hasError || bloc.hasError) { + return const ErrorDisplay(); + } var course = snapshot.data; return _buildView(course!); }); @@ -98,7 +101,7 @@ class _CoursePageState extends State with TickerProviderStateMixin { : FloatingActionButton( tooltip: "create".tr(), onPressed: _showCreatePartDialog, - child: Icon(PhosphorIcons.plusLight), + child: const Icon(PhosphorIcons.plusLight), ); } @@ -199,7 +202,8 @@ class _CoursePageState extends State with TickerProviderStateMixin { actions: [ if (_editorBloc == null) ...{ IconButton( - icon: Icon(PhosphorIcons.shareNetworkLight), + icon: const Icon( + PhosphorIcons.shareNetworkLight), tooltip: "share".tr(), onPressed: () { Clipboard.setData(ClipboardData( @@ -219,11 +223,12 @@ class _CoursePageState extends State with TickerProviderStateMixin { }), if (supportUrl != null) IconButton( - icon: Icon(PhosphorIcons.questionLight), + icon: + const Icon(PhosphorIcons.questionLight), tooltip: "course.support".tr(), onPressed: () => launch(supportUrl)), IconButton( - icon: Icon(PhosphorIcons.playLight), + icon: const Icon(PhosphorIcons.playLight), tooltip: "course.start".tr(), onPressed: () => Modular.to.pushNamed(Uri( pathSegments: [ @@ -238,14 +243,15 @@ class _CoursePageState extends State with TickerProviderStateMixin { }).toString())) } else IconButton( - icon: Icon(PhosphorIcons.codeLight), + icon: const Icon(PhosphorIcons.codeLight), tooltip: "code".tr(), onPressed: () async { var packageInfo = await PackageInfo.fromPlatform(); var buildNumber = int.tryParse(packageInfo.buildNumber); - var encoder = JsonEncoder.withIndent(" "); + var encoder = + const JsonEncoder.withIndent(" "); var data = await Modular.to.push( MaterialPageRoute( builder: (context) => @@ -262,8 +268,8 @@ class _CoursePageState extends State with TickerProviderStateMixin { } }), if (!kIsWeb && isWindow()) ...[ - VerticalDivider(), - WindowButtons() + const VerticalDivider(), + const WindowButtons() ] ], title: Text(course.name), @@ -271,8 +277,8 @@ class _CoursePageState extends State with TickerProviderStateMixin { ? null : FlexibleSpaceBar( background: Container( - margin: - EdgeInsets.fromLTRB(10, 20, 10, 84), + margin: const EdgeInsets.fromLTRB( + 10, 20, 10, 84), child: _editorBloc != null ? Container() : Hero( @@ -285,7 +291,7 @@ class _CoursePageState extends State with TickerProviderStateMixin { ))), )), SliverList( - delegate: new SliverChildListDelegate([ + delegate: SliverChildListDelegate([ Material( color: Theme.of(context).appBarTheme.backgroundColor ?? @@ -318,26 +324,27 @@ class _CoursePageState extends State with TickerProviderStateMixin { var _slugs = _editorBloc?.courses.map((e) => e.course.slug); return ListView(children: [ Padding( - padding: EdgeInsets.all(4), + padding: const EdgeInsets.all(4), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16)), child: Padding( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Column(children: [ if (_editorBloc != null) Form( key: _formKey, child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: const BoxConstraints(maxWidth: 1000), child: Column(children: [ TextFormField( decoration: InputDecoration( labelText: "course.name.label".tr(), hintText: "course.name.hint".tr()), validator: (value) { - if (value!.isEmpty) + if (value!.isEmpty) { return "course.name.empty".tr(); + } return null; }, controller: _nameController), @@ -346,11 +353,13 @@ class _CoursePageState extends State with TickerProviderStateMixin { labelText: "course.slug.label".tr(), hintText: "course.slug.hint".tr()), validator: (value) { - if (value!.isEmpty) + if (value!.isEmpty) { return "course.slug.empty".tr(); + } if (_slugs!.contains(value) && - value != course.slug) + value != course.slug) { return "course.slug.exist".tr(); + } return null; }, controller: _slugController), @@ -388,10 +397,11 @@ class _CoursePageState extends State with TickerProviderStateMixin { _editorBloc?.save(); setState(() {}); }, - icon: Icon(PhosphorIcons.floppyDiskLight), + icon: const Icon( + PhosphorIcons.floppyDiskLight), label: Text("save".tr().toUpperCase())), ), - Divider() + const Divider() ]))), Row(mainAxisAlignment: MainAxisAlignment.center, children: [ if (course.author.name.isNotEmpty) @@ -401,7 +411,7 @@ class _CoursePageState extends State with TickerProviderStateMixin { if (_editorBloc != null) ...[ IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: const Icon(PhosphorIcons.pencilLight), onPressed: () => Modular.to.pushNamed(Uri( pathSegments: [ '', @@ -416,12 +426,12 @@ class _CoursePageState extends State with TickerProviderStateMixin { if (course.author.name.isNotEmpty) IconButton( tooltip: "delete".tr(), - icon: Icon(PhosphorIcons.trashLight), + icon: const Icon(PhosphorIcons.trashLight), onPressed: () async { var courseBloc = _editorBloc!.getCourse(bloc.course!); course = courseBloc.course - .copyWith(author: Author()); + .copyWith(author: const Author()); courseBloc.course = course; await _editorBloc?.save(); setState(() {}); @@ -430,11 +440,11 @@ class _CoursePageState extends State with TickerProviderStateMixin { ]), if (course.lang.isNotEmpty || _editorBloc != null) Padding( - padding: EdgeInsets.all(8), + padding: const EdgeInsets.all(8), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Padding( + const Padding( padding: EdgeInsets.all(4), child: Icon(PhosphorIcons.globeLight)), Text(course.lang.isNotEmpty @@ -445,12 +455,13 @@ class _CoursePageState extends State with TickerProviderStateMixin { if (_editorBloc != null) IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: + const Icon(PhosphorIcons.pencilLight), onPressed: () => _showLanguageDialog()) ])), Row(children: [ Expanded( - child: (!course.body.isEmpty) + child: (course.body.isNotEmpty) ? MarkdownBody( onTapLink: (_, url, __) => launch(url!), extensionSet: md.ExtensionSet( @@ -469,7 +480,7 @@ class _CoursePageState extends State with TickerProviderStateMixin { if (_editorBloc != null) IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: const Icon(PhosphorIcons.pencilLight), onPressed: () => Modular.to.pushNamed(Uri( pathSegments: [ "", @@ -551,7 +562,7 @@ class EditorCoursePartPopupMenu extends StatelessWidget { ]), value: e); }).toList() - ..insert(3, PopupMenuDivider()); + ..insert(3, const PopupMenuDivider()); }, ); } @@ -729,7 +740,7 @@ extension PartOptionsExtension on PartOptions { ])); break; case PartOptions.code: - var encoder = JsonEncoder.withIndent(" "); + var encoder = const JsonEncoder.withIndent(" "); var packageInfo = await PackageInfo.fromPlatform(); var buildNumber = int.tryParse(packageInfo.buildNumber); var data = await Modular.to.push(MaterialPageRoute( diff --git a/app/lib/courses/drawer.dart b/app/lib/courses/drawer.dart index c4eb3aaf..2e50813c 100644 --- a/app/lib/courses/drawer.dart +++ b/app/lib/courses/drawer.dart @@ -28,8 +28,9 @@ class _CoursePartDrawerState extends State { int? partId; Future> _buildFuture() async { - if (widget.editorBloc != null) + if (widget.editorBloc != null) { return widget.editorBloc!.getCourse(widget.course!.slug).parts; + } return await widget.course!.fetchParts(); } @@ -42,8 +43,8 @@ class _CoursePartDrawerState extends State { child: Scrollbar( child: ListView(children: [ ListTile( - title: Text('course.back').tr(), - leading: Icon(PhosphorIcons.arrowArcLeftLight), + title: const Text('course.back').tr(), + leading: const Icon(PhosphorIcons.arrowArcLeftLight), onTap: () { Navigator.of(context).pop(); Navigator.of(context).pop(); @@ -51,17 +52,18 @@ class _CoursePartDrawerState extends State { ), if (supportUrl != null) ListTile( - title: Text('course.support').tr(), + title: const Text('course.support').tr(), onTap: () => launch(supportUrl), - leading: Icon(PhosphorIcons.questionLight), + leading: const Icon(PhosphorIcons.questionLight), ), - Divider(), + const Divider(), FutureBuilder>( future: _buildFuture(), builder: (context, snapshot) { if (!snapshot.hasData || - snapshot.connectionState == ConnectionState.waiting) - return Center(child: CircularProgressIndicator()); + snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } if (snapshot.hasError) return Text("Error: ${snapshot.error}"); var parts = snapshot.data!; var args = Modular.args.queryParams; diff --git a/app/lib/courses/home.dart b/app/lib/courses/home.dart index 7356cbc9..7c77c237 100644 --- a/app/lib/courses/home.dart +++ b/app/lib/courses/home.dart @@ -11,6 +11,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; class CoursesPage extends StatefulWidget { + const CoursesPage({Key? key}) : super(key: key); + @override _CoursesPageState createState() => _CoursesPageState(); } @@ -18,7 +20,7 @@ class CoursesPage extends StatefulWidget { class _ItemFetcher { final _itemsPerPage = 5; int _currentPage = 0; - Box _favoriteBox = Hive.box('favorite'); + final Box _favoriteBox = Hive.box('favorite'); List entries = []; final List servers; @@ -49,8 +51,9 @@ class _ItemFetcher { var index = _currentPage * _itemsPerPage + i; var entry = entries[index]; if (entry.body.toUpperCase().contains(query.toUpperCase()) || - entry.name.toUpperCase().contains(query.toUpperCase())) + entry.name.toUpperCase().contains(query.toUpperCase())) { list.add(entry); + } } _currentPage++; return list; @@ -58,7 +61,7 @@ class _ItemFetcher { } class CustomSearchDelegate extends SearchDelegate { - var _itemFetcher; + final _ItemFetcher _itemFetcher; final List? servers; final bool gridView; @@ -68,7 +71,7 @@ class CustomSearchDelegate extends SearchDelegate { return [ IconButton( tooltip: "clear".tr(), - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), onPressed: () { query = ''; }, @@ -80,7 +83,7 @@ class CustomSearchDelegate extends SearchDelegate { Widget buildLeading(BuildContext context) { return IconButton( tooltip: "back".tr(), - icon: Icon(PhosphorIcons.arrowArcLeftLight), + icon: const Icon(PhosphorIcons.arrowArcLeftLight), onPressed: () { close(context, null); }, @@ -117,8 +120,8 @@ class CustomSearchDelegate extends SearchDelegate { } class _CoursesPageState extends State { - var _itemFetcher; - var _box = Hive.box('servers'); + late _ItemFetcher _itemFetcher; + final _box = Hive.box('servers'); bool gridView = false; final List _filteredServers = []; @@ -134,7 +137,7 @@ class _CoursesPageState extends State { return Scaffold( appBar: MyAppBar(title: "courses.title".tr(), actions: [ IconButton( - icon: Icon(PhosphorIcons.magnifyingGlassLight), + icon: const Icon(PhosphorIcons.magnifyingGlassLight), tooltip: "search".tr(), onPressed: () { showSearch( @@ -143,16 +146,16 @@ class _CoursesPageState extends State { ); }), IconButton( - icon: Icon(PhosphorIcons.funnelLight), + icon: const Icon(PhosphorIcons.funnelLight), tooltip: "courses.filter".tr(), onPressed: () async { await showDialog( context: context, builder: (context) => AlertDialog( - title: Text("courses.filter").tr(), + title: const Text("courses.filter").tr(), actions: [ TextButton.icon( - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), label: Text("close".tr().toUpperCase()), onPressed: () => Navigator.of(context).pop()) ], @@ -218,7 +221,7 @@ class _CoursesListState extends State { bool _isLoading = true; bool _hasMore = true; - Box _favoriteBox = Hive.box('favorite'); + final Box _favoriteBox = Hive.box('favorite'); @override void initState() { super.initState(); @@ -289,12 +292,12 @@ class _CoursesListState extends State { tag: "course-icon-${course.server?.index}-${course.slug}", child: UniversalImage(type: course.icon, url: course.url + "/icon")); - if (widget.gridView) + if (widget.gridView) { return Card( child: InkWell( onTap: onTap, child: Container( - constraints: BoxConstraints(maxWidth: 250), + constraints: const BoxConstraints(maxWidth: 250), padding: const EdgeInsets.all(8.0), child: SizedBox( height: 250, @@ -313,6 +316,7 @@ class _CoursesListState extends State { ]) ]), )))); + } return ListTile( title: Text(course.name), subtitle: Text(course.description), @@ -331,7 +335,7 @@ class _CoursesListState extends State { if (!_isLoading) { _loadMore(); } - return Center( + return const Center( child: SizedBox( child: CircularProgressIndicator(), height: 24, @@ -346,16 +350,15 @@ class _CoursesListState extends State { @override Widget build(BuildContext context) { - return Container( - child: Scrollbar( - child: SingleChildScrollView( - child: widget.gridView - ? Container( - width: double.infinity, - alignment: Alignment.center, - child: Wrap(children: _buildList(context))) - : Column( - // Need to display a loading tile if more items are coming - children: _buildList(context))))); + return Scrollbar( + child: SingleChildScrollView( + child: widget.gridView + ? Container( + width: double.infinity, + alignment: Alignment.center, + child: Wrap(children: _buildList(context))) + : Column( + // Need to display a loading tile if more items are coming + children: _buildList(context)))); } } diff --git a/app/lib/courses/module.dart b/app/lib/courses/module.dart index d46a29f2..c897c05a 100644 --- a/app/lib/courses/module.dart +++ b/app/lib/courses/module.dart @@ -8,10 +8,11 @@ import 'home.dart'; class CourseModule extends Module { @override List get routes => [ - ChildRoute('/', child: (_, args) => CoursesPage()), + ChildRoute('/', child: (_, args) => const CoursesPage()), ChildRoute('/details', child: (_, args) => CoursePage(model: args.data)), ModuleRoute('/start', module: CoursePartModule()), ]; + @override List> get binds => [Bind.singleton((i) => CourseBloc())]; } diff --git a/app/lib/courses/part/bloc.dart b/app/lib/courses/part/bloc.dart index 998f4ca7..fdbcc4f1 100644 --- a/app/lib/courses/part/bloc.dart +++ b/app/lib/courses/part/bloc.dart @@ -1,5 +1,6 @@ import 'package:dev_doctor/models/editor/server.dart'; import 'package:dev_doctor/models/part.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter_modular/flutter_modular.dart'; import 'package:rxdart/rxdart.dart'; @@ -7,8 +8,10 @@ import '../bloc.dart'; class CoursePartBloc extends CourseBloc { BehaviorSubject partSubject = BehaviorSubject(); - String? course, part; - CoursePartBloc() {} + String? part; + + CoursePartBloc(); + @override Future fetch( {ServerEditorBloc? editorBloc, String? server, @@ -43,7 +46,9 @@ class CoursePartBloc extends CourseBloc { if (current == null) error = true; }).asFuture(); } catch (e) { - print("Error $e"); + if (kDebugMode) { + print("Error $e"); + } error = true; } } diff --git a/app/lib/courses/part/details.dart b/app/lib/courses/part/details.dart index d7817fc8..eb3b07c8 100644 --- a/app/lib/courses/part/details.dart +++ b/app/lib/courses/part/details.dart @@ -30,8 +30,9 @@ class PartDetailsPage extends StatefulWidget { class _PartDetailsPageState extends State { Future _buildFuture() async { if (widget.model != null) return widget.model!; - if (widget.editorBloc != null) + if (widget.editorBloc != null) { return widget.editorBloc!.getCourse(widget.course!).parts[widget.partId!]; + } var server = await CoursesServer.fetch(index: widget.serverId); var course = await server?.fetchCourse(widget.course!); return course?.fetchPart( @@ -44,18 +45,19 @@ class _PartDetailsPageState extends State { future: _buildFuture(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting || - !snapshot.hasData) - return Center(child: CircularProgressIndicator()); + !snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } if (snapshot.hasError) return Text("Error: ${snapshot.error}"); var part = snapshot.data; - if (part != null) + if (part != null) { return Scaffold( appBar: MyAppBar(title: part.name), body: Scrollbar( child: ListView(children: [ Card( child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: const BoxConstraints(maxWidth: 1000), child: Column(children: [ Text("course.details.statistics.title", style: Theme.of(context).textTheme.headline5) @@ -63,7 +65,8 @@ class _PartDetailsPageState extends State { ]), )) ]))); - return ErrorDisplay(); + } + return const ErrorDisplay(); }); } } diff --git a/app/lib/courses/part/item.dart b/app/lib/courses/part/item.dart index 7da755f6..c673f965 100644 --- a/app/lib/courses/part/item.dart +++ b/app/lib/courses/part/item.dart @@ -35,9 +35,9 @@ class PartItemPage extends StatefulWidget { class _PartItemPageState extends State { late CoursePartBloc bloc; - GlobalKey _itemKey = GlobalKey(); - ScrollController _detailsScrollController = ScrollController(); - ScrollController _itemScrollController = ScrollController(); + final GlobalKey _itemKey = GlobalKey(); + final ScrollController _detailsScrollController = ScrollController(); + final ScrollController _itemScrollController = ScrollController(); @override void initState() { @@ -61,10 +61,11 @@ class _PartItemPageState extends State { return StreamBuilder( stream: bloc.partSubject, builder: (context, snapshot) { - if (snapshot.hasError || bloc.hasError) return ErrorDisplay(); + if (snapshot.hasError || bloc.hasError) return const ErrorDisplay(); if (!snapshot.hasData || - snapshot.connectionState == ConnectionState.waiting) - return Center(child: CircularProgressIndicator()); + snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } var part = snapshot.data!; if (part.items.isEmpty) { return PartItemLayout( @@ -77,35 +78,37 @@ class _PartItemPageState extends State { if (itemId < 0) itemId = 0; if (itemId >= part.items.length) itemId = part.items.length - 1; var item = part.items[itemId]; - Widget itemWidget = Text("Not supported!"); - if (item is VideoPartItem) + Widget itemWidget = const Text("Not supported!"); + if (item is VideoPartItem) { itemWidget = VideoPartItemPage( part: part, item: item, key: _itemKey, editorBloc: widget.editorBloc, itemId: itemId); - if (item is TextPartItem) + } + if (item is TextPartItem) { itemWidget = TextPartItemPage( part: part, item: item, key: _itemKey, editorBloc: widget.editorBloc, itemId: itemId); - if (item is QuizPartItem) + } + if (item is QuizPartItem) { itemWidget = QuizPartItemPage( part: part, item: item, key: _itemKey, editorBloc: widget.editorBloc, itemId: itemId); + } final itemBuilder = Builder(builder: (context) => itemWidget); return PartItemLayout( part: part, editorBloc: widget.editorBloc, itemId: widget.itemId, - child: Container( - child: LayoutBuilder(builder: (context, constraints) { + child: LayoutBuilder(builder: (context, constraints) { var itemCard = Scrollbar( controller: _detailsScrollController, child: SingleChildScrollView( @@ -113,10 +116,9 @@ class _PartItemPageState extends State { child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16)), - child: Container( - child: Padding( - padding: const EdgeInsets.all(64.0), - child: itemBuilder))))); + child: Padding( + padding: const EdgeInsets.all(64.0), + child: itemBuilder)))); var detailsCard = Scrollbar( controller: _itemScrollController, child: SingleChildScrollView( @@ -138,7 +140,8 @@ class _PartItemPageState extends State { if (widget.editorBloc != null) IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: + const Icon(PhosphorIcons.pencilLight), onPressed: () => Modular.to.pushNamed(Uri( pathSegments: [ '', @@ -154,27 +157,28 @@ class _PartItemPageState extends State { else if (item.allowReset) IconButton( tooltip: "reset".tr(), - icon: Icon(PhosphorIcons + icon: const Icon(PhosphorIcons .clockCounterClockwiseLight), onPressed: () { part.removeItemPoints(itemId); bloc.partSubject.add(part); }) ]))))); - if (MediaQuery.of(context).size.width > 1000) + if (MediaQuery.of(context).size.width > 1000) { return Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded(child: detailsCard), Expanded(flex: 3, child: itemCard) ]); - else + } else { return Scrollbar( child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [detailsCard, itemCard]))); - }))); + } + })); }); } } diff --git a/app/lib/courses/part/layout.dart b/app/lib/courses/part/layout.dart index c7330b22..e897ab30 100644 --- a/app/lib/courses/part/layout.dart +++ b/app/lib/courses/part/layout.dart @@ -64,19 +64,19 @@ class _PartItemLayoutState extends State { if (widget.part.items.isNotEmpty) IconButton( tooltip: "course.delete.item.tooltip".tr(), - icon: Icon(PhosphorIcons.minusCircleLight), + icon: const Icon(PhosphorIcons.minusCircleLight), onPressed: () => _showDeleteDialog(widget.part, widget.itemId ?? 0)), IconButton( tooltip: "course.add.item.tooltip".tr(), - icon: Icon(PhosphorIcons.plusCircleLight), + icon: const Icon(PhosphorIcons.plusCircleLight), onPressed: () => _showCreateDialog(widget.part)), EditorCoursePartPopupMenu( bloc: widget.editorBloc!, partBloc: Modular.get()) ] else IconButton( - icon: Icon(PhosphorIcons.shareNetworkLight), + icon: const Icon(PhosphorIcons.shareNetworkLight), tooltip: "share".tr(), onPressed: () { Clipboard.setData(ClipboardData( @@ -114,7 +114,7 @@ class _PartItemLayoutState extends State { overflow: TextOverflow.fade, style: widget.editorBloc == null && !widget.part.itemVisited(index) - ? TextStyle(fontWeight: FontWeight.bold) + ? const TextStyle(fontWeight: FontWeight.bold) : null); return Tab(icon: Icon(item.icon), child: text); })), @@ -147,11 +147,10 @@ class _PartItemLayoutState extends State { child: Text("create".tr().toUpperCase())) ], title: Text("course.add.item.title".tr()), - content: Container( - child: Form( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ + content: Form( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ TextFormField( controller: nameController, decoration: InputDecoration( @@ -175,7 +174,7 @@ class _PartItemLayoutState extends State { child: Text("course.type.${e.name}".tr()), value: e)) .toList()) - ]))))); + ])))); } Future _createItem(CoursePart part, diff --git a/app/lib/courses/part/quiz.dart b/app/lib/courses/part/quiz.dart index af6f820a..b2b6e8a9 100644 --- a/app/lib/courses/part/quiz.dart +++ b/app/lib/courses/part/quiz.dart @@ -30,7 +30,7 @@ class QuizPartItemPage extends StatefulWidget { class _QuizPartItemPageState extends State { final _formKey = GlobalKey(); - int? _points = null; + int? _points; late CoursePartBloc bloc; @override @@ -58,29 +58,30 @@ class _QuizPartItemPageState extends State { showDialog( context: context, builder: (context) => AlertDialog( - title: Text("course.quiz.validation.title").tr(), + title: const Text("course.quiz.validation.title").tr(), content: Text("course.quiz.validation." + (validate ? "correct" : "wrong")) .tr(), actions: [ TextButton.icon( onPressed: () => Navigator.of(context).pop(), - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), label: Text("close".tr().toUpperCase())) ], )); - } else + } else { _points = null; + } } - Timer? _timer = null; - int? _start = null; + Timer? _timer; + int? _start; void startTimer() { - const oneSec = const Duration(seconds: 1); + const oneSec = Duration(seconds: 1); _start = widget.item.time; - if (widget.editorBloc == null) - _timer = new Timer.periodic( + if (widget.editorBloc == null) { + _timer = Timer.periodic( oneSec, (Timer timer) { if (_start == 0) { @@ -92,13 +93,16 @@ class _QuizPartItemPageState extends State { } }, ); + } } @override Widget build(BuildContext context) { if (widget.editorBloc == null && widget.part.itemVisited(widget.itemId) && - _points == null) return _buildEvaluation(); + _points == null) { + return _buildEvaluation(); + } return Container( child: _timer != null || widget.item.time == null || @@ -110,7 +114,7 @@ class _QuizPartItemPageState extends State { builder: (context) => Column(children: [ if (_points != null) Padding( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 32), child: _buildEvaluation(), ) @@ -118,7 +122,7 @@ class _QuizPartItemPageState extends State { Container(), if (_start != null || widget.editorBloc != null) Padding( - padding: EdgeInsets.symmetric( + padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 32), child: Row(children: [ Expanded( @@ -144,13 +148,14 @@ class _QuizPartItemPageState extends State { if (widget.editorBloc != null) ...[ IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: const Icon( + PhosphorIcons.pencilLight), onPressed: () => _showTimerDialog()), if (_start != null) IconButton( tooltip: "delete".tr(), - icon: - Icon(PhosphorIcons.trashLight), + icon: const Icon( + PhosphorIcons.trashLight), onPressed: () async { updateItem(widget.item.copyWith( time: null, timer: false)); @@ -210,8 +215,9 @@ class _QuizPartItemPageState extends State { FormField>( validator: (value) { if (_points == null) return null; - if (value == null) + if (value == null) { return "course.quiz.choose".tr(); + } var correct = true; for (var i = 0; i < value.length; i++) { if (value[i] == question.answers[i].correct) { @@ -229,7 +235,7 @@ class _QuizPartItemPageState extends State { } return null; }, - initialValue: new List.filled( + initialValue: List.filled( question.answers.length, false), builder: (field) => Column(children: [ ...List.generate(question.answers.length, @@ -301,7 +307,8 @@ class _QuizPartItemPageState extends State { field.hasError ? Text( field.errorText!, - style: TextStyle(color: Colors.red), + style: const TextStyle( + color: Colors.red), ) : Container() ])), @@ -309,8 +316,9 @@ class _QuizPartItemPageState extends State { FormField( validator: (value) { if (_points == null) return null; - if (value == null) + if (value == null) { return "course.quiz.choose".tr(); + } if (!question.answers[value].correct) { _points = _points! - question.answers[value].minusPoints; @@ -319,6 +327,7 @@ class _QuizPartItemPageState extends State { } _points = _points! + question.answers[value].points; + return null; }, builder: (field) => Column(children: [ ...List.generate(question.answers.length, @@ -384,7 +393,8 @@ class _QuizPartItemPageState extends State { field.hasError ? Text( field.errorText!, - style: TextStyle(color: Colors.red), + style: const TextStyle( + color: Colors.red), ) : Container() ])) @@ -426,19 +436,19 @@ class _QuizPartItemPageState extends State { .tr())))); }, label: Text("course.quiz.add".tr()), - icon: Icon(PhosphorIcons.plusLight)), - SizedBox(height: 20) + icon: const Icon(PhosphorIcons.plusLight)), + const SizedBox(height: 20) ] ]), if (_points == null) ElevatedButton.icon( onPressed: () => validate(), - icon: Icon(PhosphorIcons.checkLight), + icon: const Icon(PhosphorIcons.checkLight), label: Text("course.quiz.check".tr().toUpperCase())) ])) : Center( child: ElevatedButton.icon( - icon: Icon(PhosphorIcons.playLight), + icon: const Icon(PhosphorIcons.playLight), onPressed: () => setState(() => startTimer()), label: Text("course.quiz.start".tr().toUpperCase())))); } @@ -455,9 +465,9 @@ class _QuizPartItemPageState extends State { .tr(), if (widget.item.allowReset) Padding( - padding: EdgeInsets.all(4), + padding: const EdgeInsets.all(4), child: ElevatedButton.icon( - icon: Icon(PhosphorIcons.arrowCounterClockwiseLight), + icon: const Icon(PhosphorIcons.arrowCounterClockwiseLight), onPressed: () => setState(() { _points = null; _formKey.currentState?.reset(); @@ -576,7 +586,7 @@ extension QuestionOptionExtension on QuestionOption { questions: List.from(item.questions) ..[questionId] = question.copyWith( answers: List.from(question.answers) - ..add(QuizAnswer())))); + ..add(const QuizAnswer())))); break; case QuestionOption.title: TextEditingController titleController = @@ -682,7 +692,7 @@ extension QuestionOptionExtension on QuestionOption { onPressed: () { Navigator.of(context).pop(); }, - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), label: Text("no".tr().toUpperCase())), TextButton.icon( onPressed: () { @@ -696,13 +706,15 @@ extension QuestionOptionExtension on QuestionOption { List.from(item.questions) ..removeAt(questionId))); }, - icon: Icon(PhosphorIcons.checkLight), + icon: const Icon(PhosphorIcons.checkLight), label: Text("yes".tr().toUpperCase())) ], title: - Text("course.quiz.option.question.delete.title").tr(), - content: Text("course.quiz.option.question.delete.content") - .tr(namedArgs: { + const Text("course.quiz.option.question.delete.title") + .tr(), + content: + const Text("course.quiz.option.question.delete.content") + .tr(namedArgs: { "index": questionId.toString(), "name": question.title }))); @@ -911,7 +923,7 @@ extension AnswerOptionExtension on AnswerOption { onPressed: () { Navigator.of(context).pop(); }, - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), label: Text("no".tr().toUpperCase())), TextButton.icon( onPressed: () { @@ -926,12 +938,14 @@ extension AnswerOptionExtension on AnswerOption { List.from(question.answers) ..removeAt(answerId))); }, - icon: Icon(PhosphorIcons.checkLight), + icon: const Icon(PhosphorIcons.checkLight), label: Text("yes".tr().toUpperCase())) ], - title: Text("course.quiz.option.answer.delete.title").tr(), - content: Text("course.quiz.option.answer.delete.content") - .tr(namedArgs: { + title: const Text("course.quiz.option.answer.delete.title") + .tr(), + content: + const Text("course.quiz.option.answer.delete.content") + .tr(namedArgs: { "index": answerId.toString(), "name": answer.name }))); diff --git a/app/lib/courses/part/text.dart b/app/lib/courses/part/text.dart index 6b7e8b4e..bad05c96 100644 --- a/app/lib/courses/part/text.dart +++ b/app/lib/courses/part/text.dart @@ -44,8 +44,7 @@ class _TextPartItemPageState extends State { @override Widget build(BuildContext context) { - return Container( - child: Row(children: [ + return Row(children: [ Expanded( child: MarkdownBody( styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context)), @@ -60,7 +59,7 @@ class _TextPartItemPageState extends State { if (widget.editorBloc != null) IconButton( tooltip: "edit".tr(), - icon: Icon(PhosphorIcons.pencilLight), + icon: const Icon(PhosphorIcons.pencilLight), onPressed: () { Modular.to.push(MaterialPageRoute( builder: (context) => MarkdownEditor( @@ -79,6 +78,6 @@ class _TextPartItemPageState extends State { widget.editorBloc!.save(); }))); }) - ])); + ]); } } diff --git a/app/lib/courses/part/video.dart b/app/lib/courses/part/video.dart index 4d3432f7..1e43c465 100644 --- a/app/lib/courses/part/video.dart +++ b/app/lib/courses/part/video.dart @@ -44,16 +44,15 @@ class _VideoPartItemPageState extends State { Widget build(BuildContext context) { return Row(children: [ Expanded( - child: Container( - child: Center( - child: widget.item.url.isEmpty - ? Text('course.video.empty').tr() - : ElevatedButton.icon( - icon: Icon(PhosphorIcons.playLight), - label: Text("course.video.open".tr().toUpperCase()), - onPressed: () => launch( - widget.item.getSource(widget.part).toString()), - )))), + child: Center( + child: widget.item.url.isEmpty + ? const Text('course.video.empty').tr() + : ElevatedButton.icon( + icon: const Icon(PhosphorIcons.playLight), + label: Text("course.video.open".tr().toUpperCase()), + onPressed: () => + launch(widget.item.getSource(widget.part).toString()), + ))), if (widget.editorBloc != null) IconButton( tooltip: "edit".tr(), @@ -62,7 +61,7 @@ class _VideoPartItemPageState extends State { editorBloc: widget.editorBloc, item: widget.item, itemId: widget.itemId))), - icon: Icon(PhosphorIcons.pencilLight)) + icon: const Icon(PhosphorIcons.pencilLight)) ]); } } @@ -100,7 +99,7 @@ class _VideoPartItemEditorPageState extends State { body: Scrollbar( child: Center( child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: const BoxConstraints(maxWidth: 1000), child: ListView(children: [ TextField( controller: _urlController, @@ -125,7 +124,7 @@ class _VideoPartItemEditorPageState extends State { ])))), floatingActionButton: FloatingActionButton( tooltip: "save".tr(), - child: Icon(PhosphorIcons.floppyDiskLight), + child: const Icon(PhosphorIcons.floppyDiskLight), onPressed: () async { var bloc = Modular.get(); var courseBloc = widget.editorBloc!.getCourse(bloc.course!); diff --git a/app/lib/courses/part/video_mobile.dart b/app/lib/courses/part/video_mobile.dart index e5a9cd96..02d7b518 100644 --- a/app/lib/courses/part/video_mobile.dart +++ b/app/lib/courses/part/video_mobile.dart @@ -9,7 +9,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_modular/flutter_modular.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; import 'bloc.dart'; -import 'video.dart' as defaultVideo; +import 'video.dart' as default_video; class VideoPartItemPage extends StatefulWidget { final VideoPartItem item; @@ -44,12 +44,12 @@ class _VideoPartItemPageState extends State { @override Widget build(BuildContext context) { - if (Platform.isAndroid || Platform.isIOS) + if (Platform.isAndroid || Platform.isIOS) { return Row(children: [ Expanded( child: Container( child: isEmpty - ? Center(child: Text('course.video.empty').tr()) + ? Center(child: const Text('course.video.empty').tr()) : SafeArea( child: AspectRatio( aspectRatio: 16 / 9, @@ -65,17 +65,18 @@ class _VideoPartItemPageState extends State { IconButton( tooltip: "edit".tr(), onPressed: () => Modular.to.push(MaterialPageRoute( - builder: (context) => defaultVideo.VideoPartItemEditorPage( + builder: (context) => default_video.VideoPartItemEditorPage( editorBloc: widget.editorBloc, item: widget.item, itemId: widget.itemId))), - icon: Icon(PhosphorIcons.pencilLight)) + icon: const Icon(PhosphorIcons.pencilLight)) ]); - else - return defaultVideo.VideoPartItemPage( + } else { + return default_video.VideoPartItemPage( part: widget.part, itemId: widget.itemId, item: widget.item, editorBloc: widget.editorBloc); + } } } diff --git a/app/lib/courses/part/video_web.dart b/app/lib/courses/part/video_web.dart index ee2d0bb3..d01c79f1 100644 --- a/app/lib/courses/part/video_web.dart +++ b/app/lib/courses/part/video_web.dart @@ -11,7 +11,7 @@ import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_modular/flutter_modular.dart'; import 'bloc.dart'; -import 'video.dart' as defaultVideo; +import 'video.dart' as default_video; class VideoPartItemPage extends StatefulWidget { final VideoPartItem item; @@ -73,17 +73,18 @@ class _VideoPartItemPageState extends State { @override Widget build(BuildContext context) { - if (widget.editorBloc != null) - return defaultVideo.VideoPartItemPage( + if (widget.editorBloc != null) { + return default_video.VideoPartItemPage( part: widget.part, editorBloc: widget.editorBloc, item: widget.item, itemId: widget.itemId); + } return Row(children: [ Expanded( child: Container( child: widget.item.url.isEmpty - ? Center(child: Text('course.video.empty').tr()) + ? Center(child: const Text('course.video.empty').tr()) : AspectRatio( child: _iframeWidget!, aspectRatio: 16 / 9, @@ -92,11 +93,11 @@ class _VideoPartItemPageState extends State { IconButton( tooltip: "edit".tr(), onPressed: () => Modular.to.push(MaterialPageRoute( - builder: (context) => defaultVideo.VideoPartItemEditorPage( + builder: (context) => default_video.VideoPartItemEditorPage( editorBloc: widget.editorBloc, item: widget.item, itemId: widget.itemId))), - icon: Icon(PhosphorIcons.pencilLight)) + icon: const Icon(PhosphorIcons.pencilLight)) ]); } } diff --git a/app/lib/courses/statistics.dart b/app/lib/courses/statistics.dart index 6ac5bfbd..cda73958 100644 --- a/app/lib/courses/statistics.dart +++ b/app/lib/courses/statistics.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:dev_doctor/models/course.dart'; import 'package:dev_doctor/models/part.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_modular/flutter_modular.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -21,145 +22,140 @@ class CourseStatisticsView extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - child: FutureBuilder>( - future: course.fetchParts(), - builder: (context, snapshot) { - if (!snapshot.hasData || - snapshot.connectionState == ConnectionState.waiting) - return Center(child: CircularProgressIndicator()); - if (snapshot.hasError) return Text("Error: ${snapshot.error}"); - var parts = snapshot.data!; - double allProgress = 0; - var allScore = 0; - var allMaxScore = 0; - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - ...List.generate(parts.length, (index) { - var part = parts[index]; - double progress = 0; - for (var i = 0; i < part.items.length; i++) - if (part.itemVisited(i)) progress += 1; - progress /= part.items.length; - allProgress += progress; - int points = 0; - int maxPoints = 0; - for (var i = 0; i < part.items.length; i++) { - maxPoints += part.items[i].points; - if (part.itemVisited(i)) - points += part.getItemPoints(i) ?? 0; - } - allScore += points.toInt(); - allMaxScore += maxPoints.toInt(); + return FutureBuilder>( + future: course.fetchParts(), + builder: (context, snapshot) { + if (!snapshot.hasData || + snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } + if (snapshot.hasError) return Text("Error: ${snapshot.error}"); + var parts = snapshot.data!; + double allProgress = 0; + var allScore = 0; + var allMaxScore = 0; + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ...List.generate(parts.length, (index) { + var part = parts[index]; + double progress = 0; + for (var i = 0; i < part.items.length; i++) { + if (part.itemVisited(i)) progress += 1; + } + progress /= part.items.length; + allProgress += progress; + int points = 0; + int maxPoints = 0; + for (var i = 0; i < part.items.length; i++) { + maxPoints += part.items[i].points; + if (part.itemVisited(i)) { + points += part.getItemPoints(i) ?? 0; + } + } + allScore += points.toInt(); + allMaxScore += maxPoints.toInt(); - return Padding( - padding: EdgeInsets.all(4), - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16)), - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 16, vertical: 32), - child: Column(children: [ - Text(part.name, - style: Theme.of(context) - .textTheme - .headline6), - SizedBox(height: 50), - Text("course.progress".tr() + - " " + - (progress * 100).round().toString() + - "%"), - LinearProgressIndicator(value: progress), - SizedBox(height: 50), - Wrap( - children: List.generate( - part.items.length, (index) { - var item = part.items[index]; - return IconButton( - tooltip: "${item.name}" + - (part.itemVisited(index) - ? " ${part.getItemPoints(index)}/${item.points}" - : " 0/${item.points}"), - icon: Icon(item.icon, - color: part.itemVisited(index) - ? Theme.of(context) - .primaryColor - : null), - onPressed: () => Modular.to - .pushNamed( - Uri(pathSegments: [ - "", - "courses", - "start", - "item" - ], queryParameters: { - "serverId": course - .server?.index - ?.toString(), - "course": course.slug, - "part": part.slug, - "itemId": index.toString() - }).toString())); - })), - SizedBox(height: 50), - Text("course.points".tr() + - " " + - points.toString() + - "/" + - maxPoints.toString()), - LinearProgressIndicator( - value: points / maxPoints), - ])))); - }), - Builder(builder: (context) { - allProgress /= parts.length; - return Padding( - padding: EdgeInsets.symmetric( - horizontal: 4, vertical: 64), - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16)), - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 16, vertical: 32), - child: Column(children: [ - Text("course.progress".tr() + - " " + - (allProgress * 100) - .round() - .toString() + - "%"), - LinearProgressIndicator( - value: allProgress), - SizedBox(height: 50), - Text("course.points".tr() + - " " + - allScore.toString() + - "/" + - allMaxScore.toString()), - LinearProgressIndicator( - value: allScore / allMaxScore), - SizedBox(height: 50), - ElevatedButton.icon( - onPressed: () => _downloadCertificate( - context, - allProgress, - allScore, - allMaxScore), - icon: - Icon(PhosphorIcons.downloadLight), - label: Text( - "course.certificate.button" - .tr() - .toUpperCase())) - ])))); - }) - ]), - ); - })); + return Padding( + padding: const EdgeInsets.all(4), + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16)), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 32), + child: Column(children: [ + Text(part.name, + style: Theme.of(context) + .textTheme + .headline6), + const SizedBox(height: 50), + Text("course.progress".tr() + + " " + + (progress * 100).round().toString() + + "%"), + LinearProgressIndicator(value: progress), + const SizedBox(height: 50), + Wrap( + children: List.generate(part.items.length, + (index) { + var item = part.items[index]; + return IconButton( + tooltip: item.name + + (part.itemVisited(index) + ? " ${part.getItemPoints(index)}/${item.points}" + : " 0/${item.points}"), + icon: Icon(item.icon, + color: part.itemVisited(index) + ? Theme.of(context).primaryColor + : null), + onPressed: () => Modular.to + .pushNamed(Uri(pathSegments: [ + "", + "courses", + "start", + "item" + ], queryParameters: { + "serverId": course.server?.index + ?.toString(), + "course": course.slug, + "part": part.slug, + "itemId": index.toString() + }).toString())); + })), + const SizedBox(height: 50), + Text("course.points".tr() + + " " + + points.toString() + + "/" + + maxPoints.toString()), + LinearProgressIndicator( + value: points / maxPoints), + ])))); + }), + Builder(builder: (context) { + allProgress /= parts.length; + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, vertical: 64), + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16)), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 32), + child: Column(children: [ + Text("course.progress".tr() + + " " + + (allProgress * 100).round().toString() + + "%"), + LinearProgressIndicator(value: allProgress), + const SizedBox(height: 50), + Text("course.points".tr() + + " " + + allScore.toString() + + "/" + + allMaxScore.toString()), + LinearProgressIndicator( + value: allScore / allMaxScore), + const SizedBox(height: 50), + ElevatedButton.icon( + onPressed: () => _downloadCertificate( + context, + allProgress, + allScore, + allMaxScore), + icon: const Icon( + PhosphorIcons.downloadLight), + label: Text("course.certificate.button" + .tr() + .toUpperCase())) + ])))); + }) + ]), + ); + }); } Future _downloadCertificate(BuildContext buildContext, double progress, @@ -168,11 +164,11 @@ class CourseStatisticsView extends StatelessWidget { buildContext.showBlockDialog( dismissCompleter: completer, ); - await Future.delayed(Duration(seconds: 1)); + await Future.delayed(const Duration(seconds: 1)); try { var logoImage = await imageFromAssetBundle("images/logo.png"); final pdf = pw.Document(); - pw.Widget? image = null; + pw.Widget? image; if (course.icon.isNotEmpty) { var url = course.url + "/icon." + course.icon; switch (course.icon) { @@ -243,7 +239,9 @@ class CourseStatisticsView extends StatelessWidget { await Printing.sharePdf( bytes: await pdf.save(), filename: 'certificate.pdf'); } catch (e) { - print("Error $e"); + if (kDebugMode) { + print("Error $e"); + } } completer.complete(); } diff --git a/app/lib/editor/author.dart b/app/lib/editor/author.dart index 943b343c..c9befec5 100644 --- a/app/lib/editor/author.dart +++ b/app/lib/editor/author.dart @@ -22,11 +22,11 @@ class _AuthorEditingPageState extends State { TextEditingController? _nameController; TextEditingController? _urlController; TextEditingController? _avatarController; - GlobalKey _formKey = GlobalKey(); + final GlobalKey _formKey = GlobalKey(); late Author _author; @override void initState() { - _author = widget.author ?? Author(); + _author = widget.author ?? const Author(); _nameController = TextEditingController(text: _author.name); _urlController = TextEditingController(text: _author.url); _avatarController = TextEditingController(text: _author.avatar); @@ -42,12 +42,13 @@ class _AuthorEditingPageState extends State { child: Scrollbar( child: Center( child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: const BoxConstraints(maxWidth: 1000), child: ListView(children: [ TextFormField( validator: (value) { - if (value!.isEmpty) + if (value!.isEmpty) { return "course.author.name.empty".tr(); + } return null; }, decoration: InputDecoration( @@ -78,12 +79,12 @@ class _AuthorEditingPageState extends State { avatar: _avatarController!.text)), keyboardType: TextInputType.url, controller: _avatarController), - SizedBox(height: 10), + const SizedBox(height: 10), AuthorDisplay(author: _author), - SizedBox(height: 10) + const SizedBox(height: 10) ]))))), floatingActionButton: FloatingActionButton( - child: Icon(PhosphorIcons.checkLight), + child: const Icon(PhosphorIcons.checkLight), tooltip: "editor.create.submit".tr(), onPressed: () => widget.onSubmit(_author))); } diff --git a/app/lib/editor/code.dart b/app/lib/editor/code.dart index e9eb72c3..c856b427 100644 --- a/app/lib/editor/code.dart +++ b/app/lib/editor/code.dart @@ -31,7 +31,7 @@ class _EditorCodeDialogPageState extends State { appBar: MyAppBar(title: 'editor.code.title'.tr()), body: Center( child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: const BoxConstraints(maxWidth: 1000), child: ListView(children: [ TextField( controller: codeController, @@ -49,7 +49,7 @@ class _EditorCodeDialogPageState extends State { Modular.to.pop(data); } }, - icon: Icon(PhosphorIcons.checkLight), + icon: const Icon(PhosphorIcons.checkLight), label: Text('editor.code.submit'.tr()))); } } diff --git a/app/lib/editor/create.dart b/app/lib/editor/create.dart index f8ecdaf1..15d0554e 100644 --- a/app/lib/editor/create.dart +++ b/app/lib/editor/create.dart @@ -6,15 +6,17 @@ import 'package:hive/hive.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; class CreateServerPage extends StatefulWidget { + const CreateServerPage({Key? key}) : super(key: key); + @override _CreateServerPageState createState() => _CreateServerPageState(); } class _CreateServerPageState extends State { - TextEditingController _nameController = TextEditingController(); - TextEditingController _noteController = TextEditingController(); - GlobalKey _formKey = GlobalKey(); - Box _box = Hive.box('editor'); + final TextEditingController _nameController = TextEditingController(); + final TextEditingController _noteController = TextEditingController(); + final GlobalKey _formKey = GlobalKey(); + final Box _box = Hive.box('editor'); @override Widget build(BuildContext context) { var _names = _box.values.map((e) => e.server.name); @@ -25,14 +27,16 @@ class _CreateServerPageState extends State { child: Scrollbar( child: Center( child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: const BoxConstraints(maxWidth: 1000), child: ListView(children: [ TextFormField( validator: (value) { - if (value!.isEmpty) + if (value!.isEmpty) { return "editor.create.name.empty".tr(); - if (_names.contains(value)) + } + if (_names.contains(value)) { return "editor.create.name.exist".tr(); + } return null; }, decoration: InputDecoration( @@ -46,7 +50,7 @@ class _CreateServerPageState extends State { controller: _noteController) ]))))), floatingActionButton: FloatingActionButton( - child: Icon(PhosphorIcons.checkLight), + child: const Icon(PhosphorIcons.checkLight), tooltip: "editor.create.submit".tr(), onPressed: () async { if (_formKey.currentState!.validate()) { diff --git a/app/lib/editor/home.dart b/app/lib/editor/home.dart index 2db9c562..a36f724c 100644 --- a/app/lib/editor/home.dart +++ b/app/lib/editor/home.dart @@ -9,12 +9,14 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; class EditorPage extends StatefulWidget { + const EditorPage({Key? key}) : super(key: key); + @override _EditorPageState createState() => _EditorPageState(); } class _EditorPageState extends State { - Box _box = Hive.box('editor'); + final Box _box = Hive.box('editor'); @override Widget build(BuildContext context) { return Scaffold( @@ -41,12 +43,12 @@ class _EditorPageState extends State { }))), floatingActionButton: OpenContainer( transitionType: ContainerTransitionType.fadeThrough, - transitionDuration: Duration(milliseconds: 750), - openBuilder: (context, _) => CreateServerPage(), - closedShape: CircleBorder(), + transitionDuration: const Duration(milliseconds: 750), + openBuilder: (context, _) => const CreateServerPage(), + closedShape: const CircleBorder(), closedBuilder: (context, openContainer) => FloatingActionButton( onPressed: openContainer, - child: Icon(PhosphorIcons.plusLight), + child: const Icon(PhosphorIcons.plusLight), tooltip: "editor.create.fab".tr()))); } } diff --git a/app/lib/editor/item.dart b/app/lib/editor/item.dart index 4e251e16..d8c86d10 100644 --- a/app/lib/editor/item.dart +++ b/app/lib/editor/item.dart @@ -37,7 +37,7 @@ class _PartItemEditorPageState extends State { late CoursePart part; TextEditingController? _nameController; TextEditingController? _descriptionController; - GlobalKey _formKey = GlobalKey(); + final GlobalKey _formKey = GlobalKey(); @override void initState() { @@ -60,14 +60,15 @@ class _PartItemEditorPageState extends State { child: Scrollbar( child: Center( child: Container( - constraints: BoxConstraints(maxWidth: 1000), + constraints: const BoxConstraints(maxWidth: 1000), child: ListView( children: [ TextFormField( controller: _nameController, validator: (value) { - if (value!.isEmpty) + if (value!.isEmpty) { return 'editor.item.name.empty'.tr(); + } return null; }, decoration: InputDecoration( @@ -84,7 +85,7 @@ class _PartItemEditorPageState extends State { ], ))))), floatingActionButton: FloatingActionButton( - child: Icon(PhosphorIcons.floppyDiskLight), + child: const Icon(PhosphorIcons.floppyDiskLight), tooltip: "save".tr(), onPressed: () async { var coursePart = part.copyWith( diff --git a/app/lib/editor/markdown.dart b/app/lib/editor/markdown.dart index 8442a23f..42d8d30e 100644 --- a/app/lib/editor/markdown.dart +++ b/app/lib/editor/markdown.dart @@ -32,7 +32,7 @@ class _MarkdownEditorState extends State { return LayoutBuilder(builder: (context, constraints) { var isMobile = MediaQuery.of(context).size.width <= 1000; var textEditor = _buildTextEditor(isMobile); - if (!isMobile) + if (!isMobile) { return _buildAppBar( isMobile, Row(children: [ @@ -41,6 +41,7 @@ class _MarkdownEditorState extends State { child: _MarkdownEditorPreview( markdown: _markdownController!.text, isMobile: false)) ])); + } return _buildAppBar(isMobile, textEditor); }); } @@ -50,27 +51,26 @@ class _MarkdownEditorState extends State { if (isMobile) IconButton( tooltip: "editor.markdown.preview.button".tr(), - icon: Icon(PhosphorIcons.playLight), + icon: const Icon(PhosphorIcons.playLight), onPressed: () => Modular.to.push(MaterialPageRoute( builder: (context) => _MarkdownEditorPreview( markdown: _markdownController!.text)))), IconButton( tooltip: "save".tr(), - icon: Icon(PhosphorIcons.floppyDiskLight), + icon: const Icon(PhosphorIcons.floppyDiskLight), onPressed: () => widget.onSubmit(_markdownController!.text)) ]), body: child); Widget _buildTextEditor(bool isMobile) => Scrollbar( child: SingleChildScrollView( - child: Container( - child: TextField( + child: TextField( controller: _markdownController, onChanged: (value) { setState(() {}); }, maxLines: null, - )))); + ))); } class _MarkdownEditorPreview extends StatelessWidget { diff --git a/app/lib/editor/module.dart b/app/lib/editor/module.dart index 3ad49c5b..dd76cbe0 100644 --- a/app/lib/editor/module.dart +++ b/app/lib/editor/module.dart @@ -15,16 +15,20 @@ import 'markdown.dart'; class EditorModule extends Module { @override List get routes => [ - ChildRoute('/', child: (_, args) => EditorPage()), - WildcardRoute(child: (_, __) => ErrorDisplay()), + ChildRoute('/', child: (_, args) => const EditorPage()), + WildcardRoute(child: (_, __) => const ErrorDisplay()), ChildRoute('/details', child: (_, args) { - if (!args.queryParams.containsKey('serverId')) return ErrorDisplay(); + if (!args.queryParams.containsKey('serverId')) { + return const ErrorDisplay(); + } var bloc = ServerEditorBloc.fromKey( int.parse(args.queryParams['serverId']!)); return BackendPage(editorBloc: bloc); }), ChildRoute('/edit', child: (_, args) { - if (!args.queryParams.containsKey('serverId')) return ErrorDisplay(); + if (!args.queryParams.containsKey('serverId')) { + return const ErrorDisplay(); + } var bloc = ServerEditorBloc.fromKey( int.parse(args.queryParams['serverId']!)); return MarkdownEditor( @@ -35,13 +39,17 @@ class EditorModule extends Module { }); }), ChildRoute('/article', child: (_, args) { - if (!args.queryParams.containsKey('serverId')) return ErrorDisplay(); + if (!args.queryParams.containsKey('serverId')) { + return const ErrorDisplay(); + } var bloc = ServerEditorBloc.fromKey( int.parse(args.queryParams['serverId']!)); return ArticlePage(editorBloc: bloc); }), ChildRoute('/article/edit', child: (_, args) { - if (!args.queryParams.containsKey('serverId')) return ErrorDisplay(); + if (!args.queryParams.containsKey('serverId')) { + return const ErrorDisplay(); + } var bloc = ServerEditorBloc.fromKey( int.parse(args.queryParams['serverId']!)); var articleName = args.queryParams['article']; @@ -56,7 +64,9 @@ class EditorModule extends Module { }); }), ChildRoute('/article/author', child: (_, args) { - if (!args.queryParams.containsKey('serverId')) return ErrorDisplay(); + if (!args.queryParams.containsKey('serverId')) { + return const ErrorDisplay(); + } var bloc = ServerEditorBloc.fromKey( int.parse(args.queryParams['serverId']!)); var article = bloc.getArticle(args.queryParams['article']!); @@ -70,13 +80,17 @@ class EditorModule extends Module { }); }), ChildRoute('/course', child: (_, args) { - if (!args.queryParams.containsKey('serverId')) return ErrorDisplay(); + if (!args.queryParams.containsKey('serverId')) { + return const ErrorDisplay(); + } var bloc = ServerEditorBloc.fromKey( int.parse(args.queryParams['serverId']!)); return CoursePage(editorBloc: bloc); }), ChildRoute('/course/edit', child: (_, args) { - if (!args.queryParams.containsKey('serverId')) return ErrorDisplay(); + if (!args.queryParams.containsKey('serverId')) { + return const ErrorDisplay(); + } var bloc = ServerEditorBloc.fromKey( int.parse(args.queryParams['serverId']!)); var course = args.queryParams['course']; @@ -89,7 +103,9 @@ class EditorModule extends Module { }); }), ChildRoute('/course/author', child: (_, args) { - if (!args.queryParams.containsKey('serverId')) return ErrorDisplay(); + if (!args.queryParams.containsKey('serverId')) { + return const ErrorDisplay(); + } var bloc = ServerEditorBloc.fromKey( int.parse(args.queryParams['serverId']!)); var course = args.queryParams['course']; diff --git a/app/lib/home.dart b/app/lib/home.dart index 29f7cb43..b3372a62 100644 --- a/app/lib/home.dart +++ b/app/lib/home.dart @@ -12,6 +12,8 @@ import 'package:http/http.dart' as http; import 'package:xml/xml.dart'; class HomePage extends StatelessWidget { + const HomePage({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { var _sections = [ @@ -22,11 +24,11 @@ class HomePage extends StatelessWidget { ), Text("subtitle", style: Theme.of(context).textTheme.subtitle1).tr(), Padding( - padding: EdgeInsets.all(20), + padding: const EdgeInsets.all(20), child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( - padding: EdgeInsets.all(5), + padding: const EdgeInsets.all(5), child: Wrap(alignment: WrapAlignment.center, children: [ ElevatedButton.icon( onPressed: () => launch( @@ -37,12 +39,12 @@ class HomePage extends StatelessWidget { style: Theme.of(context).primaryTextTheme.button)), OutlinedButton.icon( onPressed: () => launch("https://discord.linwood.dev"), - icon: Icon(PhosphorIcons.usersLight), + icon: const Icon(PhosphorIcons.usersLight), label: Text("discord".tr().toUpperCase())) ])), if (kIsWeb) Padding( - padding: EdgeInsets.all(5), + padding: const EdgeInsets.all(5), child: RawMaterialButton( onPressed: () => launch( "https://vercel.com?utm_source=Linwood&utm_campaign=oss"), @@ -64,23 +66,25 @@ class HomePage extends StatelessWidget { style: Theme.of(context).textTheme.headline4, ), Padding( - padding: EdgeInsets.all(20), + padding: const EdgeInsets.all(20), child: ElevatedButton.icon( onPressed: () => launch("https://linwood.dev/blog"), - icon: Icon(PhosphorIcons.arrowSquareOutLight), + icon: const Icon(PhosphorIcons.arrowSquareOutLight), label: Text("browser".tr().toUpperCase()), )), Padding( - padding: EdgeInsets.all(20), - child: - Row(mainAxisAlignment: MainAxisAlignment.center, children: [])), + padding: const EdgeInsets.all(20), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: const [])), FutureBuilder( future: http.get(Uri.https('www.linwood.dev', '/blog/atom.xml')), builder: (context, snapshot) { if (snapshot.hasError) return Text("Error: ${snapshot.error}"); if (!snapshot.hasData || - snapshot.connectionState == ConnectionState.waiting) - return Center(child: CircularProgressIndicator()); + snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } var data = utf8.decode(snapshot.data!.bodyBytes); var document = XmlDocument.parse(data); var feed = document.getElement("feed")!; @@ -105,15 +109,16 @@ class HomePage extends StatelessWidget { appBar: MyAppBar(title: 'home'.tr()), body: Scrollbar( child: ListView.separated( - separatorBuilder: (context, index) => Padding( + separatorBuilder: (context, index) => const Padding( padding: EdgeInsets.only(top: 100), ), itemCount: _sections.length, - padding: EdgeInsets.only(top: 100), + padding: const EdgeInsets.only(top: 100), itemBuilder: (context, index) => Material( elevation: 2, child: Container( - padding: EdgeInsets.all(10), child: _sections[index])), + padding: const EdgeInsets.all(10), + child: _sections[index])), ), )); } diff --git a/app/lib/loader.dart b/app/lib/loader.dart index 449da2b9..496781a1 100644 --- a/app/lib/loader.dart +++ b/app/lib/loader.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:yaml/yaml.dart'; import 'yaml.dart'; @@ -26,7 +27,9 @@ Future?> loadYamlFile(String path) async { var response = await http.get(Uri.parse(path + ".yml")); return yamlMapToJson(loadYaml(utf8.decode(response.bodyBytes))); } catch (e) { - print(e); + if (kDebugMode) { + print(e); + } } return null; diff --git a/app/lib/main.dart b/app/lib/main.dart index aaf2a5c0..7b861a54 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -32,18 +32,21 @@ void main() async { await Hive.openBox('points'); var _serversBox = await Hive.openBox('servers'); var _collectionsBox = await Hive.openBox('collections'); - if (_collectionsBox.isEmpty) + if (_collectionsBox.isEmpty) { await _collectionsBox.add('https://collection.dev-doctor.linwood.dev'); - if (_serversBox.isEmpty) + } + if (_serversBox.isEmpty) { await _serversBox.add('https://backend.dev-doctor.linwood.dev'); - runApp(ModularApp(module: AppModule(), child: AppWidget())); + } + runApp(ModularApp(module: AppModule(), child: const AppWidget())); - if (isWindow()) + if (isWindow()) { doWhenWindowReady(() { - appWindow.minSize = Size(400, 300); - appWindow.size = Size(400, 600); + appWindow.minSize = const Size(400, 300); + appWindow.size = const Size(400, 600); appWindow.alignment = Alignment.center; appWindow.title = "Dev-Doctor"; appWindow.show(); }); + } } diff --git a/app/lib/models/collection.dart b/app/lib/models/collection.dart index fbeca5cc..ecce01dd 100644 --- a/app/lib/models/collection.dart +++ b/app/lib/models/collection.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:hive/hive.dart'; @@ -33,12 +34,16 @@ class BackendCollection { if (index == null) { var current = _box.values.toList().indexOf(url!); if (current != -1) index = _box.keyAt(current); - } else if (url == null) url = _box.get(index); + } else { + url ??= _box.get(index); + } var loadedData = await loadFile("$url/config"); if (loadedData == null) return null; data = loadedData; } catch (e) { - print(e); + if (kDebugMode) { + print(e); + } return null; } data['url'] = url; diff --git a/app/lib/models/course.dart b/app/lib/models/course.dart index 27f9d92a..4bf6cb27 100644 --- a/app/lib/models/course.dart +++ b/app/lib/models/course.dart @@ -20,7 +20,7 @@ class Course { final List parts; final bool private; - Course( + const Course( {required this.slug, this.name = '', this.description = '', @@ -36,12 +36,13 @@ class Course { factory Course.fromJson(Map json) { var apiVersion = json['api-version']; if (apiVersion != null) { - if (apiVersion < 8) + if (apiVersion < 8) { json['author'] = { "name": json['author'], "url": json['author_url'], "avatar": json['author_avatar'] }; + } } return Course( server: json['server'], @@ -79,9 +80,9 @@ class Course { Future> fetchParts() => Future.wait(parts.map((course) => fetchPart(course))).then((value) async { var list = []; - value.forEach((element) { + for (var element in value) { if (element != null) list.add(element); - }); + } return list; }); @@ -95,7 +96,9 @@ class Course { data['slug'] = part; return CoursePart.fromJson(data); } catch (e) { - print("Error $e"); + if (kDebugMode) { + print("Error $e"); + } return null; } } @@ -122,7 +125,7 @@ class Course { name: name ?? this.name, parts: parts ?? this.parts, private: private ?? this.private, - server: server ?? this.server, + server: server ?? server, slug: slug ?? this.slug, supportUrl: supportUrl ?? this.supportUrl); } diff --git a/app/lib/models/editor/server.dart b/app/lib/models/editor/server.dart index e254f7e6..442f6bb1 100644 --- a/app/lib/models/editor/server.dart +++ b/app/lib/models/editor/server.dart @@ -24,7 +24,7 @@ class ServerEditorBloc extends HiveObject { this.note, required String name, List
articles = const []}) - : _server = CoursesServer(name: name, courses: []), + : _server = CoursesServer(name: name, courses: const []), _courses = List.from(courses), _articles = List
.from(articles); ServerEditorBloc.fromJson(Map json) @@ -52,7 +52,7 @@ class ServerEditorBloc extends HiveObject { CourseEditorBloc? createCourse(String slug) { if (getCourseSlugs().contains(slug)) return null; var courseBloc = - CourseEditorBloc(Course(name: slug, slug: slug, parts: [])); + CourseEditorBloc(Course(name: slug, slug: slug, parts: const [])); _courses.add(courseBloc); return courseBloc; } diff --git a/app/lib/models/item.dart b/app/lib/models/item.dart index fb3080e6..35d23391 100644 --- a/app/lib/models/item.dart +++ b/app/lib/models/item.dart @@ -10,13 +10,13 @@ abstract class PartItem { final String name; final String description; final int? index; - final allowReset; + final bool allowReset; int get points; IconData get icon => PhosphorIcons.squareLight; - PartItem( + const PartItem( {this.allowReset = true, required this.name, required this.description, diff --git a/app/lib/models/items/quiz.dart b/app/lib/models/items/quiz.dart index 49e6fa67..c7f8feda 100644 --- a/app/lib/models/items/quiz.dart +++ b/app/lib/models/items/quiz.dart @@ -9,7 +9,7 @@ class QuizPartItem extends PartItem { final List questions; final int? time; - QuizPartItem( + const QuizPartItem( {this.text, this.time, this.questions = const [], @@ -37,6 +37,7 @@ class QuizPartItem extends PartItem { "description": description }; + @override QuizPartItem copyWith( {String? text, int? time, @@ -55,7 +56,9 @@ class QuizPartItem extends PartItem { @override int get points { int points = 0; - questions.forEach((question) => points += question.points); + for (var question in questions) { + points += question.points; + } return points; } @@ -71,7 +74,7 @@ class QuizQuestion { final List answers; final bool multi; - QuizQuestion( + const QuizQuestion( {this.title = '', this.description = '', this.answers = const [], @@ -108,7 +111,9 @@ class QuizQuestion { int get points { int points = 0; - answers.forEach((element) => points = max(points, element.points)); + for (var element in answers) { + points = max(points, element.points); + } return points; } } @@ -121,7 +126,7 @@ class QuizAnswer { final int points; final int minusPoints; - QuizAnswer( + const QuizAnswer( {this.correct = false, this.name = "", this.description = "", diff --git a/app/lib/models/items/text.dart b/app/lib/models/items/text.dart index afc66aa5..54ce1c95 100644 --- a/app/lib/models/items/text.dart +++ b/app/lib/models/items/text.dart @@ -1,13 +1,13 @@ import 'package:dev_doctor/models/item.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/src/widgets/icon_data.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; class TextPartItem extends PartItem { final String text; + @override final int points; - TextPartItem( + const TextPartItem( {this.points = 1, this.text = "", String name = '', @@ -20,6 +20,7 @@ class TextPartItem extends PartItem { points = json['points'] ?? 1, super.fromJson(json); + @override Map toJson() => { "type": "text", "text": text, @@ -28,6 +29,7 @@ class TextPartItem extends PartItem { "points": points }; + @override TextPartItem copyWith( {String? text, String? name, String? description, int? points}) => TextPartItem( diff --git a/app/lib/models/items/video.dart b/app/lib/models/items/video.dart index dd9269e4..0846cd16 100644 --- a/app/lib/models/items/video.dart +++ b/app/lib/models/items/video.dart @@ -1,7 +1,6 @@ import 'package:dev_doctor/models/item.dart'; import 'package:enum_to_string/enum_to_string.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/src/widgets/icon_data.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; import '../part.dart'; @@ -11,9 +10,10 @@ enum VideoSource { youtube, url, asset } class VideoPartItem extends PartItem { final VideoSource source; final String url; + @override final int points; - VideoPartItem( + const VideoPartItem( {this.source = VideoSource.url, this.points = 1, required this.url, @@ -36,7 +36,7 @@ class VideoPartItem extends PartItem { case VideoSource.youtube: return Uri.https( 'www.youtube-nocookie.com', - 'embed/${url}', + 'embed/$url', ); case VideoSource.asset: return Uri( @@ -49,6 +49,7 @@ class VideoPartItem extends PartItem { } } + @override Map toJson() { return { "type": "video", @@ -60,6 +61,7 @@ class VideoPartItem extends PartItem { }; } + @override VideoPartItem copyWith( {String? name, String? description, diff --git a/app/lib/models/part.dart b/app/lib/models/part.dart index 0df076a0..4ccea043 100644 --- a/app/lib/models/part.dart +++ b/app/lib/models/part.dart @@ -17,7 +17,7 @@ class CoursePart { required this.slug, List items = const [], this.course}) - : this.items = List.unmodifiable(items); + : items = List.unmodifiable(items); CoursePart.fromJson(Map json) : course = json['course'], description = json['description'] ?? "", diff --git a/app/lib/models/server.dart b/app/lib/models/server.dart index 352a8c84..c39f3479 100644 --- a/app/lib/models/server.dart +++ b/app/lib/models/server.dart @@ -21,7 +21,7 @@ class CoursesServer { static Box get _box => Hive.box('servers'); - CoursesServer( + const CoursesServer( {this.body = "", this.icon = "", this.index, @@ -112,12 +112,16 @@ class CoursesServer { if (index == null && url != null) { var current = _box.values.toList().indexOf(url); if (current != -1) index = _box.keyAt(current); - } else if (url == null) url = Hive.box('servers').get(index); + } else { + url ??= Hive.box('servers').get(index); + } var loadedData = await loadFile("$url/config"); if (loadedData == null) return null; data = loadedData; } catch (e) { - print(e); + if (kDebugMode) { + print(e); + } return null; } data['courses'] = data['courses'] ?? []; @@ -131,9 +135,9 @@ class CoursesServer { Future.wait(courses.map((course) => fetchCourse(course))) .then((value) async { var list = []; - value.forEach((element) { + for (var element in value) { if (element != null) list.add(element); - }); + } return list; }); @@ -147,7 +151,9 @@ class CoursesServer { data['api-version'] = data['api-version'] ?? 0; return Course.fromJson(data); } catch (e) { - print("Error $e"); + if (kDebugMode) { + print("Error $e"); + } return null; } } @@ -156,9 +162,9 @@ class CoursesServer { Future.wait(articles.map((article) => fetchArticle(article))) .then((value) async { var list =
[]; - value.forEach((element) { + for (var element in value) { if (element != null) list.add(element); - }); + } return list; }); @@ -172,7 +178,9 @@ class CoursesServer { data['api-version'] = data['api-version'] ?? 0; return Article.fromJson(data); } catch (e) { - print("Error $e"); + if (kDebugMode) { + print("Error $e"); + } return null; } } diff --git a/app/lib/settings/appearance.dart b/app/lib/settings/appearance.dart index bf8467fd..e5ccc524 100644 --- a/app/lib/settings/appearance.dart +++ b/app/lib/settings/appearance.dart @@ -8,6 +8,8 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'package:easy_localization/easy_localization.dart'; class AppearanceSettingsPage extends StatelessWidget { + const AppearanceSettingsPage({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { final _appearanceBox = Hive.box('appearance'); @@ -26,7 +28,8 @@ class AppearanceSettingsPage extends StatelessWidget { return Scrollbar( child: ListView(children: [ ListTile( - title: Text('settings.appearance.locale.title').tr(), + title: + const Text('settings.appearance.locale.title').tr(), subtitle: Text('settings.appearance.locale.$locale').tr(), onTap: () => showDialog( @@ -48,12 +51,13 @@ class AppearanceSettingsPage extends StatelessWidget { context.resetLocale(); ScaffoldMessenger.of(context) .showSnackBar(SnackBar( - content: Text( + content: const Text( 'settings.appearance.locale.restart') .tr())); - } else + } else { context.setLocale( Locale(selectedLocale!)); + } Navigator.pop(context); }) ], @@ -67,7 +71,7 @@ class AppearanceSettingsPage extends StatelessWidget { RadioListTile( value: "default", groupValue: selectedLocale, - title: Text( + title: const Text( 'settings.appearance.locale.default') .tr(), onChanged: (value) { @@ -99,7 +103,8 @@ class AppearanceSettingsPage extends StatelessWidget { )); })), ListTile( - title: Text('settings.appearance.theme.title').tr(), + title: + const Text('settings.appearance.theme.title').tr(), subtitle: Text('settings.appearance.theme.' + EnumToString.convertToString(theme)) .tr(), @@ -150,7 +155,7 @@ class AppearanceSettingsPage extends StatelessWidget { ); })), ListTile( - title: Text("settings.appearance.color.title").tr(), + title: const Text("settings.appearance.color.title").tr(), subtitle: Text("settings.appearance.color." + EnumToString.convertToString(color)) .tr(), diff --git a/app/lib/settings/collections.dart b/app/lib/settings/collections.dart index 51c3216d..45658fb6 100644 --- a/app/lib/settings/collections.dart +++ b/app/lib/settings/collections.dart @@ -10,6 +10,8 @@ import 'home.dart'; import 'layout.dart'; class CollectionsSettingsPage extends StatefulWidget { + const CollectionsSettingsPage({Key? key}) : super(key: key); + @override _CollectionsSettingsPageState createState() => _CollectionsSettingsPageState(); @@ -41,10 +43,11 @@ class _CollectionsSettingsPageState extends State { builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.waiting: - return Center(child: CircularProgressIndicator()); + return const Center(child: CircularProgressIndicator()); default: - if (snapshot.hasError) + if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); + } var data = snapshot.data; return Scrollbar( child: ListView.builder( @@ -72,8 +75,8 @@ class _CollectionsSettingsPageState extends State { } }))), floatingActionButton: FloatingActionButton.extended( - label: Text("settings.collections.add.fab").tr(), - icon: Icon(PhosphorIcons.plusLight), + label: const Text("settings.collections.add.fab").tr(), + icon: const Icon(PhosphorIcons.plusLight), onPressed: () => _showDialog(), ), ); @@ -85,20 +88,21 @@ class _CollectionsSettingsPageState extends State { _createCollection(String url) async { var server = await BackendCollection.fetch(url: url); - if (server == null) + if (server == null) { showDialog( context: context, builder: (context) => AlertDialog( - title: Text("settings.collections.error").tr(), + title: const Text("settings.collections.error").tr(), actions: [ TextButton.icon( onPressed: () => Navigator.pop(context), - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), label: Text("close".tr().toUpperCase())) ], )); - else + } else { await _box.add(url); + } } _showDialog() { diff --git a/app/lib/settings/general.dart b/app/lib/settings/general.dart index 4a5aa9f4..74663d66 100644 --- a/app/lib/settings/general.dart +++ b/app/lib/settings/general.dart @@ -8,6 +8,9 @@ import 'layout.dart'; class GeneralSettingsPage extends StatelessWidget { final Box _generalBox = Hive.box("general"); + + GeneralSettingsPage({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Scaffold( @@ -21,7 +24,7 @@ class GeneralSettingsPage extends StatelessWidget { return Scrollbar( child: ListView(children: [ ListTile( - title: Text('settings.general.name.title').tr(), + title: const Text('settings.general.name.title').tr(), subtitle: Text(name), onTap: () => showDialog( context: context, diff --git a/app/lib/settings/home.dart b/app/lib/settings/home.dart index 3e34092e..3923ded8 100644 --- a/app/lib/settings/home.dart +++ b/app/lib/settings/home.dart @@ -7,6 +7,8 @@ import 'package:phosphor_flutter/phosphor_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; class SettingsPage extends StatefulWidget { + const SettingsPage({Key? key}) : super(key: key); + @override _SettingsPageState createState() => _SettingsPageState(); } @@ -16,7 +18,7 @@ class _SettingsPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: MyAppBar(title: "settings.title".tr()), - body: Container(child: SettingsList())); + body: const SettingsList()); } } @@ -51,15 +53,15 @@ class SettingsList extends StatelessWidget { child: Column(mainAxisSize: MainAxisSize.max, children: [ ListTile( selected: activePage == SettingsPages.general, - leading: Icon(PhosphorIcons.wrenchLight), - title: Text("settings.general.title").tr(), + leading: const Icon(PhosphorIcons.wrenchLight), + title: const Text("settings.general.title").tr(), onTap: () => activePage != null ? Modular.to.pushReplacementNamed('/settings/general') : Modular.to.pushNamed("/settings/general")), ListTile( selected: activePage == SettingsPages.appearance, - leading: Icon(PhosphorIcons.fadersLight), - title: Text("settings.appearance.title").tr(), + leading: const Icon(PhosphorIcons.fadersLight), + title: const Text("settings.appearance.title").tr(), onTap: () => activePage != null ? Modular.to.pushReplacementNamed('/settings/appearance') : Modular.to.pushNamed("/settings/appearance")), @@ -70,55 +72,55 @@ class SettingsList extends StatelessWidget { // onTap: () => _showComingSoon(context)), ListTile( selected: activePage == SettingsPages.servers, - leading: Icon(PhosphorIcons.cardsLight), - title: Text("settings.servers.title").tr(), + leading: const Icon(PhosphorIcons.cardsLight), + title: const Text("settings.servers.title").tr(), onTap: () => activePage != null ? Modular.to.pushReplacementNamed('/settings/servers') : Modular.to.pushNamed("/settings/servers")), ListTile( selected: activePage == SettingsPages.collections, - leading: Icon(PhosphorIcons.treeStructureLight), - title: Text("settings.collections.title").tr(), + leading: const Icon(PhosphorIcons.treeStructureLight), + title: const Text("settings.collections.title").tr(), onTap: () => activePage != null ? Modular.to.pushReplacementNamed('/settings/collections') : Modular.to.pushNamed("/settings/collections")), TextDivider(text: 'settings.information'.tr().toUpperCase()), ListTile( - leading: Icon(PhosphorIcons.stackLight), - title: Text("settings.license").tr(), + leading: const Icon(PhosphorIcons.stackLight), + title: const Text("settings.license").tr(), onTap: () => launch( "https://github.com/LinwoodCloud/dev_doctor/blob/main/LICENSE")), ListTile( - leading: Icon(PhosphorIcons.codeLight), - title: Text("settings.code").tr(), + leading: const Icon(PhosphorIcons.codeLight), + title: const Text("settings.code").tr(), onTap: () => launch("https://github.com/LinwoodCloud/dev_doctor")), ListTile( - leading: Icon(PhosphorIcons.usersLight), - title: Text("discord").tr(), + leading: const Icon(PhosphorIcons.usersLight), + title: const Text("discord").tr(), onTap: () => launch("https://discord.linwood.dev")), ListTile( - leading: Icon(PhosphorIcons.articleLight), - title: Text("docs").tr(), + leading: const Icon(PhosphorIcons.articleLight), + title: const Text("docs").tr(), onTap: () => launch( "https://docs.dev-doctor.linwood.dev/backend/overview")), ListTile( - leading: Icon(PhosphorIcons.arrowCounterClockwiseLight), - title: Text("settings.changelog").tr(), + leading: const Icon(PhosphorIcons.arrowCounterClockwiseLight), + title: const Text("settings.changelog").tr(), onTap: () => launch("https://docs.dev-doctor.linwood.dev/changelog")), ListTile( - leading: Icon(PhosphorIcons.identificationCardLight), - title: Text("settings.imprint").tr(), + leading: const Icon(PhosphorIcons.identificationCardLight), + title: const Text("settings.imprint").tr(), onTap: () => launch("https://codedoctor.tk/impress")), ListTile( - leading: Icon(PhosphorIcons.shieldLight), - title: Text("settings.privacypolicy").tr(), + leading: const Icon(PhosphorIcons.shieldLight), + title: const Text("settings.privacypolicy").tr(), onTap: () => launch( "https://docs.dev-doctor.linwood.dev/docs/privacypolicy")), ListTile( - leading: Icon(PhosphorIcons.infoLight), - title: Text("settings.about").tr(), + leading: const Icon(PhosphorIcons.infoLight), + title: const Text("settings.about").tr(), onTap: () => showAboutDialog( context: context, applicationIcon: Image.asset("images/logo.png", height: 50))), diff --git a/app/lib/settings/module.dart b/app/lib/settings/module.dart index 5402ffe5..1066f809 100644 --- a/app/lib/settings/module.dart +++ b/app/lib/settings/module.dart @@ -9,8 +9,10 @@ class SettingsModule extends Module { @override final List routes = [ ChildRoute('/general', child: (_, args) => GeneralSettingsPage()), - ChildRoute('/servers', child: (_, args) => ServersSettingsPage()), - ChildRoute('/appearance', child: (_, args) => AppearanceSettingsPage()), - ChildRoute('/collections', child: (_, args) => CollectionsSettingsPage()) + ChildRoute('/servers', child: (_, args) => const ServersSettingsPage()), + ChildRoute('/appearance', + child: (_, args) => const AppearanceSettingsPage()), + ChildRoute('/collections', + child: (_, args) => const CollectionsSettingsPage()) ]; } diff --git a/app/lib/settings/servers.dart b/app/lib/settings/servers.dart index a9859e45..a6e55156 100644 --- a/app/lib/settings/servers.dart +++ b/app/lib/settings/servers.dart @@ -10,6 +10,8 @@ import 'home.dart'; import 'layout.dart'; class ServersSettingsPage extends StatefulWidget { + const ServersSettingsPage({Key? key}) : super(key: key); + @override _ServersSettingsPageState createState() => _ServersSettingsPageState(); } @@ -45,10 +47,11 @@ class _ServersSettingsPageState extends State { builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.waiting: - return Center(child: CircularProgressIndicator()); + return const Center(child: CircularProgressIndicator()); default: - if (snapshot.hasError) + if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); + } var data = snapshot.data; return Scrollbar( child: ListView.builder( @@ -75,8 +78,8 @@ class _ServersSettingsPageState extends State { } }))), floatingActionButton: FloatingActionButton.extended( - label: Text("settings.servers.add.fab").tr(), - icon: Icon(PhosphorIcons.plusLight), + label: const Text("settings.servers.add.fab").tr(), + icon: const Icon(PhosphorIcons.plusLight), onPressed: () => _showDialog(), ), ); @@ -88,20 +91,21 @@ class _ServersSettingsPageState extends State { _createServer(String url) async { var server = await CoursesServer.fetch(url: url); - if (server == null) + if (server == null) { showDialog( context: context, builder: (context) => AlertDialog( - title: Text("settings.servers.error").tr(), + title: const Text("settings.servers.error").tr(), actions: [ TextButton.icon( onPressed: () => Navigator.pop(context), - icon: Icon(PhosphorIcons.xLight), + icon: const Icon(PhosphorIcons.xLight), label: Text("close".tr().toUpperCase())) ], )); - else + } else { await _serversBox.add(url); + } } _showDialog() { diff --git a/app/lib/themes/artistic.dart b/app/lib/themes/artistic.dart index 0d92d06c..63eef25f 100644 --- a/app/lib/themes/artistic.dart +++ b/app/lib/themes/artistic.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -final mdcThemePrimary = Color(0xFF30dc4f); +const mdcThemePrimary = Color(0xFF30dc4f); const mdcThemeOnPrimary = Color(0xFFffffff); const mdcThemeSecondary = Color(0xFFdc30bc); const mdcThemeOnSecondary = Color(0xFF000000); @@ -9,7 +9,7 @@ const mdcThemeOnError = Color(0xFFffffff); const mdcThemeSurface = Color(0xFFffffff); const mdcThemeOnSurface = Color(0xFF000000); const mdcThemeBackground = Color(0xFFffffff); -final mdcTypographyFontFamily = "Raleway"; +const mdcTypographyFontFamily = "Raleway"; final mdcPrimarySwatch = MaterialColor(mdcThemePrimary.value, { 50: mdcThemePrimary.withOpacity(.1), 100: mdcThemePrimary.withOpacity(.2), diff --git a/app/lib/themes/autumn.dart b/app/lib/themes/autumn.dart index a11ce29a..1b03fe15 100644 --- a/app/lib/themes/autumn.dart +++ b/app/lib/themes/autumn.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -final mdcThemePrimary = Color(0xFFe56909); +const mdcThemePrimary = Color(0xFFe56909); const mdcThemeOnPrimary = Color(0xFFffffff); const mdcThemeSecondary = Color(0xFF0986e5); const mdcThemeOnSecondary = Color(0xFFffffff); @@ -9,7 +9,7 @@ const mdcThemeOnError = Color(0xFFffffff); const mdcThemeSurface = Color(0xFFffffff); const mdcThemeOnSurface = Color(0xFF000000); const mdcThemeBackground = Color(0xFFffffff); -final mdcTypographyFontFamily = "Josefin Sans"; +const mdcTypographyFontFamily = "Josefin Sans"; final mdcPrimarySwatch = MaterialColor(mdcThemePrimary.value, { 50: mdcThemePrimary.withOpacity(.1), 100: mdcThemePrimary.withOpacity(.2), diff --git a/app/lib/themes/classic.dart b/app/lib/themes/classic.dart index 63729a3f..dff954d1 100644 --- a/app/lib/themes/classic.dart +++ b/app/lib/themes/classic.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -final mdcThemePrimary = Color(0xFFBA26FF); +const mdcThemePrimary = Color(0xFFBA26FF); const mdcThemeOnPrimary = Color(0xFFffffff); const mdcThemeSecondary = Color(0xFF6D17E8); const mdcThemeOnSecondary = Color(0xFF000000); @@ -9,7 +9,7 @@ const mdcThemeOnError = Color(0xFFffffff); const mdcThemeSurface = Color(0xFFffffff); const mdcThemeOnSurface = Color(0xFF000000); const mdcThemeBackground = Color(0xFFffffff); -final mdcTypographyFontFamily = "Montserrat"; +const mdcTypographyFontFamily = "Montserrat"; final mdcPrimarySwatch = MaterialColor(mdcThemePrimary.value, { 50: mdcThemePrimary.withOpacity(.1), 100: mdcThemePrimary.withOpacity(.2), diff --git a/app/lib/themes/modern.dart b/app/lib/themes/modern.dart index 361835e7..c43daae8 100644 --- a/app/lib/themes/modern.dart +++ b/app/lib/themes/modern.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -final mdcThemePrimary = Color(0xFF009aff); +const mdcThemePrimary = Color(0xFF009aff); const mdcThemeOnPrimary = Color(0xFF000000); const mdcThemeSecondary = Color(0xFFffba00); const mdcThemeOnSecondary = Color(0xFF000000); @@ -9,7 +9,7 @@ const mdcThemeOnError = Color(0xFFffffff); const mdcThemeSurface = Color(0xFFffffff); const mdcThemeOnSurface = Color(0xFF000000); const mdcThemeBackground = Color(0xFFffffff); -final mdcTypographyFontFamily = "Roboto"; +const mdcTypographyFontFamily = "Roboto"; final mdcPrimarySwatch = MaterialColor(mdcThemePrimary.value, { 50: mdcThemePrimary.withOpacity(.1), 100: mdcThemePrimary.withOpacity(.2), diff --git a/app/lib/themes/spring.dart b/app/lib/themes/spring.dart index 32cb5ed5..b691f9e3 100644 --- a/app/lib/themes/spring.dart +++ b/app/lib/themes/spring.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -final mdcThemePrimary = Color(0xFFff95d1); +const mdcThemePrimary = Color(0xFFff95d1); const mdcThemeOnPrimary = Color(0xFF000000); const mdcThemeSecondary = Color(0xFF6d6dff); const mdcThemeOnSecondary = Color(0xFFffffff); @@ -9,7 +9,7 @@ const mdcThemeOnError = Color(0xFFffffff); const mdcThemeSurface = Color(0xFFffffff); const mdcThemeOnSurface = Color(0xFF000000); const mdcThemeBackground = Color(0xFFffffff); -final mdcTypographyFontFamily = "Oswald"; +const mdcTypographyFontFamily = "Oswald"; final mdcPrimarySwatch = MaterialColor(mdcThemePrimary.value, { 50: mdcThemePrimary.withOpacity(.1), 100: mdcThemePrimary.withOpacity(.2), diff --git a/app/lib/themes/summer.dart b/app/lib/themes/summer.dart index 9bf955c8..cd076bcc 100644 --- a/app/lib/themes/summer.dart +++ b/app/lib/themes/summer.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -final mdcThemePrimary = Color(0xFF178ef5); +const mdcThemePrimary = Color(0xFF178ef5); const mdcThemeOnPrimary = Color(0xFFffffff); const mdcThemeSecondary = Color(0xFFfecc2b); const mdcThemeOnSecondary = Color(0xFF000000); @@ -9,7 +9,7 @@ const mdcThemeOnError = Color(0xFFffffff); const mdcThemeSurface = Color(0xFFffffff); const mdcThemeOnSurface = Color(0xFF000000); const mdcThemeBackground = Color(0xFFffffff); -final mdcTypographyFontFamily = "Comfortaa"; +const mdcTypographyFontFamily = "Comfortaa"; final mdcPrimarySwatch = MaterialColor(mdcThemePrimary.value, { 50: mdcThemePrimary.withOpacity(.1), 100: mdcThemePrimary.withOpacity(.2), diff --git a/app/lib/themes/winter.dart b/app/lib/themes/winter.dart index 37e3638f..1e8a6205 100644 --- a/app/lib/themes/winter.dart +++ b/app/lib/themes/winter.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -final mdcThemePrimary = Color(0xFFb802ee); +const mdcThemePrimary = Color(0xFFb802ee); const mdcThemeOnPrimary = Color(0xFFffffff); const mdcThemeSecondary = Color(0xFF4102ee); const mdcThemeOnSecondary = Color(0xFFffffff); @@ -9,7 +9,7 @@ const mdcThemeOnError = Color(0xFFffffff); const mdcThemeSurface = Color(0xFFffffff); const mdcThemeOnSurface = Color(0xFF000000); const mdcThemeBackground = Color(0xFFffffff); -final mdcTypographyFontFamily = "Shippori Mincho"; +const mdcTypographyFontFamily = "Shippori Mincho"; final mdcPrimarySwatch = MaterialColor(mdcThemePrimary.value, { 50: mdcThemePrimary.withOpacity(.1), 100: mdcThemePrimary.withOpacity(.2), diff --git a/app/lib/widgets/appbar.dart b/app/lib/widgets/appbar.dart index b04925a3..8ab5fd47 100644 --- a/app/lib/widgets/appbar.dart +++ b/app/lib/widgets/appbar.dart @@ -32,17 +32,18 @@ class MyAppBar extends StatelessWidget with PreferredSizeWidget { @override Widget build(BuildContext context) { - if (isWindow()) + if (isWindow()) { return MoveWindow( child: WindowBorder( color: Theme.of(context).primaryColor, width: 1, child: _buildAppBar())); + } return _buildAppBar(); } Widget _buildAppBar() => AppBar( - leading: this.leading, + leading: leading, elevation: 5.0, automaticallyImplyLeading: automaticallyImplyLeading, title: isWindow() @@ -52,49 +53,52 @@ class MyAppBar extends StatelessWidget with PreferredSizeWidget { actions: [ ...actions, if (actions.isNotEmpty) - if (isWindow()) VerticalDivider(), - WindowButtons() + if (isWindow()) const VerticalDivider(), + const WindowButtons() ], //actions: [IconButton(icon: Icon(Icons.settings_outlined), onPressed: () {})], ); } final buttonColors = WindowButtonColors( - iconNormal: Color(0xFF805306), - mouseOver: Color(0xFFF6A00C), - mouseDown: Color(0xFF805306), - iconMouseOver: Color(0xFF805306), - iconMouseDown: Color(0xFFFFD500)); + iconNormal: const Color(0xFF805306), + mouseOver: const Color(0xFFF6A00C), + mouseDown: const Color(0xFF805306), + iconMouseOver: const Color(0xFF805306), + iconMouseDown: const Color(0xFFFFD500)); final closeButtonColors = WindowButtonColors( - mouseOver: Color(0xFFD32F2F), - mouseDown: Color(0xFFB71C1C), - iconNormal: Color(0xFF805306), + mouseOver: const Color(0xFFD32F2F), + mouseDown: const Color(0xFFB71C1C), + iconNormal: const Color(0xFF805306), iconMouseOver: Colors.white); class WindowButtons extends StatelessWidget { + const WindowButtons({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { - if (!kIsWeb) if (isWindow()) + if (!kIsWeb && isWindow()) { return Padding( padding: const EdgeInsets.all(8.0), child: Row( children: [ IconButton( - icon: Icon(PhosphorIcons.minusLight, size: 16), + icon: const Icon(PhosphorIcons.minusLight, size: 16), onPressed: () => appWindow.minimize(), ), IconButton( - icon: Icon(PhosphorIcons.squareLight, size: 16), + icon: const Icon(PhosphorIcons.squareLight, size: 16), onPressed: () => appWindow.maximizeOrRestore(), ), IconButton( - icon: Icon(PhosphorIcons.xLight, size: 16), + icon: const Icon(PhosphorIcons.xLight, size: 16), onPressed: () => appWindow.close(), ) ], ), ); + } return Container(); } } diff --git a/app/lib/widgets/author.dart b/app/lib/widgets/author.dart index ded3b8fd..4cffc987 100644 --- a/app/lib/widgets/author.dart +++ b/app/lib/widgets/author.dart @@ -23,7 +23,7 @@ class AuthorDisplay extends StatelessWidget { child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ if (author.avatar.isNotEmpty) Padding( - padding: EdgeInsets.all(8), + padding: const EdgeInsets.all(8), child: CircleAvatar( child: ClipOval( child: UniversalImage( diff --git a/app/lib/widgets/error.dart b/app/lib/widgets/error.dart index 3c16746e..cc23be3e 100644 --- a/app/lib/widgets/error.dart +++ b/app/lib/widgets/error.dart @@ -3,6 +3,8 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_modular/flutter_modular.dart'; class ErrorDisplay extends StatelessWidget { + const ErrorDisplay({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Container( @@ -11,7 +13,8 @@ class ErrorDisplay extends StatelessWidget { Text("error".tr(), style: Theme.of(context).textTheme.headline1), if (Modular.to.canPop()) TextButton( - onPressed: () => Modular.to.pop(), child: Text("back").tr()), + onPressed: () => Modular.to.pop(), + child: const Text("back").tr()), TextButton( onPressed: () => Modular.to.navigate("/"), child: Text("back-to-home".tr())) diff --git a/app/lib/widgets/image_type.dart b/app/lib/widgets/image_type.dart index 4033e075..663c298b 100644 --- a/app/lib/widgets/image_type.dart +++ b/app/lib/widgets/image_type.dart @@ -24,11 +24,12 @@ class _ImageTypeDropdownState extends State { return DropdownButton( value: dropdownValue, onChanged: (String? newValue) { - if (newValue != null) + if (newValue != null) { setState(() { widget.onChanged(newValue); dropdownValue = newValue; }); + } }, items: ['svg', 'png', 'jpg', 'jpeg'] .map>((String value) { diff --git a/app/lib/widgets/system_padding.dart b/app/lib/widgets/system_padding.dart index 1850c1a5..bf838522 100644 --- a/app/lib/widgets/system_padding.dart +++ b/app/lib/widgets/system_padding.dart @@ -3,12 +3,12 @@ import 'package:flutter/material.dart'; class SystemPadding extends StatelessWidget { final Widget? child; - SystemPadding({Key? key, this.child}) : super(key: key); + const SystemPadding({Key? key, this.child}) : super(key: key); @override Widget build(BuildContext context) { var mediaQuery = MediaQuery.of(context); - return new AnimatedContainer( + return AnimatedContainer( padding: mediaQuery.viewInsets, duration: const Duration(milliseconds: 300), child: child); diff --git a/app/lib/widgets/text_divider.dart b/app/lib/widgets/text_divider.dart index eef99d40..8629e8b8 100644 --- a/app/lib/widgets/text_divider.dart +++ b/app/lib/widgets/text_divider.dart @@ -11,7 +11,7 @@ class TextDivider extends StatelessWidget { Expanded( child: Container( margin: const EdgeInsets.only(left: 10.0, right: 20.0), - child: Divider())), + child: const Divider())), Text( text!, style: Theme.of(context).textTheme.overline, @@ -19,7 +19,7 @@ class TextDivider extends StatelessWidget { Expanded( child: Container( margin: const EdgeInsets.only(left: 10.0, right: 20.0), - child: Divider())), + child: const Divider())), ]); } } diff --git a/app/pubspec.lock b/app/pubspec.lock index 1fddfdd3..caa62f3d 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "31.0.0" + version: "34.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "2.8.0" + version: "3.2.0" animations: dependency: "direct main" description: @@ -35,7 +35,7 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.1.6" + version: "3.1.9" args: dependency: transitive description: @@ -105,7 +105,7 @@ packages: name: build url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.2.1" build_config: dependency: transitive description: @@ -154,7 +154,7 @@ packages: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.1.3" + version: "8.1.4" characters: dependency: transitive description: @@ -280,7 +280,7 @@ packages: name: flash url: "https://pub.dartlang.org" source: hosted - version: "2.0.3+1" + version: "2.0.3+2" flutter: dependency: "direct main" description: flutter @@ -293,6 +293,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.3.2" + flutter_lints: + dependency: "direct main" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" flutter_localizations: dependency: transitive description: flutter @@ -318,7 +325,7 @@ packages: name: flutter_modular url: "https://pub.dartlang.org" source: hosted - version: "4.3.0" + version: "4.4.0" flutter_modular_annotations: dependency: transitive description: @@ -332,7 +339,7 @@ packages: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.2" flutter_test: dependency: "direct dev" description: flutter @@ -384,7 +391,7 @@ packages: name: hive_generator url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.1.2" http: dependency: "direct main" description: @@ -412,7 +419,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "3.1.0" + version: "3.1.1" injector: dependency: transitive description: @@ -448,6 +455,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.4.0" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" logging: dependency: transitive description: @@ -475,7 +489,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.1.3" meta: dependency: transitive description: @@ -496,7 +510,7 @@ packages: name: modular_core url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" modular_interfaces: dependency: transitive description: @@ -510,7 +524,7 @@ packages: name: msix url: "https://pub.dartlang.org" source: hosted - version: "2.6.6" + version: "2.8.2" package_config: dependency: transitive description: @@ -594,7 +608,7 @@ packages: name: path_provider_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.9" + version: "2.0.11" path_provider_ios: dependency: transitive description: @@ -608,28 +622,28 @@ packages: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.5" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.3" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" pdf: dependency: "direct main" description: @@ -650,7 +664,7 @@ packages: name: phosphor_flutter url: "https://pub.dartlang.org" source: hosted - version: "1.3.1" + version: "1.4.0" platform: dependency: transitive description: @@ -664,7 +678,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.1.2" pool: dependency: transitive description: @@ -762,28 +776,28 @@ packages: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.12" shared_preferences_android: dependency: transitive description: name: shared_preferences_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.9" + version: "2.0.10" shared_preferences_ios: dependency: transitive description: name: shared_preferences_ios url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.0.9" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" shared_preferences_macos: dependency: transitive description: @@ -804,14 +818,14 @@ packages: name: shared_preferences_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" shelf: dependency: transitive description: @@ -907,7 +921,7 @@ packages: name: triple url: "https://pub.dartlang.org" source: hosted - version: "1.3.3" + version: "1.4.0" typed_data: dependency: transitive description: @@ -921,28 +935,28 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.0.17" + version: "6.0.18" url_launcher_android: dependency: transitive description: name: url_launcher_android url: "https://pub.dartlang.org" source: hosted - version: "6.0.13" + version: "6.0.14" url_launcher_ios: dependency: transitive description: name: url_launcher_ios url: "https://pub.dartlang.org" source: hosted - version: "6.0.13" + version: "6.0.14" url_launcher_linux: dependency: transitive description: name: url_launcher_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" url_launcher_macos: dependency: transitive description: @@ -956,14 +970,14 @@ packages: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" url_launcher_web: dependency: transitive description: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.6" url_launcher_windows: dependency: transitive description: @@ -998,7 +1012,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.3.1" + version: "2.3.6" xdg_directories: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index a6239d74..135cc2d4 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -28,18 +28,18 @@ dependencies: http: ^0.13.4 hive: ^2.0.5 hive_flutter: ^1.1.0 - flutter_modular: ^4.3.0 - url_launcher: ^6.0.12 + flutter_modular: ^4.4.0 + url_launcher: ^6.0.18 flutter_markdown: ^0.6.9 rxdart: ^0.27.3 #universal_html: ^1.2.4 - flutter_svg: ^1.0.0 + flutter_svg: ^1.0.2 flutter_inappwebview: ^5.3.2 xml: ^5.3.0 flutter_localized_locales: ^2.0.3 bitsdojo_window: ^0.1.1+1 share_plus: ^3.0.4 - phosphor_flutter: ^1.3.1 + phosphor_flutter: ^1.4.0 # The following adds the Cupertino Icons font to your application. @@ -50,15 +50,16 @@ dependencies: animations: ^2.0.2 pdf: ^3.6.5 printing: ^5.6.6 - flash: ^2.0.3+1 + flash: ^2.0.3+2 + flutter_lints: ^1.0.4 flutter_icons: android: true ios: true image_path: "images/logo.png" dev_dependencies: build_runner: ^2.1.7 - hive_generator: ^1.1.1 - msix: ^2.6.6 + hive_generator: ^1.1.2 + msix: ^2.8.2 flutter_test: sdk: flutter #integration_test: diff --git a/docs/package.json b/docs/package.json index 33f908ae..4133aeb7 100644 --- a/docs/package.json +++ b/docs/package.json @@ -18,28 +18,28 @@ "prettier:diff": "prettier --config .prettierrc --list-different \"**/*.{js,jsx,ts,tsx,md,mdx}\"" }, "dependencies": { - "@docusaurus/core": "2.0.0-beta.13", - "@docusaurus/plugin-client-redirects": "2.0.0-beta.13", - "@docusaurus/plugin-pwa": "2.0.0-beta.13", - "@docusaurus/preset-classic": "2.0.0-beta.13", + "@docusaurus/core": "2.0.0-beta.14", + "@docusaurus/plugin-client-redirects": "2.0.0-beta.14", + "@docusaurus/plugin-pwa": "2.0.0-beta.14", + "@docusaurus/preset-classic": "2.0.0-beta.14", "@mdx-js/react": "^1.6.22", "clsx": "^1.1.1", "react": "^17.0.2", "react-dom": "^17.0.2" }, "devDependencies": { - "@babel/eslint-parser": "^7.15.8", - "eslint": "^8.5.0", - "eslint-config-airbnb": "^19.0.2", + "@babel/eslint-parser": "^7.16.5", + "eslint": "^8.7.0", + "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^8.3.0", "eslint-plugin-header": "^3.1.1", - "eslint-plugin-import": "^2.25.3", + "eslint-plugin-import": "^2.25.4", "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react": "^7.28.0", "eslint-plugin-react-hooks": "^4.3.0", "pnp-webpack-plugin": "^1.7.0", "prettier": "^2.5.1", - "stylelint": "^14.1.0" + "stylelint": "^14.2.0" }, "browserslist": { "production": [ diff --git a/docs/yarn.lock b/docs/yarn.lock index 4ba8de07..0cc69f2e 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -419,17 +419,17 @@ __metadata: languageName: node linkType: hard -"@babel/eslint-parser@npm:^7.15.8": - version: 7.15.8 - resolution: "@babel/eslint-parser@npm:7.15.8" +"@babel/eslint-parser@npm:^7.16.5": + version: 7.16.5 + resolution: "@babel/eslint-parser@npm:7.16.5" dependencies: eslint-scope: ^5.1.1 eslint-visitor-keys: ^2.1.0 semver: ^6.3.0 peerDependencies: "@babel/core": ">=7.11.0" - eslint: ">=7.5.0" - checksum: 1c88334837d9555330fdeeff7b75404d931a5f9452aa57940602c78807d5324246919029c4d47059bf6927b44187938e7eb1d8570f422458bd3d26b313c9f9b3 + eslint: ^7.5.0 || ^8.0.0 + checksum: 7d4fe169b371bdce3caab64d6434f251c661cef86e01e320f4e2f81bed159d1f366138e18abb7386d40032cd4972fce723ec9af8b9895d5559fa7caff52efbab languageName: node linkType: hard @@ -2826,9 +2826,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/core@npm:2.0.0-beta.13" +"@docusaurus/core@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/core@npm:2.0.0-beta.14" dependencies: "@babel/core": ^7.16.0 "@babel/generator": ^7.16.0 @@ -2840,19 +2840,19 @@ __metadata: "@babel/runtime": ^7.16.3 "@babel/runtime-corejs3": ^7.16.3 "@babel/traverse": ^7.16.3 - "@docusaurus/cssnano-preset": 2.0.0-beta.13 - "@docusaurus/mdx-loader": 2.0.0-beta.13 + "@docusaurus/cssnano-preset": 2.0.0-beta.14 + "@docusaurus/logger": 2.0.0-beta.14 + "@docusaurus/mdx-loader": 2.0.0-beta.14 "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-common": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-common": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 "@slorber/static-site-generator-webpack-plugin": ^4.0.0 "@svgr/webpack": ^6.0.0 autoprefixer: ^10.3.5 babel-loader: ^8.2.2 babel-plugin-dynamic-import-node: 2.3.0 boxen: ^5.0.1 - chalk: ^4.1.2 chokidar: ^3.5.2 clean-css: ^5.1.5 commander: ^5.1.0 @@ -2910,31 +2910,41 @@ __metadata: react-dom: ^16.8.4 || ^17.0.0 bin: docusaurus: bin/docusaurus.js - checksum: 2a2c80e4e45ed5922f2137d45dc7ade26ccd5dd8468d587a6b5fcc263f1633db081377208235c559d7b129e6cdd00aa210e3b1cbe0f0c9e0d6d0a8c837b3fb25 + checksum: 6a5a89ecbb55c8436b3463748e4869d7adb0bbf781dcdb0559b8ac96089685e51f494557462841bbbf5d1eef04344004cf637fde119bf600063489361c1be573 languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/cssnano-preset@npm:2.0.0-beta.13" +"@docusaurus/cssnano-preset@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/cssnano-preset@npm:2.0.0-beta.14" dependencies: cssnano-preset-advanced: ^5.1.4 postcss: ^8.3.7 postcss-sort-media-queries: ^4.1.0 - checksum: abf679eb70ed36388189efb05ff23536615d520e46c64ddd02ac1ff009245345dbf0969a6b86e907cdbe35b057fa9b0bdb1c92aad7e623cee15fe152f0587b19 + checksum: 415e3b15ad51ed669bab463c4f27d1ce8afeb2513d5b7126068a1827b2154c55e6b37a7ffaad7c9ccad2011f9611cc7d70782ee56e06a6d725b38c581b69a0ac + languageName: node + linkType: hard + +"@docusaurus/logger@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/logger@npm:2.0.0-beta.14" + dependencies: + chalk: ^4.1.2 + tslib: ^2.3.1 + checksum: 4670f3f4c19d9427f3d554e4b67aee42df19d7c61be9335c6caf6e979eb9c5e6c14cb753f7456318ebdf799ccc9fee9e2283991b2166f5eaa7345ef0ef40a48a languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/mdx-loader@npm:2.0.0-beta.13" +"@docusaurus/mdx-loader@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/mdx-loader@npm:2.0.0-beta.14" dependencies: "@babel/parser": ^7.16.4 "@babel/traverse": ^7.16.3 - "@docusaurus/utils": 2.0.0-beta.13 + "@docusaurus/logger": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 "@mdx-js/mdx": ^1.6.21 "@mdx-js/react": ^1.6.21 - chalk: ^4.1.2 escape-html: ^1.0.3 file-loader: ^6.2.0 fs-extra: ^10.0.0 @@ -2949,18 +2959,19 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 74d8b9b428974d2df431872199957ec7e302e7799cfe65a88aece18994dfbbe66125ab0ea3fee6d99f71b6d1915ba338bdeefe18e73b40ff9a98e98b44c8be8f + checksum: 248a8f73b4e016757ad5317e1312a8d2a4c6ee23ccf02782eb8395f5a7e165ae6a64cb9633441e4260e53c7518aa70e61d72c2f6d35246000d92f17a7ddfcfd6 languageName: node linkType: hard -"@docusaurus/plugin-client-redirects@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-client-redirects@npm:2.0.0-beta.13" +"@docusaurus/plugin-client-redirects@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-client-redirects@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-common": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/logger": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-common": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 chalk: ^4.1.2 eta: ^1.12.3 fs-extra: ^10.0.0 @@ -2969,19 +2980,19 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: da99c4b18ca1e104d38418817a76ad6e22b455523043462f7c8fd4c01f7e107957f3876ee043cc8ac903abfb49e9a032d176c8fb5cd3d92f17f6e81f4390872b + checksum: 966a4aeb1b9cc68bb9f464f9e98fca951c5b4259d6a42e7ba870a0aff936bf9fa48ddde4df3da385b92edc4bd2a3ce04aedb84b414ee732782b8d3763f8c4ef1 languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-content-blog@npm:2.0.0-beta.13" +"@docusaurus/plugin-content-blog@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-content-blog@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/mdx-loader": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 - chalk: ^4.1.2 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/logger": 2.0.0-beta.14 + "@docusaurus/mdx-loader": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 escape-string-regexp: ^4.0.0 feed: ^4.2.2 fs-extra: ^10.0.0 @@ -2997,19 +3008,19 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 1525515f9f8b1537eb22a8f9cc42127e8cb043fd7c5b6326b02791fc9ccbf3a68f88283f1fe63929f459e8cee42f28f134e799839c0e68fc414d219427d88ed1 + checksum: 9d98707faa0e577a2f0fe1da562d7fed5a7251fc79bedaf538e334b5b3536375c35238f8e2141d24ee7f15858f169da14d4a83837608dafca2a3168c069b7c05 languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-content-docs@npm:2.0.0-beta.13" +"@docusaurus/plugin-content-docs@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-content-docs@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/mdx-loader": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 - chalk: ^4.1.2 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/logger": 2.0.0-beta.14 + "@docusaurus/mdx-loader": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 combine-promises: ^1.1.0 escape-string-regexp: ^4.0.0 fs-extra: ^10.0.0 @@ -3026,18 +3037,18 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 6fbdcaf82f2a56657b6b30bfe7265722e32220b0459f633554c79f71a67744df6fee90b6b046714a66c36d9ff8982e8838a7e64365083b2fe497c352a07ba742 + checksum: d7c1951f189906481066a68461f4e4752d8ec7b3ba15de9b2a9ee6f36000a1fe0bcccee205594e8e8fff9bfb6e41a06639b50cf75a4c90fc6c4ac9ecfbe0d807 languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-content-pages@npm:2.0.0-beta.13" +"@docusaurus/plugin-content-pages@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-content-pages@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/mdx-loader": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/mdx-loader": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 globby: ^11.0.2 remark-admonitions: ^1.2.1 tslib: ^2.3.1 @@ -3045,68 +3056,71 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 00b923a08a9600b486fa536cc07cde97ef7ad596f841d25ec79ea094a021acfb050d52deb43766f611abde27f4cc9536cf8ee491070dc24859e97f6103e98771 + checksum: 1372f554d8629fc31629e0b77dbe957703204760c1020ef0a32e0d7cfef277eb26244e9db23cad73adecb468db7397b53c169fd53126295f0b3dcbc7453940ca languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-debug@npm:2.0.0-beta.13" +"@docusaurus/plugin-debug@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-debug@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 fs-extra: ^10.0.0 react-json-view: ^1.21.3 tslib: ^2.3.1 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 0fce8901555bbad7586d7012026106a771382a7273911af53ec1025bca2e5559ed02c7fdee8cbbfd11924e5bc9041c0e2ececc35fe6c590e2ade2c4a7a301989 + checksum: c5316e2d55970a3ebfef5e6a04726eef35ffbc54976bf13791ac2888566b0454b9f60620c4f840e5ef3e216359412754fef30ccef4755726b2e6a3875deae1a8 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-google-analytics@npm:2.0.0-beta.13" +"@docusaurus/plugin-google-analytics@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-google-analytics@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 + tslib: ^2.3.1 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 95a0d83e4f1e3302dce8f3c64bdfbf800e8a1c028ce8615867680e61c3e3b4bf0e3774ef2d96296c929bdcfe7cdeb428599111268cddece2755d1f1b09236136 + checksum: 6d36fc808a54ee04afd5713d6e2ed72a1f51256c928d93b04942a960188f4f7f5710300fbaff99f9ea344c26c3305823baaebd0a01cf5a25ed8261ec2f7296bd languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-google-gtag@npm:2.0.0-beta.13" +"@docusaurus/plugin-google-gtag@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-google-gtag@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 + tslib: ^2.3.1 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 1f76ae0d242528798b6414b0508a0f1f87000380077111da2dccf1b8ab1ad45f5809d4b1288b21ba1016d1a16235632e1adaeb1ce3a4ec6cca66494dcee64cb5 + checksum: f04ef80c58f64e349daca93a06c5cb91d026ddea7047fe5f788efc2a2ca2b0bbf1b5974fe799bb0d0b1da5cede6a5539ada165bb9a23511ca07d7b0e7ff655d3 languageName: node linkType: hard -"@docusaurus/plugin-pwa@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-pwa@npm:2.0.0-beta.13" +"@docusaurus/plugin-pwa@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-pwa@npm:2.0.0-beta.14" dependencies: "@babel/plugin-proposal-nullish-coalescing-operator": ^7.16.0 "@babel/plugin-proposal-optional-chaining": ^7.16.0 "@babel/preset-env": ^7.16.4 - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/theme-common": 2.0.0-beta.13 - "@docusaurus/theme-translations": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/theme-common": 2.0.0-beta.14 + "@docusaurus/theme-translations": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 babel-loader: ^8.2.2 clsx: ^1.1.1 core-js: ^3.18.0 terser-webpack-plugin: ^5.2.4 + tslib: ^2.3.1 webpack: ^5.61.0 webpack-merge: ^5.7.3 workbox-build: ^6.1.1 @@ -3116,46 +3130,46 @@ __metadata: "@babel/core": ^7.0.0 react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 2c1c1ebb6cff5bf83746c20060282940da08be12769d6a58554afe3471fab74725cce622f4232b53037230b71246a3057c0a999f40b789ea3c28ed48c895775c + checksum: cd6c69219585c9bed31321201688ae44f8f40ebc839a3b5d010d630adacb7a465238e36420165edf9c4a5548c6dc3664c98748b15d6bfce120ec7fea0c943b0d languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/plugin-sitemap@npm:2.0.0-beta.13" +"@docusaurus/plugin-sitemap@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/plugin-sitemap@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-common": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-common": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 fs-extra: ^10.0.0 sitemap: ^7.0.0 tslib: ^2.3.1 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 35c5ea019553704ea0bb6844f87d4fd2c24011ced241564e0f7701f9f258d8e2bedcdf08c6f438ddbe5e7c8d213391b6fc2cfe25fbfa0f68e085efd9c8982495 + checksum: eb0408666be6928033ff79565de29da2cda998b8c0b207f1f6595a712e3e9c02df9a159f25a5be9f84a9e55d1df3984ffefb8c3f8808ae7b0e779af91838e23a languageName: node linkType: hard -"@docusaurus/preset-classic@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/preset-classic@npm:2.0.0-beta.13" +"@docusaurus/preset-classic@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/preset-classic@npm:2.0.0-beta.14" dependencies: - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/plugin-content-blog": 2.0.0-beta.13 - "@docusaurus/plugin-content-docs": 2.0.0-beta.13 - "@docusaurus/plugin-content-pages": 2.0.0-beta.13 - "@docusaurus/plugin-debug": 2.0.0-beta.13 - "@docusaurus/plugin-google-analytics": 2.0.0-beta.13 - "@docusaurus/plugin-google-gtag": 2.0.0-beta.13 - "@docusaurus/plugin-sitemap": 2.0.0-beta.13 - "@docusaurus/theme-classic": 2.0.0-beta.13 - "@docusaurus/theme-search-algolia": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/plugin-content-blog": 2.0.0-beta.14 + "@docusaurus/plugin-content-docs": 2.0.0-beta.14 + "@docusaurus/plugin-content-pages": 2.0.0-beta.14 + "@docusaurus/plugin-debug": 2.0.0-beta.14 + "@docusaurus/plugin-google-analytics": 2.0.0-beta.14 + "@docusaurus/plugin-google-gtag": 2.0.0-beta.14 + "@docusaurus/plugin-sitemap": 2.0.0-beta.14 + "@docusaurus/theme-classic": 2.0.0-beta.14 + "@docusaurus/theme-search-algolia": 2.0.0-beta.14 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: c725f9369598e6a10ec4b9bc9db1d615f96e2ad38fa8af9768d23b43347a72d7a9e38b8cc7e0a971f6ba85930fbbf3055618466d952510f98904061f80cf4c88 + checksum: 67019820c851503a65a8083639fb299e859fe5b9ff49dde82d7b83b7a4f7aad72bcd0c5d0187a1dfcf56fa78db41be788cb1dfcad17117c8d0c562fbb46e4c48 languageName: node linkType: hard @@ -3171,24 +3185,24 @@ __metadata: languageName: node linkType: hard -"@docusaurus/theme-classic@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/theme-classic@npm:2.0.0-beta.13" +"@docusaurus/theme-classic@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/theme-classic@npm:2.0.0-beta.14" dependencies: - "@docusaurus/plugin-content-blog": 2.0.0-beta.13 - "@docusaurus/plugin-content-docs": 2.0.0-beta.13 - "@docusaurus/plugin-content-pages": 2.0.0-beta.13 - "@docusaurus/theme-common": 2.0.0-beta.13 - "@docusaurus/theme-translations": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/plugin-content-blog": 2.0.0-beta.14 + "@docusaurus/plugin-content-docs": 2.0.0-beta.14 + "@docusaurus/plugin-content-pages": 2.0.0-beta.14 + "@docusaurus/theme-common": 2.0.0-beta.14 + "@docusaurus/theme-translations": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 "@mdx-js/mdx": ^1.6.21 "@mdx-js/react": ^1.6.21 - chalk: ^4.1.2 clsx: ^1.1.1 copy-text-to-clipboard: ^3.0.1 globby: ^11.0.2 - infima: 0.2.0-alpha.36 + infima: 0.2.0-alpha.37 lodash: ^4.17.20 postcss: ^8.3.7 prism-react-renderer: ^1.2.1 @@ -3198,17 +3212,17 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: e46520c96b649b7d0151a3086e5e38cf92bd2f568bd9d0eb5fb3b57c973683c3ab1c6abc6c65f93c34836cc67e666843a8c54bb5e503de3bc23652f1a851fd39 + checksum: ebb4c362e4a2bedcb1539b4ba90751c3942145f482ddf03734df6aafddc558e7ef8075930829d15c19be54637728a63bdefbe2c5db78a2beb3212398ecb2f313 languageName: node linkType: hard -"@docusaurus/theme-common@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/theme-common@npm:2.0.0-beta.13" +"@docusaurus/theme-common@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/theme-common@npm:2.0.0-beta.14" dependencies: - "@docusaurus/plugin-content-blog": 2.0.0-beta.13 - "@docusaurus/plugin-content-docs": 2.0.0-beta.13 - "@docusaurus/plugin-content-pages": 2.0.0-beta.13 + "@docusaurus/plugin-content-blog": 2.0.0-beta.14 + "@docusaurus/plugin-content-docs": 2.0.0-beta.14 + "@docusaurus/plugin-content-pages": 2.0.0-beta.14 clsx: ^1.1.1 fs-extra: ^10.0.0 parse-numeric-range: ^1.3.0 @@ -3218,70 +3232,75 @@ __metadata: prism-react-renderer: ^1.2.1 react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: e0f048a38f650fc9d52eefcc688fbedea0e47ea7b2d65a5ac72a0ca3a50d7a8079dda3c28f0d6e6a6d6cee21e7ddda2c33e99eb87dc1ac9c37bc2f4eacc1a38b + checksum: dbe969d676e901fe730cac2b95e87452e72c5fe31409e5d46c0d49f38da80177f79c20121eaa64b1d19cd60d6a8f179f30b13e0b1724d1e2618164a5f0dc0a2f languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/theme-search-algolia@npm:2.0.0-beta.13" +"@docusaurus/theme-search-algolia@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/theme-search-algolia@npm:2.0.0-beta.14" dependencies: "@docsearch/react": ^3.0.0-alpha.39 - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/theme-common": 2.0.0-beta.13 - "@docusaurus/theme-translations": 2.0.0-beta.13 - "@docusaurus/utils": 2.0.0-beta.13 - "@docusaurus/utils-validation": 2.0.0-beta.13 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/logger": 2.0.0-beta.14 + "@docusaurus/theme-common": 2.0.0-beta.14 + "@docusaurus/theme-translations": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 + "@docusaurus/utils-validation": 2.0.0-beta.14 algoliasearch: ^4.10.5 algoliasearch-helper: ^3.5.5 clsx: ^1.1.1 eta: ^1.12.3 lodash: ^4.17.20 + tslib: ^2.3.1 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 7cf9fccbd1e18c5e15a781d1c91bd6b0cd9e13937ee9753c48ea4958b0de74586b66e2cdd3b387f2cbc22dac8127362a4f4b1a91c90c55614a3c906c3d654fbb + checksum: d4dbaebb21e667e254f06e8146259df29c867a5d8927d09358fa233e4d526252afc9210cc446f12c13930a39880aa201ebe34ba423f7a4744475c173197d2dae languageName: node linkType: hard -"@docusaurus/theme-translations@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/theme-translations@npm:2.0.0-beta.13" +"@docusaurus/theme-translations@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/theme-translations@npm:2.0.0-beta.14" dependencies: fs-extra: ^10.0.0 tslib: ^2.3.1 - checksum: a7244d01aa1ee567b363526bfec94c7a7fec27714f9674394e15f5217bb8e44e321d6fb5adbbf30c28f23dcd945d1e396d5df5be74b69ca68c4a14bc8c6f35b7 + checksum: cb8d81ecc97aad96e3f320cb81bafe13bc9b5e0f509fdc7fbd1758c819aba8b3b50946505d2df2b0c802f3f15472295e49227c5f33037dcd3187ece7f03d227d languageName: node linkType: hard -"@docusaurus/utils-common@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/utils-common@npm:2.0.0-beta.13" +"@docusaurus/utils-common@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/utils-common@npm:2.0.0-beta.14" dependencies: tslib: ^2.3.1 - checksum: 76232c036bfd91d4d6b5125e6958d818f2cc7b9b721bc2aefbe5bfb469e51cf08587bd645ef268f5bb354396cd5a4fcaf1aac25b6690de1b4dd1e75a142cd7c2 + checksum: 9f4f225a299962aaff701e3bcb920129e1a5e6be91195ab35d121da0369316effa491e53db2dc027f001122f6dfd44f9c5eca2cfbcd18341cdd5364cc0b84377 languageName: node linkType: hard -"@docusaurus/utils-validation@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/utils-validation@npm:2.0.0-beta.13" +"@docusaurus/utils-validation@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/utils-validation@npm:2.0.0-beta.14" dependencies: - "@docusaurus/utils": 2.0.0-beta.13 - chalk: ^4.1.2 + "@docusaurus/logger": 2.0.0-beta.14 + "@docusaurus/utils": 2.0.0-beta.14 joi: ^17.4.2 tslib: ^2.3.1 - checksum: 4c5e7925e35b35e9b32fc6973d433a1d68f22e5b1201cb59cbb64b1c79aabf1e0c0cf82bb7390d444c66f3aa52d2af01ec8bc390f239e273fa4738221bd1f9aa + peerDependencies: + react: "*" + react-dom: "*" + checksum: f7ce474afe40c94cd9c82e02ee4814d4be507bf4947a793e34cd39146bff0415913646386e136b6d1a8aca5fe1621ba199cb3f8cb7e5d7a87da197cdfc58a5f7 languageName: node linkType: hard -"@docusaurus/utils@npm:2.0.0-beta.13": - version: 2.0.0-beta.13 - resolution: "@docusaurus/utils@npm:2.0.0-beta.13" +"@docusaurus/utils@npm:2.0.0-beta.14": + version: 2.0.0-beta.14 + resolution: "@docusaurus/utils@npm:2.0.0-beta.14" dependencies: + "@docusaurus/logger": 2.0.0-beta.14 "@mdx-js/runtime": ^1.6.22 "@svgr/webpack": ^6.0.0 - chalk: ^4.1.2 escape-string-regexp: ^4.0.0 file-loader: ^6.2.0 fs-extra: ^10.0.0 @@ -3299,7 +3318,7 @@ __metadata: react: "*" react-dom: "*" webpack: 5.x - checksum: d2dd59bf544b384454a5330d7f5aa342b263d567e2d00f83d55afe43f30f010d538e104089116c3d40122c2c9313b9e657aca2c5b8a08fa3e64e7eb365e5ba7d + checksum: f527eeeca51ca8f38a7d2a486af4091ef59440ff9c98c0053327d003a806a65298007ac57b02dd55b87d4cca222af45aebce3be4f6d065f5ac3abcf78567c49e languageName: node linkType: hard @@ -4226,6 +4245,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.7.0": + version: 8.7.0 + resolution: "acorn@npm:8.7.0" + bin: + acorn: bin/acorn + checksum: e0f79409d68923fbf1aa6d4166f3eedc47955320d25c89a20cc822e6ba7c48c5963d5bc657bc242d68f7a4ac9faf96eef033e8f73656da6c640d4219935fdfd0 + languageName: node + linkType: hard + "address@npm:^1.0.1, address@npm:^1.1.2": version: 1.1.2 resolution: "address@npm:1.1.2" @@ -4404,13 +4432,6 @@ __metadata: languageName: node linkType: hard -"ansi-colors@npm:^4.1.1": - version: 4.1.1 - resolution: "ansi-colors@npm:4.1.1" - checksum: 138d04a51076cb085da0a7e2d000c5c0bb09f6e772ed5c65c53cb118d37f6c5f1637506d7155fb5f330f0abcf6f12fa2e489ac3f8cdab9da393bf1bb4f9a32b0 - languageName: node - linkType: hard - "ansi-escapes@npm:^4.3.1": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -5369,7 +5390,7 @@ __metadata: languageName: node linkType: hard -"colord@npm:^2.9.1": +"colord@npm:^2.9.1, colord@npm:^2.9.2": version: 2.9.2 resolution: "colord@npm:2.9.2" checksum: 2aa6a9b3abbce74ba3c563886cfeb433ea0d7df5ad6f4a560005eddab1ddf7c0fc98f39b09b599767a19c86dd3837b77f66f036e479515d4b17347006dbd6d9f @@ -5972,7 +5993,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.3.2": +"debug@npm:4, debug@npm:^4.3.2, debug@npm:^4.3.3": version: 4.3.3 resolution: "debug@npm:4.3.3" dependencies: @@ -6181,26 +6202,26 @@ __metadata: version: 0.0.0-use.local resolution: "dev-doctor-docs@workspace:." dependencies: - "@babel/eslint-parser": ^7.15.8 - "@docusaurus/core": 2.0.0-beta.13 - "@docusaurus/plugin-client-redirects": 2.0.0-beta.13 - "@docusaurus/plugin-pwa": 2.0.0-beta.13 - "@docusaurus/preset-classic": 2.0.0-beta.13 + "@babel/eslint-parser": ^7.16.5 + "@docusaurus/core": 2.0.0-beta.14 + "@docusaurus/plugin-client-redirects": 2.0.0-beta.14 + "@docusaurus/plugin-pwa": 2.0.0-beta.14 + "@docusaurus/preset-classic": 2.0.0-beta.14 "@mdx-js/react": ^1.6.22 clsx: ^1.1.1 - eslint: ^8.5.0 - eslint-config-airbnb: ^19.0.2 + eslint: ^8.7.0 + eslint-config-airbnb: ^19.0.4 eslint-config-prettier: ^8.3.0 eslint-plugin-header: ^3.1.1 - eslint-plugin-import: ^2.25.3 + eslint-plugin-import: ^2.25.4 eslint-plugin-jsx-a11y: ^6.5.1 - eslint-plugin-react: ^7.27.1 + eslint-plugin-react: ^7.28.0 eslint-plugin-react-hooks: ^4.3.0 pnp-webpack-plugin: ^1.7.0 prettier: ^2.5.1 react: ^17.0.2 react-dom: ^17.0.2 - stylelint: ^14.1.0 + stylelint: ^14.2.0 languageName: unknown linkType: soft @@ -6484,15 +6505,6 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:^2.3.5": - version: 2.3.6 - resolution: "enquirer@npm:2.3.6" - dependencies: - ansi-colors: ^4.1.1 - checksum: 1c0911e14a6f8d26721c91e01db06092a5f7675159f0261d69c403396a385afd13dd76825e7678f66daffa930cfaa8d45f506fb35f818a2788463d022af1b884 - languageName: node - linkType: hard - "entities@npm:^1.1.1, entities@npm:~1.1.1": version: 1.1.2 resolution: "entities@npm:1.1.2" @@ -6640,9 +6652,9 @@ __metadata: languageName: node linkType: hard -"eslint-config-airbnb@npm:^19.0.2": - version: 19.0.2 - resolution: "eslint-config-airbnb@npm:19.0.2" +"eslint-config-airbnb@npm:^19.0.4": + version: 19.0.4 + resolution: "eslint-config-airbnb@npm:19.0.4" dependencies: eslint-config-airbnb-base: ^15.0.0 object.assign: ^4.1.2 @@ -6651,9 +6663,9 @@ __metadata: eslint: ^7.32.0 || ^8.2.0 eslint-plugin-import: ^2.25.3 eslint-plugin-jsx-a11y: ^6.5.1 - eslint-plugin-react: ^7.27.1 + eslint-plugin-react: ^7.28.0 eslint-plugin-react-hooks: ^4.3.0 - checksum: 668d91fee4d8e1b7ecefc3844caed6bb77a72b29521dd9595a14abaebb8651439b831da792614b51e7913bbe3b6d20df03e76f52287ccf511dee1982460d3f71 + checksum: 253178689c3c80eef2567e3aaf0612e18973bc9cf51d9be36074b5dd58210e8b6942200a424bcccbb81ac884e41303479ab09f251a2a97addc2de61efdc9576c languageName: node linkType: hard @@ -6678,14 +6690,13 @@ __metadata: languageName: node linkType: hard -"eslint-module-utils@npm:^2.7.1": - version: 2.7.1 - resolution: "eslint-module-utils@npm:2.7.1" +"eslint-module-utils@npm:^2.7.2": + version: 2.7.2 + resolution: "eslint-module-utils@npm:2.7.2" dependencies: debug: ^3.2.7 find-up: ^2.1.0 - pkg-dir: ^2.0.0 - checksum: c30dfa125aafe65e5f6a30a31c26932106fcf09934a2f47d7f8a393ed9106da7b07416f2337b55c85f9db0175c873ee0827be5429a24ec381b49940f342b9ac3 + checksum: 3e6407461d12b1568556fc9a84668415693ecce92d17d7407353defcfcafec5d3d8dfa2d9eda3743b3b53ef04101d8aa69072b3d634d92e766c3dfa10505542d languageName: node linkType: hard @@ -6698,26 +6709,26 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-import@npm:^2.25.3": - version: 2.25.3 - resolution: "eslint-plugin-import@npm:2.25.3" +"eslint-plugin-import@npm:^2.25.4": + version: 2.25.4 + resolution: "eslint-plugin-import@npm:2.25.4" dependencies: array-includes: ^3.1.4 array.prototype.flat: ^1.2.5 debug: ^2.6.9 doctrine: ^2.1.0 eslint-import-resolver-node: ^0.3.6 - eslint-module-utils: ^2.7.1 + eslint-module-utils: ^2.7.2 has: ^1.0.3 is-core-module: ^2.8.0 is-glob: ^4.0.3 minimatch: ^3.0.4 object.values: ^1.1.5 resolve: ^1.20.0 - tsconfig-paths: ^3.11.0 + tsconfig-paths: ^3.12.0 peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: 8bdf4b1fafb0e5c8f57a1673f72d84307d32c06a23942990d198c8b32a85a5ae0098872d1ef5bf80d7dfe8ec542f6a671e3c5e706731a80b493c9015f7a147f5 + checksum: 0af24f5c7c6ca692f42e3947127f0ae7dfe44f1e02740f7cbe988b510a9c52bab0065d7df04e2d953dcc88a4595a00cbdcf14018acf8cd75cfd47b72efcbb734 languageName: node linkType: hard @@ -6752,9 +6763,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react@npm:^7.27.1": - version: 7.27.1 - resolution: "eslint-plugin-react@npm:7.27.1" +"eslint-plugin-react@npm:^7.28.0": + version: 7.28.0 + resolution: "eslint-plugin-react@npm:7.28.0" dependencies: array-includes: ^3.1.4 array.prototype.flatmap: ^1.2.5 @@ -6772,7 +6783,7 @@ __metadata: string.prototype.matchall: ^4.0.6 peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: db1ce303b597ede0bc8873d3f575b05873b06a058162c80f76604c9096eee8f72f299d7f849a86ac2e59f269c196575e6bcfb1ef9d7cbb23f533d081bcc15ea0 + checksum: 90293d0fd53bb1f735ffd32141cdd211fb1120c9f7bbe5342f9e923261a39e52a2b2575d4e46c9cd77d257f42db4a99b8b339689fc5b5c1c26048929f69b1784 languageName: node linkType: hard @@ -6821,9 +6832,16 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.5.0": - version: 8.5.0 - resolution: "eslint@npm:8.5.0" +"eslint-visitor-keys@npm:^3.2.0": + version: 3.2.0 + resolution: "eslint-visitor-keys@npm:3.2.0" + checksum: fdadbb26f9e6417d3db7ad4f00bb0d573b6031c32fa72e8cdae32d038223faaeddff2ee443c90cb489bf774e75bff765c00912b8f9106d65e4f202ccd78c1b18 + languageName: node + linkType: hard + +"eslint@npm:^8.7.0": + version: 8.7.0 + resolution: "eslint@npm:8.7.0" dependencies: "@eslint/eslintrc": ^1.0.5 "@humanwhocodes/config-array": ^0.9.2 @@ -6832,12 +6850,11 @@ __metadata: cross-spawn: ^7.0.2 debug: ^4.3.2 doctrine: ^3.0.0 - enquirer: ^2.3.5 escape-string-regexp: ^4.0.0 eslint-scope: ^7.1.0 eslint-utils: ^3.0.0 - eslint-visitor-keys: ^3.1.0 - espree: ^9.2.0 + eslint-visitor-keys: ^3.2.0 + espree: ^9.3.0 esquery: ^1.4.0 esutils: ^2.0.2 fast-deep-equal: ^3.1.3 @@ -6845,7 +6862,7 @@ __metadata: functional-red-black-tree: ^1.0.1 glob-parent: ^6.0.1 globals: ^13.6.0 - ignore: ^4.0.6 + ignore: ^5.2.0 import-fresh: ^3.0.0 imurmurhash: ^0.1.4 is-glob: ^4.0.0 @@ -6856,16 +6873,14 @@ __metadata: minimatch: ^3.0.4 natural-compare: ^1.4.0 optionator: ^0.9.1 - progress: ^2.0.0 regexpp: ^3.2.0 - semver: ^7.2.1 strip-ansi: ^6.0.1 strip-json-comments: ^3.1.0 text-table: ^0.2.0 v8-compile-cache: ^2.0.3 bin: eslint: bin/eslint.js - checksum: c1a9e26070520a308cc30b62ba0d37d5b115ed23987a93219819537bdea9398e6ebe57c27d97be36ecc83b5162c72e82ecb0a9e5b44b7992980f9be90eb5c4b3 + checksum: 1c80375a48b0fe3ccae3c6354323e4f0e92e970f23abc5b9705b90b7aef514b69ebd0a63e74962d30789986c91fa41c0e25cd2f98f19e9e2a2d36aafdfc9ccc9 languageName: node linkType: hard @@ -6880,6 +6895,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^9.3.0": + version: 9.3.0 + resolution: "espree@npm:9.3.0" + dependencies: + acorn: ^8.7.0 + acorn-jsx: ^5.3.1 + eslint-visitor-keys: ^3.1.0 + checksum: c0f1885c4eab652f9be08eb9228cea0df046b559b29d4aed8d6590ea9bd60177d4cb245d204a6f737a79a096861bb4ab8e480aeb8c1dbafef5beec1157353ce4 + languageName: node + linkType: hard + "esprima@npm:^4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" @@ -8187,7 +8213,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.9": +"ignore@npm:^5.2.0": version: 5.2.0 resolution: "ignore@npm:5.2.0" checksum: 6b1f926792d614f64c6c83da3a1f9c83f6196c2839aa41e1e32dd7b8d174cef2e329d75caabb62cb61ce9dc432f75e67d07d122a037312db7caa73166a1bdb77 @@ -8246,10 +8272,10 @@ __metadata: languageName: node linkType: hard -"infima@npm:0.2.0-alpha.36": - version: 0.2.0-alpha.36 - resolution: "infima@npm:0.2.0-alpha.36" - checksum: 1f7ab5e8a30c9a43b8c4c89e9d83ffd64a23b3958e2a2be6cfdcf531ced0e0db2728f172d0c735d20c2d61455376763c088453372741eb0e9f3a8d4f4a4fa37e +"infima@npm:0.2.0-alpha.37": + version: 0.2.0-alpha.37 + resolution: "infima@npm:0.2.0-alpha.37" + checksum: e62695838bb628a0a11ea126b4ede6984e26ad46f7170ea5325bae373c6be93ea3bd1f19c274ca8ab1549705cd07b677d73a71ffe7134f06450ca299edb4d68f languageName: node linkType: hard @@ -9012,10 +9038,10 @@ __metadata: languageName: node linkType: hard -"known-css-properties@npm:^0.23.0": - version: 0.23.0 - resolution: "known-css-properties@npm:0.23.0" - checksum: 10d6400f6b411b731b9766be730ede298c7b28e94e2aaa882a014e5975da8028f3c7bab599358d4f53e1118ab33fc7e085c2b851167c698072bac917c372236f +"known-css-properties@npm:^0.24.0": + version: 0.24.0 + resolution: "known-css-properties@npm:0.24.0" + checksum: 071c3a9457ed2c5c46b6172d2c7b6a253ca4aec0c5c84da06e705026c377529fc57b690957c87f9313606be63a5152dc706102c09ba36102cc484936ec2f96b9 languageName: node linkType: hard @@ -10506,15 +10532,6 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^2.0.0": - version: 2.0.0 - resolution: "pkg-dir@npm:2.0.0" - dependencies: - find-up: ^2.1.0 - checksum: 8c72b712305b51e1108f0ffda5ec1525a8307e54a5855db8fb1dcf77561a5ae98e2ba3b4814c9806a679f76b2f7e5dd98bde18d07e594ddd9fdd25e9cf242ea1 - languageName: node - linkType: hard - "pkg-dir@npm:^4.1.0": version: 4.2.0 resolution: "pkg-dir@npm:4.2.0" @@ -11071,13 +11088,13 @@ __metadata: languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.6": - version: 6.0.7 - resolution: "postcss-selector-parser@npm:6.0.7" +"postcss-selector-parser@npm:^6.0.7": + version: 6.0.9 + resolution: "postcss-selector-parser@npm:6.0.9" dependencies: cssesc: ^3.0.0 util-deprecate: ^1.0.2 - checksum: 661808ad629e3f289e0d237fbe9bb13766dadd2d548ec09ae86f68118f5d98be0f25bbaf5cd88486c5416e2eefaa9f73c59c2fc98dc370872fa51b250c7d1d9c + checksum: f8161ab4d3e5c76b8467189c6d164ba0f6b6e74677435f29e34caa1df01e052b582b4ae4f7468b2243c4befdd8bdcdb7685542d1b2fca8deae21b3e849c78802 languageName: node linkType: hard @@ -11266,13 +11283,6 @@ __metadata: languageName: node linkType: hard -"progress@npm:^2.0.0": - version: 2.0.3 - resolution: "progress@npm:2.0.3" - checksum: f67403fe7b34912148d9252cb7481266a354bd99ce82c835f79070643bb3c6583d10dbcfda4d41e04bbc1d8437e9af0fb1e1f2135727878f5308682a579429b7 - languageName: node - linkType: hard - "promise-inflight@npm:^1.0.1": version: 1.0.1 resolution: "promise-inflight@npm:1.0.1" @@ -12338,7 +12348,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5": +"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5": version: 7.3.5 resolution: "semver@npm:7.3.5" dependencies: @@ -12989,13 +12999,14 @@ __metadata: languageName: node linkType: hard -"stylelint@npm:^14.1.0": - version: 14.1.0 - resolution: "stylelint@npm:14.1.0" +"stylelint@npm:^14.2.0": + version: 14.2.0 + resolution: "stylelint@npm:14.2.0" dependencies: balanced-match: ^2.0.0 + colord: ^2.9.2 cosmiconfig: ^7.0.1 - debug: ^4.3.2 + debug: ^4.3.3 execall: ^2.0.0 fast-glob: ^3.2.7 fastest-levenshtein: ^1.0.12 @@ -13005,11 +13016,11 @@ __metadata: globby: ^11.0.4 globjoin: ^0.1.4 html-tags: ^3.1.0 - ignore: ^5.1.9 + ignore: ^5.2.0 import-lazy: ^4.0.0 imurmurhash: ^0.1.4 is-plain-object: ^5.0.0 - known-css-properties: ^0.23.0 + known-css-properties: ^0.24.0 mathml-tag-names: ^2.1.3 meow: ^9.0.0 micromatch: ^4.0.4 @@ -13020,7 +13031,7 @@ __metadata: postcss-media-query-parser: ^0.2.3 postcss-resolve-nested-selector: ^0.1.1 postcss-safe-parser: ^6.0.0 - postcss-selector-parser: ^6.0.6 + postcss-selector-parser: ^6.0.7 postcss-value-parser: ^4.1.0 resolve-from: ^5.0.0 specificity: ^0.4.1 @@ -13028,12 +13039,12 @@ __metadata: strip-ansi: ^6.0.1 style-search: ^0.1.0 svg-tags: ^1.0.0 - table: ^6.7.3 + table: ^6.7.5 v8-compile-cache: ^2.3.0 write-file-atomic: ^3.0.3 bin: stylelint: bin/stylelint.js - checksum: c7a016ce0c0737cc5fa9ab8ab025cba2e534eae4ba936fc41d90de7e13e0947b6a78d68d2644572c0f743822444a4cdc25bb2f0bf3e3f9a8993a08b209b13e1a + checksum: cf0195b143efdea5a22d4e04817ac11ec9103a976a703265813c27baa9b52b9033f57e241b1f6ab7eb3b2eed63f66509b983c1fa03b29cb75372cc32cacfaec0 languageName: node linkType: hard @@ -13112,16 +13123,16 @@ __metadata: languageName: node linkType: hard -"table@npm:^6.7.3": - version: 6.7.5 - resolution: "table@npm:6.7.5" +"table@npm:^6.7.5": + version: 6.8.0 + resolution: "table@npm:6.8.0" dependencies: ajv: ^8.0.1 lodash.truncate: ^4.4.2 slice-ansi: ^4.0.0 string-width: ^4.2.3 strip-ansi: ^6.0.1 - checksum: 76d01e33d6ef881f21bfe2e343101cb05ef4cedf506523d187af4f3a33f0f69cf25bca3e05c0c5c0eb348b405aaac29d9bb308ba9bf2c5ca7a82d032382a1649 + checksum: 5b07fe462ee03d2e1fac02cbb578efd2e0b55ac07e3d3db2e950aa9570ade5a4a2b8d3c15e9f25c89e4e50b646bc4269934601ee1eef4ca7968ad31960977690 languageName: node linkType: hard @@ -13374,15 +13385,15 @@ __metadata: languageName: node linkType: hard -"tsconfig-paths@npm:^3.11.0": - version: 3.11.0 - resolution: "tsconfig-paths@npm:3.11.0" +"tsconfig-paths@npm:^3.12.0": + version: 3.12.0 + resolution: "tsconfig-paths@npm:3.12.0" dependencies: "@types/json5": ^0.0.29 json5: ^1.0.1 minimist: ^1.2.0 strip-bom: ^3.0.0 - checksum: e14aaa6883f316d611db41cbb0fc8779b59c66b31d1e045565ad4540c77ccd3d2bb66f7c261b74ff535d3cc6b4a1ce21dc84774bf2a2a603ed6b0fb96f7e0cc7 + checksum: 4999ec6cd1c7cc06750a460dbc0d39fe3595a4308cb5f1d0d0a8283009cf9c0a30d5a156508c28fe3a47760508af5263ab288fc23d71e9762779674257a95d3b languageName: node linkType: hard