mirror of
https://github.com/jonasbark/swiftcontrol.git
synced 2026-02-18 00:17:40 +01:00
Remove documentation file and refactor to use Settings methods instead of exposing prefs
Co-authored-by: jonasbark <1151304+jonasbark@users.noreply.github.com>
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
# Custom Profiles Feature
|
||||
|
||||
## Overview
|
||||
This feature allows users to create and manage multiple custom keymap profiles for different activity types (e.g., Workout, Race, Event, Workout with Coach).
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. CustomApp Class (`lib/utils/keymap/apps/custom_app.dart`)
|
||||
- Added `profileName` field to support named profiles
|
||||
- Each CustomApp instance can now have a unique name
|
||||
- Constructor now accepts an optional `profileName` parameter (defaults to 'Custom')
|
||||
|
||||
### 2. Settings Class (`lib/utils/settings/settings.dart`)
|
||||
- Modified storage mechanism to support multiple custom profiles
|
||||
- Old format: `customapp` → single profile
|
||||
- New format: `customapp_<profileName>` → multiple profiles
|
||||
- Added `getCustomAppProfiles()` to retrieve all saved custom profiles
|
||||
- Added `duplicateCustomAppProfile()` to copy profiles
|
||||
- Added `deleteCustomAppProfile()` to remove profiles
|
||||
- Implemented backward compatibility migration from old `customapp` key to new `customapp_Custom` key
|
||||
- Exposed `prefs` getter for UI access
|
||||
|
||||
### 3. Device Page UI (`lib/pages/device.dart`)
|
||||
- Added `_getAllApps()` method to dynamically build app list including all custom profiles
|
||||
- Added "New Custom Profile" button to create new profiles
|
||||
- Added "Manage Profile" button (visible when a CustomApp is selected) with options to:
|
||||
- Rename profile
|
||||
- Duplicate profile
|
||||
- Delete profile
|
||||
- Updated dropdown menu to use dynamic app list
|
||||
|
||||
### 4. Dialog Helpers
|
||||
Added several dialog methods to handle user interactions:
|
||||
- `_showNewProfileDialog()` - Create new profile
|
||||
- `_showManageProfileDialog()` - Select management action
|
||||
- `_showRenameProfileDialog()` - Rename existing profile
|
||||
- `_showDuplicateProfileDialog()` - Duplicate existing profile
|
||||
- `_showDeleteConfirmDialog()` - Confirm deletion
|
||||
|
||||
## User Experience
|
||||
|
||||
### Creating a New Profile
|
||||
1. Click "New Custom Profile" button
|
||||
2. Enter a name (e.g., "Workout", "Race", "Event")
|
||||
3. Customize the keymap using the "Customize Keymap" button
|
||||
4. The profile is automatically saved
|
||||
|
||||
### Switching Between Profiles
|
||||
- Use the dropdown menu to select any saved custom profile
|
||||
- All predefined keymaps (MyWhoosh, TrainingPeaks, Biketerra) remain available
|
||||
|
||||
### Managing Profiles
|
||||
1. Select a custom profile from the dropdown
|
||||
2. Click "Manage Profile" button
|
||||
3. Choose an action:
|
||||
- **Rename**: Change the profile name
|
||||
- **Duplicate**: Create a copy with a new name
|
||||
- **Delete**: Remove the profile (with confirmation)
|
||||
|
||||
## Backward Compatibility
|
||||
- Existing users with a single custom keymap will have it automatically migrated to the new format as "Custom"
|
||||
- No data loss during migration
|
||||
- Old `customapp` key is removed after successful migration
|
||||
|
||||
## Testing
|
||||
Comprehensive test suite added in `test/custom_profile_test.dart` covering:
|
||||
- Profile creation with default and custom names
|
||||
- Saving and retrieving profiles
|
||||
- Listing multiple profiles
|
||||
- Duplicating profiles
|
||||
- Deleting profiles
|
||||
- Migration from old format
|
||||
- Prevention of duplicate migrations
|
||||
|
||||
## Storage Format
|
||||
- **Profile keymaps**: `customapp_<profileName>` → List<String>
|
||||
- **Current app**: `app` → String (profile name)
|
||||
- Example:
|
||||
```
|
||||
customapp_Workout: [...keymap data...]
|
||||
customapp_Race: [...keymap data...]
|
||||
customapp_Event: [...keymap data...]
|
||||
app: "Race"
|
||||
```
|
||||
@@ -33,7 +33,7 @@ class _DevicePageState extends State<DevicePage> {
|
||||
final customProfiles = settings.getCustomAppProfiles();
|
||||
final customApps = customProfiles.map((profile) {
|
||||
final customApp = CustomApp(profileName: profile);
|
||||
final savedKeymap = settings.prefs.getStringList('customapp_$profile');
|
||||
final savedKeymap = settings.getCustomAppKeymap(profile);
|
||||
if (savedKeymap != null) {
|
||||
customApp.decodeKeymap(savedKeymap);
|
||||
}
|
||||
@@ -225,7 +225,7 @@ ${it.firmwareVersion != null ? ' - Firmware Version: ${it.firmwareVersion}' : ''
|
||||
await settings.duplicateCustomAppProfile(currentProfile, newName);
|
||||
await settings.deleteCustomAppProfile(currentProfile);
|
||||
final customApp = CustomApp(profileName: newName);
|
||||
final savedKeymap = settings.prefs.getStringList('customapp_$newName');
|
||||
final savedKeymap = settings.getCustomAppKeymap(newName);
|
||||
if (savedKeymap != null) {
|
||||
customApp.decodeKeymap(savedKeymap);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ ${it.firmwareVersion != null ? ' - Firmware Version: ${it.firmwareVersion}' : ''
|
||||
if (newName != null && newName.isNotEmpty) {
|
||||
await settings.duplicateCustomAppProfile(currentProfile, newName);
|
||||
final customApp = CustomApp(profileName: newName);
|
||||
final savedKeymap = settings.prefs.getStringList('customapp_$newName');
|
||||
final savedKeymap = settings.getCustomAppKeymap(newName);
|
||||
if (savedKeymap != null) {
|
||||
customApp.decodeKeymap(savedKeymap);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ import '../keymap/apps/custom_app.dart';
|
||||
|
||||
class Settings {
|
||||
late final SharedPreferences _prefs;
|
||||
|
||||
SharedPreferences get prefs => _prefs;
|
||||
|
||||
Future<void> init() async {
|
||||
_prefs = await SharedPreferences.getInstance();
|
||||
@@ -65,6 +63,10 @@ class Settings {
|
||||
return keys.map((key) => key.replaceFirst('customapp_', '')).toList();
|
||||
}
|
||||
|
||||
List<String>? getCustomAppKeymap(String profileName) {
|
||||
return _prefs.getStringList('customapp_$profileName');
|
||||
}
|
||||
|
||||
Future<void> deleteCustomAppProfile(String profileName) async {
|
||||
await _prefs.remove('customapp_$profileName');
|
||||
// If the current app is the one being deleted, reset
|
||||
|
||||
Reference in New Issue
Block a user