reorganize connections in bottom sheet

This commit is contained in:
Fabian Freund
2026-07-10 04:58:25 +02:00
parent 277585fc05
commit 9547169d99
2 changed files with 56 additions and 10 deletions
@@ -28,6 +28,7 @@ part 'persisted_bool.g.dart';
enum PersistedBoolKey { enum PersistedBoolKey {
extensionsExpanded(key: 'ExtensionsExpanded', defaultValue: false), extensionsExpanded(key: 'ExtensionsExpanded', defaultValue: false),
connectionsExpanded(key: 'ConnectionsExpanded', defaultValue: true),
searchSuggestionsExpanded( searchSuggestionsExpanded(
key: 'SearchSuggestionsExpanded', key: 'SearchSuggestionsExpanded',
defaultValue: true, defaultValue: true,
@@ -2024,6 +2024,9 @@ class _ConnectionCard extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final connectionsExpanded = ref.watch(
persistedBoolProvider(PersistedBoolKey.connectionsExpanded),
);
final isTorActive = ref.watch( final isTorActive = ref.watch(
torProxyServiceProvider.select((value) => value.value?.isRunning == true), torProxyServiceProvider.select((value) => value.value?.isRunning == true),
); );
@@ -2103,13 +2106,53 @@ class _ConnectionCard extends ConsumerWidget {
), ),
]; ];
final activeCount =
(isTorActive ? 1 : 0) +
assignedProfiles
.where(
(profile) =>
runtimeEndpointIds.contains(profile.proxyConnectionId),
)
.length;
return _buildMenuCard( return _buildMenuCard(
context, context,
children: [ children: [
for (var i = 0; i < rows.length; i++) ...[ Theme(
if (i > 0) _buildDivider(), data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
rows[i], child: ExpansionTile(
leading: Icon(
MdiIcons.transitConnectionVariant,
color: activeCount > 0
? AppColors.of(context).torActiveGreen
: null,
),
title: const Text('Connections'),
subtitle: Text(
activeCount > 0 ? '$activeCount connected' : 'None connected',
),
initiallyExpanded: connectionsExpanded,
onExpansionChanged: (_) => ref
.read(
persistedBoolProvider(
PersistedBoolKey.connectionsExpanded,
).notifier,
)
.toggle(),
children: [
for (final row in rows) row,
const Divider(indent: 56, endIndent: 16),
_buildSubTile(
'Manage Connections',
icon: MdiIcons.lanConnect,
onTap: () async {
Navigator.pop(context);
await const SingboxProxyProfilesRoute().push<void>(context);
},
),
], ],
),
),
], ],
); );
} }
@@ -2138,16 +2181,18 @@ class _ConnectionRow extends StatelessWidget {
final activeColor = AppColors.of(context).torActiveGreen; final activeColor = AppColors.of(context).torActiveGreen;
return ListTile( return ListTile(
// Trim the right padding by the IconButton's internal inset (~12px) so the contentPadding: const EdgeInsets.only(left: 56, right: 16),
// edit chevron's glyph lands at the same 16px from the edge as the plain
// trailing icons used by the Share/More/Containers rows, while keeping the
// button's full 48px touch target.
contentPadding: const EdgeInsets.only(left: 16, right: 16),
leading: Icon( leading: Icon(
icon, icon,
size: 20,
color: active ? activeColor : colorScheme.onSurfaceVariant, color: active ? activeColor : colorScheme.onSurfaceVariant,
), ),
title: Text(label, maxLines: 1, overflow: TextOverflow.ellipsis), title: Text(
label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14),
),
subtitle: Text(active ? 'Connected' : 'Off'), subtitle: Text(active ? 'Connected' : 'Off'),
onTap: enabled ? () => onToggle() : null, onTap: enabled ? () => onToggle() : null,
dense: true, dense: true,