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:
@@ -3,17 +3,11 @@
|
||||
<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>Browser</title>
|
||||
<style>
|
||||
.browser-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.browser-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -23,48 +17,46 @@
|
||||
}
|
||||
|
||||
.browser-nav-btn {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
color: #B3B3B3;
|
||||
cursor: pointer;
|
||||
border-radius: 28px;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.browser-nav-btn:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.browser-nav-btn.disabled {
|
||||
color: #444444;
|
||||
cursor: default;
|
||||
.browser-nav-btn img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.browser-nav-btn.disabled:hover {
|
||||
background-color: transparent;
|
||||
.browser-nav-btn.disabled img {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.browser-url-bar {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 16px;
|
||||
padding: 10px 16px;
|
||||
background-color: #2D2D2D;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.browser-secure-icon {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #4CAF50;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.browser-url {
|
||||
flex: 1;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
background: transparent;
|
||||
border: none;
|
||||
@@ -89,7 +81,7 @@
|
||||
}
|
||||
|
||||
.browser-page-text {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
color: #333333;
|
||||
margin-bottom: 16px;
|
||||
@@ -104,13 +96,11 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.browser-search-results {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.browser-search-item {
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 20px;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.browser-search-item:hover {
|
||||
@@ -124,13 +114,13 @@
|
||||
}
|
||||
|
||||
.browser-search-url {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #006621;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.browser-search-desc {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #545454;
|
||||
line-height: 1.4;
|
||||
}
|
||||
@@ -157,77 +147,78 @@
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.browser-tab-icon {
|
||||
font-size: 20px;
|
||||
.browser-tab-btn img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.browser-tab-label {
|
||||
font-size: 16px;
|
||||
.browser-tab-btn span {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.browser-tabs-indicator {
|
||||
padding: 6px 10px;
|
||||
border: 1px solid #B3B3B3;
|
||||
border-radius: 6px;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #B3B3B3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="browser-screen" data-model="browser">
|
||||
<!-- Status Bar -->
|
||||
<div class="status-bar">
|
||||
<span class="status-bar-time">12:30</span>
|
||||
<div class="status-bar-icons">
|
||||
<span>*</span>
|
||||
<span>+</span>
|
||||
<span>|</span>
|
||||
<body class="app-screen" onload="initLayout(document)" data-model="browser">
|
||||
<!-- 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>
|
||||
|
||||
<!-- Browser Toolbar -->
|
||||
<div class="browser-toolbar">
|
||||
<div class="app-bar-nav browser-nav-btn" data-class-disabled="!can_go_back" onclick="goBack()">
|
||||
<img src="../../icons/back.tga" style="width: 32px; height: 32px;"/>
|
||||
<div class="browser-nav-btn" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<div class="browser-nav-btn disabled">
|
||||
<img src="../../icons/forward.tga" style="width: 32px; height: 32px; opacity: 0.3;"/>
|
||||
<img src="../../icons/forward.tga"/>
|
||||
</div>
|
||||
<div class="browser-url-bar">
|
||||
<span class="browser-secure-icon">🔒</span>
|
||||
<input class="browser-url" type="text" data-value="current_url"/>
|
||||
</div>
|
||||
<div class="browser-nav-btn" data-event-click="refresh()">
|
||||
<img src="../../icons/refresh.tga" style="width: 32px; height: 32px;"/>
|
||||
<span class="browser-secure-icon">S</span>
|
||||
<input class="browser-url" type="text" value="example.com"/>
|
||||
</div>
|
||||
<div class="browser-nav-btn">
|
||||
<img src="../../icons/more.tga" style="width: 32px; height: 32px;"/>
|
||||
<img src="../../icons/refresh.tga"/>
|
||||
</div>
|
||||
<div class="browser-nav-btn">
|
||||
<img src="../../icons/more.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Browser Content -->
|
||||
<div class="browser-content">
|
||||
<div class="browser-page">
|
||||
<div class="browser-page-title">{{ page_title }}</div>
|
||||
<div class="browser-page-title">Example Domain</div>
|
||||
<div class="browser-page-text">
|
||||
{{ page_content }}
|
||||
This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.
|
||||
</div>
|
||||
<div class="browser-page-text">
|
||||
<span class="browser-page-link" data-event-click="navigate('iana.org')">More information...</span>
|
||||
<span class="browser-page-link">More information...</span>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 32px; padding-top: 16px; border-top: 1px solid #e0e0e0;">
|
||||
<div class="browser-page-title" style="font-size: 18px;">Related Links</div>
|
||||
<div class="browser-search-item" data-event-click="navigate('iana.org/domains')">
|
||||
<div class="browser-search-title">IANA — IANA-managed Reserved Domains</div>
|
||||
<div class="browser-search-item">
|
||||
<div class="browser-search-title">IANA - IANA-managed Reserved Domains</div>
|
||||
<div class="browser-search-url">www.iana.org > domains > reserved</div>
|
||||
<div class="browser-search-desc">Certain domains are set aside and unavailable for registration. Learn about reserved top-level domains.</div>
|
||||
<div class="browser-search-desc">Certain domains are set aside and unavailable for registration.</div>
|
||||
</div>
|
||||
<div class="browser-search-item" data-event-click="navigate('tools.ietf.org/html/rfc2606')">
|
||||
<div class="browser-search-item">
|
||||
<div class="browser-search-title">RFC 2606 - Reserved Top Level DNS Names</div>
|
||||
<div class="browser-search-url">tools.ietf.org > html > rfc2606</div>
|
||||
<div class="browser-search-desc">This document describes some domain names that are reserved for documentation purposes.</div>
|
||||
<div class="browser-search-desc">This document describes domain names reserved for documentation.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -236,20 +227,20 @@
|
||||
<!-- Bottom Bar -->
|
||||
<div class="browser-bottom-bar">
|
||||
<div class="browser-tab-btn" onclick="goHome()">
|
||||
<img src="../../icons/home.tga" class="browser-tab-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="browser-tab-label">Home</span>
|
||||
<img src="../../icons/home.tga"/>
|
||||
<span>Home</span>
|
||||
</div>
|
||||
<div class="browser-tab-btn">
|
||||
<span class="browser-tabs-indicator">{{ tabs.size }}</span>
|
||||
<span class="browser-tab-label">Tabs</span>
|
||||
<span class="browser-tabs-indicator">1</span>
|
||||
<span>Tabs</span>
|
||||
</div>
|
||||
<div class="browser-tab-btn">
|
||||
<img src="../../icons/add.tga" class="browser-tab-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="browser-tab-label">New Tab</span>
|
||||
<img src="../../icons/add.tga"/>
|
||||
<span>New Tab</span>
|
||||
</div>
|
||||
<div class="browser-tab-btn">
|
||||
<img src="../../icons/menu.tga" class="browser-tab-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="browser-tab-label">Menu</span>
|
||||
<img src="../../icons/menu.tga"/>
|
||||
<span>Menu</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,15 +3,13 @@
|
||||
<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>Camera</title>
|
||||
<style>
|
||||
.camera-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Top Controls */
|
||||
@@ -21,16 +19,16 @@
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
top: 36px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.camera-btn {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 28px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -43,8 +41,8 @@
|
||||
}
|
||||
|
||||
.camera-btn img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
/* Viewfinder */
|
||||
@@ -66,7 +64,6 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Placeholder for camera feed - replace with shared texture */
|
||||
.viewfinder-placeholder {
|
||||
color: #666666;
|
||||
font-size: 18px;
|
||||
@@ -136,10 +133,10 @@
|
||||
}
|
||||
|
||||
.camera-mode {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.camera-mode.active {
|
||||
@@ -156,7 +153,7 @@
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
padding: 24px 32px;
|
||||
padding: 20px 32px;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
@@ -173,8 +170,8 @@
|
||||
}
|
||||
|
||||
.gallery-preview img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
@@ -206,13 +203,6 @@
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.capture-btn.video .capture-btn-inner {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 6px;
|
||||
background-color: #F44336;
|
||||
}
|
||||
|
||||
.switch-camera-btn {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
@@ -229,51 +219,37 @@
|
||||
}
|
||||
|
||||
.switch-camera-btn img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
/* Settings Overlay */
|
||||
.settings-value {
|
||||
position: absolute;
|
||||
bottom: 200px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
padding: 10px 18px;
|
||||
border-radius: 22px;
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* Flash modes */
|
||||
/* Indicators */
|
||||
.flash-indicator {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
top: 100px;
|
||||
left: 16px;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
padding: 8px 14px;
|
||||
border-radius: 14px;
|
||||
font-size: 16px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* Timer indicator */
|
||||
.timer-indicator {
|
||||
position: absolute;
|
||||
top: 80px;
|
||||
top: 100px;
|
||||
right: 16px;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
padding: 8px 14px;
|
||||
border-radius: 14px;
|
||||
font-size: 16px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* Zoom slider */
|
||||
/* Zoom control */
|
||||
.zoom-control {
|
||||
position: absolute;
|
||||
bottom: 180px;
|
||||
bottom: 200px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
@@ -282,20 +258,20 @@
|
||||
}
|
||||
|
||||
.zoom-btn {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 22px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
font-size: 20px;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.zoom-level {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #FFD700;
|
||||
font-weight: 600;
|
||||
min-width: 48px;
|
||||
@@ -303,7 +279,17 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="camera-screen">
|
||||
<body class="app-screen camera-screen" onload="initLayout(document)">
|
||||
<!-- System Status Bar (transparent) -->
|
||||
<div class="system-status-bar" style="background-color: transparent; position: absolute; top: 0; left: 0; right: 0; z-index: 20;">
|
||||
<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>
|
||||
|
||||
<!-- Top Bar -->
|
||||
<div class="camera-top-bar">
|
||||
<div class="camera-btn" onclick="goBack()">
|
||||
@@ -325,11 +311,10 @@
|
||||
<!-- Viewfinder Area -->
|
||||
<div class="viewfinder-container">
|
||||
<div class="viewfinder" id="camera-viewfinder">
|
||||
<!-- This is where the shared camera texture would be rendered -->
|
||||
<div class="viewfinder-placeholder">
|
||||
<div class="viewfinder-placeholder-icon">C</div>
|
||||
<div>Camera Preview</div>
|
||||
<div style="font-size: 16px; margin-top: 8px; color: #555555;">
|
||||
<div style="font-size: 14px; margin-top: 8px; color: #555555;">
|
||||
Tap to focus
|
||||
</div>
|
||||
</div>
|
||||
@@ -346,10 +331,8 @@
|
||||
<div class="focus-indicator"></div>
|
||||
</div>
|
||||
|
||||
<!-- Flash Indicator -->
|
||||
<!-- Indicators -->
|
||||
<div class="flash-indicator">Flash: Auto</div>
|
||||
|
||||
<!-- Timer Indicator -->
|
||||
<div class="timer-indicator">Timer: Off</div>
|
||||
|
||||
<!-- Zoom Control -->
|
||||
|
||||
@@ -3,21 +3,14 @@
|
||||
<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-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.contacts-list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding-bottom: 56px;
|
||||
}
|
||||
|
||||
.contact-letter {
|
||||
@@ -41,6 +34,10 @@
|
||||
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;
|
||||
@@ -58,7 +55,7 @@
|
||||
}
|
||||
|
||||
.contact-name {
|
||||
font-size: 16px;
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
@@ -82,35 +79,216 @@
|
||||
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: 32px;
|
||||
height: 32px;
|
||||
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="contacts-screen" data-model="contacts">
|
||||
<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-nav btn-icon" onclick="goBack()"><img src="../../icons/back.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="app-bar-back" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<span class="app-bar-title">Contacts</span>
|
||||
<div class="btn-icon"><img src="../../icons/add.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<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: 28px; height: 28px;"/>
|
||||
<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="contacts-list">
|
||||
<div data-for="contact : contacts">
|
||||
<div class="contact-item" data-event-click="select_contact(contact.id); navigateTo('contact_detail')">
|
||||
<div class="contact-avatar" data-style-background-color="contact.color">{{ contact.initial }}</div>
|
||||
<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">{{ contact.name }}</div>
|
||||
<div class="contact-phone">{{ contact.phone }}</div>
|
||||
<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"/>
|
||||
@@ -120,21 +298,23 @@
|
||||
</div>
|
||||
|
||||
<!-- FAB -->
|
||||
<div class="btn-fab"><img src="../../icons/add.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="btn-fab">
|
||||
<img src="../../icons/add.tga" style="width: 32px; height: 32px;"/>
|
||||
</div>
|
||||
|
||||
<!-- Bottom Navigation -->
|
||||
<div class="bottom-nav">
|
||||
<div class="bottom-nav-item" onclick="navigateTo('dialer')">
|
||||
<img src="../../icons/dialpad.tga" class="bottom-nav-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="bottom-nav-label">Keypad</span>
|
||||
<!-- 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="bottom-nav-item">
|
||||
<img src="../../icons/history.tga" class="bottom-nav-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="bottom-nav-label">Recent</span>
|
||||
<div class="phone-tab">
|
||||
<img src="../../icons/history.tga"/>
|
||||
<span>Recent</span>
|
||||
</div>
|
||||
<div class="bottom-nav-item active">
|
||||
<img src="../../icons/contacts.tga" class="bottom-nav-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="bottom-nav-label">Contacts</span>
|
||||
<div class="phone-tab active">
|
||||
<img src="../../icons/contacts.tga"/>
|
||||
<span>Contacts</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,201 +3,154 @@
|
||||
<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>Phone</title>
|
||||
<style>
|
||||
.dialer-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dialer-tabs {
|
||||
display: flex;
|
||||
background-color: #1E1E1E;
|
||||
border-bottom: 1px solid #333333;
|
||||
}
|
||||
|
||||
.dialer-tab {
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
color: #B3B3B3;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dialer-tab.active {
|
||||
color: #BB86FC;
|
||||
border-bottom: 2px solid #BB86FC;
|
||||
}
|
||||
|
||||
.dialer-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.recent-calls {
|
||||
/* Phone app bottom tabs */
|
||||
.phone-tabs {
|
||||
height: 72px;
|
||||
background-color: #1E1E1E;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.phone-tab {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.call-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.call-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.call-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
background-color: #BB86FC;
|
||||
margin-right: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.call-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.call-name {
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.call-type {
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.call-type.missed {
|
||||
color: #CF6679;
|
||||
}
|
||||
|
||||
.call-time {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.call-action {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
color: #4CAF50;
|
||||
cursor: pointer;
|
||||
border-radius: 28px;
|
||||
.phone-tab:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.call-action:hover {
|
||||
background-color: rgba(76, 175, 80, 0.2);
|
||||
.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="dialer-screen" data-model="phone">
|
||||
<body class="app-screen" onload="initLayout(document)" data-model="phone">
|
||||
<!-- 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-nav btn-icon" onclick="goBack()"><img src="../../icons/back.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="app-bar-back" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<span class="app-bar-title">Phone</span>
|
||||
</div>
|
||||
|
||||
<!-- Tabs -->
|
||||
<div class="dialer-tabs">
|
||||
<div class="dialer-tab active" id="tab-keypad">Keypad</div>
|
||||
<div class="dialer-tab" id="tab-recent">Recent</div>
|
||||
<div class="dialer-tab" onclick="navigateTo('contacts')">Contacts</div>
|
||||
</div>
|
||||
<!-- Dialer Content -->
|
||||
<div class="dialer-content">
|
||||
<!-- Dial Display -->
|
||||
<div class="dial-display">{{ dial_number }}</div>
|
||||
|
||||
<!-- Dial Display -->
|
||||
<div class="dial-display">{{ dial_number }}</div>
|
||||
<!-- Dial Pad -->
|
||||
<div class="dial-pad">
|
||||
<div class="dial-key" data-event-click="dial_press('1')">
|
||||
<span class="dial-key-number">1</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('2')">
|
||||
<span class="dial-key-number">2</span>
|
||||
<span class="dial-key-letters">ABC</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('3')">
|
||||
<span class="dial-key-number">3</span>
|
||||
<span class="dial-key-letters">DEF</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('4')">
|
||||
<span class="dial-key-number">4</span>
|
||||
<span class="dial-key-letters">GHI</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('5')">
|
||||
<span class="dial-key-number">5</span>
|
||||
<span class="dial-key-letters">JKL</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('6')">
|
||||
<span class="dial-key-number">6</span>
|
||||
<span class="dial-key-letters">MNO</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('7')">
|
||||
<span class="dial-key-number">7</span>
|
||||
<span class="dial-key-letters">PQRS</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('8')">
|
||||
<span class="dial-key-number">8</span>
|
||||
<span class="dial-key-letters">TUV</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('9')">
|
||||
<span class="dial-key-number">9</span>
|
||||
<span class="dial-key-letters">WXYZ</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('*')">
|
||||
<span class="dial-key-number">*</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('0')">
|
||||
<span class="dial-key-number">0</span>
|
||||
<span class="dial-key-letters">+</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('#')">
|
||||
<span class="dial-key-number">#</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dial Pad -->
|
||||
<div class="dial-pad">
|
||||
<div class="dial-key" data-event-click="dial_press('1')">
|
||||
<span class="dial-key-number">1</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('2')">
|
||||
<span class="dial-key-number">2</span>
|
||||
<span class="dial-key-letters">ABC</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('3')">
|
||||
<span class="dial-key-number">3</span>
|
||||
<span class="dial-key-letters">DEF</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('4')">
|
||||
<span class="dial-key-number">4</span>
|
||||
<span class="dial-key-letters">GHI</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('5')">
|
||||
<span class="dial-key-number">5</span>
|
||||
<span class="dial-key-letters">JKL</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('6')">
|
||||
<span class="dial-key-number">6</span>
|
||||
<span class="dial-key-letters">MNO</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('7')">
|
||||
<span class="dial-key-number">7</span>
|
||||
<span class="dial-key-letters">PQRS</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('8')">
|
||||
<span class="dial-key-number">8</span>
|
||||
<span class="dial-key-letters">TUV</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('9')">
|
||||
<span class="dial-key-number">9</span>
|
||||
<span class="dial-key-letters">WXYZ</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('*')">
|
||||
<span class="dial-key-number">*</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('0')">
|
||||
<span class="dial-key-number">0</span>
|
||||
<span class="dial-key-letters">+</span>
|
||||
</div>
|
||||
<div class="dial-key" data-event-click="dial_press('#')">
|
||||
<span class="dial-key-number">#</span>
|
||||
<span class="dial-key-letters"></span>
|
||||
<!-- Call Actions -->
|
||||
<div class="dial-actions">
|
||||
<div style="width: 56px;"></div>
|
||||
<div class="dial-call-btn" data-event-click="make_call()">
|
||||
<img src="../../icons/call_small.tga" style="width: 32px; height: 32px; pointer-events: none;"/>
|
||||
</div>
|
||||
<div class="btn-icon" data-event-click="dial_backspace()" style="width: 56px; height: 56px;">
|
||||
<img src="../../icons/backspace.tga" style="width: 32px; height: 32px; pointer-events: none;"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call Actions -->
|
||||
<div class="dial-actions">
|
||||
<div style="width: 56px;"></div>
|
||||
<div class="dial-call-btn" data-event-click="make_call()"><img src="../../icons/call_small.tga" style="width: 32px; height: 32px; pointer-events: none;"/></div>
|
||||
<div class="btn-icon" data-event-click="dial_backspace()" style="width: 56px; height: 56px;"><img src="../../icons/backspace.tga" style="width: 32px; height: 32px; pointer-events: none;"/></div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom Navigation -->
|
||||
<div class="bottom-nav">
|
||||
<div class="bottom-nav-item active">
|
||||
<img src="../../icons/dialpad.tga" class="bottom-nav-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="bottom-nav-label">Keypad</span>
|
||||
<!-- Phone App Bottom Tabs -->
|
||||
<div class="phone-tabs">
|
||||
<div class="phone-tab active">
|
||||
<img src="../../icons/dialpad.tga"/>
|
||||
<span>Keypad</span>
|
||||
</div>
|
||||
<div class="bottom-nav-item">
|
||||
<img src="../../icons/history.tga" class="bottom-nav-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="bottom-nav-label">Recent</span>
|
||||
<div class="phone-tab">
|
||||
<img src="../../icons/history.tga"/>
|
||||
<span>Recent</span>
|
||||
</div>
|
||||
<div class="bottom-nav-item" onclick="navigateTo('contacts')">
|
||||
<img src="../../icons/contacts.tga" class="bottom-nav-icon" style="width: 32px; height: 32px;"/>
|
||||
<span class="bottom-nav-label">Contacts</span>
|
||||
<div class="phone-tab" onclick="navigateTo('contacts')">
|
||||
<img src="../../icons/contacts.tga"/>
|
||||
<span>Contacts</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -34,27 +34,23 @@ function initHome(doc)
|
||||
print("[Home] Initializing home screen...")
|
||||
home_document = doc
|
||||
|
||||
-- Get installed third-party apps
|
||||
-- Get all installed apps
|
||||
if mosis and mosis.apps then
|
||||
installed_apps = mosis.apps.getInstalled() or {}
|
||||
print("[Home] Found " .. #installed_apps .. " installed apps")
|
||||
|
||||
-- Filter to only third-party (non-system) apps
|
||||
local third_party = {}
|
||||
-- Log each app
|
||||
for _, app in ipairs(installed_apps) do
|
||||
if not app.is_system_app then
|
||||
table.insert(third_party, app)
|
||||
print("[Home] Third-party app: " .. app.name .. " (" .. app.package_id .. ")")
|
||||
end
|
||||
local app_type = app.is_system_app and "System" or "Third-party"
|
||||
print("[Home] " .. app_type .. " app: " .. app.name .. " (" .. app.package_id .. ")")
|
||||
end
|
||||
installed_apps = third_party
|
||||
else
|
||||
print("[Home] Warning: mosis.apps API not available")
|
||||
installed_apps = {}
|
||||
end
|
||||
|
||||
-- Render dynamic apps
|
||||
renderThirdPartyApps()
|
||||
-- Render all apps
|
||||
renderInstalledApps()
|
||||
end
|
||||
|
||||
-- Generate a color based on package_id
|
||||
@@ -79,17 +75,17 @@ function getAppInitial(name)
|
||||
return name:sub(1, 1):upper()
|
||||
end
|
||||
|
||||
-- Render third-party apps into the grid
|
||||
function renderThirdPartyApps()
|
||||
-- Render all installed apps into the grid
|
||||
function renderInstalledApps()
|
||||
-- Use stored document reference
|
||||
if not home_document then
|
||||
print("[Home] Could not get document reference")
|
||||
return
|
||||
end
|
||||
|
||||
local grid = home_document:GetElementById("third-party-apps")
|
||||
local grid = home_document:GetElementById("installed-apps")
|
||||
if not grid then
|
||||
print("[Home] third-party-apps container not found")
|
||||
print("[Home] installed-apps container not found")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -97,7 +93,7 @@ function renderThirdPartyApps()
|
||||
grid.inner_rml = ""
|
||||
|
||||
if #installed_apps == 0 then
|
||||
print("[Home] No third-party apps to display")
|
||||
print("[Home] No apps to display")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -110,25 +106,23 @@ function renderThirdPartyApps()
|
||||
|
||||
-- Check if app has an icon
|
||||
if app.icon and app.icon ~= "" then
|
||||
local icon_path
|
||||
-- Check if icon is already a full path (starts with / or contains :/)
|
||||
if app.icon:sub(1, 1) == "/" or app.icon:find(":/") then
|
||||
-- Already a full path
|
||||
icon_path = app.icon
|
||||
elseif app.install_path and app.install_path ~= "" then
|
||||
-- Relative filename - construct full path from install_path
|
||||
icon_path = app.install_path .. "/" .. app.icon
|
||||
else
|
||||
icon_path = app.icon
|
||||
end
|
||||
-- Use file:// prefix for absolute paths to prevent RmlUi URL resolution
|
||||
local src_path = icon_path
|
||||
if icon_path:sub(1, 1) == "/" then
|
||||
src_path = "file://" .. icon_path
|
||||
local icon_path = app.icon
|
||||
|
||||
-- Handle /system/ paths - map to shared assets
|
||||
if icon_path:sub(1, 8) == "/system/" then
|
||||
-- Map /system/icons/foo.tga to ../../icons/foo.tga (relative to home)
|
||||
icon_path = "../../" .. icon_path:sub(9) -- Remove "/system/" prefix
|
||||
print("[Home] Mapped system icon: " .. app.icon .. " -> " .. icon_path)
|
||||
elseif icon_path:sub(1, 1) ~= "/" and not icon_path:find(":/") then
|
||||
-- Relative path - prepend install_path
|
||||
if app.install_path and app.install_path ~= "" then
|
||||
icon_path = app.install_path .. "/" .. icon_path
|
||||
end
|
||||
end
|
||||
|
||||
-- Use img tag for actual icon
|
||||
icon_html = '<img src="' .. src_path .. '" style="width: 48px; height: 48px;"/>'
|
||||
print("[Home] Loading icon: " .. src_path)
|
||||
icon_html = '<img src="' .. icon_path .. '" style="width: 48px; height: 48px;"/>'
|
||||
print("[Home] Loading icon: " .. icon_path)
|
||||
else
|
||||
-- Fallback to initial letter
|
||||
icon_html = '<span style="font-size: 28px; color: #000000;">' .. initial .. '</span>'
|
||||
@@ -137,7 +131,7 @@ function renderThirdPartyApps()
|
||||
html = html .. [[
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: ]] .. color .. [[;"
|
||||
onclick="launchThirdPartyApp(']] .. app.package_id .. [[')">
|
||||
onclick="launchApp(']] .. app.package_id .. [[')">
|
||||
]] .. icon_html .. [[
|
||||
</div>
|
||||
<span class="app-icon-label">]] .. app.name .. [[</span>
|
||||
@@ -146,7 +140,7 @@ function renderThirdPartyApps()
|
||||
end
|
||||
|
||||
grid.inner_rml = html
|
||||
print("[Home] Rendered " .. #installed_apps .. " third-party apps")
|
||||
print("[Home] Rendered " .. #installed_apps .. " apps")
|
||||
end
|
||||
|
||||
-- Get app info by package_id
|
||||
@@ -159,8 +153,8 @@ function getAppInfo(package_id)
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Launch a third-party app
|
||||
function launchThirdPartyApp(package_id)
|
||||
-- Launch an app by package_id
|
||||
function launchApp(package_id)
|
||||
print("[Home] Launching app: " .. package_id)
|
||||
|
||||
if mosis and mosis.apps then
|
||||
|
||||
@@ -44,12 +44,13 @@
|
||||
}
|
||||
|
||||
/* Third-party apps use same sizing as system apps */
|
||||
#third-party-apps .app-icon {
|
||||
#installed-apps .app-icon {
|
||||
width: 25%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
#third-party-apps .app-icon-image {
|
||||
#installed-apps .app-icon-image {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 18px;
|
||||
@@ -60,11 +61,11 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#third-party-apps .app-icon-image:hover {
|
||||
#installed-apps .app-icon-image:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
#third-party-apps .app-icon-label {
|
||||
#installed-apps .app-icon-label {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
@@ -86,80 +87,8 @@
|
||||
<!-- App Grid -->
|
||||
<div class="home-content">
|
||||
<div class="app-grid">
|
||||
<!-- Row 1 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #4CAF50;" onclick="navigateTo('dialer')"><img src="../../icons/phone.tga"/></div>
|
||||
<span class="app-icon-label">Phone</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #2196F3;" onclick="navigateTo('messages')"><img src="../../icons/message.tga"/></div>
|
||||
<span class="app-icon-label">Messages</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #FF9800;" onclick="navigateTo('contacts')"><img src="../../icons/contacts.tga"/></div>
|
||||
<span class="app-icon-label">Contacts</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #F44336;" onclick="navigateTo('browser')"><img src="../../icons/browser.tga"/></div>
|
||||
<span class="app-icon-label">Browser</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 2 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #9C27B0;"><img src="../../icons/gallery.tga"/></div>
|
||||
<span class="app-icon-label">Gallery</span>
|
||||
</div>
|
||||
<div id="app-camera" class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #00BCD4;" onclick="navigateTo('camera')"><img src="../../icons/camera.tga"/></div>
|
||||
<span class="app-icon-label">Camera</span>
|
||||
</div>
|
||||
<div id="app-settings" class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #607D8B;" onclick="navigateTo('settings')"><img src="../../icons/settings.tga"/></div>
|
||||
<span class="app-icon-label">Settings</span>
|
||||
</div>
|
||||
<div id="app-music" class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #E91E63;" onclick="navigateTo('music')"><img src="../../icons/music.tga"/></div>
|
||||
<span class="app-icon-label">Music</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 3 -->
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #3F51B5;"><img src="../../icons/calendar.tga"/></div>
|
||||
<span class="app-icon-label">Calendar</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #009688;"><img src="../../icons/clock.tga"/></div>
|
||||
<span class="app-icon-label">Clock</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #795548;"><img src="../../icons/notes.tga"/></div>
|
||||
<span class="app-icon-label">Notes</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #FF5722;"><img src="../../icons/maps.tga"/></div>
|
||||
<span class="app-icon-label">Maps</span>
|
||||
</div>
|
||||
|
||||
<!-- Row 4 -->
|
||||
<div id="app-store" class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #8BC34A;" onclick="navigateTo('store')"><img src="../../icons/store.tga"/></div>
|
||||
<span class="app-icon-label">Store</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #CDDC39;"><img src="../../icons/files.tga"/></div>
|
||||
<span class="app-icon-label">Files</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #FFC107;"><img src="../../icons/calculator.tga"/></div>
|
||||
<span class="app-icon-label">Calculator</span>
|
||||
</div>
|
||||
<div class="app-icon">
|
||||
<div class="app-icon-image" style="background-color: #673AB7;"><img src="../../icons/weather.tga"/></div>
|
||||
<span class="app-icon-label">Weather</span>
|
||||
</div>
|
||||
|
||||
<!-- Third-party apps (dynamically populated by home.lua) -->
|
||||
<div id="third-party-apps" class="app-grid-section">
|
||||
<!-- All apps dynamically populated by home.lua -->
|
||||
<div id="installed-apps" class="app-grid-section">
|
||||
<!-- Apps will be rendered here by home.lua -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,17 +3,11 @@
|
||||
<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>Messages</title>
|
||||
<style>
|
||||
.messages-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.conversations-list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
@@ -30,15 +24,19 @@
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.conversation-item:active {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.conversation-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 28px;
|
||||
margin-right: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-size: 22px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
@@ -54,18 +52,18 @@
|
||||
}
|
||||
|
||||
.conversation-name {
|
||||
font-size: 16px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.conversation-time {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.conversation-preview {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
margin-top: 4px;
|
||||
white-space: nowrap;
|
||||
@@ -88,30 +86,135 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="messages-screen" data-model="messages">
|
||||
<body class="app-screen" onload="initLayout(document)" data-model="messages">
|
||||
<!-- 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-nav btn-icon" onclick="goBack()"><img src="../../icons/back.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="app-bar-back" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<span class="app-bar-title">Messages</span>
|
||||
<div class="btn-icon"><img src="../../icons/search.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="app-bar-actions">
|
||||
<div class="app-bar-action">
|
||||
<img src="../../icons/search.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Conversations List -->
|
||||
<div class="conversations-list">
|
||||
<div class="conversation-item" data-for="conv : conversations" data-event-click="select_conversation(conv.id); navigateTo('chat')">
|
||||
<div class="conversation-avatar" data-style-background-color="conv.color">{{ conv.name | slice(0, 1) }}</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">{{ conv.name }}</span>
|
||||
<span class="conversation-time">{{ conv.time }}</span>
|
||||
<div class="app-content with-nav">
|
||||
<div class="conversations-list">
|
||||
<!-- Alice -->
|
||||
<div class="conversation-item">
|
||||
<div class="conversation-avatar" style="background-color: #E91E63;">A</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">Alice Johnson</span>
|
||||
<span class="conversation-time">2:34 PM</span>
|
||||
</div>
|
||||
<div class="conversation-preview">Hey! Are you coming to the party tonight?</div>
|
||||
</div>
|
||||
<div class="conversation-unread">2</div>
|
||||
</div>
|
||||
|
||||
<!-- Bob -->
|
||||
<div class="conversation-item">
|
||||
<div class="conversation-avatar" style="background-color: #2196F3;">B</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">Bob Williams</span>
|
||||
<span class="conversation-time">1:15 PM</span>
|
||||
</div>
|
||||
<div class="conversation-preview">Thanks for the help yesterday!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Carol -->
|
||||
<div class="conversation-item">
|
||||
<div class="conversation-avatar" style="background-color: #4CAF50;">C</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">Carol Davis</span>
|
||||
<span class="conversation-time">Yesterday</span>
|
||||
</div>
|
||||
<div class="conversation-preview">The meeting has been rescheduled to Friday</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- David -->
|
||||
<div class="conversation-item">
|
||||
<div class="conversation-avatar" style="background-color: #FF9800;">D</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">David Brown</span>
|
||||
<span class="conversation-time">Yesterday</span>
|
||||
</div>
|
||||
<div class="conversation-preview">Can you send me the files?</div>
|
||||
</div>
|
||||
<div class="conversation-unread">1</div>
|
||||
</div>
|
||||
|
||||
<!-- Emma -->
|
||||
<div class="conversation-item">
|
||||
<div class="conversation-avatar" style="background-color: #9C27B0;">E</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">Emma Wilson</span>
|
||||
<span class="conversation-time">Mon</span>
|
||||
</div>
|
||||
<div class="conversation-preview">See you at the coffee shop!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Frank -->
|
||||
<div class="conversation-item">
|
||||
<div class="conversation-avatar" style="background-color: #00BCD4;">F</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">Frank Miller</span>
|
||||
<span class="conversation-time">Sun</span>
|
||||
</div>
|
||||
<div class="conversation-preview">Great game last night!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Grace -->
|
||||
<div class="conversation-item">
|
||||
<div class="conversation-avatar" style="background-color: #673AB7;">G</div>
|
||||
<div class="conversation-content">
|
||||
<div class="conversation-header">
|
||||
<span class="conversation-name">Grace Lee</span>
|
||||
<span class="conversation-time">Sat</span>
|
||||
</div>
|
||||
<div class="conversation-preview">Happy birthday! 🎂</div>
|
||||
</div>
|
||||
<div class="conversation-preview">{{ conv.last_message }}</div>
|
||||
</div>
|
||||
<div class="conversation-unread" data-if="conv.unread > 0">{{ conv.unread }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FAB -->
|
||||
<div class="btn-fab"><img src="../../icons/add.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="btn-fab">
|
||||
<img src="../../icons/add.tga" style="width: 32px; height: 32px;"/>
|
||||
</div>
|
||||
|
||||
<!-- System Navigation Bar -->
|
||||
<div class="system-nav-bar">
|
||||
<div class="system-nav-btn" onclick="onBackPressed()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<div class="system-nav-home" onclick="onHomePressed()"></div>
|
||||
<div class="system-nav-btn" onclick="onRecentPressed()">
|
||||
<img src="../../icons/menu.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</rml>
|
||||
|
||||
@@ -3,23 +3,16 @@
|
||||
<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>Music</title>
|
||||
<style>
|
||||
.music-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.music-content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Now Playing Mini Bar */
|
||||
.mini-player {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -47,30 +40,25 @@
|
||||
}
|
||||
|
||||
.mini-player-title {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.mini-player-artist {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #B3B3B3;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.mini-player-controls {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.mini-control-btn {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border-radius: 28px;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.mini-control-btn:hover {
|
||||
@@ -78,26 +66,25 @@
|
||||
}
|
||||
|
||||
.mini-control-btn img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
/* Section Headers */
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24px 16px 12px 16px;
|
||||
padding: 20px 16px 12px 16px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 22px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.section-action {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #B3B3B3;
|
||||
cursor: pointer;
|
||||
@@ -107,7 +94,6 @@
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* Recently Played Row */
|
||||
.recent-row {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
@@ -116,35 +102,38 @@
|
||||
}
|
||||
|
||||
.recent-item {
|
||||
min-width: 130px;
|
||||
min-width: 120px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.recent-item:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.recent-art {
|
||||
width: 130px;
|
||||
height: 130px;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40px;
|
||||
font-size: 36px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.recent-title {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.recent-subtitle {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
/* Quick Access Cards */
|
||||
.quick-access {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -174,18 +163,17 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.quick-card-title {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #FFFFFF;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
/* Playlist Row */
|
||||
.playlist-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -220,12 +208,11 @@
|
||||
}
|
||||
|
||||
.playlist-meta {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #B3B3B3;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Bottom Navigation */
|
||||
.music-bottom-nav {
|
||||
display: flex;
|
||||
height: 56px;
|
||||
@@ -244,48 +231,62 @@
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.nav-item img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.nav-item span {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Color palette for album arts */
|
||||
.bg-gradient-1 { background-color: #667eea; }
|
||||
.bg-gradient-2 { background-color: #f093fb; }
|
||||
.bg-gradient-3 { background-color: #4facfe; }
|
||||
.bg-gradient-4 { background-color: #43e97b; }
|
||||
.bg-gradient-5 { background-color: #fa709a; }
|
||||
.bg-gradient-6 { background-color: #a8edea; }
|
||||
.bg-solid-purple { background-color: #7c3aed; }
|
||||
.bg-solid-red { background-color: #dc2626; }
|
||||
.bg-solid-green { background-color: #16a34a; }
|
||||
.bg-solid-blue { background-color: #2563eb; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="music-screen">
|
||||
<body class="app-screen" onload="initLayout(document)">
|
||||
<!-- 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-nav btn-icon" onclick="goBack()">
|
||||
<img src="../../icons/back.tga" style="width: 32px; height: 32px;"/>
|
||||
<div class="app-bar-back" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<span class="app-bar-title">Music</span>
|
||||
<div class="btn-icon">
|
||||
<img src="../../icons/search.tga" style="width: 32px; height: 32px;"/>
|
||||
<div class="app-bar-actions">
|
||||
<div class="app-bar-action">
|
||||
<img src="../../icons/search.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="music-content">
|
||||
<!-- Good Morning Section -->
|
||||
<!-- Good Afternoon Section -->
|
||||
<div class="section-header">
|
||||
<span class="section-title">Good afternoon</span>
|
||||
</div>
|
||||
@@ -376,14 +377,6 @@
|
||||
<div class="playlist-meta">Your weekly mixtape</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="playlist-item">
|
||||
<div class="playlist-art bg-solid-green">R</div>
|
||||
<div class="playlist-info">
|
||||
<div class="playlist-title">Release Radar</div>
|
||||
<div class="playlist-meta">New music from artists you follow</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mini Player -->
|
||||
@@ -393,7 +386,7 @@
|
||||
<div class="mini-player-title">Midnight City</div>
|
||||
<div class="mini-player-artist">M83</div>
|
||||
</div>
|
||||
<div class="mini-player-controls">
|
||||
<div style="display: flex; gap: 4px;">
|
||||
<div class="mini-control-btn">
|
||||
<img src="../../icons/heart.tga"/>
|
||||
</div>
|
||||
|
||||
@@ -3,17 +3,11 @@
|
||||
<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>Settings</title>
|
||||
<style>
|
||||
.settings-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.settings-list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
@@ -24,7 +18,7 @@
|
||||
|
||||
.settings-section {
|
||||
margin-bottom: 8px;
|
||||
width: 540px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -37,10 +31,11 @@
|
||||
}
|
||||
|
||||
.settings-item {
|
||||
width: 540px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
cursor: pointer;
|
||||
background-color: #1E1E1E;
|
||||
@@ -56,11 +51,18 @@
|
||||
}
|
||||
|
||||
.settings-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 16px;
|
||||
font-size: 28px;
|
||||
color: #B3B3B3;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.settings-icon img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.settings-content {
|
||||
@@ -68,7 +70,7 @@
|
||||
}
|
||||
|
||||
.settings-title {
|
||||
font-size: 16px;
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
@@ -81,6 +83,7 @@
|
||||
.settings-action {
|
||||
font-size: 20px;
|
||||
color: #666666;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.settings-toggle {
|
||||
@@ -111,13 +114,8 @@
|
||||
left: 26px;
|
||||
}
|
||||
|
||||
.settings-value {
|
||||
font-size: 18px;
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
.user-card {
|
||||
width: 540px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -125,6 +123,11 @@
|
||||
padding: 20px 16px;
|
||||
background-color: #1E1E1E;
|
||||
margin-bottom: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-card:hover {
|
||||
background-color: #252525;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
@@ -133,10 +136,11 @@
|
||||
border-radius: 32px;
|
||||
background-color: #BB86FC;
|
||||
margin-right: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
line-height: 64px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
@@ -150,153 +154,206 @@
|
||||
}
|
||||
|
||||
.user-email {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="settings-screen">
|
||||
<body class="app-screen" onload="initLayout(document)">
|
||||
<!-- 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-nav btn-icon" onclick="goBack()"><img src="../../icons/back.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="app-bar-back" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<span class="app-bar-title">Settings</span>
|
||||
<div class="btn-icon"><img src="../../icons/search.tga" style="width: 32px; height: 32px;"/></div>
|
||||
<div class="app-bar-actions">
|
||||
<div class="app-bar-action">
|
||||
<img src="../../icons/search.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings List -->
|
||||
<div class="settings-list">
|
||||
<!-- User Card -->
|
||||
<div class="user-card">
|
||||
<div class="user-avatar">U</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name">User</div>
|
||||
<div class="user-email">user@mosis.local</div>
|
||||
<div class="app-content with-nav">
|
||||
<div class="settings-list">
|
||||
<!-- User Card -->
|
||||
<div class="user-card">
|
||||
<div class="user-avatar">U</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name">User</div>
|
||||
<div class="user-email">user@mosis.local</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
|
||||
<!-- Network Section -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">Network</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">W</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Wi-Fi</div>
|
||||
<div class="settings-subtitle">Connected to MosisNetwork</div>
|
||||
<!-- Network Section -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">Network</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/wifi.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Wi-Fi</div>
|
||||
<div class="settings-subtitle">Connected to MosisNetwork</div>
|
||||
</div>
|
||||
<div class="settings-toggle active">
|
||||
<div class="settings-toggle-thumb"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-toggle active">
|
||||
<div class="settings-toggle-thumb"></div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/signal.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Bluetooth</div>
|
||||
<div class="settings-subtitle">Off</div>
|
||||
</div>
|
||||
<div class="settings-toggle">
|
||||
<div class="settings-toggle-thumb"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/signal.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Airplane Mode</div>
|
||||
</div>
|
||||
<div class="settings-toggle">
|
||||
<div class="settings-toggle-thumb"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">B</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Bluetooth</div>
|
||||
<div class="settings-subtitle">Off</div>
|
||||
|
||||
<!-- Device Section -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">Device</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/settings.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Display</div>
|
||||
<div class="settings-subtitle">Brightness, wallpaper, sleep</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-toggle">
|
||||
<div class="settings-toggle-thumb"></div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/music.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Sound</div>
|
||||
<div class="settings-subtitle">Volume, ringtone, vibration</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/message.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Notifications</div>
|
||||
<div class="settings-subtitle">App notifications, Do not disturb</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/battery.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Battery</div>
|
||||
<div class="settings-subtitle">85% - 4h 30m remaining</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/files.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Storage</div>
|
||||
<div class="settings-subtitle">32 GB of 128 GB used</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">A</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Airplane Mode</div>
|
||||
|
||||
<!-- Privacy Section -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">Privacy & Security</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/account.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Lock Screen</div>
|
||||
<div class="settings-subtitle">PIN, pattern, fingerprint</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-toggle">
|
||||
<div class="settings-toggle-thumb"></div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/account.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Privacy</div>
|
||||
<div class="settings-subtitle">Permissions, account activity</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/maps.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Location</div>
|
||||
<div class="settings-subtitle">On - High accuracy</div>
|
||||
</div>
|
||||
<div class="settings-toggle active">
|
||||
<div class="settings-toggle-thumb"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- About Section -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">About</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">
|
||||
<img src="../../icons/phone.tga"/>
|
||||
</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">About Phone</div>
|
||||
<div class="settings-subtitle">Mosis Virtual Phone v1.0</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Device Section -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">Device</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">D</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Display</div>
|
||||
<div class="settings-subtitle">Brightness, wallpaper, sleep</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">S</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Sound</div>
|
||||
<div class="settings-subtitle">Volume, ringtone, vibration</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">N</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Notifications</div>
|
||||
<div class="settings-subtitle">App notifications, Do not disturb</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">B</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Battery</div>
|
||||
<div class="settings-subtitle">85% - 4h 30m remaining</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">S</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Storage</div>
|
||||
<div class="settings-subtitle">32 GB of 128 GB used</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<!-- System Navigation Bar -->
|
||||
<div class="system-nav-bar">
|
||||
<div class="system-nav-btn" onclick="onBackPressed()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
|
||||
<!-- Privacy Section -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">Privacy & Security</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">L</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Lock Screen</div>
|
||||
<div class="settings-subtitle">PIN, pattern, fingerprint</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">P</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Privacy</div>
|
||||
<div class="settings-subtitle">Permissions, account activity</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">L</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">Location</div>
|
||||
<div class="settings-subtitle">On - High accuracy</div>
|
||||
</div>
|
||||
<div class="settings-toggle active">
|
||||
<div class="settings-toggle-thumb"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- About Section -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-header">About</div>
|
||||
<div class="settings-item">
|
||||
<div class="settings-icon">I</div>
|
||||
<div class="settings-content">
|
||||
<div class="settings-title">About Phone</div>
|
||||
<div class="settings-subtitle">Model, software version</div>
|
||||
</div>
|
||||
<span class="settings-action">></span>
|
||||
</div>
|
||||
<div class="system-nav-home" onclick="onHomePressed()"></div>
|
||||
<div class="system-nav-btn" onclick="onRecentPressed()">
|
||||
<img src="../../icons/menu.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -3,25 +3,18 @@
|
||||
<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>
|
||||
<script src="store.lua"></script>
|
||||
<title>Store</title>
|
||||
<style>
|
||||
.store-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.store-content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
/* Search Bar */
|
||||
.store-search {
|
||||
margin: 16px;
|
||||
background-color: #2D2D2D;
|
||||
@@ -29,11 +22,16 @@
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.store-search:hover {
|
||||
background-color: #3D3D3D;
|
||||
}
|
||||
|
||||
.store-search img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
@@ -43,7 +41,6 @@
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
/* Section Headers */
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -58,43 +55,46 @@
|
||||
}
|
||||
|
||||
.section-action {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #BB86FC;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Featured Banner */
|
||||
.featured-banner {
|
||||
margin: 0 16px 16px 16px;
|
||||
height: 160px;
|
||||
height: 140px;
|
||||
background-color: #7C3AED;
|
||||
border-radius: 16px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.featured-banner:hover {
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.featured-tag {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: rgba(255,255,255,0.7);
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.featured-title {
|
||||
font-size: 24px;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.featured-subtitle {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: rgba(255,255,255,0.8);
|
||||
}
|
||||
|
||||
/* App Cards Row */
|
||||
.app-cards-row {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
@@ -103,7 +103,7 @@
|
||||
}
|
||||
|
||||
.app-card {
|
||||
min-width: 140px;
|
||||
min-width: 130px;
|
||||
background-color: #1E1E1E;
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
@@ -115,44 +115,35 @@
|
||||
}
|
||||
|
||||
.app-card-icon {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 14px;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
font-size: 24px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.app-card-name {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.app-card-category {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #B3B3B3;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.app-card-rating {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
.app-card-rating img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* App List Items */
|
||||
.app-list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -187,35 +178,18 @@
|
||||
}
|
||||
|
||||
.app-list-meta {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
color: #B3B3B3;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.app-list-rating {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.app-list-rating img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.app-list-rating span {
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
.install-btn {
|
||||
background-color: #BB86FC;
|
||||
color: #000000;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 10px 22px;
|
||||
border-radius: 22px;
|
||||
padding: 10px 20px;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -226,11 +200,8 @@
|
||||
.install-btn.installed {
|
||||
background-color: transparent;
|
||||
color: #BB86FC;
|
||||
border-width: 1px;
|
||||
border-color: #BB86FC;
|
||||
}
|
||||
|
||||
/* Category Chips */
|
||||
.category-chips {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
@@ -258,7 +229,6 @@
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* Bottom Nav */
|
||||
.store-bottom-nav {
|
||||
display: flex;
|
||||
height: 56px;
|
||||
@@ -275,21 +245,24 @@
|
||||
color: #B3B3B3;
|
||||
}
|
||||
|
||||
.store-nav-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.store-nav-item.active {
|
||||
color: #BB86FC;
|
||||
}
|
||||
|
||||
.store-nav-item img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.store-nav-item span {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Color palette for app icons */
|
||||
.bg-purple { background-color: #BB86FC; }
|
||||
.bg-teal { background-color: #03DAC6; }
|
||||
.bg-orange { background-color: #FF9800; }
|
||||
@@ -298,131 +271,29 @@
|
||||
.bg-red { background-color: #F44336; }
|
||||
.bg-pink { background-color: #E91E63; }
|
||||
.bg-indigo { background-color: #3F51B5; }
|
||||
|
||||
/* Dialog Overlay */
|
||||
.dialog-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
background-color: #2D2D2D;
|
||||
border-radius: 16px;
|
||||
padding: 24px;
|
||||
min-width: 280px;
|
||||
max-width: 320px;
|
||||
}
|
||||
|
||||
.dialog-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #FFFFFF;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.dialog-message {
|
||||
font-size: 16px;
|
||||
color: #B3B3B3;
|
||||
margin-bottom: 24px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.dialog-status {
|
||||
font-size: 14px;
|
||||
color: #B3B3B3;
|
||||
margin-top: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.dialog-btn {
|
||||
background-color: transparent;
|
||||
color: #BB86FC;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding: 10px 20px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dialog-btn:hover {
|
||||
background-color: rgba(187, 134, 252, 0.1);
|
||||
}
|
||||
|
||||
/* Progress Bar */
|
||||
.progress-container {
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background-color: #1E1E1E;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
background-color: #BB86FC;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* Toast */
|
||||
.toast {
|
||||
position: fixed;
|
||||
bottom: 80px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: #323232;
|
||||
color: #FFFFFF;
|
||||
font-size: 14px;
|
||||
padding: 12px 24px;
|
||||
border-radius: 8px;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
/* Badge */
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
background-color: #F44336;
|
||||
color: #FFFFFF;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 9px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.store-nav-item {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="store-screen">
|
||||
<body class="app-screen" onload="initLayout(document)">
|
||||
<!-- 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-nav btn-icon" onclick="goBack()">
|
||||
<img src="../../icons/back.tga" style="width: 32px; height: 32px;"/>
|
||||
<div class="app-bar-back" onclick="goBack()">
|
||||
<img src="../../icons/back.tga"/>
|
||||
</div>
|
||||
<span class="app-bar-title">Mosis Store</span>
|
||||
<div class="btn-icon">
|
||||
<img src="../../icons/account.tga" style="width: 32px; height: 32px;"/>
|
||||
<div class="app-bar-actions">
|
||||
<div class="app-bar-action">
|
||||
<img src="../../icons/account.tga"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -447,7 +318,6 @@
|
||||
<div class="category-chip">Games</div>
|
||||
<div class="category-chip">Social</div>
|
||||
<div class="category-chip">Productivity</div>
|
||||
<div class="category-chip">Entertainment</div>
|
||||
<div class="category-chip">Tools</div>
|
||||
</div>
|
||||
|
||||
@@ -490,15 +360,11 @@
|
||||
<span class="section-action">See all</span>
|
||||
</div>
|
||||
|
||||
<!-- App List -->
|
||||
<div class="app-list-item">
|
||||
<div class="app-list-icon bg-purple">S</div>
|
||||
<div class="app-list-info">
|
||||
<div class="app-list-name">Social Hub</div>
|
||||
<div class="app-list-meta">Social • 12 MB</div>
|
||||
<div class="app-list-rating">
|
||||
<span>4.9 • 1.2M downloads</span>
|
||||
</div>
|
||||
<div class="app-list-meta">Social - 12 MB - 4.9</div>
|
||||
</div>
|
||||
<div class="install-btn">Install</div>
|
||||
</div>
|
||||
@@ -507,10 +373,7 @@
|
||||
<div class="app-list-icon bg-red">G</div>
|
||||
<div class="app-list-info">
|
||||
<div class="app-list-name">Games Center</div>
|
||||
<div class="app-list-meta">Games • 45 MB</div>
|
||||
<div class="app-list-rating">
|
||||
<span>4.7 • 890K downloads</span>
|
||||
</div>
|
||||
<div class="app-list-meta">Games - 45 MB - 4.7</div>
|
||||
</div>
|
||||
<div class="install-btn">Install</div>
|
||||
</div>
|
||||
@@ -519,10 +382,7 @@
|
||||
<div class="app-list-icon bg-indigo">F</div>
|
||||
<div class="app-list-info">
|
||||
<div class="app-list-name">File Manager</div>
|
||||
<div class="app-list-meta">Tools • 8 MB</div>
|
||||
<div class="app-list-rating">
|
||||
<span>4.6 • 650K downloads</span>
|
||||
</div>
|
||||
<div class="app-list-meta">Tools - 8 MB - 4.6</div>
|
||||
</div>
|
||||
<div class="install-btn installed">Open</div>
|
||||
</div>
|
||||
@@ -531,100 +391,26 @@
|
||||
<div class="app-list-icon bg-pink">M</div>
|
||||
<div class="app-list-info">
|
||||
<div class="app-list-name">Music Player</div>
|
||||
<div class="app-list-meta">Music • 18 MB</div>
|
||||
<div class="app-list-rating">
|
||||
<span>4.5 • 520K downloads</span>
|
||||
</div>
|
||||
<div class="app-list-meta">Music - 18 MB - 4.5</div>
|
||||
</div>
|
||||
<div class="install-btn">Install</div>
|
||||
</div>
|
||||
|
||||
<div class="app-list-item">
|
||||
<div class="app-list-icon bg-teal">P</div>
|
||||
<div class="app-list-info">
|
||||
<div class="app-list-name">Photo Editor</div>
|
||||
<div class="app-list-meta">Photography • 32 MB</div>
|
||||
<div class="app-list-rating">
|
||||
<span>4.4 • 410K downloads</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="install-btn">Install</div>
|
||||
</div>
|
||||
|
||||
<!-- New Games Section -->
|
||||
<div class="section-header">
|
||||
<span class="section-title">New Games</span>
|
||||
<span class="section-action">See all</span>
|
||||
</div>
|
||||
|
||||
<div class="app-cards-row">
|
||||
<div class="app-card">
|
||||
<div class="app-card-icon bg-red">P</div>
|
||||
<div class="app-card-name">Puzzle Quest</div>
|
||||
<div class="app-card-category">Puzzle</div>
|
||||
<div class="app-card-rating">4.8</div>
|
||||
</div>
|
||||
<div class="app-card">
|
||||
<div class="app-card-icon bg-green">R</div>
|
||||
<div class="app-card-name">Racing VR</div>
|
||||
<div class="app-card-category">Racing</div>
|
||||
<div class="app-card-rating">4.6</div>
|
||||
</div>
|
||||
<div class="app-card">
|
||||
<div class="app-card-icon bg-blue">S</div>
|
||||
<div class="app-card-name">Space Explorer</div>
|
||||
<div class="app-card-category">Adventure</div>
|
||||
<div class="app-card-rating">4.7</div>
|
||||
</div>
|
||||
<div class="app-card">
|
||||
<div class="app-card-icon bg-orange">C</div>
|
||||
<div class="app-card-name">Card Master</div>
|
||||
<div class="app-card-category">Card</div>
|
||||
<div class="app-card-rating">4.5</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom Navigation -->
|
||||
<div class="store-bottom-nav">
|
||||
<div id="nav-apps" class="store-nav-item active" onclick="showHome()">
|
||||
<div class="store-nav-item active">
|
||||
<img src="../../icons/home.tga"/>
|
||||
<span>Apps</span>
|
||||
</div>
|
||||
<div id="nav-games" class="store-nav-item" onclick="showGames()">
|
||||
<div class="store-nav-item">
|
||||
<img src="../../icons/game.tga"/>
|
||||
<span>Games</span>
|
||||
</div>
|
||||
<div id="nav-updates" class="store-nav-item" onclick="showUpdates()">
|
||||
<div class="store-nav-item">
|
||||
<img src="../../icons/download.tga"/>
|
||||
<span>Updates</span>
|
||||
<div id="updates-badge" class="badge" style="display: none;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Progress Dialog (hidden by default) -->
|
||||
<div id="progress-dialog" class="dialog-overlay" style="display: none;">
|
||||
<div class="dialog">
|
||||
<div id="progress-title" class="dialog-title">Installing...</div>
|
||||
<div class="progress-container">
|
||||
<div id="progress-bar" class="progress-bar" style="width: 0%;"></div>
|
||||
</div>
|
||||
<div id="progress-status" class="dialog-status">Preparing...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Error Dialog (hidden by default) -->
|
||||
<div id="error-dialog" class="dialog-overlay" style="display: none;">
|
||||
<div class="dialog">
|
||||
<div class="dialog-title">Error</div>
|
||||
<div id="error-message" class="dialog-message"></div>
|
||||
<div class="dialog-actions">
|
||||
<div class="dialog-btn" onclick="hideError()">OK</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toast (hidden by default) -->
|
||||
<div id="toast" class="toast" style="display: none;"></div>
|
||||
</body>
|
||||
</rml>
|
||||
|
||||
103
src/main/assets/scripts/layout.lua
Normal file
103
src/main/assets/scripts/layout.lua
Normal file
@@ -0,0 +1,103 @@
|
||||
-- Layout System for Virtual Smartphone
|
||||
-- Provides reusable UI component helpers
|
||||
-- Requires navigation.lua to be loaded first
|
||||
|
||||
-- Icon paths (relative to assets/)
|
||||
local ICON_PATH = "../../icons/"
|
||||
|
||||
-- Default icons
|
||||
local icons = {
|
||||
back = ICON_PATH .. "back.tga",
|
||||
home = ICON_PATH .. "home.tga",
|
||||
menu = ICON_PATH .. "menu.tga",
|
||||
search = ICON_PATH .. "search.tga",
|
||||
more = ICON_PATH .. "more.tga",
|
||||
close = ICON_PATH .. "close.tga",
|
||||
wifi = ICON_PATH .. "wifi.tga",
|
||||
signal = ICON_PATH .. "signal.tga",
|
||||
battery = ICON_PATH .. "battery.tga"
|
||||
}
|
||||
|
||||
-- Get current time formatted as HH:MM
|
||||
local function getCurrentTime()
|
||||
-- In sandbox, we might not have os.date, use a default
|
||||
if os and os.date then
|
||||
return os.date("%H:%M")
|
||||
end
|
||||
return "12:30"
|
||||
end
|
||||
|
||||
-- Update status bar time
|
||||
function updateStatusTime(doc)
|
||||
local timeEl = doc:GetElementById("status-time")
|
||||
if timeEl then
|
||||
timeEl.inner_rml = getCurrentTime()
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialize status bar with current time
|
||||
-- Call from document onload
|
||||
function initStatusBar(doc)
|
||||
updateStatusTime(doc)
|
||||
|
||||
-- Set up timer to update time every minute if timers are available
|
||||
if setTimeout then
|
||||
local function updateLoop()
|
||||
updateStatusTime(doc)
|
||||
setTimeout(updateLoop, 60000)
|
||||
end
|
||||
setTimeout(updateLoop, 60000)
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialize app bar back button
|
||||
-- Call from document onload
|
||||
function initAppBar(doc)
|
||||
local backBtn = doc:GetElementById("app-bar-back")
|
||||
if backBtn then
|
||||
-- Back button is handled via onclick in RML
|
||||
-- This is for any additional setup
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialize system navigation bar
|
||||
-- Call from document onload
|
||||
function initSystemNav(doc)
|
||||
-- Navigation buttons are handled via onclick in RML
|
||||
-- This is for any additional setup
|
||||
end
|
||||
|
||||
-- Full layout initialization
|
||||
-- Call from document onload: initLayout(document)
|
||||
function initLayout(doc)
|
||||
initStatusBar(doc)
|
||||
initAppBar(doc)
|
||||
initSystemNav(doc)
|
||||
print("Layout initialized")
|
||||
end
|
||||
|
||||
-- Handle back button press (for app bar or system nav)
|
||||
function onBackPressed()
|
||||
if canGoBack and canGoBack() then
|
||||
goBack()
|
||||
else
|
||||
-- If at root, go home
|
||||
if goHome then
|
||||
goHome()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle home button press
|
||||
function onHomePressed()
|
||||
if goHome then
|
||||
goHome()
|
||||
end
|
||||
end
|
||||
|
||||
-- Handle recent apps button press (placeholder)
|
||||
function onRecentPressed()
|
||||
print("Recent apps pressed (not implemented)")
|
||||
end
|
||||
|
||||
print("Layout system loaded")
|
||||
270
src/main/assets/ui/layout.rcss
Normal file
270
src/main/assets/ui/layout.rcss
Normal file
@@ -0,0 +1,270 @@
|
||||
/* ==============================================
|
||||
Layout Components: Reusable App Layout Structure
|
||||
System status bar, app bar, navigation bar
|
||||
============================================== */
|
||||
|
||||
/* ============== System Status Bar ============== */
|
||||
/* Top bar showing time, signal, wifi, battery */
|
||||
|
||||
.system-status-bar {
|
||||
height: 36px;
|
||||
padding: 0 16px;
|
||||
background-color: transparent;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.system-status-bar.bg-surface {
|
||||
background-color: #1E1E1E;
|
||||
}
|
||||
|
||||
.system-status-time {
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.system-status-icons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.system-status-icons img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* ============== App Bar ============== */
|
||||
/* Title bar with back button and optional actions */
|
||||
|
||||
.app-bar {
|
||||
height: 72px;
|
||||
padding: 0 8px;
|
||||
background-color: #1E1E1E;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 900;
|
||||
}
|
||||
|
||||
.app-bar.transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.app-bar.primary {
|
||||
background-color: #121212;
|
||||
}
|
||||
|
||||
.app-bar-back {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border-radius: 28px;
|
||||
}
|
||||
|
||||
.app-bar-back:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.app-bar-back:active {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.app-bar-back img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.app-bar-title {
|
||||
flex: 1;
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.app-bar-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.app-bar-action {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border-radius: 28px;
|
||||
}
|
||||
|
||||
.app-bar-action:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.app-bar-action:active {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.app-bar-action img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* ============== System Navigation Bar ============== */
|
||||
/* Bottom bar with back, home, and recent buttons */
|
||||
|
||||
.system-nav-bar {
|
||||
height: 56px;
|
||||
background-color: #0A0A0A;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.system-nav-bar.transparent {
|
||||
background-color: rgba(10, 10, 10, 0.9);
|
||||
}
|
||||
|
||||
.system-nav-btn {
|
||||
width: 72px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.system-nav-btn:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.system-nav-btn:active {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.system-nav-btn img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
pointer-events: none;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Home button - pill shape */
|
||||
.system-nav-home {
|
||||
width: 96px;
|
||||
height: 8px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.system-nav-home:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.system-nav-home:active {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
/* ============== Screen Layout ============== */
|
||||
/* Standard app screen structure */
|
||||
|
||||
.app-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #121212;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.app-content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Content padding for nav bar */
|
||||
.app-content.with-nav {
|
||||
padding-bottom: 56px;
|
||||
}
|
||||
|
||||
/* Content padding for dock */
|
||||
.app-content.with-dock {
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
/* ============== Combined Header ============== */
|
||||
/* Status bar + App bar combined */
|
||||
|
||||
.app-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #1E1E1E;
|
||||
}
|
||||
|
||||
.app-header.transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.app-header .system-status-bar {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* ============== Notification Badge ============== */
|
||||
|
||||
.notification-badge {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
background-color: #CF6679;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
/* ============== Recording Indicator ============== */
|
||||
/* Shown when camera/mic is active */
|
||||
|
||||
.recording-indicator {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: #F44336;
|
||||
border-radius: 6px;
|
||||
animation: recording-pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes recording-pulse {
|
||||
0%, 100% { opacity: 1.0; }
|
||||
50% { opacity: 0.4; }
|
||||
}
|
||||
|
||||
/* ============== Divider ============== */
|
||||
|
||||
.header-divider {
|
||||
height: 1px;
|
||||
background-color: #333333;
|
||||
}
|
||||
Reference in New Issue
Block a user