From 9d77bdc1150252f3dcdc4174d3cd4b28efe6ae96 Mon Sep 17 00:00:00 2001 From: gokadzev Date: Sun, 26 Jun 2022 15:14:14 +0400 Subject: [PATCH] changelog: UI corrections basic implementation for translations --- l10n.yaml | 3 +++ lib/localization/app_en.arb | 32 ++++++++++++++++++++++++++ lib/main.dart | 16 +++++++++++++ lib/ui/aboutPage.dart | 3 ++- lib/ui/homePage.dart | 6 +++-- lib/ui/localSongsPage.dart | 16 ++++++++----- lib/ui/player.dart | 13 +++++++---- lib/ui/playlistPage.dart | 14 ++++++++---- lib/ui/playlistsPage.dart | 42 +++++++++++++++------------------- lib/ui/searchPage.dart | 22 ++++++++++++++++-- lib/ui/settingsPage.dart | 31 +++++++++++++------------ lib/ui/userLikedSongsPage.dart | 16 ++++++++----- lib/ui/userPlaylistsPage.dart | 15 ++++++++---- pubspec.lock | 12 ++++++++++ pubspec.yaml | 4 ++++ 15 files changed, 176 insertions(+), 69 deletions(-) create mode 100644 l10n.yaml create mode 100644 lib/localization/app_en.arb diff --git a/l10n.yaml b/l10n.yaml new file mode 100644 index 000000000..a5b643abb --- /dev/null +++ b/l10n.yaml @@ -0,0 +1,3 @@ +arb-dir: lib/localization +template-arb-file: app_en.arb +output-localization-file: app_localizations.dart \ No newline at end of file diff --git a/lib/localization/app_en.arb b/lib/localization/app_en.arb new file mode 100644 index 000000000..a9b213ce4 --- /dev/null +++ b/lib/localization/app_en.arb @@ -0,0 +1,32 @@ +{ + "about": "About", + "accentChangeMsg": "Accent color has been changed, move to other page to see changes", + "accentColor": "Accent color", + "add": "Add", + "appUpdateAvailableAndDownloading": "App update is available and downloading", + "appUpdateIsNotAvailable": "App update is not available", + "backupUserData": "Backup user data", + "backupedSuccesfully": "Backuped Succesfully", + "cacheMsg": "Cache cleared", + "clearCache": "Clear cache", + "downloadAppUpdate": "Download app update", + "localSongs": "Local songs", + "lyrics": "Lyrics", + "lyricsNotAvailable": "No lyrics available ;(", + "nowPlaying": "Now playing", + "playAll": "Play all", + "playlist": "Playlist", + "playlists": "Playlists", + "queueInitText": "Initialising queue... because of perfomance, only first 20 songs will be added in the queue.", + "recommendedForYou": "Recommended for you", + "restoreUserData": "Restore user data", + "restoredSuccesfully": "Restored Succesfully", + "search": "Search", + "settings": "Settings", + "suggestedPlaylists": "Suggested playlists", + "userLikedSongs": "User liked songs", + "userPlaylists": "User playlists", + "yourDownloadedSongsHere": "Your downloaded songs here", + "yourFavoriteSongsHere": "Your favorite songs here", + "youtubePlaylistID": "Youtube playlist ID" +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 32b30c9e3..788c470fd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'package:audio_service/audio_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_downloader/flutter_downloader.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:get_it/get_it.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hive_flutter/hive_flutter.dart'; @@ -12,11 +13,18 @@ import 'package:musify/services/data_manager.dart'; import 'package:musify/style/appColors.dart'; import 'package:musify/ui/rootPage.dart'; import 'package:package_info_plus/package_info_plus.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; GetIt getIt = GetIt.instance; +Locale _locale = const Locale('en', ''); main() async { await Hive.initFlutter(); + final String lang = await getData("settings", "languages") ?? "English"; + final Map codes = { + 'English': 'en', + }; + _locale = Locale(codes[lang]!); await getLocalSongs(); await FlutterDownloader.initialize( debug: @@ -55,6 +63,14 @@ class MyApp extends StatelessWidget { }, ), ), + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: [Locale('en', '')], + locale: _locale, home: Musify(), ); } diff --git a/lib/ui/aboutPage.dart b/lib/ui/aboutPage.dart index 04fddac1f..57d7dce70 100644 --- a/lib/ui/aboutPage.dart +++ b/lib/ui/aboutPage.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:musify/helper/version.dart'; import 'package:musify/style/appColors.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class AboutPage extends StatelessWidget { @override @@ -13,7 +14,7 @@ class AboutPage extends StatelessWidget { const SystemUiOverlayStyle(statusBarBrightness: Brightness.dark), centerTitle: true, title: Text( - "About", + AppLocalizations.of(context)!.about, style: TextStyle( color: accent, fontSize: 25, diff --git a/lib/ui/homePage.dart b/lib/ui/homePage.dart index e384eeff3..95efacb34 100644 --- a/lib/ui/homePage.dart +++ b/lib/ui/homePage.dart @@ -8,6 +8,7 @@ import 'package:musify/customWidgets/song_bar.dart'; import 'package:musify/customWidgets/spinner.dart'; import 'package:musify/style/appColors.dart'; import 'package:musify/ui/playlistPage.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class HomePage extends StatefulWidget { @override @@ -52,7 +53,8 @@ class _HomePageState extends State { right: 25, ), child: Text( - "Suggested Playlists", + AppLocalizations.of(context)! + .suggestedPlaylists, style: TextStyle( color: accent, fontSize: 20.0, @@ -106,7 +108,7 @@ class _HomePageState extends State { right: 25, ), child: Text( - "Recommended for you", + AppLocalizations.of(context)!.recommendedForYou, style: TextStyle( color: accent, fontSize: 20.0, diff --git a/lib/ui/localSongsPage.dart b/lib/ui/localSongsPage.dart index f8729484a..4d5e6a881 100644 --- a/lib/ui/localSongsPage.dart +++ b/lib/ui/localSongsPage.dart @@ -4,6 +4,7 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart import 'package:musify/API/musify.dart'; import 'package:musify/services/audio_manager.dart'; import 'package:musify/style/appColors.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class LocalSongsPage extends StatelessWidget { const LocalSongsPage({Key? key}) : super(key: key); @@ -17,7 +18,7 @@ class LocalSongsPage extends StatelessWidget { const SystemUiOverlayStyle(statusBarBrightness: Brightness.dark), centerTitle: true, title: Text( - "Local Songs", + AppLocalizations.of(context)!.localSongs, style: TextStyle( color: accent, fontSize: 25, @@ -62,7 +63,7 @@ class LocalSongsPage extends StatelessWidget { color: accent, ), Text( - "Local Songs", + AppLocalizations.of(context)!.localSongs, style: TextStyle(color: accent), textAlign: TextAlign.center, ), @@ -78,7 +79,7 @@ class LocalSongsPage extends StatelessWidget { children: [ const SizedBox(height: 12.0), Text( - "Local Songs", + AppLocalizations.of(context)!.localSongs, style: TextStyle( color: accent, fontSize: 18, @@ -87,7 +88,7 @@ class LocalSongsPage extends StatelessWidget { ), const SizedBox(height: 16.0), Text( - "Your downloaded songs here!", + "${AppLocalizations.of(context)!.yourDownloadedSongsHere}!", style: TextStyle( color: accent, fontSize: 10, @@ -104,8 +105,11 @@ class LocalSongsPage extends StatelessWidget { style: TextButton.styleFrom( backgroundColor: accent, ), - child: const Text( - "PLAY ALL", + child: Text( + AppLocalizations.of(context)! + .playAll + .toString() + .toUpperCase(), style: TextStyle(color: Colors.white), ), ), diff --git a/lib/ui/player.dart b/lib/ui/player.dart index 3278a7602..34a115ade 100644 --- a/lib/ui/player.dart +++ b/lib/ui/player.dart @@ -9,6 +9,7 @@ import 'package:musify/API/musify.dart'; import 'package:musify/customWidgets/spinner.dart'; import 'package:musify/services/audio_manager.dart'; import 'package:musify/style/appColors.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; String status = 'hidden'; @@ -53,7 +54,7 @@ class AudioAppState extends State { elevation: 0, centerTitle: true, title: Text( - "Now Playing", + AppLocalizations.of(context)!.nowPlaying, style: TextStyle( color: accent, fontSize: 25, @@ -409,7 +410,9 @@ class AudioAppState extends State { ), child: Center( child: Text( - "Lyrics", + AppLocalizations.of( + context)! + .lyrics, style: TextStyle( color: accent, fontSize: 30, @@ -458,7 +461,9 @@ class AudioAppState extends State { child: Center( child: Container( child: Text( - "No Lyrics available ;(", + AppLocalizations.of( + context)! + .lyricsNotAvailable, style: TextStyle( color: accentLight, fontSize: 25, @@ -474,7 +479,7 @@ class AudioAppState extends State { ); }, child: Text( - "Lyrics", + AppLocalizations.of(context)!.lyrics, style: TextStyle(color: accent), ), ); diff --git a/lib/ui/playlistPage.dart b/lib/ui/playlistPage.dart index 605d4cd58..9eb2c9821 100644 --- a/lib/ui/playlistPage.dart +++ b/lib/ui/playlistPage.dart @@ -9,6 +9,7 @@ import 'package:musify/API/musify.dart'; import 'package:musify/customWidgets/song_bar.dart'; import 'package:musify/customWidgets/spinner.dart'; import 'package:musify/style/appColors.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class PlaylistPage extends StatefulWidget { final dynamic playlist; @@ -82,7 +83,7 @@ class _PlaylistPageState extends State { const SystemUiOverlayStyle(statusBarBrightness: Brightness.dark), centerTitle: true, title: Text( - "Playlist", + AppLocalizations.of(context)!.playlist, style: TextStyle( color: accent, fontSize: 25, @@ -186,8 +187,8 @@ class _PlaylistPageState extends State { widget.playlist["list"] as List, ), Fluttertoast.showToast( - msg: - "Initialising queue... Because of perfomance, only first 20 songs will be added in the queue.", + msg: AppLocalizations.of(context)! + .queueInitText, toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.BOTTOM, backgroundColor: accent, @@ -198,8 +199,11 @@ class _PlaylistPageState extends State { style: TextButton.styleFrom( backgroundColor: accent, ), - child: const Text( - "PLAY ALL", + child: Text( + AppLocalizations.of(context)! + .playAll + .toString() + .toUpperCase(), style: TextStyle(color: Colors.white), ), ), diff --git a/lib/ui/playlistsPage.dart b/lib/ui/playlistsPage.dart index 5ada84102..16bc0e67b 100644 --- a/lib/ui/playlistsPage.dart +++ b/lib/ui/playlistsPage.dart @@ -1,10 +1,12 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:musify/API/musify.dart'; import 'package:musify/customWidgets/spinner.dart'; import 'package:musify/style/appColors.dart'; import 'package:musify/ui/playlistPage.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class PlaylistsPage extends StatefulWidget { @override @@ -15,33 +17,25 @@ class _PlaylistsPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: bgColor, + backgroundColor: Colors.transparent, + appBar: AppBar( + systemOverlayStyle: + const SystemUiOverlayStyle(statusBarBrightness: Brightness.dark), + centerTitle: true, + title: Text( + AppLocalizations.of(context)!.playlists, + style: TextStyle( + color: accent, + fontSize: 30, + fontWeight: FontWeight.w700, + ), + ), + backgroundColor: Colors.transparent, + elevation: 0, + ), body: SingleChildScrollView( child: Column( children: [ - const Padding(padding: EdgeInsets.only(top: 10, bottom: 20.0)), - Center( - child: Row( - children: [ - Expanded( - child: Padding( - padding: EdgeInsets.zero, - child: Center( - child: Text( - "Playlists", - style: TextStyle( - color: accent, - fontSize: 35, - fontWeight: FontWeight.w800, - ), - ), - ), - ), - ), - ], - ), - ), - const Padding(padding: EdgeInsets.only(top: 20)), FutureBuilder( future: getPlaylists(), builder: (context, data) { diff --git a/lib/ui/searchPage.dart b/lib/ui/searchPage.dart index 742d4601a..b0037eb58 100644 --- a/lib/ui/searchPage.dart +++ b/lib/ui/searchPage.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:musify/API/musify.dart'; import 'package:musify/customWidgets/song_bar.dart'; import 'package:musify/customWidgets/spinner.dart'; import 'package:musify/style/appColors.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class SearchPage extends StatefulWidget { @override @@ -27,11 +29,27 @@ class _SearchPageState extends State { @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + systemOverlayStyle: + const SystemUiOverlayStyle(statusBarBrightness: Brightness.dark), + centerTitle: true, + title: Text( + AppLocalizations.of(context)!.search, + style: TextStyle( + color: accent, + fontSize: 30, + fontWeight: FontWeight.w700, + ), + ), + backgroundColor: Colors.transparent, + elevation: 0, + ), body: SingleChildScrollView( padding: const EdgeInsets.all(12.0), child: Column( children: [ - const Padding(padding: EdgeInsets.only(top: 30, bottom: 20.0)), + const Padding(padding: EdgeInsets.only(bottom: 20.0)), TextField( onSubmitted: (String value) { search(); @@ -75,7 +93,7 @@ class _SearchPageState extends State { }, ), border: InputBorder.none, - hintText: "Search...", + hintText: "${AppLocalizations.of(context)!.search}...", hintStyle: TextStyle( color: accent, ), diff --git a/lib/ui/settingsPage.dart b/lib/ui/settingsPage.dart index 768165df0..98ca21500 100644 --- a/lib/ui/settingsPage.dart +++ b/lib/ui/settingsPage.dart @@ -8,6 +8,7 @@ import 'package:musify/style/appColors.dart'; import 'package:musify/ui/aboutPage.dart'; import 'package:musify/ui/userLikedSongsPage.dart'; import 'package:musify/ui/userPlaylistsPage.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class SettingsPage extends StatefulWidget { @override @@ -24,7 +25,7 @@ class _SettingsPageState extends State { const SystemUiOverlayStyle(statusBarBrightness: Brightness.dark), centerTitle: true, title: Text( - "Settings", + AppLocalizations.of(context)!.settings, style: TextStyle( color: accent, fontSize: 25, @@ -55,7 +56,7 @@ class SettingsCards extends StatelessWidget { child: ListTile( leading: Icon(MdiIcons.shapeOutline, color: accent), title: Text( - 'Accent Color', + AppLocalizations.of(context)!.accentColor, style: TextStyle(color: accent), ), onTap: () { @@ -140,8 +141,8 @@ class SettingsCards extends StatelessWidget { Fluttertoast.showToast( backgroundColor: accent, textColor: Colors.white, - msg: - "Accent Color has been Changed, move to other page to see changes!", + msg: AppLocalizations.of(context)! + .accentChangeMsg, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, fontSize: 14.0, @@ -185,7 +186,7 @@ class SettingsCards extends StatelessWidget { child: ListTile( leading: Icon(MdiIcons.broom, color: accent), title: Text( - 'Clear Cache', + AppLocalizations.of(context)!.clearCache, style: TextStyle(color: accent), ), onTap: () { @@ -193,7 +194,7 @@ class SettingsCards extends StatelessWidget { Fluttertoast.showToast( backgroundColor: accent, textColor: Colors.white, - msg: "Cache cleared!", + msg: "${AppLocalizations.of(context)!.cacheMsg}!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, fontSize: 14.0, @@ -213,7 +214,7 @@ class SettingsCards extends StatelessWidget { child: ListTile( leading: Icon(MdiIcons.account, color: accent), title: Text( - 'User Playlists', + AppLocalizations.of(context)!.userPlaylists, style: TextStyle(color: accent), ), onTap: () { @@ -238,7 +239,7 @@ class SettingsCards extends StatelessWidget { child: ListTile( leading: Icon(MdiIcons.star, color: accent), title: Text( - 'User Liked Songs', + AppLocalizations.of(context)!.userLikedSongs, style: TextStyle(color: accent), ), onTap: () { @@ -261,7 +262,7 @@ class SettingsCards extends StatelessWidget { child: ListTile( leading: Icon(MdiIcons.cloudUpload, color: accent), title: Text( - 'Backup User Data', + AppLocalizations.of(context)!.backupUserData, style: TextStyle(color: accent), ), onTap: () { @@ -290,7 +291,7 @@ class SettingsCards extends StatelessWidget { child: ListTile( leading: Icon(MdiIcons.cloudDownload, color: accent), title: Text( - 'Restore User Data', + AppLocalizations.of(context)!.restoreUserData, style: TextStyle(color: accent), ), onTap: () { @@ -317,7 +318,7 @@ class SettingsCards extends StatelessWidget { child: ListTile( leading: Icon(MdiIcons.download, color: accent), title: Text( - 'Download App Update', + AppLocalizations.of(context)!.downloadAppUpdate, style: TextStyle(color: accent), ), onTap: () { @@ -326,7 +327,8 @@ class SettingsCards extends StatelessWidget { if (available == true) { Fluttertoast.showToast( - msg: "App Update Is Available And Downloading!", + msg: + "${AppLocalizations.of(context)!.appUpdateAvailableAndDownloading}!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: accent, @@ -338,7 +340,8 @@ class SettingsCards extends StatelessWidget { else { Fluttertoast.showToast( - msg: "App Update Is Not Available!", + msg: + "${AppLocalizations.of(context)!.appUpdateIsNotAvailable}!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, backgroundColor: accent, @@ -363,7 +366,7 @@ class SettingsCards extends StatelessWidget { child: ListTile( leading: Icon(MdiIcons.information, color: accent), title: Text( - 'About', + AppLocalizations.of(context)!.about, style: TextStyle(color: accent), ), onTap: () { diff --git a/lib/ui/userLikedSongsPage.dart b/lib/ui/userLikedSongsPage.dart index af5bd0094..76073217e 100644 --- a/lib/ui/userLikedSongsPage.dart +++ b/lib/ui/userLikedSongsPage.dart @@ -4,6 +4,7 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart import 'package:musify/API/musify.dart'; import 'package:musify/customWidgets/song_bar.dart'; import 'package:musify/style/appColors.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class UserLikedSongs extends StatefulWidget { @override @@ -20,7 +21,7 @@ class _UserLikedSongsState extends State { const SystemUiOverlayStyle(statusBarBrightness: Brightness.dark), centerTitle: true, title: Text( - "User Liked Songs", + AppLocalizations.of(context)!.userLikedSongs, style: TextStyle( color: accent, fontSize: 25, @@ -72,7 +73,7 @@ class _UserLikedSongsState extends State { color: accent, ), Text( - "User Liked Songs", + AppLocalizations.of(context)!.userLikedSongs, style: TextStyle(color: accent), textAlign: TextAlign.center, ), @@ -88,7 +89,7 @@ class _UserLikedSongsState extends State { children: [ const SizedBox(height: 12.0), Text( - "User Liked Songs", + AppLocalizations.of(context)!.userLikedSongs, style: TextStyle( color: accent, fontSize: 18, @@ -97,7 +98,7 @@ class _UserLikedSongsState extends State { ), const SizedBox(height: 16.0), Text( - "Your favorite songs here!", + "${AppLocalizations.of(context)!.yourFavoriteSongsHere}!", style: TextStyle( color: accent, fontSize: 10, @@ -115,8 +116,11 @@ class _UserLikedSongsState extends State { style: TextButton.styleFrom( backgroundColor: accent, ), - child: const Text( - "PLAY ALL", + child: Text( + AppLocalizations.of(context)! + .playAll + .toString() + .toUpperCase(), style: TextStyle(color: Colors.white), ), ), diff --git a/lib/ui/userPlaylistsPage.dart b/lib/ui/userPlaylistsPage.dart index e6955c473..ce3a8d824 100644 --- a/lib/ui/userPlaylistsPage.dart +++ b/lib/ui/userPlaylistsPage.dart @@ -4,6 +4,7 @@ import 'package:musify/API/musify.dart'; import 'package:musify/customWidgets/spinner.dart'; import 'package:musify/style/appColors.dart'; import 'package:musify/ui/playlistsPage.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class UserPlaylistsPage extends StatefulWidget { @override @@ -20,7 +21,7 @@ class _UserPlaylistsPageState extends State { const SystemUiOverlayStyle(statusBarBrightness: Brightness.dark), centerTitle: true, title: Text( - "User Playlists", + AppLocalizations.of(context)!.userPlaylists, style: TextStyle( color: accent, fontSize: 25, @@ -48,8 +49,9 @@ class _UserPlaylistsPageState extends State { content: Stack( children: [ TextField( - decoration: const InputDecoration( - hintText: 'Youtube Playlist ID', + decoration: InputDecoration( + hintText: + AppLocalizations.of(context)!.youtubePlaylistID, ), onChanged: (value) { setState(() { @@ -61,8 +63,11 @@ class _UserPlaylistsPageState extends State { ), actions: [ TextButton( - child: const Text( - 'ADD', + child: Text( + AppLocalizations.of(context)! + .add + .toString() + .toUpperCase(), style: TextStyle(color: Colors.black), ), onPressed: () { diff --git a/pubspec.lock b/pubspec.lock index 8745f5a09..e592bf717 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -174,6 +174,11 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0+1" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_native_splash: dependency: "direct dev" description: @@ -268,6 +273,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.3" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" js: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7f8ede0af..911fcd6fb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -23,6 +23,9 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter + intl: ^0.17.0 path_provider: ^2.0.11 @@ -57,6 +60,7 @@ flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. + generate: true uses-material-design: true fonts: - family: DMSans