Fix web ACP endpoint input stability
This commit is contained in:
parent
148ef162ae
commit
38050c681d
@ -153,9 +153,9 @@ extension WebSettingsPageGatewayMixinInternal on WebSettingsPageStateInternal {
|
||||
() => directMessageInternal = result.message,
|
||||
);
|
||||
},
|
||||
child: Text(appText('测试连接', 'Test')),
|
||||
child: Text(appText('测试连接', 'Test Connection')),
|
||||
),
|
||||
FilledButton.icon(
|
||||
FilledButton(
|
||||
onPressed: controller.aiGatewayBusy
|
||||
? null
|
||||
: () async {
|
||||
@ -195,7 +195,7 @@ extension WebSettingsPageGatewayMixinInternal on WebSettingsPageStateInternal {
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: controller.aiGatewayBusy
|
||||
child: controller.aiGatewayBusy
|
||||
? const SizedBox(
|
||||
width: 14,
|
||||
height: 14,
|
||||
@ -203,8 +203,7 @@ extension WebSettingsPageGatewayMixinInternal on WebSettingsPageStateInternal {
|
||||
strokeWidth: 2,
|
||||
),
|
||||
)
|
||||
: const Icon(Icons.play_circle_outline_rounded),
|
||||
label: Text(appText('保存并生效', 'Save & apply')),
|
||||
: Text(appText('保存并生效', 'Save & apply')),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -263,6 +262,7 @@ extension WebSettingsPageGatewayMixinInternal on WebSettingsPageStateInternal {
|
||||
const SizedBox(height: 16),
|
||||
...controller.settingsDraft.externalAcpEndpoints.map(
|
||||
(profile) => Padding(
|
||||
key: ValueKey('web-external-acp-card-${profile.providerKey}'),
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: buildExternalAcpProviderCardInternal(
|
||||
context,
|
||||
@ -335,19 +335,21 @@ extension WebSettingsPageGatewayMixinInternal on WebSettingsPageStateInternal {
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
TextField(
|
||||
key: ValueKey('web-external-acp-label-${profile.providerKey}'),
|
||||
controller: labelController,
|
||||
decoration: InputDecoration(
|
||||
labelText: appText('显示名称', 'Display name'),
|
||||
),
|
||||
onChanged: (_) => stageExternalAcpDraftInternal(controller),
|
||||
onChanged: (_) => setStateInternal(() {}),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
TextField(
|
||||
key: ValueKey('web-external-acp-endpoint-${profile.providerKey}'),
|
||||
controller: endpointController,
|
||||
decoration: InputDecoration(
|
||||
labelText: appText('ACP Server Endpoint', 'ACP Server Endpoint'),
|
||||
),
|
||||
onChanged: (_) => stageExternalAcpDraftInternal(controller),
|
||||
onChanged: (_) => setStateInternal(() {}),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
@ -652,9 +654,9 @@ extension WebSettingsPageGatewayMixinInternal on WebSettingsPageStateInternal {
|
||||
'${result.state.toUpperCase()} · ${result.message}',
|
||||
);
|
||||
},
|
||||
child: Text(appText('Test', 'Test')),
|
||||
child: Text(appText('测试连接', 'Test Connection')),
|
||||
),
|
||||
FilledButton.icon(
|
||||
FilledButton(
|
||||
onPressed: controller.relayBusy
|
||||
? null
|
||||
: () async {
|
||||
@ -686,14 +688,13 @@ extension WebSettingsPageGatewayMixinInternal on WebSettingsPageStateInternal {
|
||||
onMessageChanged('$error');
|
||||
}
|
||||
},
|
||||
icon: controller.relayBusy
|
||||
child: controller.relayBusy
|
||||
? const SizedBox(
|
||||
width: 14,
|
||||
height: 14,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Icon(Icons.play_circle_outline_rounded),
|
||||
label: Text(appText('保存并生效', 'Save & apply')),
|
||||
: Text(appText('保存并生效', 'Save & apply')),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
65
test/features/web_settings_page_external_acp_suite.dart
Normal file
65
test/features/web_settings_page_external_acp_suite.dart
Normal file
@ -0,0 +1,65 @@
|
||||
@TestOn('vm')
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:xworkmate/app/app_controller_web.dart' as web_app;
|
||||
import 'package:xworkmate/models/app_models.dart';
|
||||
import 'package:xworkmate/runtime/runtime_models.dart';
|
||||
import 'package:xworkmate/web/web_settings_page_core.dart';
|
||||
|
||||
import '../test_support.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Web external ACP editor supports continuous input', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
SharedPreferences.setMockInitialValues(<String, Object>{});
|
||||
final controller = web_app.AppController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
await tester.pumpAndSettle();
|
||||
final customProfile = buildCustomExternalAcpEndpointProfile(
|
||||
controller.settingsDraft.externalAcpEndpoints,
|
||||
label: 'Initial Name',
|
||||
endpoint: 'wss://initial.example.com/acp',
|
||||
);
|
||||
await controller.saveSettingsDraft(
|
||||
controller.settingsDraft.copyWith(
|
||||
externalAcpEndpoints: <ExternalAcpEndpointProfile>[
|
||||
...controller.settingsDraft.externalAcpEndpoints,
|
||||
customProfile,
|
||||
],
|
||||
),
|
||||
);
|
||||
controller.setSettingsTab(SettingsTab.gateway);
|
||||
|
||||
await pumpPage(
|
||||
tester,
|
||||
child: SizedBox(
|
||||
width: 1280,
|
||||
height: 960,
|
||||
child: WebSettingsPage(controller: controller, showSectionTabs: false),
|
||||
),
|
||||
platform: TargetPlatform.macOS,
|
||||
);
|
||||
|
||||
final labelField = find.byKey(
|
||||
ValueKey('web-external-acp-label-${customProfile.providerKey}'),
|
||||
);
|
||||
|
||||
expect(labelField, findsOneWidget);
|
||||
expect(find.text('测试连接'), findsWidgets);
|
||||
expect(find.text('保存并生效'), findsWidgets);
|
||||
|
||||
await tester.enterText(labelField, 'A');
|
||||
await tester.pump();
|
||||
await tester.enterText(labelField, 'AB');
|
||||
await tester.pump();
|
||||
await tester.enterText(labelField, 'ABC');
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('ABC'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user