Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Tests

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

jobs:
web:
name: Web installer (vitest)
runs-on: ubuntu-latest
defaults:
run:
working-directory: web
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: web/package-lock.json
- run: npm ci
- run: npm test

desktop-helper:
name: Desktop helper (jest)
runs-on: ubuntu-latest
defaults:
run:
working-directory: desktop_helper
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: desktop_helper/package-lock.json
- run: npm ci
- run: npm test

flipper-host:
name: Flipper C app (host tests)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run host tests
run: make -C src/tests/host run
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ FlipDeck transforms your Flipper Zero into a programmable command deck. Store fr

- ✅ **Profile Storage** — Save command profiles on the SD card
- ✅ **USB HID Keyboard** — Send text, key presses, and shortcuts
- ✅ **Profile Types** — Commands, snippets, shortcuts, and scripts
- ✅ **No WiFi Required** — Works on stock Flipper Zero
- ✅ **Safe Mode** — Confirmation before sending commands
- ✅ **Settings** — Configurable delays and preferences
- ✅ **Favorites + quick-send** — Pin actions; long-press OK to skip confirm
- ✅ **NFC tag triggers** — Bind a tag to an action's confirm screen
- ✅ **Sub-GHz RF triggers** — RX-only 433MHz remote bind/fire (never transmits)
- ✅ **WiFi Dev Board UART** — Optional `wifi_uart` command target
- ✅ **Safe Mode** — Confirmation before sending; critical patterns blocked
- ✅ **Settings** — Configurable delays, confirm, and USB auto-check

## Installation for Flipper Zero users

Expand Down Expand Up @@ -228,6 +230,8 @@ On the Flipper, the SD card is mounted under `/ext`, so the app reads from `/ext
├── snippets/ # Text snippet templates
│ ├── typescript.txt # TS code templates
│ └── go.txt # Go code templates
├── nfc_tags.json # NFC tag → action bindings (created on first bind)
├── subghz_remotes.json # Sub-GHz remote → action bindings (created on first bind)
├── logs/ # Session logs
└── settings.json # User preferences
```
Expand Down Expand Up @@ -302,22 +306,25 @@ flipdeck/
├── src/ # Flipper app source
│ ├── flipdeck_app.c # Main application logic
│ ├── flipdeck_app.h
│ ├── flipdeck_ui.c # User interface (browser, favorites, NFC scan, confirm)
│ ├── flipdeck_ui.c # UI (browser, favorites, NFC/Sub-GHz scan, confirm)
│ ├── flipdeck_ui.h
│ ├── profile_manager.c # SD card profile system, favorites, NFC tag mappings
│ ├── profile_manager.c # Profiles, favorites, NFC + Sub-GHz mappings
│ ├── profile_manager.h
│ ├── usb_hid.c # USB HID communication
│ ├── usb_hid.h
│ ├── uart_bridge.c # UART bridge to the WiFi Dev Board
│ ├── uart_bridge.h
│ ├── nfc_bridge.c # NFC tag scan bridge (tag-triggered sends)
│ ├── nfc_bridge.c # NFC tag scan bridge
│ ├── nfc_bridge.h
│ ├── subghz_bridge.c # Sub-GHz RX-only remote scan bridge
│ ├── subghz_bridge.h
│ └── settings.c # Settings management
├── web/ # Next.js web installer
├── docs/
│ ├── flight_manual.md # Safety and usage guide
│ ├── installer-flow.md # Web Serial / ZIP installer walkthrough
│ ├── nfc_trigger_spec.md # NFC tag trigger design
│ ├── subghz_trigger_spec.md # Sub-GHz remote trigger design
│ ├── security-model.md # Safety rules and confirmation model
│ └── ROADMAP.md # Development roadmap
└── README.md
Expand Down Expand Up @@ -346,9 +353,8 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for planned features.

- [ ] Custom profile creation from Flipper UI
- [ ] Profile import/export via SD card
- [ ] Key combination support
- [ ] Presentation remote mode
- [ ] Desktop companion app for profile sync
- [ ] Desktop companion app for live profile sync
- [ ] Momentum firmware integration, optional

## Contributing
Expand Down
4 changes: 4 additions & 0 deletions desktop_helper/src/lib/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export const PATHS = {
SNIPPETS_DIR: "/ext/apps_data/flipdeck/snippets",
// Settings file
SETTINGS_FILE: "/ext/apps_data/flipdeck/settings.json",
// NFC tag → action mappings
NFC_TAGS_FILE: "/ext/apps_data/flipdeck/nfc_tags.json",
// Sub-GHz remote → action mappings
SUBGHZ_REMOTES_FILE: "/ext/apps_data/flipdeck/subghz_remotes.json",
// Logs directory
LOGS_DIR: "/ext/apps_data/flipdeck/logs",
// The installed flipdeck.fap app itself
Expand Down
5 changes: 3 additions & 2 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
## Phase 3: USB Enhancements

- [x] Key combination support (Ctrl, Alt, Shift, Win)
- [x] Delay configuration per profile (`delay_ms` per command)
- [x] Delay configuration per command (`delay_ms` on each command; profile-level default still open — see #42)
- [ ] Key press/release timing control
- [ ] USB connection auto-detection
- [x] USB connection auto-detection (settings toggle gates the status poll)
- [ ] Multiple keyboard layouts

## Phase 4: Advanced Features

- [x] Favorites + quick-send (long-press OK skips confirm; Right toggles favorite)
- [x] NFC tag triggers (scan a tag to jump straight to a mapped action's confirm screen)
- [x] Sub-GHz RF remote triggers (RX-only 433MHz bind/fire; always confirms)
- [ ] Presentation remote mode (left/right/up/down keys)
- [ ] Mouse movement and clicks
- [ ] Desktop companion app for profile sync
Expand Down
8 changes: 4 additions & 4 deletions docs/flight_manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ Default profiles use safe commands (comments, harmless text). You must create or
### Review Default Profiles
Default profiles include Git and dev commands. Review them in:
```
/stor0800/flipdeck/profiles/
/ext/apps_data/flipdeck/profiles/
```

### Backup Your SD Card
Before creating many profiles, backup your SD card. Profile data is stored in:
```
/stor0800/flipdeck/profiles/
/stor0800/flipdeck/settings.json
/ext/apps_data/flipdeck/profiles/
/ext/apps_data/flipdeck/settings.json
```

---
Expand Down Expand Up @@ -119,7 +119,7 @@ FlipDeck's default flow is Category → Action → Confirm → Send. These short
Hold MENU + DOWN during startup to disable USB.

### Factory Reset
Delete `/stor0800/flipdeck/` folder to reset all profiles and settings.
Delete `/ext/apps_data/flipdeck/` folder to reset all profiles and settings.

### Report Issues
Open an issue at: https://github.com/mohabbis/flipdeck/issues
Expand Down
16 changes: 15 additions & 1 deletion docs/installer-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,23 @@ The web installer exists to make FlipDeck feel like a simple device install inst

## User Flow

There are two install paths. Both write the same on-device layout under
`/ext/apps_data/flipdeck/`.

### Path A: Web Serial (Chrome / Edge)

1. Open the deployed FlipDeck installer in Chrome or Edge.
2. Choose the default profiles or a custom subset.
3. Review the browser safety check (critical matches block install).
4. Click **Connect Flipper & Stage Pack**, pick the Flipper in the OS picker.
5. Click **Stage N profiles to Flipper** — files are written over the CLI serial port.
6. Launch FlipDeck from the Flipper apps menu (**Apps → Tools → FlipDeck**).

### Path B: ZIP + qFlipper (any browser)

1. Open the deployed FlipDeck installer.
2. Choose the default profiles or a custom subset.
3. Download the install ZIP.
3. Review the browser safety check, then download the install ZIP.
4. Extract the ZIP locally.
5. Drag `apps_data` onto the Flipper SD card root in qFlipper.
6. Launch FlipDeck from the Flipper apps menu.
Expand Down
21 changes: 16 additions & 5 deletions src/flipdeck_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,15 @@ bool flipdeck_app_init(void* furi_void) {
// Load categories from SD card
flipdeck_load_categories();

// Check USB connection
g_app_ctx->usb_connected = usb_hid_is_connected();
// Check USB connection when auto-detect is enabled
if(g_app_ctx->settings.auto_detect_usb) {
g_app_ctx->usb_connected = usb_hid_is_connected();
} else {
// Off: don't probe — avoid a sticky "NO USB" banner when the user
// has opted out of status polling. Send still checks the live HID
// link at the moment of transmission.
g_app_ctx->usb_connected = true;
}

// Initialize UART bridge to the WiFi dev board
uart_bridge_init();
Expand Down Expand Up @@ -112,9 +119,13 @@ void flipdeck_app_free(void* furi_void) {
void flipdeck_app_loop(void* furi_void) {
UNUSED(furi_void);

// Poll USB connection status
g_app_ctx->usb_connected = usb_hid_is_connected();

// Poll USB connection status when auto-detect is enabled
if(g_app_ctx->settings.auto_detect_usb) {
g_app_ctx->usb_connected = usb_hid_is_connected();
} else {
g_app_ctx->usb_connected = true;
}

switch(g_app_ctx->state) {
case FlipDeckState_Idle:
break;
Expand Down
2 changes: 2 additions & 0 deletions src/paths.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#define FLIPDECK_PROFILES_PATH "/ext/apps_data/flipdeck/profiles"
#define FLIPDECK_SNIPPETS_PATH "/ext/apps_data/flipdeck/snippets"
#define FLIPDECK_SETTINGS_PATH "/ext/apps_data/flipdeck/settings.json"
#define FLIPDECK_NFC_TAGS_PATH "/ext/apps_data/flipdeck/nfc_tags.json"
#define FLIPDECK_SUBGHZ_REMOTES_PATH "/ext/apps_data/flipdeck/subghz_remotes.json"
#define FLIPDECK_LOGS_PATH "/ext/apps_data/flipdeck/logs"
#define FLIPDECK_APP_PATH "/ext/apps/Tools/flipdeck.fap"

Expand Down
Loading
Loading