# Jibo Dynamic Menu System This module provides a dynamic menu system that automatically scans the Skills directory for `menuEntry.json` files and adds them to Jibo's menu screen. ## How It Works When Jibo boots up, the `main-menu-patch.js` module: 1. Patches `jibo.loader.load()` to intercept menu loading 2. Scans the `/opt/jibo/Jibo/Skills` directory for folders containing `menuEntry.json` 3. Injects the found skills/submenus into the main menu 4. Patches the main-menu skill's `redirectToSkill` to handle custom skill launches ## Quick Start ### Adding a Simple Skill Button to the Menu (you really should follow PROVIDERS.md at this point) 1. Create a folder in the `Skills` directory (e.g., `MySkill/`) 2. Add a `menuEntry.json` file inside: ```json { "type": "skill", "title": "My Skill", "icon": "resources/icons/settings.png", "color": "blue", "skillId": "MySkill", "description": "Short description of my skill", "order": 50 } ``` 3. Your skill will automatically appear in Jibo's main menu! **Note:** For the button to actually launch a skill, that skill must be a proper Jibo skill package registered in `@be/be/package.json`. If the skill isn't found, Jibo will show a fallback message. ### Creating a Submenu (Category/Folder) 1. Create a folder in the `Skills` directory (e.g., `Games/`) 2. Add a `menuEntry.json` marking it as a submenu: ```json { "type": "submenu", "title": "Games", "submenuTitle": "Choose a Game", "icon": "resources/icons/fun-stuff.png", "color": "purple", "description": "Fun games to play with Jibo", "order": 10 } ``` 3. Inside that folder, create subfolders for each skill, each with their own `menuEntry.json` 4. A button will appear in the main menu that opens a submenu with those skills! ## Directory Structure Example (OLD) ``` /opt/jibo/Jibo/Skills/ ├── @be/ # Core brain (ignored by scanner) ├── MySimpleSkill/ │ └── menuEntry.json # type: "skill" - appears as button in main menu ├── MyGames/ │ ├── menuEntry.json # type: "submenu" - opens submenu when pressed │ ├── GameOne/ │ │ └── menuEntry.json # type: "skill" - appears in MyGames submenu │ └── GameTwo/ │ └── menuEntry.json # type: "skill" - appears in MyGames submenu ``` ## menuEntry.json Schema | Field | Type | Required | Description | |-------|------|----------|-------------| | `type` | `"skill"` \| `"submenu"` | **Yes** | `"skill"` for buttons, `"submenu"` for folders | | `title` | string | **Yes** | Button label shown on Jibo's screen | | `icon` | string | **Yes** | Icon path (see Icon Paths below) | | `color` | string | No | Button color theme (see below). Default: `"default"` | | `skillId` | string | **Yes** (for skills) | The skill ID to launch | | `submenuTitle` | string | No | Title shown when submenu is opened | | `description` | string | No | Tooltip/accessibility text | | `order` | number | No | Sort order (lower = first). Default: `100` | | `hidden` | boolean | No | Set to `true` to hide from menu | ### Available Colors - `default` - Standard gray - `blue` - Blue theme - `green` - Green theme - `red` - Red theme - `purple` - Purple theme - `orange` - Orange theme - `teal` - Teal/cyan theme - `pink` - Pink theme - `yellow` - Yellow theme - `cyan` - Cyan theme ### Icon Paths Icons are resolved relative to the `@be/main-menu` package. Available built-in icons: | Icon Path | Description | |-----------|-------------| | `resources/icons/settings.png` | Settings gear | | `resources/icons/fun-stuff.png` | Star/fun icon (good for submenus) | | `resources/icons/clock.png` | Clock | | `resources/icons/heart.png` | Heart | | `resources/icons/surprise.png` | Gift/surprise | | `resources/icons/dance.png` | Dancing figure | | `resources/icons/joke.png` | Comedy mask | | `resources/icons/tips.png` | Lightbulb | | `resources/icons/gallery.png` | Photo gallery | | `resources/icons/radio.png` | Music notes | | `resources/icons/create.png` | Camera | | `resources/icons/photobooth.png` | Photo booth | | `resources/icons/exercise.png` | Exercise/yoga | | `resources/icons/weather.png` | Weather cloud | | `resources/icons/calendar.png` | Calendar | | `resources/icons/circuit-saver.png` | Circuit saver | | `resources/icons/dice.png` | Dice | | `resources/icons/coin.png` | Coin | | `resources/icons/emoji.png` | Emoji face | | `resources/icons/word-of-the-day.png` | Word icon | | `resources/icons/news.png` | News icon | | `resources/icons/twerk.png` | Twerk icon | | `resources/icons/scanner.png` | Scanner icon | ## Example: Complete Skill Setup ### Simple Skill (testSkillA/menuEntry.json) ```json { "type": "skill", "title": "Test Skill A", "icon": "resources/icons/settings.png", "color": "blue", "skillId": "testSkillA", "description": "A test skill", "order": 10 } ``` ### Submenu (TestSubMenuA/menuEntry.json) ```json { "type": "submenu", "title": "Test Submenu", "submenuTitle": "Test Skills", "icon": "resources/icons/fun-stuff.png", "color": "purple", "description": "A submenu with test skills", "order": 20 } ``` ### Skill inside Submenu (TestSubMenuA/testSkillB/menuEntry.json) ```json { "type": "skill", "title": "Test Skill B", "icon": "resources/icons/surprise.png", "color": "green", "skillId": "testSkillB", "description": "A skill inside a submenu", "order": 1 } ``` ## Technical Details ### How the Patch Works 1. **postinit.js** calls `mainMenuPatch.applyPatch(be)` and `mainMenuPatch.patchLoader(jibo)` 2. When the main-menu skill tries to load `main-menu-verbal.json`, the patch intercepts it 3. The patch scans the Skills directory for `menuEntry.json` files 4. It converts them to the proper button format and injects them into the menu config 5. When a dynamic skill button is pressed, the patched `redirectToSkill` handles the launch 6. For submenus, a new menu view is displayed with the submenu's children ### Files - `main-menu-patch.js` - Core patch that hooks into the system - `skills-scanner.js` - Alternative scanning implementation (not currently used) - `menu-manager.js` - Alternative menu display implementation (not currently used) ### Debugging Check the browser console for log messages starting with `main-menu-patch:`. These show: - When the patch is initialized - When menu loads are intercepted - How many dynamic skills are injected - When skills/submenus are selected ## Limitations - Nested submenus (submenus within submenus) are not supported - Custom skills must be registered in `@be/be/package.json` to actually launch - Icon files must exist in the `@be/main-menu/resources/icons/` directory ## Troubleshooting ### Skill button not appearing in menu? 1. Check that `menuEntry.json` exists and is valid JSON 2. Verify `hidden` is not set to `true` 3. Make sure `type` is set to `"skill"` or `"submenu"` 4. Check the browser console for `main-menu-patch:` log messages ### Submenu appears empty? 1. Make sure child skill folders have `menuEntry.json` files 2. Verify child skills have `type: "skill"` (nested submenus not supported) 3. Check that child folders are direct children of the submenu folder ### Skill button doesn't launch anything? 1. The skill needs to be a proper Jibo skill package 2. The skill must be registered in `@be/be/package.json` under `jibo.skills` 3. If unregistered, Jibo will show a fallback message ### Icon not loading? 1. Verify the icon path is correct (e.g., `resources/icons/settings.png`) 2. Only built-in icons from `@be/main-menu/resources/icons/` are supported 3. Check the list of available icons above