# Milestone 6: System Apps **Status**: 75% Complete **Goal**: Core smartphone apps with full functionality. --- ## Overview System apps provide the essential smartphone experience: - Home launcher - Phone/Dialer - Messages - Contacts - Settings - Browser - Store (TODO) - Camera (TODO) - Music (TODO) --- ## App Status ### Completed Apps | App | Location | Features | Status | |-----|----------|----------|--------| | Home | `apps/home/` | App grid, dock, navigation | Complete | | Dialer | `apps/dialer/` | Keypad, call UI (mock) | Complete | | Messages | `apps/messages/` | Conversation list, chat | Complete | | Contacts | `apps/contacts/` | List, search, detail | Complete | | Settings | `apps/settings/` | Display, sound, about | Complete | | Browser | `apps/browser/` | URL bar, placeholder | Complete | ### Remaining Apps | App | Priority | Description | |-----|----------|-------------| | Store | High | Browse and install apps | | Camera | Medium | Viewfinder, capture photos | | Music | Low | Audio playback | --- ## App: Store **Location**: `src/main/assets/apps/store/` ### Features 1. **Browse Apps** - Featured apps carousel - Categories (Games, Utilities, Social) - Search functionality 2. **App Details** - Name, icon, description - Screenshots - Permissions list - Install/Update button 3. **My Apps** - Installed apps list - Update available indicator - Uninstall option ### UI Screens ``` store/ ├── store.rml # Main store screen ├── store.rcss # Store styles ├── category.rml # Category listing ├── detail.rml # App detail page └── scripts/ └── store.lua # Store logic ``` ### Main Screen (`store.rml`) ```html
Store

Categories

Games
Utilities

Top Apps

``` ### Data Model ```cpp // In data_models.cpp struct StoreApp { std::string id; std::string name; std::string icon; std::string banner; std::string category; std::string description; std::string version; std::vector screenshots; std::vector permissions; bool installed; }; void setupStoreDataModel(Rml::Context* context) { auto model = context->CreateDataModel("store"); model.Bind("featured_apps", &g_featured_apps); model.Bind("top_apps", &g_top_apps); model.Bind("categories", &g_categories); model.Bind("current_app", &g_current_app); model.BindEventCallback("install", [](auto& event, auto& args) { // Install app }); } ``` --- ## App: Camera **Location**: `src/main/assets/apps/camera/` ### Features 1. **Viewfinder** - Live camera preview (from ICamera) - Capture button - Switch camera (front/back) - Flash toggle 2. **Capture** - Take photo - Save to gallery - Share option 3. **Gallery** - View captured photos - Delete photos - Share photos ### UI Screens ``` camera/ ├── camera.rml # Viewfinder ├── camera.rcss # Camera styles ├── gallery.rml # Photo gallery └── scripts/ └── camera.lua # Camera logic ``` ### Viewfinder (`camera.rml`) ```html
``` ### Camera Lua Script ```lua -- camera.lua local camera = mosis.platform.getCamera() local capture = mosis.testing.VisualCapture(540, 960) local is_front_camera = false local flash_on = false function onAppCreate() if camera:isAvailable() then camera:startCapture(function(frame) -- Update preview texture document:GetElementById("preview-frame"):SetAttribute("src", frame.texture_url) end) else -- Show "no camera" message end end function capture() local path = mosis.filesystem:getSharedMediaPath() .. "/photos/" .. os.time() .. ".png" capture:CaptureScreenshot(path) -- Show capture animation playSound("shutter") flashScreen() -- Update last photo thumbnail document:GetElementById("last-photo"):SetAttribute("src", path) end function switchCamera() is_front_camera = not is_front_camera -- camera:setFacing(is_front_camera and "front" or "back") end function toggleFlash() flash_on = not flash_on local icon = flash_on and "flash_on" or "flash_off" document:GetElementById("flash-icon"):SetAttribute("src", "../../icons/" .. icon .. ".tga") end function openGallery() navigateTo("camera/gallery") end ``` --- ## App: Music **Location**: `src/main/assets/apps/music/` ### Features 1. **Library** - Songs list - Albums - Artists - Playlists 2. **Player** - Play/pause - Next/previous - Seek bar - Volume control - Shuffle/repeat 3. **Now Playing** - Album art - Song info - Progress bar ### UI Screens ``` music/ ├── music.rml # Library view ├── music.rcss # Music styles ├── player.rml # Now playing ├── playlist.rml # Playlist view └── scripts/ └── music.lua # Player logic ``` --- ## Data Persistence ### Storage Layer Apps need persistent storage for: - Contacts - Messages - Settings - Photos **Implementation Options**: 1. **JSON Files** (Simple) ``` /data/contacts.json /data/messages.json /data/settings.json ``` 2. **SQLite** (Robust) ``` /data/mosis.db - contacts table - messages table - settings table ``` ### Contact Storage ```cpp // contact_storage.h struct Contact { std::string id; std::string name; std::string phone; std::string email; std::string avatar; }; class ContactStorage { public: std::vector GetAll(); std::optional GetById(const std::string& id); bool Save(const Contact& contact); bool Delete(const std::string& id); std::vector Search(const std::string& query); }; ``` ### Message Storage ```cpp // message_storage.h struct Message { std::string id; std::string conversation_id; std::string sender; std::string text; int64_t timestamp; bool read; }; struct Conversation { std::string id; std::string contact_id; std::string last_message; int64_t last_timestamp; int unread_count; }; class MessageStorage { public: std::vector GetConversations(); std::vector GetMessages(const std::string& conversation_id); bool SaveMessage(const Message& message); bool MarkAsRead(const std::string& conversation_id); }; ``` --- ## Implementation Plan ### Phase 1: Store App UI - [ ] Main store screen layout - [ ] Category browsing - [ ] App detail page - [ ] Mock data for testing ### Phase 2: Camera App - [ ] Viewfinder UI - [ ] Capture to file - [ ] Gallery view - [ ] Integration with ICamera ### Phase 3: Music App - [ ] Library UI - [ ] Player UI - [ ] Audio playback (stub) ### Phase 4: Data Persistence - [ ] JSON storage layer - [ ] Contact CRUD - [ ] Message storage - [ ] Settings persistence ### Phase 5: Real Functionality - [ ] Store: Install real .mpkg files - [ ] Camera: Real camera frames - [ ] Music: Audio playback --- ## Testing ### Test IDs for Store | ID | Element | |----|---------| | `store-search` | Search button | | `store-featured` | Featured carousel | | `store-categories` | Category grid | | `app-install-btn` | Install button on detail | ### Test IDs for Camera | ID | Element | |----|---------| | `camera-preview` | Preview area | | `capture-btn` | Capture button | | `gallery-btn` | Gallery button | | `switch-camera-btn` | Switch camera | --- ## Acceptance Criteria ### Store - [ ] Browse featured and top apps - [ ] View app details - [ ] See permission requirements - [ ] Install apps (mock or real) ### Camera - [ ] Display camera preview - [ ] Capture photos - [ ] View in gallery - [ ] Share photos ### Music - [ ] Display music library - [ ] Play/pause audio - [ ] Show now playing ### Persistence - [ ] Contacts persist across sessions - [ ] Messages persist across sessions - [ ] Settings persist across sessions