From 8b4fa886baaf83ff3170bc003711f59ad219d182 Mon Sep 17 00:00:00 2001
From: Vishesh Handa <me@vhanda.in>
Date: Tue, 26 May 2020 13:14:33 +0200
Subject: [PATCH] Add a CustomRouteObserver

This basically asserts if we move to a route without a name. This way
I'll always catch when a route doesn't have a name, and I can start
getting better analytics on which screens are used most frequently.
---
 lib/analytics.dart               | 40 ++++++++++++++++++++++++++++++++
 lib/app.dart                     |  5 +++-
 lib/folder_views/common.dart     |  1 +
 lib/screens/folder_listing.dart  |  1 +
 lib/screens/folder_view.dart     |  4 ++++
 lib/screens/note_editor.dart     |  1 +
 lib/screens/settings_screen.dart |  5 ++++
 lib/screens/tag_listing.dart     | 21 ++++++++++-------
 8 files changed, 68 insertions(+), 10 deletions(-)

diff --git a/lib/analytics.dart b/lib/analytics.dart
index 622186c9..c21d17d1 100644
--- a/lib/analytics.dart
+++ b/lib/analytics.dart
@@ -1,4 +1,6 @@
 import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 
 import 'package:gitjournal/app.dart';
 import 'package:gitjournal/error_reporting.dart';
@@ -85,3 +87,41 @@ void logEvent(Event event, {Map<String, String> parameters}) {
   getAnalytics().log(e: event, parameters: parameters);
   Log.d("Event $event");
 }
+
+class CustomRouteObserver extends RouteObserver<PageRoute<dynamic>> {
+  void _sendScreenView(PageRoute<dynamic> route) {
+    final String screenName = route.settings.name;
+    assert(screenName != null, "Screen name is null $route");
+  }
+
+  @override
+  void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
+    super.didPush(route, previousRoute);
+    if (route is PageRoute) {
+      _sendScreenView(route);
+    } else {
+      print("route in not a PageRoute! $route");
+    }
+  }
+
+  @override
+  void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
+    super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
+    if (newRoute is PageRoute) {
+      _sendScreenView(newRoute);
+    } else {
+      print("newRoute in not a PageRoute! $newRoute");
+    }
+  }
+
+  @override
+  void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
+    super.didPop(route, previousRoute);
+    if (previousRoute is PageRoute && route is PageRoute) {
+      _sendScreenView(previousRoute);
+    } else {
+      print("previousRoute in not a PageRoute! $previousRoute");
+      print("route in not a PageRoute! $route");
+    }
+  }
+}
diff --git a/lib/app.dart b/lib/app.dart
index 7afe5bd8..b1d2ed9b 100644
--- a/lib/app.dart
+++ b/lib/app.dart
@@ -288,7 +288,10 @@ class _JournalAppState extends State<JournalApp> {
       locale: EasyLocalization.of(context).locale,
 
       theme: themeData,
-      navigatorObservers: <NavigatorObserver>[JournalApp.observer],
+      navigatorObservers: <NavigatorObserver>[
+        JournalApp.observer,
+        CustomRouteObserver(),
+      ],
       initialRoute: initialRoute,
       debugShowCheckedModeBanner: false,
       //debugShowMaterialGrid: true,
diff --git a/lib/folder_views/common.dart b/lib/folder_views/common.dart
index 37819e5b..a3ac764b 100644
--- a/lib/folder_views/common.dart
+++ b/lib/folder_views/common.dart
@@ -64,6 +64,7 @@ Widget buildFolderView(
 void openNoteEditor(BuildContext context, Note note) async {
   var route = MaterialPageRoute(
     builder: (context) => NoteEditor.fromNote(note),
+    settings: const RouteSettings(name: '/note/'),
   );
   var showUndoSnackBar = await Navigator.of(context).push(route);
   if (showUndoSnackBar != null) {
diff --git a/lib/screens/folder_listing.dart b/lib/screens/folder_listing.dart
index b7e19136..84121c60 100644
--- a/lib/screens/folder_listing.dart
+++ b/lib/screens/folder_listing.dart
@@ -32,6 +32,7 @@ class _FolderListingScreenState extends State<FolderListingScreen> {
           builder: (context) => FolderView(
             notesFolder: folder,
           ),
+          settings: const RouteSettings(name: '/folder/'),
         );
         Navigator.of(context).push(route);
       },
diff --git a/lib/screens/folder_view.dart b/lib/screens/folder_view.dart
index 8e4f0d22..19a8ce6a 100644
--- a/lib/screens/folder_view.dart
+++ b/lib/screens/folder_view.dart
@@ -10,6 +10,7 @@ import 'package:gitjournal/core/sorting_mode.dart';
 import 'package:gitjournal/folder_views/standard_view.dart';
 import 'package:gitjournal/screens/note_editor.dart';
 import 'package:gitjournal/screens/settings_screen.dart';
+import 'package:gitjournal/settings.dart';
 import 'package:gitjournal/state_container.dart';
 import 'package:gitjournal/utils.dart';
 import 'package:gitjournal/widgets/app_drawer.dart';
@@ -207,8 +208,11 @@ class _FolderViewState extends State<FolderView> {
       fsFolder = getFolderForEditor(rootFolder, editorType);
     }
 
+    var routeType =
+        SettingsEditorType.fromEditorType(editorType).toInternalString();
     var route = MaterialPageRoute(
       builder: (context) => NoteEditor.newNote(fsFolder, editorType),
+      settings: RouteSettings(name: '/newNote/$routeType'),
     );
     await Navigator.of(context).push(route);
     _scaffoldKey.currentState.removeCurrentSnackBar();
diff --git a/lib/screens/note_editor.dart b/lib/screens/note_editor.dart
index f67d9aa6..fd0da2cc 100644
--- a/lib/screens/note_editor.dart
+++ b/lib/screens/note_editor.dart
@@ -356,6 +356,7 @@ class NoteEditorState extends State<NoteEditor> {
         selectedTags: note.tags,
         allTags: allTags,
       ),
+      settings: const RouteSettings(name: '/editTags/'),
     );
     var newTags = await Navigator.of(context).push(route);
     assert(newTags != null);
diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart
index 2fb4f52d..abe0f2b8 100644
--- a/lib/screens/settings_screen.dart
+++ b/lib/screens/settings_screen.dart
@@ -184,6 +184,7 @@ class SettingsListState extends State<SettingsList> {
         onTap: () {
           var route = MaterialPageRoute(
             builder: (context) => GitRemoteSettingsScreen(),
+            settings: const RouteSettings(name: '/settings/gitRemote'),
           );
           Navigator.of(context).push(route);
         },
@@ -196,6 +197,7 @@ class SettingsListState extends State<SettingsList> {
         onTap: () {
           var route = MaterialPageRoute(
             builder: (context) => SettingsEditorsScreen(),
+            settings: const RouteSettings(name: '/settings/editors'),
           );
           Navigator.of(context).push(route);
         },
@@ -219,6 +221,7 @@ class SettingsListState extends State<SettingsList> {
         onTap: () {
           var route = MaterialPageRoute(
             builder: (context) => NoteMetadataSettingsScreen(),
+            settings: const RouteSettings(name: '/settings/noteMetaData'),
           );
           Navigator.of(context).push(route);
         },
@@ -229,6 +232,7 @@ class SettingsListState extends State<SettingsList> {
         onTap: () {
           var route = MaterialPageRoute(
             builder: (context) => SettingsImagesScreen(),
+            settings: const RouteSettings(name: '/settings/images'),
           );
           Navigator.of(context).push(route);
         },
@@ -260,6 +264,7 @@ class SettingsListState extends State<SettingsList> {
         onTap: () {
           var route = MaterialPageRoute(
             builder: (context) => DebugScreen(),
+            settings: const RouteSettings(name: '/settings/debug'),
           );
           Navigator.of(context).push(route);
         },
diff --git a/lib/screens/tag_listing.dart b/lib/screens/tag_listing.dart
index 6b5f4d19..364bb6a0 100644
--- a/lib/screens/tag_listing.dart
+++ b/lib/screens/tag_listing.dart
@@ -43,16 +43,19 @@ class TagListingScreen extends StatelessWidget {
       leading: FaIcon(FontAwesomeIcons.tag, color: titleColor),
       title: Text(tag),
       onTap: () {
-        var route = MaterialPageRoute(builder: (context) {
-          var rootFolder = Provider.of<NotesFolderFS>(context);
-          var folder = FlattenedNotesFolder(
-            rootFolder,
-            filter: (Note n) => n.tags.contains(tag),
-            title: tag,
-          );
+        var route = MaterialPageRoute(
+          builder: (context) {
+            var rootFolder = Provider.of<NotesFolderFS>(context);
+            var folder = FlattenedNotesFolder(
+              rootFolder,
+              filter: (Note n) => n.tags.contains(tag),
+              title: tag,
+            );
 
-          return FolderView(notesFolder: folder);
-        });
+            return FolderView(notesFolder: folder);
+          },
+          settings: const RouteSettings(name: '/tags/'),
+        );
         Navigator.of(context).push(route);
       },
     );