# 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
```
### 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