const galore

This commit is contained in:
Thibault Deckers 2021-06-08 11:05:23 +09:00
parent 236626984c
commit 0dbb46d9bb
133 changed files with 567 additions and 564 deletions

View file

@ -29,6 +29,6 @@ linter:
unnecessary_lambdas: true unnecessary_lambdas: true
# misc # misc
prefer_const_constructors: false # too noisy prefer_const_constructors: true # should specify `const` as Dart does not build constants when using const constructors without it
prefer_const_constructors_in_immutables: true prefer_const_constructors_in_immutables: true
prefer_const_declarations: true prefer_const_declarations: true

View file

@ -159,14 +159,14 @@ class CollectionLens with ChangeNotifier, CollectionActivityMixin {
break; break;
case EntryGroupFactor.none: case EntryGroupFactor.none:
sections = Map.fromEntries([ sections = Map.fromEntries([
MapEntry(SectionKey(), _filteredSortedEntries), MapEntry(const SectionKey(), _filteredSortedEntries),
]); ]);
break; break;
} }
break; break;
case EntrySortFactor.size: case EntrySortFactor.size:
sections = Map.fromEntries([ sections = Map.fromEntries([
MapEntry(SectionKey(), _filteredSortedEntries), MapEntry(const SectionKey(), _filteredSortedEntries),
]); ]);
break; break;
case EntrySortFactor.name: case EntrySortFactor.name:

View file

@ -12,10 +12,10 @@ class Themes {
scaffoldBackgroundColor: Colors.grey.shade900, scaffoldBackgroundColor: Colors.grey.shade900,
dialogBackgroundColor: Colors.grey[850], dialogBackgroundColor: Colors.grey[850],
toggleableActiveColor: _accentColor, toggleableActiveColor: _accentColor,
tooltipTheme: TooltipThemeData( tooltipTheme: const TooltipThemeData(
verticalOffset: 32, verticalOffset: 32,
), ),
appBarTheme: AppBarTheme( appBarTheme: const AppBarTheme(
textTheme: TextTheme( textTheme: TextTheme(
headline6: TextStyle( headline6: TextStyle(
fontSize: 20, fontSize: 20,
@ -24,7 +24,7 @@ class Themes {
), ),
), ),
), ),
colorScheme: ColorScheme.dark( colorScheme: const ColorScheme.dark(
primary: _accentColor, primary: _accentColor,
secondary: _accentColor, secondary: _accentColor,
onPrimary: Colors.white, onPrimary: Colors.white,
@ -32,7 +32,7 @@ class Themes {
), ),
snackBarTheme: SnackBarThemeData( snackBarTheme: SnackBarThemeData(
backgroundColor: Colors.grey.shade800, backgroundColor: Colors.grey.shade800,
contentTextStyle: TextStyle( contentTextStyle: const TextStyle(
color: Colors.white, color: Colors.white,
), ),
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,

View file

@ -15,10 +15,12 @@ class Constants {
fontFeatures: [FontFeature.enable('smcp')], fontFeatures: [FontFeature.enable('smcp')],
); );
static const embossShadow = Shadow( static const embossShadows = [
Shadow(
color: Colors.black, color: Colors.black,
offset: Offset(0.5, 1.0), offset: Offset(0.5, 1.0),
); )
];
static const overlayUnknown = ''; // em dash static const overlayUnknown = ''; // em dash

View file

@ -23,7 +23,7 @@ extension ExtraDateTime on DateTime {
bool get isToday => isAtSameDayAs(DateTime.now()); bool get isToday => isAtSameDayAs(DateTime.now());
bool get isYesterday => isAtSameDayAs(DateTime.now().subtract(Duration(days: 1))); bool get isYesterday => isAtSameDayAs(DateTime.now().subtract(const Duration(days: 1)));
bool get isThisMonth => isAtSameMonthAs(DateTime.now()); bool get isThisMonth => isAtSameMonthAs(DateTime.now());

View file

@ -18,15 +18,15 @@ class AboutPage extends StatelessWidget {
child: CustomScrollView( child: CustomScrollView(
slivers: [ slivers: [
SliverPadding( SliverPadding(
padding: EdgeInsets.only(top: 16), padding: const EdgeInsets.only(top: 16),
sliver: SliverList( sliver: SliverList(
delegate: SliverChildListDelegate( delegate: SliverChildListDelegate(
[ [
AppReference(), AppReference(),
Divider(), const Divider(),
AboutUpdate(), AboutUpdate(),
AboutCredits(), AboutCredits(),
Divider(), const Divider(),
], ],
), ),
), ),

View file

@ -28,14 +28,14 @@ class _AppReferenceState extends State<AppReference> {
children: [ children: [
_buildAvesLine(), _buildAvesLine(),
_buildFlutterLine(), _buildFlutterLine(),
SizedBox(height: 16), const SizedBox(height: 16),
], ],
), ),
); );
} }
Widget _buildAvesLine() { Widget _buildAvesLine() {
final style = TextStyle( const style = TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
letterSpacing: 1.0, letterSpacing: 1.0,
@ -66,7 +66,7 @@ class _AppReferenceState extends State<AppReference> {
children: [ children: [
WidgetSpan( WidgetSpan(
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.only(end: 4), padding: const EdgeInsetsDirectional.only(end: 4),
child: FlutterLogo( child: FlutterLogo(
size: style.fontSize! * 1.25, size: style.fontSize! * 1.25,
), ),

View file

@ -9,12 +9,12 @@ class AboutCredits extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
padding: EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ConstrainedBox( ConstrainedBox(
constraints: BoxConstraints(minHeight: 48), constraints: const BoxConstraints(minHeight: 48),
child: Align( child: Align(
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
child: Text(context.l10n.aboutCredits, style: Constants.titleTextStyle), child: Text(context.l10n.aboutCredits, style: Constants.titleTextStyle),
@ -24,7 +24,7 @@ class AboutCredits extends StatelessWidget {
TextSpan( TextSpan(
children: [ children: [
TextSpan(text: context.l10n.aboutCreditsWorldAtlas1), TextSpan(text: context.l10n.aboutCreditsWorldAtlas1),
WidgetSpan( const WidgetSpan(
child: LinkChip( child: LinkChip(
text: 'World Atlas', text: 'World Atlas',
url: 'https://github.com/topojson/world-atlas', url: 'https://github.com/topojson/world-atlas',
@ -36,7 +36,7 @@ class AboutCredits extends StatelessWidget {
], ],
), ),
), ),
SizedBox(height: 16), const SizedBox(height: 16),
], ],
), ),
); );

View file

@ -36,12 +36,12 @@ class _LicensesState extends State<Licenses> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliverPadding( return SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
sliver: SliverList( sliver: SliverList(
delegate: SliverChildListDelegate( delegate: SliverChildListDelegate(
[ [
_buildHeader(), _buildHeader(),
SizedBox(height: 16), const SizedBox(height: 16),
AvesExpansionTile( AvesExpansionTile(
title: context.l10n.aboutLicensesAndroidLibraries, title: context.l10n.aboutLicensesAndroidLibraries,
color: BrandColors.android, color: BrandColors.android,
@ -76,7 +76,7 @@ class _LicensesState extends State<Licenses> {
// as of Flutter v1.22.4, `cardColor` is used as a background color by `LicensePage` // as of Flutter v1.22.4, `cardColor` is used as a background color by `LicensePage`
cardColor: Theme.of(context).scaffoldBackgroundColor, cardColor: Theme.of(context).scaffoldBackgroundColor,
), ),
child: LicensePage(), child: const LicensePage(),
), ),
), ),
), ),
@ -91,18 +91,18 @@ class _LicensesState extends State<Licenses> {
Widget _buildHeader() { Widget _buildHeader() {
return Padding( return Padding(
padding: EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ConstrainedBox( ConstrainedBox(
constraints: BoxConstraints(minHeight: 48), constraints: const BoxConstraints(minHeight: 48),
child: Align( child: Align(
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
child: Text(context.l10n.aboutLicenses, style: Constants.titleTextStyle), child: Text(context.l10n.aboutLicenses, style: Constants.titleTextStyle),
), ),
), ),
SizedBox(height: 8), const SizedBox(height: 8),
Text(context.l10n.aboutLicensesBanner), Text(context.l10n.aboutLicensesBanner),
], ],
), ),
@ -122,17 +122,17 @@ class LicenseRow extends StatelessWidget {
final subColor = bodyTextStyle.color!.withOpacity(.6); final subColor = bodyTextStyle.color!.withOpacity(.6);
return Padding( return Padding(
padding: EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LinkChip( LinkChip(
text: package.name, text: package.name,
url: package.sourceUrl, url: package.sourceUrl,
textStyle: TextStyle(fontWeight: FontWeight.bold), textStyle: const TextStyle(fontWeight: FontWeight.bold),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.only(start: 16), padding: const EdgeInsetsDirectional.only(start: 16),
child: LinkChip( child: LinkChip(
text: package.license, text: package.license,
url: package.licenseUrl, url: package.licenseUrl,

View file

@ -1,9 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AboutNewsBadge extends StatelessWidget { class AboutNewsBadge extends StatelessWidget {
const AboutNewsBadge();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Icon( return const Icon(
Icons.circle, Icons.circle,
size: 12, size: 12,
color: Colors.red, color: Colors.red,

View file

@ -25,22 +25,22 @@ class _AboutUpdateState extends State<AboutUpdate> {
future: _updateChecker, future: _updateChecker,
builder: (context, snapshot) { builder: (context, snapshot) {
final newVersionAvailable = snapshot.data == true; final newVersionAvailable = snapshot.data == true;
if (!newVersionAvailable) return SizedBox(); if (!newVersionAvailable) return const SizedBox();
return Column( return Column(
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ConstrainedBox( ConstrainedBox(
constraints: BoxConstraints(minHeight: 48), constraints: const BoxConstraints(minHeight: 48),
child: Align( child: Align(
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
child: Text.rich( child: Text.rich(
TextSpan( TextSpan(
children: [ children: [
WidgetSpan( const WidgetSpan(
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.only(end: 8), padding: EdgeInsetsDirectional.only(end: 8),
child: AboutNewsBadge(), child: AboutNewsBadge(),
@ -61,7 +61,7 @@ class _AboutUpdateState extends State<AboutUpdate> {
child: LinkChip( child: LinkChip(
text: context.l10n.aboutUpdateGithub, text: context.l10n.aboutUpdateGithub,
url: 'https://github.com/deckerst/aves/releases', url: 'https://github.com/deckerst/aves/releases',
textStyle: TextStyle(fontWeight: FontWeight.bold), textStyle: const TextStyle(fontWeight: FontWeight.bold),
), ),
alignment: PlaceholderAlignment.middle, alignment: PlaceholderAlignment.middle,
), ),
@ -70,7 +70,7 @@ class _AboutUpdateState extends State<AboutUpdate> {
child: LinkChip( child: LinkChip(
text: context.l10n.aboutUpdateGooglePlay, text: context.l10n.aboutUpdateGooglePlay,
url: 'https://play.google.com/store/apps/details?id=deckers.thibault.aves', url: 'https://play.google.com/store/apps/details?id=deckers.thibault.aves',
textStyle: TextStyle(fontWeight: FontWeight.bold), textStyle: const TextStyle(fontWeight: FontWeight.bold),
), ),
alignment: PlaceholderAlignment.middle, alignment: PlaceholderAlignment.middle,
), ),
@ -78,11 +78,11 @@ class _AboutUpdateState extends State<AboutUpdate> {
], ],
), ),
), ),
SizedBox(height: 16), const SizedBox(height: 16),
], ],
), ),
), ),
Divider(), const Divider(),
], ],
); );
}, },

View file

@ -41,11 +41,11 @@ class _AvesAppState extends State<AvesApp> {
// observers are not registered when using the same list object with different items // observers are not registered when using the same list object with different items
// the list itself needs to be reassigned // the list itself needs to be reassigned
List<NavigatorObserver> _navigatorObservers = []; List<NavigatorObserver> _navigatorObservers = [];
final EventChannel _contentChangeChannel = EventChannel('deckers.thibault/aves/contentchange'); final EventChannel _contentChangeChannel = const EventChannel('deckers.thibault/aves/contentchange');
final EventChannel _newIntentChannel = EventChannel('deckers.thibault/aves/intent'); final EventChannel _newIntentChannel = const EventChannel('deckers.thibault/aves/intent');
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey(debugLabel: 'app-navigator'); final GlobalKey<NavigatorState> _navigatorKey = GlobalKey(debugLabel: 'app-navigator');
Widget getFirstPage({Map? intentData}) => settings.hasAcceptedTerms ? HomePage(intentData: intentData) : WelcomePage(); Widget getFirstPage({Map? intentData}) => settings.hasAcceptedTerms ? HomePage(intentData: intentData) : const WelcomePage();
@override @override
void initState() { void initState() {
@ -75,7 +75,7 @@ class _AvesAppState extends State<AvesApp> {
final home = initialized final home = initialized
? getFirstPage() ? getFirstPage()
: Scaffold( : Scaffold(
body: snapshot.hasError ? _buildError(snapshot.error!) : SizedBox(), body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(),
); );
return Selector<Settings, Locale?>( return Selector<Settings, Locale?>(
selector: (context, s) => s.locale, selector: (context, s) => s.locale,
@ -108,12 +108,12 @@ class _AvesAppState extends State<AvesApp> {
Widget _buildError(Object error) { Widget _buildError(Object error) {
return Container( return Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Icon(AIcons.error), const Icon(AIcons.error),
SizedBox(height: 16), const SizedBox(height: 16),
Text(error.toString()), Text(error.toString()),
], ],
), ),
@ -151,7 +151,7 @@ class _AvesAppState extends State<AvesApp> {
FirebaseCrashlytics.instance.log('New intent'); FirebaseCrashlytics.instance.log('New intent');
_navigatorKey.currentState!.pushReplacement(DirectMaterialPageRoute( _navigatorKey.currentState!.pushReplacement(DirectMaterialPageRoute(
settings: RouteSettings(name: HomePage.routeName), settings: const RouteSettings(name: HomePage.routeName),
builder: (_) => getFirstPage(intentData: intentData), builder: (_) => getFirstPage(intentData: intentData),
)); ));
} }

View file

@ -137,7 +137,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
tooltip = MaterialLocalizations.of(context).backButtonTooltip; tooltip = MaterialLocalizations.of(context).backButtonTooltip;
} }
return IconButton( return IconButton(
key: Key('appbar-leading-button'), key: const Key('appbar-leading-button'),
icon: AnimatedIcon( icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow, icon: AnimatedIcons.menu_arrow,
progress: _browseToSelectAnimation, progress: _browseToSelectAnimation,
@ -197,19 +197,19 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
builder: (context, snapshot) { builder: (context, snapshot) {
final canAddShortcuts = snapshot.data ?? false; final canAddShortcuts = snapshot.data ?? false;
return PopupMenuButton<CollectionAction>( return PopupMenuButton<CollectionAction>(
key: Key('appbar-menu-button'), key: const Key('appbar-menu-button'),
itemBuilder: (context) { itemBuilder: (context) {
final isNotEmpty = !collection.isEmpty; final isNotEmpty = !collection.isEmpty;
final hasSelection = collection.selection.isNotEmpty; final hasSelection = collection.selection.isNotEmpty;
return [ return [
PopupMenuItem( PopupMenuItem(
key: Key('menu-sort'), key: const Key('menu-sort'),
value: CollectionAction.sort, value: CollectionAction.sort,
child: MenuRow(text: context.l10n.menuActionSort, icon: AIcons.sort), child: MenuRow(text: context.l10n.menuActionSort, icon: AIcons.sort),
), ),
if (collection.sortFactor == EntrySortFactor.date) if (collection.sortFactor == EntrySortFactor.date)
PopupMenuItem( PopupMenuItem(
key: Key('menu-group'), key: const Key('menu-group'),
value: CollectionAction.group, value: CollectionAction.group,
child: MenuRow(text: context.l10n.menuActionGroup, icon: AIcons.group), child: MenuRow(text: context.l10n.menuActionGroup, icon: AIcons.group),
), ),
@ -231,7 +231,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
), ),
], ],
if (collection.isSelecting) ...[ if (collection.isSelecting) ...[
PopupMenuDivider(), const PopupMenuDivider(),
PopupMenuItem( PopupMenuItem(
value: CollectionAction.copy, value: CollectionAction.copy,
enabled: hasSelection, enabled: hasSelection,
@ -247,7 +247,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
enabled: hasSelection, enabled: hasSelection,
child: MenuRow(text: context.l10n.collectionActionRefreshMetadata), child: MenuRow(text: context.l10n.collectionActionRefreshMetadata),
), ),
PopupMenuDivider(), const PopupMenuDivider(),
PopupMenuItem( PopupMenuItem(
value: CollectionAction.selectAll, value: CollectionAction.selectAll,
enabled: collection.selection.length < collection.entryCount, enabled: collection.selection.length < collection.entryCount,
@ -390,7 +390,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: StatsPage.routeName), settings: const RouteSettings(name: StatsPage.routeName),
builder: (context) => StatsPage( builder: (context) => StatsPage(
source: source, source: source,
parentCollection: collection, parentCollection: collection,

View file

@ -318,7 +318,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> {
primary: true, primary: true,
// workaround to prevent scrolling the app bar away // workaround to prevent scrolling the app bar away
// when there is no content and we use `SliverFillRemaining` // when there is no content and we use `SliverFillRemaining`
physics: collection.isEmpty ? NeverScrollableScrollPhysics() : SloppyScrollPhysics(parent: AlwaysScrollableScrollPhysics()), physics: collection.isEmpty ? const NeverScrollableScrollPhysics() : const SloppyScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
cacheExtent: context.select<TileExtentController, double>((controller) => controller.effectiveExtentMax), cacheExtent: context.select<TileExtentController, double>((controller) => controller.effectiveExtentMax),
slivers: [ slivers: [
appBar, appBar,
@ -327,7 +327,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> {
hasScrollBody: false, hasScrollBody: false,
child: _buildEmptyCollectionPlaceholder(collection), child: _buildEmptyCollectionPlaceholder(collection),
) )
: SectionedListSliver<AvesEntry>(), : const SectionedListSliver<AvesEntry>(),
BottomPaddingSliver(), BottomPaddingSliver(),
], ],
); );
@ -338,7 +338,7 @@ class _CollectionScrollViewState extends State<_CollectionScrollView> {
valueListenable: collection.source.stateNotifier, valueListenable: collection.source.stateNotifier,
builder: (context, sourceState, child) { builder: (context, sourceState, child) {
if (sourceState == SourceState.loading) { if (sourceState == SourceState.loading) {
return SizedBox.shrink(); return const SizedBox.shrink();
} }
if (collection.filters.any((filter) => filter is FavouriteFilter)) { if (collection.filters.any((filter) => filter is FavouriteFilter)) {
return EmptyContent( return EmptyContent(

View file

@ -46,7 +46,7 @@ class _CollectionPageState extends State<CollectionPage> {
bottom: false, bottom: false,
child: ChangeNotifierProvider<CollectionLens>.value( child: ChangeNotifierProvider<CollectionLens>.value(
value: collection, value: collection,
child: CollectionGrid( child: const CollectionGrid(
key: Key('collection-grid'), key: Key('collection-grid'),
), ),
), ),

View file

@ -81,7 +81,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
final destinationAlbum = await Navigator.push( final destinationAlbum = await Navigator.push(
context, context,
MaterialPageRoute<String>( MaterialPageRoute<String>(
settings: RouteSettings(name: AlbumPickPage.routeName), settings: const RouteSettings(name: AlbumPickPage.routeName),
builder: (context) => AlbumPickPage(source: source, moveType: moveType), builder: (context) => AlbumPickPage(source: source, moveType: moveType),
), ),
); );

View file

@ -20,7 +20,7 @@ class FilterBar extends StatefulWidget implements PreferredSizeWidget {
super(key: key); super(key: key);
@override @override
final Size preferredSize = Size.fromHeight(preferredHeight); final Size preferredSize = const Size.fromHeight(preferredHeight);
@override @override
_FilterBarState createState() => _FilterBarState(); _FilterBarState createState() => _FilterBarState();
@ -92,10 +92,10 @@ class _FilterBarState extends State<FilterBar> {
key: _animatedListKey, key: _animatedListKey,
initialItemCount: widget.filters.length, initialItemCount: widget.filters.length,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
padding: EdgeInsets.only(left: 8), padding: const EdgeInsets.only(left: 8),
itemBuilder: (context, index, animation) { itemBuilder: (context, index, animation) {
if (index >= widget.filters.length) return SizedBox(); if (index >= widget.filters.length) return const SizedBox();
return _buildChip(widget.filters.toList()[index]); return _buildChip(widget.filters.toList()[index]);
}, },
), ),
@ -105,7 +105,7 @@ class _FilterBarState extends State<FilterBar> {
Padding _buildChip(CollectionFilter filter) { Padding _buildChip(CollectionFilter filter) {
return Padding( return Padding(
padding: EdgeInsets.only(right: 8), padding: const EdgeInsets.only(right: 8),
child: Center( child: Center(
child: AvesFilterChip( child: AvesFilterChip(
key: ValueKey(filter), key: ValueKey(filter),

View file

@ -38,7 +38,7 @@ class AlbumSectionHeader extends StatelessWidget {
leading: albumIcon, leading: albumIcon,
title: albumName ?? context.l10n.sectionUnknown, title: albumName ?? context.l10n.sectionUnknown,
trailing: directory != null && androidFileUtils.isOnRemovableStorage(directory!) trailing: directory != null && androidFileUtils.isOnRemovableStorage(directory!)
? Icon( ? const Icon(
AIcons.removableStorage, AIcons.removableStorage,
size: 16, size: 16,
color: Color(0xFF757575), color: Color(0xFF757575),

View file

@ -29,7 +29,7 @@ class CollectionSectionHeader extends StatelessWidget {
height: height, height: height,
child: header, child: header,
) )
: SizedBox.shrink(); : const SizedBox.shrink();
} }
Widget? _buildHeader(BuildContext context) { Widget? _buildHeader(BuildContext context) {

View file

@ -66,7 +66,7 @@ class InteractiveThumbnail extends StatelessWidget {
Navigator.push( Navigator.push(
context, context,
TransparentMaterialPageRoute( TransparentMaterialPageRoute(
settings: RouteSettings(name: EntryViewerPage.routeName), settings: const RouteSettings(name: EntryViewerPage.routeName),
pageBuilder: (c, a, sa) { pageBuilder: (c, a, sa) {
final viewerCollection = CollectionLens( final viewerCollection = CollectionLens(
source: collection.source, source: collection.source,

View file

@ -60,10 +60,10 @@ class DecoratedThumbnail extends StatelessWidget {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.fromBorderSide(BorderSide(
color: borderColor, color: borderColor,
width: borderWidth, width: borderWidth,
), )),
), ),
width: tileExtent, width: tileExtent,
height: tileExtent, height: tileExtent,

View file

@ -43,7 +43,7 @@ class _ErrorThumbnailState extends State<ErrorThumbnail> {
builder: (context, snapshot) { builder: (context, snapshot) {
Widget child; Widget child;
if (snapshot.connectionState != ConnectionState.done) { if (snapshot.connectionState != ConnectionState.done) {
child = SizedBox(); child = const SizedBox();
} else { } else {
final exists = snapshot.data!; final exists = snapshot.data!;
child = Tooltip( child = Tooltip(

View file

@ -23,21 +23,21 @@ class ThumbnailEntryOverlay extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final children = [ final children = [
if (entry.hasGps && context.select<ThumbnailThemeData, bool>((t) => t.showLocation)) GpsIcon(), if (entry.hasGps && context.select<ThumbnailThemeData, bool>((t) => t.showLocation)) const GpsIcon(),
if (entry.isVideo) if (entry.isVideo)
VideoIcon( VideoIcon(
entry: entry, entry: entry,
) )
else if (entry.isAnimated) else if (entry.isAnimated)
AnimatedImageIcon() const AnimatedImageIcon()
else ...[ else ...[
if (entry.isRaw && context.select<ThumbnailThemeData, bool>((t) => t.showRaw)) RawIcon(), if (entry.isRaw && context.select<ThumbnailThemeData, bool>((t) => t.showRaw)) const RawIcon(),
if (entry.isMultiPage) MultiPageIcon(entry: entry), if (entry.isMultiPage) MultiPageIcon(entry: entry),
if (entry.isGeotiff) GeotiffIcon(), if (entry.isGeotiff) const GeotiffIcon(),
if (entry.is360) SphericalImageIcon(), if (entry.is360) const SphericalImageIcon(),
] ]
]; ];
if (children.isEmpty) return SizedBox.shrink(); if (children.isEmpty) return const SizedBox.shrink();
if (children.length == 1) return children.first; if (children.length == 1) return children.first;
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -74,7 +74,7 @@ class ThumbnailSelectionOverlay extends StatelessWidget {
icon: selected ? AIcons.selected : AIcons.unselected, icon: selected ? AIcons.selected : AIcons.unselected,
size: context.select<ThumbnailThemeData, double>((t) => t.iconSize), size: context.select<ThumbnailThemeData, double>((t) => t.iconSize),
) )
: SizedBox.shrink(); : const SizedBox.shrink();
child = AnimatedSwitcher( child = AnimatedSwitcher(
duration: duration, duration: duration,
switchInCurve: Curves.easeOutBack, switchInCurve: Curves.easeOutBack,
@ -94,7 +94,7 @@ class ThumbnailSelectionOverlay extends StatelessWidget {
return child; return child;
}, },
) )
: SizedBox.shrink(); : const SizedBox.shrink();
return AnimatedSwitcher( return AnimatedSwitcher(
duration: duration, duration: duration,
child: child, child: child,
@ -130,10 +130,10 @@ class _ThumbnailHighlightOverlayState extends State<ThumbnailHighlightOverlay> {
return Sweeper( return Sweeper(
builder: (context) => Container( builder: (context) => Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.fromBorderSide(BorderSide(
color: Theme.of(context).accentColor, color: Theme.of(context).accentColor,
width: context.select<ThumbnailThemeData, double>((t) => t.highlightBorderWidth), width: context.select<ThumbnailThemeData, double>((t) => t.highlightBorderWidth),
), )),
), ),
), ),
toggledNotifier: _highlightedNotifier, toggledNotifier: _highlightedNotifier,

View file

@ -103,7 +103,7 @@ class _ReportOverlayState<T> extends State<ReportOverlay<T>> with SingleTickerPr
return FadeTransition( return FadeTransition(
opacity: _animation, opacity: _animation,
child: Container( child: Container(
decoration: BoxDecoration( decoration: const BoxDecoration(
gradient: RadialGradient( gradient: RadialGradient(
colors: [ colors: [
Colors.black, Colors.black,

View file

@ -34,7 +34,7 @@ class SourceStateAwareAppBarTitle extends StatelessWidget {
), ),
), ),
child: sourceState == SourceState.ready child: sourceState == SourceState.ready
? SizedBox.shrink() ? const SizedBox.shrink()
: SourceStateSubtitle( : SourceStateSubtitle(
source: source, source: source,
), ),
@ -70,7 +70,7 @@ class SourceStateSubtitle extends StatelessWidget {
} }
final subtitleStyle = Theme.of(context).textTheme.caption; final subtitleStyle = Theme.of(context).textTheme.caption;
return subtitle == null return subtitle == null
? SizedBox.shrink() ? const SizedBox.shrink()
: Row( : Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -78,10 +78,10 @@ class SourceStateSubtitle extends StatelessWidget {
StreamBuilder<ProgressEvent>( StreamBuilder<ProgressEvent>(
stream: source.progressStream, stream: source.progressStream,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasError || !snapshot.hasData) return SizedBox.shrink(); if (snapshot.hasError || !snapshot.hasData) return const SizedBox.shrink();
final progress = snapshot.data!; final progress = snapshot.data!;
return Padding( return Padding(
padding: EdgeInsetsDirectional.only(start: 8), padding: const EdgeInsetsDirectional.only(start: 8),
child: Text( child: Text(
'${progress.done}/${progress.total}', '${progress.done}/${progress.total}',
style: subtitleStyle!.copyWith(color: Colors.white30), style: subtitleStyle!.copyWith(color: Colors.white30),

View file

@ -17,7 +17,7 @@ class InteractiveAppBarTitle extends StatelessWidget {
// so that we can also detect taps around the title `Text` // so that we can also detect taps around the title `Text`
child: Container( child: Container(
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
padding: EdgeInsets.symmetric(horizontal: NavigationToolbar.kMiddleSpacing), padding: const EdgeInsets.symmetric(horizontal: NavigationToolbar.kMiddleSpacing),
color: Colors.transparent, color: Colors.transparent,
height: kToolbarHeight, height: kToolbarHeight,
child: child, child: child,

View file

@ -89,7 +89,7 @@ class DraggableScrollbar extends StatefulWidget {
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
child: labelText, child: labelText,
), ),
SizedBox(width: 24), const SizedBox(width: 24),
scrollThumb, scrollThumb,
], ],
); );
@ -117,11 +117,11 @@ class ScrollLabel extends StatelessWidget {
return FadeTransition( return FadeTransition(
opacity: animation, opacity: animation,
child: Container( child: Container(
margin: EdgeInsets.only(right: 12.0), margin: const EdgeInsets.only(right: 12.0),
child: Material( child: Material(
elevation: 4.0, elevation: 4.0,
color: backgroundColor, color: backgroundColor,
borderRadius: BorderRadius.circular(16), borderRadius: const BorderRadius.all(Radius.circular(16)),
child: child, child: child,
), ),
), ),
@ -386,8 +386,8 @@ class SlideFadeTransition extends StatelessWidget {
builder: (context, child) => animation.value == 0.0 ? Container() : child!, builder: (context, child) => animation.value == 0.0 ? Container() : child!,
child: SlideTransition( child: SlideTransition(
position: Tween( position: Tween(
begin: Offset(0.3, 0.0), begin: const Offset(0.3, 0.0),
end: Offset(0.0, 0.0), end: const Offset(0.0, 0.0),
).animate(animation), ).animate(animation),
child: FadeTransition( child: FadeTransition(
opacity: animation, opacity: animation,

View file

@ -17,7 +17,7 @@ class BottomGestureAreaProtector extends StatelessWidget {
right: 0, right: 0,
bottom: 0, bottom: 0,
height: systemGestureBottom, height: systemGestureBottom,
child: AbsorbPointer(), child: const AbsorbPointer(),
); );
}, },
); );

View file

@ -9,7 +9,7 @@ class LinkChip extends StatelessWidget {
final Color? color; final Color? color;
final TextStyle? textStyle; final TextStyle? textStyle;
static final borderRadius = BorderRadius.circular(8); static const borderRadius = BorderRadius.all(Radius.circular(8));
const LinkChip({ const LinkChip({
Key? key, Key? key,
@ -23,7 +23,7 @@ class LinkChip extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DefaultTextStyle.merge( return DefaultTextStyle.merge(
style: (textStyle ?? TextStyle()).copyWith(color: color), style: (textStyle ?? const TextStyle()).copyWith(color: color),
child: InkWell( child: InkWell(
borderRadius: borderRadius, borderRadius: borderRadius,
onTap: () async { onTap: () async {
@ -32,13 +32,13 @@ class LinkChip extends StatelessWidget {
} }
}, },
child: Padding( child: Padding(
padding: EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (leading != null) ...[ if (leading != null) ...[
leading!, leading!,
SizedBox(width: 8), const SizedBox(width: 8),
], ],
Flexible( Flexible(
child: Text( child: Text(
@ -48,7 +48,7 @@ class LinkChip extends StatelessWidget {
maxLines: 1, maxLines: 1,
), ),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
Builder( Builder(
builder: (context) => Icon( builder: (context) => Icon(
AIcons.openOutside, AIcons.openOutside,

View file

@ -24,11 +24,11 @@ class MenuRow extends StatelessWidget {
opacity: checked! ? 1 : 0, opacity: checked! ? 1 : 0,
child: Icon(AIcons.checked, size: iconSize), child: Icon(AIcons.checked, size: iconSize),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
], ],
if (icon != null) ...[ if (icon != null) ...[
Icon(icon, size: iconSize), Icon(icon, size: iconSize),
SizedBox(width: 8), const SizedBox(width: 8),
], ],
Expanded(child: Text(text)), Expanded(child: Text(text)),
], ],

View file

@ -26,7 +26,7 @@ class _MultiCrossFaderState extends State<MultiCrossFader> {
void initState() { void initState() {
super.initState(); super.initState();
_first = widget.child; _first = widget.child;
_second = SizedBox(); _second = const SizedBox();
} }
@override @override

View file

@ -30,7 +30,7 @@ class _QueryBarState extends State<QueryBar> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final clearButton = IconButton( final clearButton = IconButton(
icon: Icon(AIcons.clear), icon: const Icon(AIcons.clear),
onPressed: () { onPressed: () {
_controller.clear(); _controller.clear();
filterNotifier.value = ''; filterNotifier.value = '';
@ -45,7 +45,7 @@ class _QueryBarState extends State<QueryBar> {
child: TextField( child: TextField(
controller: _controller, controller: _controller,
decoration: InputDecoration( decoration: InputDecoration(
icon: Padding( icon: const Padding(
padding: EdgeInsetsDirectional.only(start: 16), padding: EdgeInsetsDirectional.only(start: 16),
child: Icon(AIcons.search), child: Icon(AIcons.search),
), ),
@ -57,7 +57,7 @@ class _QueryBarState extends State<QueryBar> {
), ),
), ),
ConstrainedBox( ConstrainedBox(
constraints: BoxConstraints(minWidth: 16), constraints: const BoxConstraints(minWidth: 16),
child: ValueListenableBuilder<TextEditingValue>( child: ValueListenableBuilder<TextEditingValue>(
valueListenable: _controller, valueListenable: _controller,
builder: (context, value, child) => AnimatedSwitcher( builder: (context, value, child) => AnimatedSwitcher(
@ -70,7 +70,7 @@ class _QueryBarState extends State<QueryBar> {
child: child, child: child,
), ),
), ),
child: value.text.isNotEmpty ? clearButton : SizedBox.shrink(), child: value.text.isNotEmpty ? clearButton : const SizedBox.shrink(),
), ),
), ),
) )

View file

@ -40,7 +40,7 @@ class BlurredRRect extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ClipRRect( return ClipRRect(
borderRadius: BorderRadius.circular(borderRadius), borderRadius: BorderRadius.all(Radius.circular(borderRadius)),
child: BackdropFilter( child: BackdropFilter(
filter: _filter, filter: _filter,
child: child, child: child,

View file

@ -17,7 +17,7 @@ class DraggableThumbLabel<T> extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final sll = context.read<SectionedListLayout<T>>(); final sll = context.read<SectionedListLayout<T>>();
final sectionLayout = sll.getSectionAt(offsetY); final sectionLayout = sll.getSectionAt(offsetY);
if (sectionLayout == null) return SizedBox(); if (sectionLayout == null) return const SizedBox();
final section = sll.sections[sectionLayout.sectionKey]!; final section = sll.sections[sectionLayout.sectionKey]!;
final dy = offsetY - (sectionLayout.minOffset + sectionLayout.headerExtent); final dy = offsetY - (sectionLayout.minOffset + sectionLayout.headerExtent);
@ -25,12 +25,12 @@ class DraggableThumbLabel<T> extends StatelessWidget {
final item = section[itemIndex]; final item = section[itemIndex];
final lines = lineBuilder(context, item); final lines = lineBuilder(context, item);
if (lines.isEmpty) return SizedBox(); if (lines.isEmpty) return const SizedBox();
return ConstrainedBox( return ConstrainedBox(
constraints: BoxConstraints(maxWidth: 140), constraints: const BoxConstraints(maxWidth: 140),
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
child: lines.length > 1 child: lines.length > 1
? Column( ? Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -44,7 +44,7 @@ class DraggableThumbLabel<T> extends StatelessWidget {
Widget _buildText(String text) => Text( Widget _buildText(String text) => Text(
text, text,
style: TextStyle( style: const TextStyle(
color: Colors.black, color: Colors.black,
), ),
softWrap: false, softWrap: false,

View file

@ -35,7 +35,7 @@ class SectionHeader extends StatelessWidget {
return Container( return Container(
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
padding: padding, padding: padding,
constraints: BoxConstraints(minHeight: leadingDimension), constraints: const BoxConstraints(minHeight: leadingDimension),
child: GestureDetector( child: GestureDetector(
onTap: selectable ? () => _toggleSectionSelection(context) : null, onTap: selectable ? () => _toggleSectionSelection(context) : null,
child: Text.rich( child: Text.rich(
@ -158,12 +158,12 @@ class _SectionSelectableLeading extends StatelessWidget {
), ),
child: IconButton( child: IconButton(
iconSize: 26, iconSize: 26,
padding: EdgeInsets.only(top: 1), padding: const EdgeInsets.only(top: 1),
alignment: AlignmentDirectional.topStart, alignment: AlignmentDirectional.topStart,
icon: Icon(selected ? AIcons.selected : AIcons.unselected), icon: Icon(selected ? AIcons.selected : AIcons.unselected),
onPressed: onPressed, onPressed: onPressed,
tooltip: selected ? context.l10n.collectionDeselectSectionTooltip : context.l10n.collectionSelectSectionTooltip, tooltip: selected ? context.l10n.collectionDeselectSectionTooltip : context.l10n.collectionSelectSectionTooltip,
constraints: BoxConstraints( constraints: const BoxConstraints(
minHeight: leadingDimension, minHeight: leadingDimension,
minWidth: leadingDimension, minWidth: leadingDimension,
), ),
@ -208,5 +208,5 @@ class _SectionSelectableLeading extends StatelessWidget {
); );
} }
Widget _buildBrowsing(BuildContext context) => browsingBuilder?.call(context) ?? SizedBox(height: leadingDimension); Widget _buildBrowsing(BuildContext context) => browsingBuilder?.call(context) ?? const SizedBox(height: leadingDimension);
} }

View file

@ -106,7 +106,7 @@ abstract class SectionedListLayoutProvider<T> extends StatelessWidget {
bool animate, bool animate,
) { ) {
if (sectionChildIndex == 0) { if (sectionChildIndex == 0) {
final header = headerExtent > 0 ? buildHeader(context, sectionKey, headerExtent) : SizedBox.shrink(); final header = headerExtent > 0 ? buildHeader(context, sectionKey, headerExtent) : const SizedBox.shrink();
return animate ? _buildAnimation(sectionGridIndex, header) : header; return animate ? _buildAnimation(sectionGridIndex, header) : header;
} }
sectionChildIndex--; sectionChildIndex--;

View file

@ -26,7 +26,7 @@ class SectionedListSliver<T> extends StatelessWidget {
(context, index) { (context, index) {
if (index >= childCount) return null; if (index >= childCount) return null;
final sectionLayout = sectionLayouts.firstWhereOrNull((section) => section.hasChild(index)); final sectionLayout = sectionLayouts.firstWhereOrNull((section) => section.hasChild(index));
return sectionLayout?.builder(context, index) ?? SizedBox.shrink(); return sectionLayout?.builder(context, index) ?? const SizedBox.shrink();
}, },
childCount: childCount, childCount: childCount,
addAutomaticKeepAlives: false, addAutomaticKeepAlives: false,

View file

@ -35,7 +35,7 @@ class AvesExpansionTile extends StatelessWidget {
titleChild = Row( titleChild = Row(
children: [ children: [
leading!, leading!,
SizedBox(width: 8), const SizedBox(width: 8),
Expanded(child: titleChild), Expanded(child: titleChild),
], ],
); );
@ -52,15 +52,15 @@ class AvesExpansionTile extends StatelessWidget {
title: titleChild, title: titleChild,
expandable: enabled, expandable: enabled,
initiallyExpanded: initiallyExpanded, initiallyExpanded: initiallyExpanded,
finalPadding: EdgeInsets.symmetric(vertical: 6.0), finalPadding: const EdgeInsets.symmetric(vertical: 6.0),
baseColor: Colors.grey.shade900, baseColor: Colors.grey.shade900,
expandedColor: Colors.grey[850], expandedColor: Colors.grey[850],
shadowColor: Theme.of(context).shadowColor, shadowColor: Theme.of(context).shadowColor,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Divider(thickness: 1, height: 1), const Divider(thickness: 1, height: 1),
SizedBox(height: 4), const SizedBox(height: 4),
if (enabled) ...children, if (enabled) ...children,
], ],
), ),

View file

@ -65,7 +65,7 @@ class AvesFilterChip extends StatefulWidget {
FocusManager.instance.primaryFocus?.unfocus(); FocusManager.instance.primaryFocus?.unfocus();
final overlay = Overlay.of(context)!.context.findRenderObject() as RenderBox; final overlay = Overlay.of(context)!.context.findRenderObject() as RenderBox;
final touchArea = Size(40, 40); const touchArea = Size(40, 40);
final selectedAction = await showMenu<ChipAction>( final selectedAction = await showMenu<ChipAction>(
context: context, context: context,
position: RelativeRect.fromRect(tapPosition & touchArea, Offset.zero & overlay.size), position: RelativeRect.fromRect(tapPosition & touchArea, Offset.zero & overlay.size),
@ -186,7 +186,7 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
color: Colors.black54, color: Colors.black54,
child: DefaultTextStyle( child: DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2!.copyWith( style: Theme.of(context).textTheme.bodyText2!.copyWith(
shadows: [Constants.embossShadow], shadows: Constants.embossShadows,
), ),
child: content, child: content,
), ),
@ -194,9 +194,9 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
); );
} }
final borderRadius = widget.borderRadius ?? BorderRadius.circular(AvesFilterChip.defaultRadius); final borderRadius = widget.borderRadius ?? const BorderRadius.all(Radius.circular(AvesFilterChip.defaultRadius));
Widget chip = Container( Widget chip = Container(
constraints: BoxConstraints( constraints: const BoxConstraints(
minWidth: AvesFilterChip.minChipWidth, minWidth: AvesFilterChip.minChipWidth,
maxWidth: AvesFilterChip.maxChipWidth, maxWidth: AvesFilterChip.maxChipWidth,
minHeight: AvesFilterChip.minChipHeight, minHeight: AvesFilterChip.minChipHeight,
@ -237,15 +237,15 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
} }
return DecoratedBox( return DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.fromBorderSide(BorderSide(
color: _outlineColor, color: _outlineColor,
width: AvesFilterChip.outlineWidth, width: AvesFilterChip.outlineWidth,
), )),
borderRadius: borderRadius, borderRadius: borderRadius,
), ),
position: DecorationPosition.foreground, position: DecorationPosition.foreground,
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
child: content, child: content,
), ),
); );
@ -263,7 +263,7 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
tag: filter, tag: filter,
transitionOnUserGestures: true, transitionOnUserGestures: true,
child: DefaultTextStyle( child: DefaultTextStyle(
style: TextStyle(), style: const TextStyle(),
child: chip, child: chip,
), ),
); );

View file

@ -150,11 +150,11 @@ class OverlayIcon extends StatelessWidget {
); );
return Container( return Container(
margin: EdgeInsets.all(1), margin: const EdgeInsets.all(1),
padding: text != null ? EdgeInsets.only(right: size / 4) : null, padding: text != null ? EdgeInsets.only(right: size / 4) : null,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color(0xBB000000), color: const Color(0xBB000000),
borderRadius: BorderRadius.circular(size), borderRadius: BorderRadius.all(Radius.circular(size)),
), ),
child: text == null child: text == null
? iconBox ? iconBox
@ -163,7 +163,7 @@ class OverlayIcon extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
iconBox, iconBox,
SizedBox(width: 2), const SizedBox(width: 2),
Text(text!), Text(text!),
], ],
), ),
@ -187,7 +187,7 @@ class IconUtils {
data: context.read<MediaQueryData>().copyWith(textScaleFactor: 1.0), data: context.read<MediaQueryData>().copyWith(textScaleFactor: 1.0),
child: DecoratedIcon( child: DecoratedIcon(
icon, icon,
shadows: [Constants.embossShadow], shadows: Constants.embossShadows,
size: size, size: size,
), ),
) )

View file

@ -25,11 +25,11 @@ class EmptyContent extends StatelessWidget {
size: 64, size: 64,
color: color, color: color,
), ),
SizedBox(height: 16) const SizedBox(height: 16)
], ],
Text( Text(
text, text,
style: TextStyle( style: const TextStyle(
color: color, color: color,
fontSize: 22, fontSize: 22,
), ),

View file

@ -25,7 +25,7 @@ class HighlightTitle extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final style = TextStyle( final style = TextStyle(
shadows: [ shadows: const [
Shadow( Shadow(
color: Colors.black, color: Colors.black,
offset: Offset(1, 1), offset: Offset(1, 1),
@ -34,7 +34,7 @@ class HighlightTitle extends StatelessWidget {
], ],
fontSize: fontSize, fontSize: fontSize,
letterSpacing: 1.0, letterSpacing: 1.0,
fontFeatures: [FontFeature.enable('smcp')], fontFeatures: const [FontFeature.enable('smcp')],
); );
return Align( return Align(
@ -45,7 +45,7 @@ class HighlightTitle extends StatelessWidget {
color: enabled ? color ?? stringToColor(title) : disabledColor, color: enabled ? color ?? stringToColor(title) : disabledColor,
) )
: null, : null,
margin: EdgeInsets.symmetric(vertical: 4.0), margin: const EdgeInsets.symmetric(vertical: 4.0),
child: selectable child: selectable
? SelectableText( ? SelectableText(
title, title,

View file

@ -10,20 +10,20 @@ ScrollThumbBuilder avesScrollThumbBuilder({
required Color backgroundColor, required Color backgroundColor,
}) { }) {
final scrollThumb = Container( final scrollThumb = Container(
decoration: BoxDecoration( decoration: const BoxDecoration(
color: Colors.black26, color: Colors.black26,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.all(Radius.circular(12)),
), ),
height: height, height: height,
margin: EdgeInsets.only(right: .5), margin: const EdgeInsets.only(right: .5),
padding: EdgeInsets.all(2), padding: const EdgeInsets.all(2),
child: ClipPath( child: ClipPath(
clipper: ArrowClipper(), clipper: ArrowClipper(),
child: Container( child: Container(
width: 20.0, width: 20.0,
decoration: BoxDecoration( decoration: BoxDecoration(
color: backgroundColor, color: backgroundColor,
borderRadius: BorderRadius.circular(12), borderRadius: const BorderRadius.all(Radius.circular(12)),
), ),
), ),
), ),

View file

@ -28,7 +28,7 @@ class MagnifierController {
_currentState = initial; _currentState = initial;
_setState(initial); _setState(initial);
final _initialScaleState = ScaleStateChange(state: ScaleState.initial, source: ChangeSource.internal); const _initialScaleState = ScaleStateChange(state: ScaleState.initial, source: ChangeSource.internal);
previousScaleState = _initialScaleState; previousScaleState = _initialScaleState;
_currentScaleState = _initialScaleState; _currentScaleState = _initialScaleState;
_setScaleState(_initialScaleState); _setScaleState(_initialScaleState);

View file

@ -302,7 +302,7 @@ class _CenterWithOriginalSizeDelegate extends SingleChildLayoutDelegate {
@override @override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) { BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return applyScale ? BoxConstraints.tight(subjectSize) : BoxConstraints(); return applyScale ? BoxConstraints.tight(subjectSize) : const BoxConstraints();
} }
@override @override

View file

@ -14,7 +14,7 @@ mixin CornerHitDetector on MagnifierControllerDelegate {
final childWidth = scaleBoundaries.childSize.width * scale!; final childWidth = scaleBoundaries.childSize.width * scale!;
final viewportWidth = scaleBoundaries.viewportSize.width; final viewportWidth = scaleBoundaries.viewportSize.width;
if (viewportWidth + precisionErrorTolerance >= childWidth) { if (viewportWidth + precisionErrorTolerance >= childWidth) {
return _CornerHit(true, true); return const _CornerHit(true, true);
} }
final x = -position.dx; final x = -position.dx;
final cornersX = this.cornersX(); final cornersX = this.cornersX();
@ -25,7 +25,7 @@ mixin CornerHitDetector on MagnifierControllerDelegate {
final childHeight = scaleBoundaries.childSize.height * scale!; final childHeight = scaleBoundaries.childSize.height * scale!;
final viewportHeight = scaleBoundaries.viewportSize.height; final viewportHeight = scaleBoundaries.viewportSize.height;
if (viewportHeight + precisionErrorTolerance >= childHeight) { if (viewportHeight + precisionErrorTolerance >= childHeight) {
return _CornerHit(true, true); return const _CornerHit(true, true);
} }
final y = -position.dy; final y = -position.dy;
final cornersY = this.cornersY(); final cornersY = this.cornersY();

View file

@ -206,7 +206,7 @@ class _ScaleOverlayState extends State<ScaleOverlay> {
], ],
), ),
) )
: BoxDecoration( : const BoxDecoration(
// provide dummy gradient to lerp to the other one during animation // provide dummy gradient to lerp to the other one during animation
gradient: RadialGradient( gradient: RadialGradient(
colors: [ colors: [
@ -237,7 +237,7 @@ class _ScaleOverlayState extends State<ScaleOverlay> {
left: clampedCenter.dx - extent / 2, left: clampedCenter.dx - extent / 2,
top: clampedCenter.dy - extent / 2, top: clampedCenter.dy - extent / 2,
child: DefaultTextStyle( child: DefaultTextStyle(
style: TextStyle(), style: const TextStyle(),
child: child, child: child,
), ),
), ),

View file

@ -30,15 +30,15 @@ class _DebugAndroidAppSectionState extends State<DebugAndroidAppSection> with Au
title: 'Android Apps', title: 'Android Apps',
children: [ children: [
Padding( Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: FutureBuilder<Set<Package>>( child: FutureBuilder<Set<Package>>(
future: _loader, future: _loader,
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final packages = snapshot.data!.toList()..sort((a, b) => compareAsciiUpperCase(a.packageName, b.packageName)); final packages = snapshot.data!.toList()..sort((a, b) => compareAsciiUpperCase(a.packageName, b.packageName));
final enabledTheme = IconTheme.of(context); final enabledTheme = IconTheme.of(context);
final disabledTheme = enabledTheme.merge(IconThemeData(opacity: .2)); final disabledTheme = enabledTheme.merge(const IconThemeData(opacity: .2));
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: packages.map((package) { children: packages.map((package) {
@ -64,7 +64,7 @@ class _DebugAndroidAppSectionState extends State<DebugAndroidAppSection> with Au
alignment: PlaceholderAlignment.middle, alignment: PlaceholderAlignment.middle,
child: IconTheme( child: IconTheme(
data: package.categoryLauncher ? enabledTheme : disabledTheme, data: package.categoryLauncher ? enabledTheme : disabledTheme,
child: Icon( child: const Icon(
Icons.launch_outlined, Icons.launch_outlined,
size: iconSize, size: iconSize,
), ),
@ -74,7 +74,7 @@ class _DebugAndroidAppSectionState extends State<DebugAndroidAppSection> with Au
alignment: PlaceholderAlignment.middle, alignment: PlaceholderAlignment.middle,
child: IconTheme( child: IconTheme(
data: package.isSystem ? enabledTheme : disabledTheme, data: package.isSystem ? enabledTheme : disabledTheme,
child: Icon( child: const Icon(
Icons.android, Icons.android,
size: iconSize, size: iconSize,
), ),

View file

@ -27,12 +27,12 @@ class _DebugAndroidDirSectionState extends State<DebugAndroidDirSection> with Au
title: 'Android Dirs', title: 'Android Dirs',
children: [ children: [
Padding( Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: FutureBuilder<Map>( child: FutureBuilder<Map>(
future: _loader, future: _loader,
builder: (context, 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 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')));
return InfoRowGroup(data); return InfoRowGroup(data);
}, },

View file

@ -27,12 +27,12 @@ class _DebugAndroidEnvironmentSectionState extends State<DebugAndroidEnvironment
title: 'Android Environment', title: 'Android Environment',
children: [ children: [
Padding( Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: FutureBuilder<Map>( child: FutureBuilder<Map>(
future: _loader, future: _loader,
builder: (context, 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 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')));
return InfoRowGroup(data); return InfoRowGroup(data);
}, },

View file

@ -35,11 +35,11 @@ class _AppDebugPageState extends State<AppDebugPage> {
return MediaQueryDataProvider( return MediaQueryDataProvider(
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('Debug'), title: const Text('Debug'),
), ),
body: SafeArea( body: SafeArea(
child: ListView( child: ListView(
padding: EdgeInsets.all(8), padding: const EdgeInsets.all(8),
children: [ children: [
_buildGeneralTabView(), _buildGeneralTabView(),
DebugAndroidAppSection(), DebugAndroidAppSection(),
@ -65,7 +65,7 @@ class _AppDebugPageState extends State<AppDebugPage> {
return AvesExpansionTile( return AvesExpansionTile(
title: 'General', title: 'General',
children: [ children: [
Padding( const Padding(
padding: EdgeInsets.all(8), padding: EdgeInsets.all(8),
child: Text('Time dilation'), child: Text('Time dilation'),
), ),
@ -91,11 +91,11 @@ class _AppDebugPageState extends State<AppDebugPage> {
} }
setState(() {}); setState(() {});
}, },
title: Text('Show tasks overlay'), title: const Text('Show tasks overlay'),
), ),
Divider(), const Divider(),
Padding( Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: InfoRowGroup( child: InfoRowGroup(
{ {
'All entries': '${source.allEntries.length}', 'All entries': '${source.allEntries.length}',

View file

@ -18,7 +18,7 @@ class _DebugCacheSectionState extends State<DebugCacheSection> with AutomaticKee
title: 'Cache', title: 'Cache',
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column( child: Column(
children: [ children: [
Row( Row(
@ -26,14 +26,14 @@ class _DebugCacheSectionState extends State<DebugCacheSection> with AutomaticKee
Expanded( Expanded(
child: Text('Image cache:\n\t${imageCache!.currentSize}/${imageCache!.maximumSize} items\n\t${formatFilesize(imageCache!.currentSizeBytes)}/${formatFilesize(imageCache!.maximumSizeBytes)}'), child: Text('Image cache:\n\t${imageCache!.currentSize}/${imageCache!.maximumSize} items\n\t${formatFilesize(imageCache!.currentSizeBytes)}/${formatFilesize(imageCache!.maximumSizeBytes)}'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
imageCache!.clear(); imageCache!.clear();
setState(() {}); setState(() {});
}, },
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
), ),
@ -42,26 +42,26 @@ class _DebugCacheSectionState extends State<DebugCacheSection> with AutomaticKee
Expanded( Expanded(
child: Text('SVG cache: ${PictureProvider.cache.count} items'), child: Text('SVG cache: ${PictureProvider.cache.count} items'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
PictureProvider.cache.clear(); PictureProvider.cache.clear();
setState(() {}); setState(() {});
}, },
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
), ),
Row( Row(
children: [ children: [
Expanded( const Expanded(
child: Text('Glide disk cache: ?'), child: Text('Glide disk cache: ?'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: imageFileService.clearSizedThumbnailDiskCache, onPressed: imageFileService.clearSizedThumbnailDiskCache,
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
), ),

View file

@ -35,7 +35,7 @@ class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with
title: 'Database', title: 'Database',
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column( child: Column(
children: [ children: [
FutureBuilder<int>( FutureBuilder<int>(
@ -43,17 +43,17 @@ class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
children: [ children: [
Expanded( Expanded(
child: Text('DB file size: ${formatFilesize(snapshot.data!)}'), child: Text('DB file size: ${formatFilesize(snapshot.data!)}'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () => metadataDb.reset().then((_) => _startDbReport()), onPressed: () => metadataDb.reset().then((_) => _startDbReport()),
child: Text('Reset'), child: const Text('Reset'),
), ),
], ],
); );
@ -64,17 +64,17 @@ class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
children: [ children: [
Expanded( Expanded(
child: Text('entry rows: ${snapshot.data!.length}'), child: Text('entry rows: ${snapshot.data!.length}'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () => metadataDb.clearEntries().then((_) => _startDbReport()), onPressed: () => metadataDb.clearEntries().then((_) => _startDbReport()),
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
); );
@ -85,17 +85,17 @@ class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
children: [ children: [
Expanded( Expanded(
child: Text('date rows: ${snapshot.data!.length}'), child: Text('date rows: ${snapshot.data!.length}'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () => metadataDb.clearDates().then((_) => _startDbReport()), onPressed: () => metadataDb.clearDates().then((_) => _startDbReport()),
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
); );
@ -106,17 +106,17 @@ class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
children: [ children: [
Expanded( Expanded(
child: Text('metadata rows: ${snapshot.data!.length}'), child: Text('metadata rows: ${snapshot.data!.length}'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () => metadataDb.clearMetadataEntries().then((_) => _startDbReport()), onPressed: () => metadataDb.clearMetadataEntries().then((_) => _startDbReport()),
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
); );
@ -127,17 +127,17 @@ class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
children: [ children: [
Expanded( Expanded(
child: Text('address rows: ${snapshot.data!.length}'), child: Text('address rows: ${snapshot.data!.length}'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () => metadataDb.clearAddresses().then((_) => _startDbReport()), onPressed: () => metadataDb.clearAddresses().then((_) => _startDbReport()),
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
); );
@ -148,17 +148,17 @@ class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
children: [ children: [
Expanded( Expanded(
child: Text('favourite rows: ${snapshot.data!.length} (${favourites.count} in memory)'), child: Text('favourite rows: ${snapshot.data!.length} (${favourites.count} in memory)'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () => favourites.clear().then((_) => _startDbReport()), onPressed: () => favourites.clear().then((_) => _startDbReport()),
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
); );
@ -169,17 +169,17 @@ class _DebugAppDatabaseSectionState extends State<DebugAppDatabaseSection> with
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Row( return Row(
children: [ children: [
Expanded( Expanded(
child: Text('cover rows: ${snapshot.data!.length} (${covers.count} in memory)'), child: Text('cover rows: ${snapshot.data!.length} (${covers.count} in memory)'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () => covers.clear().then((_) => _startDbReport()), onPressed: () => covers.clear().then((_) => _startDbReport()),
child: Text('Clear'), child: const Text('Clear'),
), ),
], ],
); );

View file

@ -12,26 +12,26 @@ class DebugFirebaseSection extends StatelessWidget {
title: 'Firebase', title: 'Firebase',
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row( child: Row(
children: [ children: [
ElevatedButton( ElevatedButton(
onPressed: FirebaseCrashlytics.instance.crash, onPressed: FirebaseCrashlytics.instance.crash,
child: Text('Crash'), child: const Text('Crash'),
), ),
SizedBox(width: 8), const SizedBox(width: 8),
ElevatedButton( ElevatedButton(
onPressed: () => FirebaseAnalytics().logEvent( onPressed: () => FirebaseAnalytics().logEvent(
name: 'debug_test', name: 'debug_test',
parameters: {'time': DateTime.now().toIso8601String()}, parameters: {'time': DateTime.now().toIso8601String()},
), ),
child: Text('Send event'), child: const Text('Send event'),
), ),
], ],
), ),
), ),
Padding( Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: InfoRowGroup({ child: InfoRowGroup({
'Firebase data collection enabled': '${Firebase.app().isAutomaticDataCollectionEnabled}', 'Firebase data collection enabled': '${Firebase.app().isAutomaticDataCollectionEnabled}',
'Crashlytics collection enabled': '${FirebaseCrashlytics.instance.isCrashlyticsCollectionEnabled}', 'Crashlytics collection enabled': '${FirebaseCrashlytics.instance.isCrashlyticsCollectionEnabled}',

View file

@ -6,17 +6,17 @@ class DebugTaskQueueOverlay extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return IgnorePointer( return IgnorePointer(
child: DefaultTextStyle( child: DefaultTextStyle(
style: TextStyle(), style: const TextStyle(),
child: Align( child: Align(
alignment: AlignmentDirectional.bottomStart, alignment: AlignmentDirectional.bottomStart,
child: SafeArea( child: SafeArea(
child: Container( child: Container(
color: Colors.indigo.shade900.withAlpha(0xCC), color: Colors.indigo.shade900.withAlpha(0xCC),
padding: EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: StreamBuilder<QueueState>( child: StreamBuilder<QueueState>(
stream: servicePolicy.queueStream, stream: servicePolicy.queueStream,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return SizedBox.shrink(); if (snapshot.hasError) return const SizedBox.shrink();
final queuedEntries = <MapEntry<dynamic, int>>[]; final queuedEntries = <MapEntry<dynamic, int>>[];
if (snapshot.hasData) { if (snapshot.hasData) {
final state = snapshot.data!; final state = snapshot.data!;

View file

@ -18,19 +18,19 @@ class DebugSettingsSection extends StatelessWidget {
title: 'Settings', title: 'Settings',
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton( child: ElevatedButton(
onPressed: () => settings.reset(), onPressed: () => settings.reset(),
child: Text('Reset'), child: const Text('Reset'),
), ),
), ),
SwitchListTile( SwitchListTile(
value: settings.hasAcceptedTerms, value: settings.hasAcceptedTerms,
onChanged: (v) => settings.hasAcceptedTerms = v, onChanged: (v) => settings.hasAcceptedTerms = v,
title: Text('hasAcceptedTerms'), title: const Text('hasAcceptedTerms'),
), ),
Padding( Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: InfoRowGroup({ child: InfoRowGroup({
'tileExtent - Collection': '${settings.getTileExtent(CollectionPage.routeName)}', 'tileExtent - Collection': '${settings.getTileExtent(CollectionPage.routeName)}',
'tileExtent - Albums': '${settings.getTileExtent(AlbumListPage.routeName)}', 'tileExtent - Albums': '${settings.getTileExtent(AlbumListPage.routeName)}',

View file

@ -33,11 +33,11 @@ class _DebugStorageSectionState extends State<DebugStorageSection> with Automati
final freeSpace = _freeSpaceByVolume[v.path]; final freeSpace = _freeSpaceByVolume[v.path];
return [ return [
Padding( Padding(
padding: EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: Text(v.path), child: Text(v.path),
), ),
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: InfoRowGroup({ child: InfoRowGroup({
'description': '${v.getDescription(context)}', 'description': '${v.getDescription(context)}',
'isPrimary': '${v.isPrimary}', 'isPrimary': '${v.isPrimary}',
@ -46,7 +46,7 @@ class _DebugStorageSectionState extends State<DebugStorageSection> with Automati
if (freeSpace != null) 'freeSpace': formatFilesize(freeSpace), if (freeSpace != null) 'freeSpace': formatFilesize(freeSpace),
}), }),
), ),
Divider(), const Divider(),
]; ];
}) })
], ],

View file

@ -67,11 +67,11 @@ class _AddShortcutDialogState extends State<AddShortcutDialog> {
if (_coverEntry != null) if (_coverEntry != null)
Container( Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsets.only(top: 16), padding: const EdgeInsets.only(top: 16),
child: _buildCover(_coverEntry!, extent), child: _buildCover(_coverEntry!, extent),
), ),
Padding( Padding(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 24), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 24),
child: TextField( child: TextField(
controller: _nameController, controller: _nameController,
decoration: InputDecoration( decoration: InputDecoration(
@ -109,7 +109,7 @@ class _AddShortcutDialogState extends State<AddShortcutDialog> {
return GestureDetector( return GestureDetector(
onTap: _pickEntry, onTap: _pickEntry,
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(32), borderRadius: const BorderRadius.all(Radius.circular(32)),
child: SizedBox( child: SizedBox(
width: extent, width: extent,
height: extent, height: extent,
@ -131,7 +131,7 @@ class _AddShortcutDialogState extends State<AddShortcutDialog> {
final entry = await Navigator.push( final entry = await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: ItemPickDialog.routeName), settings: const RouteSettings(name: ItemPickDialog.routeName),
builder: (context) => ItemPickDialog( builder: (context) => ItemPickDialog(
CollectionLens( CollectionLens(
source: collection.source, source: collection.source,

View file

@ -20,7 +20,7 @@ class AvesDialog extends AlertDialog {
title: title != null title: title != null
? Padding( ? Padding(
// padding to avoid transparent border overlapping // padding to avoid transparent border overlapping
padding: EdgeInsets.symmetric(horizontal: borderWidth), padding: const EdgeInsets.symmetric(horizontal: borderWidth),
child: DialogTitle(title: title), child: DialogTitle(title: title),
) )
: null, : null,
@ -32,7 +32,7 @@ class AvesDialog extends AlertDialog {
content: scrollableContent != null content: scrollableContent != null
? Container( ? Container(
// padding to avoid transparent border overlapping // padding to avoid transparent border overlapping
padding: EdgeInsets.symmetric(horizontal: borderWidth), padding: const EdgeInsets.symmetric(horizontal: borderWidth),
// workaround because the dialog tries // workaround because the dialog tries
// to size itself to the content intrinsic size, // to size itself to the content intrinsic size,
// but the `ListView` viewport does not have one // but the `ListView` viewport does not have one
@ -51,12 +51,12 @@ class AvesDialog extends AlertDialog {
), ),
) )
: content, : content,
contentPadding: scrollableContent != null ? EdgeInsets.zero : EdgeInsets.fromLTRB(24, 20, 24, 0), contentPadding: scrollableContent != null ? EdgeInsets.zero : const EdgeInsets.fromLTRB(24, 20, 24, 0),
actions: actions, actions: actions,
actionsPadding: EdgeInsets.symmetric(horizontal: 8), actionsPadding: const EdgeInsets.symmetric(horizontal: 8),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
side: Divider.createBorderSide(context, width: borderWidth), side: Divider.createBorderSide(context, width: borderWidth),
borderRadius: BorderRadius.circular(24), borderRadius: const BorderRadius.all(Radius.circular(24)),
), ),
); );
} }
@ -78,7 +78,7 @@ class DialogTitle extends StatelessWidget {
), ),
child: Text( child: Text(
title, title,
style: TextStyle( style: const TextStyle(
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontFeatures: [FontFeature.enable('smcp')], fontFeatures: [FontFeature.enable('smcp')],
), ),

View file

@ -74,11 +74,11 @@ class _CoverSelectionDialogState extends State<CoverSelectionDialog> {
title: isCustom title: isCustom
? Row(children: [ ? Row(children: [
title, title,
Spacer(), const Spacer(),
IconButton( IconButton(
onPressed: _isCustom ? _pickEntry : null, onPressed: _isCustom ? _pickEntry : null,
tooltip: 'Change', tooltip: 'Change',
icon: Icon(AIcons.setCover), icon: const Icon(AIcons.setCover),
), ),
]) ])
: title, : title,
@ -87,7 +87,7 @@ class _CoverSelectionDialogState extends State<CoverSelectionDialog> {
), ),
Container( Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsets.only(bottom: 16), padding: const EdgeInsets.only(bottom: 16),
child: DecoratedFilterChip( child: DecoratedFilterChip(
filter: filter, filter: filter,
extent: extent, extent: extent,
@ -116,7 +116,7 @@ class _CoverSelectionDialogState extends State<CoverSelectionDialog> {
final entry = await Navigator.push( final entry = await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: ItemPickDialog.routeName), settings: const RouteSettings(name: ItemPickDialog.routeName),
builder: (context) => ItemPickDialog( builder: (context) => ItemPickDialog(
CollectionLens( CollectionLens(
source: context.read<CollectionSource>(), source: context.read<CollectionSource>(),

View file

@ -50,12 +50,12 @@ class _CreateAlbumDialogState extends State<CreateAlbumDialog> {
final otherVolumes = (byPrimary[false] ?? [])..sort(compare); final otherVolumes = (byPrimary[false] ?? [])..sort(compare);
volumeTiles.addAll([ volumeTiles.addAll([
Padding( Padding(
padding: AvesDialog.contentHorizontalPadding + EdgeInsets.only(top: 20), padding: AvesDialog.contentHorizontalPadding + const EdgeInsets.only(top: 20),
child: Text(context.l10n.newAlbumDialogStorageLabel), child: Text(context.l10n.newAlbumDialogStorageLabel),
), ),
...primaryVolumes.map((volume) => _buildVolumeTile(context, volume)), ...primaryVolumes.map((volume) => _buildVolumeTile(context, volume)),
...otherVolumes.map((volume) => _buildVolumeTile(context, volume)), ...otherVolumes.map((volume) => _buildVolumeTile(context, volume)),
SizedBox(height: 8), const SizedBox(height: 8),
]); ]);
} }
@ -66,7 +66,7 @@ class _CreateAlbumDialogState extends State<CreateAlbumDialog> {
scrollableContent: [ scrollableContent: [
...volumeTiles, ...volumeTiles,
Padding( Padding(
padding: AvesDialog.contentHorizontalPadding + EdgeInsets.only(bottom: 8), padding: AvesDialog.contentHorizontalPadding + const EdgeInsets.only(bottom: 8),
child: ValueListenableBuilder<bool>( child: ValueListenableBuilder<bool>(
valueListenable: _existsNotifier, valueListenable: _existsNotifier,
builder: (context, exists, child) { builder: (context, exists, child) {

View file

@ -38,7 +38,7 @@ class _ItemPickDialogState extends State<ItemPickDialog> {
bottom: false, bottom: false,
child: ChangeNotifierProvider<CollectionLens>.value( child: ChangeNotifierProvider<CollectionLens>.value(
value: collection, value: collection,
child: CollectionGrid( child: const CollectionGrid(
settingsRouteKey: CollectionPage.routeName, settingsRouteKey: CollectionPage.routeName,
), ),
), ),

View file

@ -23,7 +23,7 @@ class AlbumTile extends StatelessWidget {
), ),
title: displayName, title: displayName,
trailing: androidFileUtils.isOnRemovableStorage(album) trailing: androidFileUtils.isOnRemovableStorage(album)
? Icon( ? const Icon(
AIcons.removableStorage, AIcons.removableStorage,
size: 16, size: 16,
color: Colors.grey, color: Colors.grey,

View file

@ -54,12 +54,12 @@ class _AppDrawerState extends State<AppDrawer> {
if (showVideos) videoTile, if (showVideos) videoTile,
if (showFavourites) favouriteTile, if (showFavourites) favouriteTile,
_buildSpecialAlbumSection(), _buildSpecialAlbumSection(),
Divider(), const Divider(),
albumListTile, albumListTile,
countryListTile, countryListTile,
tagListTile, tagListTile,
if (!kReleaseMode) ...[ if (!kReleaseMode) ...[
Divider(), const Divider(),
debugTile, debugTile,
], ],
]; ];
@ -101,7 +101,7 @@ class _AppDrawerState extends State<AppDrawer> {
} }
return Container( return Container(
padding: EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8), padding: const EdgeInsets.only(left: 16, top: 16, right: 16, bottom: 8),
color: Theme.of(context).accentColor, color: Theme.of(context).accentColor,
child: SafeArea( child: SafeArea(
bottom: false, bottom: false,
@ -114,10 +114,10 @@ class _AppDrawerState extends State<AppDrawer> {
spacing: 16, spacing: 16,
crossAxisAlignment: WrapCrossAlignment.center, crossAxisAlignment: WrapCrossAlignment.center,
children: [ children: [
AvesLogo(size: 64), const AvesLogo(size: 64),
Text( Text(
context.l10n.appName, context.l10n.appName,
style: TextStyle( style: const TextStyle(
fontSize: 44, fontSize: 44,
fontWeight: FontWeight.w300, fontWeight: FontWeight.w300,
letterSpacing: 1.0, letterSpacing: 1.0,
@ -127,7 +127,7 @@ class _AppDrawerState extends State<AppDrawer> {
], ],
), ),
), ),
SizedBox(height: 8), const SizedBox(height: 8),
OutlinedButtonTheme( OutlinedButtonTheme(
data: OutlinedButtonThemeData( data: OutlinedButtonThemeData(
style: ButtonStyle( style: ButtonStyle(
@ -140,9 +140,9 @@ class _AppDrawerState extends State<AppDrawer> {
runSpacing: 8, runSpacing: 8,
children: [ children: [
OutlinedButton.icon( OutlinedButton.icon(
key: Key('drawer-about-button'), key: const Key('drawer-about-button'),
onPressed: () => goTo(AboutPage.routeName, (_) => AboutPage()), onPressed: () => goTo(AboutPage.routeName, (_) => AboutPage()),
icon: Icon(AIcons.info), icon: const Icon(AIcons.info),
label: Row( label: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -156,11 +156,11 @@ class _AppDrawerState extends State<AppDrawer> {
duration: Durations.newsBadgeAnimation, duration: Durations.newsBadgeAnimation,
opacity: newVersion ? 1 : 0, opacity: newVersion ? 1 : 0,
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.only(start: 2), padding: const EdgeInsetsDirectional.only(start: 2),
child: DecoratedBox( child: DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.white70), border: const Border.fromBorderSide(BorderSide(color: Colors.white70)),
borderRadius: BorderRadius.circular(badgeSize), borderRadius: BorderRadius.all(Radius.circular(badgeSize)),
), ),
child: Icon( child: Icon(
Icons.circle, Icons.circle,
@ -176,9 +176,9 @@ class _AppDrawerState extends State<AppDrawer> {
), ),
), ),
OutlinedButton.icon( OutlinedButton.icon(
key: Key('drawer-settings-button'), key: const Key('drawer-settings-button'),
onPressed: () => goTo(SettingsPage.routeName, (_) => SettingsPage()), onPressed: () => goTo(SettingsPage.routeName, (_) => SettingsPage()),
icon: Icon(AIcons.settings), icon: const Icon(AIcons.settings),
label: Text(context.l10n.settingsPageTitle), label: Text(context.l10n.settingsPageTitle),
), ),
], ],
@ -200,10 +200,10 @@ class _AppDrawerState extends State<AppDrawer> {
}).toList() }).toList()
..sort(source.compareAlbumsByName); ..sort(source.compareAlbumsByName);
if (specialAlbums.isEmpty) return SizedBox.shrink(); if (specialAlbums.isEmpty) return const SizedBox.shrink();
return Column( return Column(
children: [ children: [
Divider(), const Divider(),
...specialAlbums.map((album) => AlbumTile(album)), ...specialAlbums.map((album) => AlbumTile(album)),
], ],
); );
@ -213,19 +213,19 @@ class _AppDrawerState extends State<AppDrawer> {
// tiles // tiles
Widget get allCollectionTile => CollectionNavTile( Widget get allCollectionTile => CollectionNavTile(
leading: Icon(AIcons.allCollection), leading: const Icon(AIcons.allCollection),
title: context.l10n.drawerCollectionAll, title: context.l10n.drawerCollectionAll,
filter: null, filter: null,
); );
Widget get videoTile => CollectionNavTile( Widget get videoTile => CollectionNavTile(
leading: Icon(AIcons.video), leading: const Icon(AIcons.video),
title: context.l10n.drawerCollectionVideos, title: context.l10n.drawerCollectionVideos,
filter: MimeFilter.video, filter: MimeFilter.video,
); );
Widget get favouriteTile => CollectionNavTile( Widget get favouriteTile => CollectionNavTile(
leading: Icon(AIcons.favourite), leading: const Icon(AIcons.favourite),
title: context.l10n.drawerCollectionFavourites, title: context.l10n.drawerCollectionFavourites,
filter: FavouriteFilter.instance, filter: FavouriteFilter.instance,
); );

View file

@ -40,7 +40,7 @@ class CollectionNavTile extends StatelessWidget {
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: CollectionPage.routeName), settings: const RouteSettings(name: CollectionPage.routeName),
builder: (context) => CollectionPage(CollectionLens( builder: (context) => CollectionPage(CollectionLens(
source: context.read<CollectionSource>(), source: context.read<CollectionSource>(),
filters: [filter], filters: [filter],

View file

@ -113,7 +113,7 @@ class AlbumPickAppBar extends StatelessWidget {
} }
return SliverAppBar( return SliverAppBar(
leading: BackButton(), leading: const BackButton(),
title: SourceStateAwareAppBarTitle( title: SourceStateAwareAppBarTitle(
title: Text(title()), title: Text(title()),
source: source, source: source,
@ -123,7 +123,7 @@ class AlbumPickAppBar extends StatelessWidget {
), ),
actions: [ actions: [
IconButton( IconButton(
icon: Icon(AIcons.createAlbum), icon: const Icon(AIcons.createAlbum),
onPressed: () async { onPressed: () async {
final newAlbum = await showDialog<String>( final newAlbum = await showDialog<String>(
context: context, context: context,
@ -173,7 +173,7 @@ class AlbumFilterBar extends StatelessWidget implements PreferredSizeWidget {
}); });
@override @override
Size get preferredSize => Size.fromHeight(preferredHeight); Size get preferredSize => const Size.fromHeight(preferredHeight);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -109,7 +109,7 @@ class AlbumListPage extends StatelessWidget {
case AlbumChipGroupFactor.none: case AlbumChipGroupFactor.none:
return { return {
if (pinnedMapEntries.isNotEmpty || unpinnedMapEntries.isNotEmpty) if (pinnedMapEntries.isNotEmpty || unpinnedMapEntries.isNotEmpty)
ChipSectionKey(): [ const ChipSectionKey(): [
...pinnedMapEntries, ...pinnedMapEntries,
...unpinnedMapEntries, ...unpinnedMapEntries,
], ],

View file

@ -53,7 +53,7 @@ abstract class ChipSetActionDelegate {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: StatsPage.routeName), settings: const RouteSettings(name: StatsPage.routeName),
builder: (context) => StatsPage( builder: (context) => StatsPage(
source: source, source: source,
), ),

View file

@ -73,7 +73,7 @@ class DecoratedFilterChip extends StatelessWidget {
); );
} }
default: default:
return SizedBox(); return const SizedBox();
} }
}, },
); );
@ -143,7 +143,7 @@ class DecoratedFilterChip extends StatelessWidget {
child: DecoratedIcon( child: DecoratedIcon(
AIcons.pin, AIcons.pin,
color: FilterGridPage.detailColor, color: FilterGridPage.detailColor,
shadows: [Constants.embossShadow], shadows: Constants.embossShadows,
size: iconSize, size: iconSize,
), ),
), ),
@ -154,7 +154,7 @@ class DecoratedFilterChip extends StatelessWidget {
child: DecoratedIcon( child: DecoratedIcon(
AIcons.removableStorage, AIcons.removableStorage,
color: FilterGridPage.detailColor, color: FilterGridPage.detailColor,
shadows: [Constants.embossShadow], shadows: Constants.embossShadows,
size: iconSize, size: iconSize,
), ),
), ),

View file

@ -53,7 +53,7 @@ class FilterNavigationPage<T extends CollectionFilter> extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isMainMode = context.select<ValueNotifier<AppMode>, bool>((vn) => vn.value == AppMode.main); final isMainMode = context.select<ValueNotifier<AppMode>, bool>((vn) => vn.value == AppMode.main);
return FilterGridPage<T>( return FilterGridPage<T>(
key: Key('filter-grid-page'), key: const Key('filter-grid-page'),
appBar: SliverAppBar( appBar: SliverAppBar(
title: InteractiveAppBarTitle( title: InteractiveAppBarTitle(
onTap: () => _goToSearch(context), onTap: () => _goToSearch(context),
@ -73,13 +73,13 @@ class FilterNavigationPage<T extends CollectionFilter> extends StatelessWidget {
emptyBuilder: () => ValueListenableBuilder<SourceState>( emptyBuilder: () => ValueListenableBuilder<SourceState>(
valueListenable: source.stateNotifier, valueListenable: source.stateNotifier,
builder: (context, sourceState, child) { builder: (context, sourceState, child) {
return sourceState != SourceState.loading ? emptyBuilder() : SizedBox.shrink(); return sourceState != SourceState.loading ? emptyBuilder() : const SizedBox.shrink();
}, },
), ),
onTap: (filter) => Navigator.push( onTap: (filter) => Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: CollectionPage.routeName), settings: const RouteSettings(name: CollectionPage.routeName),
builder: (context) => CollectionPage(CollectionLens( builder: (context) => CollectionPage(CollectionLens(
source: source, source: source,
filters: [filter], filters: [filter],
@ -92,7 +92,7 @@ class FilterNavigationPage<T extends CollectionFilter> extends StatelessWidget {
void _showMenu(BuildContext context, T filter, Offset? tapPosition) async { void _showMenu(BuildContext context, T filter, Offset? tapPosition) async {
final overlay = Overlay.of(context)!.context.findRenderObject() as RenderBox; final overlay = Overlay.of(context)!.context.findRenderObject() as RenderBox;
final touchArea = Size(40, 40); const touchArea = Size(40, 40);
final selectedAction = await showMenu<ChipAction>( final selectedAction = await showMenu<ChipAction>(
context: context, context: context,
position: RelativeRect.fromRect((tapPosition ?? Offset.zero) & touchArea, Offset.zero & overlay.size), position: RelativeRect.fromRect((tapPosition ?? Offset.zero) & touchArea, Offset.zero & overlay.size),
@ -113,11 +113,11 @@ class FilterNavigationPage<T extends CollectionFilter> extends StatelessWidget {
return [ return [
CollectionSearchButton(source), CollectionSearchButton(source),
PopupMenuButton<ChipSetAction>( PopupMenuButton<ChipSetAction>(
key: Key('appbar-menu-button'), key: const Key('appbar-menu-button'),
itemBuilder: (context) { itemBuilder: (context) {
return [ return [
PopupMenuItem( PopupMenuItem(
key: Key('menu-sort'), key: const Key('menu-sort'),
value: ChipSetAction.sort, value: ChipSetAction.sort,
child: MenuRow(text: context.l10n.menuActionSort, icon: AIcons.sort), child: MenuRow(text: context.l10n.menuActionSort, icon: AIcons.sort),
), ),

View file

@ -34,10 +34,10 @@ class _ChipHighlightOverlayState extends State<ChipHighlightOverlay> {
return Sweeper( return Sweeper(
builder: (context) => Container( builder: (context) => Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.fromBorderSide(BorderSide(
color: Theme.of(context).accentColor, color: Theme.of(context).accentColor,
width: widget.extent * .1, width: widget.extent * .1,
), )),
borderRadius: widget.borderRadius, borderRadius: widget.borderRadius,
), ),
), ),

View file

@ -80,5 +80,5 @@ class StorageVolumeSectionKey extends ChipSectionKey {
StorageVolumeSectionKey(BuildContext context, this.volume) : super(title: volume?.getDescription(context) ?? context.l10n.sectionUnknown); StorageVolumeSectionKey(BuildContext context, this.volume) : super(title: volume?.getDescription(context) ?? context.l10n.sectionUnknown);
@override @override
Widget? get leading => (volume?.isRemovable ?? false) ? Icon(AIcons.removableStorage) : null; Widget? get leading => (volume?.isRemovable ?? false) ? const Icon(AIcons.removableStorage) : null;
} }

View file

@ -65,7 +65,7 @@ class CountryListPage extends StatelessWidget {
return { return {
if (pinnedMapEntries.isNotEmpty || unpinnedMapEntries.isNotEmpty) if (pinnedMapEntries.isNotEmpty || unpinnedMapEntries.isNotEmpty)
ChipSectionKey(): [ const ChipSectionKey(): [
...pinnedMapEntries, ...pinnedMapEntries,
...unpinnedMapEntries, ...unpinnedMapEntries,
], ],

View file

@ -65,7 +65,7 @@ class TagListPage extends StatelessWidget {
return { return {
if (pinnedMapEntries.isNotEmpty || unpinnedMapEntries.isNotEmpty) if (pinnedMapEntries.isNotEmpty || unpinnedMapEntries.isNotEmpty)
ChipSectionKey(): [ const ChipSectionKey(): [
...pinnedMapEntries, ...pinnedMapEntries,
...unpinnedMapEntries, ...unpinnedMapEntries,
], ],

View file

@ -50,7 +50,7 @@ class _HomePageState extends State<HomePage> {
} }
@override @override
Widget build(BuildContext context) => Scaffold(); Widget build(BuildContext context) => const Scaffold();
Future<void> _setup() async { Future<void> _setup() async {
final permissions = await [ final permissions = await [
@ -127,7 +127,7 @@ class _HomePageState extends State<HomePage> {
Route _getRedirectRoute(AppMode appMode) { Route _getRedirectRoute(AppMode appMode) {
if (appMode == AppMode.view) { if (appMode == AppMode.view) {
return DirectMaterialPageRoute( return DirectMaterialPageRoute(
settings: RouteSettings(name: EntryViewerPage.routeName), settings: const RouteSettings(name: EntryViewerPage.routeName),
builder: (_) => EntryViewerPage( builder: (_) => EntryViewerPage(
initialEntry: _viewerEntry!, initialEntry: _viewerEntry!,
), ),
@ -146,7 +146,7 @@ class _HomePageState extends State<HomePage> {
switch (routeName) { switch (routeName) {
case AlbumListPage.routeName: case AlbumListPage.routeName:
return DirectMaterialPageRoute( return DirectMaterialPageRoute(
settings: RouteSettings(name: AlbumListPage.routeName), settings: const RouteSettings(name: AlbumListPage.routeName),
builder: (_) => AlbumListPage(), builder: (_) => AlbumListPage(),
); );
case SearchPage.routeName: case SearchPage.routeName:
@ -156,7 +156,7 @@ class _HomePageState extends State<HomePage> {
case CollectionPage.routeName: case CollectionPage.routeName:
default: default:
return DirectMaterialPageRoute( return DirectMaterialPageRoute(
settings: RouteSettings(name: CollectionPage.routeName), settings: const RouteSettings(name: CollectionPage.routeName),
builder: (_) => CollectionPage( builder: (_) => CollectionPage(
CollectionLens( CollectionLens(
source: source, source: source,

View file

@ -25,7 +25,7 @@ class ExpandableFilterRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (filters.isEmpty) return SizedBox.shrink(); if (filters.isEmpty) return const SizedBox.shrink();
final hasTitle = title != null && title!.isNotEmpty; final hasTitle = title != null && title!.isNotEmpty;
@ -34,7 +34,7 @@ class ExpandableFilterRow extends StatelessWidget {
Widget? titleRow; Widget? titleRow;
if (hasTitle) { if (hasTitle) {
titleRow = Padding( titleRow = Padding(
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Row( child: Row(
children: [ children: [
Text( Text(
@ -55,7 +55,7 @@ class ExpandableFilterRow extends StatelessWidget {
final filterList = filters.toList(); final filterList = filters.toList();
final wrap = Container( final wrap = Container(
key: ValueKey('wrap$title'), key: ValueKey('wrap$title'),
padding: EdgeInsets.symmetric(horizontal: horizontalPadding), padding: const EdgeInsets.symmetric(horizontal: horizontalPadding),
// specify transparent as a workaround to prevent // specify transparent as a workaround to prevent
// chip border clipping when the floating app bar is fading // chip border clipping when the floating app bar is fading
color: Colors.transparent, color: Colors.transparent,
@ -73,12 +73,12 @@ class ExpandableFilterRow extends StatelessWidget {
height: AvesFilterChip.minChipHeight, height: AvesFilterChip.minChipHeight,
child: ListView.separated( child: ListView.separated(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
padding: EdgeInsets.symmetric(horizontal: horizontalPadding), padding: const EdgeInsets.symmetric(horizontal: horizontalPadding),
itemBuilder: (context, index) { itemBuilder: (context, index) {
return index < filterList.length ? _buildFilterChip(filterList[index]) : SizedBox(); return index < filterList.length ? _buildFilterChip(filterList[index]) : const SizedBox();
}, },
separatorBuilder: (context, index) => SizedBox(width: 8), separatorBuilder: (context, index) => const SizedBox(width: 8),
itemCount: filterList.length, itemCount: filterList.length,
), ),
); );

View file

@ -13,8 +13,8 @@ class CollectionSearchButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return IconButton( return IconButton(
key: Key('search-button'), key: const Key('search-button'),
icon: Icon(AIcons.search), icon: const Icon(AIcons.search),
onPressed: () => _goToSearch(context), onPressed: () => _goToSearch(context),
tooltip: MaterialLocalizations.of(context).searchFieldLabel, tooltip: MaterialLocalizations.of(context).searchFieldLabel,
); );

View file

@ -53,7 +53,7 @@ class CollectionSearchDelegate {
onPressed: () => _goBack(context), onPressed: () => _goBack(context),
tooltip: MaterialLocalizations.of(context).backButtonTooltip, tooltip: MaterialLocalizations.of(context).backButtonTooltip,
) )
: CloseButton( : const CloseButton(
onPressed: SystemNavigator.pop, onPressed: SystemNavigator.pop,
); );
} }
@ -62,7 +62,7 @@ class CollectionSearchDelegate {
return [ return [
if (query.isNotEmpty) if (query.isNotEmpty)
IconButton( IconButton(
icon: Icon(AIcons.clear), icon: const Icon(AIcons.clear),
onPressed: () { onPressed: () {
query = ''; query = '';
showSuggestions(context); showSuggestions(context);
@ -93,7 +93,7 @@ class CollectionSearchDelegate {
final history = settings.searchHistory.where(notHidden).toList(); final history = settings.searchHistory.where(notHidden).toList();
return ListView( return ListView(
padding: EdgeInsets.only(top: 8), padding: const EdgeInsets.only(top: 8),
children: [ children: [
_buildFilterRow( _buildFilterRow(
context: context, context: context,
@ -195,7 +195,7 @@ class CollectionSearchDelegate {
// and possibly trigger a rebuild here // and possibly trigger a rebuild here
_select(context, _buildQueryFilter(true)); _select(context, _buildQueryFilter(true));
}); });
return SizedBox.shrink(); return const SizedBox.shrink();
} }
QueryFilter? _buildQueryFilter(bool colorful) { QueryFilter? _buildQueryFilter(bool colorful) {
@ -242,7 +242,7 @@ class CollectionSearchDelegate {
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: CollectionPage.routeName), settings: const RouteSettings(name: CollectionPage.routeName),
builder: (context) => CollectionPage(CollectionLens( builder: (context) => CollectionPage(CollectionLens(
source: source, source: source,
filters: [filter], filters: [filter],
@ -302,7 +302,7 @@ enum SearchBody { suggestions, results }
class SearchPageRoute<T> extends PageRoute<T> { class SearchPageRoute<T> extends PageRoute<T> {
SearchPageRoute({ SearchPageRoute({
required this.delegate, required this.delegate,
}) : super(settings: RouteSettings(name: SearchPage.routeName)) { }) : super(settings: const RouteSettings(name: SearchPage.routeName)) {
assert( assert(
delegate.route == null, delegate.route == null,
'The ${delegate.runtimeType} instance is currently used by another active ' 'The ${delegate.runtimeType} instance is currently used by another active '

View file

@ -93,13 +93,13 @@ class _SearchPageState extends State<SearchPage> {
switch (widget.delegate.currentBody) { switch (widget.delegate.currentBody) {
case SearchBody.suggestions: case SearchBody.suggestions:
body = KeyedSubtree( body = KeyedSubtree(
key: ValueKey<SearchBody>(SearchBody.suggestions), key: const ValueKey<SearchBody>(SearchBody.suggestions),
child: widget.delegate.buildSuggestions(context), child: widget.delegate.buildSuggestions(context),
); );
break; break;
case SearchBody.results: case SearchBody.results:
body = KeyedSubtree( body = KeyedSubtree(
key: ValueKey<SearchBody>(SearchBody.results), key: const ValueKey<SearchBody>(SearchBody.results),
child: widget.delegate.buildResults(context), child: widget.delegate.buildResults(context),
); );
break; break;

View file

@ -13,7 +13,7 @@ class StorageAccessTile extends StatelessWidget {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: StorageAccessPage.routeName), settings: const RouteSettings(name: StorageAccessPage.routeName),
builder: (context) => StorageAccessPage(), builder: (context) => StorageAccessPage(),
), ),
); );
@ -52,16 +52,16 @@ class _StorageAccessPageState extends State<StorageAccessPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: Row( child: Row(
children: [ children: [
Icon(AIcons.info), const Icon(AIcons.info),
SizedBox(width: 16), const SizedBox(width: 16),
Expanded(child: Text(context.l10n.settingsStorageAccessBanner)), Expanded(child: Text(context.l10n.settingsStorageAccessBanner)),
], ],
), ),
), ),
Divider(), const Divider(),
Expanded( Expanded(
child: FutureBuilder<List<String>>( child: FutureBuilder<List<String>>(
future: _pathLoader, future: _pathLoader,
@ -70,7 +70,7 @@ class _StorageAccessPageState extends State<StorageAccessPage> {
return Text(snapshot.error.toString()); return Text(snapshot.error.toString());
} }
if (snapshot.connectionState != ConnectionState.done && _lastPaths == null) { if (snapshot.connectionState != ConnectionState.done && _lastPaths == null) {
return SizedBox.shrink(); return const SizedBox.shrink();
} }
_lastPaths = snapshot.data!..sort(); _lastPaths = snapshot.data!..sort();
if (_lastPaths!.isEmpty) { if (_lastPaths!.isEmpty) {
@ -85,7 +85,7 @@ class _StorageAccessPageState extends State<StorageAccessPage> {
title: Text(path), title: Text(path),
dense: true, dense: true,
trailing: IconButton( trailing: IconButton(
icon: Icon(AIcons.clear), icon: const Icon(AIcons.clear),
onPressed: () async { onPressed: () async {
await storageService.revokeDirectoryAccess(path); await storageService.revokeDirectoryAccess(path);
_load(); _load();

View file

@ -45,7 +45,7 @@ class _EntryBackgroundSelectorState extends State<EntryBackgroundSelector> {
Widget? child; Widget? child;
switch (selected) { switch (selected) {
case EntryBackground.transparent: case EntryBackground.transparent:
child = Icon( child = const Icon(
Icons.clear, Icons.clear,
size: 20, size: 20,
color: Colors.white30, color: Colors.white30,

View file

@ -16,7 +16,7 @@ class HiddenFilterTile extends StatelessWidget {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: HiddenFilterPage.routeName), settings: const RouteSettings(name: HiddenFilterPage.routeName),
builder: (context) => HiddenFilterPage(), builder: (context) => HiddenFilterPage(),
), ),
); );
@ -39,19 +39,19 @@ class HiddenFilterPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: Row( child: Row(
children: [ children: [
Icon(AIcons.info), const Icon(AIcons.info),
SizedBox(width: 16), const SizedBox(width: 16),
Expanded(child: Text(context.l10n.settingsHiddenFiltersBanner)), Expanded(child: Text(context.l10n.settingsHiddenFiltersBanner)),
], ],
), ),
), ),
Divider(), const Divider(),
Expanded( Expanded(
child: Padding( child: Padding(
padding: EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: Consumer<Settings>( child: Consumer<Settings>(
builder: (context, settings, child) { builder: (context, settings, child) {
final hiddenFilters = settings.hiddenFilters; final hiddenFilters = settings.hiddenFilters;

View file

@ -53,7 +53,7 @@ class AvailableActionPanel extends StatelessWidget {
return AnimatedBuilder( return AnimatedBuilder(
animation: Listenable.merge([quickActionsChangeNotifier, draggedAvailableAction]), animation: Listenable.merge([quickActionsChangeNotifier, draggedAvailableAction]),
builder: (context, child) => Padding( builder: (context, child) => Padding(
padding: EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: Wrap( child: Wrap(
alignment: WrapAlignment.spaceEvenly, alignment: WrapAlignment.spaceEvenly,
spacing: 8, spacing: 8,

View file

@ -18,16 +18,16 @@ class ActionPanel extends StatelessWidget {
return AnimatedContainer( return AnimatedContainer(
foregroundDecoration: BoxDecoration( foregroundDecoration: BoxDecoration(
color: color.withOpacity(.2), color: color.withOpacity(.2),
border: Border.all( border: Border.fromBorderSide(BorderSide(
color: color, color: color,
width: highlight ? 2 : 1, width: highlight ? 2 : 1,
)),
borderRadius: const BorderRadius.all(Radius.circular(8)),
), ),
borderRadius: BorderRadius.circular(8), margin: const EdgeInsets.all(16),
),
margin: EdgeInsets.all(16),
duration: Durations.quickActionHighlightAnimation, duration: Durations.quickActionHighlightAnimation,
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(8), borderRadius: const BorderRadius.all(Radius.circular(8)),
child: child, child: child,
), ),
); );
@ -54,7 +54,7 @@ class ActionButton extends StatelessWidget {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
SizedBox(height: padding), const SizedBox(height: padding),
OverlayButton( OverlayButton(
child: IconButton( child: IconButton(
icon: Icon(action.getIcon()), icon: Icon(action.getIcon()),
@ -62,7 +62,7 @@ class ActionButton extends StatelessWidget {
), ),
), ),
if (showCaption) ...[ if (showCaption) ...[
SizedBox(height: padding), const SizedBox(height: padding),
Text( Text(
action.getText(context), action.getText(context),
style: enabled ? textStyle : textStyle!.copyWith(color: textStyle.color!.withOpacity(.2)), style: enabled ? textStyle : textStyle!.copyWith(color: textStyle.color!.withOpacity(.2)),
@ -71,7 +71,7 @@ class ActionButton extends StatelessWidget {
maxLines: 2, maxLines: 2,
), ),
], ],
SizedBox(height: padding), const SizedBox(height: padding),
], ],
), ),
); );

View file

@ -24,7 +24,7 @@ class QuickActionsTile extends StatelessWidget {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: QuickActionEditorPage.routeName), settings: const RouteSettings(name: QuickActionEditorPage.routeName),
builder: (context) => QuickActionEditorPage(), builder: (context) => QuickActionEditorPage(),
), ),
); );
@ -71,7 +71,7 @@ class _QuickActionEditorPageState extends State<QuickActionEditorPage> {
void _onQuickActionTargetLeave() { void _onQuickActionTargetLeave() {
_stopLeavingTimer(); _stopLeavingTimer();
final action = _draggedAvailableAction.value; final action = _draggedAvailableAction.value;
_targetLeavingTimer = Timer(Durations.quickActionListAnimation + Duration(milliseconds: 50), () { _targetLeavingTimer = Timer(Durations.quickActionListAnimation + const Duration(milliseconds: 50), () {
_removeQuickAction(action); _removeQuickAction(action);
_quickActionHighlight.value = false; _quickActionHighlight.value = false;
}); });
@ -111,18 +111,18 @@ class _QuickActionEditorPageState extends State<QuickActionEditorPage> {
child: ListView( child: ListView(
children: [ children: [
Padding( Padding(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: Row( child: Row(
children: [ children: [
Icon(AIcons.info), const Icon(AIcons.info),
SizedBox(width: 16), const SizedBox(width: 16),
Expanded(child: Text(context.l10n.settingsViewerQuickActionEditorBanner)), Expanded(child: Text(context.l10n.settingsViewerQuickActionEditorBanner)),
], ],
), ),
), ),
Divider(), const Divider(),
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text( child: Text(
context.l10n.settingsViewerQuickActionEditorDisplayedButtons, context.l10n.settingsViewerQuickActionEditorDisplayedButtons,
style: Constants.titleTextStyle, style: Constants.titleTextStyle,
@ -161,7 +161,7 @@ class _QuickActionEditorPageState extends State<QuickActionEditorPage> {
shrinkWrap: true, shrinkWrap: true,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemBuilder: (context, index, animation) { itemBuilder: (context, index, animation) {
if (index >= _quickActions.length) return SizedBox(); if (index >= _quickActions.length) return const SizedBox();
final action = _quickActions[index]; final action = _quickActions[index];
return QuickActionButton( return QuickActionButton(
placement: QuickActionPlacement.action, placement: QuickActionPlacement.action,
@ -186,14 +186,14 @@ class _QuickActionEditorPageState extends State<QuickActionEditorPage> {
style: Theme.of(context).textTheme.caption, style: Theme.of(context).textTheme.caption,
), ),
) )
: SizedBox(), : const SizedBox(),
), ),
], ],
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text( child: Text(
context.l10n.settingsViewerQuickActionEditorAvailableButtons, context.l10n.settingsViewerQuickActionEditorAvailableButtons,
style: Constants.titleTextStyle, style: Constants.titleTextStyle,
@ -278,7 +278,7 @@ class _QuickActionEditorPageState extends State<QuickActionEditorPage> {
axis: Axis.horizontal, axis: Axis.horizontal,
sizeFactor: animation, sizeFactor: animation,
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: _QuickActionEditorPageState.quickActionVerticalPadding, horizontal: 4), padding: const EdgeInsets.symmetric(vertical: _QuickActionEditorPageState.quickActionVerticalPadding, horizontal: 4),
child: OverlayButton( child: OverlayButton(
child: IconButton( child: IconButton(
icon: Icon(action.getIcon()), icon: Icon(action.getIcon()),

View file

@ -52,7 +52,7 @@ class QuickActionButton extends StatelessWidget {
}, },
onAcceptWithDetails: (details) => _setPanelHighlight(false), onAcceptWithDetails: (details) => _setPanelHighlight(false),
onLeave: (data) => onTargetLeave(), onLeave: (data) => onTargetLeave(),
builder: (context, accepted, rejected) => child ?? SizedBox(), builder: (context, accepted, rejected) => child ?? const SizedBox(),
); );
} }

View file

@ -47,14 +47,14 @@ class _SettingsPageState extends State<SettingsPage> {
data: theme.copyWith( data: theme.copyWith(
textTheme: theme.textTheme.copyWith( textTheme: theme.textTheme.copyWith(
// dense style font for tile subtitles, without modifying title font // dense style font for tile subtitles, without modifying title font
bodyText2: TextStyle(fontSize: 12), bodyText2: const TextStyle(fontSize: 12),
), ),
), ),
child: SafeArea( child: SafeArea(
child: Consumer<Settings>( child: Consumer<Settings>(
builder: (context, settings, child) => AnimationLimiter( builder: (context, settings, child) => AnimationLimiter(
child: ListView( child: ListView(
padding: EdgeInsets.all(8), padding: const EdgeInsets.all(8),
children: AnimationConfiguration.toStaggeredList( children: AnimationConfiguration.toStaggeredList(
duration: Durations.staggeredAnimation, duration: Durations.staggeredAnimation,
delay: Durations.staggeredAnimationDelay, delay: Durations.staggeredAnimationDelay,
@ -333,17 +333,17 @@ class _SettingsPageState extends State<SettingsPage> {
} }
Widget _buildLeading(IconData icon, Color color) => Container( Widget _buildLeading(IconData icon, Color color) => Container(
padding: EdgeInsets.all(6), padding: const EdgeInsets.all(6),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.fromBorderSide(BorderSide(
color: color, color: color,
width: AvesFilterChip.outlineWidth, width: AvesFilterChip.outlineWidth,
), )),
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: DecoratedIcon( child: DecoratedIcon(
icon, icon,
shadows: [Constants.embossShadow], shadows: Constants.embossShadows,
size: 18, size: 18,
), ),
); );

View file

@ -36,7 +36,7 @@ class FilterTable extends StatelessWidget {
final lineHeight = 16 * textScaleFactor; final lineHeight = 16 * textScaleFactor;
return Padding( return Padding(
padding: EdgeInsetsDirectional.only(start: AvesFilterChip.outlineWidth / 2 + 6, end: 8), padding: const EdgeInsetsDirectional.only(start: AvesFilterChip.outlineWidth / 2 + 6, end: 8),
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
final showPercentIndicator = constraints.maxWidth - (chipWidth + countWidth) > percentIndicatorMinWidth; final showPercentIndicator = constraints.maxWidth - (chipWidth + countWidth) > percentIndicatorMinWidth;
@ -52,7 +52,7 @@ class FilterTable extends StatelessWidget {
// the `Table` `border` property paints on the cells and does not add margins, // the `Table` `border` property paints on the cells and does not add margins,
// so we define margins here instead, but they should be symmetric // so we define margins here instead, but they should be symmetric
// to keep all cells vertically aligned on the center/middle // to keep all cells vertically aligned on the center/middle
margin: EdgeInsets.symmetric(vertical: 4), margin: const EdgeInsets.symmetric(vertical: 4),
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
child: AvesFilterChip( child: AvesFilterChip(
filter: filter, filter: filter,
@ -69,20 +69,20 @@ class FilterTable extends StatelessWidget {
padding: EdgeInsets.symmetric(horizontal: lineHeight), padding: EdgeInsets.symmetric(horizontal: lineHeight),
center: Text( center: Text(
NumberFormat.percentPattern().format(percent), NumberFormat.percentPattern().format(percent),
style: TextStyle(shadows: [Constants.embossShadow]), style: const TextStyle(shadows: Constants.embossShadows),
), ),
), ),
Text( Text(
'$count', '$count',
style: TextStyle(color: Colors.white70), style: const TextStyle(color: Colors.white70),
textAlign: TextAlign.end, textAlign: TextAlign.end,
), ),
], ],
); );
}).toList(), }).toList(),
columnWidths: { columnWidths: {
0: MaxColumnWidth(IntrinsicColumnWidth(), FixedColumnWidth(chipWidth)), 0: const MaxColumnWidth(IntrinsicColumnWidth(), FixedColumnWidth(chipWidth)),
2: MaxColumnWidth(IntrinsicColumnWidth(), FixedColumnWidth(countWidth)), 2: const MaxColumnWidth(IntrinsicColumnWidth(), FixedColumnWidth(countWidth)),
}, },
defaultVerticalAlignment: TableCellVerticalAlignment.middle, defaultVerticalAlignment: TableCellVerticalAlignment.middle,
); );

View file

@ -16,7 +16,6 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/empty.dart'; import 'package:aves/widgets/common/identity/empty.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/stats/filter_table.dart'; import 'package:aves/widgets/stats/filter_table.dart';
// ignore: import_of_legacy_library_into_null_safe // ignore: import_of_legacy_library_into_null_safe
import 'package:charts_flutter/flutter.dart' as charts; import 'package:charts_flutter/flutter.dart' as charts;
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
@ -87,7 +86,7 @@ class StatsPage extends StatelessWidget {
final textScaleFactor = MediaQuery.textScaleFactorOf(context); final textScaleFactor = MediaQuery.textScaleFactorOf(context);
final lineHeight = 16 * textScaleFactor; final lineHeight = 16 * textScaleFactor;
final locationIndicator = Padding( final locationIndicator = Padding(
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
children: [ children: [
LinearPercentIndicator( LinearPercentIndicator(
@ -96,15 +95,15 @@ class StatsPage extends StatelessWidget {
backgroundColor: Colors.white24, backgroundColor: Colors.white24,
progressColor: Theme.of(context).accentColor, progressColor: Theme.of(context).accentColor,
animation: true, animation: true,
leading: Icon(AIcons.location), leading: const Icon(AIcons.location),
// right padding to match leading, so that inside label is aligned with outside label below // right padding to match leading, so that inside label is aligned with outside label below
padding: EdgeInsets.symmetric(horizontal: lineHeight) + EdgeInsets.only(right: 24), padding: EdgeInsets.symmetric(horizontal: lineHeight) + const EdgeInsets.only(right: 24),
center: Text( center: Text(
NumberFormat.percentPattern().format(withGpsPercent), NumberFormat.percentPattern().format(withGpsPercent),
style: TextStyle(shadows: [Constants.embossShadow]), style: const TextStyle(shadows: Constants.embossShadows),
), ),
), ),
SizedBox(height: 8), const SizedBox(height: 8),
Text(context.l10n.statsWithGps(withGpsCount)), Text(context.l10n.statsWithGps(withGpsCount)),
], ],
), ),
@ -132,7 +131,7 @@ class StatsPage extends StatelessWidget {
} }
Widget _buildMimeDonut(BuildContext context, String Function(int) label, Map<String, int> byMimeTypes) { Widget _buildMimeDonut(BuildContext context, String Function(int) label, Map<String, int> byMimeTypes) {
if (byMimeTypes.isEmpty) return SizedBox.shrink(); if (byMimeTypes.isEmpty) return const SizedBox.shrink();
final sum = byMimeTypes.values.fold<int>(0, (prev, v) => prev + v); final sum = byMimeTypes.values.fold<int>(0, (prev, v) => prev + v);
@ -193,12 +192,12 @@ class StatsPage extends StatelessWidget {
WidgetSpan( WidgetSpan(
alignment: PlaceholderAlignment.middle, alignment: PlaceholderAlignment.middle,
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.only(end: 8), padding: const EdgeInsetsDirectional.only(end: 8),
child: Icon(AIcons.disc, color: d.color), child: Icon(AIcons.disc, color: d.color),
), ),
), ),
TextSpan(text: '${d.displayText} '), TextSpan(text: '${d.displayText} '),
TextSpan(text: '${d.entryCount}', style: TextStyle(color: Colors.white70)), TextSpan(text: '${d.entryCount}', style: const TextStyle(color: Colors.white70)),
], ],
), ),
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
@ -235,7 +234,7 @@ class StatsPage extends StatelessWidget {
return [ return [
Padding( Padding(
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Text( child: Text(
title, title,
style: Constants.titleTextStyle, style: Constants.titleTextStyle,
@ -272,7 +271,7 @@ class StatsPage extends StatelessWidget {
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: CollectionPage.routeName), settings: const RouteSettings(name: CollectionPage.routeName),
builder: (context) => CollectionPage(CollectionLens( builder: (context) => CollectionPage(CollectionLens(
source: source, source: source,
filters: [filter], filters: [filter],

View file

@ -40,13 +40,13 @@ class _DbTabState extends State<DbTab> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView( return ListView(
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
children: [ children: [
FutureBuilder<DateMetadata?>( FutureBuilder<DateMetadata?>(
future: _dbDateLoader, future: _dbDateLoader,
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = snapshot.data; final data = snapshot.data;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -60,12 +60,12 @@ class _DbTabState extends State<DbTab> {
); );
}, },
), ),
SizedBox(height: 16), const SizedBox(height: 16),
FutureBuilder<AvesEntry?>( FutureBuilder<AvesEntry?>(
future: _dbEntryLoader, future: _dbEntryLoader,
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = snapshot.data; final data = snapshot.data;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -89,12 +89,12 @@ class _DbTabState extends State<DbTab> {
); );
}, },
), ),
SizedBox(height: 16), const SizedBox(height: 16),
FutureBuilder<CatalogMetadata?>( FutureBuilder<CatalogMetadata?>(
future: _dbMetadataLoader, future: _dbMetadataLoader,
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = snapshot.data; final data = snapshot.data;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -116,12 +116,12 @@ class _DbTabState extends State<DbTab> {
); );
}, },
), ),
SizedBox(height: 16), const SizedBox(height: 16),
FutureBuilder<AddressDetails?>( FutureBuilder<AddressDetails?>(
future: _dbAddressLoader, future: _dbAddressLoader,
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
final data = snapshot.data; final data = snapshot.data;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,

View file

@ -21,16 +21,16 @@ class ViewerDebugPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final tabs = <Tuple2<Tab, Widget>>[ final tabs = <Tuple2<Tab, Widget>>[
Tuple2(Tab(text: 'Entry'), _buildEntryTabView()), Tuple2(const Tab(text: 'Entry'), _buildEntryTabView()),
if (context.select<ValueNotifier<AppMode>, bool>((vn) => vn.value != AppMode.view)) Tuple2(Tab(text: 'DB'), DbTab(entry: entry)), if (context.select<ValueNotifier<AppMode>, bool>((vn) => vn.value != AppMode.view)) Tuple2(const Tab(text: 'DB'), DbTab(entry: entry)),
Tuple2(Tab(icon: Icon(AIcons.android)), MetadataTab(entry: entry)), Tuple2(const Tab(icon: Icon(AIcons.android)), MetadataTab(entry: entry)),
Tuple2(Tab(icon: Icon(AIcons.image)), _buildThumbnailsTabView()), Tuple2(const Tab(icon: Icon(AIcons.image)), _buildThumbnailsTabView()),
]; ];
return DefaultTabController( return DefaultTabController(
length: tabs.length, length: tabs.length,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('Debug'), title: const Text('Debug'),
bottom: TabBar( bottom: TabBar(
tabs: tabs.map((t) => t.item1).toList(), tabs: tabs.map((t) => t.item1).toList(),
), ),
@ -54,7 +54,7 @@ class ViewerDebugPage extends StatelessWidget {
} }
return ListView( return ListView(
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
children: [ children: [
InfoRowGroup({ InfoRowGroup({
'uri': '${entry.uri}', 'uri': '${entry.uri}',
@ -66,13 +66,13 @@ class ViewerDebugPage extends StatelessWidget {
'sourceMimeType': '${entry.sourceMimeType}', 'sourceMimeType': '${entry.sourceMimeType}',
'mimeType': '${entry.mimeType}', 'mimeType': '${entry.mimeType}',
}), }),
Divider(), const Divider(),
InfoRowGroup({ InfoRowGroup({
'dateModifiedSecs': toDateValue(entry.dateModifiedSecs, factor: 1000), 'dateModifiedSecs': toDateValue(entry.dateModifiedSecs, factor: 1000),
'sourceDateTakenMillis': toDateValue(entry.sourceDateTakenMillis), 'sourceDateTakenMillis': toDateValue(entry.sourceDateTakenMillis),
'bestDate': '${entry.bestDate}', 'bestDate': '${entry.bestDate}',
}), }),
Divider(), const Divider(),
InfoRowGroup({ InfoRowGroup({
'width': '${entry.width}', 'width': '${entry.width}',
'height': '${entry.height}', 'height': '${entry.height}',
@ -83,12 +83,12 @@ class ViewerDebugPage extends StatelessWidget {
'displayAspectRatio': '${entry.displayAspectRatio}', 'displayAspectRatio': '${entry.displayAspectRatio}',
'displaySize': '${entry.displaySize}', 'displaySize': '${entry.displaySize}',
}), }),
Divider(), const Divider(),
InfoRowGroup({ InfoRowGroup({
'durationMillis': '${entry.durationMillis}', 'durationMillis': '${entry.durationMillis}',
'durationText': '${entry.durationText}', 'durationText': '${entry.durationText}',
}), }),
Divider(), const Divider(),
InfoRowGroup({ InfoRowGroup({
'sizeBytes': '${entry.sizeBytes}', 'sizeBytes': '${entry.sizeBytes}',
'isFavourite': '${entry.isFavourite}', 'isFavourite': '${entry.isFavourite}',
@ -104,7 +104,7 @@ class ViewerDebugPage extends StatelessWidget {
'canRotateAndFlip': '${entry.canRotateAndFlip}', 'canRotateAndFlip': '${entry.canRotateAndFlip}',
'xmpSubjects': '${entry.xmpSubjects}', 'xmpSubjects': '${entry.xmpSubjects}',
}), }),
Divider(), const Divider(),
InfoRowGroup({ InfoRowGroup({
'hasGps': '${entry.hasGps}', 'hasGps': '${entry.hasGps}',
'hasAddress': '${entry.hasAddress}', 'hasAddress': '${entry.hasAddress}',
@ -121,7 +121,7 @@ class ViewerDebugPage extends StatelessWidget {
if (entry.isSvg) { if (entry.isSvg) {
const extent = 128.0; const extent = 128.0;
children.addAll([ children.addAll([
Text('SVG ($extent)'), const Text('SVG ($extent)'),
SvgPicture( SvgPicture(
UriPicture( UriPicture(
uri: entry.uri, uri: entry.uri,
@ -140,12 +140,12 @@ class ViewerDebugPage extends StatelessWidget {
image: provider, image: provider,
), ),
), ),
SizedBox(height: 16), const SizedBox(height: 16),
]), ]),
); );
} }
return ListView( return ListView(
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
children: children, children: children,
); );
} }

View file

@ -65,7 +65,7 @@ class _MetadataTabState extends State<MetadataTab> {
children: [ children: [
if (data.isNotEmpty) if (data.isNotEmpty)
Padding( Padding(
padding: EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: InfoRowGroup( child: InfoRowGroup(
data, data,
maxValueLength: Constants.infoGroupMaxValueLength, maxValueLength: Constants.infoGroupMaxValueLength,
@ -77,12 +77,12 @@ class _MetadataTabState extends State<MetadataTab> {
Widget builderFromSnapshot(BuildContext context, AsyncSnapshot<Map> snapshot, String title) { Widget builderFromSnapshot(BuildContext context, AsyncSnapshot<Map> snapshot, String title) {
if (snapshot.hasError) return Text(snapshot.error.toString()); if (snapshot.hasError) return Text(snapshot.error.toString());
if (snapshot.connectionState != ConnectionState.done) return SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return builderFromSnapshotData(context, snapshot.data!, title); return builderFromSnapshotData(context, snapshot.data!, title);
} }
return ListView( return ListView(
padding: EdgeInsets.all(8), padding: const EdgeInsets.all(8),
children: [ children: [
FutureBuilder<Map>( FutureBuilder<Map>(
future: _bitmapFactoryLoader, future: _bitmapFactoryLoader,
@ -109,7 +109,7 @@ class _MetadataTabState extends State<MetadataTab> {
future: _tiffStructureLoader, future: _tiffStructureLoader,
builder: (context, 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 SizedBox.shrink(); if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink();
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: snapshot.data!.entries.map((kv) => builderFromSnapshotData(context, kv.value as Map, 'TIFF ${kv.key}')).toList(), children: snapshot.data!.entries.map((kv) => builderFromSnapshotData(context, kv.value as Map, 'TIFF ${kv.key}')).toList(),

View file

@ -156,7 +156,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
final destinationAlbum = await Navigator.push( final destinationAlbum = await Navigator.push(
context, context,
MaterialPageRoute<String>( MaterialPageRoute<String>(
settings: RouteSettings(name: AlbumPickPage.routeName), settings: const RouteSettings(name: AlbumPickPage.routeName),
builder: (context) => AlbumPickPage(source: source, moveType: MoveType.export), builder: (context) => AlbumPickPage(source: source, moveType: MoveType.export),
), ),
); );
@ -227,7 +227,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: SourceViewerPage.routeName), settings: const RouteSettings(name: SourceViewerPage.routeName),
builder: (context) => SourceViewerPage( builder: (context) => SourceViewerPage(
loader: () => imageFileService.getSvg(entry.uri, entry.mimeType).then(utf8.decode), loader: () => imageFileService.getSvg(entry.uri, entry.mimeType).then(utf8.decode),
), ),
@ -239,7 +239,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: ViewerDebugPage.routeName), settings: const RouteSettings(name: ViewerDebugPage.routeName),
builder: (context) => ViewerDebugPage(entry: entry), builder: (context) => ViewerDebugPage(entry: entry),
), ),
); );

View file

@ -35,10 +35,10 @@ class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticK
return MagnifierGestureDetectorScope( return MagnifierGestureDetectorScope(
axis: [Axis.horizontal, Axis.vertical], axis: [Axis.horizontal, Axis.vertical],
child: PageView.builder( child: PageView.builder(
key: Key('horizontal-pageview'), key: const Key('horizontal-pageview'),
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
controller: widget.pageController, controller: widget.pageController,
physics: MagnifierScrollerPhysics(parent: BouncingScrollPhysics()), physics: const MagnifierScrollerPhysics(parent: BouncingScrollPhysics()),
onPageChanged: widget.onPageChanged, onPageChanged: widget.onPageChanged,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final entry = entries[index]; final entry = entries[index];
@ -77,7 +77,7 @@ class _MultiEntryScrollerState extends State<MultiEntryScroller> with AutomaticK
selector: (c, mq) => mq.size, selector: (c, mq) => mq.size,
builder: (c, mqSize, child) { builder: (c, mqSize, child) {
return EntryPageView( return EntryPageView(
key: Key('imageview'), key: const Key('imageview'),
mainEntry: mainEntry, mainEntry: mainEntry,
pageEntry: pageEntry ?? mainEntry, pageEntry: pageEntry ?? mainEntry,
viewportSize: mqSize, viewportSize: mqSize,

View file

@ -82,7 +82,7 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// fake page for opacity transition between collection and viewer // fake page for opacity transition between collection and viewer
final transitionPage = SizedBox(); const transitionPage = SizedBox();
final imagePage = hasCollection final imagePage = hasCollection
? MultiEntryScroller( ? MultiEntryScroller(
@ -95,7 +95,7 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
? SingleEntryScroller( ? SingleEntryScroller(
entry: entry!, entry: entry!,
) )
: SizedBox(); : const SizedBox();
final infoPage = NotificationListener<BackUpNotification>( final infoPage = NotificationListener<BackUpNotification>(
onNotification: (notification) { onNotification: (notification) {
@ -130,10 +130,10 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
child: child, child: child,
), ),
child: PageView( child: PageView(
key: Key('vertical-pageview'), key: const Key('vertical-pageview'),
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
controller: widget.verticalPager, controller: widget.verticalPager,
physics: MagnifierScrollerPhysics(parent: PageScrollPhysics()), physics: const MagnifierScrollerPhysics(parent: PageScrollPhysics()),
onPageChanged: widget.onVerticalPageChanged, onPageChanged: widget.onVerticalPageChanged,
children: pages, children: pages,
), ),

View file

@ -101,7 +101,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
// no bounce at the bottom, to avoid video controller displacement // no bounce at the bottom, to avoid video controller displacement
curve: Curves.easeOutQuad, curve: Curves.easeOutQuad,
); );
_bottomOverlayOffset = Tween(begin: Offset(0, 1), end: Offset(0, 0)).animate(CurvedAnimation( _bottomOverlayOffset = Tween(begin: const Offset(0, 1), end: const Offset(0, 0)).animate(CurvedAnimation(
parent: _overlayAnimationController, parent: _overlayAnimationController,
curve: Curves.easeOutQuad, curve: Curves.easeOutQuad,
)); ));
@ -220,7 +220,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
Widget child = ValueListenableBuilder<AvesEntry?>( Widget child = ValueListenableBuilder<AvesEntry?>(
valueListenable: _entryNotifier, valueListenable: _entryNotifier,
builder: (context, mainEntry, child) { builder: (context, mainEntry, child) {
if (mainEntry == null) return SizedBox.shrink(); if (mainEntry == null) return const SizedBox.shrink();
return ViewerTopOverlay( return ViewerTopOverlay(
mainEntry: mainEntry, mainEntry: mainEntry,
@ -276,7 +276,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
Widget child = ValueListenableBuilder<AvesEntry?>( Widget child = ValueListenableBuilder<AvesEntry?>(
valueListenable: _entryNotifier, valueListenable: _entryNotifier,
builder: (context, mainEntry, child) { builder: (context, mainEntry, child) {
if (mainEntry == null) return SizedBox.shrink(); if (mainEntry == null) return const SizedBox.shrink();
Widget? _buildExtraBottomOverlay(AvesEntry pageEntry) { Widget? _buildExtraBottomOverlay(AvesEntry pageEntry) {
// a 360 video is both a video and a panorama but only the video controls are displayed // a 360 video is both a video and a panorama but only the video controls are displayed
@ -304,12 +304,12 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
stream: multiPageController.infoStream, stream: multiPageController.infoStream,
builder: (context, snapshot) { builder: (context, snapshot) {
final multiPageInfo = multiPageController.info; final multiPageInfo = multiPageController.info;
if (multiPageInfo == null) return SizedBox.shrink(); if (multiPageInfo == null) return const SizedBox.shrink();
return ValueListenableBuilder<int?>( return ValueListenableBuilder<int?>(
valueListenable: multiPageController.pageNotifier, valueListenable: multiPageController.pageNotifier,
builder: (context, page, child) { builder: (context, page, child) {
final pageEntry = multiPageInfo.getPageEntryByIndex(page); final pageEntry = multiPageInfo.getPageEntryByIndex(page);
return _buildExtraBottomOverlay(pageEntry) ?? SizedBox(); return _buildExtraBottomOverlay(pageEntry) ?? const SizedBox();
}, },
); );
}) })
@ -380,7 +380,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
Navigator.pushAndRemoveUntil( Navigator.pushAndRemoveUntil(
context, context,
MaterialPageRoute( MaterialPageRoute(
settings: RouteSettings(name: CollectionPage.routeName), settings: const RouteSettings(name: CollectionPage.routeName),
builder: (context) { builder: (context) {
return CollectionPage( return CollectionPage(
CollectionLens( CollectionLens(
@ -606,7 +606,7 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
// video decoding may fail or have initial artifacts when the player initializes // video decoding may fail or have initial artifacts when the player initializes
// during this widget initialization (because of the page transition and hero animation?) // during this widget initialization (because of the page transition and hero animation?)
// so we play after a delay for increased stability // so we play after a delay for increased stability
await Future.delayed(Duration(milliseconds: 300) * timeDilation); await Future.delayed(const Duration(milliseconds: 300) * timeDilation);
await videoController.play(); await videoController.play();

View file

@ -91,9 +91,9 @@ class BasicSection extends StatelessWidget {
...filters, ...filters,
if (entry.isFavourite) FavouriteFilter.instance, if (entry.isFavourite) FavouriteFilter.instance,
]..sort(); ]..sort();
if (effectiveFilters.isEmpty) return SizedBox.shrink(); if (effectiveFilters.isEmpty) return const SizedBox.shrink();
return Padding( return Padding(
padding: EdgeInsets.symmetric(horizontal: AvesFilterChip.outlineWidth / 2) + EdgeInsets.only(top: 8), padding: const EdgeInsets.symmetric(horizontal: AvesFilterChip.outlineWidth / 2) + const EdgeInsets.only(top: 8),
child: Wrap( child: Wrap(
spacing: 8, spacing: 8,
runSpacing: 8, runSpacing: 8,
@ -151,7 +151,7 @@ class _OwnerPropState extends State<OwnerProp> {
future: _ownerPackageFuture, future: _ownerPackageFuture,
builder: (context, snapshot) { builder: (context, snapshot) {
final ownerPackage = snapshot.data; final ownerPackage = snapshot.data;
if (ownerPackage == null) return SizedBox(); if (ownerPackage == null) return const SizedBox();
final appName = androidFileUtils.getCurrentAppName(ownerPackage) ?? ownerPackage; final appName = androidFileUtils.getCurrentAppName(ownerPackage) ?? ownerPackage;
// as of Flutter v1.22.6, `SelectableText` cannot contain `WidgetSpan` // as of Flutter v1.22.6, `SelectableText` cannot contain `WidgetSpan`
// so we use a basic `Text` instead // so we use a basic `Text` instead
@ -168,7 +168,7 @@ class _OwnerPropState extends State<OwnerProp> {
WidgetSpan( WidgetSpan(
alignment: PlaceholderAlignment.middle, alignment: PlaceholderAlignment.middle,
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(horizontal: 4), padding: const EdgeInsets.symmetric(horizontal: 4),
child: Image( child: Image(
image: AppIconImage( image: AppIconImage(
packageName: ownerPackage, packageName: ownerPackage,

View file

@ -13,7 +13,7 @@ class SectionRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const dim = 32.0; const dim = 32.0;
Widget buildDivider() => SizedBox( Widget buildDivider() => const SizedBox(
width: dim, width: dim,
child: Divider( child: Divider(
thickness: AvesFilterChip.outlineWidth, thickness: AvesFilterChip.outlineWidth,
@ -25,7 +25,7 @@ class SectionRow extends StatelessWidget {
children: [ children: [
buildDivider(), buildDivider(),
Padding( Padding(
padding: EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Icon( child: Icon(
icon, icon,
size: dim, size: dim,
@ -45,7 +45,7 @@ class InfoRowGroup extends StatefulWidget {
static const keyValuePadding = 16; static const keyValuePadding = 16;
static const linkColor = Colors.blue; static const linkColor = Colors.blue;
static const fontSize = 13.0; static const fontSize = 13.0;
static final baseStyle = TextStyle(fontSize: fontSize); static const baseStyle = TextStyle(fontSize: fontSize);
static final keyStyle = baseStyle.copyWith(color: Colors.white70, height: 2.0); static final keyStyle = baseStyle.copyWith(color: Colors.white70, height: 2.0);
static final linkStyle = baseStyle.copyWith(color: linkColor, decoration: TextDecoration.underline); static final linkStyle = baseStyle.copyWith(color: linkColor, decoration: TextDecoration.underline);
@ -70,7 +70,7 @@ class _InfoRowGroupState extends State<InfoRowGroup> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (keyValues.isEmpty) return SizedBox.shrink(); if (keyValues.isEmpty) return const SizedBox.shrink();
// compute the size of keys and space in order to align values // compute the size of keys and space in order to align values
final textScaleFactor = MediaQuery.textScaleFactorOf(context); final textScaleFactor = MediaQuery.textScaleFactorOf(context);
@ -143,7 +143,7 @@ class _InfoRowGroupState extends State<InfoRowGroup> {
span, span,
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
textScaleFactor: textScaleFactor, textScaleFactor: textScaleFactor,
)..layout(BoxConstraints(), parentUsesSize: true); )..layout(const BoxConstraints(), parentUsesSize: true);
return para.getMaxIntrinsicWidth(double.infinity); return para.getMaxIntrinsicWidth(double.infinity);
} }
} }

View file

@ -21,8 +21,8 @@ class InfoAppBar extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliverAppBar( return SliverAppBar(
leading: IconButton( leading: IconButton(
key: Key('back-button'), key: const Key('back-button'),
icon: Icon(AIcons.goUp), icon: const Icon(AIcons.goUp),
onPressed: onBackPressed, onPressed: onBackPressed,
tooltip: context.l10n.viewerInfoBackToViewerTooltip, tooltip: context.l10n.viewerInfoBackToViewerTooltip,
), ),
@ -32,7 +32,7 @@ class InfoAppBar extends StatelessWidget {
), ),
actions: [ actions: [
IconButton( IconButton(
icon: Icon(AIcons.search), icon: const Icon(AIcons.search),
onPressed: () => _goToSearch(context), onPressed: () => _goToSearch(context),
tooltip: MaterialLocalizations.of(context).searchFieldLabel, tooltip: MaterialLocalizations.of(context).searchFieldLabel,
), ),

View file

@ -67,7 +67,7 @@ class _InfoPageState extends State<InfoPage> {
split: mqWidth > 600, split: mqWidth > 600,
goToViewer: _goToViewer, goToViewer: _goToViewer,
) )
: SizedBox.shrink(); : const SizedBox.shrink();
}, },
); );
}, },
@ -114,7 +114,7 @@ class _InfoPageState extends State<InfoPage> {
Navigator.push( Navigator.push(
context, context,
TransparentMaterialPageRoute( TransparentMaterialPageRoute(
settings: RouteSettings(name: EntryViewerPage.routeName), settings: const RouteSettings(name: EntryViewerPage.routeName),
pageBuilder: (c, a, sa) => EntryViewerPage( pageBuilder: (c, a, sa) => EntryViewerPage(
initialEntry: tempEntry, initialEntry: tempEntry,
), ),
@ -175,7 +175,7 @@ class _InfoPageContentState extends State<_InfoPageContent> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded(child: basicSection), Expanded(child: basicSection),
SizedBox(width: 8), const SizedBox(width: 8),
Expanded(child: locationSection), Expanded(child: locationSection),
], ],
), ),
@ -202,11 +202,11 @@ class _InfoPageContentState extends State<_InfoPageContent> {
onBackPressed: widget.goToViewer, onBackPressed: widget.goToViewer,
), ),
SliverPadding( SliverPadding(
padding: horizontalPadding + EdgeInsets.only(top: 8), padding: horizontalPadding + const EdgeInsets.only(top: 8),
sliver: basicAndLocationSliver, sliver: basicAndLocationSliver,
), ),
SliverPadding( SliverPadding(
padding: horizontalPadding + EdgeInsets.only(bottom: 8), padding: horizontalPadding + const EdgeInsets.only(bottom: 8),
sliver: metadataSliver, sliver: metadataSliver,
), ),
BottomPaddingSliver(), BottomPaddingSliver(),

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