opt.: systemd page (#851)

This commit is contained in:
lollipopkit🏳️‍⚧️
2025-08-13 22:16:55 +08:00
committed by GitHub
parent e4a9875620
commit ed8a1d18b9
10 changed files with 131 additions and 84 deletions

View File

@@ -20,7 +20,10 @@ extension on _ServerPageState {
Widget _buildTopRightWidget(Server s) {
final (child, onTap) = switch (s.conn) {
ServerConn.connecting || ServerConn.loading || ServerConn.connected => (
SizedLoading(_ServerPageState._kCardHeightMin, strokeWidth: 3, padding: 5),
SizedBox.square(
dimension: _ServerPageState._kCardHeightMin,
child: SizedLoading(_ServerPageState._kCardHeightMin, strokeWidth: 3, padding: 3),
),
null,
),
ServerConn.failed => (

View File

@@ -41,38 +41,63 @@ final class _SystemdPageState extends State<SystemdPage> {
return CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: _pro.isBusy.listenVal(
(isBusy) => AnimatedContainer(
duration: Durations.medium1,
curve: Curves.fastEaseInToSlowEaseOut,
height: isBusy ? SizedLoading.medium.size : 0,
child: isBusy ? SizedLoading.medium : const SizedBox.shrink(),
),
child: Column(
children: [
_buildScopeFilterChips(),
_pro.isBusy.listenVal(
(isBusy) => AnimatedContainer(
duration: Durations.medium1,
curve: Curves.fastEaseInToSlowEaseOut,
height: isBusy ? SizedLoading.medium.size : 0,
width: isBusy ? SizedLoading.medium.size : 0,
child: isBusy ? SizedLoading.medium : const SizedBox.shrink(),
),
),
],
),
),
_buildUnitList(_pro.units),
_buildUnitList(),
],
);
}
Widget _buildUnitList(VNode<List<SystemdUnit>> units) {
return units.listenVal((units) {
if (units.isEmpty) {
return SliverToBoxAdapter(child: CenterGreyTitle(libL10n.empty).paddingSymmetric(horizontal: 13));
}
return SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
final unit = units[index];
return ListTile(
leading: _buildScopeTag(unit.scope),
title: unit.description != null ? TipText(unit.name, unit.description!) : Text(unit.name),
subtitle: Wrap(
children: [_buildStateTag(unit.state), _buildTypeTag(unit.type)],
).paddingOnly(top: 7),
trailing: _buildUnitFuncs(unit),
).cardx.paddingSymmetric(horizontal: 13);
}, childCount: units.length),
);
Widget _buildScopeFilterChips() {
return _pro.scopeFilter.listenVal((currentFilter) {
return Wrap(
spacing: 8,
children: SystemdScopeFilter.values.map((filter) {
final isSelected = filter == currentFilter;
return FilterChip(
selected: isSelected,
label: Text(filter.displayName),
onSelected: (_) => _pro.scopeFilter.value = filter,
);
}).toList(),
).paddingSymmetric(horizontal: 13, vertical: 8);
});
}
Widget _buildUnitList() {
return _pro.units.listenVal((allUnits) {
return _pro.scopeFilter.listenVal((filter) {
final filteredUnits = _pro.filteredUnits;
if (filteredUnits.isEmpty) {
return SliverToBoxAdapter(child: CenterGreyTitle(libL10n.empty).paddingSymmetric(horizontal: 13));
}
return SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
final unit = filteredUnits[index];
return ListTile(
leading: _buildScopeTag(unit.scope),
title: unit.description != null ? TipText(unit.name, unit.description!) : Text(unit.name),
subtitle: Wrap(
children: [_buildStateTag(unit.state), _buildTypeTag(unit.type)],
).paddingOnly(top: 7),
trailing: _buildUnitFuncs(unit),
).cardx.paddingSymmetric(horizontal: 13);
}, childCount: filteredUnits.length),
);
});
});
}