fixed more lint issues (effective dart style)

This commit is contained in:
Thibault Deckers 2020-07-26 03:03:07 +09:00
parent a48937795e
commit 4cbfcdc2e3
19 changed files with 72 additions and 72 deletions

View file

@ -4,9 +4,26 @@ analyzer:
exclude: exclude:
- lib/generated_plugin_registrant.dart - lib/generated_plugin_registrant.dart
# strong-mode:
# implicit-casts: false
# implicit-dynamic: false
linter: linter:
rules: rules:
- always_declare_return_types avoid_function_literals_in_foreach_calls: false # benefit?
- prefer_const_constructors lines_longer_than_80_chars: false # nope
- prefer_const_constructors_in_immutables
- prefer_const_declarations avoid_classes_with_only_static_members: false # maybe?
prefer_relative_imports: false # check IDE support (auto import, file move)
public_member_api_docs: false # maybe?
always_declare_return_types: true
avoid_types_on_closure_parameters: true
constant_identifier_names: true
prefer_const_constructors: true
prefer_const_constructors_in_immutables: true
prefer_const_declarations: true
prefer_function_declarations_over_variables: true
prefer_interpolation_to_compose_strings: true
unnecessary_brace_in_string_interps: true
unnecessary_lambdas: true

View file

@ -58,9 +58,9 @@ class _AvesAppState extends State<AvesApp> {
), ),
), ),
), ),
home: FutureBuilder( home: FutureBuilder<void>(
future: _appSetup, future: _appSetup,
builder: (context, AsyncSnapshot<void> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return const Icon(AIcons.error); if (snapshot.hasError) return const Icon(AIcons.error);
if (snapshot.connectionState != ConnectionState.done) return const Scaffold(); if (snapshot.connectionState != ConnectionState.done) return const Scaffold();
return settings.hasAcceptedTerms ? const HomePage() : const WelcomePage(); return settings.hasAcceptedTerms ? const HomePage() : const WelcomePage();

View file

@ -179,11 +179,12 @@ class AddressDetails {
} }
} }
@immutable
class FavouriteRow { class FavouriteRow {
final int contentId; final int contentId;
final String path; final String path;
FavouriteRow({ const FavouriteRow({
this.contentId, this.contentId,
this.path, this.path,
}); });

View file

@ -76,6 +76,7 @@ class Settings {
// convenience methods // convenience methods
// ignore: avoid_positional_boolean_parameters
bool getBoolOrDefault(String key, bool defaultValue) => _prefs.getKeys().contains(key) ? _prefs.getBool(key) : defaultValue; bool getBoolOrDefault(String key, bool defaultValue) => _prefs.getKeys().contains(key) ? _prefs.getBool(key) : defaultValue;
T getEnumOrDefault<T>(String key, T defaultValue, Iterable<T> values) { T getEnumOrDefault<T>(String key, T defaultValue, Iterable<T> values) {

View file

@ -168,7 +168,7 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin, CollectionSel
]); ]);
break; break;
case SortFactor.name: case SortFactor.name:
final byAlbum = groupBy(_filteredEntries, (entry) => entry.directory); final byAlbum = groupBy<ImageEntry, String>(_filteredEntries, (entry) => entry.directory);
int compare(a, b) { int compare(a, b) {
final ua = source.getUniqueAlbumName(a); final ua = source.getUniqueAlbumName(a);
final ub = source.getUniqueAlbumName(b); final ub = source.getUniqueAlbumName(b);

View file

@ -192,11 +192,12 @@ class ImageFileService {
} }
} }
@immutable
class ImageOpEvent { class ImageOpEvent {
final bool success; final bool success;
final String uri; final String uri;
ImageOpEvent({ const ImageOpEvent({
this.success, this.success,
this.uri, this.uri,
}); });
@ -226,7 +227,7 @@ class ImageOpEvent {
class MoveOpEvent extends ImageOpEvent { class MoveOpEvent extends ImageOpEvent {
final Map newFields; final Map newFields;
MoveOpEvent({bool success, String uri, this.newFields}) const MoveOpEvent({bool success, String uri, this.newFields})
: super( : super(
success: success, success: success,
uri: uri, uri: uri,

View file

@ -5,7 +5,7 @@ final Map<String, Color> _stringColors = {};
Color stringToColor(String string, {double saturation = .8, double lightness = .6}) { Color stringToColor(String string, {double saturation = .8, double lightness = .6}) {
var color = _stringColors[string]; var color = _stringColors[string];
if (color == null) { if (color == null) {
final hash = string.codeUnits.fold(0, (prev, el) => prev = el + ((prev << 5) - prev)); final hash = string.codeUnits.fold<int>(0, (prev, el) => prev = el + ((prev << 5) - prev));
final hue = (hash % 360).toDouble(); final hue = (hash % 360).toDouble();
color = HSLColor.fromAHSL(1.0, hue, saturation, lightness).toColor(); color = HSLColor.fromAHSL(1.0, hue, saturation, lightness).toColor();
_stringColors[string] = color; _stringColors[string] = color;

View file

@ -4,7 +4,6 @@ import 'package:aves/model/image_entry.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/widgets/album/grid/header_generic.dart'; import 'package:aves/widgets/album/grid/header_generic.dart';
import 'package:aves/widgets/album/grid/tile_extent_manager.dart'; import 'package:aves/widgets/album/grid/tile_extent_manager.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -145,25 +144,6 @@ class SectionedListLayout {
final top = sectionLayout.indexToLayoutOffset(listIndex); final top = sectionLayout.indexToLayoutOffset(listIndex);
return Rect.fromLTWH(left, top, tileExtent, tileExtent); return Rect.fromLTWH(left, top, tileExtent, tileExtent);
} }
int rowIndex(dynamic sectionKey, List<int> builtIds) {
if (!collection.sections.containsKey(sectionKey)) return null;
final section = collection.sections[sectionKey];
final firstId = builtIds.first;
final firstIndexInSection = section.indexWhere((entry) => entry.contentId == firstId);
if (firstIndexInSection % columnCount != 0) return null;
final collectionIds = section.skip(firstIndexInSection).take(builtIds.length).map((entry) => entry.contentId);
final eq = const IterableEquality().equals;
if (eq(builtIds, collectionIds)) {
final sectionLayout = sectionLayouts.firstWhere((section) => section.sectionKey == sectionKey, orElse: () => null);
if (sectionLayout == null) return null;
return sectionLayout.firstIndex + 1 + firstIndexInSection ~/ columnCount;
}
return null;
}
} }
class SectionLayout { class SectionLayout {

View file

@ -57,7 +57,7 @@ class ThumbnailSelectionOverlay extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final duration = Durations.thumbnailOverlayAnimation; const duration = Durations.thumbnailOverlayAnimation;
final fontSize = min(14.0, (extent / 8)).roundToDouble(); final fontSize = min(14.0, (extent / 8)).roundToDouble();
final iconSize = fontSize * 2; final iconSize = fontSize * 2;
final collection = Provider.of<CollectionLens>(context); final collection = Provider.of<CollectionLens>(context);

View file

@ -105,11 +105,11 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin {
final selection = collection.selection.toList(); final selection = collection.selection.toList();
if (!await checkStoragePermission(context, selection)) return; if (!await checkStoragePermission(context, selection)) return;
_showOpReport( _showOpReport<MoveOpEvent>(
context: context, context: context,
selection: selection, selection: selection,
opStream: ImageFileService.move(selection, copy: copy, destinationAlbum: destinationAlbum), opStream: ImageFileService.move(selection, copy: copy, destinationAlbum: destinationAlbum),
onDone: (Set<MoveOpEvent> processed) async { onDone: (processed) async {
debugPrint('$runtimeType _moveSelection onDone'); debugPrint('$runtimeType _moveSelection onDone');
final movedOps = processed.where((e) => e.success); final movedOps = processed.where((e) => e.success);
final movedCount = movedOps.length; final movedCount = movedOps.length;
@ -207,11 +207,11 @@ class SelectionActionDelegate with FeedbackMixin, PermissionAwareMixin {
if (!await checkStoragePermission(context, selection)) return; if (!await checkStoragePermission(context, selection)) return;
_showOpReport( _showOpReport<ImageOpEvent>(
context: context, context: context,
selection: selection, selection: selection,
opStream: ImageFileService.delete(selection), opStream: ImageFileService.delete(selection),
onDone: (Set<ImageOpEvent> processed) { onDone: (processed) {
final deletedUris = processed.where((e) => e.success).map((e) => e.uri); final deletedUris = processed.where((e) => e.success).map((e) => e.uri);
final deletedCount = deletedUris.length; final deletedCount = deletedUris.length;
final selectionCount = selection.length; final selectionCount = selection.length;

View file

@ -157,9 +157,9 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
} }
: null, : null,
borderRadius: borderRadius, borderRadius: borderRadius,
child: FutureBuilder( child: FutureBuilder<Color>(
future: _colorFuture, future: _colorFuture,
builder: (context, AsyncSnapshot<Color> snapshot) { builder: (context, snapshot) {
final outlineColor = snapshot.hasData ? snapshot.data : Colors.transparent; final outlineColor = snapshot.hasData ? snapshot.data : Colors.transparent;
return DecoratedBox( return DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(

View file

@ -134,16 +134,16 @@ class DebugPageState extends State<DebugPage> {
child: Text('Glide disk cache: ?'), child: Text('Glide disk cache: ?'),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
RaisedButton( const RaisedButton(
onPressed: ImageFileService.clearSizedThumbnailDiskCache, onPressed: ImageFileService.clearSizedThumbnailDiskCache,
child: const Text('Clear'), child: Text('Clear'),
), ),
], ],
), ),
const Divider(), const Divider(),
FutureBuilder( FutureBuilder<int>(
future: _dbFileSizeLoader, future: _dbFileSizeLoader,
builder: (context, AsyncSnapshot<int> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
@ -160,9 +160,9 @@ class DebugPageState extends State<DebugPage> {
); );
}, },
), ),
FutureBuilder( FutureBuilder<List>(
future: _dbEntryLoader, future: _dbEntryLoader,
builder: (context, AsyncSnapshot<List> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
@ -179,9 +179,9 @@ class DebugPageState extends State<DebugPage> {
); );
}, },
), ),
FutureBuilder( FutureBuilder<List>(
future: _dbDateLoader, future: _dbDateLoader,
builder: (context, AsyncSnapshot<List> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
@ -198,9 +198,9 @@ class DebugPageState extends State<DebugPage> {
); );
}, },
), ),
FutureBuilder( FutureBuilder<List>(
future: _dbMetadataLoader, future: _dbMetadataLoader,
builder: (context, AsyncSnapshot<List> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
@ -217,9 +217,9 @@ class DebugPageState extends State<DebugPage> {
); );
}, },
), ),
FutureBuilder( FutureBuilder<List>(
future: _dbAddressLoader, future: _dbAddressLoader,
builder: (context, AsyncSnapshot<List> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
@ -236,9 +236,9 @@ class DebugPageState extends State<DebugPage> {
); );
}, },
), ),
FutureBuilder( FutureBuilder<List>(
future: _dbFavouritesLoader, future: _dbFavouritesLoader,
builder: (context, AsyncSnapshot<List> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
@ -308,9 +308,9 @@ class DebugPageState extends State<DebugPage> {
return ListView( return ListView(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
children: [ children: [
FutureBuilder( FutureBuilder<Map>(
future: _envLoader, future: _envLoader,
builder: (context, AsyncSnapshot<Map> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = SplayTreeMap.of(snapshot.data.map((k, v) => MapEntry(k.toString(), v?.toString() ?? 'null'))); final data = SplayTreeMap.of(snapshot.data.map((k, v) => MapEntry(k.toString(), v?.toString() ?? 'null')));

View file

@ -62,9 +62,9 @@ class _FullscreenDebugPageState extends State<FullscreenDebugPage> {
return ListView( return ListView(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
children: [ children: [
FutureBuilder( FutureBuilder<DateMetadata>(
future: _dbDateLoader, future: _dbDateLoader,
builder: (context, AsyncSnapshot<DateMetadata> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = snapshot.data; final data = snapshot.data;
@ -81,9 +81,9 @@ class _FullscreenDebugPageState extends State<FullscreenDebugPage> {
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
FutureBuilder( FutureBuilder<CatalogMetadata>(
future: _dbMetadataLoader, future: _dbMetadataLoader,
builder: (context, AsyncSnapshot<CatalogMetadata> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = snapshot.data; final data = snapshot.data;
@ -107,9 +107,9 @@ class _FullscreenDebugPageState extends State<FullscreenDebugPage> {
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
FutureBuilder( FutureBuilder<AddressDetails>(
future: _dbAddressLoader, future: _dbAddressLoader,
builder: (context, AsyncSnapshot<AddressDetails> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = snapshot.data; final data = snapshot.data;
@ -155,9 +155,9 @@ class _FullscreenDebugPageState extends State<FullscreenDebugPage> {
return ListView( return ListView(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
children: [ children: [
FutureBuilder( FutureBuilder<Map>(
future: _contentResolverMetadataLoader, future: _contentResolverMetadataLoader,
builder: (context, AsyncSnapshot<Map> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = SplayTreeMap.of(snapshot.data.map((k, v) { final data = SplayTreeMap.of(snapshot.data.map((k, v) {

View file

@ -60,7 +60,7 @@ class InfoPageState extends State<InfoPage> {
final mqViewInsetsBottom = mq.item2; final mqViewInsetsBottom = mq.item2;
final split = mqWidth > 400; final split = mqWidth > 400;
return ValueListenableBuilder( return ValueListenableBuilder<ImageEntry>(
valueListenable: widget.entryNotifier, valueListenable: widget.entryNotifier,
builder: (context, entry, child) { builder: (context, entry, child) {
final locationAtTop = split && entry.hasGps; final locationAtTop = split && entry.hasGps;

View file

@ -82,9 +82,9 @@ class _FullscreenBottomOverlayState extends State<FullscreenBottomOverlay> {
return Container( return Container(
color: FullscreenOverlay.backgroundColor, color: FullscreenOverlay.backgroundColor,
padding: viewInsets + viewPadding.copyWith(top: 0), padding: viewInsets + viewPadding.copyWith(top: 0),
child: FutureBuilder( child: FutureBuilder<OverlayMetadata>(
future: _detailLoader, future: _detailLoader,
builder: (futureContext, AsyncSnapshot<OverlayMetadata> snapshot) { builder: (futureContext, snapshot) {
if (snapshot.connectionState == ConnectionState.done && !snapshot.hasError) { if (snapshot.connectionState == ConnectionState.done && !snapshot.hasError) {
_lastDetails = snapshot.data; _lastDetails = snapshot.data;
_lastEntry = entry; _lastEntry = entry;

View file

@ -98,7 +98,7 @@ class VideoControlOverlayState extends State<VideoControlOverlay> with SingleTic
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final mq = context.select((mq) => Tuple3(mq.size.width, mq.viewInsets, mq.viewPadding)); final mq = context.select<MediaQueryData, Tuple3<double, EdgeInsets, EdgeInsets>>((mq) => Tuple3(mq.size.width, mq.viewInsets, mq.viewPadding));
final mqWidth = mq.item1; final mqWidth = mq.item1;
final mqViewInsets = mq.item2; final mqViewInsets = mq.item2;
final mqViewPadding = mq.item3; final mqViewPadding = mq.item3;

View file

@ -92,9 +92,9 @@ class _HomePageState extends State<HomePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder( return FutureBuilder<void>(
future: _appSetup, future: _appSetup,
builder: (context, AsyncSnapshot<void> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return const Icon(AIcons.error); if (snapshot.hasError) return const Icon(AIcons.error);
if (snapshot.connectionState != ConnectionState.done) return const Scaffold(); if (snapshot.connectionState != ConnectionState.done) return const Scaffold();
if (AvesApp.mode == AppMode.view) { if (AvesApp.mode == AppMode.view) {

View file

@ -54,7 +54,7 @@ class StatsPage extends StatelessWidget {
text: 'No images', text: 'No images',
); );
} else { } else {
final byMimeTypes = groupBy(entries, (entry) => entry.mimeType).map<String, int>((k, v) => MapEntry(k, v.length)); final byMimeTypes = groupBy<ImageEntry, String>(entries, (entry) => entry.mimeType).map<String, int>((k, v) => MapEntry(k, v.length));
final imagesByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image/'))); final imagesByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('image/')));
final videoByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video/'))); final videoByMimeTypes = Map.fromEntries(byMimeTypes.entries.where((kv) => kv.key.startsWith('video/')));
final mimeDonuts = Wrap( final mimeDonuts = Wrap(
@ -120,7 +120,7 @@ class StatsPage extends StatelessWidget {
Widget _buildMimeDonut(BuildContext context, String Function(num) label, Map<String, num> byMimeTypes) { Widget _buildMimeDonut(BuildContext context, String Function(num) label, Map<String, num> byMimeTypes) {
if (byMimeTypes.isEmpty) return const SizedBox.shrink(); if (byMimeTypes.isEmpty) return const SizedBox.shrink();
final sum = byMimeTypes.values.fold(0, (prev, v) => prev + v); final sum = byMimeTypes.values.fold<int>(0, (prev, v) => prev + v);
final seriesData = byMimeTypes.entries.map((kv) => StringNumDatum(_cleanMime(kv.key), kv.value)).toList(); final seriesData = byMimeTypes.entries.map((kv) => StringNumDatum(_cleanMime(kv.key), kv.value)).toList();
seriesData.sort((kv1, kv2) { seriesData.sort((kv1, kv2) {

View file

@ -33,9 +33,9 @@ class _WelcomePageState extends State<WelcomePage> {
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: FutureBuilder( child: FutureBuilder<String>(
future: _termsLoader, future: _termsLoader,
builder: (context, AsyncSnapshot<String> snapshot) { builder: (context, snapshot) {
if (snapshot.hasError || snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); if (snapshot.hasError || snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final terms = snapshot.data; final terms = snapshot.data;
return Column( return Column(