Use flutter_lint

Instead of picking lint values. This way I don't need to routinely
looking at extra lints to enable.
This commit is contained in:
Vishesh Handa
2021-09-21 15:38:01 +02:00
parent 5236a2bf31
commit c4ef1f569b
121 changed files with 712 additions and 761 deletions

View File

@ -2,13 +2,8 @@
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# Specify analysis options.
#
# Until there are meta linter rules, each desired lint must be explicitly enabled.
# See: https://github.com/dart-lang/linter/issues/288
#
# For a list of lints, see: http://dart-lang.github.io/linter/lints/
#
include: package:flutter_lints/flutter.yaml
analyzer:
strong-mode:
implicit-dynamic: true
@ -28,111 +23,12 @@ analyzer:
linter:
rules:
# these rules are documented on and in the same order as
# the Dart Lint rules page to make maintenance easier
# http://dart-lang.github.io/linter/lints/
# === error rules ===
- avoid_empty_else
- avoid_slow_async_io
- cancel_subscriptions
# - close_sinks # https://github.com/flutter/flutter/issues/5789
# - comment_references # blocked on https://github.com/dart-lang/dartdoc/issues/1153
- control_flow_in_finally
- empty_statements
- hash_and_equals
# - invariant_booleans # https://github.com/flutter/flutter/issues/5790
- iterable_contains_unrelated_type
- list_remove_unrelated_type
# - literal_only_boolean_expressions # https://github.com/flutter/flutter/issues/5791
- no_adjacent_strings_in_list
- no_duplicate_case_values
- test_types_in_equals
- throw_in_finally
- unrelated_type_equality_checks
- valid_regexps
# === style rules ===
- always_declare_return_types
# - always_put_control_body_on_new_line
- always_require_non_null_named_parameters
# - always_specify_types
- annotate_overrides
# - avoid_annotating_with_dynamic # not yet tested
# - avoid_as
# - avoid_catches_without_on_clauses # not yet tested
# - avoid_catching_errors # not yet tested
# - avoid_classes_with_only_static_members
# - avoid_function_literals_in_foreach_calls # not yet tested
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
# - avoid_positional_boolean_parameters # not yet tested
- avoid_return_types_on_setters
# - avoid_returning_null # not yet tested
# - avoid_returning_this # not yet tested
# - avoid_setters_without_getters # not yet tested
# - avoid_types_on_closure_parameters # not yet tested
- await_only_futures
- camel_case_types
# - cascade_invocations # not yet tested
# - constant_identifier_names # https://github.com/dart-lang/linter/issues/204
- directives_ordering
- empty_catches
- empty_constructor_bodies
- implementation_imports
# - join_return_with_assignment # not yet tested
- library_names
- library_prefixes
- non_constant_identifier_names
# - omit_local_variable_types # opposite of always_specify_types
# - one_member_abstracts # too many false positives
- only_throw_errors
- overridden_fields
- package_api_docs
- package_prefixed_library_names
# - parameter_assignments # we do this commonly
- prefer_adjacent_string_concatenation
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
# - prefer_constructors_over_static_methods # not yet tested
- prefer_contains
- prefer_equal_for_default_values
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
# - prefer_final_fields # https://github.com/dart-lang/linter/issues/506
# - prefer_final_locals
# - prefer_foreach # not yet tested
# - prefer_function_declarations_over_variables # not yet tested
- prefer_initializing_formals
# - prefer_interpolation_to_compose_strings # not yet tested
- prefer_is_empty
- prefer_is_not_empty
- prefer_void_to_null
# - recursive_getters # https://github.com/dart-lang/linter/issues/452
- slash_for_doc_comments
- curly_braces_in_flow_control_structures
# - sort_constructors_first
# - sort_unnamed_constructors_first
# - type_annotate_public_apis # subset of always_specify_types
- type_init_formals
# - unawaited_futures # https://github.com/flutter/flutter/issues/5793
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_in_if_null_operators
# - unnecessary_overrides # https://github.com/dart-lang/linter/issues/626 and https://github.com/dart-lang/linter/issues/627
- unnecessary_statements
- unnecessary_this
# - use_rethrow_when_possible
# - use_setters_to_change_properties # not yet tested
# - use_string_buffers # https://github.com/dart-lang/linter/pull/664
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
# === pub rules ===
- package_names
avoid_print: false
constant_identifier_names: false
avoid_renaming_method_parameters: false
use_key_in_widget_constructors: false
prefer_function_declarations_over_variables: false
no_logic_in_create_state: false
dart_code_metrics:
metrics-exclude:

View File

@ -153,6 +153,8 @@ settings:
customMetaData:
title: Custom MetaData
invalid: Invalid YAML
output: Output
input: Input
privacy: Privacy Policy
terms: Terms and Conditions
experimental:

View File

@ -275,6 +275,8 @@ class _LoginPageState extends SupabaseAuthState<LoginPage> {
}
class FormBackButton extends StatelessWidget {
const FormBackButton({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
@ -284,11 +286,9 @@ class FormBackButton extends StatelessWidget {
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
children: <Widget>[
Container(
child: const Icon(Icons.keyboard_arrow_left, color: Colors.black),
),
const Text(
children: const <Widget>[
Icon(Icons.keyboard_arrow_left, color: Colors.black),
Text(
'Back',
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
)

View File

@ -50,11 +50,11 @@ class GitHubFake implements GitHost {
Future<Result<List<GitHostRepo>>> listRepos() async {
List<dynamic> list = jsonDecode(data);
var repos = <GitHostRepo>[];
list.forEach((dynamic d) {
for (var d in list) {
var map = Map<String, dynamic>.from(d);
var repo = GitHub.repoFromJson(map);
repos.add(repo);
});
}
return Result(repos);
}

View File

@ -24,7 +24,7 @@ class GitHub implements GitHost {
static const _clientID = "aa3072cbfb02b1db14ed";
static const _clientSecret = "010d303ea99f82330f2b228977cef9ddbf7af2cd";
var _platform = const MethodChannel('gitjournal.io/git');
final _platform = const MethodChannel('gitjournal.io/git');
var _accessCode = "";
@override
@ -116,11 +116,11 @@ class GitHub implements GitHost {
List<dynamic> list = jsonDecode(response.body);
var repos = <GitHostRepo>[];
list.forEach((dynamic d) {
for (var d in list) {
var map = Map<String, dynamic>.from(d);
var repo = repoFromJson(map);
repos.add(repo);
});
}
// FIXME: Sort these based on some criteria
return Result(repos);

View File

@ -24,7 +24,7 @@ class GitLab implements GitHost {
static const _clientID =
"faf33c3716faf05bfb701b1b31e36c83a23c3ec2d7161f4ff00fba2275524d09";
var _platform = const MethodChannel('gitjournal.io/git');
final _platform = const MethodChannel('gitjournal.io/git');
String? _accessCode = "";
var _stateOAuth = "";
@ -101,11 +101,11 @@ class GitLab implements GitHost {
List<dynamic> list = jsonDecode(response.body);
var repos = <GitHostRepo>[];
list.forEach((dynamic d) {
for (var d in list) {
var map = Map<String, dynamic>.from(d);
var repo = repoFromJson(map);
repos.add(repo);
});
}
// FIXME: Sort these based on some criteria
return Result(repos);

View File

@ -84,25 +84,25 @@ class JournalApp extends StatefulWidget {
repoManager: repoManager,
appSettings: appSettings,
pref: pref,
child: JournalApp(),
child: const JournalApp(),
),
supportedLocales: [
supportedLocales: const [
// Arranged Alphabetically
const Locale('de'),
const Locale('en'),
const Locale('es'),
const Locale('fr'),
const Locale('hu'),
const Locale('id'),
const Locale('it'),
const Locale('ja'),
const Locale('ko'),
const Locale('pl'),
const Locale('pt'),
const Locale('ru'),
const Locale('sv'),
const Locale('vi'),
const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'),
Locale('de'),
Locale('en'),
Locale('es'),
Locale('fr'),
Locale('hu'),
Locale('id'),
Locale('it'),
Locale('ja'),
Locale('ko'),
Locale('pl'),
Locale('pt'),
Locale('ru'),
Locale('sv'),
Locale('vi'),
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'),
], // Remember to update Info.plist
fallbackLocale: const Locale('en'),
useFallbackTranslations: true,
@ -138,7 +138,7 @@ class JournalApp extends StatefulWidget {
);
}
JournalApp();
const JournalApp({Key? key}) : super(key: key);
@override
_JournalAppState createState() => _JournalAppState();
@ -160,7 +160,7 @@ class _JournalAppState extends State<JournalApp> {
return;
}
final QuickActions quickActions = const QuickActions();
const quickActions = QuickActions();
quickActions.initialize((String shortcutType) {
Log.i("Quick Action Open: $shortcutType");
if (_navigatorKey.currentState == null) {
@ -205,30 +205,30 @@ class _JournalAppState extends State<JournalApp> {
}
}
void _handleShare(Duration _) {
var noText = _sharedText.isEmpty;
var noImages = _sharedImages.isEmpty;
if (noText && noImages) {
return;
}
var folderConfig = Provider.of<NotesFolderConfig>(context, listen: false);
var editor = folderConfig.defaultEditor.toInternalString();
_navigatorKey.currentState!.pushNamed(AppRoute.NewNotePrefix + editor);
}
void _initShareSubscriptions() {
if (!Platform.isAndroid && !Platform.isIOS) {
return;
}
var handleShare = () {
var noText = _sharedText.isEmpty;
var noImages = _sharedImages.isEmpty;
if (noText && noImages) {
return;
}
var folderConfig = Provider.of<NotesFolderConfig>(context, listen: false);
var editor = folderConfig.defaultEditor.toInternalString();
_navigatorKey.currentState!.pushNamed(AppRoute.NewNotePrefix + editor);
};
// For sharing images coming from outside the app while the app is in the memory
_intentDataStreamSubscription = ReceiveSharingIntent.getMediaStream()
.listen((List<SharedMediaFile> value) {
Log.d("Received Media Share $value");
_sharedImages = value.map((f) => f.path).toList();
WidgetsBinding.instance!.addPostFrameCallback((_) => handleShare());
WidgetsBinding.instance!.addPostFrameCallback(_handleShare);
}, onError: (err) {
Log.e("getIntentDataStream error: $err");
});
@ -238,7 +238,7 @@ class _JournalAppState extends State<JournalApp> {
Log.d("Received MediaFile Share with App (media): $value");
_sharedImages = value.map((f) => f.path).toList();
WidgetsBinding.instance!.addPostFrameCallback((_) => handleShare());
WidgetsBinding.instance!.addPostFrameCallback(_handleShare);
});
// For sharing or opening text coming from outside the app while the app is in the memory
@ -249,7 +249,7 @@ class _JournalAppState extends State<JournalApp> {
return;
}
_sharedText = value;
WidgetsBinding.instance!.addPostFrameCallback((_) => handleShare());
WidgetsBinding.instance!.addPostFrameCallback(_handleShare);
}, onError: (err) {
Log.e("getLinkStream error: $err");
});
@ -259,7 +259,7 @@ class _JournalAppState extends State<JournalApp> {
if (value == null) return;
Log.d("Received Share with App (text): ${value.length}");
_sharedText = value;
WidgetsBinding.instance!.addPostFrameCallback((_) => handleShare());
WidgetsBinding.instance!.addPostFrameCallback(_handleShare);
});
}
@ -344,7 +344,7 @@ class GitJournalChangeNotifiers extends StatelessWidget {
final SharedPreferences pref;
final Widget child;
GitJournalChangeNotifiers({
const GitJournalChangeNotifiers({
required this.repoManager,
required this.appSettings,
required this.pref,

View File

@ -131,9 +131,9 @@ class AppRouter {
case AppRoute.AllFolders:
return FolderListingScreen();
case AppRoute.AllTags:
return TagListingScreen();
return const TagListingScreen();
case AppRoute.Graph:
return GraphViewScreen();
return const GraphViewScreen();
case AppRoute.Settings:
return SettingsScreen();
case AppRoute.Login:
@ -147,7 +147,7 @@ class AppRouter {
onCompletedFunction: repository.completeGitHostSetup,
);
case AppRoute.OnBoarding:
return OnBoardingScreen();
return const OnBoardingScreen();
case AppRoute.Purchase:
return PurchaseScreen();
case AppRoute.PurchaseThank:

View File

@ -61,7 +61,7 @@ class Checklist {
multiLine: false,
);
Note _note;
final Note _note;
List<ChecklistItem> items = [];
late List<String> _lines;

View File

@ -21,8 +21,8 @@ class FlattenedFilteredNotesFolder
final _lock = Lock();
var _notes = <Note>[];
var _folders = <NotesFolder>[];
final _notes = <Note>[];
final _folders = <NotesFolder>[];
FlattenedFilteredNotesFolder._internal(
this._parentFolder, this.title, this.filter);

View File

@ -14,8 +14,8 @@ class FlattenedNotesFolder with NotesFolderNotifier implements NotesFolder {
final NotesFolder _parentFolder;
final String title;
var _notes = <Note>[];
var _folders = <NotesFolder>[];
final _notes = <Note>[];
final _folders = <NotesFolder>[];
FlattenedNotesFolder(this._parentFolder, {required this.title}) {
_addFolder(_parentFolder);

View File

@ -48,7 +48,7 @@ class Graph extends ChangeNotifier {
List<Node> nodes = [];
List<Edge> edges = [];
Map<String?, Set<int?>> _neighbours = {};
final Map<String?, Set<int?>> _neighbours = {};
Map<String?, int>? _nodeIndexes;
late GraphNodeLayout initLayouter;

View File

@ -156,7 +156,7 @@ class LinkExtractor implements md.NodeVisitor {
/// Parse [[term]]
class WikiLinkSyntax extends md.InlineSyntax {
static final String _pattern = r'\[\[([^\[\]]+)\]\]';
static const String _pattern = r'\[\[([^\[\]]+)\]\]';
// In Obsidian style, the link is like [[fileToLinkTo|display text]]
final bool obsidianStyle;

View File

@ -17,10 +17,10 @@ import 'package:gitjournal/core/link.dart';
class LinksLoader {
Isolate? _isolate;
ReceivePort _receivePort = ReceivePort();
final _receivePort = ReceivePort();
SendPort? _sendPort;
var _loadingLock = Lock();
final _loadingLock = Lock();
Future<void> _initIsolate() async {
if (_isolate != null && _sendPort != null) return;

View File

@ -15,10 +15,10 @@ import 'package:gitjournal/core/md_yaml_doc_codec.dart';
class MdYamlDocLoader {
Isolate? _isolate;
ReceivePort _receivePort = ReceivePort();
final _receivePort = ReceivePort();
SendPort? _sendPort;
var _loadingLock = Lock();
final _loadingLock = Lock();
Future<void> _initIsolate() async {
if (_isolate != null && _sendPort != null) return;

View File

@ -16,8 +16,8 @@ import 'package:gitjournal/utils/datetime.dart';
import 'md_yaml_doc.dart';
import 'note_serializer.dart';
typedef void NoteSelectedFunction(Note note);
typedef bool NoteBoolPropertyFunction(Note note);
typedef NoteSelectedFunction = void Function(Note note);
typedef NoteBoolPropertyFunction = bool Function(Note note);
/// Move this to NotesFolderFS
enum NoteLoadState {

View File

@ -104,12 +104,14 @@ class NotesCache {
SortingMode sortingMode,
) {
var origFn = sortingMode.sortingFunction();
var reversedFn = (Note a, Note b) {
reversedFn(Note a, Note b) {
var r = origFn(a, b);
if (r < 0) return 1;
if (r > 0) return -1;
return 0;
};
}
var heap = HeapPriorityQueue<Note>(reversedFn);
for (var note in allNotes) {

View File

@ -39,20 +39,22 @@ class IgnoredFile {
class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
final NotesFolderFS? _parent;
String _folderPath;
var _lock = Lock();
final _lock = Lock();
List<Note> _notes = [];
List<NotesFolderFS> _folders = [];
final _notes = <Note>[];
final _folders = <NotesFolderFS>[];
List<IgnoredFile> _ignoredFiles = [];
Map<String, dynamic> _entityMap = {};
NotesFolderConfig _config;
final _entityMap = <String, dynamic>{};
final NotesFolderConfig _config;
NotesFolderFS(this._parent, this._folderPath, this._config);
@override
void dispose() {
_folders.forEach((f) => f.removeListener(_entityChanged));
for (var f in _folders) {
f.removeListener(_entityChanged);
}
super.dispose();
}
@ -184,7 +186,8 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
// Remove notes which have errors
await _lock.synchronized(() {
var errFunc = (Note n) => n.loadState == NoteLoadState.Error;
errFunc(Note n) => n.loadState == NoteLoadState.Error;
var hasBadNotes = _notes.any(errFunc);
if (hasBadNotes) {
while (true) {
@ -292,7 +295,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
}
Set<String> pathsRemoved = _entityMap.keys.toSet().difference(pathsFound);
pathsRemoved.forEach((path) {
for (var path in pathsRemoved) {
var e = _entityMap[path];
assert(e != null);
@ -316,7 +319,7 @@ class NotesFolderFS with NotesFolderNotifier implements NotesFolder {
_folders.removeAt(i);
notifyFolderRemoved(i, folder);
}
});
}
}
void add(Note note) {

View File

@ -10,7 +10,7 @@ class NoteImage extends Equatable {
final String url;
final String alt;
NoteImage({required this.url, required this.alt});
const NoteImage({required this.url, required this.alt});
@override
List<Object> get props => [url, alt];

View File

@ -18,7 +18,7 @@ typedef InlineTagsView = NotesMaterializedView<List<String>>;
class InlineTagsProvider extends SingleChildStatelessWidget {
final String repoPath;
InlineTagsProvider({
const InlineTagsProvider({
Key? key,
Widget? child,
required this.repoPath,

View File

@ -41,7 +41,7 @@ class NoteLinksView extends NotesMaterializedView<_LinksList> {
class NoteLinksProvider extends SingleChildStatelessWidget {
final String repoPath;
NoteLinksProvider({
const NoteLinksProvider({
Key? key,
Widget? child,
required this.repoPath,

View File

@ -18,7 +18,7 @@ typedef NotesSummaryView = NotesMaterializedView<String>;
class NoteSummaryProvider extends SingleChildStatelessWidget {
final String repoPath;
NoteSummaryProvider({
const NoteSummaryProvider({
Key? key,
Widget? child,
required this.repoPath,

View File

@ -15,8 +15,8 @@ class WorkerQueue<INPUT, OUTPUT> {
Isolate? _isolate;
SendPort? _sendPort;
var _receivePort = ReceivePort();
var _loadingLock = Lock();
final _receivePort = ReceivePort();
final _loadingLock = Lock();
Func1<INPUT, OUTPUT> func;

View File

@ -20,14 +20,15 @@ class AutoCompletionWidget extends StatefulWidget {
final Widget child;
final List<String> tags;
AutoCompletionWidget({
const AutoCompletionWidget({
Key? key,
required this.textFieldFocusNode,
required this.textFieldKey,
required this.textFieldStyle,
required this.textController,
required this.child,
required this.tags,
});
}) : super(key: key);
@override
_AutoCompletionWidgetState createState() => _AutoCompletionWidgetState();

View File

@ -35,7 +35,8 @@ class EditorBottomBar extends StatelessWidget {
final Func0<void> onUndoSelected;
final Func0<void> onRedoSelected;
EditorBottomBar({
const EditorBottomBar({
Key? key,
required this.editor,
required this.editorState,
required this.parentFolder,
@ -47,7 +48,7 @@ class EditorBottomBar extends StatelessWidget {
required this.onRedoSelected,
required this.undoAllowed,
required this.redoAllowed,
});
}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -136,52 +137,50 @@ class AddBottomSheet extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: const Icon(Icons.camera),
title: Text(tr(LocaleKeys.editors_common_takePhoto)),
onTap: () async {
try {
var image = await ImagePicker().pickImage(
source: ImageSource.camera,
);
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: const Icon(Icons.camera),
title: Text(tr(LocaleKeys.editors_common_takePhoto)),
onTap: () async {
try {
var image = await ImagePicker().pickImage(
source: ImageSource.camera,
);
if (image != null) {
await editorState.addImage(image.path);
}
} catch (e) {
reportError(e, StackTrace.current);
if (image != null) {
await editorState.addImage(image.path);
}
Navigator.of(context).pop();
},
),
ListTile(
leading: const Icon(Icons.image),
title: Text(tr(LocaleKeys.editors_common_addImage)),
onTap: () async {
try {
var image = await ImagePicker().pickImage(
source: ImageSource.gallery,
);
} catch (e) {
reportError(e, StackTrace.current);
}
Navigator.of(context).pop();
},
),
ListTile(
leading: const Icon(Icons.image),
title: Text(tr(LocaleKeys.editors_common_addImage)),
onTap: () async {
try {
var image = await ImagePicker().pickImage(
source: ImageSource.gallery,
);
if (image != null) {
await editorState.addImage(image.path);
}
} catch (e) {
if (e is PlatformException && e.code == "photo_access_denied") {
Navigator.of(context).pop();
return;
}
reportError(e, StackTrace.current);
if (image != null) {
await editorState.addImage(image.path);
}
Navigator.of(context).pop();
},
),
],
),
} catch (e) {
if (e is PlatformException && e.code == "photo_access_denied") {
Navigator.of(context).pop();
return;
}
reportError(e, StackTrace.current);
}
Navigator.of(context).pop();
},
),
],
);
}
}
@ -204,48 +203,71 @@ class BottomMenuSheet extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: const Icon(Icons.undo),
title: Text(tr(LocaleKeys.editors_common_discard)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: const Icon(Icons.undo),
title: Text(tr(LocaleKeys.editors_common_discard)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
editor.common.discardChanges(note);
},
enabled: editorState.noteModified,
),
ListTile(
leading: const Icon(Icons.share),
title: Text(tr(LocaleKeys.editors_common_share)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
editor.common.discardChanges(note);
},
enabled: editorState.noteModified,
),
ListTile(
leading: const Icon(Icons.share),
title: Text(tr(LocaleKeys.editors_common_share)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
shareNote(note);
},
),
if (metaDataEditable)
ProOverlay(
feature: Feature.tags,
child: ListTile(
leading: const FaIcon(FontAwesomeIcons.tag),
title: Text(tr(LocaleKeys.editors_common_tags)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
shareNote(note);
},
),
if (metaDataEditable)
ProOverlay(
feature: Feature.tags,
child: ListTile(
leading: const FaIcon(FontAwesomeIcons.tag),
title: Text(tr(LocaleKeys.editors_common_tags)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
editor.common.editTags(note);
},
),
editor.common.editTags(note);
},
),
),
ListTile(
leading: const Icon(Icons.edit),
title: Text(tr(LocaleKeys.editors_common_editFileName)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
editor.common.renameNote(note);
},
),
ProOverlay(
feature: Feature.zenMode,
child: ListTile(
leading: const FaIcon(FontAwesomeIcons.peace),
title: Text(tr(zenModeEnabled
? LocaleKeys.editors_common_zen_disable
: LocaleKeys.editors_common_zen_enable)),
onTap: () {
zenModeChanged();
Navigator.of(context).pop();
},
),
),
if (Features.findInNote)
ListTile(
leading: const Icon(Icons.edit),
title: Text(tr(LocaleKeys.editors_common_editFileName)),
leading: const Icon(Icons.search),
title: Text(tr(LocaleKeys.editors_common_find)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
@ -253,32 +275,7 @@ class BottomMenuSheet extends StatelessWidget {
editor.common.renameNote(note);
},
),
ProOverlay(
feature: Feature.zenMode,
child: ListTile(
leading: const FaIcon(FontAwesomeIcons.peace),
title: Text(tr(zenModeEnabled
? LocaleKeys.editors_common_zen_disable
: LocaleKeys.editors_common_zen_enable)),
onTap: () {
zenModeChanged();
Navigator.of(context).pop();
},
),
),
if (Features.findInNote)
ListTile(
leading: const Icon(Icons.search),
title: Text(tr(LocaleKeys.editors_common_find)),
onTap: () {
var note = editorState.getNote();
Navigator.of(context).pop();
editor.common.renameNote(note);
},
),
],
),
],
);
}
}

View File

@ -32,7 +32,7 @@ class ChecklistEditor extends StatefulWidget implements Editor {
final String? highlightString;
final ThemeData theme;
ChecklistEditor({
const ChecklistEditor({
Key? key,
required this.note,
required this.noteModified,
@ -328,7 +328,7 @@ class ChecklistItemTile extends StatefulWidget {
final String? highlightString;
final ThemeData theme;
ChecklistItemTile({
const ChecklistItemTile({
Key? key,
required this.item,
required this.statusChanged,
@ -404,10 +404,10 @@ class _ChecklistItemTileState extends State<ChecklistItemTile> {
dense: true,
leading: Row(
children: <Widget>[
Container(
const SizedBox(
height: 24.0,
width: 24.0,
child: const Icon(Icons.drag_handle),
child: Icon(Icons.drag_handle),
),
const SizedBox(width: 8.0),
SizedBox(
@ -434,7 +434,7 @@ class _ChecklistItemTileState extends State<ChecklistItemTile> {
class AddItemButton extends StatelessWidget {
final void Function() onPressed;
AddItemButton({Key? key, required this.onPressed}) : super(key: key);
const AddItemButton({Key? key, required this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -444,7 +444,7 @@ class AddItemButton extends StatelessWidget {
dense: true,
leading: Row(
children: <Widget>[
Container(height: 24.0, width: 24.0),
const SizedBox(height: 24.0, width: 24.0),
const SizedBox(width: 8.0),
Container(
padding: const EdgeInsets.all(0.0),

View File

@ -67,7 +67,7 @@ class EditorAppBar extends StatelessWidget implements PreferredSizeWidget {
final bool allowEdits;
final Func0<void> onEditingModeChange;
EditorAppBar({
const EditorAppBar({
Key? key,
required this.editor,
required this.editorState,
@ -127,7 +127,7 @@ class EditorAppSearchBar extends StatelessWidget
final IconButton? extraButton;
final Func0<void> onEditingModeChange;
EditorAppSearchBar({
const EditorAppSearchBar({
Key? key,
required this.editor,
required this.editorState,

View File

@ -12,10 +12,11 @@ class EditorScrollView extends StatelessWidget {
final Widget child;
final EdgeInsetsGeometry padding;
EditorScrollView({
const EditorScrollView({
Key? key,
required this.child,
this.padding = const EdgeInsets.all(16.0),
});
}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -29,7 +29,7 @@ class JournalEditor extends StatefulWidget implements Editor {
@override
final EditorCommon common;
JournalEditor({
const JournalEditor({
Key? key,
required this.note,
required this.noteModified,
@ -41,31 +41,31 @@ class JournalEditor extends StatefulWidget implements Editor {
@override
JournalEditorState createState() {
return JournalEditorState(note);
return JournalEditorState();
}
}
class JournalEditorState extends State<JournalEditor>
with DisposableChangeNotifier
implements EditorState {
Note note;
late Note _note;
late TextEditingController _textController;
late bool _noteModified;
late EditorHeuristics _heuristics;
JournalEditorState(this.note);
@override
void initState() {
super.initState();
_note = widget.note;
_noteModified = widget.noteModified;
_textController = buildController(
text: note.body,
text: _note.body,
highlightText: widget.highlightString,
theme: widget.theme,
);
_heuristics = EditorHeuristics(text: note.body);
_heuristics = EditorHeuristics(text: _note.body);
}
@override
@ -90,7 +90,7 @@ class JournalEditorState extends State<JournalEditor>
var editor = EditorScrollView(
child: Column(
children: <Widget>[
JournalEditorHeader(note),
JournalEditorHeader(_note),
NoteBodyEditor(
textController: _textController,
autofocus: widget.editMode,
@ -105,7 +105,7 @@ class JournalEditorState extends State<JournalEditor>
editorState: this,
noteModified: _noteModified,
editMode: widget.editMode,
parentFolder: note.parent,
parentFolder: _note.parent,
body: editor,
onUndoSelected: _undo,
onRedoSelected: _redo,
@ -116,11 +116,11 @@ class JournalEditorState extends State<JournalEditor>
@override
Note getNote() {
note.apply(
_note.apply(
body: _textController.text.trim(),
type: NoteType.Journal,
);
return note;
return _note;
}
void _noteTextChanged() {

View File

@ -35,7 +35,7 @@ class MarkdownEditor extends StatefulWidget implements Editor {
final String? highlightString;
final ThemeData theme;
MarkdownEditor({
const MarkdownEditor({
Key? key,
required this.note,
required this.parentFolder,
@ -48,14 +48,14 @@ class MarkdownEditor extends StatefulWidget implements Editor {
@override
MarkdownEditorState createState() {
return MarkdownEditorState(note);
return MarkdownEditorState();
}
}
class MarkdownEditorState extends State<MarkdownEditor>
with DisposableChangeNotifier
implements EditorState {
Note note;
late Note _note;
late TextEditingController _textController;
late TextEditingController _titleTextController;
@ -63,25 +63,24 @@ class MarkdownEditorState extends State<MarkdownEditor>
late bool _noteModified;
MarkdownEditorState(this.note);
@override
void initState() {
super.initState();
_note = widget.note;
_noteModified = widget.noteModified;
_textController = buildController(
text: note.body,
text: _note.body,
highlightText: widget.highlightString,
theme: widget.theme,
);
_titleTextController = buildController(
text: note.title,
text: _note.title,
highlightText: widget.highlightString,
theme: widget.theme,
);
_heuristics = EditorHeuristics(text: note.body);
_heuristics = EditorHeuristics(text: _note.body);
}
@override
@ -133,7 +132,7 @@ class MarkdownEditorState extends State<MarkdownEditor>
editorState: this,
noteModified: _noteModified,
editMode: widget.editMode,
parentFolder: note.parent,
parentFolder: _note.parent,
body: editor,
onUndoSelected: _undo,
onRedoSelected: _redo,
@ -144,7 +143,7 @@ class MarkdownEditorState extends State<MarkdownEditor>
}
void _updateNote() {
note.apply(
_note.apply(
body: _textController.text.trim(),
title: _titleTextController.text.trim(),
type: NoteType.Unknown,
@ -154,7 +153,7 @@ class MarkdownEditorState extends State<MarkdownEditor>
@override
Note getNote() {
_updateNote();
return note;
return _note;
}
void _noteTextChanged() {

View File

@ -20,9 +20,10 @@ import 'package:gitjournal/forks/icon_button_more_gestures.dart' as fork;
class MarkdownToolBar extends StatelessWidget {
final TextEditingController textController;
MarkdownToolBar({
const MarkdownToolBar({
Key? key,
required this.textController,
});
}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -63,9 +64,9 @@ class MarkdownToolBar extends StatelessWidget {
padding: const EdgeInsets.all(0.0),
onPressed: () => _modifyCurrentLine('- [ ] '),
),
Container(
const SizedBox(
height: 20,
child: const VerticalDivider(),
child: VerticalDivider(),
),
fork.IconButton(
icon: const Icon(Icons.navigate_before),
@ -135,8 +136,8 @@ final _allowedBlockTags = [
];
final _allowedBlockRegExps = [
RegExp('- \[[xX ]\] '),
RegExp('\d+\. '),
RegExp('- [[xX ]] '),
RegExp('d+. '),
];
TextEditingValue modifyCurrentLine(

View File

@ -15,11 +15,12 @@ class NoteBodyEditor extends StatelessWidget {
final bool autofocus;
final Function onChanged;
NoteBodyEditor({
const NoteBodyEditor({
Key? key,
required this.textController,
required this.autofocus,
required this.onChanged,
});
}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -17,7 +17,7 @@ class NoteEditorSelector extends StatelessWidget {
final EditorType currentEditor;
final NoteFileFormat fileFormat;
NoteEditorSelector(this.currentEditor, this.fileFormat);
const NoteEditorSelector(this.currentEditor, this.fileFormat);
@override
Widget build(BuildContext context) {

View File

@ -22,11 +22,13 @@ class NoteFileNameEditor extends StatefulWidget {
final String dirName;
NoteFileNameEditor({
Key? key,
required this.filePath,
required this.fs,
required this.onChanged,
}) : fileName = p.basename(filePath),
dirName = p.dirname(filePath);
dirName = p.dirname(filePath),
super(key: key);
@override
_NoteFileNameEditorState createState() => _NoteFileNameEditorState();

View File

@ -14,7 +14,7 @@ class NoteTitleEditor extends StatelessWidget {
final TextEditingController textController;
final Function onChanged;
NoteTitleEditor(this.textController, this.onChanged);
const NoteTitleEditor(this.textController, this.onChanged);
@override
Widget build(BuildContext context) {

View File

@ -30,7 +30,7 @@ class OrgEditor extends StatefulWidget implements Editor {
final String? highlightString;
final ThemeData theme;
OrgEditor({
const OrgEditor({
Key? key,
required this.note,
required this.noteModified,
@ -42,28 +42,27 @@ class OrgEditor extends StatefulWidget implements Editor {
@override
OrgEditorState createState() {
return OrgEditorState(note);
return OrgEditorState();
}
}
class OrgEditorState extends State<OrgEditor>
with DisposableChangeNotifier
implements EditorState {
Note note;
late Note _note;
late bool _noteModified;
late TextEditingController _textController;
late UndoRedoStack _undoRedoStack;
final serializer = MarkdownYAMLCodec();
OrgEditorState(this.note);
@override
void initState() {
super.initState();
_note = widget.note;
_noteModified = widget.noteModified;
_textController = buildController(
text: serializer.encode(note.data),
text: serializer.encode(_note.data),
highlightText: widget.highlightString,
theme: widget.theme,
);
@ -102,7 +101,7 @@ class OrgEditorState extends State<OrgEditor>
editorState: this,
noteModified: _noteModified,
editMode: widget.editMode,
parentFolder: note.parent,
parentFolder: _note.parent,
body: editor,
onUndoSelected: _undo,
onRedoSelected: _redo,
@ -113,8 +112,8 @@ class OrgEditorState extends State<OrgEditor>
@override
Note getNote() {
note.data = serializer.decode(_textController.text);
return note;
_note.data = serializer.decode(_textController.text);
return _note;
}
void _noteTextChanged() {
@ -169,7 +168,7 @@ class _NoteEditor extends StatelessWidget {
final bool autofocus;
final Function onChanged;
_NoteEditor({
const _NoteEditor({
required this.textController,
required this.autofocus,
required this.onChanged,

View File

@ -36,7 +36,7 @@ class RawEditor extends StatefulWidget implements Editor {
final String? highlightString;
final ThemeData theme;
RawEditor({
const RawEditor({
Key? key,
required this.note,
required this.noteModified,
@ -48,29 +48,28 @@ class RawEditor extends StatefulWidget implements Editor {
@override
RawEditorState createState() {
return RawEditorState(note);
return RawEditorState();
}
}
class RawEditorState extends State<RawEditor>
with DisposableChangeNotifier
implements EditorState {
Note note;
late Note _note;
late bool _noteModified;
late TextEditingController _textController;
late UndoRedoStack _undoRedoStack;
final serializer = MarkdownYAMLCodec();
RawEditorState(this.note);
@override
void initState() {
super.initState();
_note = widget.note;
_noteModified = widget.noteModified;
_textController = buildController(
text: serializer.encode(note.data),
text: serializer.encode(_note.data),
highlightText: widget.highlightString,
theme: widget.theme,
);
@ -110,7 +109,7 @@ class RawEditorState extends State<RawEditor>
editorState: this,
noteModified: _noteModified,
editMode: widget.editMode,
parentFolder: note.parent,
parentFolder: _note.parent,
body: editor,
onUndoSelected: _undo,
onRedoSelected: _redo,
@ -121,8 +120,8 @@ class RawEditorState extends State<RawEditor>
@override
Note getNote() {
note.data = serializer.decode(_textController.text);
return note;
_note.data = serializer.decode(_textController.text);
return _note;
}
void _noteTextChanged() {
@ -177,7 +176,7 @@ class _NoteEditor extends StatefulWidget {
final bool autofocus;
final Function onChanged;
_NoteEditor({
const _NoteEditor({
required this.textController,
required this.autofocus,
required this.onChanged,
@ -231,8 +230,9 @@ class _NoteEditorState extends State<_NoteEditor> {
}
final rootFolder = Provider.of<NotesFolderFS>(context, listen: false);
var inlineTagsView = InlineTagsProvider.of(context);
var futureBuilder = () async {
final inlineTagsView = InlineTagsProvider.of(context);
futureBuilder() async {
var allTags = await rootFolder.getNoteTagsRecursively(inlineTagsView);
Log.d("Building autocompleter with $allTags");
@ -244,7 +244,7 @@ class _NoteEditorState extends State<_NoteEditor> {
child: textField,
tags: allTags.toList(),
);
};
}
return FutureBuilderWithProgress(future: futureBuilder());
}

View File

@ -35,7 +35,7 @@ class EditorScaffold extends StatefulWidget {
final Widget? extraBottomWidget;
EditorScaffold({
const EditorScaffold({
required this.editor,
required this.editorState,
required this.noteModified,
@ -196,7 +196,8 @@ class _AnimatedOpacityIgnorePointer extends StatelessWidget {
final bool visible;
final Widget child;
_AnimatedOpacityIgnorePointer({required this.visible, required this.child});
const _AnimatedOpacityIgnorePointer(
{required this.visible, required this.child});
@override
Widget build(BuildContext context) {

View File

@ -18,7 +18,7 @@ import 'package:gitjournal/editors/common.dart';
// be just taken from this class
//
class UndoRedoStack {
var _versions = <TextEditorState>[];
final _versions = <TextEditorState>[];
int _index = -1;
/// Returns if UI should be redrawn

View File

@ -18,13 +18,13 @@ class MyApp extends StatelessWidget {
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'AutoCompleter'),
home: const MyHomePage(title: 'AutoCompleter'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title}) : super(key: key);
const MyHomePage({Key? key, this.title}) : super(key: key);
final String? title;
@ -33,9 +33,9 @@ class MyHomePage extends StatefulWidget {
}
class _MyHomePageState extends State<MyHomePage> {
FocusNode _focusNode = FocusNode();
GlobalKey _textFieldKey = GlobalKey();
TextStyle _textFieldStyle = const TextStyle(fontSize: 20);
final FocusNode _focusNode = FocusNode();
final GlobalKey _textFieldKey = GlobalKey();
final TextStyle _textFieldStyle = const TextStyle(fontSize: 20);
TextEditingController? _textController;
@ -62,7 +62,7 @@ class _MyHomePageState extends State<MyHomePage> {
textFieldFocusNode: _focusNode,
textController: _textController!,
child: textField,
tags: ['Hello', 'Howdy', 'Pooper'],
tags: const ['Hello', 'Howdy', 'Pooper'],
);
return Scaffold(
appBar: AppBar(
@ -70,7 +70,7 @@ class _MyHomePageState extends State<MyHomePage> {
),
body: Center(
child: SingleChildScrollView(
child: Container(
child: SizedBox(
child: textField,
width: 400.0,
),

View File

@ -24,7 +24,7 @@ class CardView extends StatelessWidget {
final String searchTerm;
CardView({
const CardView({
required this.folder,
required this.noteTapped,
required this.noteLongPressed,

View File

@ -131,7 +131,7 @@ bool openNewNoteEditor(BuildContext context, String noteSpec) {
defaultEditor,
newNoteFileName: fileName,
existingText: "",
existingImages: [],
existingImages: const [],
),
AppRoute.NewNotePrefix + folderConfig.defaultEditor.toInternalString(),
);

View File

@ -45,7 +45,7 @@ class FolderView extends StatefulWidget {
final NotesFolder notesFolder;
final Map<String, dynamic> newNoteExtraProps;
FolderView({
const FolderView({
required this.notesFolder,
this.newNoteExtraProps = const {},
});
@ -250,7 +250,7 @@ class _FolderViewState extends State<FolderView> {
editorType,
newNoteExtraProps: extraProps,
existingText: "",
existingImages: [],
existingImages: const [],
),
AppRoute.NewNotePrefix + routeType,
);
@ -281,7 +281,7 @@ class _FolderViewState extends State<FolderView> {
await showDialog<SortingMode>(
context: context,
builder: (BuildContext context) {
var headerTypeChanged = (StandardViewHeader? newHeader) {
void headerTypeChanged(StandardViewHeader? newHeader) {
if (newHeader == null) {
return;
}
@ -292,9 +292,9 @@ class _FolderViewState extends State<FolderView> {
var folderConfig = sortedNotesFolder.config;
folderConfig.viewHeader = _headerType;
folderConfig.save();
};
}
var summaryChanged = (bool newVal) {
void summaryChanged(bool newVal) {
setState(() {
_showSummary = newVal;
});
@ -302,7 +302,7 @@ class _FolderViewState extends State<FolderView> {
var folderConfig = sortedNotesFolder.config;
folderConfig.showNoteSummary = newVal;
folderConfig.save();
};
}
return StatefulBuilder(
builder: (BuildContext context, Function setState) {
@ -383,7 +383,7 @@ class _FolderViewState extends State<FolderView> {
}
void _folderViewChooserSelected() async {
var onViewChange = (FolderViewType? vt) => Navigator.of(context).pop(vt);
void onViewChange(FolderViewType? vt) => Navigator.of(context).pop(vt);
var newViewType = await showDialog<FolderViewType>(
context: context,

View File

@ -20,7 +20,7 @@ class GridFolderView extends StatelessWidget {
final String searchTerm;
GridFolderView({
const GridFolderView({
required this.folder,
required this.noteTapped,
required this.noteLongPressed,

View File

@ -114,7 +114,7 @@ class JournalView extends StatelessWidget {
);
var dc = Theme.of(context).dividerColor;
var divider = Container(
var divider = SizedBox(
height: 1.0,
child: Divider(color: dc.withOpacity(dc.opacity / 3)),
);

View File

@ -17,7 +17,7 @@ import 'package:gitjournal/utils/utils.dart';
import 'package:gitjournal/widgets/icon_dismissable.dart';
import 'empty_text_sliver.dart';
typedef Widget NoteTileBuilder(BuildContext context, Note note);
typedef NoteTileBuilder = Widget Function(BuildContext context, Note note);
class FolderListView extends StatefulWidget {
final NoteTileBuilder noteTileBuilder;
@ -26,20 +26,21 @@ class FolderListView extends StatefulWidget {
final String emptyText;
final String searchTerm;
FolderListView({
const FolderListView({
required this.folder,
required this.noteTileBuilder,
required this.emptyText,
required this.isNoteSelected,
required this.searchTerm,
});
Key? key,
}) : super(key: key);
@override
_FolderListViewState createState() => _FolderListViewState();
}
class _FolderListViewState extends State<FolderListView> {
var _listKey = GlobalKey<AnimatedListState>();
final _listKey = GlobalKey<AnimatedListState>();
var deletedViaDismissed = <String>[];
@override

View File

@ -159,7 +159,7 @@ class StandardView extends StatelessWidget {
}
var dc = Theme.of(context).dividerColor;
var divider = Container(
var divider = SizedBox(
height: 1.0,
child: Divider(color: dc.withOpacity(dc.opacity / 3)),
);

View File

@ -248,6 +248,8 @@ abstract class LocaleKeys {
'settings.noteMetaData.customMetaData.invalid';
static const settings_noteMetaData_customMetaData =
'settings.noteMetaData.customMetaData';
static const settings_noteMetaData_output = 'settings.noteMetaData.output';
static const settings_noteMetaData_input = 'settings.noteMetaData.input';
static const settings_noteMetaData = 'settings.noteMetaData';
static const settings_privacy = 'settings.privacy';
static const settings_terms = 'settings.terms';

View File

@ -23,7 +23,7 @@ typedef PurchaseCallback = void Function(String, SubscriptionStatus?);
class PurchaseManager {
late InAppPurchaseConnection con;
late StreamSubscription<List<PurchaseDetails>> _subscription;
List<PurchaseCallback> _callbacks = [];
final List<PurchaseCallback> _callbacks = [];
static String? error;
static PurchaseManager? _instance;

View File

@ -105,7 +105,7 @@ class _PurchaseScreenState extends State<PurchaseScreen> {
padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 16.0),
child: Wrap(
children: [
RestorePurchaseButton(),
const RestorePurchaseButton(),
OutlinedButton(
child: Text(
tr(LocaleKeys.feature_timeline_title),
@ -113,7 +113,7 @@ class _PurchaseScreenState extends State<PurchaseScreen> {
),
onPressed: () {
var route = MaterialPageRoute(
builder: (context) => FeatureTimelineScreen(),
builder: (context) => const FeatureTimelineScreen(),
settings: const RouteSettings(name: '/featureTimeline'),
);
Navigator.of(context).push(route);
@ -219,13 +219,13 @@ class YearlyPurchaseWidget extends StatelessWidget {
class PurchaseCard extends StatelessWidget {
final Widget child;
PurchaseCard({required this.child});
const PurchaseCard({required this.child});
@override
Widget build(BuildContext context) {
var mediaQuery = MediaQuery.of(context);
return Container(
return SizedBox(
width: mediaQuery.size.width * 0.80,
child: Card(
shape: RoundedRectangleBorder(
@ -243,7 +243,7 @@ class PurchaseCard extends StatelessWidget {
class PurchaseCards extends StatelessWidget {
final List<Widget> children;
PurchaseCards({required this.children});
const PurchaseCards({required this.children});
@override
Widget build(BuildContext context) {

View File

@ -16,7 +16,8 @@ class PaymentInfo extends Equatable {
final String text;
final String id;
PaymentInfo({required this.id, required this.value, required this.text});
const PaymentInfo(
{required this.id, required this.value, required this.text});
@override
List<Object> get props => [value, text, id];
@ -54,7 +55,7 @@ class PurchaseSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
return SizedBox(
height: 50,
child: CustomPaint(
painter: ShapePainter(

View File

@ -28,13 +28,14 @@ class PurchaseButton extends StatelessWidget {
final Func1<bool, void> purchaseStarted;
final PurchaseCallback purchaseCompleted;
PurchaseButton(
const PurchaseButton(
this.product,
this.timePeriod, {
Key? key,
required this.subscription,
required this.purchaseStarted,
required this.purchaseCompleted,
});
}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -104,12 +105,13 @@ class PurchaseWidget extends StatefulWidget {
final String timePeriod;
final bool isSubscription;
PurchaseWidget({
const PurchaseWidget({
Key? key,
required this.skus,
required this.defaultSku,
this.timePeriod = "",
required this.isSubscription,
});
}) : super(key: key);
@override
_PurchaseWidgetState createState() => _PurchaseWidgetState();
@ -293,7 +295,7 @@ class _PurchaseSliderButton extends StatelessWidget {
final Widget icon;
final void Function() onPressed;
_PurchaseSliderButton({required this.icon, required this.onPressed});
const _PurchaseSliderButton({required this.icon, required this.onPressed});
@override
Widget build(BuildContext context) {
@ -309,7 +311,7 @@ class _PurchaseSliderButton extends StatelessWidget {
class PurchaseFailedDialog extends StatelessWidget {
final String text;
PurchaseFailedDialog(this.text);
const PurchaseFailedDialog(this.text, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -327,6 +329,8 @@ class PurchaseFailedDialog extends StatelessWidget {
}
class RestorePurchaseButton extends StatefulWidget {
const RestorePurchaseButton({Key? key}) : super(key: key);
@override
_RestorePurchaseButtonState createState() => _RestorePurchaseButtonState();
}

View File

@ -19,12 +19,14 @@ import 'package:gitjournal/settings/app_settings.dart';
import 'package:gitjournal/utils/utils.dart';
class DebugScreen extends StatefulWidget {
const DebugScreen({Key? key}) : super(key: key);
@override
_DebugScreenState createState() => _DebugScreenState();
}
class _DebugScreenState extends State<DebugScreen> {
ScrollController _controller = ScrollController();
final ScrollController _controller = ScrollController();
late List<LogMessage> _logs;
@ -323,7 +325,12 @@ class FilterListTile extends StatelessWidget {
final String internalLevel;
final String currentLevel;
FilterListTile(this.publicLevel, this.internalLevel, this.currentLevel);
const FilterListTile(
this.publicLevel,
this.internalLevel,
this.currentLevel, {
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -32,7 +32,7 @@ class _DebugScreenFakeState extends State<DebugScreenFake> {
@override
Widget build(BuildContext context) {
return DebugScreen();
return const DebugScreen();
}
}

View File

@ -144,7 +144,7 @@ class Log {
t: DateTime.now().millisecondsSinceEpoch,
l: level,
msg: msg.replaceAll('\n', ' '),
ex: ex != null ? ex.toString().replaceAll('\n', ' ') : null,
ex: ex?.toString().replaceAll('\n', ' '),
props: props,
);
if (stackTrace != null) {

View File

@ -20,7 +20,7 @@ import 'package:markdown/markdown.dart' as md;
// Alternatively, \begin{math} and \end{math} can be used.
class MathJaxInlineSyntax extends md.InlineSyntax {
static final String _pattern = r'\\(.*\\)';
static const String _pattern = r'\\(.*\\)';
MathJaxInlineSyntax() : super(_pattern);

View File

@ -196,7 +196,7 @@ class GitJournalRepo with ChangeNotifier {
await _notesCache.buildCache(notesFolder);
var changes = await _gitRepo.numChanges();
numChanges = changes != null ? changes : 0;
numChanges = changes ?? 0;
notifyListeners();
});
}

View File

@ -15,6 +15,8 @@ import 'package:gitjournal/features.dart';
import 'package:gitjournal/generated/locale_keys.g.dart';
class FeatureTimelineScreen extends StatelessWidget {
const FeatureTimelineScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
@ -50,7 +52,7 @@ class FeatureTimelineScreen extends StatelessWidget {
class FeatureTile extends StatelessWidget {
final Feature feature;
FeatureTile(this.feature);
const FeatureTile(this.feature, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -84,7 +86,7 @@ class _Tile extends StatelessWidget {
final String iconText;
final Color iconColor;
_Tile({
const _Tile({
required this.title,
required this.subTitle,
required this.iconText,
@ -107,7 +109,7 @@ class _Tile extends StatelessWidget {
),
child: Row(
children: <Widget>[
Container(
SizedBox(
width: 56.0,
child: _Sign(iconText, iconColor),
),
@ -142,7 +144,7 @@ class _Sign extends StatelessWidget {
final String text;
final Color? color;
_Sign(this.text, this.color);
const _Sign(this.text, this.color);
@override
Widget build(BuildContext context) {

View File

@ -7,6 +7,7 @@
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:gitjournal/core/notes_folder.dart';
import 'package:provider/provider.dart';
import 'package:gitjournal/core/flattened_notes_folder.dart';
@ -40,7 +41,7 @@ class _FolderListingScreenState extends State<FolderListingScreen> {
key: _folderTreeViewKey,
rootFolder: notesFolder,
onFolderEntered: (NotesFolderFS folder) {
var destination;
late NotesFolder destination;
if (settings.experimentalSubfolders) {
destination = FlattenedNotesFolder(folder, title: folder.name);
} else {
@ -245,7 +246,7 @@ class _CreateFolderAlertDialogState extends State<CreateFolderAlertDialog> {
class FolderErrorDialog extends StatelessWidget {
final String content;
FolderErrorDialog(this.content);
const FolderErrorDialog(this.content);
@override
Widget build(BuildContext context) {

View File

@ -13,6 +13,8 @@ import 'package:gitjournal/core/notes_folder_fs.dart';
import 'package:gitjournal/core/views/note_links_view.dart';
class GraphViewScreen extends StatefulWidget {
const GraphViewScreen({Key? key}) : super(key: key);
@override
_GraphViewScreenState createState() => _GraphViewScreenState();
}
@ -30,7 +32,7 @@ class _GraphViewScreenState extends State<GraphViewScreen> {
graph = Graph.fromFolder(rootFolder, linksProvider);
graph!.addListener(_setState);
});
return Container(width: 2500, height: 2500);
return const SizedBox(width: 2500, height: 2500);
}
return SafeArea(child: graph != null ? GraphView(graph!) : Container());
@ -56,7 +58,7 @@ class _GraphViewScreenState extends State<GraphViewScreen> {
class GraphView extends StatefulWidget {
final Graph graph;
GraphView(this.graph);
const GraphView(this.graph);
@override
_GraphViewState createState() => _GraphViewState();
@ -195,7 +197,7 @@ class NodeWidget extends StatelessWidget {
final Node node;
final double size;
NodeWidget(this.node, this.size);
const NodeWidget(this.node, this.size);
@override
Widget build(BuildContext context) {

View File

@ -66,7 +66,7 @@ class NoteEditor extends StatefulWidget {
newNoteFileName = null,
newNoteExtraProps = null;
NoteEditor.newNote(
const NoteEditor.newNote(
this.notesFolder,
this.parentFolderView,
this.defaultEditorType, {

View File

@ -18,7 +18,7 @@ import 'package:gitjournal/analytics/analytics.dart';
import 'package:gitjournal/settings/app_settings.dart';
class OnBoardingScreen extends StatefulWidget {
OnBoardingScreen();
const OnBoardingScreen();
@override
OnBoardingScreenState createState() {
@ -159,7 +159,7 @@ class OnBoardingBottomButton extends StatelessWidget {
final Func0<void> onPressed;
final String text;
OnBoardingBottomButton({
const OnBoardingBottomButton({
Key? key,
required this.text,
required this.onPressed,
@ -202,21 +202,19 @@ class OnBoardingPage1 extends StatelessWidget {
],
);
return Container(
child: Column(
children: <Widget>[
Center(child: header),
const SizedBox(height: 64.0),
AutoSizeText(
tr("OnBoarding.subtitle"),
style: textTheme.headline5,
textAlign: TextAlign.center,
maxLines: 2,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
return Column(
children: <Widget>[
Center(child: header),
const SizedBox(height: 64.0),
AutoSizeText(
tr("OnBoarding.subtitle"),
style: textTheme.headline5,
textAlign: TextAlign.center,
maxLines: 2,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
);
}
}
@ -238,21 +236,19 @@ class OnBoardingPage2 extends StatelessWidget {
],
);
return Container(
child: Column(
children: <Widget>[
Center(child: header),
const SizedBox(height: 64.0),
AutoSizeText(
tr("OnBoarding.page2"),
style: textTheme.headline5,
textAlign: TextAlign.center,
maxLines: 3,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
return Column(
children: <Widget>[
Center(child: header),
const SizedBox(height: 64.0),
AutoSizeText(
tr("OnBoarding.page2"),
style: textTheme.headline5,
textAlign: TextAlign.center,
maxLines: 3,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
);
}
}
@ -274,21 +270,19 @@ class OnBoardingPage3 extends StatelessWidget {
],
);
return Container(
child: Column(
children: <Widget>[
Center(child: header),
const SizedBox(height: 64.0),
AutoSizeText(
tr("OnBoarding.page3"),
style: textTheme.headline5,
textAlign: TextAlign.center,
maxLines: 2,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
),
return Column(
children: <Widget>[
Center(child: header),
const SizedBox(height: 64.0),
AutoSizeText(
tr("OnBoarding.page3"),
style: textTheme.headline5,
textAlign: TextAlign.center,
maxLines: 2,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
);
}
}

View File

@ -29,4 +29,4 @@ Widget page3() {
);
}
Widget all() => OnBoardingScreen();
Widget all() => const OnBoardingScreen();

View File

@ -27,6 +27,8 @@ import 'package:gitjournal/widgets/future_builder_with_progress.dart';
import 'package:gitjournal/widgets/pro_overlay.dart';
class TagListingScreen extends StatelessWidget {
const TagListingScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
var rootFolder = Provider.of<NotesFolderFS>(context);

View File

@ -71,7 +71,7 @@ class _BottomMenuBarSettingsState extends State<BottomMenuBarSettings> {
child: Container(
padding: const EdgeInsets.all(2.0),
color: theme.colorScheme.secondary.withAlpha(256 ~/ 10),
child: Container(
child: SizedBox(
width: mq.size.width,
height: mq.size.height,
child: IgnorePointer(child: HomeScreen()),

View File

@ -73,19 +73,20 @@ class SettingsDisplayImagesScreenState
activeColor: theme.colorScheme.secondary,
inactiveColor: theme.disabledColor,
)),
Container(
width: 40,
child: settings.maxImageZoom == double.infinity
? Icon(
Icons.all_inclusive,
color: theme.colorScheme.secondary,
)
: Text(
NumberFormat("##.0").format(settings.maxImageZoom),
style: theme.textTheme.subtitle2!
.copyWith(color: theme.colorScheme.secondary),
textAlign: TextAlign.center,
))
SizedBox(
width: 40,
child: settings.maxImageZoom == double.infinity
? Icon(
Icons.all_inclusive,
color: theme.colorScheme.secondary,
)
: Text(
NumberFormat("##.0").format(settings.maxImageZoom),
style: theme.textTheme.subtitle2!
.copyWith(color: theme.colorScheme.secondary),
textAlign: TextAlign.center,
),
)
])),
SwitchListTile(
title: Text(

View File

@ -29,13 +29,14 @@ class SettingsDisplayImagesCaptionScreenState
@override
Widget build(BuildContext context) {
var settings = Provider.of<MarkdownRendererConfig>(context);
var saveDoNotCaptionTag = (String? doNotCaptionTags) {
void saveDoNotCaptionTag(String? doNotCaptionTags) {
if (doNotCaptionTags == null) {
return;
}
settings.doNotCaptionTags = parseTags(doNotCaptionTags);
settings.save();
};
}
var doNotCaptionTagsForm = Form(
child: TextFormField(
key: doNotCaptionTagsKey,

View File

@ -31,10 +31,11 @@ class SettingsDisplayImagesThemingScreenState
Widget build(BuildContext context) {
var settings = Provider.of<MarkdownRendererConfig>(context);
var saveDoNotThemeTag = (String? doNotThemeTags) {
void saveDoNotThemeTag(String? doNotThemeTags) {
settings.doNotThemeTags = parseTags(doNotThemeTags!);
settings.save();
};
}
var doNotThemeTagsForm = Form(
child: TextFormField(
key: doNotThemeTagsKey,
@ -70,10 +71,11 @@ class SettingsDisplayImagesThemingScreenState
},
);
var saveDoThemeTag = (String? doThemeTags) {
void saveDoThemeTag(String? doThemeTags) {
settings.doThemeTags = parseTags(doThemeTags!);
settings.save();
};
}
var doThemeTagsForm = Form(
child: TextFormField(
key: doThemeTagsKey,

View File

@ -141,16 +141,16 @@ class _PasswordForm extends StatelessWidget {
onChanged: (String value) {
value = value.trim();
if (value.isEmpty) {
return null;
return;
}
final salt = 'randomSaltGitJournal';
const salt = 'randomSaltGitJournal';
var sha1Digest = sha1.convert(utf8.encode(value + salt));
print(sha1Digest);
if (sha1Digest.toString() !=
'27538d8231e49655fd1c26c7b8495c2c870c741b') {
return null;
return;
}
print('Unlocking Pro Mode');

View File

@ -254,7 +254,7 @@ class Button extends StatelessWidget {
final String text;
final void Function() onPressed;
Button({required this.text, required this.onPressed});
const Button({required this.text, required this.onPressed});
@override
Widget build(BuildContext context) {
@ -280,7 +280,7 @@ class RedButton extends StatelessWidget {
final String text;
final void Function() onPressed;
RedButton({required this.text, required this.onPressed});
const RedButton({required this.text, required this.onPressed});
@override
Widget build(BuildContext context) {
@ -304,7 +304,7 @@ class RedButton extends StatelessWidget {
class IrreversibleActionConfirmationDialog extends StatelessWidget {
final String title;
IrreversibleActionConfirmationDialog(this.title);
const IrreversibleActionConfirmationDialog(this.title);
@override
Widget build(BuildContext context) {

View File

@ -22,12 +22,12 @@ class GitAuthorEmail extends StatelessWidget {
Widget build(BuildContext context) {
var gitConfig = Provider.of<GitConfig>(context);
var saveGitAuthorEmail = (String? gitAuthorEmail) {
void saveGitAuthorEmail(String? gitAuthorEmail) {
if (gitAuthorEmail == null) return;
gitConfig.gitAuthorEmail = gitAuthorEmail;
gitConfig.save();
};
}
return Form(
child: TextFormField(
@ -73,11 +73,11 @@ class GitAuthor extends StatelessWidget {
Widget build(BuildContext context) {
var gitConfig = Provider.of<GitConfig>(context);
var saveGitAuthor = (String? gitAuthor) {
void saveGitAuthor(String? gitAuthor) {
if (gitAuthor == null) return;
gitConfig.gitAuthor = gitAuthor;
gitConfig.save();
};
}
return Form(
child: TextFormField(

View File

@ -8,6 +8,7 @@ import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:function_types/function_types.dart';
import 'package:gitjournal/generated/locale_keys.g.dart';
import 'package:provider/provider.dart';
import 'package:time/time.dart';
@ -105,7 +106,7 @@ class _NoteMetadataSettingsScreenState
),
ListPreference(
title: tr("settings.noteMetaData.modified"),
options: [
options: const [
"modified",
"mod",
"lastmodified",
@ -123,7 +124,7 @@ class _NoteMetadataSettingsScreenState
),
ListPreference(
title: tr("settings.noteMetaData.created"),
options: [
options: const [
"created",
"date",
],
@ -138,7 +139,7 @@ class _NoteMetadataSettingsScreenState
),
ListPreference(
title: tr("settings.noteMetaData.tags"),
options: [
options: const [
"tags",
"categories",
"keywords",
@ -197,7 +198,7 @@ class _NoteMetadataSettingsScreenState
class NoteOutputExample extends StatelessWidget {
final Note note;
NoteOutputExample(this.note);
const NoteOutputExample(this.note);
@override
Widget build(BuildContext context) {
@ -222,7 +223,10 @@ class NoteOutputExample extends StatelessWidget {
child: Text(noteStr, style: style),
),
_HeaderText(note.fileName, Alignment.topRight),
_HeaderText("Output", Alignment.topLeft),
_HeaderText(
LocaleKeys.settings_noteMetaData_output.tr(),
Alignment.topLeft,
),
],
),
);
@ -232,7 +236,7 @@ class NoteOutputExample extends StatelessWidget {
class NoteInputExample extends StatelessWidget {
final Note note;
NoteInputExample(this.note);
const NoteInputExample(this.note);
@override
Widget build(BuildContext context) {
@ -263,7 +267,10 @@ class NoteInputExample extends StatelessWidget {
),
),
_HeaderText(note.fileName, Alignment.topRight),
_HeaderText("Input", Alignment.topLeft),
_HeaderText(
LocaleKeys.settings_noteMetaData_input.tr(),
Alignment.topLeft,
),
],
),
),
@ -275,7 +282,7 @@ class _HeaderText extends StatelessWidget {
final String text;
final Alignment alignment;
_HeaderText(this.text, this.alignment);
const _HeaderText(this.text, this.alignment);
@override
Widget build(BuildContext context) {
@ -296,7 +303,7 @@ class _HeaderText extends StatelessWidget {
class _Tag extends StatelessWidget {
final String text;
_Tag(this.text);
const _Tag(this.text);
@override
Widget build(BuildContext context) {
@ -306,8 +313,8 @@ class _Tag extends StatelessWidget {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: theme.scaffoldBackgroundColor,
boxShadow: [
const BoxShadow(color: Colors.grey, spreadRadius: 1),
boxShadow: const [
BoxShadow(color: Colors.grey, spreadRadius: 1),
],
),
padding: const EdgeInsets.all(8.0),
@ -319,7 +326,7 @@ class _Tag extends StatelessWidget {
class TagsWidget extends StatelessWidget {
final Set<String> tags;
TagsWidget(this.tags);
const TagsWidget(this.tags);
@override
Widget build(BuildContext context) {
@ -338,7 +345,7 @@ class CustomMetDataTile extends StatefulWidget {
final String value;
final Func1<String, void> onChange;
CustomMetDataTile({required this.value, required this.onChange});
const CustomMetDataTile({required this.value, required this.onChange});
@override
_CustomMetDataTileState createState() => _CustomMetDataTileState();

View File

@ -229,7 +229,7 @@ class SettingsListState extends State<SettingsList> {
subtitle: Text(tr(LocaleKeys.settings_tags_subtitle)),
onTap: () {
var route = MaterialPageRoute(
builder: (context) => SettingsTagsScreen(),
builder: (context) => const SettingsTagsScreen(),
settings: const RouteSettings(name: '/settings/tags'),
);
Navigator.of(context).push(route);
@ -359,7 +359,7 @@ class SettingsListState extends State<SettingsList> {
title: Text(tr(LocaleKeys.feature_timeline_title)),
onTap: () {
var route = MaterialPageRoute(
builder: (context) => FeatureTimelineScreen(),
builder: (context) => const FeatureTimelineScreen(),
settings: const RouteSettings(name: '/featureTimeline'),
);
Navigator.of(context).push(route);
@ -389,13 +389,13 @@ class SettingsListState extends State<SettingsList> {
);
},
),
VersionNumberTile(),
const VersionNumberTile(),
ListTile(
title: Text(tr(LocaleKeys.settings_debug_title)),
subtitle: Text(tr(LocaleKeys.settings_debug_subtitle)),
onTap: () {
var route = MaterialPageRoute(
builder: (context) => DebugScreen(),
builder: (context) => const DebugScreen(),
settings: const RouteSettings(name: '/settings/debug'),
);
Navigator.of(context).push(route);
@ -430,7 +430,7 @@ class SettingsListState extends State<SettingsList> {
class SettingsHeader extends StatelessWidget {
final String text;
SettingsHeader(this.text);
const SettingsHeader(this.text);
@override
Widget build(BuildContext context) {
@ -448,6 +448,8 @@ class SettingsHeader extends StatelessWidget {
}
class VersionNumberTile extends StatefulWidget {
const VersionNumberTile({Key? key}) : super(key: key);
@override
VersionNumberTileState createState() {
return VersionNumberTileState();

View File

@ -13,6 +13,8 @@ import 'package:gitjournal/core/notes_folder_config.dart';
import 'package:gitjournal/settings/settings_screen.dart';
class SettingsTagsScreen extends StatefulWidget {
const SettingsTagsScreen({Key? key}) : super(key: key);
@override
SettingsTagsScreenState createState() => SettingsTagsScreenState();
}

View File

@ -17,13 +17,14 @@ class ListPreference extends StatelessWidget {
final Function onChange;
final bool enabled;
ListPreference({
const ListPreference({
required this.title,
required this.currentOption,
required this.options,
required this.onChange,
this.enabled = true,
});
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -25,10 +25,11 @@ class GitHostSetupAutoConfigurePage extends StatefulWidget {
final GitHostType gitHostType;
final Func2<GitHost?, UserInfo?, void> onDone;
GitHostSetupAutoConfigurePage({
const GitHostSetupAutoConfigurePage({
required this.gitHostType,
required this.onDone,
});
Key? key,
}) : super(key: key);
@override
GitHostSetupAutoConfigurePageState createState() {

View File

@ -16,11 +16,12 @@ class GitHostSetupButton extends StatelessWidget {
final String text;
final String? iconUrl;
GitHostSetupButton({
const GitHostSetupButton({
required this.text,
required this.onPressed,
this.iconUrl,
});
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -6,7 +6,7 @@
import 'package:universal_io/io.dart' show Platform;
import 'clone_gitExec.dart' as git_exec;
import 'clone_git_exec.dart' as git_exec;
import 'clone_libgit2.dart' as libgit2;
final isMobileApp = Platform.isIOS || Platform.isAndroid;

View File

@ -19,10 +19,11 @@ class GitCloneUrlPage extends StatefulWidget {
final Func1<String, void> doneFunction;
final String initialValue;
GitCloneUrlPage({
const GitCloneUrlPage({
required this.doneFunction,
required this.initialValue,
});
Key? key,
}) : super(key: key);
@override
GitCloneUrlPageState createState() {
@ -39,7 +40,7 @@ class GitCloneUrlPageState extends State<GitCloneUrlPage> {
@override
Widget build(BuildContext context) {
final formSubmitted = () {
void formSubmitted() {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
@ -47,7 +48,7 @@ class GitCloneUrlPageState extends State<GitCloneUrlPage> {
widget.doneFunction(url.trim());
inputFormFocus.unfocus();
}
};
}
var inputForm = Form(
key: _formKey,
@ -100,12 +101,13 @@ class GitCloneUrlKnownProviderPage extends StatefulWidget {
final GitHostType gitHostType;
final String initialValue;
GitCloneUrlKnownProviderPage({
const GitCloneUrlKnownProviderPage({
required this.doneFunction,
required this.launchCreateUrlPage,
required this.gitHostType,
required this.initialValue,
});
Key? key,
}) : super(key: key);
@override
GitCloneUrlKnownProviderPageState createState() {

View File

@ -22,7 +22,9 @@ class GitHostCloningPage extends StatelessWidget {
GitHostCloningPage({
required this.errorMessage,
required this.cloneProgress,
}) : loadingMessage = tr(LocaleKeys.setup_cloning);
Key? key,
}) : loadingMessage = tr(LocaleKeys.setup_cloning),
super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -11,7 +11,7 @@ import 'package:easy_localization/easy_localization.dart';
class GitHostSetupErrorPage extends StatelessWidget {
final String errorMessage;
GitHostSetupErrorPage(this.errorMessage);
const GitHostSetupErrorPage(this.errorMessage);
@override
Widget build(BuildContext context) {

View File

@ -16,7 +16,7 @@ class PublicKeyEditor extends StatelessWidget {
final Key formKey;
final TextEditingController _controller;
PublicKeyEditor(this.formKey, this._controller);
const PublicKeyEditor(this.formKey, this._controller);
@override
Widget build(BuildContext context) {
@ -40,7 +40,7 @@ class PrivateKeyEditor extends StatelessWidget {
final Key formKey;
final TextEditingController _controller;
PrivateKeyEditor(this.formKey, this._controller);
const PrivateKeyEditor(this.formKey, this._controller);
@override
Widget build(BuildContext context) {
@ -69,7 +69,7 @@ class KeyEditor extends StatelessWidget {
final TextEditingController textEditingController;
final String? Function(String?) validator;
KeyEditor(this.formKey, this.textEditingController, this.validator);
const KeyEditor(this.formKey, this.textEditingController, this.validator);
@override
Widget build(BuildContext context) {

View File

@ -8,7 +8,7 @@ import 'package:flutter/material.dart';
class GitHostSetupLoadingPage extends StatelessWidget {
final String text;
GitHostSetupLoadingPage(this.text);
const GitHostSetupLoadingPage(this.text, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -13,7 +13,7 @@ class GitHostSetupLoadingErrorPage extends StatelessWidget {
final String? errorMessage;
final String loadingMessage;
GitHostSetupLoadingErrorPage({
const GitHostSetupLoadingErrorPage({
required this.errorMessage,
required this.loadingMessage,
});

View File

@ -30,11 +30,12 @@ class GitHostSetupRepoSelector extends StatefulWidget {
final UserInfo userInfo;
final Func1<GitHostRepo, void> onDone;
GitHostSetupRepoSelector({
const GitHostSetupRepoSelector({
Key? key,
required this.gitHost,
required this.userInfo,
required this.onDone,
});
}) : super(key: key);
@override
GitHostSetupRepoSelectorState createState() {
@ -286,7 +287,7 @@ class _RepoTile extends StatelessWidget {
final void Function() onTap;
final bool selected;
_RepoTile({
const _RepoTile({
required this.repo,
required this.searchText,
required this.onTap,
@ -400,7 +401,7 @@ class _SmartDateTime extends StatelessWidget {
final DateTime? dt;
final TextStyle? style;
_SmartDateTime(this.dt, this.style);
const _SmartDateTime(this.dt, this.style);
static final _dateFormat = DateFormat('d MMM yyyy');
static final _dateFormatWithoutYear = DateFormat('d MMM');

View File

@ -43,7 +43,7 @@ class GitHostSetupScreen extends StatefulWidget {
final String remoteName;
final Func2<String, String, Future<void>> onCompletedFunction;
GitHostSetupScreen({
const GitHostSetupScreen({
required this.repoFolderName,
required this.remoteName,
required this.onCompletedFunction,
@ -62,7 +62,7 @@ enum KeyGenerationChoice { Unknown, AutoGenerated, UserProvided }
class GitHostSetupScreenState extends State<GitHostSetupScreen> {
var _pageCount = 1;
var _pageChoice = [
final _pageChoice = [
PageChoice0.Unknown,
PageChoice1.Unknown,
];
@ -693,47 +693,45 @@ class GitHostChoicePage extends StatelessWidget {
final Func1<GitHostType, void> onKnownGitHost;
final Func0<void> onCustomGitHost;
GitHostChoicePage({
const GitHostChoicePage({
required this.onKnownGitHost,
required this.onCustomGitHost,
});
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Text(
tr(LocaleKeys.setup_host_title),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 16.0),
GitHostSetupButton(
text: "GitHub",
iconUrl: 'assets/icon/github-icon.png',
onPressed: () {
onKnownGitHost(GitHostType.GitHub);
},
),
const SizedBox(height: 8.0),
GitHostSetupButton(
text: "GitLab",
iconUrl: 'assets/icon/gitlab-icon.png',
onPressed: () async {
onKnownGitHost(GitHostType.GitLab);
},
),
const SizedBox(height: 8.0),
GitHostSetupButton(
text: tr(LocaleKeys.setup_host_custom),
onPressed: () async {
onCustomGitHost();
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
),
return Column(
children: <Widget>[
Text(
tr(LocaleKeys.setup_host_title),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 16.0),
GitHostSetupButton(
text: "GitHub",
iconUrl: 'assets/icon/github-icon.png',
onPressed: () {
onKnownGitHost(GitHostType.GitHub);
},
),
const SizedBox(height: 8.0),
GitHostSetupButton(
text: "GitLab",
iconUrl: 'assets/icon/gitlab-icon.png',
onPressed: () async {
onKnownGitHost(GitHostType.GitLab);
},
),
const SizedBox(height: 8.0),
GitHostSetupButton(
text: tr(LocaleKeys.setup_host_custom),
onPressed: () async {
onCustomGitHost();
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
);
}
}
@ -748,36 +746,34 @@ var _isDesktop = Platform.isLinux || Platform.isMacOS || Platform.isWindows;
class GitHostAutoConfigureChoicePage extends StatelessWidget {
final Func1<GitHostSetupType, void> onDone;
GitHostAutoConfigureChoicePage({required this.onDone});
const GitHostAutoConfigureChoicePage({required this.onDone});
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Text(
tr(LocaleKeys.setup_autoConfigure_title),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 16.0),
if (!_isDesktop)
GitHostSetupButton(
text: tr(LocaleKeys.setup_autoConfigure_automatic),
onPressed: () {
onDone(GitHostSetupType.Auto);
},
),
if (!_isDesktop) const SizedBox(height: 8.0),
return Column(
children: <Widget>[
Text(
tr(LocaleKeys.setup_autoConfigure_title),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 16.0),
if (!_isDesktop)
GitHostSetupButton(
text: tr(LocaleKeys.setup_autoConfigure_manual),
onPressed: () async {
onDone(GitHostSetupType.Manual);
text: tr(LocaleKeys.setup_autoConfigure_automatic),
onPressed: () {
onDone(GitHostSetupType.Auto);
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
),
if (!_isDesktop) const SizedBox(height: 8.0),
GitHostSetupButton(
text: tr(LocaleKeys.setup_autoConfigure_manual),
onPressed: () async {
onDone(GitHostSetupType.Manual);
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
);
}
}

View File

@ -41,7 +41,7 @@ Widget autoConfigure() {
padding: const EdgeInsets.all(16.0),
child: GitHostSetupAutoConfigurePage(
gitHostType: GitHostType.GitHub,
onDone: (host, userInfo) => null,
onDone: (host, userInfo) {},
),
);
}
@ -51,15 +51,15 @@ Widget cloneUrl() {
padding: const EdgeInsets.all(16.0),
child: GitCloneUrlPage(
initialValue: "foo?",
doneFunction: (val) => null,
doneFunction: (val) {},
),
);
}
// FIXME: Create widgets for all the errors!
Widget loadingError() {
return Padding(
padding: const EdgeInsets.all(16.0),
return const Padding(
padding: EdgeInsets.all(16.0),
child: GitHostSetupErrorPage(
"This is an error message",
),
@ -68,8 +68,8 @@ Widget loadingError() {
// FIXME: Create widgets for all the loading screen messages!
Widget loading() {
return Padding(
padding: const EdgeInsets.all(16.0),
return const Padding(
padding: EdgeInsets.all(16.0),
child: GitHostSetupLoadingPage(
"Loading Message",
),

View File

@ -22,7 +22,7 @@ class GitHostSetupSshKeyKnownProviderPage extends StatelessWidget {
final Func0<void> openDeployKeyPage;
GitHostSetupSshKeyKnownProviderPage({
const GitHostSetupSshKeyKnownProviderPage({
required this.doneFunction,
required this.regenerateFunction,
required this.copyKeyFunction,
@ -104,7 +104,7 @@ class GitHostSetupSshKeyUnknownProviderPage extends StatelessWidget {
final Func1<BuildContext, void> copyKeyFunction;
final String? publicKey;
GitHostSetupSshKeyUnknownProviderPage({
const GitHostSetupSshKeyUnknownProviderPage({
required this.doneFunction,
required this.regenerateFunction,
required this.copyKeyFunction,
@ -178,34 +178,32 @@ class GitHostSetupKeyChoicePage extends StatelessWidget {
final Func0<void> onGenerateKeys;
final Func0<void> onUserProvidedKeys;
GitHostSetupKeyChoicePage({
const GitHostSetupKeyChoicePage({
required this.onGenerateKeys,
required this.onUserProvidedKeys,
});
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Text(
tr("setup.sshKeyChoice.title"),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 16.0),
GitHostSetupButton(
text: tr("setup.sshKeyChoice.generate"),
onPressed: onGenerateKeys,
),
const SizedBox(height: 8.0),
GitHostSetupButton(
text: tr("setup.sshKeyChoice.custom"),
onPressed: onUserProvidedKeys,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
),
return Column(
children: <Widget>[
Text(
tr("setup.sshKeyChoice.title"),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 16.0),
GitHostSetupButton(
text: tr("setup.sshKeyChoice.generate"),
onPressed: onGenerateKeys,
),
const SizedBox(height: 8.0),
GitHostSetupButton(
text: tr("setup.sshKeyChoice.custom"),
onPressed: onUserProvidedKeys,
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
);
}
}
@ -215,7 +213,7 @@ class GitHostUserProvidedKeysPage extends StatefulWidget {
doneFunction; // public, private, password
final String saveText;
GitHostUserProvidedKeysPage({
const GitHostUserProvidedKeysPage({
required this.doneFunction,
this.saveText = "",
});
@ -259,68 +257,65 @@ class _GitHostUserProvidedKeysPageState
@override
Widget build(BuildContext context) {
var body = Container(
child: Column(
children: <Widget>[
Text(
tr(LocaleKeys.setup_sshKeyUserProvided_public),
style: Theme.of(context).textTheme.headline5,
var body = Column(
children: <Widget>[
Text(
tr(LocaleKeys.setup_sshKeyUserProvided_public),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 8.0),
PublicKeyEditor(_publicFormKey, _publicKeyController),
const SizedBox(height: 8.0),
Text(
tr(LocaleKeys.setup_sshKeyUserProvided_private),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 8.0),
PrivateKeyEditor(_privateFormKey, _privateKeyController),
const SizedBox(height: 8.0),
TextField(
controller: _passwordController,
maxLines: 1,
decoration: InputDecoration(
helperText: tr(LocaleKeys.setup_sshKeyUserProvided_password),
border: const OutlineInputBorder(),
isDense: true,
),
const SizedBox(height: 8.0),
PublicKeyEditor(_publicFormKey, _publicKeyController),
const SizedBox(height: 8.0),
Text(
tr(LocaleKeys.setup_sshKeyUserProvided_private),
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 8.0),
PrivateKeyEditor(_privateFormKey, _privateKeyController),
const SizedBox(height: 8.0),
TextField(
controller: _passwordController,
maxLines: 1,
decoration: InputDecoration(
helperText: tr(LocaleKeys.setup_sshKeyUserProvided_password),
border: const OutlineInputBorder(),
isDense: true,
),
),
const SizedBox(height: 16.0),
GitHostSetupButton(
text: saveText,
onPressed: () {
if (!mounted) return;
),
const SizedBox(height: 16.0),
GitHostSetupButton(
text: saveText,
onPressed: () {
if (!mounted) return;
var publicValid =
_publicFormKey.currentState?.validate() ?? false;
var privateValid =
_privateFormKey.currentState?.validate() ?? false;
var publicValid = _publicFormKey.currentState?.validate() ?? false;
var privateValid =
_privateFormKey.currentState?.validate() ?? false;
if (!publicValid || !privateValid) {
return;
}
if (!publicValid || !privateValid) {
return;
}
var publicKey = _publicKeyController.text.trim();
if (!publicKey.endsWith('\n')) {
publicKey += '\n';
}
var publicKey = _publicKeyController.text.trim();
if (!publicKey.endsWith('\n')) {
publicKey += '\n';
}
var privateKey = _privateKeyController.text.trim();
if (!privateKey.endsWith('\n')) {
privateKey += '\n';
}
var privateKey = _privateKeyController.text.trim();
if (!privateKey.endsWith('\n')) {
privateKey += '\n';
}
widget.doneFunction(
publicKey,
privateKey,
_passwordController.text,
);
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
),
widget.doneFunction(
publicKey,
privateKey,
_passwordController.text,
);
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
);
return SingleChildScrollView(
@ -335,7 +330,7 @@ class _GitHostUserProvidedKeysPageState
class PublicKeyWidget extends StatelessWidget {
final String publicKey;
PublicKeyWidget(this.publicKey);
const PublicKeyWidget(this.publicKey);
@override
Widget build(BuildContext context) {
return Container(

View File

@ -26,7 +26,7 @@ class SshKey {
});
}
final bool useDartKeyGen = false;
const bool useDartKeyGen = false;
Future<SshKey?> generateSSHKeys({required String comment}) async {
if (Platform.isAndroid || Platform.isIOS) {

View File

@ -14,29 +14,29 @@ String resolveMergeConflict(String fileContents) {
var seenStartMarker = false;
var seenMiddleMarker = false;
lines.forEach((line) {
for (var line in lines) {
if (line.startsWith("<<<<<<<") && !inMergeConflict) {
inMergeConflict = true;
seenStartMarker = true;
return;
continue;
}
if (line == "=======" && inMergeConflict && seenStartMarker) {
seenMiddleMarker = true;
return;
continue;
}
if (line.startsWith(">>>>>>>") && inMergeConflict && seenMiddleMarker) {
inMergeConflict = false;
seenStartMarker = false;
seenMiddleMarker = false;
return;
continue;
}
if (inMergeConflict && seenMiddleMarker) {
return;
continue;
}
newLines.add(line);
});
}
return newLines.join('\n');
}

View File

@ -65,7 +65,7 @@ class _AppDrawerState extends State<AppDrawer>
}
Widget _buildRepoList() {
var divider = Row(children: <Widget>[const Expanded(child: Divider())]);
var divider = Row(children: const <Widget>[Expanded(child: Divider())]);
var repoManager = context.watch<RepositoryManager>();
var repoIds = repoManager.repoIds;
@ -127,7 +127,7 @@ class _AppDrawerState extends State<AppDrawer>
);
}
var divider = Row(children: <Widget>[const Expanded(child: Divider())]);
var divider = Row(children: const <Widget>[Expanded(child: Divider())]);
var user = Supabase.instance.client.auth.currentUser;
return Drawer(

View File

@ -23,7 +23,7 @@ import 'package:gitjournal/settings/settings.dart';
class AppDrawerHeader extends StatelessWidget {
final Func0<void> repoListToggled;
AppDrawerHeader({
const AppDrawerHeader({
required this.repoListToggled,
});

View File

@ -19,7 +19,7 @@ class FolderSelectionDialog extends StatelessWidget {
Widget build(BuildContext context) {
final notesFolder = Provider.of<NotesFolderFS>(context);
var body = Container(
var body = SizedBox(
width: double.maxFinite,
child: FolderTreeView(
rootFolder: notesFolder,
@ -36,13 +36,13 @@ class FolderSelectionDialog extends StatelessWidget {
}
}
typedef void FolderSelectedCallback(NotesFolderFS folder);
typedef FolderSelectedCallback = void Function(NotesFolderFS folder);
class FolderTreeView extends StatelessWidget {
final NotesFolderFS rootFolder;
final FolderSelectedCallback onFolderEntered;
FolderTreeView({
const FolderTreeView({
Key? key,
required this.rootFolder,
required this.onFolderEntered,
@ -65,7 +65,7 @@ class FolderMiniTile extends StatefulWidget {
final NotesFolderFS folder;
final FolderSelectedCallback onTap;
FolderMiniTile({
const FolderMiniTile({
required this.folder,
required this.onTap,
});
@ -135,12 +135,12 @@ class FolderMiniTileState extends State<FolderMiniTile> {
if (!_isExpanded) return Container();
var children = <FolderMiniTile>[];
widget.folder.subFolders.forEach((folder) {
for (var folder in widget.folder.subFolders) {
children.add(FolderMiniTile(
folder: folder as NotesFolderFS,
onTap: widget.onTap,
));
});
}
return Container(
margin: const EdgeInsets.only(left: 8.0),

View File

@ -8,7 +8,7 @@ import 'package:flutter/material.dart';
import 'package:gitjournal/core/notes_folder_fs.dart';
typedef void FolderSelectedCallback(NotesFolderFS folder);
typedef FolderSelectedCallback = void Function(NotesFolderFS folder);
class FolderTreeView extends StatefulWidget {
final NotesFolderFS rootFolder;
@ -17,7 +17,7 @@ class FolderTreeView extends StatefulWidget {
final Function onFolderUnselected;
final FolderSelectedCallback onFolderEntered;
FolderTreeView({
const FolderTreeView({
Key? key,
required this.rootFolder,
required this.onFolderEntered,
@ -79,7 +79,7 @@ class FolderTile extends StatefulWidget {
final FolderSelectedCallback onLongPress;
final NotesFolderFS? selectedFolder;
FolderTile({
const FolderTile({
required this.folder,
required this.onTap,
required this.onLongPress,
@ -169,14 +169,14 @@ class FolderTileState extends State<FolderTile> {
if (!_isExpanded) return Container();
var children = <FolderTile>[];
widget.folder.subFolders.forEach((folder) {
for (var folder in widget.folder.subFolders) {
children.add(FolderTile(
folder: folder as NotesFolderFS,
onTap: widget.onTap,
onLongPress: widget.onLongPress,
selectedFolder: widget.selectedFolder,
));
});
}
return Container(
margin: const EdgeInsets.only(left: 16.0),

View File

@ -16,7 +16,8 @@ class HighlightedText extends StatelessWidget {
final TextOverflow? overflow;
final int? maxLines;
HighlightedText({
const HighlightedText({
Key? key,
required this.text,
required this.highlightText,
required this.highlightTextLowerCase,
@ -24,7 +25,7 @@ class HighlightedText extends StatelessWidget {
this.highlightStyle,
this.overflow,
this.maxLines,
});
}) : super(key: key);
@override
Widget build(BuildContext context) {

View File

@ -20,7 +20,7 @@ class ImageCaption extends StatelessWidget {
final String altText;
final String tooltip;
final bool overlay;
ImageCaption(this.altText, this.tooltip, this.overlay);
const ImageCaption(this.altText, this.tooltip, this.overlay);
@override
Widget build(BuildContext context) {

View File

@ -17,7 +17,7 @@ import 'package:gitjournal/widgets/images/themable_image.dart';
class ImageDetails extends StatefulWidget {
final ThemableImage image;
final String caption;
ImageDetails(this.image, this.caption);
const ImageDetails(this.image, this.caption);
@override
_ImageDetailsState createState() => _ImageDetailsState();

View File

@ -33,7 +33,7 @@ class MarkdownImage extends StatelessWidget {
// FIXME: Avoid using dynamic!
final Future<dynamic> data;
MarkdownImage._(
const MarkdownImage._(
this.data, this.width, this.height, String? altText, String? tooltip)
: altText = altText ?? "",
tooltip = tooltip ?? "";

View File

@ -23,7 +23,7 @@ class ThemableImage extends StatelessWidget {
final ColorCondition colorCondition;
final Color bg;
ThemableImage.image(
const ThemableImage.image(
this.file, {
this.width,
this.height,
@ -34,7 +34,7 @@ class ThemableImage extends StatelessWidget {
themingCondition = ThemingCondition.none,
colorCondition = ColorCondition.all;
ThemableImage.svg(
const ThemableImage.svg(
this.string, {
this.width,
this.height,
@ -187,7 +187,7 @@ bool _hasBackground(Drawable draw, double width, double height,
Drawable _themeDrawable(
Drawable draw, Color? Function(Color? color) transformColor) {
if (draw is DrawableStyleable && !(draw is DrawableGroup)) {
if (draw is DrawableStyleable && draw is! DrawableGroup) {
final DrawableStyleable drawStylable = draw;
draw = drawStylable.mergeStyle(DrawableStyle(
stroke: drawStylable.style!.stroke != null &&

Some files were not shown because too many files have changed in this diff Show More