diff --git a/base-apps/com.mosis.sandbox-test/main_content.rml b/base-apps/com.mosis.sandbox-test/main_content.rml new file mode 100644 index 0000000..59dfa56 --- /dev/null +++ b/base-apps/com.mosis.sandbox-test/main_content.rml @@ -0,0 +1,39 @@ + + + +
+
+ Sandbox Test +
+ +
+
+
Timer Test
+
Not started
+
Start Timer
+
+ +
+
JSON Test
+
Not tested
+
Test JSON
+
+ +
+
Crypto Test
+
Not tested
+
Test Crypto
+
+ +
+
Storage Test
+
Not tested
+
Test Storage
+
+ +
+
Results
+
Click buttons above to run tests
+
+
+
diff --git a/src/main/assets/apps/sandbox-test/main_content.rml b/src/main/assets/apps/sandbox-test/main_content.rml new file mode 100644 index 0000000..59dfa56 --- /dev/null +++ b/src/main/assets/apps/sandbox-test/main_content.rml @@ -0,0 +1,39 @@ + + + +
+
+ Sandbox Test +
+ +
+
+
Timer Test
+
Not started
+
Start Timer
+
+ +
+
JSON Test
+
Not tested
+
Test JSON
+
+ +
+
Crypto Test
+
Not tested
+
Test Crypto
+
+ +
+
Storage Test
+
Not tested
+
Test Storage
+
+ +
+
Results
+
Click buttons above to run tests
+
+
+
diff --git a/src/main/assets/apps/shell/shell.lua b/src/main/assets/apps/shell/shell.lua index fc07def..8956143 100644 --- a/src/main/assets/apps/shell/shell.lua +++ b/src/main/assets/apps/shell/shell.lua @@ -103,7 +103,8 @@ function shellNavigateTo(app_id) browser = "apps/browser/browser_content.rml", store = "apps/store/store_content.rml", camera = "apps/camera/camera_content.rml", - music = "apps/music/music_content.rml" + music = "apps/music/music_content.rml", + ["sandbox-test"] = "apps/sandbox-test/main_content.rml" } local path = app_paths[app_id] @@ -488,7 +489,8 @@ function launchDiscoveredApp(package_id) local app_id = package_id:gsub("com.mosis.", "") local builtin_ids = { browser = true, camera = true, contacts = true, dialer = true, - messages = true, music = true, settings = true, store = true + messages = true, music = true, settings = true, store = true, + ["sandbox-test"] = true } if builtin_ids[app_id] then @@ -532,6 +534,97 @@ function launchDiscoveredApp(package_id) return false end +-- ===== SANDBOX TEST FUNCTIONS ===== + +function testSandboxTimer() + local status = shell_document:GetElementById("timer-status") + local results = shell_document:GetElementById("sandbox-results") + + if not mosis or not mosis.timer then + if status then status.inner_rml = "Timer API not available" end + return + end + + if status then status.inner_rml = "Timer started..." end + + mosis.timer.setTimeout(function() + if status then status.inner_rml = "Timer completed!" end + if results then results.inner_rml = results.inner_rml .. "\nTimer: PASSED (1 second delay)" end + showToast("Timer test passed!", "success") + end, 1000) +end + +function testSandboxJSON() + local status = shell_document:GetElementById("json-status") + local results = shell_document:GetElementById("sandbox-results") + + if not mosis or not mosis.json then + if status then status.inner_rml = "JSON API not available" end + return + end + + local test_data = {name = "test", value = 42, nested = {a = 1, b = 2}} + local encoded = mosis.json.encode(test_data) + local decoded = mosis.json.decode(encoded) + + if decoded and decoded.name == "test" and decoded.value == 42 then + if status then status.inner_rml = "JSON encode/decode: PASSED" end + if results then results.inner_rml = results.inner_rml .. "\nJSON: PASSED" end + showToast("JSON test passed!", "success") + else + if status then status.inner_rml = "JSON test: FAILED" end + showToast("JSON test failed!", "error") + end +end + +function testSandboxCrypto() + local status = shell_document:GetElementById("crypto-status") + local results = shell_document:GetElementById("sandbox-results") + + if not mosis or not mosis.crypto then + if status then status.inner_rml = "Crypto API not available" end + return + end + + local hash = mosis.crypto.sha256("test") + if hash and #hash > 0 then + if status then status.inner_rml = "SHA256: " .. hash:sub(1, 16) .. "..." end + if results then results.inner_rml = results.inner_rml .. "\nCrypto: PASSED" end + showToast("Crypto test passed!", "success") + else + if status then status.inner_rml = "Crypto test: FAILED" end + showToast("Crypto test failed!", "error") + end +end + +function testSandboxStorage() + local status = shell_document:GetElementById("storage-status") + local results = shell_document:GetElementById("sandbox-results") + + if not mosis or not mosis.fs then + if status then status.inner_rml = "Storage API not available" end + return + end + + local test_content = "Hello from sandbox test!" + local write_ok = mosis.fs.writeFile("test.txt", test_content) + + if write_ok then + local read_content = mosis.fs.readFile("test.txt") + if read_content == test_content then + if status then status.inner_rml = "Storage read/write: PASSED" end + if results then results.inner_rml = results.inner_rml .. "\nStorage: PASSED" end + showToast("Storage test passed!", "success") + else + if status then status.inner_rml = "Storage read: FAILED" end + showToast("Storage read failed!", "error") + end + else + if status then status.inner_rml = "Storage write: FAILED" end + showToast("Storage write failed!", "error") + end +end + -- Make shell functions globally available for apps _G.showToast = showToast _G.showDialog = showDialog @@ -540,5 +633,9 @@ _G.shellNavigateTo = shellNavigateTo _G.shellLaunchApp = shellLaunchApp _G.launchDiscoveredApp = launchDiscoveredApp _G.populateHomeApps = populateHomeApps +_G.testSandboxTimer = testSandboxTimer +_G.testSandboxJSON = testSandboxJSON +_G.testSandboxCrypto = testSandboxCrypto +_G.testSandboxStorage = testSandboxStorage print("[Shell] Shell script loaded") diff --git a/src/main/assets/apps/shell/shell.rml b/src/main/assets/apps/shell/shell.rml index 35f8366..02a44df 100644 --- a/src/main/assets/apps/shell/shell.rml +++ b/src/main/assets/apps/shell/shell.rml @@ -585,6 +585,77 @@ text-align: center; margin-top: 100px; } + + /* Sandbox Test App */ + .sandbox-content { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + background-color: #121212; + } + + .sandbox-header { + display: flex; + align-items: center; + height: 56px; + background-color: #1e1e1e; + padding: 0 8px; + } + + .sandbox-header-title { + font-size: 20px; + font-weight: bold; + margin-left: 16px; + color: #FFFFFF; + } + + .sandbox-body { + flex: 1; + padding: 16px; + overflow: auto; + } + + .sandbox-card { + background-color: #1e1e1e; + border-radius: 12px; + padding: 16px; + margin-bottom: 12px; + } + + .sandbox-card-title { + font-size: 18px; + font-weight: bold; + margin-bottom: 8px; + color: #bb86fc; + } + + .sandbox-status { + color: #FFFFFF; + margin-bottom: 8px; + } + + .sandbox-btn { + background-color: #bb86fc; + color: #000000; + border-radius: 8px; + padding: 12px 24px; + font-size: 14px; + font-weight: bold; + cursor: pointer; + } + + .sandbox-btn:hover { + background-color: #cf9fff; + } + + .sandbox-results { + font-size: 12px; + background-color: #0d0d0d; + padding: 12px; + border-radius: 8px; + color: #00ff00; + }