Record when an action is performed on a Note/Folder

This way I'll have statistics about how the app is used and more
importantly, figuring out crash reports will be easier as there will be
a rough trail of actions.
This commit is contained in:
Vishesh Handa
2020-04-22 01:31:48 +02:00
parent c0623d1c3c
commit 152a95d4e9
2 changed files with 79 additions and 0 deletions

View File

@ -8,6 +8,51 @@ Analytics getAnalytics() {
return JournalApp.analytics; return JournalApp.analytics;
} }
enum Event {
NoteAdded,
NoteUpdated,
NoteDeleted,
NoteUndoDeleted,
NoteRenamed,
NoteMoved,
FolderAdded,
FolderDeleted,
FolderRenamed,
FolderConfigUpdated,
RepoSynced,
}
String _eventToString(Event e) {
switch (e) {
case Event.NoteAdded:
return "note_added";
case Event.NoteUpdated:
return "note_updated";
case Event.NoteDeleted:
return "note_deleted";
case Event.NoteUndoDeleted:
return "note_undo_deleted";
case Event.NoteRenamed:
return "note_renamed";
case Event.NoteMoved:
return "note_moved";
case Event.FolderAdded:
return "folder_added";
case Event.FolderDeleted:
return "folder_deleted";
case Event.FolderRenamed:
return "folder_renamed";
case Event.FolderConfigUpdated:
return "folder_config_updated";
case Event.RepoSynced:
return "repo_synced";
}
return "unknown_event";
}
class Analytics { class Analytics {
FirebaseAnalytics firebase; FirebaseAnalytics firebase;
bool enabled = false; bool enabled = false;
@ -20,8 +65,21 @@ class Analytics {
captureErrorBreadcrumb(name: name, parameters: parameters); captureErrorBreadcrumb(name: name, parameters: parameters);
} }
Future<void> log({
@required Event e,
Map<String, dynamic> parameters,
}) async {
String name = _eventToString(e);
await firebase.logEvent(name: name, parameters: parameters);
captureErrorBreadcrumb(name: name, parameters: parameters);
}
Future<void> setAnalyticsCollectionEnabled(bool enabled) async { Future<void> setAnalyticsCollectionEnabled(bool enabled) async {
this.enabled = enabled; this.enabled = enabled;
return firebase.setAnalyticsCollectionEnabled(enabled); return firebase.setAnalyticsCollectionEnabled(enabled);
} }
} }
void logEvent(Event event, {Map<String, dynamic> parameters}) {
getAnalytics().log(e: event, parameters: parameters);
}

View File

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gitjournal/analytics.dart';
import 'package:gitjournal/apis/git_migration.dart'; import 'package:gitjournal/apis/git_migration.dart';
import 'package:gitjournal/appstate.dart'; import 'package:gitjournal/appstate.dart';
@ -95,6 +96,7 @@ class StateContainer with ChangeNotifier {
return true; return true;
} }
logEvent(Event.RepoSynced);
appState.syncStatus = SyncStatus.Pulling; appState.syncStatus = SyncStatus.Pulling;
notifyListeners(); notifyListeners();
@ -134,6 +136,8 @@ class StateContainer with ChangeNotifier {
} }
void createFolder(NotesFolderFS parent, String folderName) async { void createFolder(NotesFolderFS parent, String folderName) async {
logEvent(Event.FolderAdded);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
var newFolderPath = p.join(parent.folderPath, folderName); var newFolderPath = p.join(parent.folderPath, folderName);
var newFolder = NotesFolderFS(parent, newFolderPath); var newFolder = NotesFolderFS(parent, newFolderPath);
@ -149,6 +153,8 @@ class StateContainer with ChangeNotifier {
} }
void removeFolder(NotesFolderFS folder) async { void removeFolder(NotesFolderFS folder) async {
logEvent(Event.FolderDeleted);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
Log.d("Removing Folder: " + folder.folderPath); Log.d("Removing Folder: " + folder.folderPath);
@ -160,6 +166,8 @@ class StateContainer with ChangeNotifier {
} }
void renameFolder(NotesFolderFS folder, String newFolderName) async { void renameFolder(NotesFolderFS folder, String newFolderName) async {
logEvent(Event.FolderRenamed);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
var oldFolderPath = folder.folderPath; var oldFolderPath = folder.folderPath;
print("Renaming Folder from $oldFolderPath -> $newFolderName"); print("Renaming Folder from $oldFolderPath -> $newFolderName");
@ -174,6 +182,8 @@ class StateContainer with ChangeNotifier {
} }
void renameNote(Note note, String newFileName) async { void renameNote(Note note, String newFileName) async {
logEvent(Event.NoteRenamed);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
var oldNotePath = note.filePath; var oldNotePath = note.filePath;
note.rename(newFileName); note.rename(newFileName);
@ -188,6 +198,8 @@ class StateContainer with ChangeNotifier {
if (destFolder.folderPath == note.parent.folderPath) { if (destFolder.folderPath == note.parent.folderPath) {
return; return;
} }
logEvent(Event.NoteMoved);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
var oldNotePath = note.filePath; var oldNotePath = note.filePath;
note.move(destFolder); note.move(destFolder);
@ -199,6 +211,8 @@ class StateContainer with ChangeNotifier {
} }
void addNote(Note note) async { void addNote(Note note) async {
logEvent(Event.NoteAdded);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
Log.d("State Container addNote"); Log.d("State Container addNote");
note.parent.add(note); note.parent.add(note);
@ -210,6 +224,8 @@ class StateContainer with ChangeNotifier {
} }
void removeNote(Note note) async { void removeNote(Note note) async {
logEvent(Event.NoteDeleted);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
// FIXME: What if the Note hasn't yet been saved? // FIXME: What if the Note hasn't yet been saved?
note.parent.remove(note); note.parent.remove(note);
@ -225,6 +241,8 @@ class StateContainer with ChangeNotifier {
} }
void undoRemoveNote(Note note) async { void undoRemoveNote(Note note) async {
logEvent(Event.NoteUndoDeleted);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
note.parent.add(note); note.parent.add(note);
_gitRepo.resetLastCommit().then((NoteRepoResult _) { _gitRepo.resetLastCommit().then((NoteRepoResult _) {
@ -234,6 +252,8 @@ class StateContainer with ChangeNotifier {
} }
void updateNote(Note note) async { void updateNote(Note note) async {
logEvent(Event.NoteUpdated);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
Log.d("State Container updateNote"); Log.d("State Container updateNote");
note.updateModified(); note.updateModified();
@ -247,6 +267,7 @@ class StateContainer with ChangeNotifier {
if (!Features.perFolderConfig) { if (!Features.perFolderConfig) {
return; return;
} }
logEvent(Event.FolderConfigUpdated);
return _opLock.synchronized(() async { return _opLock.synchronized(() async {
Log.d("State Container saveFolderConfig"); Log.d("State Container saveFolderConfig");