From 93bf3daa791421286a0df5f1804da546fd990007 Mon Sep 17 00:00:00 2001 From: Jean28518 Date: Sun, 4 Aug 2024 19:47:23 +0200 Subject: [PATCH] Revamp onboarding process #227 --- lib/l10n/app_de.arb | 3 +- lib/l10n/app_en.arb | 3 +- lib/l10n/app_it.arb | 1 + .../activate_hotkey.dart | 0 .../communication_software.dart | 5 +- .../greeter/environment_selection.dart | 291 ------------------ .../greeter/is_environment_correct.dart | 56 ---- lib/layouts/greeter/start_screen.dart | 3 +- .../main_screen/recommendation_card.dart | 13 + .../settings/environment_selection.dart | 219 +++++++++++++ lib/layouts/settings/settings_start.dart | 20 +- lib/services/action_handler.dart | 2 +- 12 files changed, 262 insertions(+), 354 deletions(-) rename lib/layouts/{greeter => after_installation}/activate_hotkey.dart (100%) delete mode 100644 lib/layouts/greeter/environment_selection.dart delete mode 100644 lib/layouts/greeter/is_environment_correct.dart create mode 100644 lib/layouts/settings/environment_selection.dart diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index e54b05c..d915328 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -7,7 +7,7 @@ "warpinatorDescription": "Sende Dateien schnell über das lokale Netzwerk. Zu Linux, Android, iOS und Windows.", "sendFeedback": "Sende Feedback", "securityCheck": "Sicherheitsüberprüfung", - "afterInstallation": "Nach der Installation", + "afterInstallation": "Erste Schritte nach der Installation", "afterInstallationDescription": "Setze Deinen Linux-Rechner nach Deinen Bedürfnissen auf.", "openX": "Öffne", "searchInWebFor": "Suche im Internet nach", @@ -357,6 +357,7 @@ "grubCountdown": "Zeit bis zum automatischen Start (in Sekunden)", "startLastBootedEntry": "Starte den zuletzt gebooteten Eintrag", "save": "Speichern", + "distribution_selection": "Distributions-Auswahl", "@helloWorld": { "placeholders": {}, "description": "", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 3dda6e6..e3dd5b0 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -6,7 +6,7 @@ "securityCheckDescription": "Keep the security of your computer in track.", "warpinatorDescription": "Send files quickly over the local network. To Linux, Android, iOS and Windows.", "securityCheck": "Security Check", - "afterInstallation": "After Installation", + "afterInstallation": "First steps after installation", "afterInstallationDescription": "Set up your linux machine to your needs.", "openX": "Open", "searchInWebFor": "Search in web for", @@ -357,6 +357,7 @@ "grubCountdown": "Time until automatic start (in seconds)", "startLastBootedEntry": "Start the last booted entry", "save": "Save", + "distribution_selection": "Distribution selection", "@helloWorld": { "placeholders": {}, "description": "The conventional newborn programmer greeting", diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index 51f3476..717ad5e 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -337,6 +337,7 @@ "automaticCleanupDescription": "Pulisci automaticamente il tuo spazio di archiviazione eliminando file temporanei e cache dei pacchetti. Verranno svuotati anche i contenitori del cestino.", "diskUsage": "Utilizzo del disco", "settingUpFirewall": "Configura firewall...", + "distribution_selection": "Selezione della distribuzione", "@helloWorld": { "placeholders": {}, "description": "Il saluto convenzionale del programmatore appena nato", diff --git a/lib/layouts/greeter/activate_hotkey.dart b/lib/layouts/after_installation/activate_hotkey.dart similarity index 100% rename from lib/layouts/greeter/activate_hotkey.dart rename to lib/layouts/after_installation/activate_hotkey.dart diff --git a/lib/layouts/after_installation/communication_software.dart b/lib/layouts/after_installation/communication_software.dart index 642f9f7..8652655 100644 --- a/lib/layouts/after_installation/communication_software.dart +++ b/lib/layouts/after_installation/communication_software.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:linux_assistant/layouts/after_installation/activate_hotkey.dart'; import 'package:linux_assistant/layouts/after_installation/automatic_configuration_entry.dart'; import 'package:linux_assistant/layouts/mint_y.dart'; import 'package:linux_assistant/widgets/system_icon.dart'; @@ -284,7 +285,9 @@ class AfterInstallationCommunicationSoftwareSelection extends StatelessWidget { ], ), bottom: MintYButtonNext( - route: const AfterInstallationAutomaticConfigurationEntry(), + route: ActivateHotkeyQuestion( + route: const AfterInstallationAutomaticConfigurationEntry(), + ), onPressedFuture: () async { await AfterInstallationService.applyCommunicationSituation(); }, diff --git a/lib/layouts/greeter/environment_selection.dart b/lib/layouts/greeter/environment_selection.dart deleted file mode 100644 index 82e3f4f..0000000 --- a/lib/layouts/greeter/environment_selection.dart +++ /dev/null @@ -1,291 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:linux_assistant/enums/desktops.dart'; -import 'package:linux_assistant/enums/distros.dart'; -import 'package:linux_assistant/layouts/greeter/activate_hotkey.dart'; -import 'package:linux_assistant/layouts/greeter/is_environment_correct.dart'; -import 'package:linux_assistant/layouts/mint_y.dart'; -import 'package:linux_assistant/models/environment.dart'; -import 'package:linux_assistant/services/config_handler.dart'; -import 'package:linux_assistant/services/linux.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -class EnvironmentSelectionView extends StatefulWidget { - const EnvironmentSelectionView({Key? key}) : super(key: key); - - @override - State createState() => - _EnvironmentSelectionViewState(); -} - -class _EnvironmentSelectionViewState extends State { - Environment environment = Linux.currentenvironment; - Environment oldEnvironment = Linux.currentenvironment; - ConfigHandler configHandler = ConfigHandler(); - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "${AppLocalizations.of(context)!.distribution}: ", - style: Theme.of(context).textTheme.displayLarge, - ), - const SizedBox( - width: 16, - ), - MintYButton( - text: Text( - getNiceStringOfDistrosEnum(environment.distribution), - style: MintY.heading2, - ), - onPressed: () { - showDialog( - context: context, - builder: (BuildContext context) => - _openDistributionSelection(context), - ); - }, - ) - ], - ), - const SizedBox( - height: 32, - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.center, - // children: [ - // Text( - // "${AppLocalizations.of(context)!.version}: ", - // style: Theme.of(context).textTheme.displayLarge, - // ), - // SizedBox( - // width: 16, - // ), - // Container( - // width: 150, - // child: TextField( - // decoration: InputDecoration( - // border: OutlineInputBorder(), - // hintText: environment.version.toString(), - // hintStyle: TextStyle(fontSize: 24), - // ), - // autofocus: true, - // style: TextStyle(fontSize: 24), - // onChanged: (value) { - // if (value.isNotEmpty) { - // if (double.tryParse(value) != null) { - // environment.version = double.parse(value); - // configHandler.setValue("version", environment.version); - // } - // } else { - // environment.version = oldEnvironment.version; - // } - // }, - // ), - // ) - // ], - // ), - // SizedBox( - // height: 32, - // ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "${AppLocalizations.of(context)!.desktop}: ", - style: MintY.heading1, - ), - const SizedBox( - width: 16, - ), - MintYButton( - text: Text( - getNiceStringOfDesktopsEnum(environment.desktop), - style: Theme.of(context).textTheme.headlineLarge, - ), - onPressed: () { - showDialog( - context: context, - builder: (BuildContext context) => - _openDesktopSelection(context), - ); - }, - ) - ], - ), - const SizedBox( - height: 32, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "${AppLocalizations.of(context)!.language}: ", - style: MintY.heading1, - ), - const SizedBox( - width: 16, - ), - SizedBox( - width: 150, - child: TextField( - decoration: InputDecoration( - border: const OutlineInputBorder(), - hintText: environment.language, - hintStyle: const TextStyle(fontSize: 24), - ), - autofocus: true, - style: const TextStyle(fontSize: 24), - onChanged: (value) { - if (value.isNotEmpty) { - environment.language = value; - } else { - environment.version = oldEnvironment.version; - } - }, - ), - ) - ], - ), - const SizedBox( - height: 32, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MintYButton( - text: Text( - AppLocalizations.of(context)!.cancel, - style: MintY.heading2, - ), - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - const IsYourEnvironmentCorrectView()), - ); - }, - ), - const SizedBox( - width: 32, - ), - MintYButton( - text: Text( - AppLocalizations.of(context)!.next, - style: MintY.heading4White, - ), - color: Colors.blue, - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => ActivateHotkeyQuestion()), - ); - }, - ), - ], - ) - ], - )), - ); - } - - Widget _openDistributionSelection(context) { - return Dialog( - child: Padding( - padding: const EdgeInsets.all(32.0), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text( - "${AppLocalizations.of(context)!.selectYourDistribution}:", - style: Theme.of(context).textTheme.displayLarge, - ), - const SizedBox( - height: 32, - ), - Expanded( - child: Container( - child: ListView.builder( - // primary: true, - itemCount: DISTROS.values.length, - itemBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: MintYButton( - text: Text( - getNiceStringOfDistrosEnum(DISTROS.values[index]), - style: MintY.heading2), - onPressed: (() { - setState(() { - environment.distribution = DISTROS.values[index]; - configHandler.setValue("distribution", - environment.distribution.name); - Navigator.of(context).pop(); - }); - }), - ), - ); - }, - ), - ), - ), - ]), - ), - ); - } - - Widget _openDesktopSelection(context) { - return Dialog( - child: Padding( - padding: const EdgeInsets.all(32.0), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text( - "${AppLocalizations.of(context)!.selectYourDesktop}:", - style: Theme.of(context).textTheme.displayLarge, - ), - const SizedBox( - height: 32, - ), - Expanded( - child: Container( - child: ListView.builder( - // primary: true, - itemCount: DESKTOPS.values.length, - itemBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: MintYButton( - text: Text( - getNiceStringOfDesktopsEnum( - DESKTOPS.values[index]), - style: MintY.heading2), - onPressed: (() { - setState(() { - environment.desktop = DESKTOPS.values[index]; - configHandler.setValue( - "desktop", environment.desktop); - Navigator.of(context).pop(); - }); - }), - ), - ); - }, - ), - ), - ), - ]), - ), - ); - } -} diff --git a/lib/layouts/greeter/is_environment_correct.dart b/lib/layouts/greeter/is_environment_correct.dart deleted file mode 100644 index 21f7b5a..0000000 --- a/lib/layouts/greeter/is_environment_correct.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:linux_assistant/enums/desktops.dart'; -import 'package:linux_assistant/enums/distros.dart'; -import 'package:linux_assistant/layouts/greeter/activate_hotkey.dart'; -import 'package:linux_assistant/layouts/greeter/environment_selection.dart'; -import 'package:linux_assistant/layouts/mint_y.dart'; -import 'package:linux_assistant/services/linux.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -class IsYourEnvironmentCorrectView extends StatelessWidget { - const IsYourEnvironmentCorrectView({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return MintYPage( - contentElements: [ - Text( - AppLocalizations.of(context)!.isTheRecognizedSystemCorrect, - style: Theme.of(context).textTheme.displayLarge, - textAlign: TextAlign.center, - ), - const SizedBox( - height: 16, - ), - Text( - "${AppLocalizations.of(context)!.distribution}: ${getNiceStringOfDistrosEnum(Linux.currentenvironment.distribution)} \n${AppLocalizations.of(context)!.desktop}: ${getNiceStringOfDesktopsEnum(Linux.currentenvironment.desktop)}\n${AppLocalizations.of(context)!.language}: ${Linux.currentenvironment.language}", - style: Theme.of(context).textTheme.headlineMedium, - textAlign: TextAlign.center, - ), - ], - bottom: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MintYButtonNavigate( - text: Text( - AppLocalizations.of(context)!.noIWantToChange, - style: MintY.heading4, - ), - route: const EnvironmentSelectionView(), - ), - const SizedBox( - width: 10, - ), - MintYButtonNavigate( - text: Text( - AppLocalizations.of(context)!.yes, - style: MintY.heading4White, - ), - color: MintY.currentColor, - route: ActivateHotkeyQuestion(), - ), - ], - ), - ); - } -} diff --git a/lib/layouts/greeter/start_screen.dart b/lib/layouts/greeter/start_screen.dart index bf71d63..4daf064 100644 --- a/lib/layouts/greeter/start_screen.dart +++ b/lib/layouts/greeter/start_screen.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:linux_assistant/layouts/greeter/introduction.dart'; -import 'package:linux_assistant/layouts/greeter/is_environment_correct.dart'; import 'package:linux_assistant/layouts/mint_y.dart'; import 'package:linux_assistant/services/config_handler.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -57,7 +56,7 @@ class StartScreen extends StatelessWidget { overflow: TextOverflow.visible, ), ), - MintYButtonNext(route: const IsYourEnvironmentCorrectView()) + MintYButtonNext(route: const GreeterIntroduction()) ], ), ), diff --git a/lib/layouts/main_screen/recommendation_card.dart b/lib/layouts/main_screen/recommendation_card.dart index 55a27a0..b59f505 100644 --- a/lib/layouts/main_screen/recommendation_card.dart +++ b/lib/layouts/main_screen/recommendation_card.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:linux_assistant/content/recommendations.dart'; import 'package:linux_assistant/models/action_entry.dart'; import 'package:linux_assistant/services/action_handler.dart'; +import 'package:linux_assistant/services/config_handler.dart'; class RecommendationCard extends StatelessWidget { const RecommendationCard({Key? key}) : super(key: key); @@ -11,6 +12,18 @@ class RecommendationCard extends StatelessWidget { Widget build(BuildContext context) { int rand = Random().nextInt(getRecommendations(context).length); ActionEntry entry = getRecommendations(context)[rand]; + + // Ensure to display the after installation recommendation 5 times directly after installation of the app + int displayedAfterInstallationRecommendation = ConfigHandler() + .getValueUnsafe("displayedAfterInstallationRecommendation", 0); + if (displayedAfterInstallationRecommendation < 5) { + entry = getRecommendations(context) + .firstWhere((element) => element.action == "after_installation"); + displayedAfterInstallationRecommendation++; + ConfigHandler().setValue("displayedAfterInstallationRecommendation", + displayedAfterInstallationRecommendation); + } + return Card( child: InkWell( onTap: () { diff --git a/lib/layouts/settings/environment_selection.dart b/lib/layouts/settings/environment_selection.dart new file mode 100644 index 0000000..721d853 --- /dev/null +++ b/lib/layouts/settings/environment_selection.dart @@ -0,0 +1,219 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:linux_assistant/enums/desktops.dart'; +import 'package:linux_assistant/enums/distros.dart'; +import 'package:linux_assistant/layouts/mint_y.dart'; +import 'package:linux_assistant/models/environment.dart'; +import 'package:linux_assistant/services/config_handler.dart'; +import 'package:linux_assistant/services/linux.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class EnvironmentSelectionView extends StatefulWidget { + const EnvironmentSelectionView({Key? key}) : super(key: key); + + @override + State createState() => + _EnvironmentSelectionViewState(); +} + +class _EnvironmentSelectionViewState extends State { + Environment environment = Linux.currentenvironment; + Environment oldEnvironment = Linux.currentenvironment; + ConfigHandler configHandler = ConfigHandler(); + @override + Widget build(BuildContext context) { + return SizedBox( + width: min(600, MediaQuery.of(context).size.width - 100), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "${AppLocalizations.of(context)!.distribution}: ", + style: Theme.of(context).textTheme.bodyLarge, + ), + const SizedBox( + width: 16, + ), + MintYButton( + text: Text( + getNiceStringOfDistrosEnum(environment.distribution), + style: MintY.heading4White, + ), + color: MintY.currentColor, + width: 150, + onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) => + _openDistributionSelection(context), + ); + }, + ) + ], + ), + const SizedBox( + height: 32, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "${AppLocalizations.of(context)!.desktop}: ", + style: Theme.of(context).textTheme.bodyLarge, + ), + const SizedBox( + width: 16, + ), + MintYButton( + text: Text( + getNiceStringOfDesktopsEnum(environment.desktop), + style: MintY.heading4White, + ), + color: MintY.currentColor, + width: 150, + onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) => + _openDesktopSelection(context), + ); + }, + ) + ], + ), + const SizedBox( + height: 32, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "${AppLocalizations.of(context)!.language}: ", + style: Theme.of(context).textTheme.bodyLarge, + ), + const SizedBox( + width: 16, + ), + SizedBox( + width: 150, + child: TextField( + decoration: InputDecoration( + border: const OutlineInputBorder(), + hintText: environment.language, + ), + style: Theme.of(context).textTheme.bodyLarge, + autofocus: true, + onChanged: (value) { + if (value.isNotEmpty) { + environment.language = value; + } else { + environment.version = oldEnvironment.version; + } + }, + ), + ) + ], + ), + const SizedBox( + height: 32, + ), + ], + ), + ); + } + + Widget _openDistributionSelection(context) { + var distros = DISTROS.values.toList(); + // Sort the distros by their name + distros.sort((a, b) => a.name.compareTo(b.name)); + return Dialog( + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Column(mainAxisSize: MainAxisSize.max, children: [ + Text( + "${AppLocalizations.of(context)!.selectYourDistribution}:", + style: Theme.of(context).textTheme.headlineLarge, + ), + const SizedBox( + height: 32, + ), + Expanded( + child: ListView.builder( + // primary: true, + itemCount: distros.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: MintYButton( + text: Text( + getNiceStringOfDistrosEnum(distros[index]), + style: MintY.heading4White, + ), + color: MintY.currentColor, + onPressed: (() { + setState(() { + environment.distribution = distros[index]; + configHandler.setValue( + "distribution", environment.distribution.name); + Navigator.of(context).pop(); + }); + }), + ), + ); + }, + ), + ), + ]), + ), + ); + } + + Widget _openDesktopSelection(context) { + return Dialog( + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Column(mainAxisSize: MainAxisSize.max, children: [ + Text( + "${AppLocalizations.of(context)!.selectYourDesktop}:", + style: Theme.of(context).textTheme.headlineLarge, + ), + const SizedBox( + height: 32, + ), + Expanded( + child: Container( + child: ListView.builder( + // primary: true, + itemCount: DESKTOPS.values.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: MintYButton( + text: Text( + getNiceStringOfDesktopsEnum(DESKTOPS.values[index]), + style: MintY.heading4White, + ), + color: MintY.currentColor, + onPressed: (() { + setState(() { + environment.desktop = DESKTOPS.values[index]; + configHandler.setValue( + "desktop", environment.desktop); + Navigator.of(context).pop(); + }); + }), + ), + ); + }, + ), + ), + ), + ]), + ), + ); + } +} diff --git a/lib/layouts/settings/settings_start.dart b/lib/layouts/settings/settings_start.dart index 9ad0e23..5bca35f 100644 --- a/lib/layouts/settings/settings_start.dart +++ b/lib/layouts/settings/settings_start.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:linux_assistant/layouts/mint_y.dart'; import 'package:linux_assistant/layouts/settings/appearance_settings.dart'; +import 'package:linux_assistant/layouts/settings/environment_selection.dart'; import 'package:linux_assistant/layouts/settings/search_settings.dart'; import 'package:linux_assistant/services/main_search_loader.dart'; @@ -32,6 +33,10 @@ class _SettingsStartState extends State { content = AppearanceSettings(); heading = AppLocalizations.of(context)!.appearance_settings; break; + case "distribution_selection": + content = const EnvironmentSelectionView(); + heading = AppLocalizations.of(context)!.distribution_selection; + break; } return Dialog( child: Padding( @@ -90,6 +95,19 @@ class _SettingsStartState extends State { } Widget startContent(context) => MintYGrid(children: [ + MintYSelectableEntryWithIconHorizontal( + title: AppLocalizations.of(context)!.distribution_selection, + text: "", + icon: Icon( + Icons.screen_search_desktop_outlined, + size: 64, + color: MintY.currentColor, + ), + onPressed: () { + setState(() { + state = "distribution_selection"; + }); + }), MintYSelectableEntryWithIconHorizontal( title: AppLocalizations.of(context)!.searchSettings, text: "", @@ -115,6 +133,6 @@ class _SettingsStartState extends State { setState(() { state = "appearance_settings"; }); - }) + }), ]); } diff --git a/lib/services/action_handler.dart b/lib/services/action_handler.dart index b828ecc..d3d19ba 100644 --- a/lib/services/action_handler.dart +++ b/lib/services/action_handler.dart @@ -6,7 +6,7 @@ import 'package:linux_assistant/enums/desktops.dart'; import 'package:linux_assistant/enums/softwareManagers.dart'; import 'package:linux_assistant/layouts/after_installation/after_installation_entry.dart'; import 'package:linux_assistant/layouts/disk_cleaner/cleaner_select_disk.dart'; -import 'package:linux_assistant/layouts/greeter/activate_hotkey.dart'; +import 'package:linux_assistant/layouts/after_installation/activate_hotkey.dart'; import 'package:linux_assistant/layouts/greeter/introduction.dart'; import 'package:linux_assistant/layouts/linux_health/overview.dart'; import 'package:linux_assistant/layouts/power_mode/power_mode.dart';