mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-28 09:47:35 +08:00
Core: Null Safety++
This is a rather huge change. I hope I haven't broken anything.
This commit is contained in:
@ -1,5 +1,3 @@
|
||||
// @dart=2.9
|
||||
|
||||
/*
|
||||
Copyright 2020-2021 Vishesh Handa <me@vhanda.in>
|
||||
|
||||
@ -86,31 +84,31 @@ enum NoteFileFormat {
|
||||
|
||||
class Note with NotesNotifier {
|
||||
NotesFolderFS parent;
|
||||
String _filePath;
|
||||
String? _filePath;
|
||||
|
||||
String _title = "";
|
||||
DateTime _created;
|
||||
DateTime _modified;
|
||||
DateTime? _created;
|
||||
DateTime? _modified;
|
||||
String _body = "";
|
||||
NoteType _type = NoteType.Unknown;
|
||||
Set<String> _tags = {};
|
||||
Map<String, dynamic> _extraProps = {};
|
||||
|
||||
NoteFileFormat _fileFormat;
|
||||
NoteFileFormat? _fileFormat;
|
||||
|
||||
MdYamlDoc _data = MdYamlDoc();
|
||||
NoteSerializer noteSerializer;
|
||||
late NoteSerializer noteSerializer;
|
||||
|
||||
DateTime fileLastModified;
|
||||
DateTime? fileLastModified;
|
||||
|
||||
var _loadState = NoteLoadState.None;
|
||||
var _serializer = MarkdownYAMLCodec();
|
||||
|
||||
// Computed from body
|
||||
String _summary;
|
||||
List<Link> _links;
|
||||
Set<String> _inlineTags;
|
||||
Set<NoteImage> _images;
|
||||
String? _summary;
|
||||
List<Link>? _links;
|
||||
Set<String>? _inlineTags;
|
||||
Set<NoteImage>? _images;
|
||||
|
||||
static final _mdYamlDocLoader = MdYamlDocLoader();
|
||||
static final _linksLoader = LinksLoader();
|
||||
@ -150,58 +148,61 @@ class Note with NotesNotifier {
|
||||
|
||||
String get filePath {
|
||||
if (_filePath == null) {
|
||||
var fp = "";
|
||||
try {
|
||||
_filePath = p.join(parent.folderPath, _buildFileName());
|
||||
fp = p.join(parent.folderPath, _buildFileName());
|
||||
} catch (e, stackTrace) {
|
||||
Log.e("_buildFileName: $e");
|
||||
logExceptionWarning(e, stackTrace);
|
||||
_filePath = p.join(parent.folderPath, const Uuid().v4());
|
||||
fp = p.join(parent.folderPath, const Uuid().v4());
|
||||
}
|
||||
switch (_fileFormat) {
|
||||
case NoteFileFormat.OrgMode:
|
||||
if (!_filePath.toLowerCase().endsWith('.org')) {
|
||||
_filePath += '.org';
|
||||
if (!fp.toLowerCase().endsWith('.org')) {
|
||||
fp += '.org';
|
||||
}
|
||||
break;
|
||||
|
||||
case NoteFileFormat.Txt:
|
||||
if (!_filePath.toLowerCase().endsWith('.txt')) {
|
||||
_filePath += '.txt';
|
||||
if (!fp.toLowerCase().endsWith('.txt')) {
|
||||
fp += '.txt';
|
||||
}
|
||||
break;
|
||||
|
||||
case NoteFileFormat.Markdown:
|
||||
default:
|
||||
if (!_filePath.toLowerCase().endsWith('.md')) {
|
||||
_filePath += '.md';
|
||||
if (!fp.toLowerCase().endsWith('.md')) {
|
||||
fp += '.md';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_filePath = fp;
|
||||
}
|
||||
|
||||
return _filePath;
|
||||
return _filePath as String;
|
||||
}
|
||||
|
||||
String get fileName {
|
||||
return p.basename(filePath);
|
||||
}
|
||||
|
||||
DateTime get created {
|
||||
DateTime? get created {
|
||||
return _created;
|
||||
}
|
||||
|
||||
set created(DateTime dt) {
|
||||
set created(DateTime? dt) {
|
||||
if (!canHaveMetadata) return;
|
||||
|
||||
_created = dt;
|
||||
_notifyModified();
|
||||
}
|
||||
|
||||
DateTime get modified {
|
||||
DateTime? get modified {
|
||||
return _modified;
|
||||
}
|
||||
|
||||
set modified(DateTime dt) {
|
||||
set modified(DateTime? dt) {
|
||||
if (!canHaveMetadata) return;
|
||||
|
||||
_modified = dt;
|
||||
@ -255,7 +256,6 @@ class Note with NotesNotifier {
|
||||
}
|
||||
|
||||
set tags(Set<String> tags) {
|
||||
assert(tags != null);
|
||||
if (!canHaveMetadata) return;
|
||||
|
||||
_tags = tags;
|
||||
@ -270,16 +270,16 @@ class Note with NotesNotifier {
|
||||
var p = InlineTagsProcessor(tagPrefixes: tagPrefixes);
|
||||
_inlineTags = p.extractTags(body);
|
||||
}
|
||||
return _inlineTags;
|
||||
return _inlineTags!;
|
||||
}
|
||||
|
||||
Set<NoteImage> get images {
|
||||
if (_loadState != NoteLoadState.Loaded) return {};
|
||||
|
||||
var p = ImageExtractor();
|
||||
_images ??= p.extract(body);
|
||||
_images = p.extract(body);
|
||||
|
||||
return _images;
|
||||
return _images!;
|
||||
}
|
||||
|
||||
Map<String, dynamic> get extraProps {
|
||||
@ -317,7 +317,7 @@ class Note with NotesNotifier {
|
||||
return body.isEmpty;
|
||||
}
|
||||
|
||||
String get summary {
|
||||
String? get summary {
|
||||
if (_loadState != NoteLoadState.Loaded) return "";
|
||||
|
||||
_summary ??= stripMarkdownFormatting(body);
|
||||
@ -330,13 +330,13 @@ class Note with NotesNotifier {
|
||||
|
||||
Future<NoteLoadState> load() async {
|
||||
assert(_filePath != null);
|
||||
assert(_filePath.isNotEmpty);
|
||||
assert(_filePath!.isNotEmpty);
|
||||
|
||||
if (_loadState == NoteLoadState.Loading) {
|
||||
return _loadState;
|
||||
}
|
||||
|
||||
final file = File(_filePath);
|
||||
final file = File(_filePath!);
|
||||
if (_loadState == NoteLoadState.Loaded) {
|
||||
try {
|
||||
var fileLastModified = file.lastModifiedSync();
|
||||
@ -346,7 +346,7 @@ class Note with NotesNotifier {
|
||||
this.fileLastModified = fileLastModified;
|
||||
} catch (e, stackTrace) {
|
||||
if (e is FileSystemException &&
|
||||
e.osError.errorCode == 2 /* File Not Found */) {
|
||||
e.osError!.errorCode == 2 /* File Not Found */) {
|
||||
_loadState = NoteLoadState.NotExists;
|
||||
_notifyModified();
|
||||
return _loadState;
|
||||
@ -360,14 +360,15 @@ class Note with NotesNotifier {
|
||||
Log.d("Note modified: $_filePath");
|
||||
}
|
||||
|
||||
var fpLowerCase = _filePath.toLowerCase();
|
||||
var fpLowerCase = _filePath!.toLowerCase();
|
||||
var isMarkdown = fpLowerCase.endsWith('.md');
|
||||
var isTxt = fpLowerCase.endsWith('.txt');
|
||||
var isOrg = fpLowerCase.endsWith('.org');
|
||||
|
||||
if (isMarkdown) {
|
||||
try {
|
||||
data = await _mdYamlDocLoader.loadDoc(_filePath);
|
||||
var dataMaybe = await _mdYamlDocLoader.loadDoc(_filePath!);
|
||||
data = dataMaybe!;
|
||||
_fileFormat = NoteFileFormat.Markdown;
|
||||
} on MdYamlDocNotFoundException catch (_) {
|
||||
_loadState = NoteLoadState.NotExists;
|
||||
@ -382,7 +383,7 @@ class Note with NotesNotifier {
|
||||
}
|
||||
} else if (isTxt) {
|
||||
try {
|
||||
body = await File(_filePath).readAsString();
|
||||
body = await File(_filePath!).readAsString();
|
||||
_fileFormat = NoteFileFormat.Txt;
|
||||
} catch (e, stackTrace) {
|
||||
logExceptionWarning(e, stackTrace);
|
||||
@ -393,7 +394,7 @@ class Note with NotesNotifier {
|
||||
}
|
||||
} else if (isOrg) {
|
||||
try {
|
||||
body = await File(_filePath).readAsString();
|
||||
body = await File(_filePath!).readAsString();
|
||||
_fileFormat = NoteFileFormat.OrgMode;
|
||||
} catch (e, stackTrace) {
|
||||
logExceptionWarning(e, stackTrace);
|
||||
@ -417,10 +418,6 @@ class Note with NotesNotifier {
|
||||
|
||||
// FIXME: What about error handling?
|
||||
Future<void> save() async {
|
||||
assert(_data != null);
|
||||
assert(_data.body != null);
|
||||
assert(_data.props != null);
|
||||
|
||||
var file = File(filePath);
|
||||
var contents = _serializer.encode(data);
|
||||
// Make sure all docs end with a \n
|
||||
@ -439,7 +436,7 @@ class Note with NotesNotifier {
|
||||
Future<void> remove() async {
|
||||
assert(_filePath != null);
|
||||
|
||||
var file = File(_filePath);
|
||||
var file = File(filePath);
|
||||
await file.delete();
|
||||
}
|
||||
|
||||
@ -537,8 +534,12 @@ class Note with NotesNotifier {
|
||||
if (imageSpec == '.') {
|
||||
baseFolder = parent.folderPath;
|
||||
} else {
|
||||
baseFolder = parent.rootFolder.getFolderWithSpec(imageSpec).folderPath;
|
||||
baseFolder ??= parent.folderPath;
|
||||
var folder = parent.rootFolder.getFolderWithSpec(imageSpec);
|
||||
if (folder != null) {
|
||||
baseFolder = folder.folderPath;
|
||||
} else {
|
||||
baseFolder = parent.folderPath;
|
||||
}
|
||||
}
|
||||
|
||||
var imageFileName = p.basename(file.path);
|
||||
@ -567,9 +568,6 @@ class Note with NotesNotifier {
|
||||
}
|
||||
|
||||
String pathSpec() {
|
||||
if (parent == null) {
|
||||
return fileName;
|
||||
}
|
||||
return p.join(parent.pathSpec(), fileName);
|
||||
}
|
||||
|
||||
@ -590,7 +588,6 @@ class Note with NotesNotifier {
|
||||
} else {
|
||||
return toSimpleDateTime(date);
|
||||
}
|
||||
break;
|
||||
case NoteFileNameFormat.Iso8601:
|
||||
return toIso8601(date);
|
||||
case NoteFileNameFormat.Iso8601WithTimeZone:
|
||||
@ -606,20 +603,20 @@ class Note with NotesNotifier {
|
||||
return date.toString();
|
||||
}
|
||||
|
||||
Future<List<Link>> fetchLinks() async {
|
||||
Future<List<Link>?> fetchLinks() async {
|
||||
if (_links != null) {
|
||||
return _links;
|
||||
}
|
||||
|
||||
_links = await _linksLoader.parseLinks(body: _body, filePath: _filePath);
|
||||
_links = await _linksLoader.parseLinks(body: _body, filePath: _filePath!);
|
||||
return _links;
|
||||
}
|
||||
|
||||
List<Link> links() {
|
||||
List<Link>? links() {
|
||||
return _links;
|
||||
}
|
||||
|
||||
NoteFileFormat get fileFormat {
|
||||
NoteFileFormat? get fileFormat {
|
||||
return _fileFormat;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
// @dart=2.9
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@ -9,25 +7,27 @@ typedef NoteModificationCallback = void Function(Note note);
|
||||
typedef NoteRenameCallback = void Function(Note note, String oldPath);
|
||||
|
||||
class NotesNotifier implements ChangeNotifier {
|
||||
var _modListeners = ObserverList<NoteModificationCallback>();
|
||||
var _renameListeners = ObserverList<NoteRenameCallback>();
|
||||
ObserverList<NoteModificationCallback>? _modListeners =
|
||||
ObserverList<NoteModificationCallback>();
|
||||
ObserverList<NoteRenameCallback>? _renameListeners =
|
||||
ObserverList<NoteRenameCallback>();
|
||||
|
||||
void addModifiedListener(NoteModificationCallback listener) {
|
||||
_modListeners.add(listener);
|
||||
_modListeners?.add(listener);
|
||||
}
|
||||
|
||||
void removeModifiedListener(NoteModificationCallback listener) {
|
||||
assert(_modListeners.contains(listener));
|
||||
_modListeners.remove(listener);
|
||||
assert(_modListeners!.contains(listener));
|
||||
_modListeners?.remove(listener);
|
||||
}
|
||||
|
||||
void addRenameListener(NoteRenameCallback listener) {
|
||||
_renameListeners.add(listener);
|
||||
_renameListeners?.add(listener);
|
||||
}
|
||||
|
||||
void removeRenameListener(NoteRenameCallback listener) {
|
||||
assert(_renameListeners.contains(listener));
|
||||
_renameListeners.remove(listener);
|
||||
assert(_renameListeners!.contains(listener));
|
||||
_renameListeners?.remove(listener);
|
||||
}
|
||||
|
||||
@mustCallSuper
|
||||
@ -42,7 +42,7 @@ class NotesNotifier implements ChangeNotifier {
|
||||
//
|
||||
// ChangeNotifier implementation - How to not duplicate this?
|
||||
//
|
||||
ObserverList<VoidCallback> _listeners = ObserverList<VoidCallback>();
|
||||
ObserverList<VoidCallback>? _listeners = ObserverList<VoidCallback>();
|
||||
|
||||
bool _debugAssertNotDisposed() {
|
||||
assert(() {
|
||||
@ -77,7 +77,7 @@ class NotesNotifier implements ChangeNotifier {
|
||||
@override
|
||||
bool get hasListeners {
|
||||
assert(_debugAssertNotDisposed());
|
||||
return _listeners.isNotEmpty;
|
||||
return _listeners!.isNotEmpty;
|
||||
}
|
||||
|
||||
/// Register a closure to be called when the object changes.
|
||||
@ -86,7 +86,7 @@ class NotesNotifier implements ChangeNotifier {
|
||||
@override
|
||||
void addListener(VoidCallback listener) {
|
||||
assert(_debugAssertNotDisposed());
|
||||
_listeners.add(listener);
|
||||
_listeners!.add(listener);
|
||||
}
|
||||
|
||||
/// Remove a previously registered closure from the list of closures that are
|
||||
@ -111,7 +111,7 @@ class NotesNotifier implements ChangeNotifier {
|
||||
@override
|
||||
void removeListener(VoidCallback listener) {
|
||||
assert(_debugAssertNotDisposed());
|
||||
_listeners.remove(listener);
|
||||
_listeners!.remove(listener);
|
||||
}
|
||||
|
||||
/// Call all the registered listeners.
|
||||
@ -136,10 +136,10 @@ class NotesNotifier implements ChangeNotifier {
|
||||
assert(_debugAssertNotDisposed());
|
||||
if (_listeners != null) {
|
||||
final List<VoidCallback> localListeners =
|
||||
List<VoidCallback>.from(_listeners);
|
||||
List<VoidCallback>.from(_listeners!);
|
||||
for (VoidCallback listener in localListeners) {
|
||||
try {
|
||||
if (_listeners.contains(listener)) {
|
||||
if (_listeners!.contains(listener)) {
|
||||
listener();
|
||||
}
|
||||
} catch (exception, stack) {
|
||||
@ -165,10 +165,11 @@ class NotesNotifier implements ChangeNotifier {
|
||||
void notifyModifiedListeners(Note note) {
|
||||
assert(_debugAssertNotDisposed());
|
||||
if (_modListeners != null) {
|
||||
final localListeners = List<NoteModificationCallback>.from(_modListeners);
|
||||
final localListeners =
|
||||
List<NoteModificationCallback>.from(_modListeners!);
|
||||
for (var listener in localListeners) {
|
||||
try {
|
||||
if (_modListeners.contains(listener)) {
|
||||
if (_modListeners!.contains(listener)) {
|
||||
listener(note);
|
||||
}
|
||||
} catch (exception, stack) {
|
||||
@ -194,10 +195,10 @@ class NotesNotifier implements ChangeNotifier {
|
||||
void notifyRenameListeners(Note note, String oldPath) {
|
||||
assert(_debugAssertNotDisposed());
|
||||
if (_renameListeners != null) {
|
||||
final localListeners = List<NoteRenameCallback>.from(_renameListeners);
|
||||
final localListeners = List<NoteRenameCallback>.from(_renameListeners!);
|
||||
for (var listener in localListeners) {
|
||||
try {
|
||||
if (_renameListeners.contains(listener)) {
|
||||
if (_renameListeners!.contains(listener)) {
|
||||
listener(note, oldPath);
|
||||
}
|
||||
} catch (exception, stack) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
// @dart=2.9
|
||||
|
||||
/*
|
||||
Copyright 2020-2021 Vishesh Handa <me@vhanda.in>
|
||||
|
||||
@ -65,18 +63,18 @@ class NoteSerializer implements NoteSerializerInterface {
|
||||
data.body = emojiParser.unemojify(note.body);
|
||||
|
||||
if (note.created != null) {
|
||||
data.props[settings.createdKey] = toIso8601WithTimezone(note.created);
|
||||
data.props[settings.createdKey] = toIso8601WithTimezone(note.created!);
|
||||
} else {
|
||||
data.props.remove(settings.createdKey);
|
||||
}
|
||||
|
||||
if (note.modified != null) {
|
||||
data.props[settings.modifiedKey] = toIso8601WithTimezone(note.modified);
|
||||
data.props[settings.modifiedKey] = toIso8601WithTimezone(note.modified!);
|
||||
} else {
|
||||
data.props.remove(settings.modifiedKey);
|
||||
}
|
||||
|
||||
if (note.title != null) {
|
||||
if (note.title.isNotEmpty) {
|
||||
var title = emojiParser.unemojify(note.title.trim());
|
||||
if (settings.titleSettings == SettingsTitle.InH1) {
|
||||
if (title.isNotEmpty) {
|
||||
|
@ -1,10 +1,7 @@
|
||||
// @dart=2.9
|
||||
|
||||
import 'dart:collection';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:path/path.dart';
|
||||
import 'package:synchronized/synchronized.dart';
|
||||
@ -24,7 +21,7 @@ class IgnoredFile {
|
||||
String filePath;
|
||||
IgnoreReason reason;
|
||||
|
||||
IgnoredFile({@required this.filePath, @required this.reason});
|
||||
IgnoredFile({required this.filePath, required this.reason});
|
||||
|
||||
String get fileName {
|
||||
return p.basename(filePath);
|
||||
@ -32,7 +29,7 @@ class IgnoredFile {
|
||||
}
|
||||
|
||||
class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
|
||||
final NotesFolderFS _parent;
|
||||
final NotesFolderFS? _parent;
|
||||
String _folderPath;
|
||||
var _lock = Lock();
|
||||
|
||||
@ -54,9 +51,9 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
|
||||
}
|
||||
|
||||
@override
|
||||
NotesFolder get parent => _parent;
|
||||
NotesFolder? get parent => _parent;
|
||||
|
||||
NotesFolderFS get parentFS => _parent;
|
||||
NotesFolderFS? get parentFS => _parent;
|
||||
|
||||
void _entityChanged() {
|
||||
notifyListeners();
|
||||
@ -190,7 +187,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
|
||||
futures.add(f);
|
||||
}
|
||||
|
||||
return Future.wait(futures);
|
||||
await Future.wait(futures);
|
||||
}
|
||||
|
||||
Future<void> load() async {
|
||||
@ -418,7 +415,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
|
||||
if (parent == null) {
|
||||
return "";
|
||||
}
|
||||
return p.join(parent.pathSpec(), name);
|
||||
return p.join(parent!.pathSpec(), name);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -448,7 +445,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
|
||||
return this;
|
||||
}
|
||||
|
||||
NotesFolderFS getFolderWithSpec(String spec) {
|
||||
NotesFolderFS? getFolderWithSpec(String spec) {
|
||||
if (pathSpec() == spec) {
|
||||
return this;
|
||||
}
|
||||
@ -465,12 +462,12 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
|
||||
NotesFolderFS get rootFolder {
|
||||
var folder = this;
|
||||
while (folder.parent != null) {
|
||||
folder = folder.parent;
|
||||
folder = folder.parent as NotesFolderFS;
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
Note getNoteWithSpec(String spec) {
|
||||
Note? getNoteWithSpec(String spec) {
|
||||
var parts = spec.split(p.separator);
|
||||
var folder = this;
|
||||
while (parts.length != 1) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
// @dart=2.9
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
import 'package:gitjournal/core/note.dart';
|
||||
@ -160,7 +158,7 @@ int _sortCreatedDesc(Note a, Note b) {
|
||||
if (bDt == null && aDt == null) {
|
||||
return a.fileName.compareTo(b.fileName);
|
||||
}
|
||||
return bDt.compareTo(aDt);
|
||||
return bDt!.compareTo(aDt!);
|
||||
}
|
||||
|
||||
int _sortModifiedDesc(Note a, Note b) {
|
||||
@ -175,12 +173,12 @@ int _sortModifiedDesc(Note a, Note b) {
|
||||
if (bDt == null && aDt == null) {
|
||||
return a.fileName.compareTo(b.fileName);
|
||||
}
|
||||
return bDt.compareTo(aDt);
|
||||
return bDt!.compareTo(aDt!);
|
||||
}
|
||||
|
||||
int _sortTitleAsc(Note a, Note b) {
|
||||
var aTitleExists = a.title != null && a.title.isNotEmpty;
|
||||
var bTitleExists = b.title != null && b.title.isNotEmpty;
|
||||
var aTitleExists = a.title.isNotEmpty;
|
||||
var bTitleExists = b.title.isNotEmpty;
|
||||
|
||||
if (!aTitleExists && bTitleExists) {
|
||||
return 1;
|
||||
|
@ -1,5 +1,3 @@
|
||||
// @dart=2.9
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
@ -30,8 +28,8 @@ Future<void> initSentry() async {
|
||||
Future<SentryEvent> get _environmentEvent async {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final deviceInfoPlugin = DeviceInfoPlugin();
|
||||
SentryOperatingSystem os;
|
||||
SentryDevice device;
|
||||
SentryOperatingSystem? os;
|
||||
SentryDevice? device;
|
||||
if (Platform.isAndroid) {
|
||||
final androidInfo = await deviceInfoPlugin.androidInfo;
|
||||
os = SentryOperatingSystem(
|
||||
@ -77,19 +75,19 @@ void flutterOnErrorHandler(FlutterErrorDetails details) {
|
||||
if (reportCrashes == true) {
|
||||
// vHanda: This doesn't always call our zone error handler, why?
|
||||
// Zone.current.handleUncaughtError(details.exception, details.stack);
|
||||
reportError(details.exception, details.stack);
|
||||
reportError(details.exception, details.stack ?? StackTrace.current);
|
||||
} else {
|
||||
FlutterError.dumpErrorToConsole(details);
|
||||
}
|
||||
}
|
||||
|
||||
bool get reportCrashes => _reportCrashes ??= _initReportCrashes();
|
||||
bool _reportCrashes;
|
||||
bool? _reportCrashes;
|
||||
bool _initReportCrashes() {
|
||||
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);
|
||||
|
||||
if (reportCrashes) {
|
||||
@ -124,8 +122,8 @@ Future<void> logExceptionWarning(Object e, StackTrace stackTrace) async {
|
||||
List<Breadcrumb> breadcrumbs = [];
|
||||
|
||||
void captureErrorBreadcrumb({
|
||||
@required String name,
|
||||
Map<String, String> parameters,
|
||||
required String name,
|
||||
required Map<String, String> parameters,
|
||||
}) {
|
||||
var b = Breadcrumb(
|
||||
message: name,
|
||||
@ -136,19 +134,20 @@ void captureErrorBreadcrumb({
|
||||
}
|
||||
|
||||
Future<void> captureSentryException(
|
||||
Object exception,
|
||||
dynamic exception,
|
||||
StackTrace stackTrace, {
|
||||
SentryLevel level = SentryLevel.error,
|
||||
}) async {
|
||||
try {
|
||||
await initSentry();
|
||||
final event = (await _environmentEvent).copyWith(
|
||||
exception: exception,
|
||||
throwable: exception,
|
||||
breadcrumbs: breadcrumbs,
|
||||
level: level,
|
||||
);
|
||||
|
||||
return Sentry.captureEvent(event, stackTrace: Trace.from(stackTrace).terse);
|
||||
await Sentry.captureEvent(event, stackTrace: Trace.from(stackTrace).terse);
|
||||
return;
|
||||
} catch (e) {
|
||||
print("Failed to report with Sentry: $e");
|
||||
}
|
||||
|
@ -16,14 +16,10 @@ import 'package:gitjournal/screens/note_editor.dart';
|
||||
import 'package:gitjournal/settings.dart';
|
||||
import 'package:gitjournal/utils.dart';
|
||||
import 'package:gitjournal/utils/logger.dart';
|
||||
import 'common_types.dart';
|
||||
import 'standard_view.dart';
|
||||
|
||||
enum FolderViewType {
|
||||
Standard,
|
||||
Journal,
|
||||
Card,
|
||||
Grid,
|
||||
}
|
||||
export 'common_types.dart';
|
||||
|
||||
Widget buildFolderView({
|
||||
@required FolderViewType viewType,
|
||||
|
@ -29,7 +29,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:uuid/uuid.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';
|
||||
|
||||
const DEFAULT_ID = "0";
|
||||
|
Reference in New Issue
Block a user