diff --git a/analysis_options.yaml b/analysis_options.yaml index f779f939d..157ed9498 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -3,3 +3,10 @@ include: package:pedantic/analysis_options.yaml analyzer: exclude: - lib/generated_plugin_registrant.dart + +linter: + rules: + - always_declare_return_types + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations diff --git a/lib/main.dart b/lib/main.dart index 0698d452c..b84007b9d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,10 +16,10 @@ import 'package:pedantic/pedantic.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:screen/screen.dart'; -final stopwatch = Stopwatch()..start(); +final _stopwatch = Stopwatch()..start(); void main() { - debugPrint('main start, elapsed=${stopwatch.elapsed}'); + debugPrint('main start, elapsed=${_stopwatch.elapsed}'); // initialize binding/plugins to configure Skia before `runApp` WidgetsFlutterBinding.ensureInitialized(); // 220ms // debugPrint('main WidgetsFlutterBinding.ensureInitialized done, elapsed=${stopwatch.elapsed}'); @@ -61,7 +61,7 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { static const EventChannel eventChannel = EventChannel('deckers.thibault/aves/mediastore'); - ImageCollection localMediaCollection = ImageCollection(entries: List()); + ImageCollection localMediaCollection = ImageCollection(entries: []); @override void initState() { @@ -72,7 +72,7 @@ class _HomePageState extends State { } Future setup() async { - debugPrint('$runtimeType setup start, elapsed=${stopwatch.elapsed}'); + debugPrint('$runtimeType setup start, elapsed=${_stopwatch.elapsed}'); // TODO reduce permission check time final permissions = await PermissionHandler().requestPermissions([ PermissionGroup.storage @@ -91,7 +91,7 @@ class _HomePageState extends State { await settings.init(); // <20ms localMediaCollection.groupFactor = settings.collectionGroupFactor; localMediaCollection.sortFactor = settings.collectionSortFactor; - debugPrint('$runtimeType setup settings.init done, elapsed=${stopwatch.elapsed}'); + debugPrint('$runtimeType setup settings.init done, elapsed=${_stopwatch.elapsed}'); await metadataDb.init(); // <20ms final currentTimeZone = await FlutterNativeTimezone.getLocalTimezone(); // <20ms @@ -107,7 +107,7 @@ class _HomePageState extends State { eventChannel.receiveBroadcastStream().cast().listen( (entryMap) => localMediaCollection.add(ImageEntry.fromMap(entryMap)), onDone: () async { - debugPrint('$runtimeType mediastore stream done, elapsed=${stopwatch.elapsed}'); + debugPrint('$runtimeType mediastore stream done, elapsed=${_stopwatch.elapsed}'); localMediaCollection.updateSections(); // <50ms // TODO reduce setup time until here localMediaCollection.updateAlbums(); // <50ms @@ -115,7 +115,7 @@ class _HomePageState extends State { await localMediaCollection.catalogEntries(); // <50ms await localMediaCollection.loadAddresses(); // 350ms await localMediaCollection.locateEntries(); // <50ms - debugPrint('$runtimeType setup end, elapsed=${stopwatch.elapsed}'); + debugPrint('$runtimeType setup end, elapsed=${_stopwatch.elapsed}'); }, onError: (error) => debugPrint('$runtimeType mediastore stream error=$error'), ); diff --git a/lib/model/image_collection.dart b/lib/model/image_collection.dart index 37dcc183c..7184782e9 100644 --- a/lib/model/image_collection.dart +++ b/lib/model/image_collection.dart @@ -8,11 +8,11 @@ import 'package:path/path.dart'; class ImageCollection with ChangeNotifier { final List _rawEntries; - Map> sections = Map(); + Map> sections = {}; GroupFactor groupFactor = GroupFactor.month; SortFactor sortFactor = SortFactor.date; - List sortedAlbums = List.unmodifiable(Iterable.empty()); - List sortedTags = List.unmodifiable(Iterable.empty()); + List sortedAlbums = List.unmodifiable(const Iterable.empty()); + List sortedTags = List.unmodifiable(const Iterable.empty()); ImageCollection({ @required List entries, @@ -140,7 +140,7 @@ class ImageCollection with ChangeNotifier { Future catalogEntries() async { final start = DateTime.now(); final uncataloguedEntries = _rawEntries.where((entry) => !entry.isCatalogued).toList(); - final newMetadata = List(); + final newMetadata = []; await Future.forEach(uncataloguedEntries, (entry) async { await entry.catalog(); newMetadata.add(entry.catalogMetadata); @@ -153,7 +153,7 @@ class ImageCollection with ChangeNotifier { Future locateEntries() async { final start = DateTime.now(); final unlocatedEntries = _rawEntries.where((entry) => entry.hasGps && !entry.isLocated).toList(); - final newAddresses = List(); + final newAddresses = []; await Future.forEach(unlocatedEntries, (entry) async { await entry.locate(); newAddresses.add(entry.addressDetails); diff --git a/lib/model/image_entry.dart b/lib/model/image_entry.dart index 55f4e1317..db7caab4f 100644 --- a/lib/model/image_entry.dart +++ b/lib/model/image_entry.dart @@ -1,5 +1,3 @@ -import 'dart:collection'; - import 'package:aves/model/image_file_service.dart'; import 'package:aves/model/image_metadata.dart'; import 'package:aves/model/metadata_service.dart'; @@ -50,19 +48,19 @@ class ImageEntry { factory ImageEntry.fromMap(Map map) { return ImageEntry( - uri: map['uri'], - path: map['path'], - contentId: map['contentId'], - mimeType: map['mimeType'], - width: map['width'], - height: map['height'], - orientationDegrees: map['orientationDegrees'], - sizeBytes: map['sizeBytes'], - title: map['title'], - dateModifiedSecs: map['dateModifiedSecs'], - sourceDateTakenMillis: map['sourceDateTakenMillis'], - bucketDisplayName: map['bucketDisplayName'], - durationMillis: map['durationMillis'], + uri: map['uri'] as String, + path: map['path'] as String, + contentId: map['contentId'] as int, + mimeType: map['mimeType'] as String, + width: map['width'] as int, + height: map['height'] as int, + orientationDegrees: map['orientationDegrees'] as int, + sizeBytes: map['sizeBytes'] as int, + title: map['title'] as String, + dateModifiedSecs: map['dateModifiedSecs'] as int, + sourceDateTakenMillis: map['sourceDateTakenMillis'] as int, + bucketDisplayName: map['bucketDisplayName'] as String, + durationMillis: map['durationMillis'] as int, ); } @@ -180,13 +178,11 @@ class ImageEntry { // admin area examples: Seoul, Geneva, null // locality examples: Mapo-gu, Geneva, Annecy - return LinkedHashSet.of( - [ - addressDetails.countryName, - addressDetails.adminArea, - addressDetails.locality - ], - ).where((part) => part != null && part.isNotEmpty).join(', '); + return { + addressDetails.countryName, + addressDetails.adminArea, + addressDetails.locality + }.where((part) => part != null && part.isNotEmpty).join(', '); } bool search(String query) { @@ -203,13 +199,13 @@ class ImageEntry { if (newFields.isEmpty) return false; final uri = newFields['uri']; - if (uri != null) this.uri = uri; + if (uri is String) this.uri = uri; final path = newFields['path']; - if (path != null) this.path = path; + if (path is String) this.path = path; final contentId = newFields['contentId']; - if (contentId != null) this.contentId = contentId; + if (contentId is int) this.contentId = contentId; final title = newFields['title']; - if (title != null) this.title = title; + if (title is String) this.title = title; metadataChangeNotifier.notifyListeners(); return true; } @@ -223,11 +219,11 @@ class ImageEntry { if (newFields.isEmpty) return false; final width = newFields['width']; - if (width != null) this.width = width; + if (width is int) this.width = width; final height = newFields['height']; - if (height != null) this.height = height; + if (height is int) this.height = height; final orientationDegrees = newFields['orientationDegrees']; - if (orientationDegrees != null) this.orientationDegrees = orientationDegrees; + if (orientationDegrees is int) this.orientationDegrees = orientationDegrees; imageChangeNotifier.notifyListeners(); return true; } diff --git a/lib/model/image_file_service.dart b/lib/model/image_file_service.dart index 1da519c21..e19491e90 100644 --- a/lib/model/image_file_service.dart +++ b/lib/model/image_file_service.dart @@ -65,7 +65,7 @@ class ImageFileService { } on PlatformException catch (e) { debugPrint('rename failed with exception=${e.message}'); } - return Map(); + return {}; } static Future rotate(ImageEntry entry, {@required bool clockwise}) async { @@ -79,6 +79,6 @@ class ImageFileService { } on PlatformException catch (e) { debugPrint('rotate failed with exception=${e.message}'); } - return Map(); + return {}; } } diff --git a/lib/model/metadata_db.dart b/lib/model/metadata_db.dart index 0ad5a037a..db91f6471 100644 --- a/lib/model/metadata_db.dart +++ b/lib/model/metadata_db.dart @@ -10,8 +10,8 @@ class MetadataDb { Future get path async => join(await getDatabasesPath(), 'metadata.db'); - static final metadataTable = 'metadata'; - static final addressTable = 'address'; + static const metadataTable = 'metadata'; + static const addressTable = 'address'; MetadataDb._private(); diff --git a/lib/model/metadata_service.dart b/lib/model/metadata_service.dart index 883002049..0c5ffe779 100644 --- a/lib/model/metadata_service.dart +++ b/lib/model/metadata_service.dart @@ -17,7 +17,7 @@ class MetadataService { } on PlatformException catch (e) { debugPrint('getAllMetadata failed with exception=${e.message}'); } - return Map(); + return {}; } static Future getCatalogMetadata(ImageEntry entry) async { diff --git a/lib/model/settings.dart b/lib/model/settings.dart index 16e9f2c06..b52de626d 100644 --- a/lib/model/settings.dart +++ b/lib/model/settings.dart @@ -5,12 +5,12 @@ import 'package:shared_preferences/shared_preferences.dart'; final Settings settings = Settings._private(); -typedef void SettingsCallback(String key, dynamic oldValue, dynamic newValue); +typedef SettingsCallback = void Function(String key, dynamic oldValue, dynamic newValue); class Settings { static SharedPreferences prefs; - ObserverList _listeners = ObserverList(); + final ObserverList _listeners = ObserverList(); Settings._private(); @@ -32,7 +32,7 @@ class Settings { debugPrint('$runtimeType notifyListeners key=$key, old=$oldValue, new=$newValue'); if (_listeners != null) { final List localListeners = _listeners.toList(); - for (SettingsCallback listener in localListeners) { + for (final listener in localListeners) { try { if (_listeners.contains(listener)) { listener(key, oldValue, newValue); @@ -66,7 +66,7 @@ class Settings { T getEnumOrDefault(String key, T defaultValue, Iterable values) { final valueString = prefs.getString(key); - for (T element in values) { + for (final element in values) { if (element.toString() == valueString) { return element; } diff --git a/lib/utils/android_app_service.dart b/lib/utils/android_app_service.dart index 208a067b8..06fb8482a 100644 --- a/lib/utils/android_app_service.dart +++ b/lib/utils/android_app_service.dart @@ -13,7 +13,7 @@ class AndroidAppService { } on PlatformException catch (e) { debugPrint('getAppNames failed with exception=${e.message}'); } - return Map(); + return {}; } static Future getAppIcon(String packageName, int size) async { diff --git a/lib/utils/geo_utils.dart b/lib/utils/geo_utils.dart index fa24c3bab..506c1b29f 100644 --- a/lib/utils/geo_utils.dart +++ b/lib/utils/geo_utils.dart @@ -27,7 +27,7 @@ String _decimal2sexagesimal(final double dec) { final List minParts = _split(min); final int minFractionalPart = minParts[1]; - final double sec = (double.parse('0.$minFractionalPart') * 60); + final double sec = double.parse('0.$minFractionalPart') * 60; return '$deg° ${min.floor()}′ ${_round(sec, decimals: 2).toStringAsFixed(2)}″'; } diff --git a/lib/utils/time_utils.dart b/lib/utils/time_utils.dart index a1f58e669..7ca2dd036 100644 --- a/lib/utils/time_utils.dart +++ b/lib/utils/time_utils.dart @@ -6,7 +6,7 @@ bool isAtSameDayAs(DateTime d1, DateTime d2) => isAtSameMonthAs(d1, d2) && d1.da bool isToday(DateTime d) => isAtSameDayAs(d, DateTime.now()); -bool isYesterday(DateTime d) => isAtSameDayAs(d, DateTime.now().subtract(Duration(days: 1))); +bool isYesterday(DateTime d) => isAtSameDayAs(d, DateTime.now().subtract(const Duration(days: 1))); bool isThisMonth(DateTime d) => isAtSameMonthAs(d, DateTime.now()); diff --git a/lib/widgets/album/all_collection_drawer.dart b/lib/widgets/album/all_collection_drawer.dart index 6dc52a838..af595b897 100644 --- a/lib/widgets/album/all_collection_drawer.dart +++ b/lib/widgets/album/all_collection_drawer.dart @@ -21,6 +21,9 @@ class AllCollectionDrawer extends StatelessWidget { padding: EdgeInsets.only(bottom: window.viewInsets.bottom), children: [ DrawerHeader( + decoration: BoxDecoration( + color: Theme.of(context).accentColor, + ), child: SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -28,18 +31,18 @@ class AllCollectionDrawer extends StatelessWidget { Row( children: [ CircleAvatar( + backgroundColor: Colors.white, + radius: 44, child: Padding( - padding: EdgeInsets.only(top: 6.0), + padding: const EdgeInsets.only(top: 6.0), child: SvgPicture.asset( 'assets/aves_logo.svg', width: 64, ), ), - backgroundColor: Colors.white, - radius: 44, ), - SizedBox(width: 16), - Text( + const SizedBox(width: 16), + const Text( 'Aves', style: TextStyle( fontSize: 44, @@ -48,28 +51,28 @@ class AllCollectionDrawer extends StatelessWidget { ), ], ), - SizedBox(height: 16), + const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row(children: [ Icon(Icons.photo_library), - SizedBox(width: 4), + const SizedBox(width: 4), Text('${collection.imageCount}') ]), Row(children: [ Icon(Icons.video_library), - SizedBox(width: 4), + const SizedBox(width: 4), Text('${collection.videoCount}') ]), Row(children: [ Icon(Icons.photo_album), - SizedBox(width: 4), + const SizedBox(width: 4), Text('${collection.albumCount}') ]), Row(children: [ Icon(Icons.label), - SizedBox(width: 4), + const SizedBox(width: 4), Text('${collection.tagCount}') ]), ], @@ -77,9 +80,6 @@ class AllCollectionDrawer extends StatelessWidget { ], ), ), - decoration: BoxDecoration( - color: Theme.of(context).accentColor, - ), ), _buildFilteredCollectionNavTile( context: context, @@ -87,14 +87,14 @@ class AllCollectionDrawer extends StatelessWidget { title: 'Videos', filter: (entry) => entry.isVideo, ), - Divider(), + const Divider(), ...albums.map((album) => _buildFilteredCollectionNavTile( context: context, leading: IconUtils.getAlbumIcon(context, album) ?? Icon(Icons.photo_album), title: collection.getUniqueAlbumName(album, albums), filter: (entry) => entry.directory == album, )), - Divider(), + const Divider(), ...tags.map((tag) => _buildFilteredCollectionNavTile( context: context, leading: Icon(Icons.label), @@ -106,7 +106,7 @@ class AllCollectionDrawer extends StatelessWidget { ); } - _buildFilteredCollectionNavTile({BuildContext context, Widget leading, String title, bool Function(ImageEntry) filter}) { + Widget _buildFilteredCollectionNavTile({BuildContext context, Widget leading, String title, bool Function(ImageEntry) filter}) { return SafeArea( top: false, bottom: false, diff --git a/lib/widgets/album/all_collection_page.dart b/lib/widgets/album/all_collection_page.dart index 56f7e5ce3..3c034a343 100644 --- a/lib/widgets/album/all_collection_page.dart +++ b/lib/widgets/album/all_collection_page.dart @@ -16,7 +16,7 @@ class AllCollectionPage extends StatelessWidget { return ThumbnailCollection( collection: collection, appBar: SliverAppBar( - title: Text('All'), + title: const Text('All'), actions: [ IconButton( icon: Icon(Icons.search), @@ -35,7 +35,7 @@ class AllCollectionPage extends StatelessWidget { value: AlbumAction.sortBySize, child: MenuRow(text: 'Sort by size', checked: collection.sortFactor == SortFactor.size), ), - PopupMenuDivider(), + const PopupMenuDivider(), if (collection.sortFactor == SortFactor.date) ...[ PopupMenuItem( value: AlbumAction.groupByAlbum, @@ -49,14 +49,14 @@ class AllCollectionPage extends StatelessWidget { value: AlbumAction.groupByDay, child: MenuRow(text: 'Group by day', checked: collection.groupFactor == GroupFactor.day), ), - PopupMenuDivider(), + const PopupMenuDivider(), ], PopupMenuItem( value: AlbumAction.debug, child: MenuRow(text: 'Debug', icon: Icons.whatshot), ), ], - onSelected: (action) => onActionSelected(context, action), + onSelected: (action) => _onActionSelected(context, action), ), ], floating: true, @@ -64,7 +64,7 @@ class AllCollectionPage extends StatelessWidget { ); } - onActionSelected(BuildContext context, AlbumAction action) { + void _onActionSelected(BuildContext context, AlbumAction action) { switch (action) { case AlbumAction.debug: goToDebug(context); diff --git a/lib/widgets/album/search_delegate.dart b/lib/widgets/album/search_delegate.dart index d13dc1a9f..adf4e6d1d 100644 --- a/lib/widgets/album/search_delegate.dart +++ b/lib/widgets/album/search_delegate.dart @@ -43,14 +43,14 @@ class ImageSearchDelegate extends SearchDelegate { @override Widget buildSuggestions(BuildContext context) { - return SizedBox.shrink(); + return const SizedBox.shrink(); } @override Widget buildResults(BuildContext context) { if (query.isEmpty) { showSuggestions(context); - return SizedBox.shrink(); + return const SizedBox.shrink(); } final lowerQuery = query.toLowerCase(); final matches = collection.sortedEntries.where((entry) => entry.search(lowerQuery)).toList(); diff --git a/lib/widgets/album/sections.dart b/lib/widgets/album/sections.dart index fad86a943..e09cd5e32 100644 --- a/lib/widgets/album/sections.dart +++ b/lib/widgets/album/sections.dart @@ -7,13 +7,13 @@ class DaySectionHeader extends StatelessWidget { final String text; DaySectionHeader({Key key, DateTime date}) - : text = formatDate(date), + : text = _formatDate(date), super(key: key); static DateFormat md = DateFormat.MMMMd(); static DateFormat ymd = DateFormat.yMMMMd(); - static formatDate(DateTime date) { + static String _formatDate(DateTime date) { if (isToday(date)) return 'Today'; if (isYesterday(date)) return 'Yesterday'; if (isThisYear(date)) return md.format(date); @@ -30,13 +30,13 @@ class MonthSectionHeader extends StatelessWidget { final String text; MonthSectionHeader({Key key, DateTime date}) - : text = formatDate(date), + : text = _formatDate(date), super(key: key); static DateFormat m = DateFormat.MMMM(); static DateFormat ym = DateFormat.yMMMM(); - static formatDate(DateTime date) { + static String _formatDate(DateTime date) { if (isThisMonth(date)) return 'This month'; if (isThisYear(date)) return m.format(date); return ym.format(date); @@ -64,7 +64,7 @@ class TitleSectionHeader extends StatelessWidget { fontFamily: 'Concourse Caps', shadows: [ Shadow( - offset: Offset(0, 2), + offset: const Offset(0, 2), blurRadius: 3, color: Colors.grey[900], ), @@ -74,12 +74,12 @@ class TitleSectionHeader extends StatelessWidget { outlineWidth: 2, ); return Container( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: leading != null ? Row( children: [ leading, - SizedBox(width: 8), + const SizedBox(width: 8), text, ], ) diff --git a/lib/widgets/album/thumbnail_collection.dart b/lib/widgets/album/thumbnail_collection.dart index 9e95eb82d..af4f25fed 100644 --- a/lib/widgets/album/thumbnail_collection.dart +++ b/lib/widgets/album/thumbnail_collection.dart @@ -13,7 +13,7 @@ class ThumbnailCollection extends AnimatedWidget { final ImageCollection collection; final Widget appBar; - ThumbnailCollection({ + const ThumbnailCollection({ Key key, this.collection, this.appBar, @@ -65,6 +65,12 @@ class ThumbnailCollectionContent extends StatelessWidget { child: Selector( selector: (c, mq) => mq.viewInsets.bottom, builder: (c, mqViewInsetsBottom, child) => DraggableScrollbar.arrows( + controller: _scrollController, + padding: EdgeInsets.only( + // top padding to adjust scroll thumb + top: topPadding, + bottom: mqViewInsetsBottom, + ), child: CustomScrollView( controller: _scrollController, slivers: [ @@ -89,12 +95,6 @@ class ThumbnailCollectionContent extends StatelessWidget { }), ], ), - controller: _scrollController, - padding: EdgeInsets.only( - // top padding to adjust scroll thumb - top: topPadding, - bottom: mqViewInsetsBottom, - ), ), ), ); @@ -117,7 +117,7 @@ class SectionSliver extends StatelessWidget { @override Widget build(BuildContext context) { - final columnCount = 4; + const columnCount = 4; return SliverStickyHeader( header: SectionHeader( collection: collection, @@ -143,7 +143,7 @@ class SectionSliver extends StatelessWidget { addAutomaticKeepAlives: false, addRepaintBoundaries: true, ), - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: columnCount, ), ), @@ -151,7 +151,7 @@ class SectionSliver extends StatelessWidget { ); } - _showFullscreen(BuildContext context, ImageEntry entry) { + void _showFullscreen(BuildContext context, ImageEntry entry) { Navigator.push( context, MaterialPageRoute( @@ -178,11 +178,11 @@ class SectionHeader extends StatelessWidget { @override Widget build(BuildContext context) { - Widget header = SizedBox.shrink(); + Widget header = const SizedBox.shrink(); if (collection.sortFactor == SortFactor.date) { switch (collection.groupFactor) { case GroupFactor.album: - Widget albumIcon = IconUtils.getAlbumIcon(context, sectionKey); + Widget albumIcon = IconUtils.getAlbumIcon(context, sectionKey as String); if (albumIcon != null) { albumIcon = Material( type: MaterialType.circle, @@ -194,14 +194,14 @@ class SectionHeader extends StatelessWidget { } header = TitleSectionHeader( leading: albumIcon, - title: collection.getUniqueAlbumName(sectionKey, sections.keys.cast()), + title: collection.getUniqueAlbumName(sectionKey as String, sections.keys.cast()), ); break; case GroupFactor.month: - header = MonthSectionHeader(date: sectionKey); + header = MonthSectionHeader(date: sectionKey as DateTime); break; case GroupFactor.day: - header = DaySectionHeader(date: sectionKey); + header = DaySectionHeader(date: sectionKey as DateTime); break; } } diff --git a/lib/widgets/common/app_icon.dart b/lib/widgets/common/app_icon.dart index 014a14be1..bfaf53e30 100644 --- a/lib/widgets/common/app_icon.dart +++ b/lib/widgets/common/app_icon.dart @@ -42,7 +42,7 @@ class AppIconState extends State { width: widget.size, height: widget.size, ) - : SizedBox.shrink(); + : const SizedBox.shrink(); }, ); } diff --git a/lib/widgets/common/fake_app_bar.dart b/lib/widgets/common/fake_app_bar.dart index ccbfece96..1a0308b2c 100644 --- a/lib/widgets/common/fake_app_bar.dart +++ b/lib/widgets/common/fake_app_bar.dart @@ -3,7 +3,7 @@ import 'package:flutter/widgets.dart'; class FakeAppBar extends StatelessWidget with PreferredSizeWidget { @override Widget build(BuildContext context) { - return SafeArea(child: SizedBox.shrink()); + return const SafeArea(child: SizedBox.shrink()); } @override diff --git a/lib/widgets/common/icons.dart b/lib/widgets/common/icons.dart index 80a960e1e..9a3ab7daa 100644 --- a/lib/widgets/common/icons.dart +++ b/lib/widgets/common/icons.dart @@ -61,10 +61,10 @@ class OverlayIcon extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - margin: EdgeInsets.all(1), + margin: const EdgeInsets.all(1), padding: text != null ? EdgeInsets.only(right: iconSize / 4) : null, decoration: BoxDecoration( - color: Color(0xBB000000), + color: const Color(0xBB000000), borderRadius: BorderRadius.all( Radius.circular(iconSize), ), @@ -78,7 +78,7 @@ class OverlayIcon extends StatelessWidget { size: iconSize, ), if (text != null) ...[ - SizedBox(width: 2), + const SizedBox(width: 2), Text(text), ] ], diff --git a/lib/widgets/common/image_preview.dart b/lib/widgets/common/image_preview.dart index 7ce43a46a..52fb9f44e 100644 --- a/lib/widgets/common/image_preview.dart +++ b/lib/widgets/common/image_preview.dart @@ -40,33 +40,33 @@ class ImagePreviewState extends State with AfterInitMixin { entry.imageChangeNotifier, entry.metadataChangeNotifier ]); - _entryChangeNotifier.addListener(onEntryChange); + _entryChangeNotifier.addListener(_onEntryChange); } @override void didInitState() { _devicePixelRatio = Provider.of(context, listen: false).devicePixelRatio; - initByteLoader(); + _initByteLoader(); } @override void didUpdateWidget(ImagePreview old) { super.didUpdateWidget(old); if (widget.width == old.width && widget.height == old.height && uri == old.entry.uri && widget.entry.width == old.entry.width && widget.entry.height == old.entry.height && widget.entry.orientationDegrees == old.entry.orientationDegrees) return; - initByteLoader(); + _initByteLoader(); } - initByteLoader() { + void _initByteLoader() { final width = (widget.width * _devicePixelRatio).round(); final height = (widget.height * _devicePixelRatio).round(); _byteLoader = ImageFileService.getImageBytes(widget.entry, width, height); } - onEntryChange() => setState(() => initByteLoader()); + void _onEntryChange() => setState(() => _initByteLoader()); @override void dispose() { - _entryChangeNotifier.removeListener(onEntryChange); + _entryChangeNotifier.removeListener(_onEntryChange); super.dispose(); } diff --git a/lib/widgets/common/menu_row.dart b/lib/widgets/common/menu_row.dart index 6c52b900e..26091d197 100644 --- a/lib/widgets/common/menu_row.dart +++ b/lib/widgets/common/menu_row.dart @@ -21,11 +21,11 @@ class MenuRow extends StatelessWidget { opacity: checked ? 1 : 0, child: Icon(Icons.done), ), - SizedBox(width: 8), + const SizedBox(width: 8), ], if (icon != null) ...[ Icon(icon), - SizedBox(width: 8), + const SizedBox(width: 8), ], Text(text), ], diff --git a/lib/widgets/debug_page.dart b/lib/widgets/debug_page.dart index 780b12a05..e9459c574 100644 --- a/lib/widgets/debug_page.dart +++ b/lib/widgets/debug_page.dart @@ -39,48 +39,48 @@ class DebugPageState extends State { return MediaQueryDataProvider( child: Scaffold( appBar: AppBar( - title: Text('Info'), + title: const Text('Info'), ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Paths'), + const Text('Paths'), Text('DCIM path: ${androidFileUtils.dcimPath}'), Text('pictures path: ${androidFileUtils.picturesPath}'), - Divider(), - Text('Settings'), + const Divider(), + const Text('Settings'), Text('collectionGroupFactor: ${settings.collectionGroupFactor}'), Text('collectionSortFactor: ${settings.collectionSortFactor}'), Text('infoMapZoom: ${settings.infoMapZoom}'), - Divider(), + const Divider(), Text('Entries: ${entries.length}'), ...byMimeTypes.keys.map((mimeType) => Text('- $mimeType: ${byMimeTypes[mimeType].length}')), Text('Catalogued: ${catalogued.length}'), Text('With GPS: ${withGps.length}'), Text('With address: ${located.length}'), - Divider(), + const Divider(), RaisedButton( onPressed: () => metadataDb.reset(), - child: Text('Reset DB'), + child: const Text('Reset DB'), ), FutureBuilder( future: _dbMetadataLoader, builder: (futureContext, AsyncSnapshot> snapshot) { - if (snapshot.hasError) return Text(snapshot.error); - if (snapshot.connectionState != ConnectionState.done) return SizedBox.shrink(); + if (snapshot.hasError) return Text(snapshot.error.toString()); + if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); return Text('DB metadata rows: ${snapshot.data.length}'); }, ), FutureBuilder( future: _dbAddressLoader, builder: (futureContext, AsyncSnapshot> snapshot) { - if (snapshot.hasError) return Text(snapshot.error); - if (snapshot.connectionState != ConnectionState.done) return SizedBox.shrink(); + if (snapshot.hasError) return Text(snapshot.error.toString()); + if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); return Text('DB address rows: ${snapshot.data.length}'); }, ), - Divider(), - Text('Time dilation'), + const Divider(), + const Text('Time dilation'), Slider( value: timeDilation, onChanged: (v) => setState(() => timeDilation = v), diff --git a/lib/widgets/fullscreen/fullscreen_action_delegate.dart b/lib/widgets/fullscreen/fullscreen_action_delegate.dart index e0d9735b1..916696a9b 100644 --- a/lib/widgets/fullscreen/fullscreen_action_delegate.dart +++ b/lib/widgets/fullscreen/fullscreen_action_delegate.dart @@ -61,14 +61,14 @@ class FullscreenActionDelegate { void _showFeedback(BuildContext context, String message) { Flushbar( message: message, - margin: EdgeInsets.all(8), + margin: const EdgeInsets.all(8), borderRadius: 8, borderColor: Colors.white30, borderWidth: 0.5, - duration: Duration(seconds: 2), + duration: const Duration(seconds: 2), flushbarPosition: FlushbarPosition.TOP, - animationDuration: Duration(milliseconds: 600), - )..show(context); + animationDuration: const Duration(milliseconds: 600), + ).show(context); } Future _print(ImageEntry entry) async { @@ -94,15 +94,15 @@ class FullscreenActionDelegate { context: context, builder: (BuildContext context) { return AlertDialog( - content: Text('Are you sure?'), + content: const Text('Are you sure?'), actions: [ FlatButton( onPressed: () => Navigator.pop(context), - child: Text('CANCEL'), + child: const Text('CANCEL'), ), FlatButton( onPressed: () => Navigator.pop(context, true), - child: Text('DELETE'), + child: const Text('DELETE'), ), ], ); @@ -130,11 +130,11 @@ class FullscreenActionDelegate { actions: [ FlatButton( onPressed: () => Navigator.pop(context), - child: Text('CANCEL'), + child: const Text('CANCEL'), ), FlatButton( onPressed: () => Navigator.pop(context, controller.text), - child: Text('APPLY'), + child: const Text('APPLY'), ), ], ); diff --git a/lib/widgets/fullscreen/fullscreen_page.dart b/lib/widgets/fullscreen/fullscreen_page.dart index 751a589bf..fdeab3a67 100644 --- a/lib/widgets/fullscreen/fullscreen_page.dart +++ b/lib/widgets/fullscreen/fullscreen_page.dart @@ -61,13 +61,13 @@ class FullscreenBodyState extends State with SingleTickerProvide bool _isInitialScale = true; int _currentHorizontalPage, _currentVerticalPage = imagePage; PageController _horizontalPager, _verticalPager; - ValueNotifier _overlayVisible = ValueNotifier(true); + final ValueNotifier _overlayVisible = ValueNotifier(true); AnimationController _overlayAnimationController; Animation _topOverlayScale; Animation _bottomOverlayOffset; EdgeInsets _frozenViewInsets, _frozenViewPadding; FullscreenActionDelegate _actionDelegate; - List> _videoControllers = List(); + final List> _videoControllers = []; ImageCollection get collection => widget.collection; @@ -85,14 +85,14 @@ class FullscreenBodyState extends State with SingleTickerProvide _horizontalPager = PageController(initialPage: _currentHorizontalPage); _verticalPager = PageController(initialPage: _currentVerticalPage); _overlayAnimationController = AnimationController( - duration: Duration(milliseconds: 400), + duration: const Duration(milliseconds: 400), vsync: this, ); _topOverlayScale = CurvedAnimation( parent: _overlayAnimationController, curve: Curves.easeOutQuart, ); - _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, curve: Curves.easeOutQuart, )); @@ -105,7 +105,7 @@ class FullscreenBodyState extends State with SingleTickerProvide _initOverlay(); } - _initOverlay() async { + Future _initOverlay() async { // wait for MaterialPageRoute.transitionDuration // to show overlay after hero animation is complete await Future.delayed(Duration(milliseconds: (300 * timeDilation).toInt())); @@ -136,10 +136,10 @@ class FullscreenBodyState extends State with SingleTickerProvide PageView( scrollDirection: Axis.vertical, controller: _verticalPager, - physics: _isInitialScale ? PageScrollPhysics() : NeverScrollableScrollPhysics(), + physics: _isInitialScale ? const PageScrollPhysics() : const NeverScrollableScrollPhysics(), onPageChanged: _onVerticalPageChanged, children: [ - SizedBox(), + const SizedBox(), Container( color: Colors.black, child: ImagePage( @@ -208,12 +208,12 @@ class FullscreenBodyState extends State with SingleTickerProvide Future _goToVerticalPage(int page) { return _verticalPager.animateToPage( page, - duration: Duration(milliseconds: 350), + duration: const Duration(milliseconds: 350), curve: Curves.easeInOut, ); } - void _onVerticalPageChanged(page) { + void _onVerticalPageChanged(int page) { setState(() => _currentVerticalPage = page); if (_currentVerticalPage == transitionPage) { _onLeave(); diff --git a/lib/widgets/fullscreen/image_page.dart b/lib/widgets/fullscreen/image_page.dart index 117e74a69..c620415d2 100644 --- a/lib/widgets/fullscreen/image_page.dart +++ b/lib/widgets/fullscreen/image_page.dart @@ -51,7 +51,7 @@ class ImagePageState extends State with AutomaticKeepAliveClientMixin entry: entry, controller: videoController, ) - : SizedBox(), + : const SizedBox(), childSize: mqSize, // no hero as most videos fullscreen image is different from its thumbnail minScale: PhotoViewComputedScale.contained, @@ -70,14 +70,14 @@ class ImagePageState extends State with AutomaticKeepAliveClientMixin onTapUp: (tapContext, details, value) => widget.onTap?.call(), ); }, - loadingChild: Center( + loadingChild: const Center( child: CircularProgressIndicator(), ), backgroundDecoration: BoxDecoration(color: Colors.transparent), pageController: widget.pageController, onPageChanged: widget.onPageChanged, scaleStateChangedCallback: widget.onScaleChanged, - scrollPhysics: BouncingScrollPhysics(), + scrollPhysics: const BouncingScrollPhysics(), ), ); } diff --git a/lib/widgets/fullscreen/info/info_page.dart b/lib/widgets/fullscreen/info/info_page.dart index d0d839b12..e72ba39f9 100644 --- a/lib/widgets/fullscreen/info/info_page.dart +++ b/lib/widgets/fullscreen/info/info_page.dart @@ -119,7 +119,7 @@ class SectionRow extends StatelessWidget { padding: const EdgeInsets.all(16.0), child: Text( title, - style: TextStyle( + style: const TextStyle( fontSize: 20, fontFamily: 'Concourse Caps', ), @@ -142,9 +142,9 @@ class InfoRow extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 4.0), child: RichText( text: TextSpan( - style: TextStyle(fontFamily: 'Concourse'), + style: const TextStyle(fontFamily: 'Concourse'), children: [ - TextSpan(text: '$label ', style: TextStyle(color: Colors.white70)), + TextSpan(text: '$label ', style: const TextStyle(color: Colors.white70)), TextSpan(text: value), ], ), diff --git a/lib/widgets/fullscreen/info/location_section.dart b/lib/widgets/fullscreen/info/location_section.dart index aa5f9252c..decb77ed8 100644 --- a/lib/widgets/fullscreen/info/location_section.dart +++ b/lib/widgets/fullscreen/info/location_section.dart @@ -7,7 +7,7 @@ import 'package:google_maps_flutter/google_maps_flutter.dart'; class LocationSection extends AnimatedWidget { final ImageEntry entry; - final showTitle; + final bool showTitle; LocationSection({ Key key, @@ -23,12 +23,12 @@ class LocationSection extends AnimatedWidget { @override Widget build(BuildContext context) { return !entry.hasGps - ? SizedBox.shrink() + ? const SizedBox.shrink() : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (showTitle) - Padding( + const Padding( padding: EdgeInsets.only(bottom: 8), child: SectionRow('Location'), ), @@ -43,7 +43,7 @@ class LocationSection extends AnimatedWidget { ), if (entry.isLocated) Padding( - padding: EdgeInsets.only(top: 8), + padding: const EdgeInsets.only(top: 8), child: InfoRow('Address', entry.addressDetails.addressLine), ), ], @@ -90,7 +90,7 @@ class ImageMapState extends State with AutomaticKeepAliveClientMixin { child: SizedBox( height: 200, child: ClipRRect( - borderRadius: BorderRadius.all( + borderRadius: const BorderRadius.all( Radius.circular(16), ), child: GoogleMap( @@ -104,18 +104,18 @@ class ImageMapState extends State with AutomaticKeepAliveClientMixin { zoomGesturesEnabled: false, tiltGesturesEnabled: false, myLocationButtonEnabled: false, - markers: [ + markers: { Marker( markerId: MarkerId(widget.markerId), icon: BitmapDescriptor.defaultMarkerWithHue(accentHue), position: widget.latLng, ) - ].toSet(), + }, ), ), ), ), - SizedBox(width: 8), + const SizedBox(width: 8), Column(children: [ IconButton( icon: Icon(Icons.add), @@ -137,7 +137,7 @@ class ImageMapState extends State with AutomaticKeepAliveClientMixin { ); } - _zoomBy(double amount) { + void _zoomBy(double amount) { settings.infoMapZoom += amount; _controller.animateCamera(CameraUpdate.zoomBy(amount)); } diff --git a/lib/widgets/fullscreen/info/metadata_section.dart b/lib/widgets/fullscreen/info/metadata_section.dart index 34c1616a1..096079a22 100644 --- a/lib/widgets/fullscreen/info/metadata_section.dart +++ b/lib/widgets/fullscreen/info/metadata_section.dart @@ -23,16 +23,16 @@ class MetadataSectionState extends State { @override void initState() { super.initState(); - initMetadataLoader(); + _initMetadataLoader(); } @override void didUpdateWidget(MetadataSection oldWidget) { super.didUpdateWidget(oldWidget); - initMetadataLoader(); + _initMetadataLoader(); } - initMetadataLoader() async { + Future _initMetadataLoader() async { _metadataLoader = MetadataService.getAllMetadata(widget.entry); } @@ -43,9 +43,9 @@ class MetadataSectionState extends State { builder: (c, mqWidth, child) => FutureBuilder( future: _metadataLoader, builder: (futureContext, AsyncSnapshot snapshot) { - if (snapshot.hasError) return Text(snapshot.error); - if (snapshot.connectionState != ConnectionState.done) return SizedBox.shrink(); final metadataMap = snapshot.data.cast(); + if (snapshot.hasError) return Text(snapshot.error.toString()); + if (snapshot.connectionState != ConnectionState.done) return const SizedBox.shrink(); final directoryNames = metadataMap.keys.toList()..sort(); Widget content; @@ -68,7 +68,7 @@ class MetadataSectionState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(child: getMetadataColumn(metadataMap, first)), - SizedBox(width: 8), + const SizedBox(width: 8), Expanded(child: getMetadataColumn(metadataMap, second)), ], ); @@ -79,7 +79,7 @@ class MetadataSectionState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - SectionRow('Metadata'), + const SectionRow('Metadata'), content, ], ); @@ -98,19 +98,19 @@ class MetadataSectionState extends State { return [ if (directoryName.isNotEmpty) Padding( - padding: EdgeInsets.symmetric(vertical: 4.0), + padding: const EdgeInsets.symmetric(vertical: 4.0), child: Text(directoryName, - style: TextStyle( + style: const TextStyle( fontSize: 18, fontFamily: 'Concourse Caps', )), ), ...tagKeys.map((tagKey) { final value = directory[tagKey] as String; - if (value == null || value.isEmpty) return SizedBox.shrink(); + if (value == null || value.isEmpty) return const SizedBox.shrink(); return InfoRow(tagKey, value.length > maxValueLength ? '${value.substring(0, maxValueLength)}…' : value); }), - SizedBox(height: 16), + const SizedBox(height: 16), ]; }), ], diff --git a/lib/widgets/fullscreen/info/xmp_section.dart b/lib/widgets/fullscreen/info/xmp_section.dart index ada5266f9..83c580047 100644 --- a/lib/widgets/fullscreen/info/xmp_section.dart +++ b/lib/widgets/fullscreen/info/xmp_section.dart @@ -18,15 +18,15 @@ class XmpTagSection extends AnimatedWidget { Widget build(BuildContext context) { final tags = entry.xmpSubjects; return tags.isEmpty - ? SizedBox.shrink() + ? const SizedBox.shrink() : Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SectionRow('XMP Tags'), + const SectionRow('XMP Tags'), Wrap( children: tags .map((tag) => Padding( - padding: EdgeInsets.symmetric(horizontal: 4.0), + padding: const EdgeInsets.symmetric(horizontal: 4.0), child: ActionChip( label: Text(tag), onPressed: () => Navigator.push( diff --git a/lib/widgets/fullscreen/overlay/bottom.dart b/lib/widgets/fullscreen/overlay/bottom.dart index 606d7aa76..77a43fd79 100644 --- a/lib/widgets/fullscreen/overlay/bottom.dart +++ b/lib/widgets/fullscreen/overlay/bottom.dart @@ -45,16 +45,16 @@ class _FullscreenBottomOverlayState extends State { @override void initState() { super.initState(); - initDetailLoader(); + _initDetailLoader(); } @override void didUpdateWidget(FullscreenBottomOverlay oldWidget) { super.didUpdateWidget(oldWidget); - initDetailLoader(); + _initDetailLoader(); } - initDetailLoader() { + void _initDetailLoader() { _detailLoader = MetadataService.getOverlayMetadata(entry); } @@ -86,7 +86,7 @@ class _FullscreenBottomOverlayState extends State { _lastEntry = entry; } return _lastEntry == null - ? SizedBox.shrink() + ? const SizedBox.shrink() : _FullscreenBottomOverlayContent( entry: _lastEntry, details: _lastDetails, @@ -115,7 +115,7 @@ class _FullscreenBottomOverlayContent extends StatelessWidget { final String position; final double maxWidth; - _FullscreenBottomOverlayContent({ + const _FullscreenBottomOverlayContent({ this.entry, this.details, this.position, diff --git a/lib/widgets/fullscreen/overlay/top.dart b/lib/widgets/fullscreen/overlay/top.dart index 576ada268..61f0a70d8 100644 --- a/lib/widgets/fullscreen/overlay/top.dart +++ b/lib/widgets/fullscreen/overlay/top.dart @@ -28,14 +28,14 @@ class FullscreenTopOverlay extends StatelessWidget { return SafeArea( minimum: (viewInsets ?? EdgeInsets.zero) + (viewPadding ?? EdgeInsets.zero), child: Padding( - padding: EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8.0), child: Row( children: [ OverlayButton( scale: scale, - child: BackButton(), + child: const BackButton(), ), - Spacer(), + const Spacer(), OverlayButton( scale: scale, child: IconButton( @@ -44,7 +44,7 @@ class FullscreenTopOverlay extends StatelessWidget { tooltip: 'Share', ), ), - SizedBox(width: 8), + const SizedBox(width: 8), OverlayButton( scale: scale, child: IconButton( @@ -53,7 +53,7 @@ class FullscreenTopOverlay extends StatelessWidget { tooltip: 'Delete', ), ), - SizedBox(width: 8), + const SizedBox(width: 8), OverlayButton( scale: scale, child: PopupMenuButton( @@ -81,21 +81,21 @@ class FullscreenTopOverlay extends StatelessWidget { value: FullscreenAction.print, child: MenuRow(text: 'Print', icon: Icons.print), ), - PopupMenuDivider(), - PopupMenuItem( + const PopupMenuDivider(), + const PopupMenuItem( value: FullscreenAction.edit, child: Text('Edit with…'), ), - PopupMenuItem( + const PopupMenuItem( value: FullscreenAction.open, child: Text('Open with…'), ), - PopupMenuItem( + const PopupMenuItem( value: FullscreenAction.setAs, child: Text('Set as…'), ), if (entry.hasGps) - PopupMenuItem( + const PopupMenuItem( value: FullscreenAction.openMap, child: Text('Show on map…'), ), diff --git a/lib/widgets/fullscreen/overlay/video.dart b/lib/widgets/fullscreen/overlay/video.dart index 7d9354f12..24734c1b9 100644 --- a/lib/widgets/fullscreen/overlay/video.dart +++ b/lib/widgets/fullscreen/overlay/video.dart @@ -46,32 +46,32 @@ class VideoControlOverlayState extends State with SingleTic void initState() { super.initState(); _playPauseAnimation = AnimationController( - duration: Duration(milliseconds: 300), + duration: const Duration(milliseconds: 300), vsync: this, ); - registerWidget(widget); + _registerWidget(widget); _onValueChange(); } @override void didUpdateWidget(VideoControlOverlay oldWidget) { super.didUpdateWidget(oldWidget); - unregisterWidget(oldWidget); - registerWidget(widget); + _unregisterWidget(oldWidget); + _registerWidget(widget); } @override void dispose() { - unregisterWidget(widget); + _unregisterWidget(widget); _playPauseAnimation.dispose(); super.dispose(); } - void registerWidget(VideoControlOverlay widget) { + void _registerWidget(VideoControlOverlay widget) { widget.controller.addListener(_onValueChange); } - void unregisterWidget(VideoControlOverlay widget) { + void _unregisterWidget(VideoControlOverlay widget) { widget.controller.removeListener(_onValueChange); } @@ -86,7 +86,7 @@ class VideoControlOverlayState extends State with SingleTic final viewInsets = widget.viewInsets ?? mqViewInsets; final viewPadding = widget.viewPadding ?? mqViewPadding; - final safePadding = (viewInsets + viewPadding).copyWith(bottom: 8) + EdgeInsets.symmetric(horizontal: 8.0); + final safePadding = (viewInsets + viewPadding).copyWith(bottom: 8) + const EdgeInsets.symmetric(horizontal: 8.0); return Padding( padding: safePadding, @@ -109,7 +109,7 @@ class VideoControlOverlayState extends State with SingleTic Expanded( child: _buildProgressBar(), ), - SizedBox(width: 8), + const SizedBox(width: 8), OverlayButton( scale: scale, child: IconButton( @@ -130,7 +130,7 @@ class VideoControlOverlayState extends State with SingleTic } Widget _buildProgressBar() { - final progressBarBorderRadius = 123.0; + const progressBarBorderRadius = 123.0; return SizeTransition( sizeFactor: scale, child: BlurredRRect( @@ -150,11 +150,11 @@ class VideoControlOverlayState extends State with SingleTic if (_playingOnDragStart) controller.play(); }, child: Container( - padding: EdgeInsets.symmetric(vertical: 4, horizontal: 16) + EdgeInsets.only(bottom: 16), + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16) + const EdgeInsets.only(bottom: 16), decoration: BoxDecoration( color: Colors.black26, border: Border.all(color: Colors.white30, width: 0.5), - borderRadius: BorderRadius.all( + borderRadius: const BorderRadius.all( Radius.circular(progressBarBorderRadius), ), ), @@ -164,7 +164,7 @@ class VideoControlOverlayState extends State with SingleTic Row( children: [ Text(formatDuration(value.position ?? Duration.zero)), - Spacer(), + const Spacer(), Text(formatDuration(value.duration ?? Duration.zero)), ], ), diff --git a/lib/widgets/fullscreen/video.dart b/lib/widgets/fullscreen/video.dart index 74cd4bba4..2e12a2050 100644 --- a/lib/widgets/fullscreen/video.dart +++ b/lib/widgets/fullscreen/video.dart @@ -29,34 +29,34 @@ class AvesVideoState extends State { @override void initState() { super.initState(); - registerWidget(widget); + _registerWidget(widget); _onValueChange(); } @override void didUpdateWidget(AvesVideo oldWidget) { super.didUpdateWidget(oldWidget); - unregisterWidget(oldWidget); - registerWidget(widget); + _unregisterWidget(oldWidget); + _registerWidget(widget); } @override void dispose() { - unregisterWidget(widget); + _unregisterWidget(widget); super.dispose(); } - registerWidget(AvesVideo widget) { + void _registerWidget(AvesVideo widget) { widget.controller.addListener(_onValueChange); } - unregisterWidget(AvesVideo widget) { + void _unregisterWidget(AvesVideo widget) { widget.controller.removeListener(_onValueChange); } @override Widget build(BuildContext context) { - if (value == null) return SizedBox(); + if (value == null) return const SizedBox(); if (value.hasError) { return Selector( selector: (c, mq) => mq.size.width, @@ -79,12 +79,12 @@ class AvesVideoState extends State { ); } - _onValueChange() { - if (!value.isPlaying && value.position == value.duration) goToBeginning(); + void _onValueChange() { + if (!value.isPlaying && value.position == value.duration) _goToStart(); setState(() {}); } - goToBeginning() async { + Future _goToStart() async { await widget.controller.seekTo(Duration.zero); await widget.controller.pause(); }