add base-apps with manifests, layout system, and testing documentation
- Rename test-apps to base-apps with proper manifest.json for each app - Add is_system_app flag to app discovery and Lua API - Fix icon path resolution for /system/icons/ paths - Add layout.lua and layout.rcss for reusable UI components - Update home screen to dynamically load all apps from manifests - Update all app RML files to use layout components - Comprehensive testing framework documentation with JSON action format - Add tests/ directory structure for automated UI testing
This commit is contained in:
161
base-apps/com.mosis.contacts/contact_detail.rml
Normal file
161
base-apps/com.mosis.contacts/contact_detail.rml
Normal file
@@ -0,0 +1,161 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../../ui/components.rcss"/>
|
||||
<script src="../../scripts/navigation.lua"></script>
|
||||
<script src="../../scripts/phone.lua"></script>
|
||||
<script src="../../scripts/contacts.lua"></script>
|
||||
<title>Contact</title>
|
||||
<style>
|
||||
.contact-detail-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.contact-header {
|
||||
background: linear-gradient(180deg, #1E1E1E 0%, #121212 100%);
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.contact-avatar-large {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
border-radius: 48px;
|
||||
background-color: #BB86FC;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40px;
|
||||
color: #000000;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.contact-name-large {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.contact-actions {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.contact-action {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.contact-action-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 28px;
|
||||
background-color: #BB86FC;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.contact-action-icon img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.contact-action-label {
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
.contact-info-section {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.contact-info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.contact-info-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.contact-info-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.contact-info-label {
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
.contact-info-value {
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="contact-detail-screen" onload="updateContactDetail()">
|
||||
<!-- App Bar -->
|
||||
<div class="app-bar">
|
||||
<div class="app-bar-nav btn-icon" onclick="goBack()"><img src="../../icons/back.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<span class="app-bar-title">Contact</span>
|
||||
<div class="btn-icon"><img src="../../icons/more.tga" style="width: 32px; height: 32px;"/></div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Header -->
|
||||
<div class="contact-header">
|
||||
<div class="contact-avatar-large" id="contact-avatar">?</div>
|
||||
<div class="contact-name-large" id="contact-name">Contact Name</div>
|
||||
|
||||
<div class="contact-actions">
|
||||
<div class="contact-action" id="call-action">
|
||||
<div class="contact-action-icon" style="background-color: #4CAF50;">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
<span class="contact-action-label">Call</span>
|
||||
</div>
|
||||
<div class="contact-action" id="message-action">
|
||||
<div class="contact-action-icon" style="background-color: #2196F3;">
|
||||
<img src="../../icons/message.tga"/>
|
||||
</div>
|
||||
<span class="contact-action-label">Message</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Info -->
|
||||
<div class="contact-info-section">
|
||||
<div class="contact-info-item">
|
||||
<img src="../../icons/phone.tga" class="contact-info-icon" style="width: 28px; height: 28px;"/>
|
||||
<div class="contact-info-content">
|
||||
<div class="contact-info-label">Mobile</div>
|
||||
<div class="contact-info-value" id="contact-phone">+1 (555) 000-0000</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-info-item">
|
||||
<img src="../../icons/message.tga" class="contact-info-icon" style="width: 28px; height: 28px;"/>
|
||||
<div class="contact-info-content">
|
||||
<div class="contact-info-label">Email</div>
|
||||
<div class="contact-info-value" id="contact-email">email@example.com</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</rml>
|
||||
321
base-apps/com.mosis.contacts/contacts.rml
Normal file
321
base-apps/com.mosis.contacts/contacts.rml
Normal file
@@ -0,0 +1,321 @@
|
||||
<rml>
|
||||
<head>
|
||||
<link type="text/rcss" href="../../ui/html.rcss"/>
|
||||
<link type="text/rcss" href="../../ui/theme.rcss"/>
|
||||
<link type="text/rcss" href="../../ui/components.rcss"/>
|
||||
<link type="text/rcss" href="../../ui/layout.rcss"/>
|
||||
<script src="../../scripts/navigation.lua"></script>
|
||||
<script src="../../scripts/layout.lua"></script>
|
||||
<title>Contacts</title>
|
||||
<style>
|
||||
.contacts-list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.contact-letter {
|
||||
padding: 8px 16px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #BB86FC;
|
||||
background-color: #1E1E1E;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.contact-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.contact-item:active {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.contact-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
margin-right: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.contact-name {
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.contact-phone {
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.contact-call-btn {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border-radius: 28px;
|
||||
}
|
||||
|
||||
.contact-call-btn:hover {
|
||||
background-color: rgba(76, 175, 80, 0.2);
|
||||
}
|
||||
|
||||
.contact-call-btn:active {
|
||||
background-color: rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.contact-call-btn img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Phone app bottom tabs */
|
||||
.phone-tabs {
|
||||
height: 72px;
|
||||
background-color: #1E1E1E;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.phone-tab {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.phone-tab:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.phone-tab.active {
|
||||
color: #BB86FC;
|
||||
}
|
||||
|
||||
.phone-tab img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.phone-tab span {
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="app-screen" onload="initLayout(document)" data-model="contacts">
|
||||
<!-- System Status Bar -->
|
||||
<div class="system-status-bar">
|
||||
<span id="status-time" class="system-status-time">12:30</span>
|
||||
<div class="system-status-icons">
|
||||
<img src="../../icons/wifi.tga"/>
|
||||
<img src="../../icons/signal.tga"/>
|
||||
<img src="../../icons/battery.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- App Bar -->
|
||||
<div class="app-bar">
|
||||
<div class="app-bar-back" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<span class="app-bar-title">Contacts</span>
|
||||
<div class="app-bar-actions">
|
||||
<div class="app-bar-action">
|
||||
<img src="../../icons/search.tga"/>
|
||||
</div>
|
||||
<div class="app-bar-action">
|
||||
<img src="../../icons/add.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search Bar -->
|
||||
<div class="search-bar">
|
||||
<img src="../../icons/search.tga" class="search-icon" style="width: 24px; height: 24px;"/>
|
||||
<input class="search-input" type="text" placeholder="Search contacts"/>
|
||||
</div>
|
||||
|
||||
<!-- Contacts List -->
|
||||
<div class="app-content">
|
||||
<div class="contacts-list">
|
||||
<!-- A -->
|
||||
<div class="contact-letter">A</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #E91E63;">A</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Alice Johnson</div>
|
||||
<div class="contact-phone">+1 555-0101</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #9C27B0;">A</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Andrew Smith</div>
|
||||
<div class="contact-phone">+1 555-0102</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- B -->
|
||||
<div class="contact-letter">B</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #2196F3;">B</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Bob Williams</div>
|
||||
<div class="contact-phone">+1 555-0201</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- C -->
|
||||
<div class="contact-letter">C</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #4CAF50;">C</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Carol Davis</div>
|
||||
<div class="contact-phone">+1 555-0301</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #FF9800;">C</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Chris Miller</div>
|
||||
<div class="contact-phone">+1 555-0302</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- D -->
|
||||
<div class="contact-letter">D</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #F44336;">D</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">David Brown</div>
|
||||
<div class="contact-phone">+1 555-0401</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- E -->
|
||||
<div class="contact-letter">E</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #00BCD4;">E</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Emma Wilson</div>
|
||||
<div class="contact-phone">+1 555-0501</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- J -->
|
||||
<div class="contact-letter">J</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #673AB7;">J</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">John Doe</div>
|
||||
<div class="contact-phone">+1 555-1234</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- M -->
|
||||
<div class="contact-letter">M</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #3F51B5;">M</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Mary Taylor</div>
|
||||
<div class="contact-phone">+1 555-0601</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #009688;">M</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Michael Lee</div>
|
||||
<div class="contact-phone">+1 555-0602</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- S -->
|
||||
<div class="contact-letter">S</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-avatar" style="background-color: #795548;">S</div>
|
||||
<div class="contact-info">
|
||||
<div class="contact-name">Sarah Anderson</div>
|
||||
<div class="contact-phone">+1 555-0701</div>
|
||||
</div>
|
||||
<div class="contact-call-btn">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FAB -->
|
||||
<div class="btn-fab">
|
||||
<img src="../../icons/add.tga" style="width: 32px; height: 32px;"/>
|
||||
</div>
|
||||
|
||||
<!-- Phone App Bottom Tabs -->
|
||||
<div class="phone-tabs">
|
||||
<div class="phone-tab" onclick="navigateTo('dialer')">
|
||||
<img src="../../icons/dialpad.tga"/>
|
||||
<span>Keypad</span>
|
||||
</div>
|
||||
<div class="phone-tab">
|
||||
<img src="../../icons/history.tga"/>
|
||||
<span>Recent</span>
|
||||
</div>
|
||||
<div class="phone-tab active">
|
||||
<img src="../../icons/contacts.tga"/>
|
||||
<span>Contacts</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</rml>
|
||||
18
base-apps/com.mosis.contacts/manifest.json
Normal file
18
base-apps/com.mosis.contacts/manifest.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"id": "com.mosis.contacts",
|
||||
"name": "Contacts",
|
||||
"version": "1.0.0",
|
||||
"version_code": 1,
|
||||
"entry": "contacts.rml",
|
||||
"icon": "/system/icons/contacts.tga",
|
||||
"description": "Contact list and management",
|
||||
"developer": {
|
||||
"name": "Mosis Team",
|
||||
"email": "dev@mosis.dev"
|
||||
},
|
||||
"is_system_app": true,
|
||||
"permissions": [
|
||||
"contacts"
|
||||
],
|
||||
"min_api_version": 1
|
||||
}
|
||||
Reference in New Issue
Block a user