mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-29 02:07:39 +08:00
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:
@ -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);
|
||||||
|
}
|
||||||
|
@ -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");
|
||||||
|
Reference in New Issue
Block a user