cache
This commit is contained in:
@@ -431,4 +431,21 @@ enum CoreStatus { connecting, connected, disconnected }
|
||||
|
||||
enum RuleScene { added, disabled, custom }
|
||||
|
||||
enum ItemPosition { start, middle, end, startAndEnd }
|
||||
enum ItemPosition {
|
||||
start,
|
||||
middle,
|
||||
end,
|
||||
startAndEnd;
|
||||
|
||||
static ItemPosition get(int index, int length) {
|
||||
ItemPosition position = ItemPosition.middle;
|
||||
if (length == 1) {
|
||||
position = ItemPosition.startAndEnd;
|
||||
} else if (index == length - 1) {
|
||||
position = ItemPosition.end;
|
||||
} else if (index == 0) {
|
||||
position = ItemPosition.start;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,29 @@ class _CustomProxyGroupsView extends ConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildItem({
|
||||
required BuildContext context,
|
||||
required ProxyGroup proxyGroup,
|
||||
required int index,
|
||||
required int total,
|
||||
}) {
|
||||
final position = ItemPosition.get(index, total);
|
||||
return ItemPositionProvider(
|
||||
position: position,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: DecorationListItem(
|
||||
minVerticalPadding: 8,
|
||||
title: Text(proxyGroup.name),
|
||||
subtitle: Text(proxyGroup.type.name),
|
||||
onPressed: () {
|
||||
_handleEditProxyGroup(context, proxyGroup);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final proxyGroups = ref.watch(proxyGroupsProvider(profileId)).value ?? [];
|
||||
@@ -42,38 +65,19 @@ class _CustomProxyGroupsView extends ConsumerWidget {
|
||||
body: ReorderableListView.builder(
|
||||
buildDefaultDragHandles: false,
|
||||
padding: EdgeInsets.only(bottom: 16),
|
||||
itemBuilder: (_, index) {
|
||||
itemBuilder: (context, index) {
|
||||
final proxyGroup = proxyGroups[index];
|
||||
return ReorderableDelayedDragStartListener(
|
||||
key: ValueKey(proxyGroup),
|
||||
index: index,
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||
child: CommonCard(
|
||||
radius: 16,
|
||||
padding: EdgeInsets.all(16),
|
||||
onPressed: () {
|
||||
_handleEditProxyGroup(context, proxyGroup);
|
||||
},
|
||||
child: ListTile(
|
||||
minTileHeight: 0,
|
||||
minVerticalPadding: 0,
|
||||
titleTextStyle: context.textTheme.bodyMedium?.toJetBrainsMono,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 4,
|
||||
vertical: 4,
|
||||
),
|
||||
title: Text(proxyGroup.name),
|
||||
subtitle: Text(proxyGroup.type.name),
|
||||
),
|
||||
),
|
||||
child: _buildItem(
|
||||
context: context,
|
||||
proxyGroup: proxyGroup,
|
||||
total: proxyGroups.length,
|
||||
index: index,
|
||||
),
|
||||
);
|
||||
},
|
||||
itemExtent:
|
||||
28 +
|
||||
globalState.measure.bodyMediumHeight +
|
||||
globalState.measure.bodyLargeHeight,
|
||||
itemCount: proxyGroups.length,
|
||||
onReorder: (oldIndex, newIndex) {
|
||||
_handleReorder(ref, profileId, oldIndex, newIndex);
|
||||
@@ -248,7 +252,7 @@ class _EditProxyGroupViewState extends ConsumerState<_EditProxyGroupView> {
|
||||
Widget? trailing,
|
||||
final VoidCallback? onPressed,
|
||||
}) {
|
||||
return CommonInputListItem(
|
||||
return DecorationListItem(
|
||||
onPressed: onPressed,
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
@@ -589,6 +593,34 @@ class _EditProxiesViewState extends ConsumerState<_EditProxiesView> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildItem({
|
||||
required String proxyName,
|
||||
required String? proxyType,
|
||||
required int index,
|
||||
required int length,
|
||||
}) {
|
||||
final position = ItemPosition.get(index, length);
|
||||
return Container(
|
||||
key: Key(proxyName),
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: ItemPositionProvider(
|
||||
position: position,
|
||||
child: DecorationListItem(
|
||||
minVerticalPadding: 8,
|
||||
title: Text(proxyName),
|
||||
subtitle: Text(proxyType ?? proxyName.toLowerCase()),
|
||||
leading: CommonMinIconButtonTheme(
|
||||
child: IconButton.filledTonal(
|
||||
onPressed: () {},
|
||||
icon: Icon(Icons.remove, size: 18),
|
||||
padding: EdgeInsets.zero,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final profileId = ProfileIdProvider.of(context)!.profileId;
|
||||
@@ -645,44 +677,15 @@ class _EditProxiesViewState extends ConsumerState<_EditProxiesView> {
|
||||
SliverReorderableList(
|
||||
itemBuilder: (_, index) {
|
||||
final proxyName = proxyNames[index];
|
||||
return Container(
|
||||
key: Key(proxyName),
|
||||
margin: EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Flexible(
|
||||
child: CommonCard(
|
||||
radius: 18,
|
||||
onPressed: () {},
|
||||
child: ListTile(
|
||||
leading: CommonMinIconButtonTheme(
|
||||
child: IconButton.filledTonal(
|
||||
onPressed: () {},
|
||||
icon: Icon(Icons.remove, size: 18),
|
||||
padding: EdgeInsets.zero,
|
||||
),
|
||||
),
|
||||
minTileHeight:
|
||||
32 + globalState.measure.bodyMediumHeight,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
),
|
||||
title: Text(proxyName),
|
||||
subtitle: Text(
|
||||
proxyTypeMap[proxyName] ??
|
||||
proxyName.toLowerCase(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
return _buildItem(
|
||||
proxyName: proxyName,
|
||||
proxyType: proxyTypeMap[proxyName],
|
||||
index: index,
|
||||
length: proxyNames.length,
|
||||
);
|
||||
},
|
||||
itemExtent:
|
||||
24 +
|
||||
16 +
|
||||
globalState.measure.bodyMediumHeight +
|
||||
globalState.measure.bodyLargeHeight,
|
||||
itemCount: proxyNames.length,
|
||||
|
||||
@@ -439,19 +439,12 @@ class _ReorderableProfilesSheetState extends State<ReorderableProfilesSheet> {
|
||||
}
|
||||
|
||||
Widget _buildItem(int index, [bool isDecorator = false]) {
|
||||
ItemPosition position = ItemPosition.middle;
|
||||
if (profiles.length == 1) {
|
||||
position = ItemPosition.startAndEnd;
|
||||
} else if (index == profiles.length - 1) {
|
||||
position = ItemPosition.end;
|
||||
} else if (index == 0) {
|
||||
position = ItemPosition.start;
|
||||
}
|
||||
final position = ItemPosition.get(index, profiles.length);
|
||||
final profile = profiles[index];
|
||||
return ItemPositionProvider(
|
||||
key: Key(profile.id.toString()),
|
||||
position: position,
|
||||
child: CommonInputListItem(
|
||||
child: DecorationListItem(
|
||||
trailing: ReorderableDelayedDragStartListener(
|
||||
index: index,
|
||||
child: const Icon(Icons.drag_handle),
|
||||
|
||||
@@ -321,25 +321,18 @@ class _ListInputPageState extends ConsumerState<ListInputPage> {
|
||||
Widget _buildItem({
|
||||
required String value,
|
||||
required int index,
|
||||
required int totalLength,
|
||||
required int length,
|
||||
required bool isSelected,
|
||||
required bool isEditing,
|
||||
isDecorator = false,
|
||||
}) {
|
||||
ItemPosition position = ItemPosition.middle;
|
||||
if (totalLength == 1) {
|
||||
position = ItemPosition.startAndEnd;
|
||||
} else if (index == totalLength - 1) {
|
||||
position = ItemPosition.end;
|
||||
} else if (index == 0) {
|
||||
position = ItemPosition.start;
|
||||
}
|
||||
final position = ItemPosition.get(index, length);
|
||||
return ReorderableDelayedDragStartListener(
|
||||
key: ValueKey(value),
|
||||
index: index,
|
||||
child: ItemPositionProvider(
|
||||
position: position,
|
||||
child: CommonSelectedInputListItem(
|
||||
child: SelectedDecorationListItem(
|
||||
isDecorator: isDecorator,
|
||||
title: widget.titleBuilder(value),
|
||||
isSelected: isSelected,
|
||||
@@ -424,7 +417,7 @@ class _ListInputPageState extends ConsumerState<ListInputPage> {
|
||||
return _buildItem(
|
||||
value: value,
|
||||
index: index,
|
||||
totalLength: _items.length,
|
||||
length: _items.length,
|
||||
isSelected: selectedItems.contains(value),
|
||||
isEditing: selectedItems.isNotEmpty,
|
||||
);
|
||||
@@ -435,7 +428,7 @@ class _ListInputPageState extends ConsumerState<ListInputPage> {
|
||||
_buildItem(
|
||||
value: value,
|
||||
index: index,
|
||||
totalLength: _items.length,
|
||||
length: _items.length,
|
||||
isDecorator: true,
|
||||
isSelected: selectedItems.contains(value),
|
||||
isEditing: selectedItems.isNotEmpty,
|
||||
@@ -581,25 +574,18 @@ class _MapInputPageState extends ConsumerState<MapInputPage> {
|
||||
Widget _buildItem({
|
||||
required MapEntry<String, String> value,
|
||||
required int index,
|
||||
required int totalLength,
|
||||
required int length,
|
||||
required bool isSelected,
|
||||
required bool isEditing,
|
||||
isDecorator = false,
|
||||
}) {
|
||||
ItemPosition position = ItemPosition.middle;
|
||||
if (totalLength == 1) {
|
||||
position = ItemPosition.startAndEnd;
|
||||
} else if (index == totalLength - 1) {
|
||||
position = ItemPosition.end;
|
||||
} else if (index == 0) {
|
||||
position = ItemPosition.start;
|
||||
}
|
||||
final position = ItemPosition.get(index, length);
|
||||
return ReorderableDelayedDragStartListener(
|
||||
key: ValueKey(value),
|
||||
index: index,
|
||||
child: ItemPositionProvider(
|
||||
position: position,
|
||||
child: CommonSelectedInputListItem(
|
||||
child: SelectedDecorationListItem(
|
||||
isDecorator: isDecorator,
|
||||
title: widget.titleBuilder(value),
|
||||
leading: widget.leadingBuilder != null
|
||||
@@ -687,7 +673,7 @@ class _MapInputPageState extends ConsumerState<MapInputPage> {
|
||||
return _buildItem(
|
||||
value: value,
|
||||
index: index,
|
||||
totalLength: _items.length,
|
||||
length: _items.length,
|
||||
isSelected: selectedItems.contains(value.key),
|
||||
isEditing: selectedItems.isNotEmpty,
|
||||
);
|
||||
@@ -698,7 +684,7 @@ class _MapInputPageState extends ConsumerState<MapInputPage> {
|
||||
_buildItem(
|
||||
value: value,
|
||||
index: index,
|
||||
totalLength: _items.length,
|
||||
length: _items.length,
|
||||
isDecorator: true,
|
||||
isSelected: selectedItems.contains(value.key),
|
||||
isEditing: selectedItems.isNotEmpty,
|
||||
|
||||
@@ -548,15 +548,9 @@ Widget generateSectionV3({
|
||||
List<Widget>? actions,
|
||||
}) {
|
||||
final genItems = items.mapIndexed<Widget>((index, item) {
|
||||
if (items.length == 1) {
|
||||
return ItemPositionProvider(
|
||||
position: ItemPosition.startAndEnd,
|
||||
child: item,
|
||||
);
|
||||
} else if (index == 0) {
|
||||
return ItemPositionProvider(position: ItemPosition.start, child: item);
|
||||
} else if (index == items.length - 1) {
|
||||
return ItemPositionProvider(position: ItemPosition.end, child: item);
|
||||
final position = ItemPosition.get(index, items.length);
|
||||
if (position != ItemPosition.middle) {
|
||||
return ItemPositionProvider(position: position, child: item);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
@@ -649,24 +643,26 @@ class CommonSelectedListItem extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class CommonInputListItem extends StatelessWidget {
|
||||
class DecorationListItem extends StatelessWidget {
|
||||
final bool isDecorator;
|
||||
final Widget? title;
|
||||
final Widget title;
|
||||
final Widget? subtitle;
|
||||
final Widget? leading;
|
||||
final Widget? trailing;
|
||||
final bool? isSelected;
|
||||
final VoidCallback? onPressed;
|
||||
final double minVerticalPadding;
|
||||
|
||||
const CommonInputListItem({
|
||||
const DecorationListItem({
|
||||
super.key,
|
||||
this.isDecorator = false,
|
||||
this.title,
|
||||
required this.title,
|
||||
this.leading,
|
||||
this.trailing,
|
||||
this.subtitle,
|
||||
this.isSelected,
|
||||
this.onPressed,
|
||||
this.minVerticalPadding = 6,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -681,7 +677,7 @@ class CommonInputListItem extends StatelessWidget {
|
||||
ItemPosition.startAndEnd,
|
||||
].contains(position);
|
||||
return Container(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: ShapeDecoration(
|
||||
shape: isDecorator == true
|
||||
? LinearBorder.none
|
||||
@@ -695,10 +691,12 @@ class CommonInputListItem extends StatelessWidget {
|
||||
child: CommonCard(
|
||||
radius: 0,
|
||||
isSelected: isSelected,
|
||||
padding: EdgeInsets.zero,
|
||||
type: CommonCardType.filled,
|
||||
onPressed: onPressed,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
child: ListTile(
|
||||
@@ -706,7 +704,7 @@ class CommonInputListItem extends StatelessWidget {
|
||||
contentPadding: const EdgeInsets.only(right: 16, left: 16),
|
||||
title: title,
|
||||
subtitle: subtitle,
|
||||
minVerticalPadding: 0,
|
||||
minVerticalPadding: minVerticalPadding,
|
||||
minTileHeight: 54,
|
||||
trailing: trailing,
|
||||
),
|
||||
@@ -720,7 +718,7 @@ class CommonInputListItem extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class CommonSelectedInputListItem extends StatelessWidget {
|
||||
class SelectedDecorationListItem extends StatelessWidget {
|
||||
final bool isSelected;
|
||||
final bool isEditing;
|
||||
final Widget title;
|
||||
@@ -730,7 +728,7 @@ class CommonSelectedInputListItem extends StatelessWidget {
|
||||
final bool isDecorator;
|
||||
final Widget? leading;
|
||||
|
||||
const CommonSelectedInputListItem({
|
||||
const SelectedDecorationListItem({
|
||||
super.key,
|
||||
required this.isSelected,
|
||||
required this.onSelected,
|
||||
@@ -744,7 +742,7 @@ class CommonSelectedInputListItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CommonInputListItem(
|
||||
return DecorationListItem(
|
||||
title: title,
|
||||
isDecorator: isDecorator,
|
||||
isSelected: isSelected,
|
||||
|
||||
Reference in New Issue
Block a user