mirror of
https://github.com/jonasbark/swiftcontrol.git
synced 2026-02-18 00:17:40 +01:00
158 lines
6.9 KiB
Dart
158 lines
6.9 KiB
Dart
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
|
import 'package:swift_control/main.dart';
|
|
import 'package:swift_control/pages/button_edit.dart';
|
|
import 'package:swift_control/utils/core.dart';
|
|
import 'package:swift_control/utils/i18n_extension.dart';
|
|
import 'package:swift_control/utils/keymap/apps/custom_app.dart';
|
|
import 'package:swift_control/utils/keymap/apps/my_whoosh.dart';
|
|
import 'package:swift_control/utils/keymap/apps/supported_app.dart';
|
|
import 'package:swift_control/utils/requirements/multi.dart';
|
|
import 'package:swift_control/widgets/ui/colored_title.dart';
|
|
import 'package:swift_control/widgets/ui/warning.dart';
|
|
|
|
class ConfigurationPage extends StatefulWidget {
|
|
final VoidCallback onUpdate;
|
|
const ConfigurationPage({super.key, required this.onUpdate});
|
|
|
|
@override
|
|
State<ConfigurationPage> createState() => _ConfigurationPageState();
|
|
}
|
|
|
|
class _ConfigurationPageState extends State<ConfigurationPage> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
spacing: 12,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text.rich(
|
|
TextSpan(
|
|
children: [
|
|
TextSpan(text: '${context.i18n.needHelpClickHelp} '),
|
|
WidgetSpan(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(top: 4.0),
|
|
child: Icon(Icons.help_outline),
|
|
),
|
|
),
|
|
TextSpan(text: ' ${context.i18n.needHelpDontHesitate}'),
|
|
],
|
|
),
|
|
).small.muted,
|
|
SizedBox(height: 4),
|
|
ColoredTitle(text: context.i18n.setupTrainer),
|
|
Card(
|
|
fillColor: Theme.of(context).colorScheme.background,
|
|
filled: true,
|
|
borderWidth: 1,
|
|
borderColor: Theme.of(context).colorScheme.border,
|
|
child: Builder(
|
|
builder: (context) {
|
|
final isMobile = MediaQuery.sizeOf(context).width < 600;
|
|
return StatefulBuilder(
|
|
builder: (c, setState) => Column(
|
|
spacing: 8,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Select<SupportedApp>(
|
|
constraints: BoxConstraints(maxWidth: 400, minWidth: 400),
|
|
itemBuilder: (c, app) => Text(screenshotMode ? 'Trainer app' : app.name),
|
|
popup: SelectPopup(
|
|
items: SelectItemList(
|
|
children: SupportedApp.supportedApps.map((app) {
|
|
return SelectItemButton(
|
|
value: app,
|
|
child: Text(app.name),
|
|
);
|
|
}).toList(),
|
|
),
|
|
).call,
|
|
placeholder: Text(context.i18n.selectTrainerAppPlaceholder),
|
|
value: core.settings.getTrainerApp(),
|
|
onChanged: (selectedApp) async {
|
|
if (core.settings.getTrainerApp() is MyWhoosh &&
|
|
selectedApp is! MyWhoosh &&
|
|
core.whooshLink.isStarted.value) {
|
|
core.whooshLink.stopServer();
|
|
}
|
|
core.settings.setTrainerApp(selectedApp!);
|
|
if (core.settings.getLastTarget() == null && Target.thisDevice.isCompatible) {
|
|
await _setTarget(context, Target.thisDevice);
|
|
} else if (core.settings.getLastTarget() == null && Target.otherDevice.isCompatible) {
|
|
await _setTarget(context, Target.otherDevice);
|
|
}
|
|
if (core.actionHandler.supportedApp == null ||
|
|
(core.actionHandler.supportedApp is! CustomApp && selectedApp is! CustomApp)) {
|
|
core.actionHandler.init(selectedApp);
|
|
core.settings.setKeyMap(selectedApp);
|
|
}
|
|
widget.onUpdate();
|
|
setState(() {});
|
|
},
|
|
),
|
|
if (core.settings.getTrainerApp() != null) ...[
|
|
SizedBox(height: 8),
|
|
Text(
|
|
context.i18n.selectTargetWhereAppRuns(
|
|
screenshotMode ? 'Trainer app' : core.settings.getTrainerApp()?.name ?? 'the Trainer app',
|
|
),
|
|
).small,
|
|
Flex(
|
|
direction: isMobile ? Axis.vertical : Axis.horizontal,
|
|
spacing: 8,
|
|
children: [Target.thisDevice, Target.otherDevice]
|
|
.map(
|
|
(target) => SelectableCard(
|
|
title: Text(target.getTitle(context)),
|
|
icon: target.icon,
|
|
isActive: target == core.settings.getLastTarget(),
|
|
subtitle: !target.isCompatible
|
|
? Text(context.i18n.platformRestrictionNotSupported)
|
|
: null,
|
|
onPressed: !target.isCompatible
|
|
? null
|
|
: () async {
|
|
await _setTarget(context, target);
|
|
setState(() {});
|
|
widget.onUpdate();
|
|
},
|
|
),
|
|
)
|
|
.map((e) => !isMobile ? Expanded(child: e) : e)
|
|
.toList(),
|
|
),
|
|
],
|
|
|
|
if (core.settings.getLastTarget() == Target.otherDevice &&
|
|
!core.logic.hasRecommendedConnectionMethods) ...[
|
|
SizedBox(height: 8),
|
|
Warning(
|
|
children: [
|
|
Text(
|
|
'BikeControl is available on iOS, Android, Windows and macOS. For proper support for ${core.settings.getTrainerApp()?.name} please download BikeControl on that device.',
|
|
).small,
|
|
],
|
|
),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Future<void> _setTarget(BuildContext context, Target target) async {
|
|
await core.settings.setLastTarget(target);
|
|
|
|
if (core.settings.getTrainerApp()?.supportsOpenBikeProtocol == true && !core.logic.emulatorEnabled) {
|
|
core.settings.setObpMdnsEnabled(true);
|
|
}
|
|
core.logic.startEnabledConnectionMethod();
|
|
}
|
|
}
|