Core: Null Safety++

This is a rather huge change. I hope I haven't broken anything.
This commit is contained in:
Vishesh Handa
2021-05-17 18:15:47 +02:00
parent 5e5de203da
commit 73f9db5fab
8 changed files with 100 additions and 114 deletions

View File

@ -1,5 +1,3 @@
// @dart=2.9
/* /*
Copyright 2020-2021 Vishesh Handa <me@vhanda.in> Copyright 2020-2021 Vishesh Handa <me@vhanda.in>
@ -86,31 +84,31 @@ enum NoteFileFormat {
class Note with NotesNotifier { class Note with NotesNotifier {
NotesFolderFS parent; NotesFolderFS parent;
String _filePath; String? _filePath;
String _title = ""; String _title = "";
DateTime _created; DateTime? _created;
DateTime _modified; DateTime? _modified;
String _body = ""; String _body = "";
NoteType _type = NoteType.Unknown; NoteType _type = NoteType.Unknown;
Set<String> _tags = {}; Set<String> _tags = {};
Map<String, dynamic> _extraProps = {}; Map<String, dynamic> _extraProps = {};
NoteFileFormat _fileFormat; NoteFileFormat? _fileFormat;
MdYamlDoc _data = MdYamlDoc(); MdYamlDoc _data = MdYamlDoc();
NoteSerializer noteSerializer; late NoteSerializer noteSerializer;
DateTime fileLastModified; DateTime? fileLastModified;
var _loadState = NoteLoadState.None; var _loadState = NoteLoadState.None;
var _serializer = MarkdownYAMLCodec(); var _serializer = MarkdownYAMLCodec();
// Computed from body // Computed from body
String _summary; String? _summary;
List<Link> _links; List<Link>? _links;
Set<String> _inlineTags; Set<String>? _inlineTags;
Set<NoteImage> _images; Set<NoteImage>? _images;
static final _mdYamlDocLoader = MdYamlDocLoader(); static final _mdYamlDocLoader = MdYamlDocLoader();
static final _linksLoader = LinksLoader(); static final _linksLoader = LinksLoader();
@ -150,58 +148,61 @@ class Note with NotesNotifier {
String get filePath { String get filePath {
if (_filePath == null) { if (_filePath == null) {
var fp = "";
try { try {
_filePath = p.join(parent.folderPath, _buildFileName()); fp = p.join(parent.folderPath, _buildFileName());
} catch (e, stackTrace) { } catch (e, stackTrace) {
Log.e("_buildFileName: $e"); Log.e("_buildFileName: $e");
logExceptionWarning(e, stackTrace); logExceptionWarning(e, stackTrace);
_filePath = p.join(parent.folderPath, const Uuid().v4()); fp = p.join(parent.folderPath, const Uuid().v4());
} }
switch (_fileFormat) { switch (_fileFormat) {
case NoteFileFormat.OrgMode: case NoteFileFormat.OrgMode:
if (!_filePath.toLowerCase().endsWith('.org')) { if (!fp.toLowerCase().endsWith('.org')) {
_filePath += '.org'; fp += '.org';
} }
break; break;
case NoteFileFormat.Txt: case NoteFileFormat.Txt:
if (!_filePath.toLowerCase().endsWith('.txt')) { if (!fp.toLowerCase().endsWith('.txt')) {
_filePath += '.txt'; fp += '.txt';
} }
break; break;
case NoteFileFormat.Markdown: case NoteFileFormat.Markdown:
default: default:
if (!_filePath.toLowerCase().endsWith('.md')) { if (!fp.toLowerCase().endsWith('.md')) {
_filePath += '.md'; fp += '.md';
} }
break; break;
} }
_filePath = fp;
} }
return _filePath; return _filePath as String;
} }
String get fileName { String get fileName {
return p.basename(filePath); return p.basename(filePath);
} }
DateTime get created { DateTime? get created {
return _created; return _created;
} }
set created(DateTime dt) { set created(DateTime? dt) {
if (!canHaveMetadata) return; if (!canHaveMetadata) return;
_created = dt; _created = dt;
_notifyModified(); _notifyModified();
} }
DateTime get modified { DateTime? get modified {
return _modified; return _modified;
} }
set modified(DateTime dt) { set modified(DateTime? dt) {
if (!canHaveMetadata) return; if (!canHaveMetadata) return;
_modified = dt; _modified = dt;
@ -255,7 +256,6 @@ class Note with NotesNotifier {
} }
set tags(Set<String> tags) { set tags(Set<String> tags) {
assert(tags != null);
if (!canHaveMetadata) return; if (!canHaveMetadata) return;
_tags = tags; _tags = tags;
@ -270,16 +270,16 @@ class Note with NotesNotifier {
var p = InlineTagsProcessor(tagPrefixes: tagPrefixes); var p = InlineTagsProcessor(tagPrefixes: tagPrefixes);
_inlineTags = p.extractTags(body); _inlineTags = p.extractTags(body);
} }
return _inlineTags; return _inlineTags!;
} }
Set<NoteImage> get images { Set<NoteImage> get images {
if (_loadState != NoteLoadState.Loaded) return {}; if (_loadState != NoteLoadState.Loaded) return {};
var p = ImageExtractor(); var p = ImageExtractor();
_images ??= p.extract(body); _images = p.extract(body);
return _images; return _images!;
} }
Map<String, dynamic> get extraProps { Map<String, dynamic> get extraProps {
@ -317,7 +317,7 @@ class Note with NotesNotifier {
return body.isEmpty; return body.isEmpty;
} }
String get summary { String? get summary {
if (_loadState != NoteLoadState.Loaded) return ""; if (_loadState != NoteLoadState.Loaded) return "";
_summary ??= stripMarkdownFormatting(body); _summary ??= stripMarkdownFormatting(body);
@ -330,13 +330,13 @@ class Note with NotesNotifier {
Future<NoteLoadState> load() async { Future<NoteLoadState> load() async {
assert(_filePath != null); assert(_filePath != null);
assert(_filePath.isNotEmpty); assert(_filePath!.isNotEmpty);
if (_loadState == NoteLoadState.Loading) { if (_loadState == NoteLoadState.Loading) {
return _loadState; return _loadState;
} }
final file = File(_filePath); final file = File(_filePath!);
if (_loadState == NoteLoadState.Loaded) { if (_loadState == NoteLoadState.Loaded) {
try { try {
var fileLastModified = file.lastModifiedSync(); var fileLastModified = file.lastModifiedSync();
@ -346,7 +346,7 @@ class Note with NotesNotifier {
this.fileLastModified = fileLastModified; this.fileLastModified = fileLastModified;
} catch (e, stackTrace) { } catch (e, stackTrace) {
if (e is FileSystemException && if (e is FileSystemException &&
e.osError.errorCode == 2 /* File Not Found */) { e.osError!.errorCode == 2 /* File Not Found */) {
_loadState = NoteLoadState.NotExists; _loadState = NoteLoadState.NotExists;
_notifyModified(); _notifyModified();
return _loadState; return _loadState;
@ -360,14 +360,15 @@ class Note with NotesNotifier {
Log.d("Note modified: $_filePath"); Log.d("Note modified: $_filePath");
} }
var fpLowerCase = _filePath.toLowerCase(); var fpLowerCase = _filePath!.toLowerCase();
var isMarkdown = fpLowerCase.endsWith('.md'); var isMarkdown = fpLowerCase.endsWith('.md');
var isTxt = fpLowerCase.endsWith('.txt'); var isTxt = fpLowerCase.endsWith('.txt');
var isOrg = fpLowerCase.endsWith('.org'); var isOrg = fpLowerCase.endsWith('.org');
if (isMarkdown) { if (isMarkdown) {
try { try {
data = await _mdYamlDocLoader.loadDoc(_filePath); var dataMaybe = await _mdYamlDocLoader.loadDoc(_filePath!);
data = dataMaybe!;
_fileFormat = NoteFileFormat.Markdown; _fileFormat = NoteFileFormat.Markdown;
} on MdYamlDocNotFoundException catch (_) { } on MdYamlDocNotFoundException catch (_) {
_loadState = NoteLoadState.NotExists; _loadState = NoteLoadState.NotExists;
@ -382,7 +383,7 @@ class Note with NotesNotifier {
} }
} else if (isTxt) { } else if (isTxt) {
try { try {
body = await File(_filePath).readAsString(); body = await File(_filePath!).readAsString();
_fileFormat = NoteFileFormat.Txt; _fileFormat = NoteFileFormat.Txt;
} catch (e, stackTrace) { } catch (e, stackTrace) {
logExceptionWarning(e, stackTrace); logExceptionWarning(e, stackTrace);
@ -393,7 +394,7 @@ class Note with NotesNotifier {
} }
} else if (isOrg) { } else if (isOrg) {
try { try {
body = await File(_filePath).readAsString(); body = await File(_filePath!).readAsString();
_fileFormat = NoteFileFormat.OrgMode; _fileFormat = NoteFileFormat.OrgMode;
} catch (e, stackTrace) { } catch (e, stackTrace) {
logExceptionWarning(e, stackTrace); logExceptionWarning(e, stackTrace);
@ -417,10 +418,6 @@ class Note with NotesNotifier {
// FIXME: What about error handling? // FIXME: What about error handling?
Future<void> save() async { Future<void> save() async {
assert(_data != null);
assert(_data.body != null);
assert(_data.props != null);
var file = File(filePath); var file = File(filePath);
var contents = _serializer.encode(data); var contents = _serializer.encode(data);
// Make sure all docs end with a \n // Make sure all docs end with a \n
@ -439,7 +436,7 @@ class Note with NotesNotifier {
Future<void> remove() async { Future<void> remove() async {
assert(_filePath != null); assert(_filePath != null);
var file = File(_filePath); var file = File(filePath);
await file.delete(); await file.delete();
} }
@ -537,8 +534,12 @@ class Note with NotesNotifier {
if (imageSpec == '.') { if (imageSpec == '.') {
baseFolder = parent.folderPath; baseFolder = parent.folderPath;
} else { } else {
baseFolder = parent.rootFolder.getFolderWithSpec(imageSpec).folderPath; var folder = parent.rootFolder.getFolderWithSpec(imageSpec);
baseFolder ??= parent.folderPath; if (folder != null) {
baseFolder = folder.folderPath;
} else {
baseFolder = parent.folderPath;
}
} }
var imageFileName = p.basename(file.path); var imageFileName = p.basename(file.path);
@ -567,9 +568,6 @@ class Note with NotesNotifier {
} }
String pathSpec() { String pathSpec() {
if (parent == null) {
return fileName;
}
return p.join(parent.pathSpec(), fileName); return p.join(parent.pathSpec(), fileName);
} }
@ -590,7 +588,6 @@ class Note with NotesNotifier {
} else { } else {
return toSimpleDateTime(date); return toSimpleDateTime(date);
} }
break;
case NoteFileNameFormat.Iso8601: case NoteFileNameFormat.Iso8601:
return toIso8601(date); return toIso8601(date);
case NoteFileNameFormat.Iso8601WithTimeZone: case NoteFileNameFormat.Iso8601WithTimeZone:
@ -606,20 +603,20 @@ class Note with NotesNotifier {
return date.toString(); return date.toString();
} }
Future<List<Link>> fetchLinks() async { Future<List<Link>?> fetchLinks() async {
if (_links != null) { if (_links != null) {
return _links; return _links;
} }
_links = await _linksLoader.parseLinks(body: _body, filePath: _filePath); _links = await _linksLoader.parseLinks(body: _body, filePath: _filePath!);
return _links; return _links;
} }
List<Link> links() { List<Link>? links() {
return _links; return _links;
} }
NoteFileFormat get fileFormat { NoteFileFormat? get fileFormat {
return _fileFormat; return _fileFormat;
} }
} }

View File

@ -1,5 +1,3 @@
// @dart=2.9
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -9,25 +7,27 @@ typedef NoteModificationCallback = void Function(Note note);
typedef NoteRenameCallback = void Function(Note note, String oldPath); typedef NoteRenameCallback = void Function(Note note, String oldPath);
class NotesNotifier implements ChangeNotifier { class NotesNotifier implements ChangeNotifier {
var _modListeners = ObserverList<NoteModificationCallback>(); ObserverList<NoteModificationCallback>? _modListeners =
var _renameListeners = ObserverList<NoteRenameCallback>(); ObserverList<NoteModificationCallback>();
ObserverList<NoteRenameCallback>? _renameListeners =
ObserverList<NoteRenameCallback>();
void addModifiedListener(NoteModificationCallback listener) { void addModifiedListener(NoteModificationCallback listener) {
_modListeners.add(listener); _modListeners?.add(listener);
} }
void removeModifiedListener(NoteModificationCallback listener) { void removeModifiedListener(NoteModificationCallback listener) {
assert(_modListeners.contains(listener)); assert(_modListeners!.contains(listener));
_modListeners.remove(listener); _modListeners?.remove(listener);
} }
void addRenameListener(NoteRenameCallback listener) { void addRenameListener(NoteRenameCallback listener) {
_renameListeners.add(listener); _renameListeners?.add(listener);
} }
void removeRenameListener(NoteRenameCallback listener) { void removeRenameListener(NoteRenameCallback listener) {
assert(_renameListeners.contains(listener)); assert(_renameListeners!.contains(listener));
_renameListeners.remove(listener); _renameListeners?.remove(listener);
} }
@mustCallSuper @mustCallSuper
@ -42,7 +42,7 @@ class NotesNotifier implements ChangeNotifier {
// //
// ChangeNotifier implementation - How to not duplicate this? // ChangeNotifier implementation - How to not duplicate this?
// //
ObserverList<VoidCallback> _listeners = ObserverList<VoidCallback>(); ObserverList<VoidCallback>? _listeners = ObserverList<VoidCallback>();
bool _debugAssertNotDisposed() { bool _debugAssertNotDisposed() {
assert(() { assert(() {
@ -77,7 +77,7 @@ class NotesNotifier implements ChangeNotifier {
@override @override
bool get hasListeners { bool get hasListeners {
assert(_debugAssertNotDisposed()); assert(_debugAssertNotDisposed());
return _listeners.isNotEmpty; return _listeners!.isNotEmpty;
} }
/// Register a closure to be called when the object changes. /// Register a closure to be called when the object changes.
@ -86,7 +86,7 @@ class NotesNotifier implements ChangeNotifier {
@override @override
void addListener(VoidCallback listener) { void addListener(VoidCallback listener) {
assert(_debugAssertNotDisposed()); assert(_debugAssertNotDisposed());
_listeners.add(listener); _listeners!.add(listener);
} }
/// Remove a previously registered closure from the list of closures that are /// Remove a previously registered closure from the list of closures that are
@ -111,7 +111,7 @@ class NotesNotifier implements ChangeNotifier {
@override @override
void removeListener(VoidCallback listener) { void removeListener(VoidCallback listener) {
assert(_debugAssertNotDisposed()); assert(_debugAssertNotDisposed());
_listeners.remove(listener); _listeners!.remove(listener);
} }
/// Call all the registered listeners. /// Call all the registered listeners.
@ -136,10 +136,10 @@ class NotesNotifier implements ChangeNotifier {
assert(_debugAssertNotDisposed()); assert(_debugAssertNotDisposed());
if (_listeners != null) { if (_listeners != null) {
final List<VoidCallback> localListeners = final List<VoidCallback> localListeners =
List<VoidCallback>.from(_listeners); List<VoidCallback>.from(_listeners!);
for (VoidCallback listener in localListeners) { for (VoidCallback listener in localListeners) {
try { try {
if (_listeners.contains(listener)) { if (_listeners!.contains(listener)) {
listener(); listener();
} }
} catch (exception, stack) { } catch (exception, stack) {
@ -165,10 +165,11 @@ class NotesNotifier implements ChangeNotifier {
void notifyModifiedListeners(Note note) { void notifyModifiedListeners(Note note) {
assert(_debugAssertNotDisposed()); assert(_debugAssertNotDisposed());
if (_modListeners != null) { if (_modListeners != null) {
final localListeners = List<NoteModificationCallback>.from(_modListeners); final localListeners =
List<NoteModificationCallback>.from(_modListeners!);
for (var listener in localListeners) { for (var listener in localListeners) {
try { try {
if (_modListeners.contains(listener)) { if (_modListeners!.contains(listener)) {
listener(note); listener(note);
} }
} catch (exception, stack) { } catch (exception, stack) {
@ -194,10 +195,10 @@ class NotesNotifier implements ChangeNotifier {
void notifyRenameListeners(Note note, String oldPath) { void notifyRenameListeners(Note note, String oldPath) {
assert(_debugAssertNotDisposed()); assert(_debugAssertNotDisposed());
if (_renameListeners != null) { if (_renameListeners != null) {
final localListeners = List<NoteRenameCallback>.from(_renameListeners); final localListeners = List<NoteRenameCallback>.from(_renameListeners!);
for (var listener in localListeners) { for (var listener in localListeners) {
try { try {
if (_renameListeners.contains(listener)) { if (_renameListeners!.contains(listener)) {
listener(note, oldPath); listener(note, oldPath);
} }
} catch (exception, stack) { } catch (exception, stack) {

View File

@ -1,5 +1,3 @@
// @dart=2.9
/* /*
Copyright 2020-2021 Vishesh Handa <me@vhanda.in> Copyright 2020-2021 Vishesh Handa <me@vhanda.in>
@ -65,18 +63,18 @@ class NoteSerializer implements NoteSerializerInterface {
data.body = emojiParser.unemojify(note.body); data.body = emojiParser.unemojify(note.body);
if (note.created != null) { if (note.created != null) {
data.props[settings.createdKey] = toIso8601WithTimezone(note.created); data.props[settings.createdKey] = toIso8601WithTimezone(note.created!);
} else { } else {
data.props.remove(settings.createdKey); data.props.remove(settings.createdKey);
} }
if (note.modified != null) { if (note.modified != null) {
data.props[settings.modifiedKey] = toIso8601WithTimezone(note.modified); data.props[settings.modifiedKey] = toIso8601WithTimezone(note.modified!);
} else { } else {
data.props.remove(settings.modifiedKey); data.props.remove(settings.modifiedKey);
} }
if (note.title != null) { if (note.title.isNotEmpty) {
var title = emojiParser.unemojify(note.title.trim()); var title = emojiParser.unemojify(note.title.trim());
if (settings.titleSettings == SettingsTitle.InH1) { if (settings.titleSettings == SettingsTitle.InH1) {
if (title.isNotEmpty) { if (title.isNotEmpty) {

View File

@ -1,10 +1,7 @@
// @dart=2.9
import 'dart:collection'; import 'dart:collection';
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:synchronized/synchronized.dart'; import 'package:synchronized/synchronized.dart';
@ -24,7 +21,7 @@ class IgnoredFile {
String filePath; String filePath;
IgnoreReason reason; IgnoreReason reason;
IgnoredFile({@required this.filePath, @required this.reason}); IgnoredFile({required this.filePath, required this.reason});
String get fileName { String get fileName {
return p.basename(filePath); return p.basename(filePath);
@ -32,7 +29,7 @@ class IgnoredFile {
} }
class NotesFolderFS with NotesFolderNotifier implements NotesFolder { class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
final NotesFolderFS _parent; final NotesFolderFS? _parent;
String _folderPath; String _folderPath;
var _lock = Lock(); var _lock = Lock();
@ -54,9 +51,9 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
} }
@override @override
NotesFolder get parent => _parent; NotesFolder? get parent => _parent;
NotesFolderFS get parentFS => _parent; NotesFolderFS? get parentFS => _parent;
void _entityChanged() { void _entityChanged() {
notifyListeners(); notifyListeners();
@ -190,7 +187,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
futures.add(f); futures.add(f);
} }
return Future.wait(futures); await Future.wait(futures);
} }
Future<void> load() async { Future<void> load() async {
@ -418,7 +415,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
if (parent == null) { if (parent == null) {
return ""; return "";
} }
return p.join(parent.pathSpec(), name); return p.join(parent!.pathSpec(), name);
} }
@override @override
@ -448,7 +445,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
return this; return this;
} }
NotesFolderFS getFolderWithSpec(String spec) { NotesFolderFS? getFolderWithSpec(String spec) {
if (pathSpec() == spec) { if (pathSpec() == spec) {
return this; return this;
} }
@ -465,12 +462,12 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
NotesFolderFS get rootFolder { NotesFolderFS get rootFolder {
var folder = this; var folder = this;
while (folder.parent != null) { while (folder.parent != null) {
folder = folder.parent; folder = folder.parent as NotesFolderFS;
} }
return folder; return folder;
} }
Note getNoteWithSpec(String spec) { Note? getNoteWithSpec(String spec) {
var parts = spec.split(p.separator); var parts = spec.split(p.separator);
var folder = this; var folder = this;
while (parts.length != 1) { while (parts.length != 1) {

View File

@ -1,5 +1,3 @@
// @dart=2.9
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:gitjournal/core/note.dart'; import 'package:gitjournal/core/note.dart';
@ -160,7 +158,7 @@ int _sortCreatedDesc(Note a, Note b) {
if (bDt == null && aDt == null) { if (bDt == null && aDt == null) {
return a.fileName.compareTo(b.fileName); return a.fileName.compareTo(b.fileName);
} }
return bDt.compareTo(aDt); return bDt!.compareTo(aDt!);
} }
int _sortModifiedDesc(Note a, Note b) { int _sortModifiedDesc(Note a, Note b) {
@ -175,12 +173,12 @@ int _sortModifiedDesc(Note a, Note b) {
if (bDt == null && aDt == null) { if (bDt == null && aDt == null) {
return a.fileName.compareTo(b.fileName); return a.fileName.compareTo(b.fileName);
} }
return bDt.compareTo(aDt); return bDt!.compareTo(aDt!);
} }
int _sortTitleAsc(Note a, Note b) { int _sortTitleAsc(Note a, Note b) {
var aTitleExists = a.title != null && a.title.isNotEmpty; var aTitleExists = a.title.isNotEmpty;
var bTitleExists = b.title != null && b.title.isNotEmpty; var bTitleExists = b.title.isNotEmpty;
if (!aTitleExists && bTitleExists) { if (!aTitleExists && bTitleExists) {
return 1; return 1;

View File

@ -1,5 +1,3 @@
// @dart=2.9
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
@ -30,8 +28,8 @@ Future<void> initSentry() async {
Future<SentryEvent> get _environmentEvent async { Future<SentryEvent> get _environmentEvent async {
final packageInfo = await PackageInfo.fromPlatform(); final packageInfo = await PackageInfo.fromPlatform();
final deviceInfoPlugin = DeviceInfoPlugin(); final deviceInfoPlugin = DeviceInfoPlugin();
SentryOperatingSystem os; SentryOperatingSystem? os;
SentryDevice device; SentryDevice? device;
if (Platform.isAndroid) { if (Platform.isAndroid) {
final androidInfo = await deviceInfoPlugin.androidInfo; final androidInfo = await deviceInfoPlugin.androidInfo;
os = SentryOperatingSystem( os = SentryOperatingSystem(
@ -77,19 +75,19 @@ void flutterOnErrorHandler(FlutterErrorDetails details) {
if (reportCrashes == true) { if (reportCrashes == true) {
// vHanda: This doesn't always call our zone error handler, why? // vHanda: This doesn't always call our zone error handler, why?
// Zone.current.handleUncaughtError(details.exception, details.stack); // Zone.current.handleUncaughtError(details.exception, details.stack);
reportError(details.exception, details.stack); reportError(details.exception, details.stack ?? StackTrace.current);
} else { } else {
FlutterError.dumpErrorToConsole(details); FlutterError.dumpErrorToConsole(details);
} }
} }
bool get reportCrashes => _reportCrashes ??= _initReportCrashes(); bool get reportCrashes => _reportCrashes ??= _initReportCrashes();
bool _reportCrashes; bool? _reportCrashes;
bool _initReportCrashes() { bool _initReportCrashes() {
return !JournalApp.isInDebugMode && AppSettings.instance.collectCrashReports; return !JournalApp.isInDebugMode && AppSettings.instance.collectCrashReports;
} }
Future<void> reportError(Object error, StackTrace stackTrace) async { Future<void> reportError(dynamic error, StackTrace stackTrace) async {
Log.e("Uncaught Exception", ex: error, stacktrace: stackTrace); Log.e("Uncaught Exception", ex: error, stacktrace: stackTrace);
if (reportCrashes) { if (reportCrashes) {
@ -124,8 +122,8 @@ Future<void> logExceptionWarning(Object e, StackTrace stackTrace) async {
List<Breadcrumb> breadcrumbs = []; List<Breadcrumb> breadcrumbs = [];
void captureErrorBreadcrumb({ void captureErrorBreadcrumb({
@required String name, required String name,
Map<String, String> parameters, required Map<String, String> parameters,
}) { }) {
var b = Breadcrumb( var b = Breadcrumb(
message: name, message: name,
@ -136,19 +134,20 @@ void captureErrorBreadcrumb({
} }
Future<void> captureSentryException( Future<void> captureSentryException(
Object exception, dynamic exception,
StackTrace stackTrace, { StackTrace stackTrace, {
SentryLevel level = SentryLevel.error, SentryLevel level = SentryLevel.error,
}) async { }) async {
try { try {
await initSentry(); await initSentry();
final event = (await _environmentEvent).copyWith( final event = (await _environmentEvent).copyWith(
exception: exception, throwable: exception,
breadcrumbs: breadcrumbs, breadcrumbs: breadcrumbs,
level: level, level: level,
); );
return Sentry.captureEvent(event, stackTrace: Trace.from(stackTrace).terse); await Sentry.captureEvent(event, stackTrace: Trace.from(stackTrace).terse);
return;
} catch (e) { } catch (e) {
print("Failed to report with Sentry: $e"); print("Failed to report with Sentry: $e");
} }

View File

@ -16,14 +16,10 @@ import 'package:gitjournal/screens/note_editor.dart';
import 'package:gitjournal/settings.dart'; import 'package:gitjournal/settings.dart';
import 'package:gitjournal/utils.dart'; import 'package:gitjournal/utils.dart';
import 'package:gitjournal/utils/logger.dart'; import 'package:gitjournal/utils/logger.dart';
import 'common_types.dart';
import 'standard_view.dart'; import 'standard_view.dart';
enum FolderViewType { export 'common_types.dart';
Standard,
Journal,
Card,
Grid,
}
Widget buildFolderView({ Widget buildFolderView({
@required FolderViewType viewType, @required FolderViewType viewType,

View File

@ -29,7 +29,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import 'package:gitjournal/core/sorting_mode.dart'; import 'package:gitjournal/core/sorting_mode.dart';
import 'package:gitjournal/folder_views/common.dart'; import 'package:gitjournal/folder_views/common_types.dart';
import 'package:gitjournal/screens/note_editor.dart'; import 'package:gitjournal/screens/note_editor.dart';
const DEFAULT_ID = "0"; const DEFAULT_ID = "0";