diff --git a/analysis_options.yaml b/analysis_options.yaml
index ebdc9e8e6..b95c4a07a 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -22,7 +22,6 @@ linter:
   # `// ignore_for_file: name_of_lint` syntax on the line or in the file
   # producing the lint.
   rules:
-    avoid_function_literals_in_foreach_calls: false # TODO(ykh09242): Enable this lint.
     avoid_print: false
     use_build_context_synchronously: false # TODO(ykh09242): Enable this lint.
 
diff --git a/lib/cert/root.dart b/lib/cert/root.dart
index 1651c2c27..dee38ebee 100644
--- a/lib/cert/root.dart
+++ b/lib/cert/root.dart
@@ -8,7 +8,7 @@ import 'package:violet/cert/cert_data.dart';
 import 'package:violet/cert/cert_util.dart';
 
 class RootCert extends CertData {
-  RootCert({required Map<String, dynamic> data}) : super(data: data);
+  RootCert({required super.data});
 
   RSAPublicKey rsaPublic() => CertUtil.importRSAPublicKey(data['PubKey']);
 
diff --git a/lib/component/eh/eh_bookmark.dart b/lib/component/eh/eh_bookmark.dart
index b89d95e43..9a14790be 100644
--- a/lib/component/eh/eh_bookmark.dart
+++ b/lib/component/eh/eh_bookmark.dart
@@ -23,9 +23,9 @@ class EHBookmark {
               'https://exhentai.org/favorites.php?page=$j&favcat=$i');
           var matched = rr.allMatches(html).map((e) => e.group(0));
           if (matched.isEmpty) break;
-          matched.forEach((element) {
+          for (var element in matched) {
             hh.add(int.parse(element!.split('/')[4]));
-          });
+          }
         }
       } catch (_) {}
       result.add(hh);
@@ -39,9 +39,9 @@ class EHBookmark {
               'https://e-hentai.org/favorites.php?page=$j&favcat=$i');
           var matched = r2.allMatches(html).map((e) => e.group(0));
           if (matched.isEmpty) break;
-          matched.forEach((element) {
+          for (var element in matched) {
             result[i].add(int.parse(element!.split('/')[4]));
-          });
+          }
         }
       } catch (_) {}
     }
diff --git a/lib/component/eh/eh_parser.dart b/lib/component/eh/eh_parser.dart
index 9a19a956a..3378c8e90 100644
--- a/lib/component/eh/eh_parser.dart
+++ b/lib/component/eh/eh_parser.dart
@@ -135,7 +135,7 @@ class EHParser {
         doc.querySelectorAll("div[id='gmid'] div[id='taglist'] table tr");
     var info = <String, List<String>>{};
 
-    nodesData.forEach((element) {
+    for (var element in nodesData) {
       try {
         info[element.querySelector('td')!.text.trim()] = element
             .querySelectorAll('td')[1]
@@ -146,7 +146,7 @@ class EHParser {
         Logger.error('[eh-parser] E: $e\n'
             '$st');
       }
-    });
+    }
 
     if (info.containsKey('language:')) article.languages = info['language:'];
     if (info.containsKey('group:')) article.group = info['group:'];
@@ -162,7 +162,7 @@ class EHParser {
 
     var hu = HtmlUnescape();
     var df = DateFormat('dd MMMM yyyy, H:m');
-    nodeComments.forEach((element) {
+    for (var element in nodeComments) {
       var date =
           hu.convert(element.querySelector('div.c2 div.c3')!.text.trim());
       var author =
@@ -179,7 +179,7 @@ class EHParser {
               true),
           author,
           contents));
-    });
+    }
 
     comments.sort((x, y) => x.item1.compareTo(y.item1));
     article.comment = comments;
@@ -193,7 +193,7 @@ class EHParser {
 
     var nodes = parse(html).querySelectorAll('div.itg > div.id1');
 
-    nodes.forEach((element) {
+    for (var element in nodes) {
       try {
         var article = EHResultArticle();
 
@@ -210,7 +210,7 @@ class EHParser {
 
         result.add(article);
       } catch (_) {}
-    });
+    }
 
     return result;
   }
@@ -223,7 +223,7 @@ class EHParser {
 
     if (nodes.length > 1) nodes.removeAt(0);
 
-    nodes.forEach((element) {
+    for (var element in nodes) {
       try {
         var article = EHResultArticle();
         var tds = element.querySelectorAll('td');
@@ -242,7 +242,7 @@ class EHParser {
 
         result.add(article);
       } catch (_) {}
-    });
+    }
 
     return result;
   }
@@ -325,7 +325,7 @@ class EHParser {
 
     if (nodes.length > 1) nodes.removeAt(0);
 
-    nodes.forEach((element) {
+    for (var element in nodes) {
       var article = EHResultArticle();
 
       article.type =
@@ -365,7 +365,7 @@ class EHParser {
           element.querySelectorAll('td')[5].querySelector('div a')!.text.trim();
 
       result.add(article);
-    });
+    }
 
     return result;
   }
diff --git a/lib/component/hitomi/indexs.dart b/lib/component/hitomi/indexs.dart
index e54261a5a..03a529547 100644
--- a/lib/component/hitomi/indexs.dart
+++ b/lib/component/hitomi/indexs.dart
@@ -76,10 +76,10 @@ class HitomiIndexs {
             'assets/locale/tag/related-tag-${TagTranslate.defaultLanguage}.json'))
         as List<dynamic>;
     relatedTag = <String, dynamic>{};
-    relatedData.forEach((element) {
+    for (var element in relatedData) {
       var kv = (element as Map<String, dynamic>).entries.first;
       relatedTag[kv.key] = kv.value;
-    });
+    }
   }
 
   static List<Tuple2<String, double>> _calculateSimilars(
diff --git a/lib/component/hitomi/series_finder.dart b/lib/component/hitomi/series_finder.dart
index db1e32faa..aa6e7165b 100644
--- a/lib/component/hitomi/series_finder.dart
+++ b/lib/component/hitomi/series_finder.dart
@@ -71,9 +71,9 @@ class SeriesFinder {
     }
 
     seriesList.sort((x, y) => x.length.compareTo(y.length));
-    seriesList.forEach((element) {
+    for (var element in seriesList) {
       print('[${element.length}] ${element.first.artists()}');
-    });
+    }
   }
 
   static Future<void> doFind2() async {
@@ -150,8 +150,8 @@ class SeriesFinder {
     }
 
     seriesList.sort((x, y) => x.item2.length.compareTo(y.item2.length));
-    seriesList.forEach((element) {
+    for (var element in seriesList) {
       print('[${element.item2.length}] ${element.item1}');
-    });
+    }
   }
 }
diff --git a/lib/component/hitomi/tag_translate.dart b/lib/component/hitomi/tag_translate.dart
index 710bec401..50052b4fb 100644
--- a/lib/component/hitomi/tag_translate.dart
+++ b/lib/component/hitomi/tag_translate.dart
@@ -123,11 +123,11 @@ class TagTranslate {
     var result = contains(part) + containsAndro(part);
     var overlap = <String>{};
     var rresult = <DisplayedTag>[];
-    result.forEach((element) {
-      if (overlap.contains(element.getTag())) return;
+    for (var element in result) {
+      if (overlap.contains(element.getTag())) continue;
       overlap.add(element.getTag());
       rresult.add(element);
-    });
+    }
     return rresult;
   }
 
@@ -167,11 +167,11 @@ class TagTranslate {
     result.sort((x, y) => x.item2.compareTo(y.item2));
     var overlap = <String>{};
     var rresult = <Tuple2<DisplayedTag, int>>[];
-    result.forEach((element) {
-      if (overlap.contains(element.item1.getTag())) return;
+    for (var element in result) {
+      if (overlap.contains(element.item1.getTag())) continue;
       overlap.add(element.item1.getTag());
       rresult.add(element);
-    });
+    }
     return rresult;
   }
 
diff --git a/lib/component/hitomi/title_cluster.dart b/lib/component/hitomi/title_cluster.dart
index 150e8cc49..0cad75569 100644
--- a/lib/component/hitomi/title_cluster.dart
+++ b/lib/component/hitomi/title_cluster.dart
@@ -64,17 +64,17 @@ class HitomiTitleCluster {
     if (maxnode > 100) maxnode = 100;
 
     var groups = <List<int>>[];
-    ctitles.forEach((element) {
+    for (var element in ctitles) {
       var near = tree.nearest(element, maxnode, 8);
 
       var rr = <int>[];
-      near.forEach((element) {
+      for (var element in near) {
         rr.add(element[0]['t'].index);
-      });
+      }
 
       rr.sort();
       groups.add(rr);
-    });
+    }
 
     // Group By Same Lists
     var gg = groupBy(groups, (group) => group.join(','));
@@ -82,10 +82,10 @@ class HitomiTitleCluster {
 
     // Join groups
     gg.forEach((key, value) {
-      value[0].forEach((element) {
-        if (value[0][0] == element) return;
+      for (var element in value[0]) {
+        if (value[0][0] == element) continue;
         ds.union(value[0][0], element);
-      });
+      }
     });
 
     var join = <int, List<int>>{};
diff --git a/lib/database/query.dart b/lib/database/query.dart
index 10454d874..83b41111f 100644
--- a/lib/database/query.dart
+++ b/lib/database/query.dart
@@ -87,9 +87,9 @@ class QueryManager {
         queryRaw + (!Settings.searchPure ? ' AND ExistOnHitomi=1' : ''));
 
     var qr = <String, QueryResult>{};
-    qm.results!.forEach((element) {
+    for (var element in qm.results!) {
       qr[element.id().toString()] = element;
-    });
+    }
 
     var rr = ids
         .where((e) => qr.containsKey(e.toString()))
diff --git a/lib/database/user/bookmark.dart b/lib/database/user/bookmark.dart
index e8def9be3..67828b645 100644
--- a/lib/database/user/bookmark.dart
+++ b/lib/database/user/bookmark.dart
@@ -290,9 +290,9 @@ class Bookmark {
       groups[y] = tmp;
     }
 
-    groups.forEach((element) {
+    for (var element in groups) {
       print(element.gorder());
-    });
+    }
 
     if (from < to) {
       for (; from < to; from++) {
@@ -306,9 +306,9 @@ class Bookmark {
       }
     }
 
-    groups.forEach((element) {
+    for (var element in groups) {
       print(element.gorder());
-    });
+    }
   }
 
   Future<List<BookmarkArticle>> getArticle() async {
@@ -354,9 +354,9 @@ class Bookmark {
     if (bookmarkSet == null) {
       var article = await getArticle();
       bookmarkSet = HashSet<int>();
-      article.forEach((element) {
+      for (var element in article) {
         bookmarkSet!.add(int.parse(element.article()));
-      });
+      }
     }
 
     return bookmarkSet!.contains(id);
@@ -385,9 +385,9 @@ class Bookmark {
       bookmarkArtistSet![2] = HashSet<String>();
       bookmarkArtistSet![3] = HashSet<String>();
       bookmarkArtistSet![4] = HashSet<String>();
-      artist.forEach((element) {
+      for (var element in artist) {
         bookmarkArtistSet![element.type()]!.add(element.artist());
-      });
+      }
     }
 
     return bookmarkArtistSet![type]!.contains(name);
@@ -398,9 +398,9 @@ class Bookmark {
     if (bookmarkUserSet == null) {
       var user = await getUser();
       bookmarkUserSet = HashSet<String>();
-      user.forEach((element) {
+      for (var element in user) {
         bookmarkUserSet!.add(element.user());
-      });
+      }
     }
 
     return bookmarkUserSet!.contains(user);
@@ -411,9 +411,9 @@ class Bookmark {
     if (historyUserSet == null) {
       var user = await getHistoryUser();
       historyUserSet = HashSet<String>();
-      user.forEach((element) {
+      for (var element in user) {
         historyUserSet!.add(element.user());
-      });
+      }
     }
 
     return historyUserSet!.contains(user);
diff --git a/lib/downloader/isolate/core.dart b/lib/downloader/isolate/core.dart
index 17a21bbb2..d8adcfa93 100644
--- a/lib/downloader/isolate/core.dart
+++ b/lib/downloader/isolate/core.dart
@@ -55,9 +55,9 @@ class IsolateDownloaderTask {
     if (task.accept != null) header['accept'] = task.accept!;
     if (task.userAgent != null) header['user-agent'] = task.userAgent!;
     if (task.headers != null) {
-      task.headers!.entries.forEach((element) {
+      for (var element in task.headers!.entries) {
         header[element.key.toLowerCase()] = element.value;
-      });
+      }
     }
     return IsolateDownloaderTask(
       id: taskId,
@@ -282,7 +282,9 @@ void _cancelTask(int taskId) {
 /// cancel all tasks and remove dqueue
 void _terminate() {
   _dqueue.clear();
-  _workingMap.entries.forEach((element) => element.value.cancelToken!.cancel());
+  for (var value in _workingMap.values) {
+    value.cancelToken!.cancel();
+  }
 }
 
 void _modifyTaskPoolSize(int sz) {
diff --git a/lib/log/log.dart b/lib/log/log.dart
index af1a2fb15..d5bb7a2dd 100644
--- a/lib/log/log.dart
+++ b/lib/log/log.dart
@@ -103,9 +103,9 @@ class Logger {
   }
 
   static Future<void> showLogs() async {
-    (await logFile.readAsLines()).forEach((element) {
+    for (var element in (await logFile.readAsLines())) {
       print(element);
-    });
+    }
   }
 
   static Future<void> exportLog() async {
diff --git a/lib/main.dart b/lib/main.dart
index 0aa01d9d1..c3cbd6eea 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -86,7 +86,7 @@ Future<void> initFirebase() async {
 }
 
 class MyApp extends StatelessWidget {
-  const MyApp({Key? key}) : super(key: key);
+  const MyApp({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/after_loading/afterloading_page.dart b/lib/pages/after_loading/afterloading_page.dart
index e1cfc0f7c..9b1d8021d 100644
--- a/lib/pages/after_loading/afterloading_page.dart
+++ b/lib/pages/after_loading/afterloading_page.dart
@@ -28,7 +28,7 @@ import 'package:violet/version/update_sync.dart';
 import 'package:violet/widgets/toast.dart';
 
 class AfterLoadingPage extends StatefulWidget {
-  const AfterLoadingPage({Key? key}) : super(key: key);
+  const AfterLoadingPage({super.key});
 
   @override
   State<AfterLoadingPage> createState() => AfterLoadingPageState();
diff --git a/lib/pages/article_info/article_info_page.dart b/lib/pages/article_info/article_info_page.dart
index 3a39d85f0..796811078 100644
--- a/lib/pages/article_info/article_info_page.dart
+++ b/lib/pages/article_info/article_info_page.dart
@@ -52,8 +52,8 @@ import 'package:violet/widgets/toast.dart';
 
 class ArticleInfoPage extends StatelessWidget {
   const ArticleInfoPage({
-    Key? key,
-  }) : super(key: key);
+    super.key,
+  });
 
   @override
   Widget build(BuildContext context) {
@@ -339,7 +339,7 @@ class ArticleInfoPage extends StatelessWidget {
 }
 
 class DividerWidget extends StatelessWidget {
-  const DividerWidget({Key? key}) : super(key: key);
+  const DividerWidget({super.key});
 
   @override
   Widget build(BuildContext context) {
@@ -357,8 +357,7 @@ class DividerWidget extends StatelessWidget {
 class TagInfoAreaWidget extends StatelessWidget {
   final QueryResult queryResult;
 
-  const TagInfoAreaWidget({Key? key, required this.queryResult})
-      : super(key: key);
+  const TagInfoAreaWidget({super.key, required this.queryResult});
 
   @override
   Widget build(BuildContext context) {
@@ -464,8 +463,7 @@ class SingleChipWidget extends StatelessWidget {
   final String name;
   final String raw;
 
-  const SingleChipWidget(this.target, this.name, this.raw, {Key? key})
-      : super(key: key);
+  const SingleChipWidget(this.target, this.name, this.raw, {super.key});
 
   @override
   Widget build(BuildContext context) {
@@ -490,8 +488,7 @@ class MultiChipWidget extends StatelessWidget {
   final String name;
   final String? target;
 
-  const MultiChipWidget(this.target, this.name, this.groupName, {Key? key})
-      : super(key: key);
+  const MultiChipWidget(this.target, this.name, this.groupName, {super.key});
 
   @override
   Widget build(BuildContext context) {
@@ -523,8 +520,7 @@ class MultiChipWidget extends StatelessWidget {
 class PreviewAreaWidget extends StatelessWidget {
   final QueryResult queryResult;
 
-  const PreviewAreaWidget({Key? key, required this.queryResult})
-      : super(key: key);
+  const PreviewAreaWidget({super.key, required this.queryResult});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/article_info/simple_info.dart b/lib/pages/article_info/simple_info.dart
index 68645615a..8893783b5 100644
--- a/lib/pages/article_info/simple_info.dart
+++ b/lib/pages/article_info/simple_info.dart
@@ -16,7 +16,7 @@ class SimpleInfoWidget extends StatelessWidget {
   final FlareControls _flareController = FlareControls();
   static final DateFormat _dateFormat = DateFormat(' yyyy/MM/dd HH:mm');
 
-  SimpleInfoWidget({Key? key}) : super(key: key);
+  SimpleInfoWidget({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/artist_info/article_list_page.dart b/lib/pages/artist_info/article_list_page.dart
index a164787ea..53b987a37 100644
--- a/lib/pages/artist_info/article_list_page.dart
+++ b/lib/pages/artist_info/article_list_page.dart
@@ -21,8 +21,7 @@ class ArticleListPage extends StatefulWidget {
   final List<QueryResult> cc;
   final String name;
 
-  const ArticleListPage({Key? key, required this.name, required this.cc})
-      : super(key: key);
+  const ArticleListPage({super.key, required this.name, required this.cc});
 
   @override
   State<ArticleListPage> createState() => _ArticleListPageState();
@@ -187,7 +186,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
   void _applyFilter() {
     var result = <QueryResult>[];
     var isOr = _filterController.isOr;
-    widget.cc.forEach((element) {
+    for (var element in widget.cc) {
       // key := <group>:<name>
       var succ = !_filterController.isOr;
       _filterController.tagStates.forEach((key, value) {
@@ -223,7 +222,7 @@ class _ArticleListPageState extends State<ArticleListPage> {
         }
       });
       if (succ) result.add(element);
-    });
+    }
 
     filterResult = result;
     isFilterUsed = true;
diff --git a/lib/pages/artist_info/artist_info_page.dart b/lib/pages/artist_info/artist_info_page.dart
index ce92e8b09..954d60cb4 100644
--- a/lib/pages/artist_info/artist_info_page.dart
+++ b/lib/pages/artist_info/artist_info_page.dart
@@ -44,13 +44,13 @@ class ArtistInfoPage extends StatefulWidget {
   final bool isCharacter;
 
   const ArtistInfoPage({
-    Key? key,
+    super.key,
     required this.artist,
     this.isGroup = false,
     this.isUploader = false,
     this.isSeries = false,
     this.isCharacter = false,
-  }) : super(key: key);
+  });
 
   @override
   State<ArtistInfoPage> createState() => _ArtistInfoPageState();
@@ -135,8 +135,8 @@ class _ArtistInfoPageState extends State<ArtistInfoPage> {
       //
       var ffstat = <String, int>{};
 
-      cc.forEach((element) {
-        if (element.tags() == null) return;
+      for (var element in cc) {
+        if (element.tags() == null) continue;
         (element.tags() as String)
             .split('|')
             .where((element) => element != '')
@@ -152,7 +152,7 @@ class _ArtistInfoPageState extends State<ArtistInfoPage> {
           if (!ffstat.containsKey(element)) ffstat[element] = 0;
           ffstat[element] = ffstat[element]! + 1;
         });
-      });
+      }
 
       ffstat.forEach((key, value) {
         lff.add(Tuple2<String, int>(key, value));
diff --git a/lib/pages/artist_info/search_type2.dart b/lib/pages/artist_info/search_type2.dart
index 71a275ebf..698e042df 100644
--- a/lib/pages/artist_info/search_type2.dart
+++ b/lib/pages/artist_info/search_type2.dart
@@ -19,7 +19,7 @@ class SearchType2 extends StatelessWidget {
   }
 
   final int nowType;
-  const SearchType2({Key? key, required this.nowType}) : super(key: key);
+  const SearchType2({super.key, required this.nowType});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/artist_info/series_list_page.dart b/lib/pages/artist_info/series_list_page.dart
index 853c653d5..ea901db94 100644
--- a/lib/pages/artist_info/series_list_page.dart
+++ b/lib/pages/artist_info/series_list_page.dart
@@ -16,11 +16,11 @@ class SeriesListPage extends StatelessWidget {
   final List<QueryResult> cc;
 
   const SeriesListPage({
-    Key? key,
+    super.key,
     required this.prefix,
     required this.series,
     required this.cc,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/artist_info/similar_list_page.dart b/lib/pages/artist_info/similar_list_page.dart
index db3b9160e..e6760330a 100644
--- a/lib/pages/artist_info/similar_list_page.dart
+++ b/lib/pages/artist_info/similar_list_page.dart
@@ -23,14 +23,14 @@ class SimilarListPage extends StatelessWidget {
   final List<Tuple2<String, double>> similarsAll;
 
   const SimilarListPage({
-    Key? key,
+    super.key,
     required this.prefix,
     required this.similarsAll,
     required this.isGroup,
     required this.isUploader,
     required this.isSeries,
     required this.isCharacter,
-  }) : super(key: key);
+  });
 
   Future<List<QueryResult>> _future(String e) async {
     var unescape = HtmlUnescape();
diff --git a/lib/pages/bookmark/bookmark_page.dart b/lib/pages/bookmark/bookmark_page.dart
index fe615f8b9..8f240ed37 100644
--- a/lib/pages/bookmark/bookmark_page.dart
+++ b/lib/pages/bookmark/bookmark_page.dart
@@ -22,7 +22,7 @@ import 'package:violet/widgets/theme_switchable_state.dart';
 import 'package:violet/widgets/toast.dart';
 
 class BookmarkPage extends StatefulWidget {
-  const BookmarkPage({Key? key}) : super(key: key);
+  const BookmarkPage({super.key});
 
   @override
   State<BookmarkPage> createState() => _BookmarkPageState();
diff --git a/lib/pages/bookmark/group/group_article_list_page.dart b/lib/pages/bookmark/group/group_article_list_page.dart
index c5354304b..91ed0ea61 100644
--- a/lib/pages/bookmark/group/group_article_list_page.dart
+++ b/lib/pages/bookmark/group/group_article_list_page.dart
@@ -35,10 +35,10 @@ class GroupArticleListPage extends StatefulWidget {
   final int groupId;
 
   const GroupArticleListPage({
-    Key? key,
+    super.key,
     required this.name,
     required this.groupId,
-  }) : super(key: key);
+  });
 
   @override
   State<GroupArticleListPage> createState() => _GroupArticleListPageState();
@@ -97,42 +97,47 @@ class _GroupArticleListPageState extends State<GroupArticleListPage> {
     nowType = prefs.getInt('bookmark_${widget.groupId}') ?? 3;
   }
 
-  void refresh() {
+  Future<void> _refreshAsync() async {
     _loadBookmarkAlignType();
-    Bookmark.getInstance().then((value) =>
-        value.getArticle().then((value) async {
-          var cc = value
-              .where((e) => e.group() == widget.groupId)
-              .toList()
-              .reversed
-              .toList();
-
-          if (cc.isEmpty) {
-            queryResult = <QueryResult>[];
-            filterResult = queryResult;
-            _rebuild();
-            return;
-          }
-
-          QueryManager.queryIds(cc.map((e) => int.parse(e.article())).toList())
-              .then((value) async {
-            var qr = <String, QueryResult>{};
-            value.forEach((element) {
-              qr[element.id().toString()] = element;
-            });
 
-            var result = <QueryResult>[];
-            cc.forEach((element) async {
-              var article = qr[element.article()];
-              article ??= await _tryGetArticleFromHitomi(element.article());
-              result.add(article);
-            });
+    final bookmark = await Bookmark.getInstance();
+    final articles = await bookmark.getArticle();
 
-            queryResult = result;
-            _applyFilter();
-            _rebuild();
-          });
-        }));
+    var cc = articles
+        .where((e) => e.group() == widget.groupId)
+        .toList()
+        .reversed
+        .toList();
+
+    if (cc.isEmpty) {
+      queryResult = <QueryResult>[];
+      filterResult = queryResult;
+      _rebuild();
+      return;
+    }
+
+    final value = await QueryManager.queryIds(
+        cc.map((e) => int.parse(e.article())).toList());
+
+    var qr = <String, QueryResult>{};
+    for (var element in value) {
+      qr[element.id().toString()] = element;
+    }
+
+    var result = <QueryResult>[];
+    for (var element in cc) {
+      var article = qr[element.article()];
+      article ??= await _tryGetArticleFromHitomi(element.article());
+      result.add(article);
+    }
+
+    queryResult = result;
+    _applyFilter();
+    _rebuild();
+  }
+
+  void refresh() {
+    _refreshAsync();
   }
 
   bool _shouldRebuild = false;
@@ -240,9 +245,9 @@ class _GroupArticleListPageState extends State<GroupArticleListPage> {
       fabButtons: <Widget>[
         FloatingActionButton(
           onPressed: () {
-            filterResult.forEach((element) {
+            for (var element in filterResult) {
               checked.add(element.id());
-            });
+            }
             _shouldRebuild = true;
             setState(() {
               _shouldRebuild = true;
@@ -261,9 +266,9 @@ class _GroupArticleListPageState extends State<GroupArticleListPage> {
                     .replaceAll('%s', checked.length.toString()),
                 Translations.of(context).trans('bookmark'))) {
               var bookmark = await Bookmark.getInstance();
-              checked.forEach((element) async {
-                bookmark.unbookmark(element);
-              });
+              for (var element in checked) {
+                await bookmark.unbookmark(element);
+              }
               checked.clear();
               refresh();
             }
diff --git a/lib/pages/bookmark/group/group_artist_article_list.dart b/lib/pages/bookmark/group/group_artist_article_list.dart
index 27d03834b..355ef52d9 100644
--- a/lib/pages/bookmark/group/group_artist_article_list.dart
+++ b/lib/pages/bookmark/group/group_artist_article_list.dart
@@ -19,10 +19,10 @@ class GroupArtistArticleList extends StatefulWidget {
   final int groupId;
 
   const GroupArtistArticleList({
-    Key? key,
+    super.key,
     required this.name,
     required this.groupId,
-  }) : super(key: key);
+  });
 
   @override
   State<GroupArtistArticleList> createState() => _GroupArtistArticleListState();
diff --git a/lib/pages/bookmark/group/group_artist_list.dart b/lib/pages/bookmark/group/group_artist_list.dart
index 5a71f1c41..00874d5f7 100644
--- a/lib/pages/bookmark/group/group_artist_list.dart
+++ b/lib/pages/bookmark/group/group_artist_list.dart
@@ -27,8 +27,7 @@ class GroupArtistList extends StatefulWidget {
   final String name;
   final int groupId;
 
-  const GroupArtistList({Key? key, required this.name, required this.groupId})
-      : super(key: key);
+  const GroupArtistList({super.key, required this.name, required this.groupId});
 
   @override
   State<GroupArtistList> createState() => _GroupArtistListState();
@@ -347,10 +346,10 @@ class _GroupArtistListState extends State<GroupArtistList>
       fabButtons: <Widget>[
         FloatingActionButton(
           onPressed: () {
-            artists.forEach((element) {
+            for (var element in artists) {
               checked
                   .add(Tuple2<int, String>(element.type(), element.artist()));
-            });
+            }
             setState(() {});
           },
           elevation: 4,
@@ -366,9 +365,9 @@ class _GroupArtistListState extends State<GroupArtistList>
                     .replaceAll('%s', checked.length.toString()),
                 Translations.of(context).trans('bookmark'))) {
               var bookmark = await Bookmark.getInstance();
-              checked.forEach((element) async {
-                bookmark.unbookmarkArtist(element.item2, element.item1);
-              });
+              for (var element in checked) {
+                await bookmark.unbookmarkArtist(element.item2, element.item1);
+              }
               checked.clear();
               refresh();
               setState(() {
diff --git a/lib/pages/bookmark/group_modify.dart b/lib/pages/bookmark/group_modify.dart
index d32c61380..b242e200d 100644
--- a/lib/pages/bookmark/group_modify.dart
+++ b/lib/pages/bookmark/group_modify.dart
@@ -11,10 +11,10 @@ class GroupModifyPage extends StatefulWidget {
   final String desc;
 
   const GroupModifyPage({
-    Key? key,
+    super.key,
     required this.name,
     required this.desc,
-  }) : super(key: key);
+  });
 
   @override
   State<GroupModifyPage> createState() => _GroupModifyPageState();
diff --git a/lib/pages/bookmark/record_view_page.dart b/lib/pages/bookmark/record_view_page.dart
index 2c908efdd..1d3d80aed 100644
--- a/lib/pages/bookmark/record_view_page.dart
+++ b/lib/pages/bookmark/record_view_page.dart
@@ -13,7 +13,7 @@ import 'package:violet/pages/segment/card_panel.dart';
 import 'package:violet/widgets/article_item/article_list_item_widget.dart';
 
 class RecordViewPage extends StatelessWidget {
-  const RecordViewPage({Key? key}) : super(key: key);
+  const RecordViewPage({super.key});
 
   @override
   Widget build(BuildContext context) {
@@ -33,11 +33,11 @@ class RecordViewPage extends StatelessWidget {
                 var overap = HashSet<String>();
                 var rr = <ArticleReadLog>[];
 
-                value.forEach((element) {
-                  if (overap.contains(element.articleId())) return;
+                for (var element in value) {
+                  if (overap.contains(element.articleId())) continue;
                   rr.add(element);
                   overap.add(element.articleId());
-                });
+                }
 
                 return await QueryManager.queryIds(
                     rr.map((e) => e.articleId()).toList());
diff --git a/lib/pages/community/community_page.dart b/lib/pages/community/community_page.dart
index 214415383..a0cbc5027 100644
--- a/lib/pages/community/community_page.dart
+++ b/lib/pages/community/community_page.dart
@@ -13,7 +13,7 @@ import 'package:violet/server/community/session.dart';
 import 'package:violet/settings/settings.dart';
 
 class CommunityPage extends StatefulWidget {
-  const CommunityPage({Key? key}) : super(key: key);
+  const CommunityPage({super.key});
 
   @override
   State<CommunityPage> createState() => _CommunityPageState();
diff --git a/lib/pages/community/signin_dialog.dart b/lib/pages/community/signin_dialog.dart
index e94f0698f..17deff61b 100644
--- a/lib/pages/community/signin_dialog.dart
+++ b/lib/pages/community/signin_dialog.dart
@@ -7,7 +7,7 @@ import 'package:violet/server/community/session.dart';
 import 'package:violet/settings/settings.dart';
 
 class SignInDialog extends StatefulWidget {
-  const SignInDialog({Key? key}) : super(key: key);
+  const SignInDialog({super.key});
 
   @override
   State<SignInDialog> createState() => _SignInDialogState();
diff --git a/lib/pages/community/signup_dialog.dart b/lib/pages/community/signup_dialog.dart
index 3cff32a15..4f40e317b 100644
--- a/lib/pages/community/signup_dialog.dart
+++ b/lib/pages/community/signup_dialog.dart
@@ -7,7 +7,7 @@ import 'package:violet/server/community/session.dart';
 import 'package:violet/settings/settings.dart';
 
 class SignUpDialog extends StatefulWidget {
-  const SignUpDialog({Key? key}) : super(key: key);
+  const SignUpDialog({super.key});
 
   @override
   State<SignUpDialog> createState() => _SignUpDialogState();
diff --git a/lib/pages/community/user_status_card.dart b/lib/pages/community/user_status_card.dart
index 709c3fe35..6a3977b6e 100644
--- a/lib/pages/community/user_status_card.dart
+++ b/lib/pages/community/user_status_card.dart
@@ -15,7 +15,7 @@ import 'package:violet/widgets/theme_switchable_state.dart';
 import 'package:violet/widgets/toast.dart';
 
 class UserStatusCard extends StatefulWidget {
-  const UserStatusCard({Key? key}) : super(key: key);
+  const UserStatusCard({super.key});
 
   @override
   State<UserStatusCard> createState() => _UserStatusCardState();
diff --git a/lib/pages/community/user_status_card_dead.dart b/lib/pages/community/user_status_card_dead.dart
index ed19cfe24..49fb68ca5 100644
--- a/lib/pages/community/user_status_card_dead.dart
+++ b/lib/pages/community/user_status_card_dead.dart
@@ -16,7 +16,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/widgets/toast.dart';
 
 class UserStatusCard extends StatefulWidget {
-  const UserStatusCard({Key? key}) : super(key: key);
+  const UserStatusCard({super.key});
 
   @override
   State<UserStatusCard> createState() => _UserStatusCardState();
diff --git a/lib/pages/database_download/database_download_page.dart b/lib/pages/database_download/database_download_page.dart
index 5b6f57be9..c4c492bb8 100644
--- a/lib/pages/database_download/database_download_page.dart
+++ b/lib/pages/database_download/database_download_page.dart
@@ -32,10 +32,10 @@ class DataBaseDownloadPage extends StatefulWidget {
   final bool isSync;
 
   const DataBaseDownloadPage({
-    Key? key,
+    super.key,
     this.dbType,
     this.isSync = false,
-  }) : super(key: key);
+  });
 
   @override
   State<DataBaseDownloadPage> createState() => DataBaseDownloadPageState();
diff --git a/lib/pages/download/download_align_type.dart b/lib/pages/download/download_align_type.dart
index 0c27ccb91..e1c6c8f8b 100644
--- a/lib/pages/download/download_align_type.dart
+++ b/lib/pages/download/download_align_type.dart
@@ -8,7 +8,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class DownloadAlignType extends StatelessWidget {
-  const DownloadAlignType({Key? key}) : super(key: key);
+  const DownloadAlignType({super.key});
 
   Color getColor(int i) {
     return Settings.themeWhat
diff --git a/lib/pages/download/download_features_menu.dart b/lib/pages/download/download_features_menu.dart
index 971496742..a741b68c9 100644
--- a/lib/pages/download/download_features_menu.dart
+++ b/lib/pages/download/download_features_menu.dart
@@ -7,7 +7,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class DownloadFeaturesMenu extends StatelessWidget {
-  const DownloadFeaturesMenu({Key? key}) : super(key: key);
+  const DownloadFeaturesMenu({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/download/download_item_menu.dart b/lib/pages/download/download_item_menu.dart
index 6fb832a75..1d5122c1a 100644
--- a/lib/pages/download/download_item_menu.dart
+++ b/lib/pages/download/download_item_menu.dart
@@ -7,7 +7,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class DownloadImageMenu extends StatelessWidget {
-  const DownloadImageMenu({Key? key}) : super(key: key);
+  const DownloadImageMenu({super.key});
 
   Color getColor(int i) {
     return Settings.themeWhat ? Colors.grey.shade200 : Colors.grey.shade900;
diff --git a/lib/pages/download/download_item_widget.dart b/lib/pages/download/download_item_widget.dart
index a439c7305..62684f931 100644
--- a/lib/pages/download/download_item_widget.dart
+++ b/lib/pages/download/download_item_widget.dart
@@ -56,13 +56,13 @@ class DownloadItemWidget extends StatefulWidget {
   final VoidCallback refeshCallback;
 
   const DownloadItemWidget({
-    Key? key,
+    super.key,
     // this.width,
     required this.item,
     required this.initialStyle,
     required this.download,
     required this.refeshCallback,
-  }) : super(key: key);
+  });
 
   @override
   State<DownloadItemWidget> createState() => DownloadItemWidgetState();
@@ -764,9 +764,9 @@ class _ThumbnailWidget extends StatelessWidget {
       Map<String, String> headers = {};
       if (thumbnailHeader != null) {
         var hh = jsonDecode(thumbnailHeader!) as Map<String, dynamic>;
-        hh.entries.forEach((element) {
+        for (var element in hh.entries) {
           headers[element.key] = element.value as String;
-        });
+        }
       }
       return Hero(
         tag: thumbnailTag!,
diff --git a/lib/pages/download/download_page.dart b/lib/pages/download/download_page.dart
index 214c2c5bf..df0984347 100644
--- a/lib/pages/download/download_page.dart
+++ b/lib/pages/download/download_page.dart
@@ -49,7 +49,7 @@ class DownloadPageManager {
 
 // This page must remain alive until the app is closed.
 class DownloadPage extends StatefulWidget {
-  const DownloadPage({Key? key}) : super(key: key);
+  const DownloadPage({super.key});
 
   @override
   State<DownloadPage> createState() => _DownloadPageState();
@@ -165,39 +165,40 @@ class _DownloadPageState extends ThemeSwitchableState<DownloadPage>
 
     var queryRaw = 'SELECT * FROM HitomiColumnModel WHERE ';
     queryRaw += 'Id IN (${articles.map((e) => e).join(',')})';
-    QueryManager.query(queryRaw).then((value) async {
-      var qr = <int, QueryResult>{};
-      value.results!.forEach((element) {
-        qr[element.id()] = element;
-      });
 
-      var result = <QueryResult>[];
-      articles.forEach((element) async {
-        if (qr[element] == null) {
-          try {
-            var headers = await ScriptManager.runHitomiGetHeaderContent(
-                element.toString());
-            var hh = await http.get(
-              'https://ltn.hitomi.la/galleryblock/$element.html',
-              headers: headers,
-            );
-            var article = await HitomiParser.parseGalleryBlock(hh.body);
-            var meta = {
-              'Id': element,
-              'Title': article['Title'],
-              'Artists': article['Artists'].join('|'),
-            };
-            result.add(QueryResult(result: meta));
-            return;
-          } catch (_) {}
-        }
+    final value = await QueryManager.query(queryRaw);
+
+    var qr = <int, QueryResult>{};
+    for (var element in value.results!) {
+      qr[element.id()] = element;
+    }
+
+    var result = <QueryResult>[];
+    for (var element in articles) {
+      if (qr[element] == null) {
+        try {
+          var headers =
+              await ScriptManager.runHitomiGetHeaderContent(element.toString());
+          var hh = await http.get(
+            'https://ltn.hitomi.la/galleryblock/$element.html',
+            headers: headers,
+          );
+          var article = await HitomiParser.parseGalleryBlock(hh.body);
+          var meta = {
+            'Id': element,
+            'Title': article['Title'],
+            'Artists': article['Artists'].join('|'),
+          };
+          result.add(QueryResult(result: meta));
+        } catch (_) {}
+      } else {
         result.add(qr[element]!);
-      });
+      }
+    }
 
-      result.forEach((element) {
-        queryResults[element.id()] = element;
-      });
-    });
+    for (var element in result) {
+      queryResults[element.id()] = element;
+    }
   }
 
   final ScrollController _scrollController = ScrollController();
@@ -696,19 +697,19 @@ class _DownloadPageState extends ThemeSwitchableState<DownloadPage>
     var downloading = <int>[];
     var result = <int>[];
     var isOr = _filterController.isOr;
-    itemsMap.entries.forEach((element) {
+    for (var element in itemsMap.entries) {
       // 1: Pending
       // 2: Extracting
       // 3: Downloading
       // 4: Post Processing
       if (1 <= element.value.state() && element.value.state() <= 4) {
         downloading.add(element.key);
-        return;
+        continue;
       }
 
-      if (int.tryParse(element.value.url()) == null) return;
+      if (int.tryParse(element.value.url()) == null) continue;
       final qr = queryResults[int.parse(element.value.url())];
-      if (qr == null) return;
+      if (qr == null) continue;
 
       // key := <group>:<name>
       var succ = !_filterController.isOr;
@@ -745,7 +746,7 @@ class _DownloadPageState extends ThemeSwitchableState<DownloadPage>
         }
       });
       if (succ) result.add(element.key);
-    });
+    }
 
     if (_filterController.tagStates.isNotEmpty) {
       filterResult = result.map((e) => itemsMap[e]!).toList();
@@ -762,12 +763,12 @@ class _DownloadPageState extends ThemeSwitchableState<DownloadPage>
       final userlog = await user.getUserLog();
       final articlereadlog = <int, DateTime>{};
 
-      userlog.forEach((element) {
+      for (var element in userlog) {
         final id = int.tryParse(element.articleId());
         if (id == null) {
           Logger.warning(
               '[download-_applyFilter] articleId is not int type: ${element.articleId()}');
-          return;
+          continue;
         }
         if (!articlereadlog.containsKey(id)) {
           final dt = DateTime.tryParse(element.datetimeStart());
@@ -778,7 +779,7 @@ class _DownloadPageState extends ThemeSwitchableState<DownloadPage>
                 '[download-_applyFilter] datetimeStart is not DateTime type: ${element.datetimeStart()}');
           }
         }
-      });
+      }
 
       filterResult.sort((x, y) {
         if (int.tryParse(x.url()) == null) return 1;
diff --git a/lib/pages/download/download_view_type.dart b/lib/pages/download/download_view_type.dart
index 1bac5d259..5a54c919d 100644
--- a/lib/pages/download/download_view_type.dart
+++ b/lib/pages/download/download_view_type.dart
@@ -8,7 +8,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class DownloadViewType extends StatelessWidget {
-  const DownloadViewType({Key? key}) : super(key: key);
+  const DownloadViewType({super.key});
 
   Color getColor(int i) {
     return Settings.themeWhat
diff --git a/lib/pages/hot/hot_page.dart b/lib/pages/hot/hot_page.dart
index 09459f74f..138d2ce11 100644
--- a/lib/pages/hot/hot_page.dart
+++ b/lib/pages/hot/hot_page.dart
@@ -20,7 +20,7 @@ import 'package:violet/widgets/search_bar.dart';
 import 'package:violet/widgets/theme_switchable_state.dart';
 
 class HotPage extends StatefulWidget {
-  const HotPage({Key? key}) : super(key: key);
+  const HotPage({super.key});
 
   @override
   State<HotPage> createState() => _HotPageState();
@@ -72,15 +72,15 @@ class _HotPageState extends ThemeSwitchableState<HotPage>
             );
           } else if (snapshot.data!.item1 != 200) {
             final errmsg = {
-              '400': 'Bad Request',
-              '403': 'Forbidden',
-              '429': 'Too Many Requests',
-              '500': 'Internal Server Error',
-              '502': 'Bad Gateway',
-              '521': 'Web server is down',
+              400: 'Bad Request',
+              403: 'Forbidden',
+              429: 'Too Many Requests',
+              500: 'Internal Server Error',
+              502: 'Bad Gateway',
+              521: 'Web server is down',
               //
-              '900': 'Nothing To Display',
-              '901': 'No Query Results.',
+              900: 'Nothing To Display',
+              901: 'No Query Results.',
             };
 
             sliverList = SliverToBoxAdapter(
@@ -108,7 +108,10 @@ class _HotPageState extends ThemeSwitchableState<HotPage>
                       style: TextStyle(fontSize: 16),
                     ),
                     Text(
-                        'Error${errmsg[snapshot.data!.item1] != null ? ': ${errmsg[snapshot.data!.item1]!}' : ' Code: ${snapshot.data!.item1}'}')
+                      errmsg[snapshot.data!.item1] != null
+                          ? 'Error: ${errmsg[snapshot.data!.item1]!}'
+                          : 'Error Code: ${snapshot.data!.item1}',
+                    )
                   ],
                 ),
               ),
@@ -200,9 +203,9 @@ class _HotPageState extends ThemeSwitchableState<HotPage>
       }
 
       final qr = <String, QueryResult>{};
-      query.results!.forEach((element) {
+      for (var element in query.results!) {
         qr[element.id().toString()] = element;
-      });
+      }
 
       final result = <Tuple2<QueryResult, int>>[];
       value.forEach((element) {
diff --git a/lib/pages/lock/lock_screen.dart b/lib/pages/lock/lock_screen.dart
index c358004d2..d4a8d8274 100644
--- a/lib/pages/lock/lock_screen.dart
+++ b/lib/pages/lock/lock_screen.dart
@@ -15,8 +15,7 @@ class LockScreen extends StatefulWidget {
   final bool isSecureMode;
 
   const LockScreen(
-      {Key? key, this.isRegisterMode = false, this.isSecureMode = false})
-      : super(key: key);
+      {super.key, this.isRegisterMode = false, this.isSecureMode = false});
 
   @override
   State<LockScreen> createState() => _LockScreenState();
diff --git a/lib/pages/main/artist_collection/artist_collection_page.dart b/lib/pages/main/artist_collection/artist_collection_page.dart
index 528c74dd3..dcd95620c 100644
--- a/lib/pages/main/artist_collection/artist_collection_page.dart
+++ b/lib/pages/main/artist_collection/artist_collection_page.dart
@@ -10,7 +10,7 @@ import 'package:violet/pages/segment/card_panel.dart';
 import 'package:violet/pages/segment/platform_navigator.dart';
 
 class ArtistCollectionPage extends StatefulWidget {
-  const ArtistCollectionPage({Key? key}) : super(key: key);
+  const ArtistCollectionPage({super.key});
 
   @override
   State<ArtistCollectionPage> createState() => _ArtistCollectionPageState();
diff --git a/lib/pages/main/artist_collection/artist_list_page.dart b/lib/pages/main/artist_collection/artist_list_page.dart
index bde36c432..c6d0a6176 100644
--- a/lib/pages/main/artist_collection/artist_list_page.dart
+++ b/lib/pages/main/artist_collection/artist_list_page.dart
@@ -19,8 +19,7 @@ class ArtistListPage extends StatelessWidget {
   final List<String> artists;
   final bool isLast;
 
-  const ArtistListPage({Key? key, required this.artists, required this.isLast})
-      : super(key: key);
+  const ArtistListPage({super.key, required this.artists, required this.isLast});
 
   static final RegExp _chDot = RegExp('[cC]h\\.');
 
diff --git a/lib/pages/main/faq/faq_page.dart b/lib/pages/main/faq/faq_page.dart
index f85bec24c..24c61865c 100644
--- a/lib/pages/main/faq/faq_page.dart
+++ b/lib/pages/main/faq/faq_page.dart
@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
 import 'package:violet/settings/settings.dart';
 
 class FAQPageKorean extends StatelessWidget {
-  const FAQPageKorean({Key? key}) : super(key: key);
+  const FAQPageKorean({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/main/info/info_page.dart b/lib/pages/main/info/info_page.dart
index 85677fbfc..7ea0372b7 100644
--- a/lib/pages/main/info/info_page.dart
+++ b/lib/pages/main/info/info_page.dart
@@ -14,7 +14,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class InfoPage extends StatefulWidget {
-  const InfoPage({Key? key}) : super(key: key);
+  const InfoPage({super.key});
 
   @override
   State<InfoPage> createState() => _InfoPageState();
diff --git a/lib/pages/main/info/lab/artist_search/artist_search.dart b/lib/pages/main/info/lab/artist_search/artist_search.dart
index 490842f69..ca6464b54 100644
--- a/lib/pages/main/info/lab/artist_search/artist_search.dart
+++ b/lib/pages/main/info/lab/artist_search/artist_search.dart
@@ -54,7 +54,7 @@ class _ArtistSearchState extends State<ArtistSearch> {
       'uploader': HitomiIndexs.tagUploader,
     };
 
-    this.tagGroup.entries.forEach((element) {
+    for (var element in this.tagGroup.entries) {
       var key = element.key;
 
       if (key.startsWith('tag:')) {
@@ -67,7 +67,7 @@ class _ArtistSearchState extends State<ArtistSearch> {
         tagGroup[HitomiIndexs.tagIndex[key.replaceAll('_', ' ')].toString()] =
             element.value;
       }
-    });
+    }
 
     print(tagGroup);
 
diff --git a/lib/pages/main/info/lab/bookmark/bookmarks.dart b/lib/pages/main/info/lab/bookmark/bookmarks.dart
index 1642b4f9b..4b823683e 100644
--- a/lib/pages/main/info/lab/bookmark/bookmarks.dart
+++ b/lib/pages/main/info/lab/bookmark/bookmarks.dart
@@ -19,10 +19,10 @@ class LabBookmarkPage extends StatefulWidget {
   final String? version;
 
   const LabBookmarkPage({
-    Key? key,
+    super.key,
     required this.userAppId,
     this.version,
-  }) : super(key: key);
+  });
 
   @override
   State<LabBookmarkPage> createState() => _BookmarkPageState();
diff --git a/lib/pages/main/info/lab/bookmark/bookmarks_article_list.dart b/lib/pages/main/info/lab/bookmark/bookmarks_article_list.dart
index 483fe932f..432fe1588 100644
--- a/lib/pages/main/info/lab/bookmark/bookmarks_article_list.dart
+++ b/lib/pages/main/info/lab/bookmark/bookmarks_article_list.dart
@@ -31,12 +31,12 @@ class LabGroupArticleListPage extends StatefulWidget {
   final int groupId;
 
   const LabGroupArticleListPage({
-    Key? key,
+    super.key,
     required this.articles,
     required this.artists,
     required this.name,
     required this.groupId,
-  }) : super(key: key);
+  });
 
   @override
   State<LabGroupArticleListPage> createState() => _GroupArticleListPageState();
@@ -88,14 +88,14 @@ class _GroupArticleListPageState extends State<LabGroupArticleListPage> {
               queryRaw + (!Settings.searchPure ? ' AND ExistOnHitomi=1' : ''))
           .then((value) async {
         var qr = <String, QueryResult>{};
-        value.results!.forEach((element) {
+        for (var element in value.results!) {
           qr[element.id().toString()] = element;
-        });
+        }
 
         var result = <QueryResult>[];
-        cc.forEach((element) async {
+        for (var element in cc) {
           if (qr[element.article()] == null) {
-            // TODO: Handle qurey not found
+            // TODO: Handle query not found
             var headers = await ScriptManager.runHitomiGetHeaderContent(
                 element.article());
             var hh = await http.get(
@@ -113,10 +113,10 @@ class _GroupArticleListPageState extends State<LabGroupArticleListPage> {
             setState(() {
               _shouldRebuild = true;
             });
-            return;
+          } else {
+            result.add(qr[element.article()]!);
           }
-          result.add(qr[element.article()]!);
-        });
+        }
 
         queryResult = result;
         _applyFilter();
@@ -307,7 +307,7 @@ class _GroupArticleListPageState extends State<LabGroupArticleListPage> {
   void _applyFilter() {
     var result = <QueryResult>[];
     var isOr = _filterController.isOr;
-    queryResult.forEach((element) {
+    for (var element in queryResult) {
       // key := <group>:<name>
       var succ = !_filterController.isOr;
       _filterController.tagStates.forEach((key, value) {
@@ -343,7 +343,7 @@ class _GroupArticleListPageState extends State<LabGroupArticleListPage> {
         }
       });
       if (succ) result.add(element);
-    });
+    }
 
     filterResult = result;
     isFilterUsed = true;
diff --git a/lib/pages/main/info/lab/bookmark/bookmarks_artist_list.dart b/lib/pages/main/info/lab/bookmark/bookmarks_artist_list.dart
index 59d549ad2..7c12fc0b8 100644
--- a/lib/pages/main/info/lab/bookmark/bookmarks_artist_list.dart
+++ b/lib/pages/main/info/lab/bookmark/bookmarks_artist_list.dart
@@ -24,11 +24,11 @@ class LabGroupArtistList extends StatefulWidget {
   final int groupId;
 
   const LabGroupArtistList({
-    Key? key,
+    super.key,
     required this.artists,
     required this.name,
     required this.groupId,
-  }) : super(key: key);
+  });
 
   @override
   State<LabGroupArtistList> createState() => _GroupArtistListState();
diff --git a/lib/pages/main/info/lab/bookmark/bookmarks_records.dart b/lib/pages/main/info/lab/bookmark/bookmarks_records.dart
index d307a47ca..286417bdc 100644
--- a/lib/pages/main/info/lab/bookmark/bookmarks_records.dart
+++ b/lib/pages/main/info/lab/bookmark/bookmarks_records.dart
@@ -15,7 +15,7 @@ import 'package:violet/widgets/article_item/article_list_item_widget.dart';
 class LabRecordViewPage extends StatelessWidget {
   final List<dynamic> records;
 
-  const LabRecordViewPage({Key? key, required this.records}) : super(key: key);
+  const LabRecordViewPage({super.key, required this.records});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/main/info/lab/bookmark_spy.dart b/lib/pages/main/info/lab/bookmark_spy.dart
index da19a14d9..3262b939d 100644
--- a/lib/pages/main/info/lab/bookmark_spy.dart
+++ b/lib/pages/main/info/lab/bookmark_spy.dart
@@ -14,7 +14,7 @@ import 'package:violet/server/violet.dart';
 import 'package:violet/settings/settings.dart';
 
 class LabBookmarkSpyPage extends StatefulWidget {
-  const LabBookmarkSpyPage({Key? key}) : super(key: key);
+  const LabBookmarkSpyPage({super.key});
 
   @override
   State<LabBookmarkSpyPage> createState() => _LabBookmarkSpyPageState();
diff --git a/lib/pages/main/info/lab/global_comments.dart b/lib/pages/main/info/lab/global_comments.dart
index e85c4f3d8..4fe7bbc39 100644
--- a/lib/pages/main/info/lab/global_comments.dart
+++ b/lib/pages/main/info/lab/global_comments.dart
@@ -15,7 +15,7 @@ import 'package:violet/server/community/anon.dart';
 import 'package:violet/settings/settings.dart';
 
 class LabGlobalComments extends StatefulWidget {
-  const LabGlobalComments({Key? key}) : super(key: key);
+  const LabGlobalComments({super.key});
 
   @override
   State<LabGlobalComments> createState() => _LabGlobalCommentsState();
@@ -214,7 +214,7 @@ class CommentUnit extends StatelessWidget {
   static const String dev = '1918c652d3a9';
 
   const CommentUnit({
-    Key? key,
+    super.key,
     required this.id,
     required this.author,
     required this.body,
@@ -222,7 +222,7 @@ class CommentUnit extends StatelessWidget {
     this.reply,
     required this.replies,
     this.isReply = false,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/main/info/lab/recent_comments.dart b/lib/pages/main/info/lab/recent_comments.dart
index 7b03abe28..1d9833c5a 100644
--- a/lib/pages/main/info/lab/recent_comments.dart
+++ b/lib/pages/main/info/lab/recent_comments.dart
@@ -10,7 +10,7 @@ import 'package:violet/pages/segment/platform_navigator.dart';
 import 'package:violet/server/community/anon.dart';
 
 class LabRecentComments extends StatefulWidget {
-  const LabRecentComments({Key? key}) : super(key: key);
+  const LabRecentComments({super.key});
 
   @override
   State<LabRecentComments> createState() => _LabRecentCommentsState();
diff --git a/lib/pages/main/info/lab/recent_record.dart b/lib/pages/main/info/lab/recent_record.dart
index e327c2d26..01ad31c72 100644
--- a/lib/pages/main/info/lab/recent_record.dart
+++ b/lib/pages/main/info/lab/recent_record.dart
@@ -19,7 +19,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/widgets/article_item/article_list_item_widget.dart';
 
 class LabRecentRecords extends StatefulWidget {
-  const LabRecentRecords({Key? key}) : super(key: key);
+  const LabRecentRecords({super.key});
 
   @override
   State<LabRecentRecords> createState() => _LabRecentRecordsState();
@@ -83,18 +83,18 @@ class _LabRecentRecordsState extends State<LabRecentRecords> {
       if (query.results!.isEmpty) return;
 
       var qr = <String, QueryResult>{};
-      query.results!.forEach((element) {
+      for (var element in query.results!) {
         qr[element.id().toString()] = element;
-      });
+      }
 
       var result = <Tuple2<QueryResult, int>>[];
-      xrecords.forEach((element) {
+      for (var element in xrecords) {
         if (qr[element.item2.toString()] == null) {
-          return;
+          continue;
         }
         result.add(Tuple2<QueryResult, int>(
             qr[element.item2.toString()]!, element.item3));
-      });
+      }
 
       records.insertAll(0, result);
 
diff --git a/lib/pages/main/info/lab/recent_record_u.dart b/lib/pages/main/info/lab/recent_record_u.dart
index cb422168a..cab398e72 100644
--- a/lib/pages/main/info/lab/recent_record_u.dart
+++ b/lib/pages/main/info/lab/recent_record_u.dart
@@ -21,7 +21,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/widgets/article_item/article_list_item_widget.dart';
 
 class LabRecentRecordsU extends StatefulWidget {
-  const LabRecentRecordsU({Key? key}) : super(key: key);
+  const LabRecentRecordsU({super.key});
 
   @override
   State<LabRecentRecordsU> createState() => _LabRecentRecordsUState();
@@ -86,18 +86,18 @@ class _LabRecentRecordsUState extends State<LabRecentRecordsU> {
       if (query.results!.isEmpty) return;
 
       var qr = <String, QueryResult>{};
-      query.results!.forEach((element) {
+      for (var element in query.results!) {
         qr[element.id().toString()] = element;
-      });
+      }
 
       var result = <Tuple3<QueryResult, int, String>>[];
-      xrecords.forEach((element) {
+      for (var element in xrecords) {
         if (qr[element.item2.toString()] == null) {
-          return;
+          continue;
         }
         result.add(Tuple3<QueryResult, int, String>(
             qr[element.item2.toString()]!, element.item3, element.item4));
-      });
+      }
 
       records.insertAll(0, result);
 
diff --git a/lib/pages/main/info/lab/recent_user_record.dart b/lib/pages/main/info/lab/recent_user_record.dart
index a8245c858..373be85b8 100644
--- a/lib/pages/main/info/lab/recent_user_record.dart
+++ b/lib/pages/main/info/lab/recent_user_record.dart
@@ -25,7 +25,7 @@ import 'package:violet/widgets/article_item/article_list_item_widget.dart';
 class LabUserRecentRecords extends StatefulWidget {
   final String userAppId;
 
-  const LabUserRecentRecords(this.userAppId, {Key? key}) : super(key: key);
+  const LabUserRecentRecords(this.userAppId, {super.key});
 
   @override
   State<LabUserRecentRecords> createState() => _LabUserRecentRecordsState();
@@ -75,8 +75,8 @@ class _LabUserRecentRecordsState extends State<LabUserRecentRecords> {
 
       var ffstat = <String, int>{};
 
-      query.results!.forEach((element) {
-        if (element.tags() == null) return;
+      for (var element in query.results!) {
+        if (element.tags() == null) continue;
         (element.tags() as String)
             .split('|')
             .where((element) => element != '')
@@ -92,7 +92,7 @@ class _LabUserRecentRecordsState extends State<LabUserRecentRecords> {
           if (!ffstat.containsKey(element)) ffstat[element] = 0;
           ffstat[element] = ffstat[element]! + 1;
         });
-      });
+      }
 
       ffstat.forEach((key, value) {
         lff.add(Tuple2<String, int>(key, value));
@@ -107,18 +107,18 @@ class _LabUserRecentRecordsState extends State<LabUserRecentRecords> {
       /* -- Statistics */
 
       var qr = <String, QueryResult>{};
-      query.results!.forEach((element) {
+      for (var element in query.results!) {
         qr[element.id().toString()] = element;
-      });
+      }
 
       var result = <Tuple2<QueryResult, int>>[];
-      xrecords.forEach((element) {
+      for (var element in xrecords) {
         if (qr[element.item2.toString()] == null) {
-          return;
+          continue;
         }
         result.add(Tuple2<QueryResult, int>(
             qr[element.item2.toString()]!, element.item3));
-      });
+      }
 
       records.insertAll(0, result);
 
diff --git a/lib/pages/main/info/lab/search_comment.dart b/lib/pages/main/info/lab/search_comment.dart
index 032d3dddd..41e8cb035 100644
--- a/lib/pages/main/info/lab/search_comment.dart
+++ b/lib/pages/main/info/lab/search_comment.dart
@@ -16,7 +16,7 @@ import 'package:violet/server/violet.dart';
 import 'package:violet/widgets/article_item/image_provider_manager.dart';
 
 class LabSearchComments extends StatefulWidget {
-  const LabSearchComments({Key? key}) : super(key: key);
+  const LabSearchComments({super.key});
 
   @override
   State<LabSearchComments> createState() => _LabSearchCommentsState();
diff --git a/lib/pages/main/info/lab/search_comment_author.dart b/lib/pages/main/info/lab/search_comment_author.dart
index 8b9474b4b..862c932ba 100644
--- a/lib/pages/main/info/lab/search_comment_author.dart
+++ b/lib/pages/main/info/lab/search_comment_author.dart
@@ -16,7 +16,7 @@ import 'package:violet/widgets/article_item/image_provider_manager.dart';
 class LabSearchCommentsAuthor extends StatefulWidget {
   final String author;
 
-  const LabSearchCommentsAuthor(this.author, {Key? key}) : super(key: key);
+  const LabSearchCommentsAuthor(this.author, {super.key});
 
   @override
   State<LabSearchCommentsAuthor> createState() =>
diff --git a/lib/pages/main/info/lab/search_message.dart b/lib/pages/main/info/lab/search_message.dart
index 241f107b0..08df67edc 100644
--- a/lib/pages/main/info/lab/search_message.dart
+++ b/lib/pages/main/info/lab/search_message.dart
@@ -22,11 +22,12 @@ import 'package:violet/pages/segment/card_panel.dart';
 import 'package:violet/pages/segment/platform_navigator.dart';
 import 'package:violet/script/script_manager.dart';
 import 'package:violet/server/violet.dart';
+import 'package:violet/util/evict_image_urls.dart';
 import 'package:violet/widgets/article_item/image_provider_manager.dart';
 import 'package:violet/widgets/v_cached_network_image.dart';
 
 class LabSearchMessage extends StatefulWidget {
-  const LabSearchMessage({Key? key}) : super(key: key);
+  const LabSearchMessage({super.key});
 
   @override
   State<LabSearchMessage> createState() => _LabSearchMessageState();
@@ -91,11 +92,7 @@ class _LabSearchMessageState extends State<LabSearchMessage> {
     PaintingBinding.instance.imageCache.clear();
     imageCache.clearLiveImages();
     imageCache.clear();
-    if (_urls != null) {
-      _urls!.forEach((element) async {
-        await CachedNetworkImageProvider(element).evict();
-      });
-    }
+    evictImageUrls(_urls);
     super.dispose();
   }
 
@@ -314,9 +311,7 @@ class _LabSearchMessageState extends State<LabSearchMessage> {
                                     .toList()))
                         .toList();
 
-                    _urls!.forEach((element) async {
-                      await CachedNetworkImageProvider(element).evict();
-                    });
+                    evictImageUrls(_urls);
 
                     _height = List<double>.filled(messages.length, 0);
                     _keys = List<GlobalKey>.generate(
@@ -435,9 +430,7 @@ class _LabSearchMessageState extends State<LabSearchMessage> {
                 .toList()))
         .toList();
 
-    _urls!.forEach((element) async {
-      await CachedNetworkImageProvider(element).evict();
-    });
+    evictImageUrls(_urls);
 
     _height = List<double>.filled(messages.length, 0);
     _keys = List<GlobalKey>.generate(messages.length, (index) => GlobalKey());
diff --git a/lib/pages/main/info/lab/search_message_rank.dart b/lib/pages/main/info/lab/search_message_rank.dart
index 3f5d5496b..b10932b29 100644
--- a/lib/pages/main/info/lab/search_message_rank.dart
+++ b/lib/pages/main/info/lab/search_message_rank.dart
@@ -16,7 +16,7 @@ class SearchMessageRankPageMemory {
 }
 
 class SearchMessageRankPage extends StatefulWidget {
-  const SearchMessageRankPage({Key? key}) : super(key: key);
+  const SearchMessageRankPage({super.key});
 
   @override
   State<SearchMessageRankPage> createState() => _SearchMessageRankPageState();
diff --git a/lib/pages/main/info/lab/setting.dart b/lib/pages/main/info/lab/setting.dart
index 86388e5f3..e78a66b95 100644
--- a/lib/pages/main/info/lab/setting.dart
+++ b/lib/pages/main/info/lab/setting.dart
@@ -7,7 +7,7 @@ import 'package:violet/pages/segment/card_panel.dart';
 import 'package:violet/settings/settings.dart';
 
 class LabSetting extends StatefulWidget {
-  const LabSetting({Key? key}) : super(key: key);
+  const LabSetting({super.key});
 
   @override
   State<LabSetting> createState() => _LabSettingState();
diff --git a/lib/pages/main/info/lab/statistics.dart b/lib/pages/main/info/lab/statistics.dart
index cb7249c46..5111b4bb7 100644
--- a/lib/pages/main/info/lab/statistics.dart
+++ b/lib/pages/main/info/lab/statistics.dart
@@ -21,7 +21,7 @@ import 'package:violet/pages/segment/card_panel.dart';
 import 'package:violet/settings/settings.dart';
 
 class Statistics extends StatefulWidget {
-  const Statistics({Key? key}) : super(key: key);
+  const Statistics({super.key});
 
   @override
   State<Statistics> createState() => _StatisticsState();
@@ -62,11 +62,11 @@ class _StatisticsState extends State<Statistics> {
                 totalRead = value.length;
                 var overap = HashSet<String>();
                 var rr = <ArticleReadLog>[];
-                value.forEach((element) {
-                  if (overap.contains(element.articleId())) return;
+                for (var element in value) {
+                  if (overap.contains(element.articleId())) continue;
                   rr.add(element);
                   overap.add(element.articleId());
-                });
+                }
                 pureRead = rr.length;
                 return rr;
               }));
@@ -90,8 +90,8 @@ class _StatisticsState extends State<Statistics> {
       var ffstat = <String, int>{};
 
       if (!_allowOverlap) {
-        query.results!.forEach((element) {
-          if (element.tags() == null) return;
+        for (var element in query.results!) {
+          if (element.tags() == null) continue;
           (element.tags() as String)
               .split('|')
               .where((element) => element != '')
@@ -107,18 +107,18 @@ class _StatisticsState extends State<Statistics> {
             if (!ffstat.containsKey(element)) ffstat[element] = 0;
             ffstat[element] = ffstat[element]! + 1;
           });
-        });
+        }
       } else {
         final log =
             await User.getInstance().then((value) => value.getUserLog());
         final idMap = <String, QueryResult>{};
-        query.results!.forEach((element) {
+        for (var element in query.results!) {
           idMap[element.id().toString()] = element;
-        });
-        log.forEach((element) {
-          if (!idMap.containsKey(element.articleId())) return;
+        }
+        for (var element in log) {
+          if (!idMap.containsKey(element.articleId())) continue;
           final qr = idMap[element.articleId()]!;
-          if (qr.tags() == null) return;
+          if (qr.tags() == null) continue;
           (qr.tags() as String)
               .split('|')
               .where((element) => element != '')
@@ -134,7 +134,7 @@ class _StatisticsState extends State<Statistics> {
             if (!ffstat.containsKey(element)) ffstat[element] = 0;
             ffstat[element] = ffstat[element]! + 1;
           });
-        });
+        }
       }
 
       ffstat.forEach((key, value) {
@@ -272,7 +272,7 @@ class _StatisticsState extends State<Statistics> {
     }
 
     totalPureSeconds = 0;
-    events.entries.forEach((element) {
+    for (var element in events.entries) {
       var accSeconds = 0;
 
       bool stopAcc = false;
@@ -307,7 +307,7 @@ class _StatisticsState extends State<Statistics> {
       }
 
       totalPureSeconds += accSeconds;
-    });
+    }
   }
 
   bool _alreadyCacheAnalysis = false;
diff --git a/lib/pages/main/info/lab/top_recent.dart b/lib/pages/main/info/lab/top_recent.dart
index 6634619c2..f79455d11 100644
--- a/lib/pages/main/info/lab/top_recent.dart
+++ b/lib/pages/main/info/lab/top_recent.dart
@@ -17,7 +17,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/widgets/article_item/article_list_item_widget.dart';
 
 class LabTopRecent extends StatefulWidget {
-  const LabTopRecent({Key? key}) : super(key: key);
+  const LabTopRecent({super.key});
 
   @override
   State<LabTopRecent> createState() => _LabTopRecentState();
@@ -70,18 +70,18 @@ class _LabTopRecentState extends State<LabTopRecent> {
       if (query.results!.isEmpty) return;
 
       var qr = <String, QueryResult>{};
-      query.results!.forEach((element) {
+      for (var element in query.results!) {
         qr[element.id().toString()] = element;
-      });
+      }
 
       var result = <Tuple2<QueryResult, int>>[];
-      xrecords.forEach((element) {
+      for (var element in xrecords) {
         if (qr[element.item1.toString()] == null) {
-          return;
+          continue;
         }
         result.add(Tuple2<QueryResult, int>(
             qr[element.item1.toString()]!, element.item2));
-      });
+      }
 
       records = result;
 
diff --git a/lib/pages/main/info/lab/user_bookmark_page.dart b/lib/pages/main/info/lab/user_bookmark_page.dart
index 17e0c8f9b..502960308 100644
--- a/lib/pages/main/info/lab/user_bookmark_page.dart
+++ b/lib/pages/main/info/lab/user_bookmark_page.dart
@@ -11,7 +11,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class LabUserBookmarkPage extends StatefulWidget {
-  const LabUserBookmarkPage({Key? key}) : super(key: key);
+  const LabUserBookmarkPage({super.key});
 
   @override
   State<LabUserBookmarkPage> createState() => _LabUserBookmarkPageState();
diff --git a/lib/pages/main/info/lab_page.dart b/lib/pages/main/info/lab_page.dart
index 9efa5abd7..c5af39942 100644
--- a/lib/pages/main/info/lab_page.dart
+++ b/lib/pages/main/info/lab_page.dart
@@ -35,7 +35,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class LaboratoryPage extends StatefulWidget {
-  const LaboratoryPage({Key? key}) : super(key: key);
+  const LaboratoryPage({super.key});
 
   @override
   State<LaboratoryPage> createState() => _LaboratoryPageState();
@@ -96,13 +96,13 @@ class _LaboratoryPageState extends State<LaboratoryPage> {
                       .then((value) => value.getUserLog());
                   final articleCount = <String, int>{};
 
-                  userLog.forEach((element) {
+                  for (var element in userLog) {
                     if (!articleCount.containsKey(element.articleId())) {
                       articleCount[element.articleId()] = 0;
                     }
                     articleCount[element.articleId()] =
                         articleCount[element.articleId()]! + 1;
-                  });
+                  }
 
                   final ll = articleCount.entries.toList();
                   ll.sort((x, y) => y.value.compareTo(x.value));
@@ -124,11 +124,11 @@ class _LaboratoryPageState extends State<LaboratoryPage> {
                       .then((value) => value.getUserLog());
                   final articleCount = <String, int>{};
 
-                  userLog.forEach((element) {
+                  for (var element in userLog) {
                     if (!articleCount.containsKey(element.articleId())) {
                       articleCount[element.articleId()] = 0;
                     }
-                  });
+                  }
 
                   final ll = articleCount.entries.toList();
                   ll.sort((x, y) => y.value.compareTo(x.value));
diff --git a/lib/pages/main/info/user_manual_page.dart b/lib/pages/main/info/user_manual_page.dart
index 26cf74efc..f2bbb03f1 100644
--- a/lib/pages/main/info/user_manual_page.dart
+++ b/lib/pages/main/info/user_manual_page.dart
@@ -9,7 +9,7 @@ import 'package:violet/network/wrapper.dart' as http;
 import 'package:violet/pages/segment/card_panel.dart';
 
 class UserManualPage extends StatefulWidget {
-  const UserManualPage({Key? key}) : super(key: key);
+  const UserManualPage({super.key});
 
   @override
   State<UserManualPage> createState() => _UserManualPageState();
diff --git a/lib/pages/main/info/violet_page.dart b/lib/pages/main/info/violet_page.dart
index f0cb49f9b..41fc397a4 100644
--- a/lib/pages/main/info/violet_page.dart
+++ b/lib/pages/main/info/violet_page.dart
@@ -6,7 +6,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/version/update_sync.dart';
 
 class VioletPage extends StatelessWidget {
-  const VioletPage({Key? key}) : super(key: key);
+  const VioletPage({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/main/main_page.dart b/lib/pages/main/main_page.dart
index 6c636c72b..495ea5d81 100644
--- a/lib/pages/main/main_page.dart
+++ b/lib/pages/main/main_page.dart
@@ -58,7 +58,7 @@ final _contactUri = Uri(
 final _gitHubUri = Uri.tryParse('https://github.com/project-violet/');
 
 class MainPage extends StatefulWidget {
-  const MainPage({Key? key}) : super(key: key);
+  const MainPage({super.key});
 
   @override
   State<MainPage> createState() => _MainPageState();
@@ -309,7 +309,7 @@ class _MainPageState extends ThemeSwitchableState<MainPage>
 }
 
 class _VersionAreaWidget extends StatefulWidget {
-  const _VersionAreaWidget({Key? key}) : super(key: key);
+  const _VersionAreaWidget();
 
   @override
   State<_VersionAreaWidget> createState() => _VersionAreaWidgetState();
@@ -531,7 +531,7 @@ class _VersionAreaWidgetState extends State<_VersionAreaWidget> {
 }
 
 class _StatAreaWidget extends StatelessWidget {
-  const _StatAreaWidget({Key? key}) : super(key: key);
+  const _StatAreaWidget();
 
   String numberWithComma(int param) {
     return NumberFormat('###,###,###,###').format(param).replaceAll(' ', '');
@@ -616,9 +616,7 @@ class _StatAreaWidget extends StatelessWidget {
 }
 
 class _ServiceAreaWidget extends StatelessWidget {
-  const _ServiceAreaWidget({
-    Key? key,
-  }) : super(key: key);
+  const _ServiceAreaWidget();
 
   @override
   Widget build(BuildContext context) {
@@ -729,10 +727,9 @@ class _BuildGroupWidget extends StatelessWidget {
   final Widget content;
 
   const _BuildGroupWidget({
-    Key? key,
     required this.name,
     required this.content,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/main/patchnote/patchnote_page.dart b/lib/pages/main/patchnote/patchnote_page.dart
index 71983ad2b..694371256 100644
--- a/lib/pages/main/patchnote/patchnote_page.dart
+++ b/lib/pages/main/patchnote/patchnote_page.dart
@@ -942,7 +942,7 @@ Thank you so much for using the beta version until now.'''
 ];
 
 class PatchNotePage extends StatefulWidget {
-  const PatchNotePage({Key? key}) : super(key: key);
+  const PatchNotePage({super.key});
 
   @override
   State<PatchNotePage> createState() => _PatchNotePageState();
diff --git a/lib/pages/main/views/views_page.dart b/lib/pages/main/views/views_page.dart
index 3a5e62450..34377ce55 100644
--- a/lib/pages/main/views/views_page.dart
+++ b/lib/pages/main/views/views_page.dart
@@ -18,7 +18,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/widgets/article_item/article_list_item_widget.dart';
 
 class ViewsPage extends StatefulWidget {
-  const ViewsPage({Key? key}) : super(key: key);
+  const ViewsPage({super.key});
 
   @override
   State<ViewsPage> createState() => _ViewsPageState();
@@ -155,9 +155,9 @@ class __TabState extends State<_Tab> with AutomaticKeepAliveClientMixin {
         if (query.results!.isEmpty) return 901;
 
         var qr = <String, QueryResult>{};
-        query.results!.forEach((element) {
+        for (var element in query.results!) {
           qr[element.id().toString()] = element;
-        });
+        }
 
         var result = <Tuple2<QueryResult, int>>[];
         value.forEach((element) {
diff --git a/lib/pages/search/search_bar_page.dart b/lib/pages/search/search_bar_page.dart
index 7a564f285..950033e17 100644
--- a/lib/pages/search/search_bar_page.dart
+++ b/lib/pages/search/search_bar_page.dart
@@ -26,11 +26,11 @@ class SearchBarPage extends StatefulWidget {
   final String initText;
 
   const SearchBarPage({
-    Key? key,
+    super.key,
     required this.assetProvider,
     required this.initText,
     required this.heroController,
-  }) : super(key: key);
+  });
 
   @override
   State<SearchBarPage> createState() => _SearchBarPageState();
@@ -102,12 +102,12 @@ class _SearchBarPageState extends State<SearchBarPage>
         'page',
       ];
 
-      prefixList.forEach(
-        (element) => _searchLists.add(
+      for (var element in prefixList) {
+        _searchLists.add(
           Tuple2<DisplayedTag, int>(
               DisplayedTag(group: 'prefix', name: element), 0),
-        ),
-      );
+        );
+      }
     }
 
     _initBottomPadding ??= (mediaQuery.padding + mediaQuery.viewInsets).bottom;
diff --git a/lib/pages/search/search_nav_page.dart b/lib/pages/search/search_nav_page.dart
index f0cfb696c..630f6031a 100644
--- a/lib/pages/search/search_nav_page.dart
+++ b/lib/pages/search/search_nav_page.dart
@@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
 import 'package:violet/pages/segment/card_panel.dart';
 
 class SearchNavPage extends StatefulWidget {
-  const SearchNavPage({Key? key}) : super(key: key);
+  const SearchNavPage({super.key});
 
   @override
   State<SearchNavPage> createState() => _SearchNavPageState();
diff --git a/lib/pages/search/search_page.dart b/lib/pages/search/search_page.dart
index 832794442..28e6d7c98 100644
--- a/lib/pages/search/search_page.dart
+++ b/lib/pages/search/search_page.dart
@@ -44,7 +44,7 @@ bool blurred = false;
 class SearchPage extends StatefulWidget {
   final String? searchKeyWord;
 
-  const SearchPage({Key? key, this.searchKeyWord}) : super(key: key);
+  const SearchPage({super.key, this.searchKeyWord});
 
   @override
   State<SearchPage> createState() => _SearchPageState();
@@ -559,12 +559,12 @@ class ResultPanelWidget extends StatelessWidget {
   final Map<String, GlobalKey> itemKeys;
 
   const ResultPanelWidget({
-    Key? key,
+    super.key,
     required this.resultList,
     required this.dateTime,
     required this.sliverKey,
     required this.itemKeys,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/search/search_page_modify.dart b/lib/pages/search/search_page_modify.dart
index 37c02e518..f84cc5db7 100644
--- a/lib/pages/search/search_page_modify.dart
+++ b/lib/pages/search/search_page_modify.dart
@@ -12,10 +12,10 @@ class SearchPageModifyPage extends StatefulWidget {
   final int maxPage;
 
   const SearchPageModifyPage({
-    Key? key,
+    super.key,
     required this.curPage,
     required this.maxPage,
-  }) : super(key: key);
+  });
 
   @override
   State<SearchPageModifyPage> createState() => _SearchPageModifyPageState();
diff --git a/lib/pages/search/search_result_selector.dart b/lib/pages/search/search_result_selector.dart
index b66ab9396..2cd11a794 100644
--- a/lib/pages/search/search_result_selector.dart
+++ b/lib/pages/search/search_result_selector.dart
@@ -7,7 +7,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class SearchResultSelector extends StatelessWidget {
-  const SearchResultSelector({Key? key}) : super(key: key);
+  const SearchResultSelector({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/search/search_type.dart b/lib/pages/search/search_type.dart
index 8360f6bfa..6983ca43b 100644
--- a/lib/pages/search/search_type.dart
+++ b/lib/pages/search/search_type.dart
@@ -9,7 +9,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class SearchType extends StatelessWidget {
-  const SearchType({Key? key}) : super(key: key);
+  const SearchType({super.key});
 
   Color getColor(int i) {
     return Settings.themeWhat
diff --git a/lib/pages/segment/filter_page.dart b/lib/pages/segment/filter_page.dart
index 8b98a6d24..9c27be019 100644
--- a/lib/pages/segment/filter_page.dart
+++ b/lib/pages/segment/filter_page.dart
@@ -17,9 +17,9 @@ class FilterPage extends StatefulWidget {
   final List<QueryResult> queryResult;
 
   const FilterPage({
-    Key? key,
+    super.key,
     required this.queryResult,
-  }) : super(key: key);
+  });
 
   @override
   State<FilterPage> createState() => _FilterPageState();
@@ -38,7 +38,7 @@ class _FilterPageState extends State<FilterPage> {
 
   _initTagPad() {
     Map<String, int> tags = <String, int>{};
-    widget.queryResult.forEach((element) {
+    for (var element in widget.queryResult) {
       if (element.tags() != null) {
         element.tags().split('|').forEach((element) {
           if (element == '') return;
@@ -46,7 +46,7 @@ class _FilterPageState extends State<FilterPage> {
           tags[element] = tags[element]! + 1;
         });
       }
-    });
+    }
     _groupCount['tag'] = 0;
     _groupCount['female'] = 0;
     _groupCount['male'] = 0;
@@ -84,7 +84,7 @@ class _FilterPageState extends State<FilterPage> {
     if (!c.groupStates.containsKey(group)) c.groupStates[group] = false;
     _groupCount[group] = 0;
     Map<String, int> tags = <String, int>{};
-    widget.queryResult.forEach((element) {
+    for (var element in widget.queryResult) {
       if (element.result[vv] != null) {
         element.result[vv].split('|').forEach((element) {
           if (element == '') return;
@@ -92,7 +92,7 @@ class _FilterPageState extends State<FilterPage> {
           tags[element] = tags[element]! + 1;
         });
       }
-    });
+    }
     _groupCount[group] = _groupCount[group]! + tags.length;
     tags.forEach((key, value) {
       _tags.add(Tuple3<String, String, int>(group, key, value));
diff --git a/lib/pages/segment/filter_page_controller.dart b/lib/pages/segment/filter_page_controller.dart
index 719b6ede7..09cb9f89b 100644
--- a/lib/pages/segment/filter_page_controller.dart
+++ b/lib/pages/segment/filter_page_controller.dart
@@ -18,7 +18,7 @@ class FilterController {
   List<QueryResult> applyFilter(List<QueryResult> queryResult) {
     final result = <QueryResult>[];
 
-    queryResult.forEach((element) {
+    for (var element in queryResult) {
       // key := <group>:<name>
       var succ = !isOr;
       tagStates.forEach((key, value) {
@@ -54,7 +54,7 @@ class FilterController {
         }
       });
       if (succ) result.add(element);
-    });
+    }
 
     if (isPopulationSort) {
       Population.sortByPopulation(result);
diff --git a/lib/pages/segment/three_article_panel.dart b/lib/pages/segment/three_article_panel.dart
index 9da692835..f00d4ffe7 100644
--- a/lib/pages/segment/three_article_panel.dart
+++ b/lib/pages/segment/three_article_panel.dart
@@ -17,12 +17,12 @@ class ThreeArticlePanel extends StatelessWidget {
   final List<QueryResult> articles;
 
   const ThreeArticlePanel({
-    Key? key,
+    super.key,
     required this.tappedRoute,
     required this.title,
     required this.count,
     required this.articles,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/settings/bookmark_version_select.dart b/lib/pages/settings/bookmark_version_select.dart
index 86b573378..24bb6a7f7 100644
--- a/lib/pages/settings/bookmark_version_select.dart
+++ b/lib/pages/settings/bookmark_version_select.dart
@@ -35,10 +35,10 @@ class BookmarkVersionSelectPage extends StatefulWidget {
   final List<dynamic> versions;
 
   const BookmarkVersionSelectPage({
-    Key? key,
+    super.key,
     required this.userAppId,
     required this.versions,
-  }) : super(key: key);
+  });
 
   @override
   State<BookmarkVersionSelectPage> createState() =>
diff --git a/lib/pages/settings/db_rebuild_page.dart b/lib/pages/settings/db_rebuild_page.dart
index 4286c2a0b..087e4b1c2 100644
--- a/lib/pages/settings/db_rebuild_page.dart
+++ b/lib/pages/settings/db_rebuild_page.dart
@@ -8,7 +8,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class DBRebuildPage extends StatefulWidget {
-  const DBRebuildPage({Key? key}) : super(key: key);
+  const DBRebuildPage({super.key});
 
   @override
   State<DBRebuildPage> createState() => _DBRebuildPagePageState();
diff --git a/lib/pages/settings/import_from_eh.dart b/lib/pages/settings/import_from_eh.dart
index e1a8d4d59..33d10e605 100644
--- a/lib/pages/settings/import_from_eh.dart
+++ b/lib/pages/settings/import_from_eh.dart
@@ -7,7 +7,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class ImportFromEHPage extends StatefulWidget {
-  const ImportFromEHPage({Key? key}) : super(key: key);
+  const ImportFromEHPage({super.key});
 
   @override
   State<ImportFromEHPage> createState() => _ImportFromEHPageState();
diff --git a/lib/pages/settings/libviolet_page.dart b/lib/pages/settings/libviolet_page.dart
index 74deec246..944ea3f8c 100644
--- a/lib/pages/settings/libviolet_page.dart
+++ b/lib/pages/settings/libviolet_page.dart
@@ -7,7 +7,7 @@ import 'package:url_launcher/url_launcher.dart';
 import 'package:violet/settings/settings.dart';
 
 class LibvioletPage extends StatelessWidget {
-  const LibvioletPage({Key? key}) : super(key: key);
+  const LibvioletPage({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/settings/license_page.dart b/lib/pages/settings/license_page.dart
index afce08048..f56a593dd 100644
--- a/lib/pages/settings/license_page.dart
+++ b/lib/pages/settings/license_page.dart
@@ -8,7 +8,7 @@ import 'package:violet/pages/settings/libviolet_page.dart';
 import 'package:violet/settings/settings.dart';
 
 class VioletLicensePage extends StatelessWidget {
-  const VioletLicensePage({Key? key}) : super(key: key);
+  const VioletLicensePage({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/settings/lock_setting_page.dart b/lib/pages/settings/lock_setting_page.dart
index 8ce3e7d5c..973679cd2 100644
--- a/lib/pages/settings/lock_setting_page.dart
+++ b/lib/pages/settings/lock_setting_page.dart
@@ -11,7 +11,7 @@ import 'package:violet/pages/lock/lock_screen.dart';
 import 'package:violet/settings/settings.dart';
 
 class LockSettingPage extends StatefulWidget {
-  const LockSettingPage({Key? key}) : super(key: key);
+  const LockSettingPage({super.key});
 
   @override
   State<LockSettingPage> createState() => _LockSettingPageState();
diff --git a/lib/pages/settings/log_page.dart b/lib/pages/settings/log_page.dart
index 72adfb1e5..d40591ca8 100644
--- a/lib/pages/settings/log_page.dart
+++ b/lib/pages/settings/log_page.dart
@@ -6,7 +6,7 @@ import 'package:violet/log/log.dart';
 import 'package:violet/other/dialogs.dart';
 
 class LogPage extends StatefulWidget {
-  const LogPage({Key? key}) : super(key: key);
+  const LogPage({super.key});
 
   @override
   State<LogPage> createState() => _LogPageState();
diff --git a/lib/pages/settings/login/ehentai_login.dart b/lib/pages/settings/login/ehentai_login.dart
index 835d6e0cf..14e8e686f 100644
--- a/lib/pages/settings/login/ehentai_login.dart
+++ b/lib/pages/settings/login/ehentai_login.dart
@@ -30,7 +30,7 @@ Map<String, String> parseCookies(String cookies) {
 // Or cookie?
 
 class LoginScreen extends StatefulWidget {
-  const LoginScreen({Key? key}) : super(key: key);
+  const LoginScreen({super.key});
 
   @override
   State<LoginScreen> createState() => _LoginScreenState();
diff --git a/lib/pages/settings/restore_bookmark.dart b/lib/pages/settings/restore_bookmark.dart
index 7e44fb3ed..4825cdbde 100644
--- a/lib/pages/settings/restore_bookmark.dart
+++ b/lib/pages/settings/restore_bookmark.dart
@@ -17,10 +17,10 @@ class RestoreBookmarkPage extends StatefulWidget {
   final bool restoreWithRecord;
 
   const RestoreBookmarkPage({
-    Key? key,
+    super.key,
     required this.source,
     required this.restoreWithRecord,
-  }) : super(key: key);
+  });
 
   @override
   State<RestoreBookmarkPage> createState() => _RestoreBookmarkPageState();
diff --git a/lib/pages/settings/route.dart b/lib/pages/settings/route.dart
index 24b3f88d9..16d31e4c5 100644
--- a/lib/pages/settings/route.dart
+++ b/lib/pages/settings/route.dart
@@ -6,7 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart';
 import 'package:violet/settings/settings.dart';
 
 class RouteDialog extends StatefulWidget {
-  const RouteDialog({Key? key}) : super(key: key);
+  const RouteDialog({super.key});
 
   @override
   State<RouteDialog> createState() => _RouteDialogState();
@@ -71,7 +71,7 @@ class _RouteDialogState extends State<RouteDialog> {
 }
 
 class ImageRouteDialog extends StatefulWidget {
-  const ImageRouteDialog({Key? key}) : super(key: key);
+  const ImageRouteDialog({super.key});
 
   @override
   State<ImageRouteDialog> createState() => _ImageRouteDialogState();
diff --git a/lib/pages/settings/settings_page.dart b/lib/pages/settings/settings_page.dart
index 475114971..3ff9e5295 100644
--- a/lib/pages/settings/settings_page.dart
+++ b/lib/pages/settings/settings_page.dart
@@ -146,7 +146,7 @@ class ExCountry extends Country {
 }
 
 class SettingsPage extends StatefulWidget {
-  const SettingsPage({Key? key}) : super(key: key);
+  const SettingsPage({super.key});
 
   @override
   State<SettingsPage> createState() => _SettingsPageState();
@@ -2044,9 +2044,9 @@ class _SettingsPageState extends State<SettingsPage>
               }
 
               int count = 0;
-              EHBookmark.bookmarkInfo!.forEach((element) {
+              for (var element in EHBookmark.bookmarkInfo!) {
                 count += element.length;
-              });
+              }
 
               var qqq = await showYesNoDialog(
                   context,
diff --git a/lib/pages/settings/tag_rebuild_page.dart b/lib/pages/settings/tag_rebuild_page.dart
index e7bb822a7..7e5ab9b10 100644
--- a/lib/pages/settings/tag_rebuild_page.dart
+++ b/lib/pages/settings/tag_rebuild_page.dart
@@ -13,7 +13,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/style/palette.dart';
 
 class TagRebuildPage extends StatefulWidget {
-  const TagRebuildPage({Key? key}) : super(key: key);
+  const TagRebuildPage({super.key});
 
   @override
   State<TagRebuildPage> createState() => _TagRebuildPageState();
diff --git a/lib/pages/settings/tag_selector.dart b/lib/pages/settings/tag_selector.dart
index 9c0a5c5c2..918e4b18d 100644
--- a/lib/pages/settings/tag_selector.dart
+++ b/lib/pages/settings/tag_selector.dart
@@ -12,8 +12,7 @@ class TagSelectorDialog extends StatefulWidget {
   final String what;
   final bool onlyFMT;
 
-  const TagSelectorDialog({Key? key, required this.what, this.onlyFMT = false})
-      : super(key: key);
+  const TagSelectorDialog({super.key, required this.what, this.onlyFMT = false});
 
   @override
   State<TagSelectorDialog> createState() => _TagSelectorDialogState();
diff --git a/lib/pages/settings/version_page.dart b/lib/pages/settings/version_page.dart
index a7a731d33..7b45213c7 100644
--- a/lib/pages/settings/version_page.dart
+++ b/lib/pages/settings/version_page.dart
@@ -7,7 +7,7 @@ import 'package:violet/settings/settings.dart';
 import 'package:violet/version/update_sync.dart';
 
 class VersionViewPage extends StatelessWidget {
-  const VersionViewPage({Key? key}) : super(key: key);
+  const VersionViewPage({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/splash/splash_page.dart b/lib/pages/splash/splash_page.dart
index 5d451fd79..bb3130761 100644
--- a/lib/pages/splash/splash_page.dart
+++ b/lib/pages/splash/splash_page.dart
@@ -38,14 +38,14 @@ import 'package:violet/version/sync.dart';
 
 class RadioTile<T> extends StatefulWidget {
   const RadioTile({
-    Key? key,
+    super.key,
     required this.value,
     required this.groupValue,
     required this.setGroupValue,
     required this.title,
     required this.subtitle,
     required this.onLongPress,
-  }) : super(key: key);
+  });
 
   final T value;
   final T groupValue;
@@ -128,7 +128,7 @@ class _RadioTileState<T> extends State<RadioTile<T>> {
 class SplashPage extends StatefulWidget {
   final bool switching;
 
-  const SplashPage({Key? key, this.switching = false}) : super(key: key);
+  const SplashPage({super.key, this.switching = false});
 
   @override
   State<SplashPage> createState() => _SplashPageState();
diff --git a/lib/pages/viewer/double_viewer_page.dart b/lib/pages/viewer/double_viewer_page.dart
index f9cffd30e..6f67c69e1 100644
--- a/lib/pages/viewer/double_viewer_page.dart
+++ b/lib/pages/viewer/double_viewer_page.dart
@@ -4,7 +4,7 @@
 import 'package:flutter/material.dart';
 
 class DoubleViewerPage extends StatefulWidget {
-  const DoubleViewerPage({Key? key}) : super(key: key);
+  const DoubleViewerPage({super.key});
 
   @override
   State<DoubleViewerPage> createState() => _DoubleViewerPageState();
diff --git a/lib/pages/viewer/horizontal_viewer_page.dart b/lib/pages/viewer/horizontal_viewer_page.dart
index c0a3f5719..e63d474d2 100644
--- a/lib/pages/viewer/horizontal_viewer_page.dart
+++ b/lib/pages/viewer/horizontal_viewer_page.dart
@@ -16,9 +16,9 @@ import 'package:violet/settings/settings_wrapper.dart';
 class HorizontalViewerPage extends StatefulWidget {
   final String getxId;
   const HorizontalViewerPage({
-    Key? key,
+    super.key,
     required this.getxId,
-  }) : super(key: key);
+  });
 
   @override
   State<HorizontalViewerPage> createState() => _HorizontalViewerPageState();
diff --git a/lib/pages/viewer/image/file_image.dart b/lib/pages/viewer/image/file_image.dart
index cd00ebedd..3eceaabf4 100644
--- a/lib/pages/viewer/image/file_image.dart
+++ b/lib/pages/viewer/image/file_image.dart
@@ -18,12 +18,12 @@ class FileImage extends StatefulWidget {
   final DoubleCallback? heightCallback;
 
   const FileImage({
-    Key? key,
+    super.key,
     required this.getxId,
     required this.path,
     this.heightCallback,
     this.cachedHeight,
-  }) : super(key: key);
+  });
 
   @override
   State<FileImage> createState() => _FileImageState();
diff --git a/lib/pages/viewer/image/provider_image.dart b/lib/pages/viewer/image/provider_image.dart
index 01fc5e429..561037097 100644
--- a/lib/pages/viewer/image/provider_image.dart
+++ b/lib/pages/viewer/image/provider_image.dart
@@ -34,14 +34,14 @@ class ProviderImage extends StatefulWidget {
   final int index;
 
   const ProviderImage({
-    Key? key,
+    super.key,
     required this.getxId,
     required this.imgKey,
     required this.imgUrl,
     required this.imgHeader,
     required this.imageWidgetBuilder,
     required this.index,
-  }) : super(key: key);
+  });
 
   @override
   State<ProviderImage> createState() => _ProviderImageState();
diff --git a/lib/pages/viewer/others/photo_view_gallery.dart b/lib/pages/viewer/others/photo_view_gallery.dart
index fb285883b..5d3cb0a2e 100644
--- a/lib/pages/viewer/others/photo_view_gallery.dart
+++ b/lib/pages/viewer/others/photo_view_gallery.dart
@@ -91,7 +91,7 @@ typedef PhotoViewGalleryBuilder = PhotoViewGalleryPageOptions Function(
 class VPhotoViewGallery extends StatefulWidget {
   /// Construct a gallery with static items through a list of [PhotoViewGalleryPageOptions].
   const VPhotoViewGallery({
-    Key? key,
+    super.key,
     this.pageOptions,
     this.loadingBuilder,
     this.backgroundDecoration,
@@ -105,14 +105,13 @@ class VPhotoViewGallery extends StatefulWidget {
     this.scrollDirection = Axis.horizontal,
     this.customSize,
   })  : itemCount = null,
-        builder = null,
-        super(key: key);
+        builder = null;
 
   /// Construct a gallery with dynamic items.
   ///
   /// The builder must return a [PhotoViewGalleryPageOptions].
   const VPhotoViewGallery.builder({
-    Key? key,
+    super.key,
     this.itemCount,
     this.builder,
     this.loadingBuilder,
@@ -128,8 +127,7 @@ class VPhotoViewGallery extends StatefulWidget {
     this.customSize,
   })  : pageOptions = null,
         assert(itemCount != null),
-        assert(builder != null),
-        super(key: key);
+        assert(builder != null);
 
   /// A list of options to describe the items in the gallery
   final List<PhotoViewGalleryPageOptions>? pageOptions;
diff --git a/lib/pages/viewer/others/preload_page_view.dart b/lib/pages/viewer/others/preload_page_view.dart
index 6254c4812..92b484910 100644
--- a/lib/pages/viewer/others/preload_page_view.dart
+++ b/lib/pages/viewer/others/preload_page_view.dart
@@ -798,21 +798,14 @@ class PreloadPageController extends ScrollController {
 class PageMetrics extends FixedScrollMetrics {
   /// Creates an immutable snapshot of values associated with a [PreloadPageView].
   PageMetrics({
-    required double? minScrollExtent,
-    required double? maxScrollExtent,
-    required double? pixels,
-    required double? viewportDimension,
-    required double devicePixelRatio,
-    required AxisDirection axisDirection,
+    required super.minScrollExtent,
+    required super.maxScrollExtent,
+    required super.pixels,
+    required super.viewportDimension,
+    required super.devicePixelRatio,
+    required super.axisDirection,
     required this.viewportFraction,
-  }) : super(
-          minScrollExtent: minScrollExtent,
-          maxScrollExtent: maxScrollExtent,
-          pixels: pixels,
-          viewportDimension: viewportDimension,
-          axisDirection: axisDirection,
-          devicePixelRatio: devicePixelRatio,
-        );
+  });
 
   @override
   PageMetrics copyWith({
@@ -850,21 +843,18 @@ class PageMetrics extends FixedScrollMetrics {
 class _PagePosition extends ScrollPositionWithSingleContext
     implements PageMetrics {
   _PagePosition({
-    required ScrollPhysics physics,
-    required ScrollContext context,
+    required super.physics,
+    required super.context,
     this.initialPage = 0,
     bool keepPage = true,
     double viewportFraction = 1.0,
-    ScrollPosition? oldPosition,
+    super.oldPosition,
   })  : assert(viewportFraction > 0.0),
         _viewportFraction = viewportFraction,
         _pageToUseOnStartup = initialPage.toDouble(),
         super(
-          physics: physics,
-          context: context,
           initialPixels: null,
           keepScrollOffset: keepPage,
-          oldPosition: oldPosition,
         );
 
   final int initialPage;
@@ -975,7 +965,7 @@ class _PagePosition extends ScrollPositionWithSingleContext
 ///  * [PreloadPageView.physics], which can override the physics used by a page view.
 class PageScrollPhysics extends ScrollPhysics {
   /// Creates physics for a [PreloadPageView].
-  const PageScrollPhysics({ScrollPhysics? parent}) : super(parent: parent);
+  const PageScrollPhysics({super.parent});
 
   @override
   PageScrollPhysics applyTo(ScrollPhysics? ancestor) {
@@ -1066,7 +1056,7 @@ class PreloadPageView extends StatefulWidget {
   /// child that could possibly be displayed in the page view, instead of just
   /// those children that are actually visible.
   PreloadPageView({
-    Key? key,
+    super.key,
     this.scrollDirection = Axis.horizontal,
     this.reverse = false,
     PreloadPageController? controller,
@@ -1076,8 +1066,7 @@ class PreloadPageView extends StatefulWidget {
     List<Widget> children = const <Widget>[],
     this.preloadPagesCount = 1,
   })  : controller = controller ?? _defaultPageController,
-        childrenDelegate = SliverChildListDelegate(children),
-        super(key: key);
+        childrenDelegate = SliverChildListDelegate(children);
 
   /// Creates a scrollable list that works page by page using widgets that are
   /// created on demand.
@@ -1094,7 +1083,7 @@ class PreloadPageView extends StatefulWidget {
   ///
   /// You can add [preloadPagesCount] for PreloadPageView if you want preload multiple pages
   PreloadPageView.builder({
-    Key? key,
+    super.key,
     this.scrollDirection = Axis.horizontal,
     this.reverse = false,
     PreloadPageController? controller,
@@ -1106,13 +1095,12 @@ class PreloadPageView extends StatefulWidget {
     this.preloadPagesCount = 1,
   })  : controller = controller ?? _defaultPageController,
         childrenDelegate =
-            SliverChildBuilderDelegate(itemBuilder, childCount: itemCount),
-        super(key: key);
+            SliverChildBuilderDelegate(itemBuilder, childCount: itemCount);
 
   /// Creates a scrollable list that works page by page with a custom child
   /// model.
   PreloadPageView.custom({
-    Key? key,
+    super.key,
     this.scrollDirection = Axis.horizontal,
     this.reverse = false,
     PreloadPageController? controller,
@@ -1123,8 +1111,7 @@ class PreloadPageView extends StatefulWidget {
     this.preloadPagesCount = 1,
   })  : assert(preloadPagesCount >= 0,
             'preloadPagesCount cannot be less than 0. Actual value: $preloadPagesCount'),
-        controller = controller ?? _defaultPageController,
-        super(key: key);
+        controller = controller ?? _defaultPageController;
 
   /// The axis along which the page view scrolls.
   ///
diff --git a/lib/pages/viewer/others/scrollable_positioned_list/src/element_registry.dart b/lib/pages/viewer/others/scrollable_positioned_list/src/element_registry.dart
index 08692197f..946d45351 100644
--- a/lib/pages/viewer/others/scrollable_positioned_list/src/element_registry.dart
+++ b/lib/pages/viewer/others/scrollable_positioned_list/src/element_registry.dart
@@ -7,8 +7,7 @@ import 'package:flutter/widgets.dart';
 /// A registry to track some [Element]s in the tree.
 class RegistryWidget extends StatefulWidget {
   /// Creates a [RegistryWidget].
-  const RegistryWidget({Key? key, this.elementNotifier, required this.child})
-      : super(key: key);
+  const RegistryWidget({super.key, this.elementNotifier, required this.child});
 
   /// The widget below this widget in the tree.
   final Widget child;
@@ -28,8 +27,7 @@ class RegistryWidget extends StatefulWidget {
 /// [RegistryWidget].
 class RegisteredElementWidget extends ProxyWidget {
   /// Creates a [RegisteredElementWidget].
-  const RegisteredElementWidget({Key? key, required Widget child})
-      : super(key: key, child: child);
+  const RegisteredElementWidget({super.key, required super.child});
 
   @override
   Element createElement() => _RegisteredElement(this);
@@ -48,16 +46,14 @@ class _RegistryWidgetState extends State<RegistryWidget> {
 class _InheritedRegistryWidget extends InheritedWidget {
   final _RegistryWidgetState state;
 
-  const _InheritedRegistryWidget(
-      {Key? key, required this.state, required Widget child})
-      : super(key: key, child: child);
+  const _InheritedRegistryWidget({required this.state, required super.child});
 
   @override
   bool updateShouldNotify(InheritedWidget oldWidget) => true;
 }
 
 class _RegisteredElement extends ProxyElement {
-  _RegisteredElement(ProxyWidget widget) : super(widget);
+  _RegisteredElement(super.widget);
 
   @override
   void notifyClients(ProxyWidget oldWidget) {}
diff --git a/lib/pages/viewer/others/scrollable_positioned_list/src/positioned_list.dart b/lib/pages/viewer/others/scrollable_positioned_list/src/positioned_list.dart
index d22a6b6df..e289c3a04 100644
--- a/lib/pages/viewer/others/scrollable_positioned_list/src/positioned_list.dart
+++ b/lib/pages/viewer/others/scrollable_positioned_list/src/positioned_list.dart
@@ -25,7 +25,7 @@ import 'package:violet/pages/viewer/others/scrollable_positioned_list/src/wrappi
 class PositionedList extends StatefulWidget {
   /// Create a [PositionedList].
   const PositionedList({
-    Key? key,
+    super.key,
     required this.itemCount,
     required this.itemBuilder,
     this.separatorBuilder,
@@ -43,8 +43,7 @@ class PositionedList extends StatefulWidget {
     this.addSemanticIndexes = true,
     this.addRepaintBoundaries = true,
     this.addAutomaticKeepAlives = true,
-  })  : assert((positionedIndex == 0) || (positionedIndex < itemCount)),
-        super(key: key);
+  })  : assert((positionedIndex == 0) || (positionedIndex < itemCount));
 
   /// Number of items the [itemBuilder] can produce.
   final int itemCount;
diff --git a/lib/pages/viewer/others/scrollable_positioned_list/src/post_mount_callback.dart b/lib/pages/viewer/others/scrollable_positioned_list/src/post_mount_callback.dart
index 9ec553fa7..dde2874b8 100644
--- a/lib/pages/viewer/others/scrollable_positioned_list/src/post_mount_callback.dart
+++ b/lib/pages/viewer/others/scrollable_positioned_list/src/post_mount_callback.dart
@@ -7,8 +7,7 @@ import 'package:flutter/widgets.dart';
 /// Widget whose [Element] calls a callback when the element is mounted.
 class PostMountCallback extends StatelessWidget {
   /// Creates a [PostMountCallback] widget.
-  const PostMountCallback({required this.child, this.callback, Key? key})
-      : super(key: key);
+  const PostMountCallback({required this.child, this.callback, super.key});
 
   /// The widget below this widget in the tree.
   final Widget child;
@@ -24,7 +23,7 @@ class PostMountCallback extends StatelessWidget {
 }
 
 class _PostMountCallbackElement extends StatelessElement {
-  _PostMountCallbackElement(PostMountCallback widget) : super(widget);
+  _PostMountCallbackElement(PostMountCallback super.widget);
 
   @override
   void mount(Element? parent, dynamic newSlot) {
diff --git a/lib/pages/viewer/others/scrollable_positioned_list/src/scroll_view.dart b/lib/pages/viewer/others/scrollable_positioned_list/src/scroll_view.dart
index 40ad147c2..36ec66429 100644
--- a/lib/pages/viewer/others/scrollable_positioned_list/src/scroll_view.dart
+++ b/lib/pages/viewer/others/scrollable_positioned_list/src/scroll_view.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:flutter/gestures.dart';
 import 'package:flutter/rendering.dart';
 import 'package:flutter/widgets.dart';
 import 'package:violet/pages/viewer/others/scrollable_positioned_list/src/viewport.dart';
@@ -14,34 +13,23 @@ class UnboundedCustomScrollView extends CustomScrollView {
   final bool _shrinkWrap;
 
   const UnboundedCustomScrollView({
-    Key? key,
-    Axis scrollDirection = Axis.vertical,
-    bool reverse = false,
-    ScrollController? controller,
-    bool? primary,
-    ScrollPhysics? physics,
+    super.key,
+    super.scrollDirection,
+    super.reverse,
+    super.controller,
+    super.primary,
+    super.physics,
     bool shrinkWrap = false,
-    Key? center,
+    super.center,
     double anchor = 0.0,
-    double? cacheExtent,
-    List<Widget> slivers = const <Widget>[],
-    int? semanticChildCount,
-    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
+    super.cacheExtent,
+    super.slivers,
+    super.semanticChildCount,
+    super.dragStartBehavior,
   })  : _shrinkWrap = shrinkWrap,
         _anchor = anchor,
         super(
-          key: key,
-          scrollDirection: scrollDirection,
-          reverse: reverse,
-          controller: controller,
-          primary: primary,
-          physics: physics,
           shrinkWrap: false,
-          center: center,
-          cacheExtent: cacheExtent,
-          semanticChildCount: semanticChildCount,
-          dragStartBehavior: dragStartBehavior,
-          slivers: slivers,
         );
 
   // [CustomScrollView] enforces constraints on [CustomScrollView.anchor], so
diff --git a/lib/pages/viewer/others/scrollable_positioned_list/src/scrollable_positioned_list.dart b/lib/pages/viewer/others/scrollable_positioned_list/src/scrollable_positioned_list.dart
index f30d42c89..e2d4ad6e5 100644
--- a/lib/pages/viewer/others/scrollable_positioned_list/src/scrollable_positioned_list.dart
+++ b/lib/pages/viewer/others/scrollable_positioned_list/src/scrollable_positioned_list.dart
@@ -35,7 +35,7 @@ class ScrollablePositionedList extends StatefulWidget {
   const ScrollablePositionedList.builder({
     required this.itemCount,
     required this.itemBuilder,
-    Key? key,
+    super.key,
     this.itemScrollController,
     this.shrinkWrap = false,
     ItemPositionsListener? itemPositionsListener,
@@ -51,8 +51,7 @@ class ScrollablePositionedList extends StatefulWidget {
     this.addRepaintBoundaries = true,
     this.minCacheExtent,
   })  : itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?,
-        separatorBuilder = null,
-        super(key: key);
+        separatorBuilder = null;
 
   /// Create a [ScrollablePositionedList] whose items are provided by
   /// [itemBuilder] and separators provided by [separatorBuilder].
@@ -60,7 +59,7 @@ class ScrollablePositionedList extends StatefulWidget {
     required this.itemCount,
     required this.itemBuilder,
     required this.separatorBuilder,
-    Key? key,
+    super.key,
     this.shrinkWrap = false,
     this.itemScrollController,
     ItemPositionsListener? itemPositionsListener,
@@ -76,8 +75,7 @@ class ScrollablePositionedList extends StatefulWidget {
     this.addRepaintBoundaries = true,
     this.minCacheExtent,
   })  : assert(separatorBuilder != null),
-        itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?,
-        super(key: key);
+        itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?;
 
   /// Number of items the [itemBuilder] can produce.
   final int itemCount;
diff --git a/lib/pages/viewer/others/scrollable_positioned_list/src/viewport.dart b/lib/pages/viewer/others/scrollable_positioned_list/src/viewport.dart
index 40abf9231..ce0181a49 100644
--- a/lib/pages/viewer/others/scrollable_positioned_list/src/viewport.dart
+++ b/lib/pages/viewer/others/scrollable_positioned_list/src/viewport.dart
@@ -14,23 +14,15 @@ import 'package:flutter/widgets.dart';
 /// for more information.
 class UnboundedViewport extends Viewport {
   UnboundedViewport({
-    Key? key,
-    AxisDirection axisDirection = AxisDirection.down,
-    AxisDirection? crossAxisDirection,
+    super.key,
+    super.axisDirection,
+    super.crossAxisDirection,
     double anchor = 0.0,
-    required ViewportOffset offset,
-    Key? center,
-    double? cacheExtent,
-    List<Widget> slivers = const <Widget>[],
-  })  : _anchor = anchor,
-        super(
-            key: key,
-            axisDirection: axisDirection,
-            crossAxisDirection: crossAxisDirection,
-            offset: offset,
-            center: center,
-            cacheExtent: cacheExtent,
-            slivers: slivers);
+    required super.offset,
+    super.center,
+    super.cacheExtent,
+    super.slivers,
+  })  : _anchor = anchor;
 
   // [Viewport] enforces constraints on [Viewport.anchor], so we need our own
   // version.
@@ -63,21 +55,14 @@ class UnboundedViewport extends Viewport {
 class UnboundedRenderViewport extends RenderViewport {
   /// Creates a viewport for [RenderSliver] objects.
   UnboundedRenderViewport({
-    AxisDirection axisDirection = AxisDirection.down,
-    required AxisDirection crossAxisDirection,
-    required ViewportOffset offset,
+    super.axisDirection,
+    required super.crossAxisDirection,
+    required super.offset,
     double anchor = 0.0,
-    List<RenderSliver>? children,
-    RenderSliver? center,
-    double? cacheExtent,
-  })  : _anchor = anchor,
-        super(
-            axisDirection: axisDirection,
-            crossAxisDirection: crossAxisDirection,
-            offset: offset,
-            center: center,
-            cacheExtent: cacheExtent,
-            children: children);
+    super.children,
+    super.center,
+    super.cacheExtent,
+  })  : _anchor = anchor;
 
   static const int _maxLayoutCycles = 10;
 
diff --git a/lib/pages/viewer/others/scrollable_positioned_list/src/wrapping.dart b/lib/pages/viewer/others/scrollable_positioned_list/src/wrapping.dart
index f806aa0aa..57b482421 100644
--- a/lib/pages/viewer/others/scrollable_positioned_list/src/wrapping.dart
+++ b/lib/pages/viewer/others/scrollable_positioned_list/src/wrapping.dart
@@ -37,24 +37,16 @@ class CustomShrinkWrappingViewport extends CustomViewport {
   ///
   /// The [offset] argument must not be null.
   CustomShrinkWrappingViewport({
-    Key? key,
-    AxisDirection axisDirection = AxisDirection.down,
-    AxisDirection? crossAxisDirection,
+    super.key,
+    super.axisDirection,
+    super.crossAxisDirection,
     double anchor = 0.0,
-    required ViewportOffset offset,
+    required super.offset,
     List<RenderSliver>? children,
-    Key? center,
-    double? cacheExtent,
-    List<Widget> slivers = const <Widget>[],
-  })  : _anchor = anchor,
-        super(
-            key: key,
-            axisDirection: axisDirection,
-            crossAxisDirection: crossAxisDirection,
-            offset: offset,
-            center: center,
-            cacheExtent: cacheExtent,
-            slivers: slivers);
+    super.center,
+    super.cacheExtent,
+    super.slivers,
+  })  : _anchor = anchor;
 
   // [Viewport] enforces constraints on [Viewport.anchor], so we need our own
   // version.
@@ -122,22 +114,14 @@ class CustomRenderShrinkWrappingViewport extends CustomRenderViewport {
   /// The [offset] must be specified. For testing purposes, consider passing a
   /// [ViewportOffset.zero] or [ViewportOffset.fixed].
   CustomRenderShrinkWrappingViewport({
-    AxisDirection axisDirection = AxisDirection.down,
-    required AxisDirection crossAxisDirection,
-    required ViewportOffset offset,
+    super.axisDirection,
+    required super.crossAxisDirection,
+    required super.offset,
     double anchor = 0.0,
-    List<RenderSliver>? children,
-    RenderSliver? center,
-    double? cacheExtent,
-  })  : _anchor = anchor,
-        super(
-          axisDirection: axisDirection,
-          crossAxisDirection: crossAxisDirection,
-          offset: offset,
-          center: center,
-          cacheExtent: cacheExtent,
-          children: children,
-        );
+    super.children,
+    super.center,
+    super.cacheExtent,
+  })  : _anchor = anchor;
 
   double _anchor;
 
@@ -409,7 +393,7 @@ abstract class CustomViewport extends MultiChildRenderObjectWidget {
   /// The [cacheExtent] must be specified if the [cacheExtentStyle] is
   /// not [CacheExtentStyle.pixel].
   CustomViewport({
-    Key? key,
+    super.key,
     this.axisDirection = AxisDirection.down,
     this.crossAxisDirection,
     this.anchor = 0.0,
@@ -423,7 +407,7 @@ abstract class CustomViewport extends MultiChildRenderObjectWidget {
             slivers.where((Widget child) => child.key == center).length == 1),
         assert(cacheExtentStyle != CacheExtentStyle.viewport ||
             cacheExtent != null),
-        super(key: key, children: slivers);
+        super(children: slivers);
 
   /// The direction in which the [offset]'s [ViewportOffset.pixels] increases.
   ///
@@ -548,7 +532,7 @@ abstract class CustomViewport extends MultiChildRenderObjectWidget {
 
 class ViewportElement extends MultiChildRenderObjectElement {
   /// Creates an element that uses the given widget as its configuration.
-  ViewportElement(CustomViewport widget) : super(widget);
+  ViewportElement(CustomViewport super.widget);
 
   @override
   CustomViewport get widget => super.widget as CustomViewport;
@@ -648,27 +632,19 @@ abstract class CustomRenderViewport
   /// The [offset] must be specified. For testing purposes, consider passing a
   /// [ViewportOffset.zero] or [ViewportOffset.fixed].
   CustomRenderViewport({
-    AxisDirection axisDirection = AxisDirection.down,
-    required AxisDirection crossAxisDirection,
-    required ViewportOffset offset,
+    super.axisDirection,
+    required super.crossAxisDirection,
+    required super.offset,
     double anchor = 0.0,
     List<RenderSliver>? children,
     RenderSliver? center,
-    double? cacheExtent,
-    CacheExtentStyle cacheExtentStyle = CacheExtentStyle.pixel,
-    Clip clipBehavior = Clip.hardEdge,
+    super.cacheExtent,
+    super.cacheExtentStyle,
+    super.clipBehavior,
   })  : assert(anchor >= 0.0 && anchor <= 1.0),
         assert(cacheExtentStyle != CacheExtentStyle.viewport ||
             cacheExtent != null),
-        _center = center,
-        super(
-          axisDirection: axisDirection,
-          crossAxisDirection: crossAxisDirection,
-          offset: offset,
-          cacheExtent: cacheExtent,
-          cacheExtentStyle: cacheExtentStyle,
-          clipBehavior: clipBehavior,
-        ) {
+        _center = center {
     addAll(children);
     if (center == null && firstChild != null) _center = firstChild;
   }
diff --git a/lib/pages/viewer/overlay/page_label.dart b/lib/pages/viewer/overlay/page_label.dart
index 2e79a03d4..5ab25479c 100644
--- a/lib/pages/viewer/overlay/page_label.dart
+++ b/lib/pages/viewer/overlay/page_label.dart
@@ -10,7 +10,7 @@ import 'package:violet/pages/viewer/viewer_controller.dart';
 class PageLabel extends StatelessWidget {
   late final ViewerController c;
 
-  PageLabel({Key? key, required String getxId}) : super(key: key) {
+  PageLabel({super.key, required String getxId}) {
     c = Get.find(tag: getxId);
   }
 
diff --git a/lib/pages/viewer/overlay/viewer_gallery.dart b/lib/pages/viewer/overlay/viewer_gallery.dart
index 39f4952a3..9be224c10 100644
--- a/lib/pages/viewer/overlay/viewer_gallery.dart
+++ b/lib/pages/viewer/overlay/viewer_gallery.dart
@@ -16,7 +16,7 @@ import 'package:violet/widgets/search_bar.dart';
 class ViewerGallery extends StatefulWidget {
   final int viewedPage;
 
-  const ViewerGallery({Key? key, required this.viewedPage}) : super(key: key);
+  const ViewerGallery({super.key, required this.viewedPage});
 
   @override
   State<ViewerGallery> createState() => _ViewerGalleryState();
@@ -30,10 +30,11 @@ class _ViewerGalleryState extends State<ViewerGallery> {
   @override
   void didChangeDependencies() {
     super.didChangeDependencies();
+
     _pageInfo = Provider.of<ViewerPageProvider>(context);
-    List.generate(_pageInfo.uris.length, (index) => index).forEach((element) {
-      itemKeys.add(GlobalKey());
-    });
+    itemKeys.addAll(
+      Iterable.generate(_pageInfo.uris.length, (index) => GlobalKey()),
+    );
 
     Future.value(1).then((value) {
       var row = widget.viewedPage ~/ 4;
diff --git a/lib/pages/viewer/overlay/viewer_overlay.dart b/lib/pages/viewer/overlay/viewer_overlay.dart
index 4061369e5..597752c1d 100644
--- a/lib/pages/viewer/overlay/viewer_overlay.dart
+++ b/lib/pages/viewer/overlay/viewer_overlay.dart
@@ -40,9 +40,9 @@ class ViewerOverlay extends StatefulWidget {
   final String getxId;
 
   const ViewerOverlay({
-    Key? key,
+    super.key,
     required this.getxId,
-  }) : super(key: key);
+  });
 
   @override
   State<ViewerOverlay> createState() => _ViewerOverlayState();
diff --git a/lib/pages/viewer/overlay/viewer_record_panel.dart b/lib/pages/viewer/overlay/viewer_record_panel.dart
index ca834dc85..cebd4dcc4 100644
--- a/lib/pages/viewer/overlay/viewer_record_panel.dart
+++ b/lib/pages/viewer/overlay/viewer_record_panel.dart
@@ -11,8 +11,7 @@ import 'package:violet/variables.dart';
 class ViewerRecordPanel extends StatefulWidget {
   final int articleId;
 
-  const ViewerRecordPanel({Key? key, required this.articleId})
-      : super(key: key);
+  const ViewerRecordPanel({super.key, required this.articleId});
 
   @override
   State<ViewerRecordPanel> createState() => _ViewerRecordPanelState();
diff --git a/lib/pages/viewer/overlay/viewer_setting_panel.dart b/lib/pages/viewer/overlay/viewer_setting_panel.dart
index c3031be5b..8eaee4eb8 100644
--- a/lib/pages/viewer/overlay/viewer_setting_panel.dart
+++ b/lib/pages/viewer/overlay/viewer_setting_panel.dart
@@ -18,11 +18,11 @@ class ViewerSettingPanel extends StatefulWidget {
   final VoidCallback thumbSizeChangeEvent;
 
   const ViewerSettingPanel({
-    Key? key,
+    super.key,
     required this.viewerStyleChangeEvent,
     required this.thumbSizeChangeEvent,
     required this.getxId,
-  }) : super(key: key);
+  });
 
   @override
   State<ViewerSettingPanel> createState() => _ViewerSettingPanelState();
diff --git a/lib/pages/viewer/overlay/viewer_tab_panel.dart b/lib/pages/viewer/overlay/viewer_tab_panel.dart
index 7ca6c85bf..f25dc523b 100644
--- a/lib/pages/viewer/overlay/viewer_tab_panel.dart
+++ b/lib/pages/viewer/overlay/viewer_tab_panel.dart
@@ -31,11 +31,11 @@ class ViewerTabPanel extends StatefulWidget {
   final List<QueryResult>? usableTabList;
 
   const ViewerTabPanel({
-    Key? key,
+    super.key,
     required this.articleId,
     this.usableTabList,
     required this.height,
-  }) : super(key: key);
+  });
 
   @override
   State<ViewerTabPanel> createState() => _ViewerTabPanelState();
@@ -151,8 +151,9 @@ class __UsableTabListState extends State<_UsableTabList>
   void initState() {
     super.initState();
 
-    widget.usableTabList
-        .forEach((element) => itemKeys[element.id()] = GlobalKey());
+    for (var element in widget.usableTabList) {
+      itemKeys[element.id()] = GlobalKey();
+    }
 
     Future.value(1).then((value) {
       var row = widget.usableTabList
@@ -291,7 +292,9 @@ class __ArtistsArticleTabListState extends State<_ArtistsArticleTabList>
       }
 
       articleList = queryResult;
-      articleList.forEach((element) => itemKeys[element.id()] = GlobalKey());
+      for (var element in articleList) {
+        itemKeys[element.id()] = GlobalKey();
+      }
 
       setState(() => isLoaded = true);
 
diff --git a/lib/pages/viewer/overlay/viewer_thumbnails.dart b/lib/pages/viewer/overlay/viewer_thumbnails.dart
index 15fd81519..1e5ec3cb1 100644
--- a/lib/pages/viewer/overlay/viewer_thumbnails.dart
+++ b/lib/pages/viewer/overlay/viewer_thumbnails.dart
@@ -22,7 +22,7 @@ import 'package:violet/widgets/article_item/image_provider_manager.dart';
 class ViewerThumbnail extends StatefulWidget {
   final int viewedPage;
 
-  const ViewerThumbnail({Key? key, required this.viewedPage}) : super(key: key);
+  const ViewerThumbnail({super.key, required this.viewedPage});
 
   @override
   State<ViewerThumbnail> createState() => _ViewerThumbnailState();
@@ -38,9 +38,9 @@ class _ViewerThumbnailState extends State<ViewerThumbnail> {
     super.didChangeDependencies();
 
     _pageInfo = Provider.of<ViewerPageProvider>(context);
-    List.generate(_pageInfo.uris.length, (index) => index).forEach((element) {
-      itemKeys.add(GlobalKey());
-    });
+    itemKeys.addAll(
+      Iterable.generate(_pageInfo.uris.length, (index) => GlobalKey()),
+    );
 
     if (_pageInfo.useFileSystem) _jumpToViewedPage();
   }
diff --git a/lib/pages/viewer/vertical_viewer_page.dart b/lib/pages/viewer/vertical_viewer_page.dart
index beb651f45..5da4c75cb 100644
--- a/lib/pages/viewer/vertical_viewer_page.dart
+++ b/lib/pages/viewer/vertical_viewer_page.dart
@@ -21,9 +21,9 @@ typedef StringCallback = Future Function(String);
 class VerticalViewerPage extends StatefulWidget {
   final String getxId;
   const VerticalViewerPage({
-    Key? key,
+    super.key,
     required this.getxId,
-  }) : super(key: key);
+  });
 
   @override
   State<VerticalViewerPage> createState() => _VerticalViewerPageState();
diff --git a/lib/pages/viewer/vertical_webview_viewer_page.dart b/lib/pages/viewer/vertical_webview_viewer_page.dart
index 167143370..f6ac30ba4 100644
--- a/lib/pages/viewer/vertical_webview_viewer_page.dart
+++ b/lib/pages/viewer/vertical_webview_viewer_page.dart
@@ -13,9 +13,9 @@ import 'package:violet/pages/viewer/viewer_controller.dart';
 class VerticalWebviewViewerPage extends StatefulWidget {
   final String getxId;
   const VerticalWebviewViewerPage({
-    Key? key,
+    super.key,
     required this.getxId,
-  }) : super(key: key);
+  });
 
   @override
   State<VerticalWebviewViewerPage> createState() =>
diff --git a/lib/pages/viewer/viewer_page.dart b/lib/pages/viewer/viewer_page.dart
index fe5648528..52de9f42d 100644
--- a/lib/pages/viewer/viewer_page.dart
+++ b/lib/pages/viewer/viewer_page.dart
@@ -4,7 +4,6 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:cached_network_image/cached_network_image.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:get/get.dart';
@@ -27,10 +26,11 @@ import 'package:violet/script/script_manager.dart';
 import 'package:violet/server/violet.dart';
 import 'package:violet/settings/settings.dart';
 import 'package:violet/util/call_once.dart';
+import 'package:violet/util/evict_image_urls.dart';
 import 'package:violet/widgets/article_item/image_provider_manager.dart';
 
 class ViewerPage extends StatefulWidget {
-  const ViewerPage({Key? key}) : super(key: key);
+  const ViewerPage({super.key});
 
   @override
   State<ViewerPage> createState() => _ViewerPageState();
@@ -166,9 +166,7 @@ class _ViewerPageState extends State<ViewerPage> {
   _dispose() {
     PaintingBinding.instance.imageCache.clear();
     if (_pageInfo.useWeb) {
-      _pageInfo.uris.forEach((element) async {
-        await CachedNetworkImageProvider(element).evict();
-      });
+      evictImageUrls(_pageInfo.uris);
     }
     SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [
       SystemUiOverlay.top,
diff --git a/lib/pages/viewer/widget/custom_doubletap_gesture_detector.dart b/lib/pages/viewer/widget/custom_doubletap_gesture_detector.dart
index 42f9941e9..0a7ea2fde 100644
--- a/lib/pages/viewer/widget/custom_doubletap_gesture_detector.dart
+++ b/lib/pages/viewer/widget/custom_doubletap_gesture_detector.dart
@@ -14,12 +14,12 @@ class CustomDoubleTapGestureDectector extends StatefulWidget {
   final Duration doubleTapMaxDelay;
 
   const CustomDoubleTapGestureDectector({
-    Key? key,
+    super.key,
     required this.onTap,
     required this.onDoubleTap,
     // ignore: unused_element
     this.doubleTapMaxDelay = const Duration(milliseconds: 200),
-  }) : super(key: key);
+  });
 
   @override
   State<CustomDoubleTapGestureDectector> createState() =>
diff --git a/lib/pages/viewer/widget/double_point_listener.dart b/lib/pages/viewer/widget/double_point_listener.dart
index 366f4044e..8815df322 100644
--- a/lib/pages/viewer/widget/double_point_listener.dart
+++ b/lib/pages/viewer/widget/double_point_listener.dart
@@ -10,10 +10,10 @@ class DoublePointListener extends StatefulWidget {
   final BoolCallback onStateChanged;
 
   const DoublePointListener({
-    Key? key,
+    super.key,
     required this.child,
     required this.onStateChanged,
-  }) : super(key: key);
+  });
 
   @override
   State<DoublePointListener> createState() => __DoublePointListener();
diff --git a/lib/script/script_webview.dart b/lib/script/script_webview.dart
index 99509e786..4f096ba53 100644
--- a/lib/script/script_webview.dart
+++ b/lib/script/script_webview.dart
@@ -14,7 +14,7 @@ class ScriptWebViewProxy {
 }
 
 class ScriptWebView extends StatefulWidget {
-  const ScriptWebView({Key? key}) : super(key: key);
+  const ScriptWebView({super.key});
 
   @override
   State<ScriptWebView> createState() => _ScriptWebViewState();
diff --git a/lib/util/evict_image_urls.dart b/lib/util/evict_image_urls.dart
new file mode 100644
index 000000000..f5291c77d
--- /dev/null
+++ b/lib/util/evict_image_urls.dart
@@ -0,0 +1,11 @@
+import 'package:cached_network_image/cached_network_image.dart';
+
+Future<void> evictImageUrls(Iterable<String>? urls) async {
+  if (urls == null) {
+    return;
+  }
+
+  for (final url in urls) {
+    await CachedNetworkImageProvider(url).evict();
+  }
+}
diff --git a/lib/version/sync.dart b/lib/version/sync.dart
index 2b72b89d1..49d0f3f70 100644
--- a/lib/version/sync.dart
+++ b/lib/version/sync.dart
@@ -87,8 +87,8 @@ class SyncManager {
 
         와 같은 형식으로 아래쪽이 항상 최신 청크다. 따라서 reversed 탐색을 시도한다.
        */
-      lines.reversed.forEach((element) {
-        if (element.startsWith('#')) return;
+      for (var element in lines.reversed) {
+        if (element.startsWith('#')) continue;
 
         var split = element.split(' ');
         var type = split[0];
@@ -98,12 +98,12 @@ class SyncManager {
         if (type == 'chunk') size = int.parse(split[3]);
 
         // We require only json files when synchronize with chunk.
-        if (type == 'chunk' && !url.endsWith('.json')) return;
+        if (type == 'chunk' && !url.endsWith('.json')) continue;
 
         //
         // 마지막으로 동기화한 시간보다 작은 경우 해당 청크는 무시한다.
         //
-        if (type == 'chunk' && timestamp <= latest!) return;
+        if (type == 'chunk' && timestamp <= latest) continue;
 
         requestSize += size;
         _rows!.add(SyncInfoRecord(
@@ -112,7 +112,7 @@ class SyncManager {
           url: url,
           size: size,
         ));
-      });
+      }
 
       /*
          너무 많은 청크를 다운로드해야하는 경우 동기화를 추천한다.
diff --git a/lib/widgets/article_item/article_list_item_widget.dart b/lib/widgets/article_item/article_list_item_widget.dart
index 347b620ed..c64671493 100644
--- a/lib/widgets/article_item/article_list_item_widget.dart
+++ b/lib/widgets/article_item/article_list_item_widget.dart
@@ -41,10 +41,10 @@ class ArticleListItemWidget extends StatefulWidget {
   final bool isCheckMode;
 
   const ArticleListItemWidget({
-    Key? key,
+    super.key,
     this.isChecked = false,
     this.isCheckMode = false,
-  }) : super(key: key);
+  });
 
   @override
   State<ArticleListItemWidget> createState() => _ArticleListItemWidgetState();
@@ -423,9 +423,9 @@ class BodyWidget extends StatelessWidget {
   final String getxId;
 
   BodyWidget({
-    Key? key,
+    super.key,
     required this.getxId,
-  }) : super(key: key) {
+  }) {
     c = Get.find(tag: getxId);
   }
 
@@ -591,8 +591,7 @@ class TagChip extends StatelessWidget {
   final String name;
   final String group;
 
-  const TagChip({Key? key, required this.name, required this.group})
-      : super(key: key);
+  const TagChip({super.key, required this.name, required this.group});
 
   String normalize(String tag) {
     if (tag == 'groups') return 'group';
@@ -713,7 +712,7 @@ class TagChip extends StatelessWidget {
 class ModalInsideModal extends StatelessWidget {
   final bool reverse;
 
-  const ModalInsideModal({Key? key, this.reverse = false}) : super(key: key);
+  const ModalInsideModal({super.key, this.reverse = false});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/widgets/article_item/thumbnail.dart b/lib/widgets/article_item/thumbnail.dart
index f7dae4113..8d250fc2e 100644
--- a/lib/widgets/article_item/thumbnail.dart
+++ b/lib/widgets/article_item/thumbnail.dart
@@ -15,9 +15,9 @@ class ThumbnailWidget extends StatelessWidget {
   final String getxId;
 
   ThumbnailWidget({
-    Key? key,
+    super.key,
     required this.getxId,
-  }) : super(key: key) {
+  }) {
     c = Get.find(tag: getxId);
   }
 
@@ -111,13 +111,13 @@ class ThumbnailImageWidget extends StatelessWidget {
   final _rebuildValueNotifier = ValueNotifier('');
 
   ThumbnailImageWidget({
-    Key? key,
+    super.key,
     required this.thumbnail,
     required this.thumbnailTag,
     required this.headers,
     required this.showUltra,
     required this.greyScale,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
@@ -194,10 +194,10 @@ class BookmarkIndicatorWidget extends StatelessWidget {
   final bool greyScale;
 
   BookmarkIndicatorWidget({
-    Key? key,
+    super.key,
     required String getxId,
     required this.greyScale,
-  }) : super(key: key) {
+  }) {
     c = Get.find(tag: getxId);
   }
 
@@ -245,12 +245,12 @@ class ReadProgressOverlayWidget extends StatelessWidget {
   final bool greyScale;
 
   const ReadProgressOverlayWidget({
-    Key? key,
+    super.key,
     required this.isLastestRead,
     required this.latestReadPage,
     required this.imageCount,
     required this.greyScale,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
@@ -286,10 +286,10 @@ class PagesOverlayWidget extends StatelessWidget {
   final int imageCount;
 
   const PagesOverlayWidget({
-    Key? key,
+    super.key,
     required this.showDetail,
     required this.imageCount,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/widgets/article_item/thumbnail_view_page.dart b/lib/widgets/article_item/thumbnail_view_page.dart
index 97aa74bc4..74530eb5e 100644
--- a/lib/widgets/article_item/thumbnail_view_page.dart
+++ b/lib/widgets/article_item/thumbnail_view_page.dart
@@ -13,12 +13,12 @@ class ThumbnailViewPage extends StatefulWidget {
   final bool showUltra;
 
   const ThumbnailViewPage({
-    Key? key,
+    super.key,
     required this.thumbnail,
     required this.headers,
     required this.heroKey,
     required this.showUltra,
-  }) : super(key: key);
+  });
 
   @override
   State<ThumbnailViewPage> createState() => _ThumbnailViewPageState();
diff --git a/lib/widgets/debounce_widget.dart b/lib/widgets/debounce_widget.dart
index 7987ecabf..351ea6d12 100644
--- a/lib/widgets/debounce_widget.dart
+++ b/lib/widgets/debounce_widget.dart
@@ -7,8 +7,7 @@ class DebounceWidget extends StatefulWidget {
   final Widget child;
   final Widget? loadingWidget;
 
-  const DebounceWidget({Key? key, required this.child, this.loadingWidget})
-      : super(key: key);
+  const DebounceWidget({super.key, required this.child, this.loadingWidget});
 
   @override
   State<DebounceWidget> createState() => _DebounceWidgetState();
diff --git a/lib/widgets/dots_indicator.dart b/lib/widgets/dots_indicator.dart
index 619298f66..8cf8f09c4 100644
--- a/lib/widgets/dots_indicator.dart
+++ b/lib/widgets/dots_indicator.dart
@@ -10,12 +10,12 @@ import 'package:violet/style/palette.dart';
 // https://gist.github.com/collinjackson/4fddbfa2830ea3ac033e34622f278824#file-main-dart-L24
 class DotsIndicator extends AnimatedWidget {
   const DotsIndicator({
-    Key? key,
+    super.key,
     required this.controller,
     required this.itemCount,
     required this.onPageSelected,
     this.color = Colors.white,
-  }) : super(key: key, listenable: controller);
+  }) : super(listenable: controller);
 
   /// The PageController that this DotsIndicator is representing.
   final PageController controller;
diff --git a/lib/widgets/floating_button.dart b/lib/widgets/floating_button.dart
index d5208a874..463e593bd 100644
--- a/lib/widgets/floating_button.dart
+++ b/lib/widgets/floating_button.dart
@@ -36,11 +36,11 @@ class AnimatedFloatingActionButton extends StatefulWidget {
   final VoidCallback exitCallback;
 
   const AnimatedFloatingActionButton({
-    Key? key,
+    super.key,
     required this.fabButtons,
     required this.animatedIconData,
     required this.exitCallback,
-  }) : super(key: key);
+  });
 
   @override
   State<AnimatedFloatingActionButton> createState() =>
diff --git a/lib/widgets/theme_switchable_state.dart b/lib/widgets/theme_switchable_state.dart
index f405e5f0a..8aac6a4cd 100644
--- a/lib/widgets/theme_switchable_state.dart
+++ b/lib/widgets/theme_switchable_state.dart
@@ -18,9 +18,9 @@ class ThemeSwitchableStateTargetStore {
 
   static void doChange() {
     Timer.run(() {
-      targets.forEach((element) {
+      for (var element in targets) {
         element.checkDirty();
-      });
+      }
     });
   }
 }
diff --git a/lib/widgets/toast.dart b/lib/widgets/toast.dart
index 650896728..b95f43316 100644
--- a/lib/widgets/toast.dart
+++ b/lib/widgets/toast.dart
@@ -17,7 +17,7 @@ class ToastWrapper extends StatefulWidget {
   final bool reverse;
 
   const ToastWrapper({
-    Key? key,
+    super.key,
     this.isCheck = false,
     this.isWarning = false,
     required this.msg,
@@ -25,7 +25,7 @@ class ToastWrapper extends StatefulWidget {
     this.color,
     this.ignoreDrawer = false,
     this.reverse = false,
-  }) : super(key: key);
+  });
 
   @override
   State<ToastWrapper> createState() => _ToastWrapperState();
diff --git a/lib/widgets/v_cached_network_image.dart b/lib/widgets/v_cached_network_image.dart
index 9561e6ae9..b37a20d25 100644
--- a/lib/widgets/v_cached_network_image.dart
+++ b/lib/widgets/v_cached_network_image.dart
@@ -196,7 +196,7 @@ class VCachedNetworkImage extends StatelessWidget {
   /// loaded image. Next to that it supports most features of a default Image
   /// widget.
   VCachedNetworkImage({
-    Key? key,
+    super.key,
     required this.imageUrl,
     this.httpHeaders,
     this.imageBuilder,
@@ -231,8 +231,7 @@ class VCachedNetworkImage extends StatelessWidget {
           cacheKey: cacheKey,
           maxWidth: maxWidthDiskCache,
           maxHeight: maxHeightDiskCache,
-        ),
-        super(key: key);
+        );
 
   @override
   Widget build(BuildContext context) {
diff --git a/pubspec.lock b/pubspec.lock
index 84c5da645..d41f33258 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -707,10 +707,10 @@ packages:
     dependency: "direct dev"
     description:
       name: flutter_lints
-      sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
+      sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.3"
+    version: "3.0.1"
   flutter_localizations:
     dependency: "direct main"
     description: flutter
@@ -979,10 +979,10 @@ packages:
     dependency: transitive
     description:
       name: lints
-      sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
+      sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.1"
+    version: "3.0.0"
   local_auth:
     dependency: "direct main"
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 4dae19866..255ef3954 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -133,7 +133,7 @@ dev_dependencies:
   freezed: ^2.3.5
   drift_sqflite: ^2.0.0
   sqflite_common_ffi:
-  flutter_lints: ^2.0.1
+  flutter_lints: ^3.0.0
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
diff --git a/test/test_downloader_tasks.dart b/test/test_downloader_tasks.dart
index 52bfc1ff3..b7d1a8286 100644
--- a/test/test_downloader_tasks.dart
+++ b/test/test_downloader_tasks.dart
@@ -214,9 +214,9 @@ void main() {
     //   ),
     // );
 
-    tasks.forEach((element) {
+    for (var element in tasks) {
       print(element.url);
-    });
+    }
 
     downloader.appendTasks(tasks);