diff --git a/lib/bluetooth/devices/base_device.dart b/lib/bluetooth/devices/base_device.dart index e4818d8..09304bb 100644 --- a/lib/bluetooth/devices/base_device.dart +++ b/lib/bluetooth/devices/base_device.dart @@ -6,6 +6,7 @@ import 'package:swift_control/bluetooth/devices/zwift/constants.dart'; import 'package:swift_control/utils/actions/desktop.dart'; import 'package:swift_control/utils/core.dart'; import 'package:swift_control/utils/keymap/apps/custom_app.dart'; +import 'package:swift_control/utils/keymap/manager.dart'; import '../../utils/keymap/buttons.dart'; import '../messages/notification.dart'; @@ -148,17 +149,18 @@ abstract class BaseDevice { Widget showInformation(BuildContext context); - ControllerButton? getOrAddButton(String key, ControllerButton Function() creator) { - if (core.actionHandler.supportedApp is CustomApp) { - final button = core.actionHandler.supportedApp?.keymap.getOrAddButton(key, creator); - - if (button != null && availableButtons.none((e) => e.name == button.name)) { - availableButtons.add(button); - core.settings.setKeyMap(core.actionHandler.supportedApp!); - } - return button; - } else { - return null; + Future getOrAddButton(String key, ControllerButton Function() creator) async { + if (core.actionHandler.supportedApp is! CustomApp) { + final currentProfile = core.actionHandler.supportedApp!.name; + // should we display this to the user? + await KeymapManager().duplicate(null, currentProfile, skipName: '$currentProfile (Copy)'); } + final button = core.actionHandler.supportedApp!.keymap.getOrAddButton(key, creator); + + if (availableButtons.none((e) => e.name == button.name)) { + availableButtons.add(button); + core.settings.setKeyMap(core.actionHandler.supportedApp!); + } + return button; } } diff --git a/lib/bluetooth/devices/gamepad/gamepad_device.dart b/lib/bluetooth/devices/gamepad/gamepad_device.dart index 2f748f3..487f0ba 100644 --- a/lib/bluetooth/devices/gamepad/gamepad_device.dart +++ b/lib/bluetooth/devices/gamepad/gamepad_device.dart @@ -2,7 +2,6 @@ import 'package:dartx/dartx.dart'; import 'package:flutter/material.dart'; import 'package:gamepads/gamepads.dart'; import 'package:swift_control/bluetooth/devices/base_device.dart'; -import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart'; import 'package:swift_control/bluetooth/messages/notification.dart'; import 'package:swift_control/pages/device.dart'; import 'package:swift_control/utils/core.dart'; @@ -21,21 +20,15 @@ class GamepadDevice extends BaseDevice { @override Future connect() async { - Gamepads.eventsByGamepad(id).listen((event) { + Gamepads.eventsByGamepad(id).listen((event) async { actionStreamInternal.add(LogNotification('Gamepad event: $event')); - ControllerButton? button = getOrAddButton( + ControllerButton button = await getOrAddButton( event.key, () => ControllerButton(event.key), ); - if (button == null && event.value == 0) { - actionStreamInternal.add( - AlertNotification(LogLevel.LOGLEVEL_WARNING, 'Use a custom keymap to use the buttons on $name.'), - ); - } - - final buttonsClicked = event.value == 0.0 && button != null ? [button] : []; + final buttonsClicked = event.value == 0.0 ? [button] : []; if (_lastButtonsClicked.contentEquals(buttonsClicked) == false) { handleButtonsClicked(buttonsClicked); } diff --git a/lib/bluetooth/devices/shimano/shimano_di2.dart b/lib/bluetooth/devices/shimano/shimano_di2.dart index fb4b5c0..099d85f 100644 --- a/lib/bluetooth/devices/shimano/shimano_di2.dart +++ b/lib/bluetooth/devices/shimano/shimano_di2.dart @@ -51,17 +51,17 @@ class ShimanoDi2 extends BluetoothDevice { final clickedButtons = []; - channels.forEachIndexed((int value, int index) { + channels.forEachIndexed((int value, int index) async { final didChange = _lastButtons[index] != value; _lastButtons[index] = value; final readableIndex = index + 1; - final button = getOrAddButton( + final button = await getOrAddButton( 'D-Fly Channel $readableIndex', () => ControllerButton('D-Fly Channel $readableIndex'), ); - if (didChange && button != null) { + if (didChange) { clickedButtons.add(button); } }); diff --git a/lib/utils/actions/android.dart b/lib/utils/actions/android.dart index 4975d1b..fd91842 100644 --- a/lib/utils/actions/android.dart +++ b/lib/utils/actions/android.dart @@ -27,9 +27,9 @@ class AndroidActions extends BaseActions { } }); - hidKeyPressed().listen((keyPressed) { + hidKeyPressed().listen((keyPressed) async { final hidDevice = HidDevice(keyPressed.source); - final button = hidDevice.getOrAddButton(keyPressed.hidKey, () => ControllerButton(keyPressed.hidKey))!; + final button = await hidDevice.getOrAddButton(keyPressed.hidKey, () => ControllerButton(keyPressed.hidKey))!; var availableDevice = core.connection.controllerDevices.firstOrNullWhere((e) => e.name == hidDevice.name); if (availableDevice == null) { diff --git a/lib/utils/core.dart b/lib/utils/core.dart index a1000eb..c0c40de 100644 --- a/lib/utils/core.dart +++ b/lib/utils/core.dart @@ -350,14 +350,14 @@ class MediaKeyHandler { }); } - void _onMediaKeyPressedListener(PressedButton mediaKey) { + Future _onMediaKeyPressedListener(PressedButton mediaKey) async { final hidDevice = HidDevice('HID Device'); final keyPressed = mediaKey.name; - final button = hidDevice.getOrAddButton( + final button = await hidDevice.getOrAddButton( keyPressed, () => ControllerButton(keyPressed), - )!; + ); var availableDevice = core.connection.controllerDevices.firstOrNullWhere((e) => e.name == hidDevice.name); if (availableDevice == null) { diff --git a/lib/utils/keymap/manager.dart b/lib/utils/keymap/manager.dart index 17e11c8..ea510d4 100644 --- a/lib/utils/keymap/manager.dart +++ b/lib/utils/keymap/manager.dart @@ -231,8 +231,8 @@ class KeymapManager { ); } - Future duplicate(BuildContext context, String currentProfile, {String? skipName}) async { - final newName = skipName ?? await _showDuplicateProfileDialog(context, currentProfile); + Future duplicate(BuildContext? context, String currentProfile, {String? skipName}) async { + final newName = skipName ?? await _showDuplicateProfileDialog(context!, currentProfile); if (newName != null && newName.isNotEmpty) { if (core.actionHandler.supportedApp is CustomApp) { await core.settings.duplicateCustomAppProfile(currentProfile, newName);