diff --git a/analysis_options.yaml b/analysis_options.yaml index 1492838..42e96ec 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -26,6 +26,10 @@ linter: always_use_package_imports: true sort_constructors_first: true sort_unnamed_constructors_first: true + avoid_types_on_closure_parameters: true + omit_local_variable_types: true + prefer_final_in_for_each: true + prefer_final_locals: true analyzer: exclude: diff --git a/lib/home.dart b/lib/home.dart index c0193c5..fb80017 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -143,7 +143,7 @@ class _HomeState extends State { Widget _buildNotificationIcon(BuildContext context, IconData iconData) { final theme = Provider.of(context); - int count = Provider.of(context).count; + final count = Provider.of(context).count; if (count == 0) { return Icon(iconData); } diff --git a/lib/main.dart b/lib/main.dart index c3b336b..25dfe49 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -42,7 +42,7 @@ void main() async { ChangeNotifierProvider(create: (context) => authModel), ChangeNotifierProvider(create: (context) => codeModel), ], - child: MyApp(), + child: const MyApp(), )); }, ); diff --git a/lib/models/auth.dart b/lib/models/auth.dart index f1390c5..7185650 100644 --- a/lib/models/auth.dart +++ b/lib/models/auth.dart @@ -238,7 +238,7 @@ class AuthModel with ChangeNotifier { Map body = const {}, }) async { late http.Response res; - Map headers = { + final headers = { 'Authorization': 'token $token', HttpHeaders.contentTypeHeader: 'application/json' }; @@ -342,7 +342,7 @@ class AuthModel with ChangeNotifier { Map body = const {}, }) async { late http.Response res; - Map headers = { + final headers = { 'Authorization': 'token $token', HttpHeaders.contentTypeHeader: 'application/json' }; @@ -418,7 +418,7 @@ class AuthModel with ChangeNotifier { Map body = const {}, }) async { http.Response res; - Map headers = { + final headers = { 'Authorization': 'token $token', HttpHeaders.contentTypeHeader: 'application/json' }; @@ -612,11 +612,11 @@ class AuthModel with ChangeNotifier { Fimber.e('getUriLinksStream failed', ex: err); }); - var prefs = await SharedPreferences.getInstance(); + final prefs = await SharedPreferences.getInstance(); // Read accounts try { - String? str = prefs.getString(StorageKeys.accounts); + final str = prefs.getString(StorageKeys.accounts); // Fimber.d('read accounts: $str'); _accounts = (json.decode(str ?? '[]') as List) .map((item) => Account.fromJson(item)) diff --git a/lib/models/code.dart b/lib/models/code.dart index ca860bc..adbf7b1 100644 --- a/lib/models/code.dart +++ b/lib/models/code.dart @@ -39,11 +39,11 @@ class CodeModel with ChangeNotifier { } Future init() async { - var prefs = await SharedPreferences.getInstance(); - var vh = prefs.getString(StorageKeys.codeTheme); - var vdh = prefs.getString(StorageKeys.codeThemeDark); - var vs = prefs.getInt(StorageKeys.iCodeFontSize); - var vf = prefs.getString(StorageKeys.codeFontFamily); + final prefs = await SharedPreferences.getInstance(); + final vh = prefs.getString(StorageKeys.codeTheme); + final vdh = prefs.getString(StorageKeys.codeThemeDark); + final vs = prefs.getInt(StorageKeys.iCodeFontSize); + final vf = prefs.getString(StorageKeys.codeFontFamily); Fimber.d('read code: $vh, $vs, $vf'); if (themeMap.keys.contains(vh)) { @@ -63,7 +63,7 @@ class CodeModel with ChangeNotifier { } setTheme(String v) async { - var prefs = await SharedPreferences.getInstance(); + final prefs = await SharedPreferences.getInstance(); await prefs.setString(StorageKeys.codeTheme, v); Fimber.d('write code theme: $v'); @@ -73,7 +73,7 @@ class CodeModel with ChangeNotifier { } setThemeDark(String v) async { - var prefs = await SharedPreferences.getInstance(); + final prefs = await SharedPreferences.getInstance(); await prefs.setString(StorageKeys.codeThemeDark, v); Fimber.d('write code theme dark: $v'); @@ -83,7 +83,7 @@ class CodeModel with ChangeNotifier { } setFontSize(int v) async { - var prefs = await SharedPreferences.getInstance(); + final prefs = await SharedPreferences.getInstance(); await prefs.setInt(StorageKeys.iCodeFontSize, v); Fimber.d('write code font size: $v'); @@ -93,7 +93,7 @@ class CodeModel with ChangeNotifier { } setFontFamily(String v) async { - var prefs = await SharedPreferences.getInstance(); + final prefs = await SharedPreferences.getInstance(); await prefs.setString(StorageKeys.codeFontFamily, v); Fimber.d('write code font family: $v'); diff --git a/lib/models/github.dart b/lib/models/github.dart index 3fccc9d..ec3966b 100644 --- a/lib/models/github.dart +++ b/lib/models/github.dart @@ -353,8 +353,8 @@ class GithubGistsItem { Map? files; GithubEventUser? owner; List get fileNames { - List filenames = []; - files!.forEach((String key, GistFiles value) { + final filenames = []; + files!.forEach((key, value) { filenames.add(value); }); return filenames; diff --git a/lib/models/theme.dart b/lib/models/theme.dart index f923524..2fff40d 100644 --- a/lib/models/theme.dart +++ b/lib/models/theme.dart @@ -58,14 +58,14 @@ class SelectorItem { class StaticRoute extends PageRouteBuilder { StaticRoute({this.builder}) : super( - pageBuilder: (BuildContext context, Animation animation, - Animation secondaryAnimation) { + pageBuilder: (context, animation, + secondaryAnimation) { return builder!(context); }, - transitionsBuilder: (BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child) { + transitionsBuilder: (context, + animation, + secondaryAnimation, + child) { return child; }, ); diff --git a/lib/scaffolds/list_stateful.dart b/lib/scaffolds/list_stateful.dart index b3e29cb..4a242e2 100644 --- a/lib/scaffolds/list_stateful.dart +++ b/lib/scaffolds/list_stateful.dart @@ -65,7 +65,7 @@ class _ListStatefulScaffoldState loading = true; }); try { - final ListPayload p = await widget.fetch(null); + final p = await widget.fetch(null); items = p.items.toList(); cursor = p.cursor; hasMore = p.hasMore; @@ -87,7 +87,7 @@ class _ListStatefulScaffoldState loadingMore = true; }); try { - ListPayload p = await widget.fetch(cursor); + final p = await widget.fetch(cursor); items.addAll(p.items); cursor = p.cursor; hasMore = p.hasMore; diff --git a/lib/scaffolds/long_list.dart b/lib/scaffolds/long_list.dart index daf814d..86a4901 100644 --- a/lib/scaffolds/long_list.dart +++ b/lib/scaffolds/long_list.dart @@ -89,7 +89,7 @@ class _LongListStatefulScaffoldState loadingMore = true; }); try { - LongListPayload p = await widget.onLoadMore(payload!.cursor); + final LongListPayload p = await widget.onLoadMore(payload!.cursor); payload!.totalCount = p.totalCount; payload!.cursor = p.cursor; payload!.leadingItems.addAll(p.leadingItems); @@ -109,12 +109,12 @@ class _LongListStatefulScaffoldState return CommonStyle.border; } - int realIndex = index ~/ 2; + final realIndex = index ~/ 2; if (realIndex < payload!.leadingItems.length) { return widget.itemBuilder(payload!.leadingItems[realIndex]); } else if (realIndex == payload!.leadingItems.length) { - var count = payload!.totalCount - + final count = payload!.totalCount - payload!.leadingItems.length + payload!.trailingItems!.length; return Container( @@ -153,7 +153,7 @@ class _LongListStatefulScaffoldState } int get _itemCount { - int count = payload!.leadingItems.length + payload!.trailingItems!.length; + var count = payload!.leadingItems.length + payload!.trailingItems!.length; if (payload!.totalCount > count) { count++; } @@ -177,7 +177,7 @@ class _LongListStatefulScaffoldState @override Widget build(BuildContext context) { - List slivers = [CupertinoSliverRefreshControl(onRefresh: _refresh)]; + final slivers = [CupertinoSliverRefreshControl(onRefresh: _refresh)]; if (payload != null) { slivers.add( SliverToBoxAdapter(child: widget.headerBuilder(payload!.header)), diff --git a/lib/screens/bb_issues.dart b/lib/screens/bb_issues.dart index 6194b48..02fa0b9 100644 --- a/lib/screens/bb_issues.dart +++ b/lib/screens/bb_issues.dart @@ -34,7 +34,7 @@ class BbIssuesScreen extends StatelessWidget { ); }, itemBuilder: (v) { - int issueNumber = + final issueNumber = int.parse(v.issueLink!.replaceFirst(RegExp(r'.*\/'), '')); return IssueItem( avatarUrl: v.reporter!.avatarUrl, diff --git a/lib/screens/bb_pulls.dart b/lib/screens/bb_pulls.dart index 1ee6cfc..be96574 100644 --- a/lib/screens/bb_pulls.dart +++ b/lib/screens/bb_pulls.dart @@ -29,7 +29,7 @@ class BbPullsScreen extends StatelessWidget { ); }, itemBuilder: (v) { - int pullNumber = + final pullNumber = int.parse(v.pullRequestLink!.replaceFirst(RegExp(r'.*\/'), '')); return IssueItem( avatarUrl: v.author!.avatarUrl, diff --git a/lib/screens/code_theme.dart b/lib/screens/code_theme.dart index fbcb97d..c0aba69 100644 --- a/lib/screens/code_theme.dart +++ b/lib/screens/code_theme.dart @@ -35,8 +35,8 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - var codeProvider = Provider.of(context); - var theme = Provider.of(context); + final codeProvider = Provider.of(context); + final theme = Provider.of(context); return SingleScaffold( title: AppBarTitle(AppLocalizations.of(context)!.codeTheme), @@ -76,7 +76,7 @@ class MyApp extends StatelessWidget { items: CodeModel.fontFamilies .map((v) => PickerItem(v, text: v)) .toList(), - onChange: (String? value) { + onChange: (value) { codeProvider.setFontFamily(value!); }, ), diff --git a/lib/screens/ge_pull.dart b/lib/screens/ge_pull.dart index 6afaa50..89bca84 100644 --- a/lib/screens/ge_pull.dart +++ b/lib/screens/ge_pull.dart @@ -83,7 +83,7 @@ class GePullScreen extends StatelessWidget { final theme = context.read(); var additions = 0; var deletions = 0; - for (var file in files) { + for (final file in files) { additions += int.parse(file.additions!); deletions += int.parse(file.deletions!); } diff --git a/lib/screens/ge_repo.dart b/lib/screens/ge_repo.dart index 220474e..59cbae7 100644 --- a/lib/screens/ge_repo.dart +++ b/lib/screens/ge_repo.dart @@ -58,14 +58,14 @@ class GeRepoScreen extends StatelessWidget { await auth.fetchGitee('/repos/$owner/$name/branches').then((v) { return [for (var branch in v) GiteeBranch.fromJson(branch)]; }); - bool isStarred = await auth + final isStarred = await auth .fetchGitee('/user/starred/$owner/$name', requestType: 'NO CONTENT') .then((v) => v.statusCode == HttpStatus.noContent); - bool isWatching = await auth + final isWatching = await auth .fetchGitee('/user/subscriptions/$owner/$name', requestType: 'NO CONTENT') .then((v) => v.statusCode == HttpStatus.noContent); - StatusPayload statusPayload = StatusPayload(isWatching, isStarred); + final statusPayload = StatusPayload(isWatching, isStarred); return Tuple4(repo, readmeData, branches, statusPayload); }, bodyBuilder: (t, setData) { @@ -88,7 +88,7 @@ class GeRepoScreen extends StatelessWidget { active: t.item4.isWatching, text: t.item4.isWatching ? 'Ignore' : 'Watch', onTap: () async { - final String watchType = + final watchType = t.item4.isWatching ? 'ignoring' : 'watching'; await context.read().fetchGitee( '/user/subscriptions/$owner/$name?watch_type=$watchType', diff --git a/lib/screens/ge_search.dart b/lib/screens/ge_search.dart index fd773ea..b9117a1 100644 --- a/lib/screens/ge_search.dart +++ b/lib/screens/ge_search.dart @@ -41,7 +41,7 @@ class _GeSearchScreenState extends State { Future _query() async { if (_loading || _keyword.isEmpty) return; - var keyword = _controller!.text; + final keyword = _controller!.text; setState(() { _loading = true; }); diff --git a/lib/screens/gh_contributors.dart b/lib/screens/gh_contributors.dart index 7e64a2f..b9d899d 100644 --- a/lib/screens/gh_contributors.dart +++ b/lib/screens/gh_contributors.dart @@ -34,7 +34,7 @@ class GhContributorsScreen extends StatelessWidget { ); }, itemBuilder: (v) { - final String? login = v.login; + final login = v.login; return ContributorItem( avatarUrl: v.avatarUrl, commits: v.contributions, diff --git a/lib/screens/gh_issue.dart b/lib/screens/gh_issue.dart index 6c08eb9..9d080e3 100644 --- a/lib/screens/gh_issue.dart +++ b/lib/screens/gh_issue.dart @@ -95,7 +95,7 @@ class GhIssueScreen extends StatelessWidget { b.vars.number = number; b.vars.cursor = cursor; }); - OperationResponse res = + final OperationResponse res = await context.read().gqlClient.request(req).first; return res.data!.repository!; } diff --git a/lib/screens/gh_news.dart b/lib/screens/gh_news.dart index 86b069c..791b1fe 100644 --- a/lib/screens/gh_news.dart +++ b/lib/screens/gh_news.dart @@ -21,7 +21,7 @@ class GhNewsScreenState extends State { Future.microtask(() async { // Check if there are unread notification items. // 1 item is enough since count is not displayed for now. - var items = await context + final items = await context .read() .ghClient .getJSON('/notifications?per_page=1'); diff --git a/lib/screens/gh_notification.dart b/lib/screens/gh_notification.dart index 6567949..a006471 100644 --- a/lib/screens/gh_notification.dart +++ b/lib/screens/gh_notification.dart @@ -31,9 +31,9 @@ class GhNotificationScreenState extends State { context.read().setCount(ns.length); } - Map groupMap = {}; + final groupMap = {}; - for (var item in ns) { + for (final item in ns) { final repo = item.repository!.fullName ?? ''; // TODO: nullable if (groupMap[repo] == null) { groupMap[repo] = NotificationGroup(repo); @@ -57,7 +57,7 @@ class GhNotificationScreenState extends State { schema += '${group.key}: repository(owner: "${group.owner}", name: "${group.name}") {'; - for (var item in group.items) { + for (final item in group.items) { switch (item.subject!.type) { case 'Issue': schema += ''' @@ -83,13 +83,13 @@ ${item.key}: pullRequest(number: ${item.subject!.number}) { if (schema == '{}') return groupMap; // Fimber.d(schema); - var data = await context.read().query(schema); + final data = await context.read().query(schema); groupMap.forEach((repo, group) { - for (var item in group.items) { - var groupData = data[group.key]; + for (final item in group.items) { + final groupData = data[group.key]; if (groupData == null) continue; - var itemData = data[group.key][item.key]; + final itemData = data[group.key][item.key]; if (itemData != null) { item.state = itemData['state']; } diff --git a/lib/screens/gh_search.dart b/lib/screens/gh_search.dart index c84c66f..710eed0 100644 --- a/lib/screens/gh_search.dart +++ b/lib/screens/gh_search.dart @@ -41,7 +41,7 @@ class _GhSearchScreenState extends State { Future _query() async { if (_loading || _keyword.isEmpty) return; - var keyword = _controller!.text; + final keyword = _controller!.text; setState(() { _loading = true; }); diff --git a/lib/screens/gl_search.dart b/lib/screens/gl_search.dart index 4e9bdff..559ccfb 100644 --- a/lib/screens/gl_search.dart +++ b/lib/screens/gl_search.dart @@ -42,7 +42,7 @@ class _GlSearchScreenState extends State { Future _query() async { if (_loading || _keyword.isEmpty) return; - var keyword = _controller!.text; + final keyword = _controller!.text; setState(() { _loading = true; }); diff --git a/lib/screens/go_repo.dart b/lib/screens/go_repo.dart index a92e555..c416a4c 100644 --- a/lib/screens/go_repo.dart +++ b/lib/screens/go_repo.dart @@ -47,12 +47,11 @@ class GoRepoScreen extends StatelessWidget { return utf8.decode(res.bodyBytes).normalizedHtml; }); final readmeData = MarkdownViewData(context, md: md, html: html); - List branches = + final branches = await auth.fetchGogs('/repos/$owner/$name/branches').then((v) { - if (v is! List) { - return []; - } // Valid API Response only returned if repo contains >= 2 branches - return [for (var branch in v) GogsBranch.fromJson(branch)]; + return [ + for (var branch in (v is List ? v : [])) GogsBranch.fromJson(branch) + ]; // Valid API Response only returned if repo contains >= 2 branches }); return Tuple3(repo, readmeData, branches); diff --git a/lib/screens/gt_user.dart b/lib/screens/gt_user.dart index 3d06855..070592d 100644 --- a/lib/screens/gt_user.dart +++ b/lib/screens/gt_user.dart @@ -32,7 +32,7 @@ class GtUserScreen extends StatelessWidget { final heatmapItems = [ for (final v in userHeatmap) GiteaHeatmapItem.fromJson(v) ]; - List> heatmapWeeks = [[]]; + final heatmapWeeks = >[[]]; for (var i = 0; i < heatmapItems.length; i++) { if (i > 0 && heatmapItems[i].timestamp! - heatmapItems[i - 1].timestamp! > 86400) { diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 2788743..de834ff 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -48,10 +48,10 @@ class CommonStyle { } Color getFontColorByBrightness(Color color) { - var grayscale = color.red * 0.3 + color.green * 0.59 + color.blue * 0.11; + final grayscale = color.red * 0.3 + color.green * 0.59 + color.blue * 0.11; // Fimber.d('color: $color, $grayscale'); - var showWhite = grayscale < 128; + final showWhite = grayscale < 128; return showWhite ? AntTheme.white : AntTheme.text; } @@ -90,12 +90,12 @@ class GithubPalette { const PAGE_SIZE = 30; var createWarning = - (String text) => Text(text, style: const TextStyle(color: AntTheme.danger)); + (text) => Text(text, style: const TextStyle(color: AntTheme.danger)); var warningSpan = const TextSpan(text: 'xxx', style: TextStyle(color: AntTheme.danger)); List join(T seperator, List xs) { - List result = []; + final result = []; xs.asMap().forEach((index, x) { if (x == null) return; @@ -109,7 +109,7 @@ List join(T seperator, List xs) { } List joinAll(T seperator, List> xss) { - List result = []; + final result = []; xss.asMap().forEach((index, x) { if (x.isEmpty) return; diff --git a/lib/widgets/contribution.dart b/lib/widgets/contribution.dart index 7470a3c..01a4164 100644 --- a/lib/widgets/contribution.dart +++ b/lib/widgets/contribution.dart @@ -33,12 +33,12 @@ class ContributionWidget extends StatelessWidget { ContributionWidget({required this.weeks}) { int? maxCount; - for (var week in weeks!) { - for (var day in week) { + for (final week in weeks!) { + for (final day in week) { if (day.count != null) { if (maxCount == null) { - for (var week in weeks!) { - for (var day in week) { + for (final week in weeks!) { + for (final day in week) { maxCount = max(day.count!, maxCount ?? 0); } } diff --git a/lib/widgets/event_item.dart b/lib/widgets/event_item.dart index ea780a9..5efb0fd 100644 --- a/lib/widgets/event_item.dart +++ b/lib/widgets/event_item.dart @@ -308,7 +308,7 @@ class EventItem extends StatelessWidget { ]); case 'CheckSuiteEvent': // Needs checks permission - String conclusion = ''; + var conclusion = ''; switch (e.payload!.checkSuite!.conclusion) { case 'success': case 'failure': @@ -387,9 +387,9 @@ class EventItem extends StatelessWidget { ], ); case 'GollumEvent': - String pageNamesCreated = ''; - String pageNamesEdited = ''; - for (GithubPagesItem page in e.payload!.pages!) { + var pageNamesCreated = ''; + var pageNamesEdited = ''; + for (final page in e.payload!.pages!) { if (page.action == 'edited') { pageNamesEdited += ', ${page.pageName!}'; } else { @@ -409,7 +409,7 @@ class EventItem extends StatelessWidget { context: context, spans: [TextSpan(text: ' $pageNamesCreated\n$pageNamesEdited ')]); case 'InstallationEvent': - String? action = e.payload!.action; + var action = e.payload!.action; if (action == 'new_permissions_accepted') { action = AppLocalizations.of(context)!.newPermissionsAccepted; } @@ -422,19 +422,19 @@ class EventItem extends StatelessWidget { ], ); case 'InstallationRepositoriesEvent': - List repositoriesAdded = + final repositoriesAdded = e.payload!.installation!.repositoriesAdded!; - List repositoriesRemoved = + final repositoriesRemoved = e.payload!.installation!.repositoriesRemoved!; - String addedRepos = ''; - String removedRepos = ''; - for (GithubNotificationItemRepo repo in repositoriesAdded) { + var addedRepos = ''; + var removedRepos = ''; + for (final repo in repositoriesAdded) { addedRepos += '${repo.fullName!}, '; } - for (GithubNotificationItemRepo repo in repositoriesRemoved) { + for (final repo in repositoriesRemoved) { removedRepos += '${repo.fullName!}, '; } - String finalListOfRepos = ''; + var finalListOfRepos = ''; if (addedRepos != '') { finalListOfRepos += '${AppLocalizations.of(context)!.wereAddedTo(addedRepos, e.payload!.installation!.id.toString())}\n '; @@ -531,7 +531,7 @@ class EventItem extends StatelessWidget { ], ); case 'ProjectCardEvent': - String? action = e.payload!.action; + var action = e.payload!.action; if (action == 'converted') { action = ' ${AppLocalizations.of(context)!.convertProjectCard} '; } else { diff --git a/lib/widgets/markdown_view.dart b/lib/widgets/markdown_view.dart index 8f28332..ca4aa37 100644 --- a/lib/widgets/markdown_view.dart +++ b/lib/widgets/markdown_view.dart @@ -92,7 +92,7 @@ class MarkdownFlutterView extends StatelessWidget { final EdgeInsetsGeometry padding; static Map? matchPattern(String url, String pattern) { - var uri = Uri.parse(url); + final uri = Uri.parse(url); return UriParser(UriTemplate(pattern)).match(uri)?.parameters; } @@ -145,7 +145,7 @@ class MarkdownFlutterView extends StatelessWidget { '/{owner}/{name}', '/{login}' ]; - for (var p in matchedPaths) { + for (final p in matchedPaths) { final m = matchPattern(url, p); if (m != null) { context.pushUrl( diff --git a/lib/widgets/text_with_at.dart b/lib/widgets/text_with_at.dart index d001b8b..8608c66 100644 --- a/lib/widgets/text_with_at.dart +++ b/lib/widgets/text_with_at.dart @@ -21,8 +21,8 @@ class TextWithAt extends StatelessWidget { final matches = _reg.allMatches(text).map((m) => m.group(0)).toList(); final chunks = text.split(_reg); - List spans = []; - for (var index in List.generate(matches.length, (i) => (i))) { + final spans = []; + for (final index in List.generate(matches.length, (i) => (i))) { if (chunks[index].isNotEmpty) { spans.add(TextSpan(text: chunks[index])); }