Skip to content

Cleanup 1#76

Merged
GT-610 merged 6 commits into
mainfrom
cleanup-1
Jun 1, 2026
Merged

Cleanup 1#76
GT-610 merged 6 commits into
mainfrom
cleanup-1

Conversation

@GT-610

@GT-610 GT-610 commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Introduced shared settings UI helpers for consistent styling and layout across settings pages.
  • Improvements

    • Optimized task filtering with caching to reduce unnecessary recomputations.
    • Added instance connection caching for improved performance.
    • Simplified public APIs by removing unnecessary async wrappers and JSON serialization.
    • Updated error messages to English for consistency.
    • Enhanced theme system with better reactive updates.
  • Updates

    • Updated intl dependency to ^0.20.2.

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@GT-610, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 39 minutes and 40 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5248d3da-57f0-4c51-a11d-5197eeb20850

📥 Commits

Reviewing files that changed from the base of the PR and between 8214cf6 and b5ff5d2.

📒 Files selected for processing (7)
  • .gitignore
  • lib/app.dart
  • lib/models/settings.dart
  • lib/pages/components/settings_helpers.dart
  • lib/pages/download_page/download_page.dart
  • lib/services/download_data_service.dart
  • lib/services/instance_manager.dart
📝 Walkthrough

Walkthrough

This PR refactors settings UI across builtin and remote instance pages by introducing reusable helpers, modernizes the download status bar with context.select-based selectors, optimizes download task filtering with caching, and hardens data layer APIs with immutability and invalidation patterns.

Changes

Settings UI Helpers & Page Refactoring

Layer / File(s) Summary
Settings helpers abstraction
lib/pages/components/settings_helpers.dart
New SettingsSection abstract class and SettingsPageHelpers mixin provide reusable text style helpers, card wrapper, section block, and responsive multi-column tab view layout used by settings pages.
Builtin instance settings page adoption
lib/pages/builtin_instance_settings_page.dart
Page mixes in SettingsPageHelpers, creates _BuiltinSettingsSection implementing SettingsSection, delegates layout/styling to helpers, and updates all setting row tiles to use shared SettingsPageHelpers.kSettingTilePadding.
Remote instance settings page adoption
lib/pages/remote_instance_settings_page.dart
Page mixes in SettingsPageHelpers, refactors _RemoteSettingsSection to implement SettingsSection, delegates tab view/card/text styles to helpers, and updates row tiles to use shared padding constant.

Download Status Bar & Filtering Optimization

Layer / File(s) Summary
Theme wiring & status bar widget
lib/app.dart
_ThemeProviderState uses context.select to derive locale and theme settings; new _StatusBar widget uses context.select to compute active/waiting task counts and total speed from download tasks, rendering Material-You styled speed and count chips.
Download page caching & task filtering
lib/pages/download_page/download_page.dart
State caches filtered task list with dependency tracking (tasks ref, filter/sort/search selections, instance names); refactors task counting to single-pass _countAllActionableTasks() helper; optimizes sorting with precomputed keys and id tie-breaking.

Data Layer & Service Infrastructure Updates

Layer / File(s) Summary
Download task model cleanup
lib/pages/download_page/models/download_task.dart
Removes JSON serialization support (fromJson, toJson, _parseDownloadStatus), leaving only field declarations and constructor.
Immutable list exports
lib/services/download_data_service.dart
tasks getter now returns UnmodifiableListView instead of mutable _tasks list to enforce read-only external access.
Settings sync migration & defaults
lib/models/settings.dart, lib/utils/default_download_directory.dart
Settings._defaultDownloadDirectory() switches to getDefaultDownloadDirectorySync(); async wrapper function removed from utility module.
Instance manager caching & messages
lib/services/instance_manager.dart
Introduces connected instances cache with invalidation called after all mutations; updates built-in instance name and error messages to English.
Service API cleanup
lib/services/builtin_instance_service.dart, lib/services/aria2_rpc_client.dart, .gitignore, pubspec.yaml, packages/fl_lib
Removes pid getter from BuiltinInstanceService; updates RPC exception messages to English; adds .vscode/ to gitignore; pins intl to ^0.20.2; updates fl_lib submodule.

Possibly related PRs

  • GT-610/setsuna#75: Both modify lib/models/settings.dart and lib/utils/default_download_directory.dart to switch default download directory resolution from async to sync API.
  • GT-610/setsuna#74: Both refactor download status/speed chip rendering in lib/app.dart and share logic for deriving total download speed and task counts.
  • GT-610/setsuna#73: Both remove the pid getter from BuiltinInstanceService in lib/services/builtin_instance_service.dart.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Cleanup 1' is vague and does not convey meaningful information about the changeset; it does not describe what was actually cleaned up or the primary purpose of the changes. Consider using a more descriptive title that summarizes the main purpose, such as 'Refactor settings UI helpers and task filtering logic' or 'Extract common settings UI patterns into reusable helpers'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/services/instance_manager.dart (1)

161-177: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Default built-in instance name is still in Chinese here.

Line 75 in initialize() creates the built-in instance with name: 'Built-in', but _createDefaultInstance() still uses '内建实例'. Depending on which path runs, users see a different display name for the same built-in instance. This also contradicts the intended English migration.

🌐 Proposed fix
       Aria2Instance(
         id: 'builtin',
-        name: '内建实例',
+        name: 'Built-in',
         type: InstanceType.builtin,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/services/instance_manager.dart` around lines 161 - 177, The default
built-in instance name in _createDefaultInstance() is still Chinese ('内建实例');
update it to match the other creation path by changing the Aria2Instance name to
'Built-in' in _createDefaultInstance() so both paths use the same display name
(refer to _createDefaultInstance() and the earlier initialize() creation of the
built-in instance).
🧹 Nitpick comments (2)
lib/app.dart (1)

540-560: ⚡ Quick win

Consolidate task summary logic to prevent tray/status-bar drift.

Line 540 and Line 931 duplicate the same summary rules in two places. Extract a shared helper so both tray menu and bottom status bar always stay consistent.

Proposed refactor
+({int active, int waiting, int speed}) _summarizeTasks(
+  List<DownloadTask> tasks,
+) {
+  var active = 0;
+  var waiting = 0;
+  var speed = 0;
+  for (final task in tasks) {
+    if (task.status == DownloadStatus.active) {
+      active++;
+      speed += task.downloadSpeedBytes;
+    } else if (task.status == DownloadStatus.waiting) {
+      waiting++;
+    }
+  }
+  return (active: active, waiting: waiting, speed: speed);
+}
...
-    var activeCount = 0;
-    var waitingCount = 0;
-    var totalDownloadSpeed = 0;
-    for (final task in tasks) { ... }
+    final summary = _summarizeTasks(tasks);
+    final activeCount = summary.active;
+    final waitingCount = summary.waiting;
+    final totalDownloadSpeed = summary.speed;
...
-    final counts = context.select<DownloadDataService, ({int active, int waiting, int speed})>((service) {
-      var active = 0;
-      var waiting = 0;
-      var speed = 0;
-      for (final task in service.tasks) { ... }
-      return (active: active, waiting: waiting, speed: speed);
-    });
+    final counts = context.select<
+      DownloadDataService,
+      ({int active, int waiting, int speed})
+    >((service) => _summarizeTasks(service.tasks));

Also applies to: 931-944

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/app.dart` around lines 540 - 560, The task summary logic that computes
activeCount, waitingCount, resumableCount, pausableCount, and totalDownloadSpeed
is duplicated (seen around the loop over tasks in lib/app.dart) causing drift
between tray/status-bar; extract this into a single helper (e.g.,
computeTaskSummary or TaskSummary.fromTasks) that accepts the tasks list and
returns a struct/object with fields activeCount, waitingCount, resumableCount,
pausableCount, and totalDownloadSpeed, replace the inline loop in both places
(the current loop and the duplicate at lines ~931–944) with calls to that
helper, and ensure callers read the returned fields rather than recomputing.
lib/models/settings.dart (1)

97-99: Confirm getDefaultDownloadDirectorySync() type-safety in settings

  • getDefaultDownloadDirectorySync() is defined in lib/utils/default_download_directory.dart and returns a synchronous String, so lib/models/settings.dart’s Future<String> _defaultDownloadDirectory() async { return getDefaultDownloadDirectorySync(); } is type-safe.
  • No getDefaultDownloadDirectory symbol appears to be referenced/defined elsewhere; leaving the redundant async wrapper is an optional cleanup.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/models/settings.dart` around lines 97 - 99, The
_defaultDownloadDirectory() function currently uses an unnecessary async wrapper
around the synchronous getDefaultDownloadDirectorySync(); replace the async
function body with a direct Future return to avoid the redundant async: change
Future<String> _defaultDownloadDirectory() async { return
getDefaultDownloadDirectorySync(); } to Future<String>
_defaultDownloadDirectory() { return
Future.value(getDefaultDownloadDirectorySync()); } so the method remains
async-compatible but no longer uses an unnecessary async/await; reference
symbols: _defaultDownloadDirectory and getDefaultDownloadDirectorySync.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.gitignore:
- Around line 21-24: The .gitignore comment and the actual rule for ".vscode/"
are inconsistent: the comment says the entry is "commented out by default" but
the file currently contains an active ".vscode/" ignore line; update either the
comment or the rule to match policy by either commenting out the ".vscode/" line
or changing the comment to indicate it is intentionally ignored — locate the
".vscode/" entry in the .gitignore and make the comment and the rule consistent
(edit the comment text near ".vscode/" or prepend a "#" to the ".vscode/" line).

In `@lib/pages/components/settings_helpers.dart`:
- Around line 60-73: The current calculation of columns (derived from width) can
exceed the number of sections, causing empty trailing columns and squeezed
content; update the logic in the same block that defines
columns/distributedSections so that you clamp the column count to the number of
sections (e.g., use a clampedColumns = min(columns, max(1, sections.length)) or
equivalent) and then generate distributedSections and the for-loop using that
clampedColumns (ensure index % clampedColumns is used and handle the
zero-sections case by forcing at least 1 column).

In `@lib/pages/download_page/download_page.dart`:
- Around line 332-343: The cache-hit check in download_page.dart fails because
DownloadDataService.tasks returns a new UnmodifiableListView each access so
identical(_cachedTasksRef, tasksRef) is always false; update the cache logic to
use a stable change token/version or a stable reference instead of wrapper
identity: either add and read a changeCounter/version (e.g., expose a
version/getter on DownloadDataService) or cache the underlying list reference
(or a cheap content signature like length + lastModified) and compare that
(replace references to identical(_cachedTasksRef, tasksRef) with the new stable
token/version check), keeping the rest of the predicate (e.g., _cachedFilter,
_cachedCategoryType, _selectedInstanceId, _searchQuery, _sortOption,
_sortDescending, _instanceNames) intact and ensure _cachedTasksRef is set from
the chosen stable token when updating _cachedFilteredTasks.

---

Outside diff comments:
In `@lib/services/instance_manager.dart`:
- Around line 161-177: The default built-in instance name in
_createDefaultInstance() is still Chinese ('内建实例'); update it to match the other
creation path by changing the Aria2Instance name to 'Built-in' in
_createDefaultInstance() so both paths use the same display name (refer to
_createDefaultInstance() and the earlier initialize() creation of the built-in
instance).

---

Nitpick comments:
In `@lib/app.dart`:
- Around line 540-560: The task summary logic that computes activeCount,
waitingCount, resumableCount, pausableCount, and totalDownloadSpeed is
duplicated (seen around the loop over tasks in lib/app.dart) causing drift
between tray/status-bar; extract this into a single helper (e.g.,
computeTaskSummary or TaskSummary.fromTasks) that accepts the tasks list and
returns a struct/object with fields activeCount, waitingCount, resumableCount,
pausableCount, and totalDownloadSpeed, replace the inline loop in both places
(the current loop and the duplicate at lines ~931–944) with calls to that
helper, and ensure callers read the returned fields rather than recomputing.

In `@lib/models/settings.dart`:
- Around line 97-99: The _defaultDownloadDirectory() function currently uses an
unnecessary async wrapper around the synchronous
getDefaultDownloadDirectorySync(); replace the async function body with a direct
Future return to avoid the redundant async: change Future<String>
_defaultDownloadDirectory() async { return getDefaultDownloadDirectorySync(); }
to Future<String> _defaultDownloadDirectory() { return
Future.value(getDefaultDownloadDirectorySync()); } so the method remains
async-compatible but no longer uses an unnecessary async/await; reference
symbols: _defaultDownloadDirectory and getDefaultDownloadDirectorySync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d23c4ae2-4728-45f2-9c91-e39a35df7200

📥 Commits

Reviewing files that changed from the base of the PR and between 3526dba and 8214cf6.

⛔ Files ignored due to path filters (1)
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • .gitignore
  • lib/app.dart
  • lib/models/settings.dart
  • lib/pages/builtin_instance_settings_page.dart
  • lib/pages/components/settings_helpers.dart
  • lib/pages/download_page/download_page.dart
  • lib/pages/download_page/models/download_task.dart
  • lib/pages/remote_instance_settings_page.dart
  • lib/services/aria2_rpc_client.dart
  • lib/services/builtin_instance_service.dart
  • lib/services/download_data_service.dart
  • lib/services/instance_manager.dart
  • lib/utils/default_download_directory.dart
  • packages/fl_lib
  • pubspec.yaml
💤 Files with no reviewable changes (3)
  • lib/utils/default_download_directory.dart
  • lib/pages/download_page/models/download_task.dart
  • lib/services/builtin_instance_service.dart

Comment thread .gitignore
Comment thread lib/pages/components/settings_helpers.dart Outdated
Comment thread lib/pages/download_page/download_page.dart
@GT-610 GT-610 merged commit d08dd52 into main Jun 1, 2026
1 of 2 checks passed
@GT-610 GT-610 deleted the cleanup-1 branch June 1, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant