Browse Source

Add debug info button (#189)

* Add debug info button

* Get rid of extra line

* Upgrade to device_info_plus 3.2.0 & format debug info

* Remove unused import

* Use locale translation mechanism
Poly-Pixel 3 years ago
parent
commit
bc645af3e2

+ 6 - 1
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",

+ 6 - 1
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",

+ 6 - 1
frontend/app_flowy/assets/translations/zh_CN.json

@@ -65,7 +65,12 @@
   "dialogCreatePageNameHint": "页面名称",
   "questionBubble": {
     "whatsNew": "新功能?",
-    "help": "帮助 & 支持"
+    "help": "帮助 & 支持",
+    "debug": {
+      "name": "调试信息",
+      "success": "将调试信息复制到剪贴板!",
+      "fail": "无法将调试信息复制到剪贴板"
+    }
   },
   "menuAppHeader": {
     "addPageTooltip": "在其中快速添加页面",

+ 142 - 5
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<String,dynamic> en = {
-  "appName": "Appflowy",
+  static const Map<String,dynamic> 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<String,dynamic> 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<String,dynamic> zh_CN = {
   "dialogCreatePageNameHint": "页面名称",
   "questionBubble": {
     "whatsNew": "新功能?",
-    "help": "帮助 & 支持"
+    "help": "帮助 & 支持",
+    "debug": {
+      "name": "调试信息",
+      "success": "将调试信息复制到剪贴板!",
+      "fail": "无法将调试信息复制到剪贴板"
+    }
   },
   "menuAppHeader": {
     "addPageTooltip": "在其中快速添加页面",
@@ -258,5 +395,5 @@ static const Map<String,dynamic> zh_CN = {
     }
   }
 };
-static const Map<String, Map<String,dynamic>> mapLocales = {"en": en, "zh_CN": zh_CN};
+static const Map<String, Map<String,dynamic>> mapLocales = {"it_IT": it_IT, "en": en, "zh_CN": zh_CN};
 }

+ 4 - 0
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';

+ 11 - 0
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<FadingIndexedStack> {
   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;

+ 73 - 0
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));
     }
   }
 }

+ 2 - 0
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"))

+ 49 - 0
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:

+ 2 - 0
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