style: streamline settings section shells

This commit is contained in:
Haitao Pan 2026-03-30 15:52:23 +08:00
parent 2b836c5c6e
commit 8ab1c09891
3 changed files with 76 additions and 45 deletions

View File

@ -76,6 +76,7 @@ class SettingsPageStateInternal extends State<SettingsPage> {
bool vaultServerExpandedInternal = true;
bool aiGatewayExpandedInternal = true;
bool externalAcpExpandedInternal = true;
bool skillsDirectoryAuthorizationExpandedInternal = true;
int selectedGatewayProfileIndexInternal = kGatewayLocalProfileIndex;
String gatewaySetupCodeSyncedValueInternal = '';
String gatewayHostSyncedValueInternal = '';
@ -251,7 +252,7 @@ class SettingsPageStateInternal extends State<SettingsPage> {
),
),
child: SettingsPageBodyShell(
padding: const EdgeInsets.fromLTRB(32, 32, 32, 8),
padding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
breadcrumbs: buildSettingsBreadcrumbs(
controller,
tab: tabInternal,

View File

@ -161,7 +161,21 @@ extension SettingsPageGatewayMixinInternal on SettingsPageStateInternal {
),
],
GatewayIntegrationSubTabInternal.skills => <Widget>[
SkillDirectoryAuthorizationCard(controller: controller),
buildCollapsibleGatewaySectionInternal(
context: context,
title: appText(
'SKILLS 目录授权',
'SKILLS Directory Authorization',
),
expanded: skillsDirectoryAuthorizationExpandedInternal,
onChanged: (value) => setStateInternal(() {
skillsDirectoryAuthorizationExpandedInternal = value;
}),
child: SkillDirectoryAuthorizationCard(
controller: controller,
showHeader: false,
),
),
],
},
];
@ -232,7 +246,21 @@ extension SettingsPageGatewayMixinInternal on SettingsPageStateInternal {
),
),
const SizedBox(height: 16),
SkillDirectoryAuthorizationCard(controller: controller),
buildCollapsibleGatewaySectionInternal(
context: context,
title: appText(
'SKILLS 目录授权',
'SKILLS Directory Authorization',
),
expanded: skillsDirectoryAuthorizationExpandedInternal,
onChanged: (value) => setStateInternal(() {
skillsDirectoryAuthorizationExpandedInternal = value;
}),
child: SkillDirectoryAuthorizationCard(
controller: controller,
showHeader: false,
),
),
];
}
@ -651,45 +679,40 @@ extension SettingsPageGatewayMixinInternal on SettingsPageStateInternal {
required Widget child,
}) {
final theme = Theme.of(context);
return SurfaceCard(
borderWidth: settingsHairlineBorderWidthInternal,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
borderRadius: BorderRadius.circular(18),
onTap: () => onChanged(!expanded),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Expanded(
child: Text(title, style: theme.textTheme.titleLarge),
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
borderRadius: BorderRadius.circular(18),
onTap: () => onChanged(!expanded),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Expanded(child: Text(title, style: theme.textTheme.titleLarge)),
IconButton(
tooltip: expanded
? appText('折叠', 'Collapse')
: appText('展开', 'Expand'),
onPressed: () => onChanged(!expanded),
icon: AnimatedRotation(
turns: expanded ? 0.5 : 0,
duration: const Duration(milliseconds: 180),
curve: Curves.easeOut,
child: const Icon(Icons.expand_more_rounded),
),
IconButton(
tooltip: expanded
? appText('折叠', 'Collapse')
: appText('展开', 'Expand'),
onPressed: () => onChanged(!expanded),
icon: AnimatedRotation(
turns: expanded ? 0.5 : 0,
duration: const Duration(milliseconds: 180),
curve: Curves.easeOut,
child: const Icon(Icons.expand_more_rounded),
),
),
],
),
),
],
),
),
AnimatedSize(
duration: const Duration(milliseconds: 180),
curve: Curves.easeOut,
alignment: Alignment.topCenter,
child: expanded ? child : const SizedBox.shrink(),
),
],
),
),
AnimatedSize(
duration: const Duration(milliseconds: 180),
curve: Curves.easeOut,
alignment: Alignment.topCenter,
child: expanded ? child : const SizedBox.shrink(),
),
],
);
}
}

View File

@ -9,9 +9,14 @@ import '../../widgets/surface_card.dart';
enum _SkillDirectoryAuthorizationMode { direct, picker }
class SkillDirectoryAuthorizationCard extends StatefulWidget {
const SkillDirectoryAuthorizationCard({super.key, required this.controller});
const SkillDirectoryAuthorizationCard({
super.key,
required this.controller,
this.showHeader = true,
});
final AppController controller;
final bool showHeader;
@override
State<SkillDirectoryAuthorizationCard> createState() =>
@ -48,11 +53,13 @@ class _SkillDirectoryAuthorizationCardState
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
appText('SKILLS 目录授权', 'SKILLS Directory Authorization'),
style: theme.textTheme.titleLarge,
),
const SizedBox(height: 8),
if (widget.showHeader) ...[
Text(
appText('SKILLS 目录授权', 'SKILLS Directory Authorization'),
style: theme.textTheme.titleLarge,
),
const SizedBox(height: 8),
],
Text(
appText(
'预设目录支持直接按路径加入;也可以把终端输出里的目录或单个技能包路径直接贴进来批量导入。系统目录选择器保留在同行旁侧,作为可选授权方式。设置中心修改会写入 settings.yaml。',