-
-
Notifications
You must be signed in to change notification settings - Fork 466
opt.: systemd page #851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
opt.: systemd page #851
Conversation
Reviewer's GuideThis PR enhances the Systemd page by adding scope-based filtering to the UI and provider, refactors unit parsing and logging logic in the SystemdProvider, makes targeted UI layout fixes (spinner sizing, server tab loading), tightens CI workflow filters for the Claude bot, and updates package versions. Class diagram for SystemdProvider and SystemdScopeFilter changesclassDiagram
class SystemdProvider {
+VNode<Server> _si
+VNode<bool> isBusy
+VNode<List<SystemdUnit>> units
+VNode<SystemdScopeFilter> scopeFilter
+List<SystemdUnit> filteredUnits
+void dispose()
+Future<void> getUnits()
+Future<List<SystemdUnit>> _parseUnitObj(List<String>, SystemdUnitScope)
}
class SystemdScopeFilter {
+all
+system
+user
+String displayName
}
SystemdProvider --> SystemdScopeFilter
SystemdProvider --> SystemdUnit
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @lollipopkit - I've reviewed your changes - here's some feedback:
- Consider setting isBusy.value = true at the beginning of getUnits to ensure the loading spinner appears while units are being fetched.
- In _buildUnitList you can drop the outer listenVal on units (allUnits) since it’s not used and simplify by listening only to scopeFilter or filteredUnits.
- Instead of nesting your filter chips and spinner inside a single SliverToBoxAdapter Column, consider using separate slivers (e.g., a SliverPadding or SliverToBoxAdapter per widget) for better scroll performance.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider setting isBusy.value = true at the beginning of getUnits to ensure the loading spinner appears while units are being fetched.
- In _buildUnitList you can drop the outer listenVal on units (allUnits) since it’s not used and simplify by listening only to scopeFilter or filteredUnits.
- Instead of nesting your filter chips and spinner inside a single SliverToBoxAdapter Column, consider using separate slivers (e.g., a SliverPadding or SliverToBoxAdapter per widget) for better scroll performance.
## Individual Comments
### Comment 1
<location> `lib/data/provider/systemd.dart:49` </location>
<code_context>
final systemUnits = <String>[];
for (final unit in units) {
- if (unit.startsWith('/etc/systemd/system')) {
+ final maybeSystem = unit.contains('/systemd/system');
+ final maybeUser = unit.contains('/.config/systemd/user');
+ if (maybeSystem && !maybeUser) {
systemUnits.add(unit);
- } else if (unit.startsWith('~/.config/systemd/user')) {
+ } else {
userUnits.add(unit);
- } else if (unit.trim().isNotEmpty) {
</code_context>
<issue_to_address>
The logic for classifying system/user units may misclassify units with overlapping paths.
Using contains for path matching can lead to false positives if both substrings appear or if the path format changes. More precise matching, such as startsWith or regular expressions, is recommended.
</issue_to_address>
### Comment 2
<location> `lib/data/provider/systemd.dart:83` </location>
<code_context>
final parsedUnits = <SystemdUnit>[];
- for (final unit in units) {
- final parts = unit.split('\n');
+ for (final unit in units.skipWhile((e) => e.trim().isEmpty)) {
+ final parts = unit.split('\n').skipWhile((e) => e.trim().isEmpty);
+ if (parts.isEmpty) continue;
var name = '';
var type = '';
</code_context>
<issue_to_address>
Skipping empty units and lines may inadvertently skip valid but empty entries.
Using skipWhile only removes leading empty entries. To exclude all empty entries, use where or another filtering method.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
for (final unit in units.skipWhile((e) => e.trim().isEmpty)) {
final parts = unit.split('\n').skipWhile((e) => e.trim().isEmpty);
if (parts.isEmpty) continue;
var name = '';
var type = '';
var state = '';
=======
for (final unit in units.where((e) => e.trim().isNotEmpty)) {
final parts = unit
.split('\n')
.where((e) => e.trim().isNotEmpty)
.toList();
if (parts.isEmpty) continue;
var name = '';
var type = '';
var state = '';
>>>>>>> REPLACE
</suggested_fix>
### Comment 3
<location> `lib/data/provider/systemd.dart:158` </location>
<code_context>
String _getIniVal(String line) {
- return line.split('=').last;
+ final idx = line.indexOf('=');
+ if (idx < 0) return line;
+ return line.substring(idx + 1).trim();
}
</code_context>
<issue_to_address>
The _getIniVal function may return the entire line if '=' is not found.
Consider returning an empty string or null when '=' is missing, or handle this case explicitly at the call site to avoid propagating unintended values.
</issue_to_address>
### Comment 4
<location> `lib/view/page/systemd.dart:80` </location>
<code_context>
+ Widget _buildUnitList() {
</code_context>
<issue_to_address>
Nesting listenVal calls may lead to unnecessary rebuilds.
Consider refactoring _buildUnitList to use a single listenVal with a derived value, reducing redundant rebuilds and improving performance.
Suggested implementation:
```
Widget _buildUnitList() {
return listenVal2(_pro.units, _pro.scopeFilter, (allUnits, filter) {
final filteredUnits = _pro.getFilteredUnits(allUnits, filter);
if (filteredUnits.isEmpty) {
return SliverToBoxAdapter(child: CenterGreyTitle(libL10n.empty).paddingSymmetric(horizontal: 13));
}
return SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
final unit = filteredUnits[index];
return ListTile(
```
You will need to implement the `listenVal2` function if it does not already exist. It should take two listenable values and a callback, and rebuild when either changes.
Also, replace `_pro.filteredUnits` with a method like `_pro.getFilteredUnits(allUnits, filter)` that computes the filtered units from the provided values, rather than relying on possibly stale state.
If you have a utility for combining listenables, use that instead of `listenVal2`.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| ); | ||
| }).toList(), | ||
| ).paddingSymmetric(horizontal: 13, vertical: 8); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (performance): Nesting listenVal calls may lead to unnecessary rebuilds.
Consider refactoring _buildUnitList to use a single listenVal with a derived value, reducing redundant rebuilds and improving performance.
Suggested implementation:
Widget _buildUnitList() {
return listenVal2(_pro.units, _pro.scopeFilter, (allUnits, filter) {
final filteredUnits = _pro.getFilteredUnits(allUnits, filter);
if (filteredUnits.isEmpty) {
return SliverToBoxAdapter(child: CenterGreyTitle(libL10n.empty).paddingSymmetric(horizontal: 13));
}
return SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
final unit = filteredUnits[index];
return ListTile(
You will need to implement the listenVal2 function if it does not already exist. It should take two listenable values and a callback, and rebuild when either changes.
Also, replace _pro.filteredUnits with a method like _pro.getFilteredUnits(allUnits, filter) that computes the filtered units from the provided values, rather than relying on possibly stale state.
If you have a utility for combining listenables, use that instead of listenVal2.
Summary by Sourcery
Add scope filter functionality to the systemd page, refactor unit fetching and parsing logic in the provider, improve UI loading indicators and SSH prompt context handling, tighten GitHub workflow triggers, and bump fl_lib dependency.
New Features:
Enhancements:
CI:
Chores: