fix Music app layout and document RmlUi encoding issue
- Fixed Music app layout using incremental edit approach - Documented RmlUi file encoding issue in DESKTOP-DESIGNER.md - Added workaround: copy from working file and edit incrementally
This commit is contained in:
@@ -219,3 +219,49 @@ The JSON contains element bounds, classes, IDs, and visibility - useful for auto
|
|||||||
## Action Recording and Playback
|
## Action Recording and Playback
|
||||||
|
|
||||||
See [TESTING-FRAMEWORK.md](TESTING-FRAMEWORK.md) for details on recording and playing back UI interactions.
|
See [TESTING-FRAMEWORK.md](TESTING-FRAMEWORK.md) for details on recording and playing back UI interactions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Known Issues and Workarounds
|
||||||
|
|
||||||
|
### RmlUi Layout Breaking Due to File Encoding
|
||||||
|
|
||||||
|
**Problem**: Content fragments created with certain file-writing methods may render with broken layouts - elements appear with 0 width, text wraps excessively, and flex layouts collapse.
|
||||||
|
|
||||||
|
**Symptoms**:
|
||||||
|
- List items don't expand to full width
|
||||||
|
- Text wraps to very narrow columns
|
||||||
|
- Avatars/icons overlap with text
|
||||||
|
- UI hierarchy shows `"width": 0.0` for elements that should have proper width
|
||||||
|
|
||||||
|
**Root Cause**: RmlUi's parser is sensitive to certain invisible file formatting. While files may appear identical in text editors and have the same line endings (CRLF), subtle encoding differences can break layout parsing.
|
||||||
|
|
||||||
|
**Diagnosis**: Use `--hierarchy FILE` flag to dump UI element dimensions:
|
||||||
|
```bash
|
||||||
|
./designer/build/Release/mosis-designer.exe --simulator --playback tests/test_app.json --hierarchy hierarchy.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Check the JSON for elements with `"width": 0.0` that should have proper dimensions.
|
||||||
|
|
||||||
|
**Workaround**: Instead of creating content fragments from scratch, copy an existing working file and modify it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Copy a known working file (e.g., messages_content.rml)
|
||||||
|
cp src/main/assets/apps/messages/messages_content.rml src/main/assets/apps/myapp/myapp_content.rml
|
||||||
|
|
||||||
|
# 2. Edit the file incrementally (use sed, text editor, or Edit tool)
|
||||||
|
# DO NOT rewrite the entire file - preserve the original byte structure
|
||||||
|
|
||||||
|
# 3. Test the layout
|
||||||
|
./designer/build/Release/mosis-designer.exe --simulator --playback tests/test_myapp.json --screenshot-after test.png
|
||||||
|
```
|
||||||
|
|
||||||
|
**Working Reference Files**:
|
||||||
|
- `apps/messages/messages_content.rml` - Known good file format
|
||||||
|
- `apps/store/store_content.rml` - Created by copying from messages
|
||||||
|
- `apps/settings/settings_content.rml` - Created by copying from messages
|
||||||
|
|
||||||
|
**Prevention**: When creating new content fragments:
|
||||||
|
1. Always start by copying an existing working content fragment
|
||||||
|
2. Make incremental edits rather than full file rewrites
|
||||||
|
3. Test layout after changes using `--hierarchy` flag
|
||||||
|
|||||||
@@ -1,174 +1,108 @@
|
|||||||
<!-- Music App Content Fragment -->
|
<!-- Music App Content Fragment -->
|
||||||
<!-- Uses classes from components.rcss -->
|
<!-- Uses classes from components.rcss -->
|
||||||
|
|
||||||
<div class="app-content" style="position: relative;">
|
<div class="app-content">
|
||||||
<div class="app-bar">
|
<div class="app-bar">
|
||||||
<span class="app-bar-title">Good afternoon</span>
|
<span class="app-bar-title">Music</span>
|
||||||
<div class="btn-icon" onclick="openMusicSettings()">
|
<div class="app-bar-actions">
|
||||||
<img src="../../icons/settings.tga" style="width: 28px; height: 28px;"/>
|
<div class="btn-icon" onclick="searchMusic()">
|
||||||
</div>
|
<img src="../../icons/search.tga" style="width: 28px; height: 28px;"/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="flex: 1; overflow: auto; padding-bottom: 100px;">
|
|
||||||
<!-- Quick Access Grid -->
|
|
||||||
<div style="display: flex; flex-wrap: wrap; gap: 8px; padding: 16px;">
|
|
||||||
<div class="quick-card" onclick="openPlaylist('liked')" style="width: 48%;">
|
|
||||||
<div class="quick-card-art" style="background-color: #7c3aed;">L</div>
|
|
||||||
<span class="quick-card-title">Liked Songs</span>
|
|
||||||
</div>
|
|
||||||
<div class="quick-card" onclick="openPlaylist('daily1')" style="width: 48%;">
|
|
||||||
<div class="quick-card-art" style="background-color: #667eea;">D</div>
|
|
||||||
<span class="quick-card-title">Daily Mix 1</span>
|
|
||||||
</div>
|
|
||||||
<div class="quick-card" onclick="openPlaylist('release')" style="width: 48%;">
|
|
||||||
<div class="quick-card-art" style="background-color: #16a34a;">R</div>
|
|
||||||
<span class="quick-card-title">Release Radar</span>
|
|
||||||
</div>
|
|
||||||
<div class="quick-card" onclick="openPlaylist('chill')" style="width: 48%;">
|
|
||||||
<div class="quick-card-art" style="background-color: #f093fb;">C</div>
|
|
||||||
<span class="quick-card-title">Chill Vibes</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Recently Played -->
|
|
||||||
<div class="section-header">
|
|
||||||
<span class="section-title">Recently Played</span>
|
|
||||||
<span class="section-action" onclick="showAllRecent()">SEE ALL</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="display: flex; overflow-x: auto; padding: 0 16px; gap: 16px;">
|
|
||||||
<div class="recent-item" onclick="openPlaylist('pop')">
|
|
||||||
<div class="recent-art" style="background-color: #43e97b;">P</div>
|
|
||||||
<div class="recent-title">Pop Hits</div>
|
|
||||||
<div class="recent-subtitle">Playlist</div>
|
|
||||||
</div>
|
|
||||||
<div class="recent-item" onclick="openPlaylist('electronic')">
|
|
||||||
<div class="recent-art" style="background-color: #fa709a;">E</div>
|
|
||||||
<div class="recent-title">Electronic</div>
|
|
||||||
<div class="recent-subtitle">Playlist</div>
|
|
||||||
</div>
|
|
||||||
<div class="recent-item" onclick="openPlaylist('jazz')">
|
|
||||||
<div class="recent-art" style="background-color: #667eea;">J</div>
|
|
||||||
<div class="recent-title">Jazz Classics</div>
|
|
||||||
<div class="recent-subtitle">Playlist</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Made For You -->
|
|
||||||
<div class="section-header">
|
|
||||||
<span class="section-title">Made For You</span>
|
|
||||||
<span class="section-action" onclick="showAllMixes()">SEE ALL</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="playlist-item" onclick="openPlaylist('daily1')">
|
|
||||||
<div class="playlist-art" style="background-color: #4facfe;">1</div>
|
|
||||||
<div class="playlist-info">
|
|
||||||
<div class="playlist-title">Daily Mix 1</div>
|
|
||||||
<div class="playlist-meta">Based on your listening</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="playlist-item" onclick="openPlaylist('daily2')">
|
|
||||||
<div class="playlist-art" style="background-color: #43e97b;">2</div>
|
|
||||||
<div class="playlist-info">
|
|
||||||
<div class="playlist-title">Daily Mix 2</div>
|
|
||||||
<div class="playlist-meta">Electronic, Ambient, Chill</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="playlist-item" onclick="openPlaylist('discover')">
|
|
||||||
<div class="playlist-art" style="background-color: #fa709a;">D</div>
|
|
||||||
<div class="playlist-info">
|
|
||||||
<div class="playlist-title">Discover Weekly</div>
|
|
||||||
<div class="playlist-meta">Your weekly mixtape</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Mini Player -->
|
<div class="list" style="flex: 1; overflow: auto;">
|
||||||
<div class="mini-player" onclick="openNowPlaying()" style="position: absolute; bottom: 0; left: 0; right: 0;">
|
<div class="list-item" onclick="playSong('midnight')">
|
||||||
<div class="mini-player-art" id="mini-art" style="background-color: #667eea;">M</div>
|
<div class="list-item-avatar" style="background-color: #5C6BC0;">M</div>
|
||||||
<div class="mini-player-info">
|
<div class="list-item-content">
|
||||||
<div class="mini-player-title" id="mini-title">Midnight City</div>
|
<span class="list-item-title" style="color: #BB86FC;">Midnight City</span>
|
||||||
<div class="mini-player-artist" id="mini-artist">M83</div>
|
<span class="list-item-subtitle" style="color: #FFFFFF;">M83</span>
|
||||||
|
</div>
|
||||||
|
<span style="font-size: 14px; color: #888888;">4:03</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mini-player-controls">
|
|
||||||
<div class="mini-control-btn" onclick="toggleLike(); event.stopPropagation();">
|
<div class="list-divider"></div>
|
||||||
<img src="../../icons/heart.tga" style="width: 28px; height: 28px;"/>
|
|
||||||
|
<div class="list-item" onclick="playSong('blinding')">
|
||||||
|
<div class="list-item-avatar" style="background-color: #E91E63;">B</div>
|
||||||
|
<div class="list-item-content">
|
||||||
|
<span class="list-item-title">Blinding Lights</span>
|
||||||
|
<span class="list-item-subtitle">The Weeknd</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mini-control-btn" id="play-btn" onclick="togglePlay(); event.stopPropagation();">
|
<span style="font-size: 14px; color: #888888;">3:20</span>
|
||||||
<img id="play-icon" src="../../icons/play.tga" style="width: 28px; height: 28px;"/>
|
</div>
|
||||||
|
|
||||||
|
<div class="list-divider"></div>
|
||||||
|
|
||||||
|
<div class="list-item" onclick="playSong('levitating')">
|
||||||
|
<div class="list-item-avatar" style="background-color: #9C27B0;">L</div>
|
||||||
|
<div class="list-item-content">
|
||||||
|
<span class="list-item-title" style="color: #BB86FC;">Levitating</span>
|
||||||
|
<span class="list-item-subtitle" style="color: #FFFFFF;">Dua Lipa</span>
|
||||||
</div>
|
</div>
|
||||||
|
<span style="font-size: 14px; color: #888888;">3:23</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="list-divider"></div>
|
||||||
|
|
||||||
|
<div class="list-item" onclick="openPlaylist('favorites')">
|
||||||
|
<div class="list-item-avatar" style="background-color: #F44336;">F</div>
|
||||||
|
<div class="list-item-content">
|
||||||
|
<span class="list-item-title">Favorites</span>
|
||||||
|
<span class="list-item-subtitle">24 songs</span>
|
||||||
|
</div>
|
||||||
|
<span style="font-size: 14px; color: #888888;">></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="list-divider"></div>
|
||||||
|
|
||||||
|
<div class="list-item" onclick="openPlaylist('workout')">
|
||||||
|
<div class="list-item-avatar" style="background-color: #4CAF50;">W</div>
|
||||||
|
<div class="list-item-content">
|
||||||
|
<span class="list-item-title">Workout Mix</span>
|
||||||
|
<span class="list-item-subtitle">18 songs</span>
|
||||||
|
</div>
|
||||||
|
<span style="font-size: 14px; color: #888888;">></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="list-divider"></div>
|
||||||
|
|
||||||
|
<div class="list-item" onclick="openPlaylist('chill')">
|
||||||
|
<div class="list-item-avatar" style="background-color: #00BCD4;">C</div>
|
||||||
|
<div class="list-item-content">
|
||||||
|
<span class="list-item-title">Chill Vibes</span>
|
||||||
|
<span class="list-item-subtitle">32 songs</span>
|
||||||
|
</div>
|
||||||
|
<span style="font-size: 14px; color: #888888;">></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="list-divider"></div>
|
||||||
|
|
||||||
|
<div class="list-item" onclick="openPlaylist('party')">
|
||||||
|
<div class="list-item-avatar" style="background-color: #FF9800;">P</div>
|
||||||
|
<div class="list-item-content">
|
||||||
|
<span class="list-item-title">Party Hits</span>
|
||||||
|
<span class="list-item-subtitle">45 songs</span>
|
||||||
|
</div>
|
||||||
|
<span style="font-size: 14px; color: #888888;">></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
local is_playing = false
|
function searchMusic()
|
||||||
local current_track = {
|
print("[Music] Search")
|
||||||
title = "Midnight City",
|
if showToast then showToast("Search music") end
|
||||||
artist = "M83"
|
|
||||||
}
|
|
||||||
|
|
||||||
local function getDoc()
|
|
||||||
return shell_document
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function togglePlay()
|
function playSong(id)
|
||||||
is_playing = not is_playing
|
print("[Music] Playing: " .. id)
|
||||||
local doc = getDoc()
|
if showToast then showToast("Now playing") end
|
||||||
if doc then
|
|
||||||
local icon = doc:GetElementById("play-icon")
|
|
||||||
if icon then
|
|
||||||
icon:SetAttribute("src", is_playing and "../../icons/pause.tga" or "../../icons/play.tga")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print("[Music] " .. (is_playing and "Playing" or "Paused"))
|
|
||||||
if showToast then
|
|
||||||
showToast(is_playing and "Playing" or "Paused")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function toggleLike()
|
|
||||||
print("[Music] Liked")
|
|
||||||
if showToast then
|
|
||||||
showToast("Added to Liked Songs")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function openPlaylist(id)
|
function openPlaylist(id)
|
||||||
print("[Music] Opening playlist: " .. id)
|
print("[Music] Opening playlist: " .. id)
|
||||||
if showToast then
|
if showToast then showToast("Playlist: " .. id) end
|
||||||
showToast("Playlist: " .. id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function openNowPlaying()
|
|
||||||
print("[Music] Now playing")
|
|
||||||
if showToast then
|
|
||||||
showToast("Now Playing: " .. current_track.title)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function showAllRecent()
|
|
||||||
print("[Music] Show all recent")
|
|
||||||
if showToast then
|
|
||||||
showToast("Recently played")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function showAllMixes()
|
|
||||||
print("[Music] Show all mixes")
|
|
||||||
if showToast then
|
|
||||||
showToast("Made for you")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function openMusicSettings()
|
|
||||||
print("[Music] Settings")
|
|
||||||
if showToast then
|
|
||||||
showToast("Music settings")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
print("[Music] Content loaded")
|
print("[Music] Content loaded")
|
||||||
|
|||||||
Reference in New Issue
Block a user