diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json index 2285416727..b0741e8859 100644 --- a/frontend/app_flowy/assets/translations/en.json +++ b/frontend/app_flowy/assets/translations/en.json @@ -65,7 +65,12 @@ "dialogCreatePageNameHint": "Page name", "questionBubble": { "whatsNew": "What's new?", - "help": "Help & Support" + "help": "Help & Support", + "debug": { + "name": "Debug Info", + "success": "Copied debug info to clipboard!", + "fail": "Unable to copy debug info to clipboard" + } }, "menuAppHeader": { "addPageTooltip": "Quickly add a page inside", diff --git a/frontend/app_flowy/assets/translations/it_IT.json b/frontend/app_flowy/assets/translations/it_IT.json index feb4190f58..067b0f06b5 100644 --- a/frontend/app_flowy/assets/translations/it_IT.json +++ b/frontend/app_flowy/assets/translations/it_IT.json @@ -65,7 +65,12 @@ "dialogCreatePageNameHint": "Nome pagina", "questionBubble": { "whatsNew": "Cosa c'è di nuovo?", - "help": "Aiuto & Supporto" + "help": "Aiuto & Supporto", + "debug": { + "name": "Informazioni di debug", + "success": "Informazioni di debug copiate negli appunti!", + "fail": "Impossibile copiare le informazioni di debug negli appunti" + } }, "menuAppHeader": { "addPageTooltip": "Aggiungi velocemente una pagina all'interno", diff --git a/frontend/app_flowy/assets/translations/zh_CN.json b/frontend/app_flowy/assets/translations/zh_CN.json index 86d6710314..8fc58a0d14 100644 --- a/frontend/app_flowy/assets/translations/zh_CN.json +++ b/frontend/app_flowy/assets/translations/zh_CN.json @@ -65,7 +65,12 @@ "dialogCreatePageNameHint": "页面名称", "questionBubble": { "whatsNew": "新功能?", - "help": "帮助 & 支持" + "help": "帮助 & 支持", + "debug": { + "name": "调试信息", + "success": "将调试信息复制到剪贴板!", + "fail": "无法将调试信息复制到剪贴板" + } }, "menuAppHeader": { "addPageTooltip": "在其中快速添加页面", diff --git a/frontend/app_flowy/lib/generated/codegen_loader.g.dart b/frontend/app_flowy/lib/generated/codegen_loader.g.dart index 8637cff2ea..ae47302061 100644 --- a/frontend/app_flowy/lib/generated/codegen_loader.g.dart +++ b/frontend/app_flowy/lib/generated/codegen_loader.g.dart @@ -14,8 +14,135 @@ class CodegenLoader extends AssetLoader{ return Future.value(mapLocales[locale.toString()]); } - static const Map en = { - "appName": "Appflowy", + static const Map it_IT = { + "appName": "AppFlowy", + "defaultUsername": "Me", + "welcomeText": "Benvenuto in @:appName", + "githubStarText": "Vota su GitHub", + "subscribeNewsletterText": "Sottoscrivi la Newsletter", + "letsGoButtonText": "Andiamo", + "title": "Titolo", + "signUp": { + "buttonText": "Registrati", + "title": "Registrati per @:appName", + "getStartedText": "Iniziamo", + "emptyPasswordError": "La password non può essere vuota", + "repeatPasswordEmptyError": "La password ripetuta non può essere vuota", + "unmatchedPasswordError": "La password ripetuta non è uguale alla password", + "alreadyHaveAnAccount": "Hai già un account?", + "emailHint": "Email", + "passwordHint": "Password", + "repeatPasswordHint": "Ripeti password" + }, + "signIn": { + "loginTitle": "Accedi a @:appName", + "loginButtonText": "Login", + "buttonText": "Accedi", + "forgotPassword": "Password Dimentica?", + "emailHint": "Email", + "passwordHint": "Password", + "dontHaveAnAccount": "Non hai un account?", + "repeatPasswordEmptyError": "La password ripetuta non può essere vuota", + "unmatchedPasswordError": "La password ripetuta non è uguale alla password" + }, + "workspace": { + "create": "Crea spazio di lavoro", + "hint": "spazio di lavoro", + "notFoundError": "Spazio di lavoro non trovato" + }, + "shareAction": { + "buttonText": "Condividi", + "workInProgress": "In corso", + "markdown": "Markdown", + "copyLink": "Copia Link" + }, + "disclosureAction": { + "rename": "Rinomina", + "delete": "Cancella", + "duplicate": "Duplica" + }, + "blankPageTitle": "Pagina vuota", + "newPageText": "Nuova pagina", + "trash": { + "text": "Cestino", + "restoreAll": "Ripristina Tutto", + "deleteAll": "Elimina Tutto", + "pageHeader": { + "fileName": "Nome file", + "lastModified": "Ultima Modifica", + "created": "Creato" + } + }, + "deletePagePrompt": { + "text": "Questa pagina è nel Cestino", + "restore": "Ripristina pagina", + "deletePermanent": "Elimina definitivamente" + }, + "dialogCreatePageNameHint": "Nome pagina", + "questionBubble": { + "whatsNew": "Cosa c'è di nuovo?", + "help": "Aiuto & Supporto", + "debug": { + "name": "Informazioni di debug", + "success": "Informazioni di debug copiate negli appunti!", + "fail": "Impossibile copiare le informazioni di debug negli appunti" + } + }, + "menuAppHeader": { + "addPageTooltip": "Aggiungi velocemente una pagina all'interno", + "defaultNewPageName": "Senza titolo", + "renameDialog": "Rinomina" + }, + "toolbar": { + "undo": "Undo", + "redo": "Redo", + "bold": "Grassetto", + "italic": "Italico", + "underline": "Sottolineato", + "strike": "Barrato", + "numList": "Lista numerata", + "bulletList": "Lista a punti", + "checkList": "Lista Controllo", + "inlineCode": "Codice in linea", + "quote": "Cita Blocco" + }, + "contactsPage": { + "title": "Contatti", + "whatsHappening": "Cosa accadrà la prossima settimana?", + "addContact": "Aggiungi Contatti", + "editContact": "Modifica Contatti" + }, + "button": { + "OK": "OK", + "Cancel": "Annulla", + "signIn": "Accedi", + "signOut": "Esci", + "complete": "Completa", + "save": "Salva" + }, + "label": { + "welcome": "Benvenuto!", + "firstName": "Name", + "middleName": "Secondo Name", + "lastName": "Cognome", + "stepX": "Passo {X}" + }, + "oAuth": { + "err": { + "failedTitle": "Impossibile collegarsi al tuo account.", + "failedMsg": "Si prega di verificare di aver completato il processo di iscrizione nel tuo browser." + }, + "google": { + "title": "GOOGLE SIGN-IN", + "instruction1": "Al fine di importare i tuoi Contatti Google è necessario autorizzare questa applicaizone ad utilizzare il tuo beowser web.", + "instruction2": "Copia questo codice nella tua clipboard premendo l'icona o selezionando il testo:", + "instruction3": "Naviga sul seguente link con il tuo browser web e inserisci il codice seguente:", + "instruction4": "Premi il bottono qui sotto quando hai completato l'iscrizione:" + } + } +}; +static const Map en = { + "appName": "AppFlowy", "defaultUsername": "Me", "welcomeText": "Welcome to @:appName", "githubStarText": "Star on GitHub", @@ -81,7 +208,12 @@ class CodegenLoader extends AssetLoader{ "dialogCreatePageNameHint": "Page name", "questionBubble": { "whatsNew": "What's new?", - "help": "Help & Support" + "help": "Help & Support", + "debug": { + "name": "Debug Info", + "success": "Copied debug info to clipboard!", + "fail": "Unable to copy debug info to clipboard" + } }, "menuAppHeader": { "addPageTooltip": "Quickly add a page inside", @@ -203,7 +335,12 @@ static const Map zh_CN = { "dialogCreatePageNameHint": "页面名称", "questionBubble": { "whatsNew": "新功能?", - "help": "帮助 & 支持" + "help": "帮助 & 支持", + "debug": { + "name": "调试信息", + "success": "将调试信息复制到剪贴板!", + "fail": "无法将调试信息复制到剪贴板" + } }, "menuAppHeader": { "addPageTooltip": "在其中快速添加页面", @@ -258,5 +395,5 @@ static const Map zh_CN = { } } }; -static const Map> mapLocales = {"en": en, "zh_CN": zh_CN}; +static const Map> mapLocales = {"it_IT": it_IT, "en": en, "zh_CN": zh_CN}; } diff --git a/frontend/app_flowy/lib/generated/locale_keys.g.dart b/frontend/app_flowy/lib/generated/locale_keys.g.dart index 28888ad277..958e9b0e9e 100644 --- a/frontend/app_flowy/lib/generated/locale_keys.g.dart +++ b/frontend/app_flowy/lib/generated/locale_keys.g.dart @@ -59,6 +59,10 @@ abstract class LocaleKeys { static const dialogCreatePageNameHint = 'dialogCreatePageNameHint'; static const questionBubble_whatsNew = 'questionBubble.whatsNew'; static const questionBubble_help = 'questionBubble.help'; + static const questionBubble_debug_name = 'questionBubble.debug.name'; + static const questionBubble_debug_success = 'questionBubble.debug.success'; + static const questionBubble_debug_fail = 'questionBubble.debug.fail'; + static const questionBubble_debug = 'questionBubble.debug'; static const questionBubble = 'questionBubble'; static const menuAppHeader_addPageTooltip = 'menuAppHeader.addPageTooltip'; static const menuAppHeader_defaultNewPageName = 'menuAppHeader.defaultNewPageName'; diff --git a/frontend/app_flowy/lib/workspace/presentation/stack_page/home_stack.dart b/frontend/app_flowy/lib/workspace/presentation/stack_page/home_stack.dart index 8ee7d3d6d8..c83445dc12 100644 --- a/frontend/app_flowy/lib/workspace/presentation/stack_page/home_stack.dart +++ b/frontend/app_flowy/lib/workspace/presentation/stack_page/home_stack.dart @@ -1,8 +1,12 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart'; +import 'package:app_flowy/workspace/presentation/home/home_screen.dart'; import 'package:flowy_log/flowy_log.dart'; import 'package:flutter/material.dart'; import 'package:time/time.dart'; +import 'package:fluttertoast/fluttertoast.dart'; + +late FToast fToast; // [[diagram: HomeStack's widget structure]] // @@ -61,6 +65,13 @@ class FadingIndexedStack extends StatefulWidget { class _FadingIndexedStackState extends State { double _targetOpacity = 1; + @override + void initState() { + super.initState(); + fToast = FToast(); + fToast.init(HomeScreen.scaffoldKey.currentState!.context); + } + @override void didUpdateWidget(FadingIndexedStack oldWidget) { if (oldWidget.index == widget.index) return; diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart index a2e1012583..62e10be3b6 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart @@ -5,13 +5,18 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_log/flowy_log.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:dartz/dartz.dart' as dartz; import 'package:styled_widget/styled_widget.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:app_flowy/generated/locale_keys.g.dart'; +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart'; class QuestionBubble extends StatelessWidget { const QuestionBubble({Key? key}) : super(key: key); @@ -40,6 +45,69 @@ class QuestionBubble extends StatelessWidget { case BubbleAction.help: _launchURL("https://discord.gg/9Q2xaN37tV"); break; + case BubbleAction.debug: + final deviceInfoPlugin = DeviceInfoPlugin(); + final deviceInfo = deviceInfoPlugin.deviceInfo; + + deviceInfo.then((info) { + var debugText = ""; + info.toMap().forEach((key, value) { + debugText = debugText + "$key: $value\n"; + }); + + Clipboard.setData(ClipboardData( text: debugText )); + + Widget toast = Container( + padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25.0), + color: theme.main1, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.check), + const SizedBox( + width: 12.0, + ), + Text(LocaleKeys.questionBubble_debug_success.tr()), + ], + ), + ); + + fToast.showToast( + child: toast, + gravity: ToastGravity.BOTTOM, + toastDuration: const Duration(seconds: 3), + ); + }).catchError((error) { + Log.info("Debug info has not yet been implemented on this platform"); + + Widget toast = Container( + padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25.0), + color: Colors.red, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.close), + const SizedBox( + width: 12.0, + ), + Text(LocaleKeys.questionBubble_debug_fail.tr()), + ], + ), + ); + + fToast.showToast( + child: toast, + gravity: ToastGravity.BOTTOM, + toastDuration: const Duration(seconds: 3), + ); + }, test: (e) => e is UnimplementedError); + break; } }); }); @@ -148,6 +216,7 @@ class FlowyVersionDescription extends StatelessWidget { enum BubbleAction { whatsNews, help, + debug } class BubbleActionWrapper extends ActionItem { @@ -168,6 +237,8 @@ extension QuestionBubbleExtension on BubbleAction { return LocaleKeys.questionBubble_whatsNew.tr(); case BubbleAction.help: return LocaleKeys.questionBubble_help.tr(); + case BubbleAction.debug: + return LocaleKeys.questionBubble_debug_name.tr(); } } @@ -177,6 +248,8 @@ extension QuestionBubbleExtension on BubbleAction { return const Text('⭐️', style: TextStyle(fontSize: 12)); case BubbleAction.help: return const Text('👥', style: TextStyle(fontSize: 12)); + case BubbleAction.debug: + return const Text('🐛', style: TextStyle(fontSize: 12)); } } } diff --git a/frontend/app_flowy/macos/Flutter/GeneratedPluginRegistrant.swift b/frontend/app_flowy/macos/Flutter/GeneratedPluginRegistrant.swift index fcef838641..8d97942332 100644 --- a/frontend/app_flowy/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/frontend/app_flowy/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,7 @@ import FlutterMacOS import Foundation import connectivity_plus_macos +import device_info_plus_macos import flowy_infra_ui import flowy_sdk import package_info_plus_macos @@ -16,6 +17,7 @@ import window_size func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FlowyInfraUIPlugin.register(with: registry.registrar(forPlugin: "FlowyInfraUIPlugin")) FlowySdkPlugin.register(with: registry.registrar(forPlugin: "FlowySdkPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) diff --git a/frontend/app_flowy/pubspec.lock b/frontend/app_flowy/pubspec.lock index 11622827be..e8ff993053 100644 --- a/frontend/app_flowy/pubspec.lock +++ b/frontend/app_flowy/pubspec.lock @@ -260,6 +260,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.6" + device_info_plus: + dependency: "direct main" + description: + name: device_info_plus + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" + device_info_plus_linux: + dependency: transitive + description: + name: device_info_plus_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + device_info_plus_macos: + dependency: transitive + description: + name: device_info_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + device_info_plus_web: + dependency: transitive + description: + name: device_info_plus_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + device_info_plus_windows: + dependency: transitive + description: + name: device_info_plus_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" diff_match_patch: dependency: transitive description: @@ -457,6 +499,13 @@ packages: description: flutter source: sdk version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + url: "https://pub.dartlang.org" + source: hosted + version: "8.0.8" freezed: dependency: "direct dev" description: diff --git a/frontend/app_flowy/pubspec.yaml b/frontend/app_flowy/pubspec.yaml index 8ad85a6066..99c6b90b41 100644 --- a/frontend/app_flowy/pubspec.yaml +++ b/frontend/app_flowy/pubspec.yaml @@ -73,6 +73,8 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + device_info_plus: ^3.2.0 + fluttertoast: ^8.0.8 dev_dependencies: flutter_lints: ^1.0.0